static char Sccsid[] = "cata.c @(#)cata.c	1.1	10/1/82 Berkeley ";
#

/*

cata.c	-- cat files in apl format

Usage:  cata file1 file2 file3...
	catb file1 file2 file3.....
	cata [-bl] file1 file2 file3...
can also be used as a filter, i.e.  cat file ^ cata ^ opr

cat? copies each line from the input file to the output
file, preceding each line with the line number in brackets.
the first line of each file is assumed to be the
function name and is printed without a line number.

cata performs overprints by backspacing and printing
the overprint character directly on top of the base
character.
catb captures each overprinted character and prints
it on the line after its occurance, underneath
the character that formed the base of the overprint.

cata.c is the program used to generate the binary:
the binary is linked to two file names: cata and catb
the program checks to detemine which one was called
and executes accordingly.
cata and catb are generated by compiling cata.c :
	cc cata.c -m -O ; mv a.out cata
	ln cata catb
note:   cata and catb must be linked together

flags:
Two flags are currently available to cata.
-l disables the printing of line numbers.
-b puts cata into the catb mode of printing lines.
examples:
	cata -l w1	print w1 in cata mode without line numbers
	cata -b w1	print w1 in catb mode
	cata -bl w1	print w1 in catb mode without line numbers
	cata w1		print w1 in cata mode

as of 10/23/78 cata and catb are linked together.
using catb is equivilent to typing:  cata  -b
default argument is to print line numbers and use cata mode.
hopefully at the beginning of spring 79 semester,
catb will be removed and apl users will use
cata -b  to perform the same function.


author:  a.p. reeves
10/21/78
modified for buffered i/o and fixed 'blank line' bug
added dual link ability
added -l and -b flags.
r.l. reeves

01/15/79
modified for standard i/o package
John Bruner
*/

#include <stdio.h>

FILE *infile;		/* input file pointer */

char *buf, line[128];	/* overprint buffer for catb mode */
			/* buf will be called newprint buffer */

int catb =  0;		/* catb mode if non-zero */
int lflg  = 1;		/* list line numbers if non-zero */

main(argc,argv)
int argc;char **argv;
{
	
	int iarg;	/* index of string being processed from argument list */
	register int frstim;	/* first time flag--on if first time */
				/* through main printing loop */
	register char *ap;	/* point to char in flag argument */
	extern char _sobuf[];
	
	/* force buffering */
	setbuf(stdout, _sobuf);
	
	/* set up newprint buffer to have leading tab */
	*line = '\t';
	buf = &line[1];
	
	/*
	* detect which file is being run of the two
	* possible file links.
	* set catb if file 'catb' is running
	*/
	
	if(argv[0][3] == 'b')
		catb++;
	
	iarg = 1;
	
	/*
	* check for flag argument
	*/
	
	if(argc > 1 && *argv[1] == '-') {
		ap = argv[1];
		while(*++ap) switch(*ap) {
			case 'b':	/* set catb mode */
					catb++;
					break;
			case 'l':	/* no line numbers */
					lflg = 0;
					break;
		}
		iarg++;
	}
	
	
	frstim = 1;	/* first time through main loop, print std input */
			/* in case no files given */
	
	while (argc > iarg || frstim) {
	
		if(argc > iarg){
			/* process argument list of files */
			close(0);
			if(open(argv[iarg], 0) != 0){
				printf("can't open input file: %s\n", argv[iarg]);
				exit(1);
			}
		}
	
		catfil();	/* print file */
	
		frstim = 0;
	
		/* advance to next file in argument list */
		putchar('\n');
		iarg++;
	
	}	/* end while */
	
	/* dump buffers and exit */
	
	exit(0);
}	/* end main */


/*
* catfil -- routine to print current file to standard output
*/

catfil() {

	register int new, orig;	/* index into newprint buffer */
				/* and original input buffer */
	int lincnt;		/* line counter */
	register char c;	/* character read in from input */

/* copy first line in file verbatim -- this is function name */
	printf("\n\n\t");
	while((c=getchar()) != EOF && putchar(c) != '\n');
	if(c == '\0') return;

/*
* copy remainder of file placing line numbers in front
* of each line.
*/

	lincnt = 1;
	while((c=getchar()) != EOF){

		new = orig = 0;

		/* print line number */
		if(lflg) printf(" [%d]\t%c",lincnt,c);
		else printf("\t%c",c);

		/* if not end of line, copy until then */
		if( c != '\n' ) {

			while((c = getchar()) && c != '\n'){
			   if(catb) {
		 		if(c != '\b'){
		 			putchar (c);
					orig++;
		 		} else {
		 			while(new < orig)  buf[new++] = ' ';
		 			c = buf[new++] = getchar();
		 		}
			   } else {
				putchar(c);
			   }
			}

			putchar('\n');

			/* perform newprint if needed */
			if(catb && new) {
	 			buf[new++] = '\n';
	 			buf[new] = '\0';
	 			printf(line);
	 		}

		}

		if(c == '\0') return;

		/* increment line counter */
		lincnt++;
	}

	return;

}
