colcomp.c revision 1.1.1.4
1/* $NetBSD: colcomp.c,v 1.1.1.4 2016/01/08 21:21:33 christos 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@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 38int 39colcomp (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 96static int qcmp( const void *fi1, 97 const void *fi2) 98{ 99 return colcomp(*(char**)fi1, *(char**)fi2); 100} 101 102int 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