Style change for strnatcmp

This commit is contained in:
o9000 2016-02-26 11:08:20 +01:00
parent 7c70ae365e
commit 1d28475a0c
2 changed files with 48 additions and 63 deletions

View file

@ -36,37 +36,21 @@
#include "strnatcmp.h" #include "strnatcmp.h"
/* These are defined as macros to make it easier to adapt this code to // Compare two right-aligned numbers:
* different characters types or comparison functions. */ // The longest run of digits wins. That aside, the greatest
static inline int nat_isdigit(nat_char a) // value wins, but we can't know that it will until we've scanned
{ // both numbers to know that they have the same magnitude, so we
return isdigit((unsigned char)a); // remember it in BIAS.
} static int compare_right(char const *a, char const *b)
static inline int nat_isspace(nat_char a)
{
return isspace((unsigned char)a);
}
static inline nat_char nat_toupper(nat_char a)
{
return toupper((unsigned char)a);
}
static int compare_right(nat_char const *a, nat_char const *b)
{ {
int bias = 0; int bias = 0;
/* The longest run of digits wins. That aside, the greatest
* value wins, but we can't know that it will until we've scanned
* both numbers to know that they have the same magnitude, so we
* remember it in BIAS. */
for (;; a++, b++) { for (;; a++, b++) {
if (!nat_isdigit(*a) && !nat_isdigit(*b)) if (!isdigit(*a) && !isdigit(*b))
return bias; return bias;
else if (!nat_isdigit(*a)) else if (!isdigit(*a))
return -1; return -1;
else if (!nat_isdigit(*b)) else if (!isdigit(*b))
return +1; return +1;
else if (*a < *b) { else if (*a < *b) {
if (!bias) if (!bias)
@ -81,15 +65,16 @@ static int compare_right(nat_char const *a, nat_char const *b)
return 0; return 0;
} }
static int compare_left(nat_char const *a, nat_char const *b) // Compare two left-aligned numbers:
// The first to have a different value wins.
static int compare_left(char const *a, char const *b)
{ {
/* Compare two left-aligned numbers: the first to have a different value wins. */
for (;; a++, b++) { for (;; a++, b++) {
if (!nat_isdigit(*a) && !nat_isdigit(*b)) if (!isdigit(*a) && !isdigit(*b))
return 0; return 0;
else if (!nat_isdigit(*a)) else if (!isdigit(*a))
return -1; return -1;
else if (!nat_isdigit(*b)) else if (!isdigit(*b))
return +1; return +1;
else if (*a < *b) else if (*a < *b)
return -1; return -1;
@ -100,46 +85,50 @@ static int compare_left(nat_char const *a, nat_char const *b)
return 0; return 0;
} }
static int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case) static int strnatcmp0(char const *a, char const *b, int ignore_case)
{ {
int ai, bi;
nat_char ca, cb;
int fractional, result;
assert(a && b); assert(a && b);
int ai, bi;
ai = bi = 0; ai = bi = 0;
while (1) { while (1) {
ca = a[ai]; char ca = a[ai];
cb = b[bi]; char cb = b[bi];
/* skip over leading spaces or zeros */ // Skip over leading spaces
while (nat_isspace(ca)) while (isspace(ca)) {
ca = a[++ai]; ai++;
ca = a[ai];
}
while (nat_isspace(cb)) while (isspace(cb)) {
cb = b[++bi]; bi++;
cb = b[bi];
}
/* process run of digits */ // Process run of digits
if (nat_isdigit(ca) && nat_isdigit(cb)) { if (isdigit(ca) && isdigit(cb)) {
fractional = (ca == '0' || cb == '0'); int fractional = (ca == '0' || cb == '0');
if (fractional) { if (fractional) {
if ((result = compare_left(a + ai, b + bi)) != 0) int result = compare_left(a + ai, b + bi);
if (result)
return result; return result;
} else { } else {
if ((result = compare_right(a + ai, b + bi)) != 0) int result = compare_right(a + ai, b + bi);
if (result)
return result; return result;
} }
} }
if (!ca && !cb) { if (!ca && !cb) {
/* The strings compare the same. Perhaps the caller will want to call strcmp to break the tie. */ // The strings compare the same. Perhaps the caller will want to call strcmp to break the tie.
return 0; return 0;
} }
if (fold_case) { if (ignore_case) {
ca = nat_toupper(ca); ca = toupper(ca);
cb = nat_toupper(cb); cb = toupper(cb);
} }
if (ca < cb) if (ca < cb)
@ -147,18 +136,17 @@ static int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
else if (ca > cb) else if (ca > cb)
return +1; return +1;
++ai; ai++;
++bi; bi++;
} }
} }
int strnatcmp(nat_char const *a, nat_char const *b) int strnatcmp(char const *a, char const *b)
{ {
return strnatcmp0(a, b, 0); return strnatcmp0(a, b, 0);
} }
/* Compare, recognizing numeric string and ignoring case. */ int strnatcasecmp(char const *a, char const *b)
int strnatcasecmp(nat_char const *a, nat_char const *b)
{ {
return strnatcmp0(a, b, 1); return strnatcmp0(a, b, 1);
} }

View file

@ -20,11 +20,8 @@
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
/* CUSTOMIZATION SECTION // Compare, recognizing numeric strings. Case sensitive.
* int strnatcmp(char const *a, char const *b);
* You can change this typedef, but must then also change the inline
* functions in strnatcmp.c */
typedef char nat_char;
int strnatcmp(nat_char const *a, nat_char const *b); // Compare, recognizing numeric strings. Case insensitive.
int strnatcasecmp(nat_char const *a, nat_char const *b); int strnatcasecmp(char const *a, char const *b);