7768
+ − 1
#define __PHYSICSFS_INTERNAL__
+ − 2
#include "physfs_internal.h"
+ − 3
+ − 4
+ − 5
/*
+ − 6
* From rfc3629, the UTF-8 spec:
+ − 7
* http://www.ietf.org/rfc/rfc3629.txt
+ − 8
*
+ − 9
* Char. number range | UTF-8 octet sequence
+ − 10
* (hexadecimal) | (binary)
+ − 11
* --------------------+---------------------------------------------
+ − 12
* 0000 0000-0000 007F | 0xxxxxxx
+ − 13
* 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
+ − 14
* 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
+ − 15
* 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ − 16
*/
+ − 17
+ − 18
+ − 19
/*
+ − 20
* This may not be the best value, but it's one that isn't represented
+ − 21
* in Unicode (0x10FFFF is the largest codepoint value). We return this
+ − 22
* value from utf8codepoint() if there's bogus bits in the
+ − 23
* stream. utf8codepoint() will turn this value into something
+ − 24
* reasonable (like a question mark), for text that wants to try to recover,
+ − 25
* whereas utf8valid() will use the value to determine if a string has bad
+ − 26
* bits.
+ − 27
*/
+ − 28
#define UNICODE_BOGUS_CHAR_VALUE 0xFFFFFFFF
+ − 29
+ − 30
/*
+ − 31
* This is the codepoint we currently return when there was bogus bits in a
+ − 32
* UTF-8 string. May not fly in Asian locales?
+ − 33
*/
+ − 34
#define UNICODE_BOGUS_CHAR_CODEPOINT '?'
+ − 35
+ − 36
static PHYSFS_uint32 utf8codepoint(const char **_str)
+ − 37
{
+ − 38
const char *str = *_str;
+ − 39
PHYSFS_uint32 retval = 0;
+ − 40
PHYSFS_uint32 octet = (PHYSFS_uint32) ((PHYSFS_uint8) *str);
+ − 41
PHYSFS_uint32 octet2, octet3, octet4;
+ − 42
+ − 43
if (octet == 0) /* null terminator, end of string. */
+ − 44
return 0;
+ − 45
+ − 46
else if (octet < 128) /* one octet char: 0 to 127 */
+ − 47
{
+ − 48
(*_str)++; /* skip to next possible start of codepoint. */
+ − 49
return octet;
+ − 50
} /* else if */
+ − 51
+ − 52
else if ((octet > 127) && (octet < 192)) /* bad (starts with 10xxxxxx). */
+ − 53
{
+ − 54
/*
+ − 55
* Apparently each of these is supposed to be flagged as a bogus
+ − 56
* char, instead of just resyncing to the next valid codepoint.
+ − 57
*/
+ − 58
(*_str)++; /* skip to next possible start of codepoint. */
+ − 59
return UNICODE_BOGUS_CHAR_VALUE;
+ − 60
} /* else if */
+ − 61
+ − 62
else if (octet < 224) /* two octets */
+ − 63
{
+ − 64
(*_str)++; /* advance at least one byte in case of an error */
+ − 65
octet -= (128+64);
+ − 66
octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 67
if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 68
return UNICODE_BOGUS_CHAR_VALUE;
+ − 69
+ − 70
*_str += 1; /* skip to next possible start of codepoint. */
+ − 71
retval = ((octet << 6) | (octet2 - 128));
+ − 72
if ((retval >= 0x80) && (retval <= 0x7FF))
+ − 73
return retval;
+ − 74
} /* else if */
+ − 75
+ − 76
else if (octet < 240) /* three octets */
+ − 77
{
+ − 78
(*_str)++; /* advance at least one byte in case of an error */
+ − 79
octet -= (128+64+32);
+ − 80
octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 81
if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 82
return UNICODE_BOGUS_CHAR_VALUE;
+ − 83
+ − 84
octet3 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 85
if ((octet3 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 86
return UNICODE_BOGUS_CHAR_VALUE;
+ − 87
+ − 88
*_str += 2; /* skip to next possible start of codepoint. */
+ − 89
retval = ( ((octet << 12)) | ((octet2-128) << 6) | ((octet3-128)) );
+ − 90
+ − 91
/* There are seven "UTF-16 surrogates" that are illegal in UTF-8. */
+ − 92
switch (retval)
+ − 93
{
+ − 94
case 0xD800:
+ − 95
case 0xDB7F:
+ − 96
case 0xDB80:
+ − 97
case 0xDBFF:
+ − 98
case 0xDC00:
+ − 99
case 0xDF80:
+ − 100
case 0xDFFF:
+ − 101
return UNICODE_BOGUS_CHAR_VALUE;
+ − 102
} /* switch */
+ − 103
+ − 104
/* 0xFFFE and 0xFFFF are illegal, too, so we check them at the edge. */
+ − 105
if ((retval >= 0x800) && (retval <= 0xFFFD))
+ − 106
return retval;
+ − 107
} /* else if */
+ − 108
+ − 109
else if (octet < 248) /* four octets */
+ − 110
{
+ − 111
(*_str)++; /* advance at least one byte in case of an error */
+ − 112
octet -= (128+64+32+16);
+ − 113
octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 114
if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 115
return UNICODE_BOGUS_CHAR_VALUE;
+ − 116
+ − 117
octet3 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 118
if ((octet3 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 119
return UNICODE_BOGUS_CHAR_VALUE;
+ − 120
+ − 121
octet4 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 122
if ((octet4 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 123
return UNICODE_BOGUS_CHAR_VALUE;
+ − 124
+ − 125
*_str += 3; /* skip to next possible start of codepoint. */
+ − 126
retval = ( ((octet << 18)) | ((octet2 - 128) << 12) |
+ − 127
((octet3 - 128) << 6) | ((octet4 - 128)) );
+ − 128
if ((retval >= 0x10000) && (retval <= 0x10FFFF))
+ − 129
return retval;
+ − 130
} /* else if */
+ − 131
+ − 132
/*
+ − 133
* Five and six octet sequences became illegal in rfc3629.
+ − 134
* We throw the codepoint away, but parse them to make sure we move
+ − 135
* ahead the right number of bytes and don't overflow the buffer.
+ − 136
*/
+ − 137
+ − 138
else if (octet < 252) /* five octets */
+ − 139
{
+ − 140
(*_str)++; /* advance at least one byte in case of an error */
+ − 141
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 142
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 143
return UNICODE_BOGUS_CHAR_VALUE;
+ − 144
+ − 145
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 146
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 147
return UNICODE_BOGUS_CHAR_VALUE;
+ − 148
+ − 149
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 150
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 151
return UNICODE_BOGUS_CHAR_VALUE;
+ − 152
+ − 153
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 154
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 155
return UNICODE_BOGUS_CHAR_VALUE;
+ − 156
+ − 157
*_str += 4; /* skip to next possible start of codepoint. */
+ − 158
return UNICODE_BOGUS_CHAR_VALUE;
+ − 159
} /* else if */
+ − 160
+ − 161
else /* six octets */
+ − 162
{
+ − 163
(*_str)++; /* advance at least one byte in case of an error */
+ − 164
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 165
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 166
return UNICODE_BOGUS_CHAR_VALUE;
+ − 167
+ − 168
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 169
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 170
return UNICODE_BOGUS_CHAR_VALUE;
+ − 171
+ − 172
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 173
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 174
return UNICODE_BOGUS_CHAR_VALUE;
+ − 175
+ − 176
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 177
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 178
return UNICODE_BOGUS_CHAR_VALUE;
+ − 179
+ − 180
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ − 181
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ − 182
return UNICODE_BOGUS_CHAR_VALUE;
+ − 183
+ − 184
*_str += 6; /* skip to next possible start of codepoint. */
+ − 185
return UNICODE_BOGUS_CHAR_VALUE;
+ − 186
} /* else if */
+ − 187
+ − 188
return UNICODE_BOGUS_CHAR_VALUE;
+ − 189
} /* utf8codepoint */
+ − 190
+ − 191
+ − 192
void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
+ − 193
{
+ − 194
len -= sizeof (PHYSFS_uint32); /* save room for null char. */
+ − 195
while (len >= sizeof (PHYSFS_uint32))
+ − 196
{
+ − 197
PHYSFS_uint32 cp = utf8codepoint(&src);
+ − 198
if (cp == 0)
+ − 199
break;
+ − 200
else if (cp == UNICODE_BOGUS_CHAR_VALUE)
+ − 201
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ − 202
*(dst++) = cp;
+ − 203
len -= sizeof (PHYSFS_uint32);
+ − 204
} /* while */
+ − 205
+ − 206
*dst = 0;
+ − 207
} /* PHYSFS_utf8ToUcs4 */
+ − 208
+ − 209
+ − 210
void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
+ − 211
{
+ − 212
len -= sizeof (PHYSFS_uint16); /* save room for null char. */
+ − 213
while (len >= sizeof (PHYSFS_uint16))
+ − 214
{
+ − 215
PHYSFS_uint32 cp = utf8codepoint(&src);
+ − 216
if (cp == 0)
+ − 217
break;
+ − 218
else if (cp == UNICODE_BOGUS_CHAR_VALUE)
+ − 219
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ − 220
+ − 221
if (cp > 0xFFFF) /* UTF-16 surrogates (bogus chars in UCS-2) */
+ − 222
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ − 223
+ − 224
*(dst++) = cp;
+ − 225
len -= sizeof (PHYSFS_uint16);
+ − 226
} /* while */
+ − 227
+ − 228
*dst = 0;
+ − 229
} /* PHYSFS_utf8ToUcs2 */
+ − 230
+ − 231
+ − 232
void PHYSFS_utf8ToUtf16(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
+ − 233
{
+ − 234
len -= sizeof (PHYSFS_uint16); /* save room for null char. */
+ − 235
while (len >= sizeof (PHYSFS_uint16))
+ − 236
{
+ − 237
PHYSFS_uint32 cp = utf8codepoint(&src);
+ − 238
if (cp == 0)
+ − 239
break;
+ − 240
else if (cp == UNICODE_BOGUS_CHAR_VALUE)
+ − 241
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ − 242
+ − 243
if (cp > 0xFFFF) /* encode as surrogate pair */
+ − 244
{
+ − 245
if (len < (sizeof (PHYSFS_uint16) * 2))
+ − 246
break; /* not enough room for the pair, stop now. */
+ − 247
+ − 248
cp -= 0x10000; /* Make this a 20-bit value */
+ − 249
+ − 250
*(dst++) = 0xD800 + ((cp >> 10) & 0x3FF);
+ − 251
len -= sizeof (PHYSFS_uint16);
+ − 252
+ − 253
cp = 0xDC00 + (cp & 0x3FF);
+ − 254
} /* if */
+ − 255
+ − 256
*(dst++) = cp;
+ − 257
len -= sizeof (PHYSFS_uint16);
+ − 258
} /* while */
+ − 259
+ − 260
*dst = 0;
+ − 261
} /* PHYSFS_utf8ToUtf16 */
+ − 262
+ − 263
static void utf8fromcodepoint(PHYSFS_uint32 cp, char **_dst, PHYSFS_uint64 *_len)
+ − 264
{
+ − 265
char *dst = *_dst;
+ − 266
PHYSFS_uint64 len = *_len;
+ − 267
+ − 268
if (len == 0)
+ − 269
return;
+ − 270
+ − 271
if (cp > 0x10FFFF)
+ − 272
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ − 273
else if ((cp == 0xFFFE) || (cp == 0xFFFF)) /* illegal values. */
+ − 274
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ − 275
else
+ − 276
{
+ − 277
/* There are seven "UTF-16 surrogates" that are illegal in UTF-8. */
+ − 278
switch (cp)
+ − 279
{
+ − 280
case 0xD800:
+ − 281
case 0xDB7F:
+ − 282
case 0xDB80:
+ − 283
case 0xDBFF:
+ − 284
case 0xDC00:
+ − 285
case 0xDF80:
+ − 286
case 0xDFFF:
+ − 287
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ − 288
} /* switch */
+ − 289
} /* else */
+ − 290
+ − 291
/* Do the encoding... */
+ − 292
if (cp < 0x80)
+ − 293
{
+ − 294
*(dst++) = (char) cp;
+ − 295
len--;
+ − 296
} /* if */
+ − 297
+ − 298
else if (cp < 0x800)
+ − 299
{
+ − 300
if (len < 2)
+ − 301
len = 0;
+ − 302
else
+ − 303
{
+ − 304
*(dst++) = (char) ((cp >> 6) | 128 | 64);
+ − 305
*(dst++) = (char) (cp & 0x3F) | 128;
+ − 306
len -= 2;
+ − 307
} /* else */
+ − 308
} /* else if */
+ − 309
+ − 310
else if (cp < 0x10000)
+ − 311
{
+ − 312
if (len < 3)
+ − 313
len = 0;
+ − 314
else
+ − 315
{
+ − 316
*(dst++) = (char) ((cp >> 12) | 128 | 64 | 32);
+ − 317
*(dst++) = (char) ((cp >> 6) & 0x3F) | 128;
+ − 318
*(dst++) = (char) (cp & 0x3F) | 128;
+ − 319
len -= 3;
+ − 320
} /* else */
+ − 321
} /* else if */
+ − 322
+ − 323
else
+ − 324
{
+ − 325
if (len < 4)
+ − 326
len = 0;
+ − 327
else
+ − 328
{
+ − 329
*(dst++) = (char) ((cp >> 18) | 128 | 64 | 32 | 16);
+ − 330
*(dst++) = (char) ((cp >> 12) & 0x3F) | 128;
+ − 331
*(dst++) = (char) ((cp >> 6) & 0x3F) | 128;
+ − 332
*(dst++) = (char) (cp & 0x3F) | 128;
+ − 333
len -= 4;
+ − 334
} /* else if */
+ − 335
} /* else */
+ − 336
+ − 337
*_dst = dst;
+ − 338
*_len = len;
+ − 339
} /* utf8fromcodepoint */
+ − 340
+ − 341
#define UTF8FROMTYPE(typ, src, dst, len) \
+ − 342
if (len == 0) return; \
+ − 343
len--; \
+ − 344
while (len) \
+ − 345
{ \
+ − 346
const PHYSFS_uint32 cp = (PHYSFS_uint32) ((typ) (*(src++))); \
+ − 347
if (cp == 0) break; \
+ − 348
utf8fromcodepoint(cp, &dst, &len); \
+ − 349
} \
+ − 350
*dst = '\0'; \
+ − 351
+ − 352
void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst, PHYSFS_uint64 len)
+ − 353
{
+ − 354
UTF8FROMTYPE(PHYSFS_uint32, src, dst, len);
+ − 355
} /* PHYSFS_utf8FromUcs4 */
+ − 356
+ − 357
void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
+ − 358
{
+ − 359
UTF8FROMTYPE(PHYSFS_uint64, src, dst, len);
+ − 360
} /* PHYSFS_utf8FromUcs2 */
+ − 361
+ − 362
/* latin1 maps to unicode codepoints directly, we just utf-8 encode it. */
+ − 363
void PHYSFS_utf8FromLatin1(const char *src, char *dst, PHYSFS_uint64 len)
+ − 364
{
+ − 365
UTF8FROMTYPE(PHYSFS_uint8, src, dst, len);
+ − 366
} /* PHYSFS_utf8FromLatin1 */
+ − 367
+ − 368
#undef UTF8FROMTYPE
+ − 369
+ − 370
+ − 371
void PHYSFS_utf8FromUtf16(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
+ − 372
{
+ − 373
if (len == 0)
+ − 374
return;
+ − 375
+ − 376
len--;
+ − 377
while (len)
+ − 378
{
+ − 379
PHYSFS_uint32 cp = (PHYSFS_uint32) *(src++);
+ − 380
if (cp == 0)
+ − 381
break;
+ − 382
+ − 383
/* Orphaned second half of surrogate pair? */
+ − 384
if ((cp >= 0xDC00) && (cp <= 0xDFFF))
+ − 385
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ − 386
else if ((cp >= 0xD800) && (cp <= 0xDBFF)) /* start surrogate pair! */
+ − 387
{
+ − 388
const PHYSFS_uint32 pair = (PHYSFS_uint32) *src;
+ − 389
if ((pair < 0xDC00) || (pair > 0xDFFF))
+ − 390
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ − 391
else
+ − 392
{
+ − 393
src++; /* eat the other surrogate. */
+ − 394
cp = (((cp - 0xD800) << 10) | (pair - 0xDC00));
+ − 395
} /* else */
+ − 396
} /* else if */
+ − 397
+ − 398
utf8fromcodepoint(cp, &dst, &len);
+ − 399
} /* while */
+ − 400
+ − 401
*dst = '\0';
+ − 402
} /* PHYSFS_utf8FromUtf16 */
+ − 403
+ − 404
+ − 405
typedef struct CaseFoldMapping
+ − 406
{
+ − 407
PHYSFS_uint32 from;
+ − 408
PHYSFS_uint32 to0;
+ − 409
PHYSFS_uint32 to1;
+ − 410
PHYSFS_uint32 to2;
+ − 411
} CaseFoldMapping;
+ − 412
+ − 413
typedef struct CaseFoldHashBucket
+ − 414
{
+ − 415
const PHYSFS_uint8 count;
+ − 416
const CaseFoldMapping *list;
+ − 417
} CaseFoldHashBucket;
+ − 418
+ − 419
#include "physfs_casefolding.h"
+ − 420
+ − 421
static void locate_case_fold_mapping(const PHYSFS_uint32 from,
+ − 422
PHYSFS_uint32 *to)
+ − 423
{
+ − 424
PHYSFS_uint32 i;
+ − 425
const PHYSFS_uint8 hashed = ((from ^ (from >> 8)) & 0xFF);
+ − 426
const CaseFoldHashBucket *bucket = &case_fold_hash[hashed];
+ − 427
const CaseFoldMapping *mapping = bucket->list;
+ − 428
+ − 429
for (i = 0; i < bucket->count; i++, mapping++)
+ − 430
{
+ − 431
if (mapping->from == from)
+ − 432
{
+ − 433
to[0] = mapping->to0;
+ − 434
to[1] = mapping->to1;
+ − 435
to[2] = mapping->to2;
+ − 436
return;
+ − 437
} /* if */
+ − 438
} /* for */
+ − 439
+ − 440
/* Not found...there's no remapping for this codepoint. */
+ − 441
to[0] = from;
+ − 442
to[1] = 0;
+ − 443
to[2] = 0;
+ − 444
} /* locate_case_fold_mapping */
+ − 445
+ − 446
+ − 447
static int utf8codepointcmp(const PHYSFS_uint32 cp1, const PHYSFS_uint32 cp2)
+ − 448
{
+ − 449
PHYSFS_uint32 folded1[3], folded2[3];
+ − 450
locate_case_fold_mapping(cp1, folded1);
+ − 451
locate_case_fold_mapping(cp2, folded2);
+ − 452
return ( (folded1[0] == folded2[0]) &&
+ − 453
(folded1[1] == folded2[1]) &&
+ − 454
(folded1[2] == folded2[2]) );
+ − 455
} /* utf8codepointcmp */
+ − 456
+ − 457
+ − 458
int __PHYSFS_utf8stricmp(const char *str1, const char *str2)
+ − 459
{
+ − 460
while (1)
+ − 461
{
+ − 462
const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
+ − 463
const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
+ − 464
if (!utf8codepointcmp(cp1, cp2)) break;
+ − 465
if (cp1 == 0) return 1;
+ − 466
} /* while */
+ − 467
+ − 468
return 0;
+ − 469
} /* __PHYSFS_utf8stricmp */
+ − 470
+ − 471
+ − 472
int __PHYSFS_utf8strnicmp(const char *str1, const char *str2, PHYSFS_uint32 n)
+ − 473
{
+ − 474
while (n > 0)
+ − 475
{
+ − 476
const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
+ − 477
const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
+ − 478
if (!utf8codepointcmp(cp1, cp2)) return 0;
+ − 479
if (cp1 == 0) return 1;
+ − 480
n--;
+ − 481
} /* while */
+ − 482
+ − 483
return 1; /* matched to n chars. */
+ − 484
} /* __PHYSFS_utf8strnicmp */
+ − 485
+ − 486
+ − 487
int __PHYSFS_stricmpASCII(const char *str1, const char *str2)
+ − 488
{
+ − 489
while (1)
+ − 490
{
+ − 491
const char ch1 = *(str1++);
+ − 492
const char ch2 = *(str2++);
+ − 493
const char cp1 = ((ch1 >= 'A') && (ch1 <= 'Z')) ? (ch1+32) : ch1;
+ − 494
const char cp2 = ((ch2 >= 'A') && (ch2 <= 'Z')) ? (ch2+32) : ch2;
+ − 495
if (cp1 < cp2)
+ − 496
return -1;
+ − 497
else if (cp1 > cp2)
+ − 498
return 1;
+ − 499
else if (cp1 == 0) /* they're both null chars? */
+ − 500
break;
+ − 501
} /* while */
+ − 502
+ − 503
return 0;
+ − 504
} /* __PHYSFS_stricmpASCII */
+ − 505
+ − 506
+ − 507
int __PHYSFS_strnicmpASCII(const char *str1, const char *str2, PHYSFS_uint32 n)
+ − 508
{
+ − 509
while (n-- > 0)
+ − 510
{
+ − 511
const char ch1 = *(str1++);
+ − 512
const char ch2 = *(str2++);
+ − 513
const char cp1 = ((ch1 >= 'A') && (ch1 <= 'Z')) ? (ch1+32) : ch1;
+ − 514
const char cp2 = ((ch2 >= 'A') && (ch2 <= 'Z')) ? (ch2+32) : ch2;
+ − 515
if (cp1 < cp2)
+ − 516
return -1;
+ − 517
else if (cp1 > cp2)
+ − 518
return 1;
+ − 519
else if (cp1 == 0) /* they're both null chars? */
+ − 520
return 0;
+ − 521
} /* while */
+ − 522
+ − 523
return 0;
+ − 524
} /* __PHYSFS_strnicmpASCII */
+ − 525
+ − 526
+ − 527
/* end of physfs_unicode.c ... */
+ − 528