c-strcaseeq.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /* Optimized case-insensitive string comparison in C locale.
  2. Copyright (C) 2001-2002, 2007, 2009-2013 Free Software Foundation, Inc.
  3. This program is free software: you can redistribute it and/or modify it
  4. under the terms of the GNU General Public License as published
  5. by the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. /* Written by Bruno Haible <bruno@clisp.org>. */
  14. #include "c-strcase.h"
  15. #include "c-ctype.h"
  16. /* STRCASEEQ allows to optimize string comparison with a small literal string.
  17. STRCASEEQ (s, "UTF-8", 'U','T','F','-','8',0,0,0,0)
  18. is semantically equivalent to
  19. c_strcasecmp (s, "UTF-8") == 0
  20. just faster. */
  21. /* Help GCC to generate good code for string comparisons with
  22. immediate strings. */
  23. #if defined (__GNUC__) && defined (__OPTIMIZE__)
  24. /* Case insensitive comparison of ASCII characters. */
  25. # if C_CTYPE_ASCII
  26. # define CASEEQ(other,upper) \
  27. (c_isupper (upper) ? ((other) & ~0x20) == (upper) : (other) == (upper))
  28. # elif C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
  29. # define CASEEQ(other,upper) \
  30. (c_isupper (upper) ? (other) == (upper) || (other) == (upper) - 'A' + 'a' : (other) == (upper))
  31. # else
  32. # define CASEEQ(other,upper) \
  33. (c_toupper (other) == (upper))
  34. # endif
  35. static inline int
  36. strcaseeq9 (const char *s1, const char *s2)
  37. {
  38. return c_strcasecmp (s1 + 9, s2 + 9) == 0;
  39. }
  40. static inline int
  41. strcaseeq8 (const char *s1, const char *s2, char s28)
  42. {
  43. if (CASEEQ (s1[8], s28))
  44. {
  45. if (s28 == 0)
  46. return 1;
  47. else
  48. return strcaseeq9 (s1, s2);
  49. }
  50. else
  51. return 0;
  52. }
  53. static inline int
  54. strcaseeq7 (const char *s1, const char *s2, char s27, char s28)
  55. {
  56. if (CASEEQ (s1[7], s27))
  57. {
  58. if (s27 == 0)
  59. return 1;
  60. else
  61. return strcaseeq8 (s1, s2, s28);
  62. }
  63. else
  64. return 0;
  65. }
  66. static inline int
  67. strcaseeq6 (const char *s1, const char *s2, char s26, char s27, char s28)
  68. {
  69. if (CASEEQ (s1[6], s26))
  70. {
  71. if (s26 == 0)
  72. return 1;
  73. else
  74. return strcaseeq7 (s1, s2, s27, s28);
  75. }
  76. else
  77. return 0;
  78. }
  79. static inline int
  80. strcaseeq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28)
  81. {
  82. if (CASEEQ (s1[5], s25))
  83. {
  84. if (s25 == 0)
  85. return 1;
  86. else
  87. return strcaseeq6 (s1, s2, s26, s27, s28);
  88. }
  89. else
  90. return 0;
  91. }
  92. static inline int
  93. strcaseeq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28)
  94. {
  95. if (CASEEQ (s1[4], s24))
  96. {
  97. if (s24 == 0)
  98. return 1;
  99. else
  100. return strcaseeq5 (s1, s2, s25, s26, s27, s28);
  101. }
  102. else
  103. return 0;
  104. }
  105. static inline int
  106. strcaseeq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28)
  107. {
  108. if (CASEEQ (s1[3], s23))
  109. {
  110. if (s23 == 0)
  111. return 1;
  112. else
  113. return strcaseeq4 (s1, s2, s24, s25, s26, s27, s28);
  114. }
  115. else
  116. return 0;
  117. }
  118. static inline int
  119. strcaseeq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
  120. {
  121. if (CASEEQ (s1[2], s22))
  122. {
  123. if (s22 == 0)
  124. return 1;
  125. else
  126. return strcaseeq3 (s1, s2, s23, s24, s25, s26, s27, s28);
  127. }
  128. else
  129. return 0;
  130. }
  131. static inline int
  132. strcaseeq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
  133. {
  134. if (CASEEQ (s1[1], s21))
  135. {
  136. if (s21 == 0)
  137. return 1;
  138. else
  139. return strcaseeq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28);
  140. }
  141. else
  142. return 0;
  143. }
  144. static inline int
  145. strcaseeq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
  146. {
  147. if (CASEEQ (s1[0], s20))
  148. {
  149. if (s20 == 0)
  150. return 1;
  151. else
  152. return strcaseeq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28);
  153. }
  154. else
  155. return 0;
  156. }
  157. #define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \
  158. strcaseeq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28)
  159. #else
  160. #define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \
  161. (c_strcasecmp (s1, s2) == 0)
  162. #endif