int strnatcmp(const TCHAR *psz1, const TCHAR *psz2) { int ai, bi; TCHAR ca, cb; int fractional, result; __try{ TCHAR a [MAX_PATH]; TCHAR b [MAX_PATH]; memset(a, 0, MAX_PATH); memset(b, 0, MAX_PATH); _tcscpy_s(a, MAX_PATH, psz1); _tcscpy_s(b, MAX_PATH, psz2); _tcslwr_s(a, MAX_PATH); _tcslwr_s(b, MAX_PATH); ai = bi = 0; while (1) { ca = a[ai]; cb = b[bi]; /* skip over leading spaces or zeros */ while (_is_meaningless_char(ca)) ca = a[++ai]; while (_is_meaningless_char(cb)) cb = b[++bi]; /* process run of digits */ if (_istdigit(ca) && _istdigit(cb)) { fractional = (ca == '0' || cb == '0'); if (fractional) { if ((result = compare_left(a + ai, b + bi)) != 0) return result; } else { if ((result = compare_right(a + ai, b + bi)) != 0) return result; } } if (!ca && !cb) { /* The strings compare the same. Perhaps the caller will want to call strcmp to break the tie. */ return 0; } if (ca < cb) return -1; else if (ca > cb) return +1; ++ai; ++bi; } }__except(EXCEPTION_EXECUTE_HANDLER){} return 0; }
int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case) { int ai, bi; nat_char ca, cb; int fractional, result; assert(a && b); ai = bi = 0; while (1) { ca = a[ai]; cb = b[bi]; /* skip over leading spaces or zeros */ while (nat_isspace(ca)) ca = a[++ai]; while (nat_isspace(cb)) cb = b[++bi]; /* process run of digits */ if (nat_isdigit(ca) && nat_isdigit(cb)) { fractional = (ca == '0' || cb == '0'); if (fractional) { if ((result = compare_left(a+ai, b+bi)) != 0) return result; } else { if ((result = compare_right(a+ai, b+bi)) != 0) return result; } } if (!ca && !cb) { /* The strings compare the same. Perhaps the caller will want to call strcmp to break the tie. */ return 0; } if (fold_case) { ca = nat_toupper(ca); cb = nat_toupper(cb); } if (ca < cb) return -1; else if (ca > cb) return +1; ++ai; ++bi; } }
static int strnatcmp0(char const *a, char const *b, int fold_case) { int ai, bi; int ca, cb; int fractional, result; assert(a && b); ai = bi = 0; while (1) { ca = to_int(a[ai]); cb = to_int(b[bi]); /* process run of digits */ if (nat_isdigit(ca) && nat_isdigit(cb)) { fractional = (ca == '0' || cb == '0'); if (fractional) { if ((result = compare_left(a+ai, b+bi)) != 0) return result; } else { if ((result = compare_right(a+ai, b+bi)) != 0) return result; } } if (!ca && !cb) { /* The strings compare the same. Call str[case]cmp() to ensure consistent results. */ if(fold_case) return strcasecmp(a,b); else return strcmp(a,b); } if (fold_case) { ca = nat_unify_case(ca); cb = nat_unify_case(cb); } if (ca < cb) return -1; else if (ca > cb) return +1; ++ai; ++bi; } }
PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case) { char ca, cb; char const *ap, *bp; char const *aend = a + a_len, *bend = b + b_len; int fractional, result; if (a_len == 0 || b_len == 0) return a_len - b_len; ap = a; bp = b; while (1) { ca = *ap; cb = *bp; /* skip over leading spaces or zeros */ while (isspace((int)ca)) ca = *++ap; while (isspace((int)cb)) cb = *++bp; /* process run of digits */ if (isdigit((int)ca) && isdigit((int)cb)) { fractional = (ca == '0' || cb == '0'); if (fractional) result = compare_left(&ap, aend, &bp, bend); else result = compare_right(&ap, aend, &bp, bend); if (result != 0) return result; else if (ap == aend && bp == bend) /* End of the strings. Let caller sort them out. */ return 0; else { /* Keep on comparing from the current point. */ ca = *ap; cb = *bp; } } if (fold_case) { ca = toupper(ca); cb = toupper(cb); } if (ca < cb) return -1; else if (ca > cb) return +1; ++ap; ++bp; if (ap == aend && bp == bend) /* The strings compare the same. Perhaps the caller will want to call strcmp to break the tie. */ return 0; else if (ap == aend) return -1; else if (bp == bend) return 1; } }
/* {{{ strnatcmp_ex */ PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case) { unsigned char ca, cb; char const *ap, *bp; char const *aend = a + a_len, *bend = b + b_len; int fractional, result; short leading = 1; if (a_len == 0 || b_len == 0) { result = 0; if (a_len > b_len) { if (a_len - b_len <= INT_MAX) { result = (int)(a_len - b_len); } else { result = 1; } } else { if (b_len - a_len <= (size_t)(-INT_MIN)) { result = -(int)(b_len - a_len); } else { result = -1; } } return result; } ap = a; bp = b; while (1) { ca = *ap; cb = *bp; /* skip over leading zeros */ while (leading && ca == '0' && (ap+1 < aend) && isdigit(*(ap+1))) { ca = *++ap; } while (leading && cb == '0' && (bp+1 < bend) && isdigit(*(bp+1))) { cb = *++bp; } leading = 0; /* Skip consecutive whitespace */ while (isspace((int)(unsigned char)ca)) { ca = *++ap; } while (isspace((int)(unsigned char)cb)) { cb = *++bp; } /* process run of digits */ if (isdigit((int)(unsigned char)ca) && isdigit((int)(unsigned char)cb)) { fractional = (ca == '0' || cb == '0'); if (fractional) result = compare_left(&ap, aend, &bp, bend); else result = compare_right(&ap, aend, &bp, bend); if (result != 0) return result; else if (ap == aend && bp == bend) /* End of the strings. Let caller sort them out. */ return 0; else { /* Keep on comparing from the current point. */ ca = *ap; cb = *bp; } } if (fold_case) { ca = toupper((int)(unsigned char)ca); cb = toupper((int)(unsigned char)cb); } if (ca < cb) return -1; else if (ca > cb) return +1; ++ap; ++bp; if (ap >= aend && bp >= bend) /* The strings compare the same. Perhaps the caller will want to call strcmp to break the tie. */ return 0; else if (ap >= aend) return -1; else if (bp >= bend) return 1; } }