main.c revision 90902
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 20020101";
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;
56
57	cmdname = argv[0];
58	if (argc == 1) {
59		fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [files]\n", cmdname);
60		exit(1);
61	}
62	signal(SIGFPE, fpecatch);
63	yyin = NULL;
64	symtab = makesymtab(NSYMTAB);
65	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
66		if (strcmp(argv[1], "--") == 0) {	/* explicit end of args */
67			argc--;
68			argv++;
69			break;
70		}
71		switch (argv[1][1]) {
72		case 's':
73			if (strcmp(argv[1], "-safe") == 0)
74				safe = 1;
75			break;
76		case 'f':	/* next argument is program filename */
77			argc--;
78			argv++;
79			if (argc <= 1)
80				FATAL("no program filename");
81			pfile[npfile++] = argv[1];
82			break;
83		case 'F':	/* set field separator */
84			if (argv[1][2] != 0) {	/* arg is -Fsomething */
85				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
86					fs = "\t";
87				else if (argv[1][2] != 0)
88					fs = &argv[1][2];
89			} else {		/* arg is -F something */
90				argc--; argv++;
91				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
92					fs = "\t";
93				else if (argc > 1 && argv[1][0] != 0)
94					fs = &argv[1][0];
95			}
96			if (fs == NULL || *fs == '\0')
97				WARNING("field separator FS is empty");
98			break;
99		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
100			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
101				setclvar(argv[1]);
102			break;
103		case 'm':	/* more memory: -mr=record, -mf=fields */
104				/* no longer supported */
105			WARNING("obsolete option %s ignored", argv[1]);
106			break;
107		case 'd':
108			dbg = atoi(&argv[1][2]);
109			if (dbg == 0)
110				dbg = 1;
111			printf("awk %s\n", version);
112			break;
113		case 'V':	/* added for exptools "standard" */
114			printf("awk %s\n", version);
115			exit(0);
116			break;
117		default:
118			WARNING("unknown option %s ignored", argv[1]);
119			break;
120		}
121		argc--;
122		argv++;
123	}
124	/* argv[1] is now the first argument */
125	if (npfile == 0) {	/* no -f; first argument is program */
126		if (argc <= 1) {
127			if (dbg)
128				exit(0);
129			FATAL("no program given");
130		}
131		   dprintf( ("program = |%s|\n", argv[1]) );
132		lexprog = argv[1];
133		argc--;
134		argv++;
135	}
136	recinit(recsize);
137	syminit();
138	compile_time = 1;
139	argv[0] = cmdname;	/* put prog name at front of arglist */
140	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
141	arginit(argc, argv);
142	if (!safe)
143		envinit(environ);
144	yyparse();
145	if (fs)
146		*FS = qstring(fs, '\0');
147	   dprintf( ("errorflag=%d\n", errorflag) );
148	if (errorflag == 0) {
149		compile_time = 0;
150		run(winner);
151	} else
152		bracecheck();
153	return(errorflag);
154}
155
156int pgetc(void)		/* get 1 character from awk program */
157{
158	int c;
159
160	for (;;) {
161		if (yyin == NULL) {
162			if (curpfile >= npfile)
163				return EOF;
164			if (strcmp(pfile[curpfile], "-") == 0)
165				yyin = stdin;
166			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
167				FATAL("can't open file %s", pfile[curpfile]);
168			lineno = 1;
169		}
170		if ((c = getc(yyin)) != EOF)
171			return c;
172		if (yyin != stdin)
173			fclose(yyin);
174		yyin = NULL;
175		curpfile++;
176	}
177}
178
179char *cursource(void)	/* current source file name */
180{
181	if (npfile > 0)
182		return pfile[curpfile];
183	else
184		return NULL;
185}
186