page ,132 title stricmp ;*** ;stricmp.asm - contains case-insensitive string comparision routine ; _stricmp/_strcmpi ; ; Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. ; ;Purpose: ; contains _stricmpi(), also known as _strcmpi() ; ;******************************************************************************* .xlist include cruntime.inc .list ifdef _MT ; Def and decls necessary to assert the lock for the LC_CTYPE locale category _SETLOCALE_LOCK EQU 19 extrn _lock:proc extrn _unlock:proc endif ; _MT ; Defs and decl necessary to test for the C locale. _CLOCALEHANDLE EQU 0 LC_CTYPE EQU 2 * 4 extrn __lc_handle:dword ifdef _MT extrn __setlc_active:dword extrn __unguarded_readlc_active:dword endif ; _MT ifdef _MT crt_tolower EQU _tolower_lk else ; _MT crt_tolower EQU tolower endif ; _MT extrn crt_tolower:proc page ;*** ;int _stricmp(dst, src), _strcmpi(dst, src) - compare strings, ignore case ; ;Purpose: ; _stricmp/_strcmpi perform a case-insensitive string comparision. ; For differences, upper case letters are mapped to lower case. ; Thus, "abc_" < "ABCD" since "_" < "d". ; ; Algorithm: ; ; int _strcmpi (char * dst, char * src) ; { ; int f,l; ; ; do { ; f = tolower(*dst); ; l = tolower(*src); ; dst++; ; src++; ; } while (f && f == l); ; ; return(f - l); ; } ; ;Entry: ; char *dst, *src - strings to compare ; ;Exit: ; AX = -1 if dst < src ; AX = 0 if dst = src ; AX = +1 if dst > src ; ;Uses: ; CX, DX ; ;Exceptions: ; ;******************************************************************************* CODESEG public _strcmpi ; alternate entry point for compatibility _strcmpi proc _strcmpi endp public _stricmp _stricmp proc \ uses edi esi ebx, \ dst:ptr, \ src:ptr ; load up args mov esi,[src] ; esi = src mov edi,[dst] ; edi = dst ; test locale lea eax,__lc_handle cmp [eax + LC_CTYPE],_CLOCALEHANDLE jne notclocale ; C locale mov al,-1 ; fall into loop align 4 chk_null: or al,al jz short done mov al,[esi] ; al = next source byte inc esi mov ah,[edi] ; ah = next dest byte inc edi cmp ah,al ; first try case-sensitive comparision je short chk_null ; match sub al,'A' cmp al,'Z'-'A'+1 sbb cl,cl and cl,'a'-'A' add al,cl add al,'A' ; tolower(*dst) xchg ah,al ; operations on AL are shorter than AH sub al,'A' cmp al,'Z'-'A'+1 sbb cl,cl and cl,'a'-'A' add al,cl add al,'A' ; tolower(*src) cmp al,ah ; inverse of above comparison -- AL & AH are swapped je short chk_null ; dst < src dst > src sbb al,al ; AL=-1, CY=1 AL=0, CY=0 sbb al,-1 ; AL=-1 AL=1 done: movsx eax,al ; extend al to eax jmp short doret notclocale: ; Not the C locale. Must call tolower/_tolower_lk to convert chars ; to lower case. ifdef _MT lock inc __unguarded_readlc_active ; bump unguarded locale read flag cmp __setlc_active,0 ; is setlocale() active? jg short do_lock ; yes, go assert lock push 0 ; local lock flag is 0 jmp short end_lock do_lock: lock dec __unguarded_readlc_active ; restore flag push _SETLOCALE_LOCK call _lock mov [esp],1 ; local lock flag is 1 end_lock: endif ; _MT mov eax,255 xor ebx,ebx align 4 chk_null2: or al,al ; not that if al == 0, then eax == 0! jz short done2 mov al,[esi] ; al = next src byte inc esi mov bl,[edi] ; bl = next dst byte inc edi cmp al,bl ; first try case-sensitive comparision je short chk_null2 ; match push eax push ebx call crt_tolower ; convert dst char to lower case mov ebx,eax add esp,4 call crt_tolower ; convert src char to lower case add esp,4 cmp bl,al je chk_null2 sbb eax,eax sbb eax,-1 done2: ifdef _MT mov ebx,eax ; save return value in ebx pop eax ; get local lock flag or eax,eax ; lock held? jnz do_unlock ; yes lock dec __unguarded_readlc_active jmp short end_unlock do_unlock: push _SETLOCALE_LOCK call _unlock add esp,4 end_unlock: mov eax,ebx ; recover return value endif ; _MT doret: ret _stricmp endp end