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