home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / platform / stricmp.asm < prev    next >
Assembly Source File  |  1998-06-17  |  6KB  |  240 lines

  1.         page    ,132
  2.         title   stricmp
  3. ;***
  4. ;stricmp.asm - contains case-insensitive string comparision routine
  5. ;       _stricmp/_strcmpi
  6. ;
  7. ;       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
  8. ;
  9. ;Purpose:
  10. ;       contains _stricmpi(), also known as _strcmpi()
  11. ;
  12. ;*******************************************************************************
  13.  
  14.         .xlist
  15.         include cruntime.inc
  16.         .list
  17.  
  18.  
  19. ifdef _MT
  20.  
  21. ; Def and decls necessary to assert the lock for the LC_CTYPE locale category
  22.  
  23. _SETLOCALE_LOCK EQU     19
  24.  
  25. extrn   _lock:proc
  26. extrn   _unlock:proc
  27.  
  28. endif  ; _MT
  29.  
  30. ; Defs and decl necessary to test for the C locale.
  31.  
  32. _CLOCALEHANDLE  EQU     0
  33. LC_CTYPE        EQU     2 * 4
  34.  
  35.  
  36. extrn   __lc_handle:dword
  37.  
  38. ifdef _MT
  39. extrn   __setlc_active:dword
  40. extrn   __unguarded_readlc_active:dword
  41. endif  ; _MT
  42.  
  43.  
  44.  
  45. ifdef _MT
  46. crt_tolower EQU _tolower_lk
  47. else  ; _MT
  48. crt_tolower EQU tolower
  49. endif  ; _MT
  50.  
  51.  
  52. extrn   crt_tolower:proc
  53.  
  54.  
  55. page
  56. ;***
  57. ;int _stricmp(dst, src), _strcmpi(dst, src) - compare strings, ignore case
  58. ;
  59. ;Purpose:
  60. ;       _stricmp/_strcmpi perform a case-insensitive string comparision.
  61. ;       For differences, upper case letters are mapped to lower case.
  62. ;       Thus, "abc_" < "ABCD" since "_" < "d".
  63. ;
  64. ;       Algorithm:
  65. ;
  66. ;       int _strcmpi (char * dst, char * src)
  67. ;       {
  68. ;               int f,l;
  69. ;
  70. ;               do {
  71. ;                       f = tolower(*dst);
  72. ;                       l = tolower(*src);
  73. ;                       dst++;
  74. ;                       src++;
  75. ;               } while (f && f == l);
  76. ;
  77. ;               return(f - l);
  78. ;       }
  79. ;
  80. ;Entry:
  81. ;       char *dst, *src - strings to compare
  82. ;
  83. ;Exit:
  84. ;       AX = -1 if dst < src
  85. ;       AX =  0 if dst = src
  86. ;       AX = +1 if dst > src
  87. ;
  88. ;Uses:
  89. ;       CX, DX
  90. ;
  91. ;Exceptions:
  92. ;
  93. ;*******************************************************************************
  94.  
  95.         CODESEG
  96.  
  97.         public  _strcmpi        ; alternate entry point for compatibility
  98. _strcmpi proc
  99. _strcmpi endp
  100.  
  101.         public  _stricmp
  102. _stricmp proc \
  103.         uses edi esi ebx, \
  104.         dst:ptr, \
  105.         src:ptr
  106.  
  107.         ; load up args
  108.  
  109.         mov     esi,[src]       ; esi = src
  110.         mov     edi,[dst]       ; edi = dst
  111.  
  112.         ; test locale
  113.  
  114.         lea     eax,__lc_handle
  115.         cmp     [eax + LC_CTYPE],_CLOCALEHANDLE
  116.  
  117.         jne     notclocale
  118.  
  119.         ; C locale
  120.  
  121.         mov     al,-1           ; fall into loop
  122.  
  123.         align   4
  124.  
  125. chk_null:
  126.         or      al,al
  127.         jz      short done
  128.  
  129.         mov     al,[esi]        ; al = next source byte
  130.         inc     esi
  131.         mov     ah,[edi]        ; ah = next dest byte
  132.         inc     edi
  133.  
  134.         cmp     ah,al           ; first try case-sensitive comparision
  135.         je      short chk_null  ; match
  136.  
  137.         sub     al,'A'
  138.         cmp     al,'Z'-'A'+1
  139.         sbb     cl,cl
  140.         and     cl,'a'-'A'
  141.         add     al,cl
  142.         add     al,'A'          ; tolower(*dst)
  143.  
  144.         xchg    ah,al           ; operations on AL are shorter than AH
  145.  
  146.         sub     al,'A'
  147.         cmp     al,'Z'-'A'+1
  148.         sbb     cl,cl
  149.         and     cl,'a'-'A'
  150.         add     al,cl
  151.         add     al,'A'          ; tolower(*src)
  152.  
  153.         cmp     al,ah           ; inverse of above comparison -- AL & AH are swapped
  154.         je      short chk_null
  155.  
  156.                                 ; dst < src     dst > src
  157.         sbb     al,al           ; AL=-1, CY=1   AL=0, CY=0
  158.         sbb     al,-1           ; AL=-1         AL=1
  159. done:
  160.         movsx   eax,al          ; extend al to eax
  161.  
  162.         jmp     short doret
  163.  
  164. notclocale:
  165.  
  166.         ; Not the C locale. Must call tolower/_tolower_lk to convert chars
  167.         ; to lower case.
  168.  
  169. ifdef _MT
  170. lock    inc     __unguarded_readlc_active   ; bump unguarded locale read flag
  171.         cmp     __setlc_active,0            ; is setlocale() active?
  172.         jg      short do_lock               ; yes, go assert lock
  173.         push    0                           ; local lock flag is 0
  174.         jmp     short end_lock
  175. do_lock:
  176. lock    dec     __unguarded_readlc_active   ; restore flag
  177.         push    _SETLOCALE_LOCK
  178.         call    _lock
  179.         mov     [esp],1                     ; local lock flag is 1
  180. end_lock:
  181. endif  ; _MT
  182.  
  183.         mov     eax,255
  184.         xor     ebx,ebx
  185.  
  186.         align   4
  187.  
  188. chk_null2:
  189.         or      al,al           ; not that if al == 0, then eax == 0!
  190.         jz      short done2
  191.  
  192.         mov     al,[esi]        ; al = next src byte
  193.         inc     esi
  194.         mov     bl,[edi]        ; bl = next dst byte
  195.         inc     edi
  196.  
  197.         cmp     al,bl           ; first try case-sensitive comparision
  198.         je      short chk_null2 ; match
  199.  
  200.         push    eax
  201.         push    ebx
  202.  
  203.         call    crt_tolower     ; convert dst char to lower case
  204.  
  205.         mov     ebx,eax
  206.         add     esp,4
  207.  
  208.         call    crt_tolower     ; convert src char to lower case
  209.  
  210.         add     esp,4
  211.  
  212.         cmp     bl,al
  213.         je      chk_null2
  214.  
  215.         sbb     eax,eax
  216.         sbb     eax,-1
  217.  
  218. done2:
  219.  
  220. ifdef _MT
  221.         mov     ebx,eax                     ; save return value in ebx
  222.         pop     eax                         ; get local lock flag
  223.         or      eax,eax                     ; lock held?
  224.         jnz     do_unlock                   ; yes
  225. lock    dec     __unguarded_readlc_active
  226.         jmp     short end_unlock
  227. do_unlock:
  228.         push    _SETLOCALE_LOCK
  229.         call    _unlock
  230.         add     esp,4
  231. end_unlock:
  232.         mov     eax,ebx         ; recover return value
  233. endif  ; _MT
  234.  
  235. doret:
  236.         ret
  237.  
  238. _stricmp endp
  239.         end
  240.