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