GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/awk/main.c Lines: 66 120 55.0 %
Date: 2017-11-13 Branches: 43 99 43.4 %

Line Branch Exec Source
1
/*	$OpenBSD: main.c,v 1.21 2017/10/09 14:51:31 deraadt 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 <unistd.h>
36
#include "awk.h"
37
#include "ytab.h"
38
39
extern	char	**environ;
40
extern	int	nfields;
41
extern	char	*__progname;
42
43
int	dbg	= 0;
44
Awkfloat	srand_seed = 1;
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
extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
49
int	compile_time = 2;	/* for error printing: */
50
				/* 2 = cmdline, 1 = compile, 0 = running */
51
52
#define	MAX_PFILE	20	/* max number of -f's */
53
54
char	*pfile[MAX_PFILE];	/* program filenames from -f's */
55
int	npfile = 0;	/* number of filenames */
56
int	curpfile = 0;	/* current filename */
57
58
int	safe	= 0;	/* 1 => "safe" mode */
59
60
int main(int argc, char *argv[])
61
{
62
	const char *fs = NULL;
63
64
974
	setlocale(LC_ALL, "");
65
487
	setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
66
67
487
	cmdname = __progname;
68
487
	if (pledge("stdio rpath wpath cpath proc exec flock", NULL) == -1) {
69
		fprintf(stderr, "%s: pledge: incorrect arguments\n",
70
		    cmdname);
71
		exit(1);
72
	}
73
74
487
	if (argc == 1) {
75
		fprintf(stderr, "usage: %s [-safe] [-V] [-d[n]] [-F fs] "
76
		    "[-v var=value] [prog | -f progfile]\n\tfile ...\n",
77
		    cmdname);
78
		exit(1);
79
	}
80
487
	signal(SIGFPE, fpecatch);
81
82
487
	yyin = NULL;
83
487
	symtab = makesymtab(NSYMTAB);
84

1719
	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
85
65
		if (strcmp(argv[1], "--") == 0) {	/* explicit end of args */
86
			argc--;
87
			argv++;
88
			break;
89
		}
90

65
		switch (argv[1][1]) {
91
		case 's':
92
			if (strcmp(argv[1], "-safe") == 0)
93
				safe = 1;
94
			break;
95
		case 'f':	/* next argument is program filename */
96
16
			if (argv[1][2] != 0) {  /* arg is -fsomething */
97
				if (npfile >= MAX_PFILE - 1)
98
					FATAL("too many -f options");
99
				pfile[npfile++] = &argv[1][2];
100
			} else {		/* arg is -f something */
101
16
				argc--; argv++;
102
16
				if (argc <= 1)
103
					FATAL("no program filename");
104
16
				if (npfile >= MAX_PFILE - 1)
105
					FATAL("too many -f options");
106
16
				pfile[npfile++] = argv[1];
107
			}
108
16
			break;
109
		case 'F':	/* set field separator */
110
49
			if (argv[1][2] != 0) {	/* arg is -Fsomething */
111

50
				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
112
1
					fs = "\t";
113
48
				else if (argv[1][2] != 0)
114
48
					fs = &argv[1][2];
115
			} else {		/* arg is -F something */
116
				argc--; argv++;
117
				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
118
					fs = "\t";
119
				else if (argc > 1 && argv[1][0] != 0)
120
					fs = &argv[1][0];
121
			}
122

98
			if (fs == NULL || *fs == '\0')
123
				WARNING("field separator FS is empty");
124
			break;
125
		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
126
			if (argv[1][2] != 0) {  /* arg is -vsomething */
127
				if (isclvar(&argv[1][2]))
128
					setclvar(&argv[1][2]);
129
				else
130
					FATAL("invalid -v option argument: %s", &argv[1][2]);
131
			} else {		/* arg is -v something */
132
				argc--; argv++;
133
				if (argc <= 1)
134
					FATAL("no variable name");
135
				if (isclvar(argv[1]))
136
					setclvar(argv[1]);
137
				else
138
					FATAL("invalid -v option argument: %s", argv[1]);
139
			}
140
			break;
141
		case 'd':
142
			dbg = atoi(&argv[1][2]);
143
			if (dbg == 0)
144
				dbg = 1;
145
			printf("awk %s\n", version);
146
			break;
147
		case 'V':	/* added for exptools "standard" */
148
			printf("awk %s\n", version);
149
			exit(0);
150
			break;
151
		default:
152
			WARNING("unknown option %s ignored", argv[1]);
153
			break;
154
		}
155
65
		argc--;
156
65
		argv++;
157
	}
158
159
487
	if (safe) {
160
		if (pledge("stdio rpath flock cpath wpath", NULL) == -1) {
161
			fprintf(stderr, "%s: pledge: incorrect arguments\n",
162
			    cmdname);
163
			exit(1);
164
		}
165
	}
166
167
	/* argv[1] is now the first argument */
168
487
	if (npfile == 0) {	/* no -f; first argument is program */
169
471
		if (argc <= 1) {
170
			if (dbg)
171
				exit(0);
172
			FATAL("no program given");
173
		}
174
471
		   DPRINTF( ("program = |%s|\n", argv[1]) );
175
471
		lexprog = argv[1];
176
471
		argc--;
177
471
		argv++;
178
471
	}
179
487
	recinit(recsize);
180
487
	syminit();
181
487
	compile_time = 1;
182
487
	argv[0] = cmdname;	/* put prog name at front of arglist */
183
487
	   DPRINTF( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
184
487
	arginit(argc, argv);
185
487
	if (!safe)
186
487
		envinit(environ);
187
487
	yyparse();
188
487
	setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
189
487
	if (fs)
190
49
		*FS = qstring(fs, '\0');
191
487
	   DPRINTF( ("errorflag=%d\n", errorflag) );
192
487
	if (errorflag == 0) {
193
487
		compile_time = 0;
194
487
		run(winner);
195
487
	} else
196
		bracecheck();
197
487
	return(errorflag);
198
}
199
200
int pgetc(void)		/* get 1 character from awk program */
201
{
202
	int c;
203
204
149576
	for (;;) {
205
74796
		if (yyin == NULL) {
206
32
			if (curpfile >= npfile)
207
16
				return EOF;
208
16
			if (strcmp(pfile[curpfile], "-") == 0)
209
				yyin = stdin;
210
16
			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
211
				FATAL("can't open file %s", pfile[curpfile]);
212
16
			lineno = 1;
213
16
		}
214

299120
		if ((c = getc(yyin)) != EOF)
215
74764
			return c;
216
16
		if (yyin != stdin)
217
16
			fclose(yyin);
218
16
		yyin = NULL;
219
16
		curpfile++;
220
	}
221
74780
}
222
223
char *cursource(void)	/* current source file name */
224
{
225
	if (npfile > 0)
226
		return pfile[curpfile];
227
	else
228
		return NULL;
229
}