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