Skip to content

Commit 21fff73

Browse files
committed
casecompare: a strncasemp replacement
Avoid using strncasecmp() because it relies on and uses the current locale which makes it work differently depending on where it runs. Including locales where 'i' and 'I' are not matching case insensitively. Closes #313
1 parent c51017c commit 21fff73

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

trurl.c

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ typedef enum {
4646
#include "version.h"
4747

4848
#ifdef _MSC_VER
49-
#define strncasecmp _strnicmp
50-
#define strcasecmp _stricmp
5149
#define strdup _strdup
5250
#endif
5351

@@ -151,6 +149,52 @@ static char *curl_url_strerror(CURLUcode error)
151149
}
152150
#endif
153151

152+
/* Mapping table to go from lowercase to uppercase for plain ASCII.*/
153+
static const unsigned char touppermap[256] = {
154+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
155+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
156+
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
157+
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
158+
79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 65,
159+
66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
160+
85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
161+
134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
162+
150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
163+
166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
164+
182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
165+
198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
166+
214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
167+
230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
168+
246, 247, 248, 249, 250, 251, 252, 253, 254, 255
169+
};
170+
171+
/* Portable, ASCII-consistent toupper. Do not use toupper() because its
172+
behavior is altered by the current locale. */
173+
#define raw_toupper(in) touppermap[(unsigned int)in]
174+
175+
/*
176+
* casecompare() does ASCII based case insensitive checks, as a strncasecmp
177+
* replacement.
178+
*/
179+
180+
static int casecompare(const char *first, const char *second, size_t max)
181+
{
182+
while(*first && *second && max) {
183+
int diff = raw_toupper(*first) - raw_toupper(*second);
184+
if(diff)
185+
/* get out of the loop as soon as they don't match */
186+
return diff;
187+
max--;
188+
first++;
189+
second++;
190+
}
191+
if(!max)
192+
return 0; /* identical to this point */
193+
194+
return raw_toupper(*first) - raw_toupper(*second);
195+
}
196+
#define strncasecmp(x,y,z) casecompare(x,y,z)
197+
154198
static void message_low(const char *prefix, const char *suffix,
155199
const char *fmt, va_list ap)
156200
{

0 commit comments

Comments
 (0)