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

Line Branch Exec Source
1
/*	$OpenBSD: main.c,v 1.19 2015/10/22 04:08:17 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
1962
	setlocale(LC_ALL, "");
65
981
	setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
66
67
981
	if (pledge("stdio rpath wpath cpath proc exec flock", NULL) == -1) {
68
		fprintf(stderr, "%s: pledge: incorrect arguments\n",
69
		    cmdname);
70
		exit(1);
71
	}
72
73
981
	cmdname = __progname;
74
981
	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
981
	signal(SIGFPE, fpecatch);
81
82
981
	yyin = NULL;
83
981
	symtab = makesymtab(NSYMTAB);
84

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

71
		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
20
			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
20
				argc--; argv++;
102
20
				if (argc <= 1)
103
					FATAL("no program filename");
104
20
				if (npfile >= MAX_PFILE - 1)
105
					FATAL("too many -f options");
106
20
				pfile[npfile++] = argv[1];
107
			}
108
20
			break;
109
		case 'F':	/* set field separator */
110
51
			if (argv[1][2] != 0) {	/* arg is -Fsomething */
111

54
				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
112
3
					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

102
			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
71
		argc--;
156
71
		argv++;
157
	}
158
159
981
	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
981
	if (npfile == 0) {	/* no -f; first argument is program */
169
961
		if (argc <= 1) {
170
			if (dbg)
171
				exit(0);
172
			FATAL("no program given");
173
		}
174
961
		   dprintf( ("program = |%s|\n", argv[1]) );
175
961
		lexprog = argv[1];
176
961
		argc--;
177
961
		argv++;
178
961
	}
179
981
	recinit(recsize);
180
981
	syminit();
181
981
	compile_time = 1;
182
981
	argv[0] = cmdname;	/* put prog name at front of arglist */
183
981
	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
184
981
	arginit(argc, argv);
185
981
	if (!safe)
186
981
		envinit(environ);
187
981
	yyparse();
188
981
	setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
189
981
	if (fs)
190
51
		*FS = qstring(fs, '\0');
191
981
	   dprintf( ("errorflag=%d\n", errorflag) );
192
981
	if (errorflag == 0) {
193
981
		compile_time = 0;
194
981
		run(winner);
195
981
	} else
196
		bracecheck();
197
981
	return(errorflag);
198
}
199
200
int pgetc(void)		/* get 1 character from awk program */
201
{
202
	int c;
203
204
180522
	for (;;) {
205
90271
		if (yyin == NULL) {
206
40
			if (curpfile >= npfile)
207
20
				return EOF;
208
20
			if (strcmp(pfile[curpfile], "-") == 0)
209
				yyin = stdin;
210
20
			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
211
				FATAL("can't open file %s", pfile[curpfile]);
212
20
			lineno = 1;
213
20
		}
214

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