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