xref: /openbsd/usr.bin/awk/main.c (revision 8932bfb7)
1 /*	$OpenBSD: main.c,v 1.16 2010/06/13 17:58:19 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 20100523";
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 "ytab.h"
37 
38 extern	char	**environ;
39 extern	int	nfields;
40 extern	char	*__progname;
41 
42 int	dbg	= 0;
43 char	*cmdname;	/* gets argv[0] for error messages */
44 extern	FILE	*yyin;	/* lex input file */
45 char	*lexprog;	/* points to program argument if it exists */
46 extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
47 int	compile_time = 2;	/* for error printing: */
48 				/* 2 = cmdline, 1 = compile, 0 = running */
49 
50 #define	MAX_PFILE	20	/* max number of -f's */
51 
52 char	*pfile[MAX_PFILE];	/* program filenames from -f's */
53 int	npfile = 0;	/* number of filenames */
54 int	curpfile = 0;	/* current filename */
55 
56 int	safe	= 0;	/* 1 => "safe" mode */
57 
58 int main(int argc, char *argv[])
59 {
60 	const char *fs = NULL;
61 
62 	setlocale(LC_ALL, "");
63 	setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
64 	cmdname = __progname;
65 	if (argc == 1) {
66 		fprintf(stderr, "usage: %s [-safe] [-V] [-d[n]] [-F fs] "
67 		    "[-v var=value] [prog | -f progfile]\n\tfile ...\n",
68 		    cmdname);
69 		exit(1);
70 	}
71 	signal(SIGFPE, fpecatch);
72 	yyin = NULL;
73 	symtab = makesymtab(NSYMTAB);
74 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
75 		if (strcmp(argv[1], "--") == 0) {	/* explicit end of args */
76 			argc--;
77 			argv++;
78 			break;
79 		}
80 		switch (argv[1][1]) {
81 		case 's':
82 			if (strcmp(argv[1], "-safe") == 0)
83 				safe = 1;
84 			break;
85 		case 'f':	/* next argument is program filename */
86 			argc--;
87 			argv++;
88 			if (npfile >= MAX_PFILE - 1)
89 				FATAL("too many -f options");
90 			if (argc <= 1)
91 				FATAL("no program filename");
92 			if (npfile >= MAX_PFILE - 1)
93 				FATAL("too many -f options");
94 			pfile[npfile++] = argv[1];
95 			break;
96 		case 'F':	/* set field separator */
97 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
98 				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
99 					fs = "\t";
100 				else if (argv[1][2] != 0)
101 					fs = &argv[1][2];
102 			} else {		/* arg is -F something */
103 				argc--; argv++;
104 				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
105 					fs = "\t";
106 				else if (argc > 1 && argv[1][0] != 0)
107 					fs = &argv[1][0];
108 			}
109 			if (fs == NULL || *fs == '\0')
110 				WARNING("field separator FS is empty");
111 			break;
112 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
113 			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
114 				setclvar(argv[1]);
115 			else if (argv[1][2] != '\0')
116 				setclvar(&argv[1][2]);
117 			break;
118 		case 'd':
119 			dbg = atoi(&argv[1][2]);
120 			if (dbg == 0)
121 				dbg = 1;
122 			printf("awk %s\n", version);
123 			break;
124 		case 'V':	/* added for exptools "standard" */
125 			printf("awk %s\n", version);
126 			exit(0);
127 			break;
128 		default:
129 			WARNING("unknown option %s ignored", argv[1]);
130 			break;
131 		}
132 		argc--;
133 		argv++;
134 	}
135 	/* argv[1] is now the first argument */
136 	if (npfile == 0) {	/* no -f; first argument is program */
137 		if (argc <= 1) {
138 			if (dbg)
139 				exit(0);
140 			FATAL("no program given");
141 		}
142 		   dprintf( ("program = |%s|\n", argv[1]) );
143 		lexprog = argv[1];
144 		argc--;
145 		argv++;
146 	}
147 	recinit(recsize);
148 	syminit();
149 	compile_time = 1;
150 	argv[0] = cmdname;	/* put prog name at front of arglist */
151 	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
152 	arginit(argc, argv);
153 	if (!safe)
154 		envinit(environ);
155 	yyparse();
156 	setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
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 
168 int 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 
191 char *cursource(void)	/* current source file name */
192 {
193 	if (npfile > 0)
194 		return pfile[curpfile];
195 	else
196 		return NULL;
197 }
198