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