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