GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/awk/main.c Lines: 57 114 50.0 %
Date: 2016-12-06 Branches: 34 101 33.7 %

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
31
{
62
31
	const char *fs = NULL;
63
64
31
	setlocale(LC_ALL, "");
65
31
	setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
66
67
31
	if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1) {
68
		fprintf(stderr, "%s: pledge: incorrect arguments\n",
69
		    cmdname);
70
		exit(1);
71
	}
72
73
31
	cmdname = __progname;
74
31
	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
31
	signal(SIGFPE, fpecatch);
81
82
31
	yyin = NULL;
83
31
	symtab = makesymtab(NSYMTAB);
84

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

2
		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
2
			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
2
				argc--; argv++;
102
2
				if (argc <= 1)
103
					FATAL("no program filename");
104
2
				if (npfile >= MAX_PFILE - 1)
105
					FATAL("too many -f options");
106
2
				pfile[npfile++] = argv[1];
107
			}
108
			break;
109
		case 'F':	/* set field separator */
110
			if (argv[1][2] != 0) {	/* arg is -Fsomething */
111
				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
112
					fs = "\t";
113
				else if (argv[1][2] != 0)
114
					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
			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
2
		argc--;
156
2
		argv++;
157
	}
158
159
31
	if (safe) {
160
		if (pledge("stdio rpath wpath cpath", 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
31
	if (npfile == 0) {	/* no -f; first argument is program */
169
29
		if (argc <= 1) {
170
			if (dbg)
171
				exit(0);
172
			FATAL("no program given");
173
		}
174
29
		   dprintf( ("program = |%s|\n", argv[1]) );
175
29
		lexprog = argv[1];
176
29
		argc--;
177
29
		argv++;
178
	}
179
31
	recinit(recsize);
180
31
	syminit();
181
31
	compile_time = 1;
182
31
	argv[0] = cmdname;	/* put prog name at front of arglist */
183
31
	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
184
31
	arginit(argc, argv);
185
31
	if (!safe)
186
31
		envinit(environ);
187
31
	yyparse();
188
31
	setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
189
31
	if (fs)
190
		*FS = qstring(fs, '\0');
191
31
	   dprintf( ("errorflag=%d\n", errorflag) );
192
31
	if (errorflag == 0) {
193
31
		compile_time = 0;
194
31
		run(winner);
195
	} else
196
		bracecheck();
197
31
	return(errorflag);
198
}
199
200
int pgetc(void)		/* get 1 character from awk program */
201
7809
{
202
	int c;
203
204
	for (;;) {
205
7809
		if (yyin == NULL) {
206
4
			if (curpfile >= npfile)
207
2
				return EOF;
208
2
			if (strcmp(pfile[curpfile], "-") == 0)
209
				yyin = stdin;
210
2
			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
211
				FATAL("can't open file %s", pfile[curpfile]);
212
2
			lineno = 1;
213
		}
214

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