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