strcasecmp.c

00001 /* Case-insensitive string comparison function.
00002    Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
00003    Written by Bruno Haible <bruno@clisp.org>, 2005,
00004    based on earlier glibc code.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU Lesser General Public License as published by
00008    the Free Software Foundation; either version 2.1, or (at your option)
00009    any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public License
00017    along with this program; if not, write to the Free Software Foundation,
00018    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 # include <config.h>
00022 #endif
00023 
00024 /* Specification.  */
00025 #include "strcase.h"
00026 
00027 #include <ctype.h>
00028 #include <limits.h>
00029 
00030 #if HAVE_MBRTOWC
00031 # include "mbuiter.h"
00032 #endif
00033 
00034 #define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
00035 
00036 /* Compare strings S1 and S2, ignoring case, returning less than, equal to or
00037    greater than zero if S1 is lexicographically less than, equal to or greater
00038    than S2.
00039    Note: This function may, in multibyte locales, return 0 for strings of
00040    different lengths!  */
00041 int
00042 strcasecmp (const char *s1, const char *s2)
00043 {
00044   if (s1 == s2)
00045     return 0;
00046 
00047   /* Be careful not to look at the entire extent of s1 or s2 until needed.
00048      This is useful because when two strings differ, the difference is
00049      most often already in the very few first characters.  */
00050 #if HAVE_MBRTOWC
00051   if (MB_CUR_MAX > 1)
00052     {
00053       mbui_iterator_t iter1;
00054       mbui_iterator_t iter2;
00055 
00056       mbui_init (iter1, s1);
00057       mbui_init (iter2, s2);
00058 
00059       while (mbui_avail (iter1) && mbui_avail (iter2))
00060         {
00061           int cmp = mb_casecmp (mbui_cur (iter1), mbui_cur (iter2));
00062 
00063           if (cmp != 0)
00064             return cmp;
00065 
00066           mbui_advance (iter1);
00067           mbui_advance (iter2);
00068         }
00069       if (mbui_avail (iter1))
00070         /* s2 terminated before s1.  */
00071         return 1;
00072       if (mbui_avail (iter2))
00073         /* s1 terminated before s2.  */
00074         return -1;
00075       return 0;
00076     }
00077   else
00078 #endif
00079     {
00080       const unsigned char *p1 = (const unsigned char *) s1;
00081       const unsigned char *p2 = (const unsigned char *) s2;
00082       unsigned char c1, c2;
00083 
00084       do
00085         {
00086           c1 = TOLOWER (*p1);
00087           c2 = TOLOWER (*p2);
00088 
00089           if (c1 == '\0')
00090             break;
00091 
00092           ++p1;
00093           ++p2;
00094         }
00095       while (c1 == c2);
00096 
00097       if (UCHAR_MAX <= INT_MAX)
00098         return c1 - c2;
00099       else
00100         /* On machines where 'char' and 'int' are types of the same size, the
00101            difference of two 'unsigned char' values - including the sign bit -
00102            doesn't fit in an 'int'.  */
00103         return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
00104     }
00105 }

Generated on Thu May 25 21:51:01 2006 for WvStreams by  doxygen 1.4.6