xref: /csrg-svn/contrib/awk.research/main.c (revision 65391)
1*65391Sbostic /****************************************************************
2*65391Sbostic Copyright (C) AT&T 1993
3*65391Sbostic All Rights Reserved
4*65391Sbostic 
5*65391Sbostic Permission to use, copy, modify, and distribute this software and
6*65391Sbostic its documentation for any purpose and without fee is hereby
7*65391Sbostic granted, provided that the above copyright notice appear in all
8*65391Sbostic copies and that both that the copyright notice and this
9*65391Sbostic permission notice and warranty disclaimer appear in supporting
10*65391Sbostic documentation, and that the name of AT&T or any of its entities
11*65391Sbostic not be used in advertising or publicity pertaining to
12*65391Sbostic distribution of the software without specific, written prior
13*65391Sbostic permission.
14*65391Sbostic 
15*65391Sbostic AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16*65391Sbostic INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17*65391Sbostic IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18*65391Sbostic SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19*65391Sbostic WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20*65391Sbostic IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21*65391Sbostic ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22*65391Sbostic THIS SOFTWARE.
23*65391Sbostic ****************************************************************/
24*65391Sbostic 
25*65391Sbostic char	*version = "version July 23, 1993";
26*65391Sbostic 
27*65391Sbostic #define DEBUG
28*65391Sbostic #include <stdio.h>
29*65391Sbostic #include <ctype.h>
30*65391Sbostic #include <stdlib.h>
31*65391Sbostic #include <string.h>
32*65391Sbostic #include <signal.h>
33*65391Sbostic #include "awk.h"
34*65391Sbostic #include "y.tab.h"
35*65391Sbostic 
36*65391Sbostic extern	char	**environ;
37*65391Sbostic extern	int	nfields;
38*65391Sbostic 
39*65391Sbostic int	dbg	= 0;
40*65391Sbostic uchar	*cmdname;	/* gets argv[0] for error messages */
41*65391Sbostic extern	FILE	*yyin;	/* lex input file */
42*65391Sbostic uchar	*lexprog;	/* points to program argument if it exists */
43*65391Sbostic extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
44*65391Sbostic int	compile_time = 2;	/* for error printing: */
45*65391Sbostic 				/* 2 = cmdline, 1 = compile, 0 = running */
46*65391Sbostic 
47*65391Sbostic uchar	*pfile[20];	/* program filenames from -f's */
48*65391Sbostic int	npfile = 0;	/* number of filenames */
49*65391Sbostic int	curpfile = 0;	/* current filename */
50*65391Sbostic 
51*65391Sbostic 
52*65391Sbostic main(int argc, uchar *argv[])
53*65391Sbostic {
54*65391Sbostic 	uchar *fs = NULL, *marg;
55*65391Sbostic 	int temp;
56*65391Sbostic 
57*65391Sbostic 	cmdname = argv[0];
58*65391Sbostic 	if (argc == 1) {
59*65391Sbostic 		fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [-mf n] [-mr n] [files]\n", cmdname);
60*65391Sbostic 		exit(1);
61*65391Sbostic 	}
62*65391Sbostic 	signal(SIGFPE, fpecatch);
63*65391Sbostic 	yyin = NULL;
64*65391Sbostic 	symtab = makesymtab(NSYMTAB);
65*65391Sbostic 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
66*65391Sbostic 		if (strcmp((char *) argv[1], "--") == 0) {	/* explicit end of args */
67*65391Sbostic 			argc--;
68*65391Sbostic 			argv++;
69*65391Sbostic 			break;
70*65391Sbostic 		}
71*65391Sbostic 		switch (argv[1][1]) {
72*65391Sbostic 		case 'f':	/* next argument is program filename */
73*65391Sbostic 			argc--;
74*65391Sbostic 			argv++;
75*65391Sbostic 			if (argc <= 1)
76*65391Sbostic 				ERROR "no program filename" FATAL;
77*65391Sbostic 			pfile[npfile++] = argv[1];
78*65391Sbostic 			break;
79*65391Sbostic 		case 'F':	/* set field separator */
80*65391Sbostic 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
81*65391Sbostic 				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
82*65391Sbostic 					fs = (uchar *) "\t";
83*65391Sbostic 				else if (argv[1][2] != 0)
84*65391Sbostic 					fs = &argv[1][2];
85*65391Sbostic 			} else {		/* arg is -F something */
86*65391Sbostic 				argc--; argv++;
87*65391Sbostic 				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
88*65391Sbostic 					fs = (uchar *) "\t";
89*65391Sbostic 				else if (argc > 1 && argv[1][0] != 0)
90*65391Sbostic 					fs = &argv[1][0];
91*65391Sbostic 			}
92*65391Sbostic 			if (fs == NULL || *fs == '\0')
93*65391Sbostic 				ERROR "field separator FS is empty" WARNING;
94*65391Sbostic 			break;
95*65391Sbostic 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
96*65391Sbostic 			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
97*65391Sbostic 				setclvar(argv[1]);
98*65391Sbostic 			break;
99*65391Sbostic 		case 'm':	/* more memory: -mr=record, -mf=fields */
100*65391Sbostic 			marg = argv[1];
101*65391Sbostic 			if (argv[1][3])
102*65391Sbostic 				temp = atoi(&argv[1][3]);
103*65391Sbostic 			else {
104*65391Sbostic 				argv++; argc--;
105*65391Sbostic 				temp = atoi(&argv[1][0]);
106*65391Sbostic 			}
107*65391Sbostic 			switch (marg[2]) {
108*65391Sbostic 			case 'r':	recsize = temp; break;
109*65391Sbostic 			case 'f':	nfields = temp; break;
110*65391Sbostic 			default: ERROR "unknown option %s\n", marg FATAL;
111*65391Sbostic 			}
112*65391Sbostic 			break;
113*65391Sbostic 		case 'd':
114*65391Sbostic 			dbg = atoi(&argv[1][2]);
115*65391Sbostic 			if (dbg == 0)
116*65391Sbostic 				dbg = 1;
117*65391Sbostic 			printf("awk %s\n", version);
118*65391Sbostic 			break;
119*65391Sbostic 		default:
120*65391Sbostic 			ERROR "unknown option %s ignored", argv[1] WARNING;
121*65391Sbostic 			break;
122*65391Sbostic 		}
123*65391Sbostic 		argc--;
124*65391Sbostic 		argv++;
125*65391Sbostic 	}
126*65391Sbostic 	/* argv[1] is now the first argument */
127*65391Sbostic 	if (npfile == 0) {	/* no -f; first argument is program */
128*65391Sbostic 		if (argc <= 1) {
129*65391Sbostic 			if (dbg)
130*65391Sbostic 				exit(0);
131*65391Sbostic 			ERROR "no program given" FATAL;
132*65391Sbostic 		}
133*65391Sbostic 		dprintf( ("program = |%s|\n", argv[1]) );
134*65391Sbostic 		lexprog = argv[1];
135*65391Sbostic 		argc--;
136*65391Sbostic 		argv++;
137*65391Sbostic 	}
138*65391Sbostic 	recinit(recsize);
139*65391Sbostic 	syminit();
140*65391Sbostic 	compile_time = 1;
141*65391Sbostic 	argv[0] = cmdname;	/* put prog name at front of arglist */
142*65391Sbostic 	dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
143*65391Sbostic 	arginit(argc, argv);
144*65391Sbostic 	envinit(environ);
145*65391Sbostic 	yyparse();
146*65391Sbostic 	if (fs)
147*65391Sbostic 		*FS = tostring(qstring(fs, '\0'));
148*65391Sbostic 	dprintf( ("errorflag=%d\n", errorflag) );
149*65391Sbostic 	if (errorflag == 0) {
150*65391Sbostic 		compile_time = 0;
151*65391Sbostic 		run(winner);
152*65391Sbostic 	} else
153*65391Sbostic 		bracecheck();
154*65391Sbostic 	return(errorflag);
155*65391Sbostic }
156*65391Sbostic 
157*65391Sbostic pgetc(void)		/* get 1 character from awk program */
158*65391Sbostic {
159*65391Sbostic 	int c;
160*65391Sbostic 
161*65391Sbostic 	for (;;) {
162*65391Sbostic 		if (yyin == NULL) {
163*65391Sbostic 			if (curpfile >= npfile)
164*65391Sbostic 				return EOF;
165*65391Sbostic 			if (strcmp((char *) pfile[curpfile], "-") == 0)
166*65391Sbostic 				yyin = stdin;
167*65391Sbostic 			else if ((yyin = fopen((char *) pfile[curpfile], "r")) == NULL)
168*65391Sbostic 				ERROR "can't open file %s", pfile[curpfile] FATAL;
169*65391Sbostic 		}
170*65391Sbostic 		if ((c = getc(yyin)) != EOF)
171*65391Sbostic 			return c;
172*65391Sbostic 		if (yyin != stdin)
173*65391Sbostic 			fclose(yyin);
174*65391Sbostic 		yyin = NULL;
175*65391Sbostic 		curpfile++;
176*65391Sbostic 	}
177*65391Sbostic }
178