Annotation of embedaddon/curl/lib/strcase.c, revision 1.1.1.1
1.1 misho 1: /***************************************************************************
2: * _ _ ____ _
3: * Project ___| | | | _ \| |
4: * / __| | | | |_) | |
5: * | (__| |_| | _ <| |___
6: * \___|\___/|_| \_\_____|
7: *
8: * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
9: *
10: * This software is licensed as described in the file COPYING, which
11: * you should have received as part of this distribution. The terms
12: * are also available at https://curl.haxx.se/docs/copyright.html.
13: *
14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15: * copies of the Software, and permit persons to whom the Software is
16: * furnished to do so, under the terms of the COPYING file.
17: *
18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19: * KIND, either express or implied.
20: *
21: ***************************************************************************/
22:
23: #include "curl_setup.h"
24:
25: #include <curl/curl.h>
26:
27: #include "strcase.h"
28:
29: static char raw_tolower(char in);
30:
31: /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
32: its behavior is altered by the current locale. */
33: char Curl_raw_toupper(char in)
34: {
35: #if !defined(CURL_DOES_CONVERSIONS)
36: if(in >= 'a' && in <= 'z')
37: return (char)('A' + in - 'a');
38: #else
39: switch(in) {
40: case 'a':
41: return 'A';
42: case 'b':
43: return 'B';
44: case 'c':
45: return 'C';
46: case 'd':
47: return 'D';
48: case 'e':
49: return 'E';
50: case 'f':
51: return 'F';
52: case 'g':
53: return 'G';
54: case 'h':
55: return 'H';
56: case 'i':
57: return 'I';
58: case 'j':
59: return 'J';
60: case 'k':
61: return 'K';
62: case 'l':
63: return 'L';
64: case 'm':
65: return 'M';
66: case 'n':
67: return 'N';
68: case 'o':
69: return 'O';
70: case 'p':
71: return 'P';
72: case 'q':
73: return 'Q';
74: case 'r':
75: return 'R';
76: case 's':
77: return 'S';
78: case 't':
79: return 'T';
80: case 'u':
81: return 'U';
82: case 'v':
83: return 'V';
84: case 'w':
85: return 'W';
86: case 'x':
87: return 'X';
88: case 'y':
89: return 'Y';
90: case 'z':
91: return 'Z';
92: }
93: #endif
94:
95: return in;
96: }
97:
98:
99: /* Portable, consistent tolower (remember EBCDIC). Do not use tolower() because
100: its behavior is altered by the current locale. */
101: static char raw_tolower(char in)
102: {
103: #if !defined(CURL_DOES_CONVERSIONS)
104: if(in >= 'A' && in <= 'Z')
105: return (char)('a' + in - 'A');
106: #else
107: switch(in) {
108: case 'A':
109: return 'a';
110: case 'B':
111: return 'b';
112: case 'C':
113: return 'c';
114: case 'D':
115: return 'd';
116: case 'E':
117: return 'e';
118: case 'F':
119: return 'f';
120: case 'G':
121: return 'g';
122: case 'H':
123: return 'h';
124: case 'I':
125: return 'i';
126: case 'J':
127: return 'j';
128: case 'K':
129: return 'k';
130: case 'L':
131: return 'l';
132: case 'M':
133: return 'm';
134: case 'N':
135: return 'n';
136: case 'O':
137: return 'o';
138: case 'P':
139: return 'p';
140: case 'Q':
141: return 'q';
142: case 'R':
143: return 'r';
144: case 'S':
145: return 's';
146: case 'T':
147: return 't';
148: case 'U':
149: return 'u';
150: case 'V':
151: return 'v';
152: case 'W':
153: return 'w';
154: case 'X':
155: return 'x';
156: case 'Y':
157: return 'y';
158: case 'Z':
159: return 'z';
160: }
161: #endif
162:
163: return in;
164: }
165:
166:
167: /*
168: * Curl_strcasecompare() is for doing "raw" case insensitive strings. This is
169: * meant to be locale independent and only compare strings we know are safe
170: * for this. See
171: * https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for some
172: * further explanation to why this function is necessary.
173: *
174: * The function is capable of comparing a-z case insensitively even for
175: * non-ascii.
176: *
177: * @unittest: 1301
178: */
179:
180: int Curl_strcasecompare(const char *first, const char *second)
181: {
182: while(*first && *second) {
183: if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
184: /* get out of the loop as soon as they don't match */
185: break;
186: first++;
187: second++;
188: }
189: /* we do the comparison here (possibly again), just to make sure that if the
190: loop above is skipped because one of the strings reached zero, we must not
191: return this as a successful match */
192: return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
193: }
194:
195: int Curl_safe_strcasecompare(const char *first, const char *second)
196: {
197: if(first && second)
198: /* both pointers point to something then compare them */
199: return Curl_strcasecompare(first, second);
200:
201: /* if both pointers are NULL then treat them as equal */
202: return (NULL == first && NULL == second);
203: }
204:
205: /*
206: * @unittest: 1301
207: */
208: int Curl_strncasecompare(const char *first, const char *second, size_t max)
209: {
210: while(*first && *second && max) {
211: if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
212: break;
213: }
214: max--;
215: first++;
216: second++;
217: }
218: if(0 == max)
219: return 1; /* they are equal this far */
220:
221: return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
222: }
223:
224: /* Copy an upper case version of the string from src to dest. The
225: * strings may overlap. No more than n characters of the string are copied
226: * (including any NUL) and the destination string will NOT be
227: * NUL-terminated if that limit is reached.
228: */
229: void Curl_strntoupper(char *dest, const char *src, size_t n)
230: {
231: if(n < 1)
232: return;
233:
234: do {
235: *dest++ = Curl_raw_toupper(*src);
236: } while(*src++ && --n);
237: }
238:
239: /* Copy a lower case version of the string from src to dest. The
240: * strings may overlap. No more than n characters of the string are copied
241: * (including any NUL) and the destination string will NOT be
242: * NUL-terminated if that limit is reached.
243: */
244: void Curl_strntolower(char *dest, const char *src, size_t n)
245: {
246: if(n < 1)
247: return;
248:
249: do {
250: *dest++ = raw_tolower(*src);
251: } while(*src++ && --n);
252: }
253:
254: /* --- public functions --- */
255:
256: int curl_strequal(const char *first, const char *second)
257: {
258: return Curl_strcasecompare(first, second);
259: }
260: int curl_strnequal(const char *first, const char *second, size_t max)
261: {
262: return Curl_strncasecompare(first, second, max);
263: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>