/[inetutils]/inetutils/lib/strcasecmp.c
ViewVC logotype

Diff of /inetutils/lib/strcasecmp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by gray, Fri Jul 29 10:52:44 2005 UTC revision 1.3 by ams, Fri Dec 2 14:00:00 2005 UTC
# Line 1  Line 1 
1  /* strcasecmp.c -- case insensitive string comparator  /* Case-insensitive string comparison function.
2     Copyright (C) 1998, 1999 Free Software Foundation, Inc.     Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
3       Written by Bruno Haible <bruno@clisp.org>, 2005,
4       based on earlier glibc code.
5    
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 15  Line 17 
17     along with this program; if not, write to the Free Software Foundation,     along with this program; if not, write to the Free Software Foundation,
18     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19    
20  #if HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
21  # include <config.h>  # include <config.h>
22  #endif  #endif
23    
24  #ifdef LENGTH_LIMIT  /* Specification.  */
25  # define STRXCASECMP_FUNCTION strncasecmp  #include "strcase.h"
 # define STRXCASECMP_DECLARE_N , size_t n  
 # define LENGTH_LIMIT_EXPR(Expr) Expr  
 #else  
 # define STRXCASECMP_FUNCTION strcasecmp  
 # define STRXCASECMP_DECLARE_N /* empty */  
 # define LENGTH_LIMIT_EXPR(Expr) 0  
 #endif  
26    
 #include <stddef.h>  
27  #include <ctype.h>  #include <ctype.h>
28    #include <limits.h>
29    
30  #define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))  #if HAVE_MBRTOWC
31    # include "mbuiter.h"
32    #endif
33    
34  /* Compare {{no more than N characters of }}strings S1 and S2,  #define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
    ignoring case, returning less than, equal to or  
    greater than zero if S1 is lexicographically less  
    than, equal to or greater than S2.  */  
35    
36    /* Compare strings S1 and S2, ignoring case, returning less than, equal to or
37       greater than zero if S1 is lexicographically less than, equal to or greater
38       than S2.
39       Note: This function may, in multibyte locales, return 0 for strings of
40       different lengths!  */
41  int  int
42  STRXCASECMP_FUNCTION (const char *s1, const char *s2 STRXCASECMP_DECLARE_N)  strcasecmp (const char *s1, const char *s2)
43  {  {
44    register const unsigned char *p1 = (const unsigned char *) s1;    if (s1 == s2)
   register const unsigned char *p2 = (const unsigned char *) s2;  
   unsigned char c1, c2;  
   
   if (p1 == p2 || LENGTH_LIMIT_EXPR (n == 0))  
45      return 0;      return 0;
46    
47    do    /* Be careful not to look at the entire extent of s1 or s2 until needed.
48         This is useful because when two strings differ, the difference is
49         most often already in the very few first characters.  */
50    #if HAVE_MBRTOWC
51      if (MB_CUR_MAX > 1)
52      {      {
53        c1 = TOLOWER (*p1);        mbui_iterator_t iter1;
54        c2 = TOLOWER (*p2);        mbui_iterator_t iter2;
55    
56        if (LENGTH_LIMIT_EXPR (--n == 0) || c1 == '\0')        mbui_init (iter1, s1);
57          break;        mbui_init (iter2, s2);
58    
59        ++p1;        while (mbui_avail (iter1) && mbui_avail (iter2))
60        ++p2;          {
61              int cmp = mb_casecmp (mbui_cur (iter1), mbui_cur (iter2));
62    
63              if (cmp != 0)
64                return cmp;
65    
66              mbui_advance (iter1);
67              mbui_advance (iter2);
68            }
69          if (mbui_avail (iter1))
70            /* s2 terminated before s1.  */
71            return 1;
72          if (mbui_avail (iter2))
73            /* s1 terminated before s2.  */
74            return -1;
75          return 0;
76        }
77      else
78    #endif
79        {
80          const unsigned char *p1 = (const unsigned char *) s1;
81          const unsigned char *p2 = (const unsigned char *) s2;
82          unsigned char c1, c2;
83    
84          do
85            {
86              c1 = TOLOWER (*p1);
87              c2 = TOLOWER (*p2);
88    
89              if (c1 == '\0')
90                break;
91    
92              ++p1;
93              ++p2;
94            }
95          while (c1 == c2);
96    
97          if (UCHAR_MAX <= INT_MAX)
98            return c1 - c2;
99          else
100            /* On machines where 'char' and 'int' are types of the same size, the
101               difference of two 'unsigned char' values - including the sign bit -
102               doesn't fit in an 'int'.  */
103            return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
104      }      }
   while (c1 == c2);  
   
   return c1 - c2;  
105  }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26