home *** CD-ROM | disk | FTP | other *** search
- /*-----------------------------------------------------------------------*
- * filename - strnicmp.cas
- *
- * function(s)
- * strnicmp - compare one string to another without case
- * sensitivity
- *-----------------------------------------------------------------------*/
-
- /*[]------------------------------------------------------------[]*/
- /*| |*/
- /*| Turbo C Run Time Library - Version 3.0 |*/
- /*| |*/
- /*| |*/
- /*| Copyright (c) 1987,1988,1990 by Borland International |*/
- /*| All Rights Reserved. |*/
- /*| |*/
- /*[]------------------------------------------------------------[]*/
-
-
- #pragma inline
- #include <asmrules.h>
- #include <string.h>
-
- /*-----------------------------------------------------------------------*
-
- Name strnicmp - compare one string to another without case
- sensitivity
-
- Usage int strnicmp(const char *str1, const char *str2, size_t maxlen);
-
- Prototype in string.h
-
- Description Case-independent comparison of *str1 with *str2. Compare
- the strings, but act as if upper and lower case characters
- were always upper-case, returning a negative, zero, or
- positive integer according to whether *str1 is less than,
- equal, or greater than *str2, respectively.
-
- At most "maxlen" bytes will be compared before stopping. A
- zero "maxlen" results in an equal strnicmp, i.e. returns
- zero.
-
- The strings *str1 and *str2 are not changed.
-
- When comparing to punctuation characters alphabetics are
- always treated as upper-case.
-
- Return value strcmp returns an integer value such as:
- < 0 if str1 is less than str2
- = 0 if str1 is the same as str2
- > 0 if str2 is greater than str2
-
- *------------------------------------------------------------------------*/
- int strnicmp(const char *str1, const char *str2, size_t maxlen)
- {
- pushDS_
- #if !(LDATA)
- _ES = _DS;
- #endif
- asm cld
-
- asm LDS_ si, str1
- asm LES_ di, str2
- asm mov cx, maxlen
-
- /*
- AH and BH will stay zero during this process. This'll be handy when its
- time for a final subtract later. Setting up the 'az' constant in DX can
- have a slight payoff for strings greater than 3-4 chars in length(which
- should be the usual case).
- */
- asm xor ax, ax /* AX <- 0 */
- asm mov bx, ax /* BX <- 0 */
- asm mov dx, 617aH /* DH <- 'a', DL <- 'z' */
-
- nci_nextCh:
- asm jcxz nci_end /* length limited? */
- asm lodsb /* AL <- str1[i] */
- asm mov bl, ES_ [di] /* BL <- str2[i] */
- asm or al, al /* end of string? */
- asm jz nci_end
- asm scasb /* str1[i] == str2[i]?, advance DI */
- asm loope nci_nextCh
-
- nci_alUpper:
- asm cmp al, dh /* str1[i] < 'a' */
- asm jb nci_blUpper
- asm cmp al, dl /* str1[i] > 'z' */
- asm ja nci_blUpper
- asm sub al, 'a' - 'A' /* upper case str1[i] */
-
- nci_blUpper:
- asm cmp bl, dh /* str2[i] < 'a' */
- asm jb nci_finalDif
- asm cmp bl, dl /* str2[i] > 'z' */
- asm ja nci_finalDif
- asm sub bl, 'a' - 'A' /* upper case str2[i] */
-
- nci_finalDif:
- asm cmp al, bl /* compare after conversion */
- asm je nci_nextCh
-
- nci_end:
- /*
- We need to do the full word subtract here because ANSI requires unsigned
- comparisons. A simple byte subtract with a CBW would produce the wrong
- result in some cases. Remember that AH, BH are still zero.
- */
- asm sub ax, bx /* Get the result. Note: AH & BH are still zero */
-
- popDS_
- return _AX;
- }
-