diff options
Diffstat (limited to 'sntp/libpkgver/colcomp.c')
-rw-r--r-- | sntp/libpkgver/colcomp.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/sntp/libpkgver/colcomp.c b/sntp/libpkgver/colcomp.c new file mode 100644 index 0000000000000..4b151e3faf62b --- /dev/null +++ b/sntp/libpkgver/colcomp.c @@ -0,0 +1,135 @@ +/* COLLATE COMPARE, COMPARES DIGITS NUMERICALLY AND OTHERS IN ASCII */ + +/* + * Copyright 2001, 2015, Harlan Stenn. Used by NTP with permission. + * + * Author: Harlan Stenn <harlan@pfcs.com> + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + */ + +/* + * Expected collate order for numeric "pieces" is: + * 0 - 9 followed by + * 00 - 99 followed by + * 000 - 999 followed by + * ... + */ + +#include <ctype.h> + +/* + * Older versions of isdigit() require the argument be isascii() + */ + +#if 0 +# define MyIsDigit(x) \ + (isascii ((unsigned char) (x)) && isdigit ((unsigned char) (x))) +#else +# define MyIsDigit(x) isdigit ((unsigned char) (x)) +#endif + + +int +colcomp (s1, s2) + register char *s1; + register char *s2; +{ + int hilo = 0; /* comparison value */ + + while (*s1 && *s2) + { + if ( MyIsDigit(*s1) + && MyIsDigit(*s2)) + { + hilo = (*s1 < *s2) ? -1 : (*s1 > *s2) ? 1 : 0; + ++s1; + ++s2; + while (MyIsDigit(*s1) + && MyIsDigit(*s2)) + { + if (!hilo) + hilo = (*s1 < *s2) ? -1 : (*s1 > *s2) ? 1 : 0; + ++s1; + ++s2; + } + if (MyIsDigit(*s1)) + hilo = 1; /* s2 is first */ + if (MyIsDigit(*s2)) + hilo = -1; /* s1 is first */ + if (hilo) + break; + continue; + } + if (MyIsDigit(*s1)) + { + hilo = -1; /* s1 must come first */ + break; + } + if (MyIsDigit(*s2)) + { + hilo = 1; /* s2 must come first */ + break; + } + hilo = (*s1 < *s2) ? -1 : (*s1 > *s2) ? 1 : 0; + if (hilo) + break; + ++s1; + ++s2; + } + if (*s1 && *s2) + return (hilo); + if (hilo) + return (hilo); + return ((*s1 < *s2) ? -1 : (*s1 > *s2) ? 1 : 0); +} + +#ifdef TEST + +#include <stdlib.h> + +static int qcmp( const void *fi1, + const void *fi2) +{ + return colcomp(*(char**)fi1, *(char**)fi2); +} + +int main( int argc, char *argv[], char *environ[]) { + void *base; + size_t nmemb = 0; + size_t size = sizeof(char *); + char *ca[] = { + "999", "0", "10", "1", "01", "100", "010", "99", "00", "001", "099", "9" + }; + char **cp; + int i; + + if (argc > 1) { + /* Sort use-provided list */ + } else { + base = (void *) ca; + nmemb = sizeof ca / size; + } + printf("argc is <%d>, nmemb = <%d>\n", argc, nmemb); + + printf("Before:\n"); + cp = (char **)base; + for (i = 0; i < nmemb; ++i) { + printf("%s\n", *cp++); + } + + qsort((void *)base, nmemb, size, qcmp); + + printf("After:\n"); + cp = (char **)base; + for (i = 0; i < nmemb; ++i) { + printf("%s\n", *cp++); + } + + exit(0); +} + +#endif |