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