Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
5.3 KiB

  1. /***
  2. *mbsnbicmp.c - Compare n bytes of strings, ignoring case (MBCS)
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Compare n bytes of strings, ignoring case (MBCS)
  8. *
  9. *Revision History:
  10. * 08-03-93 KRS Ported from 16-bit sources.
  11. * 09-29-93 CFW Merge _KANJI and _MBCS_OS
  12. * 10-05-93 GJF Replaced _CRTAPI1 with __cdecl.
  13. * 10-12-93 CFW Compare lower case, not upper.
  14. * 04-12-94 CFW Make function generic.
  15. * 05-05-94 CFW Work around NT/Chico bug: CompareString ignores
  16. * control characters.
  17. * 05-09-94 CFW Return EQUAL when loop exits.
  18. * 05-09-94 CFW Optimize for SBCS, no re-scan if CompareString fixed.
  19. * 05-12-94 CFW Back to hard-coded, CompareString sort is backwards.
  20. * 05-16-94 CFW Use _mbbtolower/upper.
  21. * 05-19-94 CFW Enable non-Win32.
  22. * 05-20-94 CFW Bug fix: if last char is LB, must still test values.
  23. * 05-27-94 CFW Last char LB should end string.
  24. * 09-11-97 GJF Replaced __mbcodepage == 0 with _ISNOTMBCP.
  25. * 04-13-98 GJF Revised multithread support based on threadmbcinfo
  26. * structs
  27. *
  28. *******************************************************************************/
  29. #ifdef _MBCS
  30. #include <mtdll.h>
  31. #include <cruntime.h>
  32. #include <mbdata.h>
  33. #include <mbctype.h>
  34. #include <string.h>
  35. #include <mbstring.h>
  36. /***
  37. * _mbsnbicmp - Compare n bytes of strings, ignoring case (MBCS)
  38. *
  39. *Purpose:
  40. * Compares up to n bytes of two strings for lexical order.
  41. * Strings are compared on a character basis, not a byte basis.
  42. * Case of characters is not considered.
  43. *
  44. *Entry:
  45. * unsigned char *s1, *s2 = strings to compare
  46. * size_t n = maximum number of bytes to compare
  47. *
  48. *Exit:
  49. * returns <0 if s1 < s2
  50. * returns 0 if s1 == s2
  51. * returns >0 if s1 > s2
  52. *
  53. *Exceptions:
  54. *
  55. *******************************************************************************/
  56. int __cdecl _mbsnbicmp(
  57. const unsigned char *s1,
  58. const unsigned char *s2,
  59. size_t n
  60. )
  61. {
  62. unsigned short c1, c2;
  63. #ifdef _MT
  64. pthreadmbcinfo ptmbci = _getptd()->ptmbcinfo;
  65. if ( ptmbci != __ptmbcinfo )
  66. ptmbci = __updatetmbcinfo();
  67. #endif
  68. if (n==0)
  69. return(0);
  70. #ifdef _MT
  71. if ( _ISNOTMBCP_MT(ptmbci) )
  72. #else
  73. if ( _ISNOTMBCP )
  74. #endif
  75. return _strnicmp(s1, s2, n);
  76. while (n--) {
  77. c1 = *s1++;
  78. #ifdef _MT
  79. if ( __ismbblead_mt(ptmbci, c1) )
  80. #else
  81. if ( _ismbblead(c1) )
  82. #endif
  83. {
  84. if (n==0)
  85. {
  86. c1 = 0; /* 'naked' lead - end of string */
  87. #ifdef _MT
  88. c2 = __ismbblead_mt(ptmbci, *s2) ? 0 : *s2;
  89. #else
  90. c2 = _ismbblead(*s2) ? 0 : *s2;
  91. #endif
  92. goto test;
  93. }
  94. if (*s1 == '\0')
  95. c1 = 0;
  96. else {
  97. c1 = ((c1<<8) | *s1++);
  98. #ifdef _MT
  99. if ( ((c1 >= _MBUPPERLOW1_MT(ptmbci)) &&
  100. (c1 <= _MBUPPERHIGH1_MT(ptmbci))) )
  101. c1 += _MBCASEDIFF1_MT(ptmbci);
  102. else if ( ((c1 >= _MBUPPERLOW2_MT(ptmbci)) &&
  103. (c1 <= _MBUPPERHIGH2_MT(ptmbci))) )
  104. c1 += _MBCASEDIFF2_MT(ptmbci);
  105. #else
  106. if ( ((c1 >= _MBUPPERLOW1) && (c1 <= _MBUPPERHIGH1)) )
  107. c1 += _MBCASEDIFF1;
  108. else if ( ((c1 >= _MBUPPERLOW2) && (c1 <= _MBUPPERHIGH2)) )
  109. c1 += _MBCASEDIFF2;
  110. #endif
  111. }
  112. }
  113. else
  114. #ifdef _MT
  115. c1 = __mbbtolower_mt(ptmbci, c1);
  116. #else
  117. c1 = _mbbtolower(c1);
  118. #endif
  119. c2 = *s2++;
  120. #ifdef _MT
  121. if ( __ismbblead_mt(ptmbci, c2) )
  122. #else
  123. if ( _ismbblead(c2) )
  124. #endif
  125. {
  126. if (n==0)
  127. {
  128. c2 = 0; /* 'naked' lead - end of string */
  129. goto test;
  130. }
  131. n--;
  132. if (*s2 == '\0')
  133. c2 = 0;
  134. else {
  135. c2 = ((c2<<8) | *s2++);
  136. #ifdef _MT
  137. if ( ((c2 >= _MBUPPERLOW1_MT(ptmbci)) &&
  138. (c2 <= _MBUPPERHIGH1_MT(ptmbci))) )
  139. c2 += _MBCASEDIFF1_MT(ptmbci);
  140. else if ( ((c2 >= _MBUPPERLOW2_MT(ptmbci)) &&
  141. (c2 <= _MBUPPERHIGH2_MT(ptmbci))) )
  142. c2 += _MBCASEDIFF2_MT(ptmbci);
  143. #else
  144. if ( ((c2 >= _MBUPPERLOW1) && (c2 <= _MBUPPERHIGH1)) )
  145. c2 += _MBCASEDIFF1;
  146. else if ( ((c2 >= _MBUPPERLOW2) && (c2 <= _MBUPPERHIGH2)) )
  147. c2 += _MBCASEDIFF2;
  148. #endif
  149. }
  150. }
  151. else
  152. #ifdef _MT
  153. c2 = __mbbtolower_mt(ptmbci, c2);
  154. #else
  155. c2 = _mbbtolower(c2);
  156. #endif
  157. test:
  158. if (c1 != c2)
  159. return( (c1 > c2) ? 1 : -1);
  160. if (c1 == 0)
  161. return(0);
  162. }
  163. return(0);
  164. }
  165. #endif /* _MBCS */