Mercurial > hg > octave-kai > gnulib-hg
annotate lib/mbscasecmp.c @ 10531:e83a90adf243
Override fopen more carefully.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 28 Sep 2008 16:12:20 +0200 |
parents | bbbbbf4cd1c5 |
children | a0bbe1a6f787 |
rev | line source |
---|---|
8089 | 1 /* Case-insensitive string comparison function. |
2 Copyright (C) 1998-1999, 2005-2007 Free Software Foundation, Inc. | |
3 Written by Bruno Haible <bruno@clisp.org>, 2005, | |
4 based on earlier glibc code. | |
5 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8091
diff
changeset
|
6 This program is free software: you can redistribute it and/or modify |
8089 | 7 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8091
diff
changeset
|
8 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8091
diff
changeset
|
9 (at your option) any later version. |
8089 | 10 |
11 This program is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8091
diff
changeset
|
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
8089 | 18 |
19 #include <config.h> | |
20 | |
21 /* Specification. */ | |
22 #include <string.h> | |
23 | |
24 #include <ctype.h> | |
25 #include <limits.h> | |
26 | |
27 #if HAVE_MBRTOWC | |
28 # include "mbuiter.h" | |
29 #endif | |
30 | |
31 #define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) | |
32 | |
8091
ebf2b19b5684
New module 'mbscasecmp'. strcasecmp is not expected to work with multibyte
Bruno Haible <bruno@clisp.org>
parents:
8089
diff
changeset
|
33 /* Compare the character strings S1 and S2, ignoring case, returning less than, |
ebf2b19b5684
New module 'mbscasecmp'. strcasecmp is not expected to work with multibyte
Bruno Haible <bruno@clisp.org>
parents:
8089
diff
changeset
|
34 equal to or greater than zero if S1 is lexicographically less than, equal to |
ebf2b19b5684
New module 'mbscasecmp'. strcasecmp is not expected to work with multibyte
Bruno Haible <bruno@clisp.org>
parents:
8089
diff
changeset
|
35 or greater than S2. |
8089 | 36 Note: This function may, in multibyte locales, return 0 for strings of |
37 different lengths! */ | |
38 int | |
8091
ebf2b19b5684
New module 'mbscasecmp'. strcasecmp is not expected to work with multibyte
Bruno Haible <bruno@clisp.org>
parents:
8089
diff
changeset
|
39 mbscasecmp (const char *s1, const char *s2) |
8089 | 40 { |
41 if (s1 == s2) | |
42 return 0; | |
43 | |
44 /* Be careful not to look at the entire extent of s1 or s2 until needed. | |
45 This is useful because when two strings differ, the difference is | |
46 most often already in the very few first characters. */ | |
47 #if HAVE_MBRTOWC | |
48 if (MB_CUR_MAX > 1) | |
49 { | |
50 mbui_iterator_t iter1; | |
51 mbui_iterator_t iter2; | |
52 | |
53 mbui_init (iter1, s1); | |
54 mbui_init (iter2, s2); | |
55 | |
56 while (mbui_avail (iter1) && mbui_avail (iter2)) | |
57 { | |
58 int cmp = mb_casecmp (mbui_cur (iter1), mbui_cur (iter2)); | |
59 | |
60 if (cmp != 0) | |
61 return cmp; | |
62 | |
63 mbui_advance (iter1); | |
64 mbui_advance (iter2); | |
65 } | |
66 if (mbui_avail (iter1)) | |
67 /* s2 terminated before s1. */ | |
68 return 1; | |
69 if (mbui_avail (iter2)) | |
70 /* s1 terminated before s2. */ | |
71 return -1; | |
72 return 0; | |
73 } | |
74 else | |
75 #endif | |
76 { | |
77 const unsigned char *p1 = (const unsigned char *) s1; | |
78 const unsigned char *p2 = (const unsigned char *) s2; | |
79 unsigned char c1, c2; | |
80 | |
81 do | |
82 { | |
83 c1 = TOLOWER (*p1); | |
84 c2 = TOLOWER (*p2); | |
85 | |
86 if (c1 == '\0') | |
87 break; | |
88 | |
89 ++p1; | |
90 ++p2; | |
91 } | |
92 while (c1 == c2); | |
93 | |
94 if (UCHAR_MAX <= INT_MAX) | |
95 return c1 - c2; | |
96 else | |
97 /* On machines where 'char' and 'int' are types of the same size, the | |
98 difference of two 'unsigned char' values - including the sign bit - | |
99 doesn't fit in an 'int'. */ | |
100 return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); | |
101 } | |
102 } |