]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/ntp/sntp/libpkgver/colcomp.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / ntp / sntp / libpkgver / colcomp.c
1 /* COLLATE COMPARE, COMPARES DIGITS NUMERICALLY AND OTHERS IN ASCII */
2
3 /*
4  *   Copyright 2001, 2015, Harlan Stenn.  Used by NTP with permission.
5  *
6  *   Author: Harlan Stenn <harlan@pfcs.com>
7  *
8  *   Copying and distribution of this file, with or without modification,
9  *   are permitted in any medium without royalty provided the copyright
10  *   notice and this notice are preserved. This file is offered as-is,
11  *   without any warranty.
12  */
13
14 /*
15  * Expected collate order for numeric "pieces" is:
16  * 0 - 9        followed by
17  * 00 - 99      followed by
18  * 000 - 999    followed by
19  * ...
20  */
21
22 #include <ctype.h>
23
24 /*
25  * Older versions of isdigit() require the argument be isascii()
26  */
27
28 #if 0
29 # define MyIsDigit(x)   \
30       (isascii ((unsigned char) (x)) && isdigit ((unsigned char) (x)))
31 #else
32 # define MyIsDigit(x)   isdigit ((unsigned char) (x))
33 #endif
34
35
36 int 
37 colcomp (s1, s2)
38      register char *s1;
39      register char *s2;
40 {
41   int hilo = 0;                 /* comparison value */
42
43   while (*s1 && *s2)
44     {
45       if  (  MyIsDigit(*s1)
46           && MyIsDigit(*s2))
47         {
48           hilo = (*s1 < *s2) ? -1 : (*s1 > *s2) ? 1 : 0;
49           ++s1;
50           ++s2;
51           while (MyIsDigit(*s1)
52              &&  MyIsDigit(*s2))
53             {
54               if (!hilo)
55                 hilo = (*s1 < *s2) ? -1 : (*s1 > *s2) ? 1 : 0;
56               ++s1;
57               ++s2;
58             }
59           if (MyIsDigit(*s1))
60             hilo = 1;           /* s2 is first */
61           if (MyIsDigit(*s2))
62             hilo = -1;          /* s1 is first */
63           if (hilo)
64             break;
65           continue;
66         }
67       if (MyIsDigit(*s1))
68         {
69           hilo = -1;            /* s1 must come first */
70           break;
71         }
72       if (MyIsDigit(*s2))
73         {
74           hilo = 1;             /* s2 must come first */
75           break;
76         }
77       hilo = (*s1 < *s2) ? -1 : (*s1 > *s2) ? 1 : 0;
78       if (hilo)
79         break;
80       ++s1;
81       ++s2;
82     }
83   if (*s1 && *s2)
84     return (hilo);
85   if (hilo)
86     return (hilo);
87   return ((*s1 < *s2) ? -1 : (*s1 > *s2) ? 1 : 0);
88 }
89
90 #ifdef TEST
91
92 #include <stdlib.h>
93
94 static int  qcmp(   const void      *fi1,
95                     const void      *fi2)
96 {
97     return colcomp(*(char**)fi1, *(char**)fi2);
98 }
99
100 int main( int argc, char *argv[], char *environ[]) {
101   void *base;
102   size_t nmemb = 0;
103   size_t size = sizeof(char *);
104   char *ca[] = {
105     "999", "0", "10", "1", "01", "100", "010", "99", "00", "001", "099", "9"
106   };
107   char **cp;
108   int i;
109
110   if (argc > 1) {
111     /* Sort use-provided list */
112   } else {
113     base = (void *) ca;
114     nmemb = sizeof ca / size;
115   }
116   printf("argc is <%d>, nmemb = <%d>\n", argc, nmemb);
117
118   printf("Before:\n");
119   cp = (char **)base;
120   for (i = 0; i < nmemb; ++i) {
121     printf("%s\n", *cp++);
122   }
123
124   qsort((void *)base, nmemb, size, qcmp);
125
126   printf("After:\n");
127   cp = (char **)base;
128   for (i = 0; i < nmemb; ++i) {
129     printf("%s\n", *cp++);
130   }
131
132   exit(0);
133 }
134
135 #endif