[net.sources] Aztec C source - sort.c

dcn@ihuxl.UUCP (Dave Newkirk) (11/14/83)

/* tail - print last part of file */

#include "stdio.h"

int lines, chars ;

main(argc, argv)
int argc ;
char *argv[] ;
{
	char *s ;
	FILE *input ;
	int count ;


	argc-- ; argv++ ;
	lines = TRUE ;
	chars = FALSE ;
	count = -10 ;

	if( argc == 0 ) {
		tail( stdin, count ) ;
		exit(0) ;
	}

	s = *argv ;
	if( *s == '-' || *s == '+' ) {
		s++ ;
		if( *s >= '0' && *s <= '9' ) {
			count = stoi( *argv ) ;
			s++ ;
			while( *s >= '0' && *s <= '9' )
				s++ ;
		}
		if( *s == 'c' ) {
			chars = TRUE ;
			lines = FALSE ;
		}
		else if( *s != 'l' && *s != EOS ) {
			fprintf(stderr, "tail: unknown option %c\n", *s ) ;
			argc = 0 ;
		}
		argc-- ; argv++ ;
	}

	if( argc < 0 ) {
		fprintf(stderr, "usage: tail [+/-[number][lc]] [files]\n");
		exit(1) ;
	}

	if( argc == 0 )
		tail( stdin, count ) ;

	else if( (input=fopen(*argv,"r")) == NULL ) {
		fprintf(stderr, "tail: can't open %s\n", *argv) ;
		exit(1) ;
	}
	else {
		tail( input, count ) ;
		fclose( input ) ;
	}

	exit(0) ;

} /* end main */

/* stoi - convert string to integer */

stoi(s)
char *s ;
{
	int n, sign ;

	while( *s == BLANK || *s == NL || *s == TAB )
		s++ ;

	sign = 1 ;
	if( *s == '+' )
		s++ ;
	else if( *s == '-' ) {
		sign = -1 ;
		s++ ;
	}
	for( n=0 ; *s >= '0' && *s <= '9' ; s++ )
		n = 10 * n + *s - '0' ;
	return( sign * n ) ;
}

/* tail - print 'count' lines/chars */

#define INCR(p)  if(p >= end) p=cbuf ; else p++
#define BUFSIZE 4098

char cbuf[ BUFSIZE ] ;

tail( in, goal )
FILE *in ;
int goal ;
{
	int c, count ;
	char *start, *finish, *end ;

	count = 0 ;

	if( goal > 0 ) {	/* skip */

		if( lines )		/* lines */
			while( (c=agetc(in)) != EOF ) {
				if( c == NL )
					count++ ; 
				if( count >= goal )
					break ;
			}
		else			/* chars */
			while( agetc(in) != EOF ) {
				count++ ;
				if( count >= goal )
					break ;
			}
		if( count >= goal )
			while( (c=agetc(in)) != EOF )
				aputc(c, stdout ) ;
	}

	else {				/* tail */

		goal = -goal ;
		start = finish = cbuf ;
		end = &cbuf[ BUFSIZE - 1 ] ;

		while( (c=agetc(in)) != EOF ) {
			*finish = c ;
			INCR( finish ) ;

			if( start == finish )
				INCR( start ) ;
			if( !lines || c == NL )
				count++ ;

			if( count > goal ) {
				count = goal ;
				if( lines )
					while( *start != NL )
						INCR( start ) ;
				INCR( start ) ;
			}

		} /* end while */

		while( start != finish ) {
			aputc( *start, stdout ) ;
			INCR( start ) ;
		}

	} /* end else */

} /* end tail */

dcn@ihuxl.UUCP (Dave Newkirk) (11/14/83)

/* sort - sort text files in memory */

#include "stdio.h"

#define MAXTEXT 16384
#define MAXPTR  1024

char linebuf[MAXTEXT] ;
char *lineptr[MAXPTR] ;
int reverse ;

main(argc, argv)
int argc ;
char *argv[] ;
{
	char *s ;
	FILE *input ;


	reverse = FALSE ;
	while( --argc>0 && **++argv == '-' )
		for( s=&argv[0][1] ; *s != EOS ; s++ )
			switch( *s ) {
				case 'r':
					reverse = TRUE ;
					break ;
				default:
					fprintf(stderr, "sort: unknown option %c\n", *s ) ;
					argc = -1 ;
					break ;
			}

	if( argc < 0 ) {
		fprintf(stderr, "usage: sort files\n");
		exit(1) ;
	}

	if( argc == 0 )
		sort( stdin, "stdin" ) ;
	else
		for( ; argc>0 ; argc--,argv++)
			if( (input=fopen(*argv,"r")) == NULL ) {
				fprintf(stderr, "sort: can't open %s\n", *argv) ;
				exit(1) ;
			}
			else {
				sort( input, *argv ) ;
				fclose( input ) ;
			}

	exit(0) ;

} /* end main */


/* sort - sort text files in memory */

sort( in, fname )
FILE *in ;
char *fname ;
{
	int nlines ;

	if( (nlines=readlines(in)) > 0 ) {
		sortlines( 0, nlines-1 ) ;
		printlines( stdout, nlines ) ;
	}
	else if( nlines < 0 )
		fprintf(stderr, "sort: file is too large: %s\n", fname ) ;

} /* end sort */


/* readlines - store text in linebuf */

readlines( in )
FILE *in ;
{
	int nlines, len ;
	char *lbptr, *endbuffer ;

	nlines = 0 ;
	lbptr = &linebuf[0] ;
	endbuffer = &linebuf[MAXTEXT-1] ;

	do {
		if( (len = getline(lbptr, in)) == EOF )
			return nlines ;
		lineptr[ nlines ] = lbptr ;
		nlines++ ;
		lbptr += len + 1 ;	/* 1 for EOS */
	} while( lbptr < endbuffer && nlines < MAXPTR ) ;

	return EOF ;

} /* end readlines */


/* sortlines - quicksort on pointers */

sortlines( left, right )
int left, right ;
{
	int l, r, middle ;
	char *pivot, *temp ;
	l = left ; r = right ;
	middle = (l + r) / 2 ;
	pivot = lineptr[ middle ] ;

	do {

			while( strcmp(lineptr[l],pivot) < 0 )
				l++ ;
			while( strcmp(pivot,lineptr[r]) < 0 )
				r-- ;

		if( l <= r ) {
			temp = lineptr[l] ;
			lineptr[l] = lineptr[r] ;
			lineptr[r] = temp ;
			l++ ;
			r-- ;
		}

	} while( l <= r ) ;

	if( left < r )
		sortlines( left, r ) ;
	if( l < right )
		sortlines( l, right ) ;

} /* end sortlines */

/* printlines */

printlines( out, nlines )
FILE *out ;
int nlines ;
{
	int i ;

	if( reverse )
		for( i=nlines-1 ; i >= 0 ; i-- )
			fprintf( out, "%s", lineptr[i] ) ;
	else
		for( i=0 ; i < nlines ; i++ )
			fprintf( out, "%s", lineptr[i] ) ;

} /* end printlines */


/* getline - read input line */

getline( ptr, input )
char *ptr ;
FILE *input ;
{
	int c ;
	char *bufptr ;

	bufptr = ptr ;

	while( (c=agetc(input)) != NL ) {
		if( c == EOF )
			return EOF ;
		*bufptr++ = c ;
	}

	*bufptr++ = NL ;
	*bufptr++ = EOS ;
	return bufptr - ptr ;

} /* end getline */