home *** CD-ROM | disk | FTP | other *** search
- /*
- * A quicksort routine; nothing special. Only works on machines
- * which store the most significant byte of a longword in the
- * first byte, and so on.
- */
- #include "stdio.h"
- char **lineptrs ;
- long numlines ;
- long lineptrsize ;
- char inbuf[255] ;
- char **ssmin[25], **ssmax[25] ;
- int stval ;
- void *lmalloc() ;
- #define MEMCHUNK 4096
- #define swap(a, b) {t= a;a= b;b= t;}
- char *tbuf ;
- int bytesleft ;
- int reverse ;
- char *saveit(s)
- register char *s ;
- {
- int len = (strlen(s) + (2*sizeof(long)-1)) & ~(sizeof(long)-1) ;
- register char *p ;
-
- if (len > bytesleft) {
- tbuf = (char *)lmalloc((long)MEMCHUNK) ;
- if (tbuf == NULL)
- error("! couldn't allocate memory") ;
- bytesleft = MEMCHUNK ;
- }
- p = tbuf ;
- while (*p++ = *s++) ;
- s = tbuf ;
- tbuf += len ;
- while (p < tbuf)
- *p++ = 0 ;
- bytesleft -= len ;
- return(s) ;
- }
- long strlcmp(a, b)
- register long *a, *b ;
- {
- while (*a == *b && *a) {
- a++ ;
- b++ ;
- }
- return(*b - *a) ;
- }
- error(s)
- char *s ;
- {
- fputs("sort: ", stdout) ;
- puts(s) ;
- if (*s == '!')
- exit(1) ;
- }
- getlines() {
- register int c ;
- register char *p ;
- register long i ;
- char **olineptrs ;
-
- lineptrsize = 0 ;
- numlines = 0 ;
- while (1) {
- p = inbuf ;
- while ((c=getchar())!=EOF && c != 10) {
- *p++ = c ;
- if (p > inbuf + 250)
- error("! input line too long") ;
- }
- *p = 0 ;
- if (c==EOF && p==inbuf)
- break ;
- p = saveit(inbuf) ;
- if (numlines >= lineptrsize) {
- olineptrs = lineptrs ;
- lineptrsize = lineptrsize + (MEMCHUNK/sizeof(char *)) ;
- lineptrs = (char **)lmalloc((long)sizeof(char *)*lineptrsize) ;
- if (lineptrs == NULL)
- error("! couldn't allocate memory") ;
- for (i=0; i<lineptrsize-MEMCHUNK/sizeof(char *); i++)
- lineptrs[i] = olineptrs[i] ;
- free(olineptrs) ;
- }
- lineptrs[numlines++] = p ;
- }
- }
- sortlines() {
- register char **i, **j ;
- register char *medp ;
- char **min, **max, **med ;
- register char *t ;
-
- stval = 0 ;
- min = lineptrs ;
- max = lineptrs + numlines - 1 ;
- while (1) {
- if (max < min + 3) {
- if (max > min) {
- if (strlcmp(*max, *min)<0)
- swap(*max, *min) ;
- if (max == min + 2) {
- if (strlcmp(*(min+1), *min)<0)
- swap(*(min+1),*min) ;
- if (strlcmp(*max, *(min+1))<0)
- swap(*max,*(min+1)) ;
- }
- }
- if (stval > 0) {
- stval-- ;
- min = ssmin[stval] ;
- max = ssmax[stval] ;
- } else
- break ;
- } else {
- med = min + (max - min) / 2 ;
- if (strlcmp(*max, *min)<0)
- swap(*max, *min) ;
- if (strlcmp(*med, *min)<0)
- swap(*med, *min) ;
- if (strlcmp(*max, *med)<0)
- swap(*max, *med) ;
- i = min + 1 ;
- j = max - 1 ;
- medp = *med ;
- while (1) {
- if (strlcmp(medp, *i)>=0) {
- i++ ;
- if (i>j)
- break ;
- } else
- goto checkj ;
- if (strlcmp(*j, medp)>=0) {
- j-- ;
- if (i>j)
- break ;
- } else
- goto checki ;
- continue ;
- checki:
- while (strlcmp(medp, *i)>=0 && i<=j)
- i++ ;
- goto over ;
- checkj:
- while (strlcmp(*j, medp)>=0 && i<=j)
- j-- ;
- over:
- if (i < j) {
- swap(*i, *j)
- i++ ;
- j-- ;
- if (i>j)
- break ;
- } else
- break ;
- }
- if (j-min > max-i) {
- ssmin[stval] = min ;
- ssmax[stval] = j ;
- stval++ ;
- min = i ;
- } else {
- ssmin[stval] = i ;
- ssmax[stval] = max ;
- stval++ ;
- max = j ;
- }
- }
- }
- }
- putlines() {
- register long i ;
-
- if (reverse)
- for (i=0; i<numlines; i++)
- puts(lineptrs[i]) ;
- else
- for (i=numlines-1; i>=0; i--)
- puts(lineptrs[i]) ;
- }
- main(argc, argv)
- int argc ;
- char *argv[] ;
- {
- while (argc > 1 && argv[1][0]=='-') {
- argc-- ;
- argv++ ;
- switch(argv[0][1]) {
- case 'r' : reverse = 1 ;
- break ;
- default : break ;
- }
- }
- if (argc > 1) {
- argc-- ;
- argv++ ;
- if (freopen(argv[0], "r", stdin) == NULL)
- error("! couldn't open input file") ;
- }
- if (argc > 1) {
- argc-- ;
- argv++ ;
- if (freopen(argv[0], "w", stdout) == NULL)
- error("! couldn't open output file") ;
- }
- getlines() ;
- if (numlines > 1)
- sortlines() ;
- putlines() ;
- fclose(stdout) ;
- }
- _wb_parse() {}
-