Style change for strnatcmp
This commit is contained in:
parent
7c70ae365e
commit
1d28475a0c
2 changed files with 48 additions and 63 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue