Import awk-20110810.
[dragonfly.git] / contrib / awk / main.c
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 20110810";
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 int     compile_time = 2;       /* for error printing: */
47                                 /* 2 = cmdline, 1 = compile, 0 = running */
48
49 #define MAX_PFILE       20      /* max number of -f's */
50
51 char    *pfile[MAX_PFILE];      /* program filenames from -f's */
52 int     npfile = 0;     /* number of filenames */
53 int     curpfile = 0;   /* current filename */
54
55 int     safe    = 0;    /* 1 => "safe" mode */
56
57 int main(int argc, char *argv[])
58 {
59         const char *fs = NULL;
60
61         setlocale(LC_CTYPE, "");
62         setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
63         cmdname = argv[0];
64         if (argc == 1) {
65                 fprintf(stderr, 
66                   "usage: %s [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]\n", 
67                   cmdname);
68                 exit(1);
69         }
70         signal(SIGFPE, fpecatch);
71
72         srand_seed = 1;
73         srand(srand_seed);
74
75         yyin = NULL;
76         symtab = makesymtab(NSYMTAB/NSYMTAB);
77         while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
78                 if (strcmp(argv[1],"-version") == 0 || strcmp(argv[1],"--version") == 0) {
79                         printf("awk %s\n", version);
80                         exit(0);
81                         break;
82                 }
83                 if (strncmp(argv[1], "--", 2) == 0) {   /* explicit end of args */
84                         argc--;
85                         argv++;
86                         break;
87                 }
88                 switch (argv[1][1]) {
89                 case 's':
90                         if (strcmp(argv[1], "-safe") == 0)
91                                 safe = 1;
92                         break;
93                 case 'f':       /* next argument is program filename */
94                         if (argv[1][2] != 0) {  /* arg is -fsomething */
95                                 if (npfile >= MAX_PFILE - 1)
96                                         FATAL("too many -f options"); 
97                                 pfile[npfile++] = &argv[1][2];
98                         } else {                /* arg is -f something */
99                                 argc--; argv++;
100                                 if (argc <= 1)
101                                         FATAL("no program filename");
102                                 if (npfile >= MAX_PFILE - 1)
103                                         FATAL("too many -f options"); 
104                                 pfile[npfile++] = argv[1];
105                         }
106                         break;
107                 case 'F':       /* set field separator */
108                         if (argv[1][2] != 0) {  /* arg is -Fsomething */
109                                 if (argv[1][2] == 't' && argv[1][3] == 0)       /* wart: t=>\t */
110                                         fs = "\t";
111                                 else if (argv[1][2] != 0)
112                                         fs = &argv[1][2];
113                         } else {                /* arg is -F something */
114                                 argc--; argv++;
115                                 if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)   /* wart: t=>\t */
116                                         fs = "\t";
117                                 else if (argc > 1 && argv[1][0] != 0)
118                                         fs = &argv[1][0];
119                         }
120                         if (fs == NULL || *fs == '\0')
121                                 WARNING("field separator FS is empty");
122                         break;
123                 case 'v':       /* -v a=1 to be done NOW.  one -v for each */
124                         if (argv[1][2] != 0) {  /* arg is -vsomething */
125                                 if (isclvar(&argv[1][2]))
126                                         setclvar(&argv[1][2]);
127                                 else
128                                         FATAL("invalid -v option argument: %s", &argv[1][2]);
129                         } else {                /* arg is -v something */
130                                 argc--; argv++;
131                                 if (argc <= 1)
132                                         FATAL("no variable name");
133                                 if (isclvar(argv[1]))
134                                         setclvar(argv[1]);
135                                 else
136                                         FATAL("invalid -v option argument: %s", argv[1]);
137                         }
138                         break;
139                 case 'd':
140                         dbg = atoi(&argv[1][2]);
141                         if (dbg == 0)
142                                 dbg = 1;
143                         printf("awk %s\n", version);
144                         break;
145                 default:
146                         WARNING("unknown option %s ignored", argv[1]);
147                         break;
148                 }
149                 argc--;
150                 argv++;
151         }
152         /* argv[1] is now the first argument */
153         if (npfile == 0) {      /* no -f; first argument is program */
154                 if (argc <= 1) {
155                         if (dbg)
156                                 exit(0);
157                         FATAL("no program given");
158                 }
159                    dprintf( ("program = |%s|\n", argv[1]) );
160                 lexprog = argv[1];
161                 argc--;
162                 argv++;
163         }
164         recinit(recsize);
165         syminit();
166         compile_time = 1;
167         argv[0] = cmdname;      /* put prog name at front of arglist */
168            dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
169         arginit(argc, argv);
170         if (!safe)
171                 envinit(environ);
172         yyparse();
173         setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
174         if (fs)
175                 *FS = qstring(fs, '\0');
176            dprintf( ("errorflag=%d\n", errorflag) );
177         if (errorflag == 0) {
178                 compile_time = 0;
179                 run(winner);
180         } else
181                 bracecheck();
182         return(errorflag);
183 }
184
185 int pgetc(void)         /* get 1 character from awk program */
186 {
187         int c;
188
189         for (;;) {
190                 if (yyin == NULL) {
191                         if (curpfile >= npfile)
192                                 return EOF;
193                         if (strcmp(pfile[curpfile], "-") == 0)
194                                 yyin = stdin;
195                         else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
196                                 FATAL("can't open file %s", pfile[curpfile]);
197                         lineno = 1;
198                 }
199                 if ((c = getc(yyin)) != EOF)
200                         return c;
201                 if (yyin != stdin)
202                         fclose(yyin);
203                 yyin = NULL;
204                 curpfile++;
205         }
206 }
207
208 char *cursource(void)   /* current source file name */
209 {
210         if (npfile > 0)
211                 return pfile[curpfile];
212         else
213                 return NULL;
214 }