summaryrefslogtreecommitdiff
path: root/sntp/libpkgver/colcomp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sntp/libpkgver/colcomp.c')
-rw-r--r--sntp/libpkgver/colcomp.c135
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