105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Optimized case-insensitive string comparison in C locale. 205436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 2001-2002, 2007, 2009-2012 Free Software Foundation, Inc. 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 405436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is free software: you can redistribute it and/or modify it 505436638acc7c010349a69c3395f1a57c642dc62Ying Wang under the terms of the GNU General Public License as published 605436638acc7c010349a69c3395f1a57c642dc62Ying Wang by the Free Software Foundation; either version 3 of the License, or 705436638acc7c010349a69c3395f1a57c642dc62Ying Wang (at your option) any later version. 805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 905436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is distributed in the hope that it will be useful, 1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang but WITHOUT ANY WARRANTY; without even the implied warranty of 1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang General Public License for more details. 1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang You should have received a copy of the GNU General Public License 1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang along with this program. If not, see <http://www.gnu.org/licenses/>. */ 1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Written by Bruno Haible <bruno@clisp.org>. */ 1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "c-strcase.h" 2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "c-ctype.h" 2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* STRCASEEQ allows to optimize string comparison with a small literal string. 2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang STRCASEEQ (s, "UTF-8", 'U','T','F','-','8',0,0,0,0) 2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang is semantically equivalent to 2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang c_strcasecmp (s, "UTF-8") == 0 2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang just faster. */ 2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Help GCC to generate good code for string comparisons with 2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang immediate strings. */ 3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if defined (__GNUC__) && defined (__OPTIMIZE__) 3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Case insensitive comparison of ASCII characters. */ 3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if C_CTYPE_ASCII 3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define CASEEQ(other,upper) \ 3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang (c_isupper (upper) ? ((other) & ~0x20) == (upper) : (other) == (upper)) 3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# elif C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE 3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define CASEEQ(other,upper) \ 3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (c_isupper (upper) ? (other) == (upper) || (other) == (upper) - 'A' + 'a' : (other) == (upper)) 3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else 4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define CASEEQ(other,upper) \ 4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang (c_toupper (other) == (upper)) 4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 4405436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline int 4505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstrcaseeq9 (const char *s1, const char *s2) 4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang return c_strcasecmp (s1 + 9, s2 + 9) == 0; 4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5005436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline int 5105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstrcaseeq8 (const char *s1, const char *s2, char s28) 5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (CASEEQ (s1[8], s28)) 5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (s28 == 0) 5605436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 1; 5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang return strcaseeq9 (s1, s2); 5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 6405436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline int 6505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstrcaseeq7 (const char *s1, const char *s2, char s27, char s28) 6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (CASEEQ (s1[7], s27)) 6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (s27 == 0) 7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 1; 7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang return strcaseeq8 (s1, s2, s28); 7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 7805436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline int 7905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstrcaseeq6 (const char *s1, const char *s2, char s26, char s27, char s28) 8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (CASEEQ (s1[6], s26)) 8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (s26 == 0) 8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 1; 8505436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 8605436638acc7c010349a69c3395f1a57c642dc62Ying Wang return strcaseeq7 (s1, s2, s27, s28); 8705436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 9005436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 9105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 9205436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline int 9305436638acc7c010349a69c3395f1a57c642dc62Ying Wangstrcaseeq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28) 9405436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (CASEEQ (s1[5], s25)) 9605436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (s25 == 0) 9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 1; 9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang return strcaseeq6 (s1, s2, s26, s27, s28); 10105436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 10305436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 10405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 10505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline int 10705436638acc7c010349a69c3395f1a57c642dc62Ying Wangstrcaseeq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28) 10805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 10905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (CASEEQ (s1[4], s24)) 11005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 11105436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (s24 == 0) 11205436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 1; 11305436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 11405436638acc7c010349a69c3395f1a57c642dc62Ying Wang return strcaseeq5 (s1, s2, s25, s26, s27, s28); 11505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 11605436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 11705436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 11805436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 11905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 12005436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline int 12105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstrcaseeq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28) 12205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 12305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (CASEEQ (s1[3], s23)) 12405436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 12505436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (s23 == 0) 12605436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 1; 12705436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 12805436638acc7c010349a69c3395f1a57c642dc62Ying Wang return strcaseeq4 (s1, s2, s24, s25, s26, s27, s28); 12905436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 13005436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 13105436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 13205436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 13305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 13405436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline int 13505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstrcaseeq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28) 13605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 13705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (CASEEQ (s1[2], s22)) 13805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 13905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (s22 == 0) 14005436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 1; 14105436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 14205436638acc7c010349a69c3395f1a57c642dc62Ying Wang return strcaseeq3 (s1, s2, s23, s24, s25, s26, s27, s28); 14305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 14405436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 14505436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 14605436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 14705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 14805436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline int 14905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstrcaseeq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) 15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 15105436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (CASEEQ (s1[1], s21)) 15205436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 15305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (s21 == 0) 15405436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 1; 15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang return strcaseeq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28); 15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 15805436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 15905436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 16005436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 16105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 16205436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline int 16305436638acc7c010349a69c3395f1a57c642dc62Ying Wangstrcaseeq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) 16405436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 16505436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (CASEEQ (s1[0], s20)) 16605436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 16705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (s20 == 0) 16805436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 1; 16905436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 17005436638acc7c010349a69c3395f1a57c642dc62Ying Wang return strcaseeq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28); 17105436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 17205436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 17305436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 17405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 17505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 17605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ 17705436638acc7c010349a69c3395f1a57c642dc62Ying Wang strcaseeq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28) 17805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 17905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#else 18005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 18105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ 18205436638acc7c010349a69c3395f1a57c642dc62Ying Wang (c_strcasecmp (s1, s2) == 0) 18305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 18405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 185