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