• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************
2 Copyright (C) Lucent Technologies 1997
3 All Rights Reserved
4 
5 Permission to use, copy, modify, and distribute this software and
6 its documentation for any purpose and without fee is hereby
7 granted, provided that the above copyright notice appear in all
8 copies and that both that the copyright notice and this
9 permission notice and warranty disclaimer appear in supporting
10 documentation, and that the name Lucent Technologies or any of
11 its entities not be used in advertising or publicity pertaining
12 to distribution of the software without specific, written prior
13 permission.
14 
15 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22 THIS SOFTWARE.
23 ****************************************************************/
24 
25 const char	*version = "version 20200206";
26 
27 #define DEBUG
28 #include <stdio.h>
29 #include <ctype.h>
30 #include <locale.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <signal.h>
34 #include "awk.h"
35 #include "ytab.h"
36 
37 extern	char	**environ;
38 extern	int	nfields;
39 
40 int	dbg	= 0;
41 Awkfloat	srand_seed = 1;
42 char	*cmdname;	/* gets argv[0] for error messages */
43 extern	FILE	*yyin;	/* lex input file */
44 char	*lexprog;	/* points to program argument if it exists */
45 extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
46 enum compile_states	compile_time = ERROR_PRINTING;
47 
48 #define	MAX_PFILE	20	/* max number of -f's */
49 
50 char	*pfile[MAX_PFILE];	/* program filenames from -f's */
51 int	npfile = 0;	/* number of filenames */
52 int	curpfile = 0;	/* current filename */
53 
54 bool	safe = false;	/* true => "safe" mode */
55 
56 /* Can this work with recursive calls?  I don't think so.
57 void segvcatch(int n)
58 {
59 	FATAL("segfault.  Do you have an unbounded recursive call?", n);
60 }
61 */
62 
main(int argc,char * argv[])63 int main(int argc, char *argv[])
64 {
65 	const char *fs = NULL;
66 
67 	setlocale(LC_CTYPE, "");
68 	setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
69 	cmdname = argv[0];
70 	if (argc == 1) {
71 		fprintf(stderr,
72 		  "usage: %s [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]\n",
73 		  cmdname);
74 		exit(1);
75 	}
76 	signal(SIGFPE, fpecatch);
77 	/*signal(SIGSEGV, segvcatch); experiment */
78 
79 	srand_seed = 1;
80 	srandom((unsigned long) srand_seed);
81 
82 	yyin = NULL;
83 	symtab = makesymtab(NSYMTAB/NSYMTAB);
84 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
85 		if (strcmp(argv[1],"-version") == 0 || strcmp(argv[1],"--version") == 0) {
86 			printf("awk %s\n", version);
87 			exit(0);
88 			break;
89 		}
90 		if (strcmp(argv[1], "--") == 0) {	/* explicit end of args */
91 			argc--;
92 			argv++;
93 			break;
94 		}
95 		switch (argv[1][1]) {
96 		case 's':
97 			if (strcmp(argv[1], "-safe") == 0)
98 				safe = true;
99 			break;
100 		case 'f':	/* next argument is program filename */
101 			if (argv[1][2] != 0) {  /* arg is -fsomething */
102 				if (npfile >= MAX_PFILE - 1)
103 					FATAL("too many -f options");
104 				pfile[npfile++] = &argv[1][2];
105 			} else {		/* arg is -f something */
106 				argc--; argv++;
107 				if (argc <= 1)
108 					FATAL("no program filename");
109 				if (npfile >= MAX_PFILE - 1)
110 					FATAL("too many -f options");
111 				pfile[npfile++] = argv[1];
112 			}
113 			break;
114 		case 'F':	/* set field separator */
115 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
116 				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
117 					fs = "\t";
118 				else if (argv[1][2] != 0)
119 					fs = &argv[1][2];
120 			} else {		/* arg is -F something */
121 				argc--; argv++;
122 				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
123 					fs = "\t";
124 				else if (argc > 1 && argv[1][0] != 0)
125 					fs = &argv[1][0];
126 			}
127 			if (fs == NULL || *fs == '\0')
128 				WARNING("field separator FS is empty");
129 			break;
130 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
131 			if (argv[1][2] != 0) {  /* arg is -vsomething */
132 				if (isclvar(&argv[1][2]))
133 					setclvar(&argv[1][2]);
134 				else
135 					FATAL("invalid -v option argument: %s", &argv[1][2]);
136 			} else {		/* arg is -v something */
137 				argc--; argv++;
138 				if (argc <= 1)
139 					FATAL("no variable name");
140 				if (isclvar(argv[1]))
141 					setclvar(argv[1]);
142 				else
143 					FATAL("invalid -v option argument: %s", argv[1]);
144 			}
145 			break;
146 		case 'd':
147 			dbg = atoi(&argv[1][2]);
148 			if (dbg == 0)
149 				dbg = 1;
150 			printf("awk %s\n", version);
151 			break;
152 		default:
153 			WARNING("unknown option %s ignored", argv[1]);
154 			break;
155 		}
156 		argc--;
157 		argv++;
158 	}
159 	/* argv[1] is now the first argument */
160 	if (npfile == 0) {	/* no -f; first argument is program */
161 		if (argc <= 1) {
162 			if (dbg)
163 				exit(0);
164 			FATAL("no program given");
165 		}
166 		   dprintf( ("program = |%s|\n", argv[1]) );
167 		lexprog = argv[1];
168 		argc--;
169 		argv++;
170 	}
171 	recinit(recsize);
172 	syminit();
173 	compile_time = COMPILING;
174 	argv[0] = cmdname;	/* put prog name at front of arglist */
175 	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
176 	arginit(argc, argv);
177 	if (!safe)
178 		envinit(environ);
179 	yyparse();
180 	setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
181 	if (fs)
182 		*FS = qstring(fs, '\0');
183 	   dprintf( ("errorflag=%d\n", errorflag) );
184 	if (errorflag == 0) {
185 		compile_time = RUNNING;
186 		run(winner);
187 	} else
188 		bracecheck();
189 	return(errorflag);
190 }
191 
pgetc(void)192 int pgetc(void)		/* get 1 character from awk program */
193 {
194 	int c;
195 
196 	for (;;) {
197 		if (yyin == NULL) {
198 			if (curpfile >= npfile)
199 				return EOF;
200 			if (strcmp(pfile[curpfile], "-") == 0)
201 				yyin = stdin;
202 			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
203 				FATAL("can't open file %s", pfile[curpfile]);
204 			lineno = 1;
205 		}
206 		if ((c = getc(yyin)) != EOF)
207 			return c;
208 		if (yyin != stdin)
209 			fclose(yyin);
210 		yyin = NULL;
211 		curpfile++;
212 	}
213 }
214 
cursource(void)215 char *cursource(void)	/* current source file name */
216 {
217 	if (npfile > 0)
218 		return pfile[curpfile];
219 	else
220 		return NULL;
221 }
222