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