[comp.sources.misc] v10i061: Backwards cat

dennis@virtech.UUCP (Dennis P. Bednar) (02/14/90)

Posting-number: Volume 10, Issue 61
Submitted-by: dennis@virtech.UUCP (Dennis P. Bednar)
Archive-name: revcat_db

#! /bin/sh
# This file was wrapped with "dummyshar".  "sh" this file to extract.
# Contents:  revcat.c
echo extracting 'revcat.c'
if test -f 'revcat.c' -a -z "$1"; then echo Not overwriting 'revcat.c'; else
sed 's/^X//' << \EOF > 'revcat.c'
X/*
X * rev.c
X * dennis bednar
X * Cat a file backwards (last line first, first line last).
X * Done by a recursive procedure that minimizes chewing up
X * the stack space.
X */
X
X#include <stdio.h>
X
Xmain( argc, argv )
X	char	**argv;
X{
X	FILE	*ifp;
X	int	i;
X
X	if (argc == 1)			/* no arguments			*/
X		rev_stream(stdin);	/* so reverse stdin		*/
X	else for (i = 1; i < argc; ++i)	/* loop on file name args	*/
X	{
X		ifp = fopen( argv[i], "r");
X		rev_stream( ifp );	/* reverse one file		*/
X		fclose( ifp );
X	}
X	exit(0);
X}
X
X/* this is outside of rev_stream() function to avoid eating up stack space */
Xstatic	char	linebuf[ BUFSIZ ];	/* one line from file		*/
Xstatic	FILE	*rev_ifp;		/* handle for file		*/
X
X/* Note that we want to minimize the stack space used by the recursive
X * function.  So we use global static variables wherever possible.
X */ 
Xrev_stream( ifp )
X	FILE	*ifp;
X{
X	rev_ifp = ifp;			/* save in global for recursion	*/
X	rev_stream_recursive();		/* do the work			*/
X}
X
X/*
X * recursively function to reverse lines of a stream 'rev_ifp'.
X */
Xrev_stream_recursive( )
X{
X	char	*cp;
X	char	*strdup();
X
X	/* read one line then recurse to read the rest of the file.
X	 */
X	if ( fgets(linebuf, sizeof(linebuf), rev_ifp ) )	/* !EOF */
X	{
X		cp = strdup( linebuf );	/* duplicate this line		*/
X		rev_stream_recursive();	/* reverse the rest of file	*/
X		fputs( cp, stdout );	/* now print this line		*/
X	}
X}
X
Xchar	*strdup( old )
X	char	*old;
X{
X	char	*new;
X	extern	char	*malloc();
X	
X	new = malloc( strlen(old) + 1 );	/* room for null */
X	strcpy( new, old );
X	return new;
X}
EOF
chars=`wc -c < 'revcat.c'`
if test $chars !=     1549; then echo 'revcat.c' is $chars characters, should be     1549 characters!; fi
fi
exit 0
-- 
Dennis Bednar	uunet!virtech!dennis	(703)760-3357(w)   (703)437-4384(h)
Cable & Wireless,	Tysons Corner VA