14536c563SJohn Marino /* Optimized case-insensitive string comparison in C locale.
2*6ea1f93eSDaniel Fojt Copyright (C) 2001-2002, 2007, 2009-2018 Free Software Foundation, Inc.
34536c563SJohn Marino
44536c563SJohn Marino This program is free software: you can redistribute it and/or modify it
54536c563SJohn Marino under the terms of the GNU General Public License as published
64536c563SJohn Marino by the Free Software Foundation; either version 3 of the License, or
74536c563SJohn Marino (at your option) any later version.
84536c563SJohn Marino
94536c563SJohn Marino This program is distributed in the hope that it will be useful,
104536c563SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
114536c563SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
124536c563SJohn Marino General Public License for more details.
134536c563SJohn Marino
144536c563SJohn Marino You should have received a copy of the GNU General Public License
15*6ea1f93eSDaniel Fojt along with this program. If not, see <https://www.gnu.org/licenses/>. */
164536c563SJohn Marino
174536c563SJohn Marino /* Written by Bruno Haible <bruno@clisp.org>. */
184536c563SJohn Marino
194536c563SJohn Marino #include "c-strcase.h"
204536c563SJohn Marino #include "c-ctype.h"
214536c563SJohn Marino
224536c563SJohn Marino /* STRCASEEQ allows to optimize string comparison with a small literal string.
234536c563SJohn Marino STRCASEEQ (s, "UTF-8", 'U','T','F','-','8',0,0,0,0)
244536c563SJohn Marino is semantically equivalent to
254536c563SJohn Marino c_strcasecmp (s, "UTF-8") == 0
264536c563SJohn Marino just faster. */
274536c563SJohn Marino
284536c563SJohn Marino /* Help GCC to generate good code for string comparisons with
294536c563SJohn Marino immediate strings. */
304536c563SJohn Marino #if defined (__GNUC__) && defined (__OPTIMIZE__)
314536c563SJohn Marino
324536c563SJohn Marino /* Case insensitive comparison of ASCII characters. */
334536c563SJohn Marino # if C_CTYPE_ASCII
344536c563SJohn Marino # define CASEEQ(other,upper) \
354536c563SJohn Marino (c_isupper (upper) ? ((other) & ~0x20) == (upper) : (other) == (upper))
364536c563SJohn Marino # else
374536c563SJohn Marino # define CASEEQ(other,upper) \
384536c563SJohn Marino (c_toupper (other) == (upper))
394536c563SJohn Marino # endif
404536c563SJohn Marino
414536c563SJohn Marino static inline int
strcaseeq9(const char * s1,const char * s2)424536c563SJohn Marino strcaseeq9 (const char *s1, const char *s2)
434536c563SJohn Marino {
444536c563SJohn Marino return c_strcasecmp (s1 + 9, s2 + 9) == 0;
454536c563SJohn Marino }
464536c563SJohn Marino
474536c563SJohn Marino static inline int
strcaseeq8(const char * s1,const char * s2,char s28)484536c563SJohn Marino strcaseeq8 (const char *s1, const char *s2, char s28)
494536c563SJohn Marino {
504536c563SJohn Marino if (CASEEQ (s1[8], s28))
514536c563SJohn Marino {
524536c563SJohn Marino if (s28 == 0)
534536c563SJohn Marino return 1;
544536c563SJohn Marino else
554536c563SJohn Marino return strcaseeq9 (s1, s2);
564536c563SJohn Marino }
574536c563SJohn Marino else
584536c563SJohn Marino return 0;
594536c563SJohn Marino }
604536c563SJohn Marino
614536c563SJohn Marino static inline int
strcaseeq7(const char * s1,const char * s2,char s27,char s28)624536c563SJohn Marino strcaseeq7 (const char *s1, const char *s2, char s27, char s28)
634536c563SJohn Marino {
644536c563SJohn Marino if (CASEEQ (s1[7], s27))
654536c563SJohn Marino {
664536c563SJohn Marino if (s27 == 0)
674536c563SJohn Marino return 1;
684536c563SJohn Marino else
694536c563SJohn Marino return strcaseeq8 (s1, s2, s28);
704536c563SJohn Marino }
714536c563SJohn Marino else
724536c563SJohn Marino return 0;
734536c563SJohn Marino }
744536c563SJohn Marino
754536c563SJohn Marino static inline int
strcaseeq6(const char * s1,const char * s2,char s26,char s27,char s28)764536c563SJohn Marino strcaseeq6 (const char *s1, const char *s2, char s26, char s27, char s28)
774536c563SJohn Marino {
784536c563SJohn Marino if (CASEEQ (s1[6], s26))
794536c563SJohn Marino {
804536c563SJohn Marino if (s26 == 0)
814536c563SJohn Marino return 1;
824536c563SJohn Marino else
834536c563SJohn Marino return strcaseeq7 (s1, s2, s27, s28);
844536c563SJohn Marino }
854536c563SJohn Marino else
864536c563SJohn Marino return 0;
874536c563SJohn Marino }
884536c563SJohn Marino
894536c563SJohn Marino static inline int
strcaseeq5(const char * s1,const char * s2,char s25,char s26,char s27,char s28)904536c563SJohn Marino strcaseeq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28)
914536c563SJohn Marino {
924536c563SJohn Marino if (CASEEQ (s1[5], s25))
934536c563SJohn Marino {
944536c563SJohn Marino if (s25 == 0)
954536c563SJohn Marino return 1;
964536c563SJohn Marino else
974536c563SJohn Marino return strcaseeq6 (s1, s2, s26, s27, s28);
984536c563SJohn Marino }
994536c563SJohn Marino else
1004536c563SJohn Marino return 0;
1014536c563SJohn Marino }
1024536c563SJohn Marino
1034536c563SJohn Marino static inline int
strcaseeq4(const char * s1,const char * s2,char s24,char s25,char s26,char s27,char s28)1044536c563SJohn Marino strcaseeq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28)
1054536c563SJohn Marino {
1064536c563SJohn Marino if (CASEEQ (s1[4], s24))
1074536c563SJohn Marino {
1084536c563SJohn Marino if (s24 == 0)
1094536c563SJohn Marino return 1;
1104536c563SJohn Marino else
1114536c563SJohn Marino return strcaseeq5 (s1, s2, s25, s26, s27, s28);
1124536c563SJohn Marino }
1134536c563SJohn Marino else
1144536c563SJohn Marino return 0;
1154536c563SJohn Marino }
1164536c563SJohn Marino
1174536c563SJohn Marino static inline int
strcaseeq3(const char * s1,const char * s2,char s23,char s24,char s25,char s26,char s27,char s28)1184536c563SJohn Marino strcaseeq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28)
1194536c563SJohn Marino {
1204536c563SJohn Marino if (CASEEQ (s1[3], s23))
1214536c563SJohn Marino {
1224536c563SJohn Marino if (s23 == 0)
1234536c563SJohn Marino return 1;
1244536c563SJohn Marino else
1254536c563SJohn Marino return strcaseeq4 (s1, s2, s24, s25, s26, s27, s28);
1264536c563SJohn Marino }
1274536c563SJohn Marino else
1284536c563SJohn Marino return 0;
1294536c563SJohn Marino }
1304536c563SJohn Marino
1314536c563SJohn 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)1324536c563SJohn Marino strcaseeq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
1334536c563SJohn Marino {
1344536c563SJohn Marino if (CASEEQ (s1[2], s22))
1354536c563SJohn Marino {
1364536c563SJohn Marino if (s22 == 0)
1374536c563SJohn Marino return 1;
1384536c563SJohn Marino else
1394536c563SJohn Marino return strcaseeq3 (s1, s2, s23, s24, s25, s26, s27, s28);
1404536c563SJohn Marino }
1414536c563SJohn Marino else
1424536c563SJohn Marino return 0;
1434536c563SJohn Marino }
1444536c563SJohn Marino
1454536c563SJohn 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)1464536c563SJohn Marino strcaseeq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
1474536c563SJohn Marino {
1484536c563SJohn Marino if (CASEEQ (s1[1], s21))
1494536c563SJohn Marino {
1504536c563SJohn Marino if (s21 == 0)
1514536c563SJohn Marino return 1;
1524536c563SJohn Marino else
1534536c563SJohn Marino return strcaseeq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28);
1544536c563SJohn Marino }
1554536c563SJohn Marino else
1564536c563SJohn Marino return 0;
1574536c563SJohn Marino }
1584536c563SJohn Marino
1594536c563SJohn 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)1604536c563SJohn 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)
1614536c563SJohn Marino {
1624536c563SJohn Marino if (CASEEQ (s1[0], s20))
1634536c563SJohn Marino {
1644536c563SJohn Marino if (s20 == 0)
1654536c563SJohn Marino return 1;
1664536c563SJohn Marino else
1674536c563SJohn Marino return strcaseeq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28);
1684536c563SJohn Marino }
1694536c563SJohn Marino else
1704536c563SJohn Marino return 0;
1714536c563SJohn Marino }
1724536c563SJohn Marino
1734536c563SJohn Marino #define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \
1744536c563SJohn Marino strcaseeq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28)
1754536c563SJohn Marino
1764536c563SJohn Marino #else
1774536c563SJohn Marino
1784536c563SJohn Marino #define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \
1794536c563SJohn Marino (c_strcasecmp (s1, s2) == 0)
1804536c563SJohn Marino
1814536c563SJohn Marino #endif
182