Bunch of work on Unicode...added case-folding stricmp, removed
platform-specific stricmp implementations, changed appropriate calls to an ASCII-only stricmp that ignores locale. Fixed case on UTF-8 API entry points.
This commit is contained in:
parent
52cb5bac69
commit
607d39a1d3
|
@ -2,6 +2,10 @@
|
|||
* CHANGELOG.
|
||||
*/
|
||||
|
||||
03152007 - Bunch of work on Unicode...added case-folding stricmp, removed
|
||||
platform-specific stricmp implementations, changed appropriate
|
||||
calls to an ASCII-only stricmp that ignores locale. Fixed case on
|
||||
UTF-8 API entry points.
|
||||
03142007 - Dropped classic Mac OS support. It's just too hard to find a working
|
||||
Mac OS 9 install and reasonable development tools, so it's not
|
||||
worth it. If you still target OS 8 or 9, please use PhysicsFS 1.0.
|
||||
|
|
1
TODO.txt
1
TODO.txt
|
@ -9,7 +9,6 @@ UNICODE:
|
|||
systems, otherwise try to use a sane codepage.
|
||||
- OS/2: Codepages. No full Unicode in the filesystem, but we can probably make
|
||||
a conversion effort.
|
||||
- Everywhere: Move stricmp() out of platform layer and make it grok UTF-8.
|
||||
|
||||
|
||||
Stuff:
|
||||
|
|
|
@ -229,7 +229,7 @@ static int HOG_isArchive(const char *filename, int forWriting)
|
|||
static int hog_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||
{
|
||||
HOGentry *a = (HOGentry *) _a;
|
||||
return(__PHYSFS_platformStricmp(a[one].name, a[two].name));
|
||||
return(__PHYSFS_stricmpASCII(a[one].name, a[two].name));
|
||||
} /* hog_entry_cmp */
|
||||
|
||||
|
||||
|
@ -367,7 +367,7 @@ static HOGentry *hog_find_entry(HOGinfo *info, const char *name)
|
|||
while (lo <= hi)
|
||||
{
|
||||
middle = lo + ((hi - lo) / 2);
|
||||
rc = __PHYSFS_platformStricmp(name, a[middle].name);
|
||||
rc = __PHYSFS_stricmpASCII(name, a[middle].name);
|
||||
if (rc == 0) /* found it! */
|
||||
return(&a[middle]);
|
||||
else if (rc > 0)
|
||||
|
|
|
@ -324,7 +324,7 @@ static MVLentry *mvl_find_entry(MVLinfo *info, const char *name)
|
|||
while (lo <= hi)
|
||||
{
|
||||
middle = lo + ((hi - lo) / 2);
|
||||
rc = __PHYSFS_platformStricmp(name, a[middle].name);
|
||||
rc = __PHYSFS_stricmpASCII(name, a[middle].name);
|
||||
if (rc == 0) /* found it! */
|
||||
return(&a[middle]);
|
||||
else if (rc > 0)
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
#include "physfs_internal.h"
|
||||
|
||||
#if 1 /* Make this case insensitive? */
|
||||
#define QPAK_strcmp(x, y) __PHYSFS_platformStricmp(x, y)
|
||||
#define QPAK_strncmp(x, y, z) __PHYSFS_platformStrnicmp(x, y, z)
|
||||
#define QPAK_strcmp(x, y) __PHYSFS_stricmpASCII(x, y)
|
||||
#define QPAK_strncmp(x, y, z) __PHYSFS_strnicmpASCII(x, y, z)
|
||||
#else
|
||||
#define QPAK_strcmp(x, y) strcmp(x, y)
|
||||
#define QPAK_strncmp(x, y, z) strncmp(x, y, z)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,6 +28,7 @@
|
|||
*/
|
||||
|
||||
/* I'm not screwing around with stricmp vs. strcasecmp... */
|
||||
/* !!! FIXME: this will NOT work with UTF-8 strings in physfs2.0 */
|
||||
static int caseInsensitiveStringCompare(const char *x, const char *y)
|
||||
{
|
||||
int ux, uy;
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/perl -w
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
print <<__EOF__;
|
||||
/*
|
||||
* This file is part of PhysicsFS (http://icculus.org/physfs/)
|
||||
*
|
||||
* This data generated by physfs/extras/makecasefoldhashtable.pl ...
|
||||
* Do not manually edit this file!
|
||||
*
|
||||
* Please see the file LICENSE.txt in the source's root directory.
|
||||
*/
|
||||
|
||||
#ifndef __PHYSICSFS_INTERNAL__
|
||||
#error Do not include this header from your applications.
|
||||
#endif
|
||||
|
||||
__EOF__
|
||||
|
||||
|
||||
my @foldPairs;
|
||||
|
||||
for (my $i = 0; $i < 256; $i++) {
|
||||
$foldPairs[$i] = '';
|
||||
}
|
||||
|
||||
open(FH,'<','casefolding.txt') or die("failed to open casefolding.txt: $!\n");
|
||||
while (<FH>) {
|
||||
chomp;
|
||||
# strip comments from textfile...
|
||||
s/\#.*\Z//;
|
||||
|
||||
# strip whitespace...
|
||||
s/\A\s+//;
|
||||
s/\s+\Z//;
|
||||
|
||||
next if not /\A([a-fA-F0-9]+)\;\s*(.)\;\s*(.+)\;/;
|
||||
my ($code, $status, $mapping) = ($1, $2, $3);
|
||||
my $hexxed = hex($code);
|
||||
my $hashed = (($hexxed ^ ($hexxed >> 8)) & 0xFF);
|
||||
#print("// code '$code' status '$status' mapping '$mapping'\n");
|
||||
#print("// hexxed '$hexxed' hashed '$hashed'\n");
|
||||
|
||||
if (($status eq 'C') or ($status eq 'F')) {
|
||||
my ($map1, $map2, $map3) = ('0000', '0000', '0000');
|
||||
$map1 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
|
||||
$map2 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
|
||||
$map3 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
|
||||
die("mapping space too small for '$code'\n") if ($mapping ne '');
|
||||
$foldPairs[$hashed] .= " { 0x$code, 0x$map1, 0x$map2, 0x$map3 },\n";
|
||||
}
|
||||
}
|
||||
close(FH);
|
||||
|
||||
for (my $i = 0; $i < 256; $i++) {
|
||||
$foldPairs[$i] =~ s/,\n\Z//;
|
||||
my $str = $foldPairs[$i];
|
||||
next if $str eq '';
|
||||
my $num = '000' . $i;
|
||||
$num =~ s/\A.*?(\d\d\d)\Z/$1/;
|
||||
my $sym = "case_fold_${num}";
|
||||
print("static const CaseFoldMapping ${sym}[] = {\n$str\n};\n\n");
|
||||
}
|
||||
|
||||
print("\nstatic const CaseFoldHashBucket case_fold_hash[256] = {\n");
|
||||
|
||||
for (my $i = 0; $i < 256; $i++) {
|
||||
my $str = $foldPairs[$i];
|
||||
if ($str eq '') {
|
||||
print(" { 0, NULL },\n");
|
||||
} else {
|
||||
my $num = '000' . $i;
|
||||
$num =~ s/\A.*?(\d\d\d)\Z/$1/;
|
||||
my $sym = "case_fold_${num}";
|
||||
print(" { __PHYSFS_ARRAYLEN($sym), $sym },\n");
|
||||
}
|
||||
}
|
||||
print("};\n\n");
|
||||
|
||||
exit 0;
|
||||
|
||||
# end of makecashfoldhashtable.pl ...
|
||||
|
6
physfs.c
6
physfs.c
|
@ -426,14 +426,14 @@ static DirHandle *openDirectory(const char *d, int forWriting)
|
|||
/* Look for archivers with matching file extensions first... */
|
||||
for (i = archivers; (*i != NULL) && (retval == NULL); i++)
|
||||
{
|
||||
if (__PHYSFS_platformStricmp(ext, (*i)->info->extension) == 0)
|
||||
if (__PHYSFS_stricmpASCII(ext, (*i)->info->extension) == 0)
|
||||
retval = tryOpenDir(*i, d, forWriting);
|
||||
} /* for */
|
||||
|
||||
/* failing an exact file extension match, try all the others... */
|
||||
for (i = archivers; (*i != NULL) && (retval == NULL); i++)
|
||||
{
|
||||
if (__PHYSFS_platformStricmp(ext, (*i)->info->extension) != 0)
|
||||
if (__PHYSFS_stricmpASCII(ext, (*i)->info->extension) != 0)
|
||||
retval = tryOpenDir(*i, d, forWriting);
|
||||
} /* for */
|
||||
} /* if */
|
||||
|
@ -1133,7 +1133,7 @@ int PHYSFS_setSaneConfig(const char *organization, const char *appName,
|
|||
if ((l > extlen) && ((*i)[l - extlen - 1] == '.'))
|
||||
{
|
||||
ext = (*i) + (l - extlen);
|
||||
if (__PHYSFS_platformStricmp(ext, archiveExt) == 0)
|
||||
if (__PHYSFS_stricmpASCII(ext, archiveExt) == 0)
|
||||
{
|
||||
const char *d = PHYSFS_getRealDir(*i);
|
||||
size_t allocsize = strlen(d) + strlen(dirsep) + l + 1;
|
||||
|
|
12
physfs.h
12
physfs.h
|
@ -2061,7 +2061,7 @@ __EXPORT__ void PHYSFS_enumerateFilesCallback(const char *dir,
|
|||
* \param dst Buffer to store converted UTF-8 string.
|
||||
* \param len Size, in bytes, of destination buffer.
|
||||
*/
|
||||
__EXPORT__ void PHYSFS_utf8fromucs4(const PHYSFS_uint32 *src, char *dst,
|
||||
__EXPORT__ void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst,
|
||||
PHYSFS_uint64 len);
|
||||
|
||||
/**
|
||||
|
@ -2083,7 +2083,7 @@ __EXPORT__ void PHYSFS_utf8fromucs4(const PHYSFS_uint32 *src, char *dst,
|
|||
* \param dst Buffer to store converted UCS-4 string.
|
||||
* \param len Size, in bytes, of destination buffer.
|
||||
*/
|
||||
__EXPORT__ void PHYSFS_utf8toucs4(const char *src, PHYSFS_uint32 *dst,
|
||||
__EXPORT__ void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst,
|
||||
PHYSFS_uint64 len);
|
||||
|
||||
/**
|
||||
|
@ -2109,7 +2109,7 @@ __EXPORT__ void PHYSFS_utf8toucs4(const char *src, PHYSFS_uint32 *dst,
|
|||
* \param dst Buffer to store converted UTF-8 string.
|
||||
* \param len Size, in bytes, of destination buffer.
|
||||
*/
|
||||
__EXPORT__ void PHYSFS_utf8fromucs2(const PHYSFS_uint16 *src, char *dst,
|
||||
__EXPORT__ void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst,
|
||||
PHYSFS_uint64 len);
|
||||
|
||||
/**
|
||||
|
@ -2135,11 +2135,11 @@ __EXPORT__ void PHYSFS_utf8fromucs2(const PHYSFS_uint16 *src, char *dst,
|
|||
* \param dst Buffer to store converted UCS-2 string.
|
||||
* \param len Size, in bytes, of destination buffer.
|
||||
*/
|
||||
__EXPORT__ void PHYSFS_utf8toucs2(const char *src, PHYSFS_uint16 *dst,
|
||||
__EXPORT__ void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst,
|
||||
PHYSFS_uint64 len);
|
||||
|
||||
/**
|
||||
* \fn void PHYSFS_utf8fromlatin1(const char *src, char *dst, PHYSFS_uint64 len)
|
||||
* \fn void PHYSFS_utf8FromLatin1(const char *src, char *dst, PHYSFS_uint64 len)
|
||||
* \brief Convert a UTF-8 string to a Latin1 string.
|
||||
*
|
||||
* Latin1 strings are 8-bits per character: a popular "high ASCII"
|
||||
|
@ -2162,7 +2162,7 @@ __EXPORT__ void PHYSFS_utf8toucs2(const char *src, PHYSFS_uint16 *dst,
|
|||
* \param dst Buffer to store converted UTF-8 string.
|
||||
* \param len Size, in bytes, of destination buffer.
|
||||
*/
|
||||
__EXPORT__ void PHYSFS_utf8fromlatin1(const char *src, char *dst,
|
||||
__EXPORT__ void PHYSFS_utf8FromLatin1(const char *src, char *dst,
|
||||
PHYSFS_uint64 len);
|
||||
|
||||
/* Everything above this line is part of the PhysicsFS 2.0 API. */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include "physfs.h"
|
||||
|
||||
#include <stdlib.h> /* make sure NULL is defined... */
|
||||
|
||||
#ifdef HAVE_ASSERT_H
|
||||
#include <assert.h>
|
||||
#elif (!defined assert)
|
||||
|
@ -1264,6 +1266,8 @@ void __PHYSFS_sort(void *entries, PHYSFS_uint32 max,
|
|||
#define GOTO_MACRO_MUTEX(e, m, g) { __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); goto g; }
|
||||
#define GOTO_IF_MACRO_MUTEX(c, e, m, g) if (c) { __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); goto g; }
|
||||
|
||||
#define __PHYSFS_ARRAYLEN(x) ( (sizeof (x)) / (sizeof (x[0])) )
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define LONGLONGLITERAL(x) x##LL
|
||||
#else
|
||||
|
@ -1282,6 +1286,39 @@ void __PHYSFS_sort(void *entries, PHYSFS_uint32 max,
|
|||
((s) > (LONGLONGLITERAL(0xFFFFFFFFFFFFFFFF) >> (64-(sizeof(size_t)*8)))) \
|
||||
)
|
||||
|
||||
/*
|
||||
* This is a strcasecmp() or stricmp() replacement that expects both strings
|
||||
* to be in UTF-8 encoding. It will do "case folding" to decide if the
|
||||
* Unicode codepoints in the strings match.
|
||||
*
|
||||
* It will report which string is "greater than" the other, but be aware that
|
||||
* this doesn't necessarily mean anything: 'a' may be "less than" 'b', but
|
||||
* a random Kanji codepoint has no meaningful alphabetically relationship to
|
||||
* a Greek Lambda, but being able to assign a reliable "value" makes sorting
|
||||
* algorithms possible, if not entirely sane. Most cases should treat the
|
||||
* return value as "equal" or "not equal".
|
||||
*/
|
||||
int __PHYSFS_utf8strcasecmp(const char *s1, const char *s2);
|
||||
|
||||
/*
|
||||
* This works like __PHYSFS_utf8strcasecmp(), but takes a character (NOT BYTE
|
||||
* COUNT) argument, like strcasencmp().
|
||||
*/
|
||||
int __PHYSFS_utf8strnicmp(const char *s1, const char *s2, PHYSFS_uint32 l);
|
||||
|
||||
/*
|
||||
* stricmp() that guarantees to only work with low ASCII. The C runtime
|
||||
* stricmp() might try to apply a locale/codepage/etc, which we don't want.
|
||||
*/
|
||||
int __PHYSFS_stricmpASCII(const char *s1, const char *s2);
|
||||
|
||||
/*
|
||||
* strnicmp() that guarantees to only work with low ASCII. The C runtime
|
||||
* strnicmp() might try to apply a locale/codepage/etc, which we don't want.
|
||||
*/
|
||||
int __PHYSFS_strnicmpASCII(const char *s1, const char *s2, PHYSFS_uint32 l);
|
||||
|
||||
|
||||
/*
|
||||
* The current allocator. Not valid before PHYSFS_init is called!
|
||||
*/
|
||||
|
@ -1516,16 +1553,6 @@ char *__PHYSFS_platformGetUserDir(void);
|
|||
*/
|
||||
PHYSFS_uint64 __PHYSFS_platformGetThreadID(void);
|
||||
|
||||
/*
|
||||
* This is a pass-through to whatever stricmp() is called on your platform.
|
||||
*/
|
||||
int __PHYSFS_platformStricmp(const char *str1, const char *str2);
|
||||
|
||||
/*
|
||||
* This is a pass-through to whatever strnicmp() is called on your platform.
|
||||
*/
|
||||
int __PHYSFS_platformStrnicmp(const char *s1, const char *s2, PHYSFS_uint32 l);
|
||||
|
||||
/*
|
||||
* Return non-zero if filename (in platform-dependent notation) exists.
|
||||
* Symlinks should NOT be followed; at this stage, we do not care what the
|
||||
|
|
145
physfs_unicode.c
145
physfs_unicode.c
|
@ -185,7 +185,8 @@ static PHYSFS_uint32 utf8codepoint(const char **_str)
|
|||
return UNICODE_BOGUS_CHAR_VALUE;
|
||||
} /* utf8codepoint */
|
||||
|
||||
void PHYSFS_utf8toucs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
|
||||
|
||||
void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
|
||||
{
|
||||
len -= sizeof (PHYSFS_uint32); /* save room for null char. */
|
||||
while (len >= sizeof (PHYSFS_uint32))
|
||||
|
@ -200,9 +201,10 @@ void PHYSFS_utf8toucs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
|
|||
} /* while */
|
||||
|
||||
*dst = 0;
|
||||
} /* PHYSFS_utf8toucs4 */
|
||||
} /* PHYSFS_utf8ToUcs4 */
|
||||
|
||||
void PHYSFS_utf8toucs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
|
||||
|
||||
void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
|
||||
{
|
||||
len -= sizeof (PHYSFS_uint16); /* save room for null char. */
|
||||
while (len >= sizeof (PHYSFS_uint16))
|
||||
|
@ -222,7 +224,7 @@ void PHYSFS_utf8toucs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
|
|||
} /* while */
|
||||
|
||||
*dst = 0;
|
||||
} /* PHYSFS_utf8toucs2 */
|
||||
} /* PHYSFS_utf8ToUcs2 */
|
||||
|
||||
static void utf8fromcodepoint(PHYSFS_uint32 cp, char **_dst, PHYSFS_uint64 *_len)
|
||||
{
|
||||
|
@ -312,23 +314,146 @@ static void utf8fromcodepoint(PHYSFS_uint32 cp, char **_dst, PHYSFS_uint64 *_len
|
|||
} \
|
||||
*dst = '\0'; \
|
||||
|
||||
void PHYSFS_utf8fromucs4(const PHYSFS_uint32 *src, char *dst, PHYSFS_uint64 len)
|
||||
void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst, PHYSFS_uint64 len)
|
||||
{
|
||||
UTF8FROMTYPE(PHYSFS_uint32, src, dst, len);
|
||||
} /* PHYSFS_utf8fromucs4 */
|
||||
} /* PHYSFS_utf8FromUcs4 */
|
||||
|
||||
void PHYSFS_utf8fromucs2(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
|
||||
void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
|
||||
{
|
||||
UTF8FROMTYPE(PHYSFS_uint64, src, dst, len);
|
||||
} /* PHYSFS_utf8fromucs4 */
|
||||
} /* PHYSFS_utf8FromUcs4 */
|
||||
|
||||
/* latin1 maps to unicode codepoints directly, we just utf-8 encode it. */
|
||||
void PHYSFS_utf8fromlatin1(const char *src, char *dst, PHYSFS_uint64 len)
|
||||
void PHYSFS_utf8FromLatin1(const char *src, char *dst, PHYSFS_uint64 len)
|
||||
{
|
||||
UTF8FROMTYPE(PHYSFS_uint8, src, dst, len);
|
||||
} /* PHYSFS_utf8fromlatin1 */
|
||||
} /* PHYSFS_utf8FromLatin1 */
|
||||
|
||||
#undef UTF8FROMTYPE
|
||||
|
||||
|
||||
typedef struct CaseFoldMapping
|
||||
{
|
||||
PHYSFS_uint32 from;
|
||||
PHYSFS_uint32 to0;
|
||||
PHYSFS_uint32 to1;
|
||||
PHYSFS_uint32 to2;
|
||||
} CaseFoldMapping;
|
||||
|
||||
typedef struct CaseFoldHashBucket
|
||||
{
|
||||
const PHYSFS_uint8 count;
|
||||
const CaseFoldMapping *list;
|
||||
} CaseFoldHashBucket;
|
||||
|
||||
#include "physfs_casefolding.h"
|
||||
|
||||
static void locate_case_fold_mapping(const PHYSFS_uint32 from,
|
||||
PHYSFS_uint32 *to)
|
||||
{
|
||||
PHYSFS_uint32 i;
|
||||
const PHYSFS_uint8 hashed = ((from ^ (from >> 8)) & 0xFF);
|
||||
const CaseFoldHashBucket *bucket = &case_fold_hash[hashed];
|
||||
const CaseFoldMapping *mapping = bucket->list;
|
||||
|
||||
for (i = 0; i < bucket->count; i++, mapping++)
|
||||
{
|
||||
if (mapping->from == from)
|
||||
{
|
||||
to[0] = mapping->to0;
|
||||
to[1] = mapping->to1;
|
||||
to[2] = mapping->to2;
|
||||
return;
|
||||
} /* if */
|
||||
} /* for */
|
||||
|
||||
/* Not found...there's no remapping for this codepoint. */
|
||||
to[0] = from;
|
||||
to[1] = 0;
|
||||
to[2] = 0;
|
||||
} /* locate_case_fold_mapping */
|
||||
|
||||
|
||||
static int utf8codepointcmp(const PHYSFS_uint32 cp1, const PHYSFS_uint32 cp2)
|
||||
{
|
||||
PHYSFS_uint32 folded1[3], folded2[3];
|
||||
locate_case_fold_mapping(cp1, folded1);
|
||||
locate_case_fold_mapping(cp2, folded2);
|
||||
return ( (folded1[0] == folded2[0]) &&
|
||||
(folded1[1] == folded2[1]) &&
|
||||
(folded1[2] == folded2[2]) );
|
||||
} /* utf8codepointcmp */
|
||||
|
||||
|
||||
int __PHYSFS_utf8strcasecmp(const char *str1, const char *str2)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
|
||||
const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
|
||||
if (!utf8codepointcmp(cp1, cp2)) return 0;
|
||||
if (cp1 == 0) return 1;
|
||||
} /* while */
|
||||
|
||||
return 0; /* shouldn't hit this. */
|
||||
} /* __PHYSFS_utf8strcasecmp */
|
||||
|
||||
|
||||
int __PHYSFS_utf8strnicmp(const char *str1, const char *str2, PHYSFS_uint32 n)
|
||||
{
|
||||
while (n > 0)
|
||||
{
|
||||
const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
|
||||
const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
|
||||
if (!utf8codepointcmp(cp1, cp2)) return 0;
|
||||
if (cp1 == 0) return 1;
|
||||
n--;
|
||||
} /* while */
|
||||
|
||||
return 1; /* matched to n chars. */
|
||||
} /* __PHYSFS_utf8strnicmp */
|
||||
|
||||
|
||||
int __PHYSFS_stricmpASCII(const char *str1, const char *str2)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
const char ch1 = *(str1++);
|
||||
const char ch2 = *(str2++);
|
||||
const char cp1 = ((ch1 >= 'A') && (ch1 <= 'Z')) ? (ch1+32) : ch1;
|
||||
const char cp2 = ((ch2 >= 'A') && (ch2 <= 'Z')) ? (ch2+32) : ch2;
|
||||
if (cp1 < cp2)
|
||||
return -1;
|
||||
else if (cp1 > cp2)
|
||||
return 1;
|
||||
else if (cp1 == 0) /* they're both null chars? */
|
||||
return 0;
|
||||
} /* while */
|
||||
|
||||
return 0; /* shouldn't hit this. */
|
||||
} /* __PHYSFS_stricmpASCII */
|
||||
|
||||
|
||||
int __PHYSFS_strnicmpASCII(const char *str1, const char *str2, PHYSFS_uint32 n)
|
||||
{
|
||||
while (n-- > 0)
|
||||
{
|
||||
const char ch1 = *(str1++);
|
||||
const char ch2 = *(str2++);
|
||||
const char cp1 = ((ch1 >= 'A') && (ch1 <= 'Z')) ? (ch1+32) : ch1;
|
||||
const char cp2 = ((ch2 >= 'A') && (ch2 <= 'Z')) ? (ch2+32) : ch2;
|
||||
if (cp1 < cp2)
|
||||
return -1;
|
||||
else if (cp1 > cp2)
|
||||
return 1;
|
||||
else if (cp1 == 0) /* they're both null chars? */
|
||||
return 0;
|
||||
} /* while */
|
||||
|
||||
return 0;
|
||||
} /* __PHYSFS_stricmpASCII */
|
||||
|
||||
|
||||
/* end of physfs_unicode.c ... */
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ static void cvt_path_to_correct_case(char *buf)
|
|||
{
|
||||
while (count == 1) /* while still entries to enumerate... */
|
||||
{
|
||||
if (__PHYSFS_platformStricmp(fb.achName, fname) == 0)
|
||||
if (__PHYSFS_stricmpASCII(fb.achName, fname) == 0)
|
||||
{
|
||||
strcpy(fname, fb.achName);
|
||||
break; /* there it is. Overwrite and stop searching. */
|
||||
|
@ -297,50 +297,6 @@ char *__PHYSFS_platformGetUserDir(void)
|
|||
} /* __PHYSFS_platformGetUserDir */
|
||||
|
||||
|
||||
int __PHYSFS_platformStricmp(const char *x, const char *y)
|
||||
{
|
||||
int ux, uy;
|
||||
|
||||
do
|
||||
{
|
||||
ux = toupper((int) *x);
|
||||
uy = toupper((int) *y);
|
||||
if (ux > uy)
|
||||
return(1);
|
||||
else if (ux < uy)
|
||||
return(-1);
|
||||
x++;
|
||||
y++;
|
||||
} while ((ux) && (uy));
|
||||
|
||||
return(0);
|
||||
} /* __PHYSFS_platformStricmp */
|
||||
|
||||
|
||||
int __PHYSFS_platformStrnicmp(const char *x, const char *y, PHYSFS_uint32 len)
|
||||
{
|
||||
int ux, uy;
|
||||
|
||||
if (!len)
|
||||
return(0);
|
||||
|
||||
do
|
||||
{
|
||||
ux = toupper((int) *x);
|
||||
uy = toupper((int) *y);
|
||||
if (ux > uy)
|
||||
return(1);
|
||||
else if (ux < uy)
|
||||
return(-1);
|
||||
x++;
|
||||
y++;
|
||||
len--;
|
||||
} while ((ux) && (uy) && (len));
|
||||
|
||||
return(0);
|
||||
} /* __PHYSFS_platformStrnicmp */
|
||||
|
||||
|
||||
int __PHYSFS_platformExists(const char *fname)
|
||||
{
|
||||
FILESTATUS3 fs;
|
||||
|
|
|
@ -164,18 +164,6 @@ PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
|
|||
} /* __PHYSFS_platformGetThreadID */
|
||||
|
||||
|
||||
int __PHYSFS_platformStricmp(const char *x, const char *y)
|
||||
{
|
||||
return(_stricmp(x, y));
|
||||
} /* __PHYSFS_platformStricmp */
|
||||
|
||||
|
||||
int __PHYSFS_platformStrnicmp(const char *x, const char *y, PHYSFS_uint32 len)
|
||||
{
|
||||
return(_strnicmp(x, y, (int) len));
|
||||
} /* __PHYSFS_platformStrnicmp */
|
||||
|
||||
|
||||
int __PHYSFS_platformExists(const char *fname)
|
||||
{
|
||||
int retval = 0;
|
||||
|
|
|
@ -120,47 +120,6 @@ char *__PHYSFS_platformGetUserDir(void)
|
|||
} /* __PHYSFS_platformGetUserDir */
|
||||
|
||||
|
||||
/* -ansi and -pedantic flags prevent use of strcasecmp() on Linux. */
|
||||
int __PHYSFS_platformStricmp(const char *x, const char *y)
|
||||
{
|
||||
int ux, uy;
|
||||
|
||||
do
|
||||
{
|
||||
ux = toupper((int) *x);
|
||||
uy = toupper((int) *y);
|
||||
if (ux != uy)
|
||||
return((ux > uy) ? 1 : -1);
|
||||
x++;
|
||||
y++;
|
||||
} while ((ux) && (uy));
|
||||
|
||||
return(0);
|
||||
} /* __PHYSFS_platformStricmp */
|
||||
|
||||
|
||||
int __PHYSFS_platformStrnicmp(const char *x, const char *y, PHYSFS_uint32 len)
|
||||
{
|
||||
int ux, uy;
|
||||
|
||||
if (!len)
|
||||
return(0);
|
||||
|
||||
do
|
||||
{
|
||||
ux = toupper((int) *x);
|
||||
uy = toupper((int) *y);
|
||||
if (ux != uy)
|
||||
return((ux > uy) ? 1 : -1);
|
||||
x++;
|
||||
y++;
|
||||
len--;
|
||||
} while ((ux) && (uy) && (len));
|
||||
|
||||
return(0);
|
||||
} /* __PHYSFS_platformStrnicmp */
|
||||
|
||||
|
||||
#if (defined __PHYSFS_NO_SYMLINKS__)
|
||||
#define doStat stat
|
||||
#else
|
||||
|
|
|
@ -59,18 +59,6 @@ PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
|
|||
} /* __PHYSFS_platformGetThreadID */
|
||||
|
||||
|
||||
int __PHYSFS_platformStricmp(const char *x, const char *y)
|
||||
{
|
||||
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
|
||||
} /* __PHYSFS_platformStricmp */
|
||||
|
||||
|
||||
int __PHYSFS_platformStrnicmp(const char *x, const char *y, PHYSFS_uint32 l)
|
||||
{
|
||||
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
|
||||
} /* __PHYSFS_platformStrnicmp */
|
||||
|
||||
|
||||
int __PHYSFS_platformExists(const char *fname)
|
||||
{
|
||||
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
|
||||
|
|
|
@ -122,7 +122,7 @@ static char *getExePath(const char *argv0)
|
|||
retval[buflen] = '\0'; /* does API always null-terminate this? */
|
||||
|
||||
/* make sure the string was not truncated. */
|
||||
if (__PHYSFS_platformStricmp(&retval[buflen - 4], ".exe") != 0)
|
||||
if (__PHYSFS_stricmpASCII(&retval[buflen - 4], ".exe") != 0)
|
||||
__PHYSFS_setError(ERR_GETMODFN_TRUNC);
|
||||
else
|
||||
{
|
||||
|
@ -324,59 +324,6 @@ PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
|
|||
} /* __PHYSFS_platformGetThreadID */
|
||||
|
||||
|
||||
/* ...make this Cygwin AND Visual C friendly... */
|
||||
int __PHYSFS_platformStricmp(const char *x, const char *y)
|
||||
{
|
||||
#if (defined _MSC_VER)
|
||||
return(stricmp(x, y));
|
||||
#else
|
||||
int ux, uy;
|
||||
|
||||
do
|
||||
{
|
||||
ux = toupper((int) *x);
|
||||
uy = toupper((int) *y);
|
||||
if (ux > uy)
|
||||
return(1);
|
||||
else if (ux < uy)
|
||||
return(-1);
|
||||
x++;
|
||||
y++;
|
||||
} while ((ux) && (uy));
|
||||
|
||||
return(0);
|
||||
#endif
|
||||
} /* __PHYSFS_platformStricmp */
|
||||
|
||||
|
||||
int __PHYSFS_platformStrnicmp(const char *x, const char *y, PHYSFS_uint32 len)
|
||||
{
|
||||
#if (defined _MSC_VER)
|
||||
return(strnicmp(x, y, (int) len));
|
||||
#else
|
||||
int ux, uy;
|
||||
|
||||
if (!len)
|
||||
return(0);
|
||||
|
||||
do
|
||||
{
|
||||
ux = toupper((int) *x);
|
||||
uy = toupper((int) *y);
|
||||
if (ux > uy)
|
||||
return(1);
|
||||
else if (ux < uy)
|
||||
return(-1);
|
||||
x++;
|
||||
y++;
|
||||
len--;
|
||||
} while ((ux) && (uy) && (len));
|
||||
|
||||
return(0);
|
||||
#endif
|
||||
} /* __PHYSFS_platformStricmp */
|
||||
|
||||
|
||||
int __PHYSFS_platformExists(const char *fname)
|
||||
{
|
||||
BAIL_IF_MACRO
|
||||
|
|
Loading…
Reference in New Issue