xref: /plan9/sys/src/cmd/awk/main.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier Copyright (c) 1989 AT&T
33e12c5d1SDavid du Colombier 	All Rights Reserved
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier The copyright notice above does not evidence any
83e12c5d1SDavid du Colombier actual or intended publication of such source code.
93e12c5d1SDavid du Colombier */
103e12c5d1SDavid du Colombier 
11*219b2ee8SDavid du Colombier char	*version = "version April 22, 1994";
123e12c5d1SDavid du Colombier 
133e12c5d1SDavid du Colombier #define DEBUG
143e12c5d1SDavid du Colombier #include <stdio.h>
153e12c5d1SDavid du Colombier #include <ctype.h>
163e12c5d1SDavid du Colombier #include <stdlib.h>
173e12c5d1SDavid du Colombier #include <string.h>
183e12c5d1SDavid du Colombier #include <signal.h>
193e12c5d1SDavid du Colombier #include "awk.h"
203e12c5d1SDavid du Colombier #include "y.tab.h"
213e12c5d1SDavid du Colombier 
223e12c5d1SDavid du Colombier extern	char	**environ;
23*219b2ee8SDavid du Colombier extern	int	nfields;
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier int	dbg	= 0;
263e12c5d1SDavid du Colombier uchar	*cmdname;	/* gets argv[0] for error messages */
273e12c5d1SDavid du Colombier extern	FILE	*yyin;	/* lex input file */
283e12c5d1SDavid du Colombier uchar	*lexprog;	/* points to program argument if it exists */
293e12c5d1SDavid du Colombier extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
303e12c5d1SDavid du Colombier int	compile_time = 2;	/* for error printing: */
313e12c5d1SDavid du Colombier 				/* 2 = cmdline, 1 = compile, 0 = running */
323e12c5d1SDavid du Colombier 
333e12c5d1SDavid du Colombier uchar	*pfile[20];	/* program filenames from -f's */
343e12c5d1SDavid du Colombier int	npfile = 0;	/* number of filenames */
353e12c5d1SDavid du Colombier int	curpfile = 0;	/* current filename */
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier 
383e12c5d1SDavid du Colombier main(int argc, uchar *argv[])
393e12c5d1SDavid du Colombier {
40*219b2ee8SDavid du Colombier 	uchar *fs = NULL, *marg;
41*219b2ee8SDavid du Colombier 	int temp;
423e12c5d1SDavid du Colombier 
433e12c5d1SDavid du Colombier 	cmdname = argv[0];
443e12c5d1SDavid du Colombier 	if (argc == 1) {
45*219b2ee8SDavid du Colombier 		fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [-mf n] [-mr n] [files]\n", cmdname);
463e12c5d1SDavid du Colombier 		exit(1);
473e12c5d1SDavid du Colombier 	}
483e12c5d1SDavid du Colombier 	signal(SIGFPE, fpecatch);
493e12c5d1SDavid du Colombier 	yyin = NULL;
50*219b2ee8SDavid du Colombier 	symtab = makesymtab(NSYMTAB);
513e12c5d1SDavid du Colombier 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
523e12c5d1SDavid du Colombier 		if (strcmp((char *) argv[1], "--") == 0) {	/* explicit end of args */
533e12c5d1SDavid du Colombier 			argc--;
543e12c5d1SDavid du Colombier 			argv++;
553e12c5d1SDavid du Colombier 			break;
563e12c5d1SDavid du Colombier 		}
573e12c5d1SDavid du Colombier 		switch (argv[1][1]) {
583e12c5d1SDavid du Colombier 		case 'f':	/* next argument is program filename */
593e12c5d1SDavid du Colombier 			argc--;
603e12c5d1SDavid du Colombier 			argv++;
613e12c5d1SDavid du Colombier 			if (argc <= 1)
623e12c5d1SDavid du Colombier 				ERROR "no program filename" FATAL;
633e12c5d1SDavid du Colombier 			pfile[npfile++] = argv[1];
643e12c5d1SDavid du Colombier 			break;
653e12c5d1SDavid du Colombier 		case 'F':	/* set field separator */
663e12c5d1SDavid du Colombier 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
673e12c5d1SDavid du Colombier 				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
683e12c5d1SDavid du Colombier 					fs = (uchar *) "\t";
693e12c5d1SDavid du Colombier 				else if (argv[1][2] != 0)
703e12c5d1SDavid du Colombier 					fs = &argv[1][2];
713e12c5d1SDavid du Colombier 			} else {		/* arg is -F something */
723e12c5d1SDavid du Colombier 				argc--; argv++;
733e12c5d1SDavid du Colombier 				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
743e12c5d1SDavid du Colombier 					fs = (uchar *) "\t";
753e12c5d1SDavid du Colombier 				else if (argc > 1 && argv[1][0] != 0)
763e12c5d1SDavid du Colombier 					fs = &argv[1][0];
773e12c5d1SDavid du Colombier 			}
783e12c5d1SDavid du Colombier 			if (fs == NULL || *fs == '\0')
793e12c5d1SDavid du Colombier 				ERROR "field separator FS is empty" WARNING;
803e12c5d1SDavid du Colombier 			break;
813e12c5d1SDavid du Colombier 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
823e12c5d1SDavid du Colombier 			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
833e12c5d1SDavid du Colombier 				setclvar(argv[1]);
843e12c5d1SDavid du Colombier 			break;
85*219b2ee8SDavid du Colombier 		case 'm':	/* more memory: -mr=record, -mf=fields */
86*219b2ee8SDavid du Colombier 			marg = argv[1];
87*219b2ee8SDavid du Colombier 			if (argv[1][3])
88*219b2ee8SDavid du Colombier 				temp = atoi(&argv[1][3]);
89*219b2ee8SDavid du Colombier 			else {
90*219b2ee8SDavid du Colombier 				argv++; argc--;
91*219b2ee8SDavid du Colombier 				temp = atoi(&argv[1][0]);
92*219b2ee8SDavid du Colombier 			}
93*219b2ee8SDavid du Colombier 			switch (marg[2]) {
94*219b2ee8SDavid du Colombier 			case 'r':	recsize = temp; break;
95*219b2ee8SDavid du Colombier 			case 'f':	nfields = temp; break;
96*219b2ee8SDavid du Colombier 			default: ERROR "unknown option %s\n", marg FATAL;
97*219b2ee8SDavid du Colombier 			}
98*219b2ee8SDavid du Colombier 			break;
993e12c5d1SDavid du Colombier 		case 'd':
1003e12c5d1SDavid du Colombier 			dbg = atoi(&argv[1][2]);
1013e12c5d1SDavid du Colombier 			if (dbg == 0)
1023e12c5d1SDavid du Colombier 				dbg = 1;
1033e12c5d1SDavid du Colombier 			printf("awk %s\n", version);
1043e12c5d1SDavid du Colombier 			break;
1053e12c5d1SDavid du Colombier 		default:
1063e12c5d1SDavid du Colombier 			ERROR "unknown option %s ignored", argv[1] WARNING;
1073e12c5d1SDavid du Colombier 			break;
1083e12c5d1SDavid du Colombier 		}
1093e12c5d1SDavid du Colombier 		argc--;
1103e12c5d1SDavid du Colombier 		argv++;
1113e12c5d1SDavid du Colombier 	}
1123e12c5d1SDavid du Colombier 	/* argv[1] is now the first argument */
1133e12c5d1SDavid du Colombier 	if (npfile == 0) {	/* no -f; first argument is program */
114*219b2ee8SDavid du Colombier 		if (argc <= 1) {
115*219b2ee8SDavid du Colombier 			if (dbg)
116*219b2ee8SDavid du Colombier 				exit(0);
1173e12c5d1SDavid du Colombier 			ERROR "no program given" FATAL;
118*219b2ee8SDavid du Colombier 		}
1193e12c5d1SDavid du Colombier 		dprintf( ("program = |%s|\n", argv[1]) );
1203e12c5d1SDavid du Colombier 		lexprog = argv[1];
1213e12c5d1SDavid du Colombier 		argc--;
1223e12c5d1SDavid du Colombier 		argv++;
1233e12c5d1SDavid du Colombier 	}
124*219b2ee8SDavid du Colombier 	recinit(recsize);
125*219b2ee8SDavid du Colombier 	syminit();
1263e12c5d1SDavid du Colombier 	compile_time = 1;
1273e12c5d1SDavid du Colombier 	argv[0] = cmdname;	/* put prog name at front of arglist */
1283e12c5d1SDavid du Colombier 	dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
1293e12c5d1SDavid du Colombier 	arginit(argc, argv);
1303e12c5d1SDavid du Colombier 	envinit(environ);
1313e12c5d1SDavid du Colombier 	yyparse();
1323e12c5d1SDavid du Colombier 	if (fs)
1333e12c5d1SDavid du Colombier 		*FS = tostring(qstring(fs, '\0'));
1343e12c5d1SDavid du Colombier 	dprintf( ("errorflag=%d\n", errorflag) );
1353e12c5d1SDavid du Colombier 	if (errorflag == 0) {
1363e12c5d1SDavid du Colombier 		compile_time = 0;
1373e12c5d1SDavid du Colombier 		run(winner);
1383e12c5d1SDavid du Colombier 	} else
1393e12c5d1SDavid du Colombier 		bracecheck();
1403e12c5d1SDavid du Colombier 	return(errorflag);
1413e12c5d1SDavid du Colombier }
1423e12c5d1SDavid du Colombier 
143*219b2ee8SDavid du Colombier pgetc(void)		/* get 1 character from awk program */
1443e12c5d1SDavid du Colombier {
1453e12c5d1SDavid du Colombier 	int c;
1463e12c5d1SDavid du Colombier 
1473e12c5d1SDavid du Colombier 	for (;;) {
1483e12c5d1SDavid du Colombier 		if (yyin == NULL) {
1493e12c5d1SDavid du Colombier 			if (curpfile >= npfile)
1503e12c5d1SDavid du Colombier 				return EOF;
1513e12c5d1SDavid du Colombier 			if (strcmp((char *) pfile[curpfile], "-") == 0)
1523e12c5d1SDavid du Colombier 				yyin = stdin;
1533e12c5d1SDavid du Colombier 			else if ((yyin = fopen((char *) pfile[curpfile], "r")) == NULL)
1543e12c5d1SDavid du Colombier 				ERROR "can't open file %s", pfile[curpfile] FATAL;
1553e12c5d1SDavid du Colombier 		}
1563e12c5d1SDavid du Colombier 		if ((c = getc(yyin)) != EOF)
1573e12c5d1SDavid du Colombier 			return c;
158*219b2ee8SDavid du Colombier 		if (yyin != stdin)
1593e12c5d1SDavid du Colombier 			fclose(yyin);
1603e12c5d1SDavid du Colombier 		yyin = NULL;
1613e12c5d1SDavid du Colombier 		curpfile++;
1623e12c5d1SDavid du Colombier 	}
1633e12c5d1SDavid du Colombier }
164