xref: /plan9/sys/src/cmd/awk/main.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1*3e12c5d1SDavid du Colombier /*
2*3e12c5d1SDavid du Colombier Copyright (c) 1989 AT&T
3*3e12c5d1SDavid du Colombier 	All Rights Reserved
4*3e12c5d1SDavid du Colombier 
5*3e12c5d1SDavid du Colombier THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.
6*3e12c5d1SDavid du Colombier 
7*3e12c5d1SDavid du Colombier The copyright notice above does not evidence any
8*3e12c5d1SDavid du Colombier actual or intended publication of such source code.
9*3e12c5d1SDavid du Colombier */
10*3e12c5d1SDavid du Colombier 
11*3e12c5d1SDavid du Colombier char	*version = "version Feb 20, 1992";
12*3e12c5d1SDavid du Colombier 
13*3e12c5d1SDavid du Colombier #define DEBUG
14*3e12c5d1SDavid du Colombier #include <stdio.h>
15*3e12c5d1SDavid du Colombier #include <ctype.h>
16*3e12c5d1SDavid du Colombier #include <stdlib.h>
17*3e12c5d1SDavid du Colombier #include <string.h>
18*3e12c5d1SDavid du Colombier #include <signal.h>
19*3e12c5d1SDavid du Colombier #include "awk.h"
20*3e12c5d1SDavid du Colombier #include "y.tab.h"
21*3e12c5d1SDavid du Colombier 
22*3e12c5d1SDavid du Colombier extern	char	**environ;
23*3e12c5d1SDavid du Colombier 
24*3e12c5d1SDavid du Colombier int	dbg	= 0;
25*3e12c5d1SDavid du Colombier uchar	*cmdname;	/* gets argv[0] for error messages */
26*3e12c5d1SDavid du Colombier extern	FILE	*yyin;	/* lex input file */
27*3e12c5d1SDavid du Colombier uchar	*lexprog;	/* points to program argument if it exists */
28*3e12c5d1SDavid du Colombier extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
29*3e12c5d1SDavid du Colombier int	compile_time = 2;	/* for error printing: */
30*3e12c5d1SDavid du Colombier 				/* 2 = cmdline, 1 = compile, 0 = running */
31*3e12c5d1SDavid du Colombier 
32*3e12c5d1SDavid du Colombier uchar	*pfile[20];	/* program filenames from -f's */
33*3e12c5d1SDavid du Colombier int	npfile = 0;	/* number of filenames */
34*3e12c5d1SDavid du Colombier int	curpfile = 0;	/* current filename */
35*3e12c5d1SDavid du Colombier 
36*3e12c5d1SDavid du Colombier 
37*3e12c5d1SDavid du Colombier main(int argc, uchar *argv[])
38*3e12c5d1SDavid du Colombier {
39*3e12c5d1SDavid du Colombier 	uchar *fs = NULL;
40*3e12c5d1SDavid du Colombier 
41*3e12c5d1SDavid du Colombier 	cmdname = argv[0];
42*3e12c5d1SDavid du Colombier 	if (argc == 1) {
43*3e12c5d1SDavid du Colombier 		fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [files]\n", cmdname);
44*3e12c5d1SDavid du Colombier 		exit(1);
45*3e12c5d1SDavid du Colombier 	}
46*3e12c5d1SDavid du Colombier 	signal(SIGFPE, fpecatch);
47*3e12c5d1SDavid du Colombier 	yyin = NULL;
48*3e12c5d1SDavid du Colombier 	syminit();
49*3e12c5d1SDavid du Colombier 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
50*3e12c5d1SDavid du Colombier 		if (strcmp((char *) argv[1], "--") == 0) {	/* explicit end of args */
51*3e12c5d1SDavid du Colombier 			argc--;
52*3e12c5d1SDavid du Colombier 			argv++;
53*3e12c5d1SDavid du Colombier 			break;
54*3e12c5d1SDavid du Colombier 		}
55*3e12c5d1SDavid du Colombier 		switch (argv[1][1]) {
56*3e12c5d1SDavid du Colombier 		case 'f':	/* next argument is program filename */
57*3e12c5d1SDavid du Colombier 			argc--;
58*3e12c5d1SDavid du Colombier 			argv++;
59*3e12c5d1SDavid du Colombier 			if (argc <= 1)
60*3e12c5d1SDavid du Colombier 				ERROR "no program filename" FATAL;
61*3e12c5d1SDavid du Colombier 			pfile[npfile++] = argv[1];
62*3e12c5d1SDavid du Colombier 			break;
63*3e12c5d1SDavid du Colombier 		case 'F':	/* set field separator */
64*3e12c5d1SDavid du Colombier 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
65*3e12c5d1SDavid du Colombier 				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
66*3e12c5d1SDavid du Colombier 					fs = (uchar *) "\t";
67*3e12c5d1SDavid du Colombier 				else if (argv[1][2] != 0)
68*3e12c5d1SDavid du Colombier 					fs = &argv[1][2];
69*3e12c5d1SDavid du Colombier 			} else {		/* arg is -F something */
70*3e12c5d1SDavid du Colombier 				argc--; argv++;
71*3e12c5d1SDavid du Colombier 				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
72*3e12c5d1SDavid du Colombier 					fs = (uchar *) "\t";
73*3e12c5d1SDavid du Colombier 				else if (argc > 1 && argv[1][0] != 0)
74*3e12c5d1SDavid du Colombier 					fs = &argv[1][0];
75*3e12c5d1SDavid du Colombier 			}
76*3e12c5d1SDavid du Colombier 			if (fs == NULL || *fs == '\0')
77*3e12c5d1SDavid du Colombier 				ERROR "field separator FS is empty" WARNING;
78*3e12c5d1SDavid du Colombier 			break;
79*3e12c5d1SDavid du Colombier 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
80*3e12c5d1SDavid du Colombier 			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
81*3e12c5d1SDavid du Colombier 				setclvar(argv[1]);
82*3e12c5d1SDavid du Colombier 			break;
83*3e12c5d1SDavid du Colombier 		case 'd':
84*3e12c5d1SDavid du Colombier 			dbg = atoi(&argv[1][2]);
85*3e12c5d1SDavid du Colombier 			if (dbg == 0)
86*3e12c5d1SDavid du Colombier 				dbg = 1;
87*3e12c5d1SDavid du Colombier 			printf("awk %s\n", version);
88*3e12c5d1SDavid du Colombier 			break;
89*3e12c5d1SDavid du Colombier 		default:
90*3e12c5d1SDavid du Colombier 			ERROR "unknown option %s ignored", argv[1] WARNING;
91*3e12c5d1SDavid du Colombier 			break;
92*3e12c5d1SDavid du Colombier 		}
93*3e12c5d1SDavid du Colombier 		argc--;
94*3e12c5d1SDavid du Colombier 		argv++;
95*3e12c5d1SDavid du Colombier 	}
96*3e12c5d1SDavid du Colombier 	/* argv[1] is now the first argument */
97*3e12c5d1SDavid du Colombier 	if (npfile == 0) {	/* no -f; first argument is program */
98*3e12c5d1SDavid du Colombier 		if (argc <= 1)
99*3e12c5d1SDavid du Colombier 			ERROR "no program given" FATAL;
100*3e12c5d1SDavid du Colombier 		dprintf( ("program = |%s|\n", argv[1]) );
101*3e12c5d1SDavid du Colombier 		lexprog = argv[1];
102*3e12c5d1SDavid du Colombier 		argc--;
103*3e12c5d1SDavid du Colombier 		argv++;
104*3e12c5d1SDavid du Colombier 	}
105*3e12c5d1SDavid du Colombier 	compile_time = 1;
106*3e12c5d1SDavid du Colombier 	argv[0] = cmdname;	/* put prog name at front of arglist */
107*3e12c5d1SDavid du Colombier 	dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
108*3e12c5d1SDavid du Colombier 	arginit(argc, argv);
109*3e12c5d1SDavid du Colombier 	envinit(environ);
110*3e12c5d1SDavid du Colombier 	yyparse();
111*3e12c5d1SDavid du Colombier 	if (fs)
112*3e12c5d1SDavid du Colombier 		*FS = tostring(qstring(fs, '\0'));
113*3e12c5d1SDavid du Colombier 	dprintf( ("errorflag=%d\n", errorflag) );
114*3e12c5d1SDavid du Colombier 	if (errorflag == 0) {
115*3e12c5d1SDavid du Colombier 		compile_time = 0;
116*3e12c5d1SDavid du Colombier 		run(winner);
117*3e12c5d1SDavid du Colombier 	} else
118*3e12c5d1SDavid du Colombier 		bracecheck();
119*3e12c5d1SDavid du Colombier 	return(errorflag);
120*3e12c5d1SDavid du Colombier }
121*3e12c5d1SDavid du Colombier 
122*3e12c5d1SDavid du Colombier pgetc(void)		/* get program character */
123*3e12c5d1SDavid du Colombier {
124*3e12c5d1SDavid du Colombier 	int c;
125*3e12c5d1SDavid du Colombier 
126*3e12c5d1SDavid du Colombier 	for (;;) {
127*3e12c5d1SDavid du Colombier 		if (yyin == NULL) {
128*3e12c5d1SDavid du Colombier 			if (curpfile >= npfile)
129*3e12c5d1SDavid du Colombier 				return EOF;
130*3e12c5d1SDavid du Colombier 			if (strcmp((char *) pfile[curpfile], "-") == 0)
131*3e12c5d1SDavid du Colombier 				yyin = stdin;
132*3e12c5d1SDavid du Colombier 			else if ((yyin = fopen((char *) pfile[curpfile], "r")) == NULL)
133*3e12c5d1SDavid du Colombier 				ERROR "can't open file %s", pfile[curpfile] FATAL;
134*3e12c5d1SDavid du Colombier 		}
135*3e12c5d1SDavid du Colombier 		if ((c = getc(yyin)) != EOF)
136*3e12c5d1SDavid du Colombier 			return c;
137*3e12c5d1SDavid du Colombier 		fclose(yyin);
138*3e12c5d1SDavid du Colombier 		yyin = NULL;
139*3e12c5d1SDavid du Colombier 		curpfile++;
140*3e12c5d1SDavid du Colombier 	}
141*3e12c5d1SDavid du Colombier }
142