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 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 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 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 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 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 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 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 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 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 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