Sync usage with man page.
[netbsd-mini2440.git] / dist / nawk / main.c
blobf40dd3c9d0050a4c19e0dbbb5688a1e3e8647741
1 /****************************************************************
2 Copyright (C) Lucent Technologies 1997
3 All Rights Reserved
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.
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 ****************************************************************/
25 const char *version = "version 20070501";
27 #if HAVE_NBTOOL_CONFIG_H
28 #include "nbtool_config.h"
29 #endif
31 #define DEBUG
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <locale.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <signal.h>
38 #include "awk.h"
39 #include "awkgram.h"
41 extern char **environ;
42 extern int nfields;
44 int dbg = 0;
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 */
52 #define MAX_PFILE 20 /* max number of -f's */
54 char *pfile[MAX_PFILE]; /* program filenames from -f's */
55 int npfile = 0; /* number of filenames */
56 int curpfile = 0; /* current filename */
58 int safe = 0; /* 1 => "safe" mode */
60 static char *
61 setfs(char *p)
63 #ifdef notdef
64 /* wart: t=>\t */
65 if (p[0] == 't' && p[1] == 0)
66 return "\t";
67 else
68 #endif
69 if (p[0] != 0)
70 return p;
71 return NULL;
74 static void fpecatch(int n
75 #ifdef SA_SIGINFO
76 , siginfo_t *si, void *uc
77 #endif
80 #ifdef SA_SIGINFO
81 static const char *emsg[] = {
82 "Unknown error",
83 "Integer divide by zero",
84 "Integer overflow",
85 "Floating point divide by zero",
86 "Floating point overflow",
87 "Floating point underflow",
88 "Floating point inexact result",
89 "Invalid Floating point operation",
90 "Subscript out of range",
92 #endif
93 FATAL("floating point exception"
94 #ifdef SA_SIGINFO
95 ": %s\n", emsg[si->si_code >= 1 && si->si_code <= 8 ?
96 si->si_code : 0]
97 #endif
101 int main(int argc, char *argv[])
103 const char *fs = NULL;
105 setlocale(LC_ALL, "");
106 setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
107 cmdname = argv[0];
108 if (argc == 1) {
109 fprintf(stderr,
110 "usage: %s [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]\n",
111 cmdname);
112 exit(1);
115 #ifdef SA_SIGINFO
117 struct sigaction sa;
118 sa.sa_sigaction = fpecatch;
119 sa.sa_flags = SA_SIGINFO;
120 sigemptyset(&sa.sa_mask);
121 (void)sigaction(SIGFPE, &sa, NULL);
123 #else
124 (void)signal(SIGFPE, fpecatch);
125 #endif
126 yyin = NULL;
127 symtab = makesymtab(NSYMTAB/NSYMTAB);
128 while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
129 if (strcmp(argv[1],"-version") == 0 || strcmp(argv[1],"--version") == 0) {
130 printf("awk %s\n", version);
131 exit(0);
132 break;
134 if (strncmp(argv[1], "--", 2) == 0) { /* explicit end of args */
135 argc--;
136 argv++;
137 break;
139 switch (argv[1][1]) {
140 case 's':
141 if (strcmp(argv[1], "-safe") == 0)
142 safe = 1;
143 break;
144 case 'f': /* next argument is program filename */
145 argc--;
146 argv++;
147 if (argc <= 1)
148 FATAL("no program filename");
149 if (npfile >= MAX_PFILE - 1)
150 FATAL("too many -f options");
151 pfile[npfile++] = argv[1];
152 break;
153 case 'F': /* set field separator */
154 if (argv[1][2] != 0) { /* arg is -Fsomething */
155 fs = setfs(argv[1] + 2);
156 } else { /* arg is -F something */
157 argc--; argv++;
158 if (argc > 1)
159 fs = setfs(argv[1]);
161 if (fs == NULL || *fs == '\0')
162 WARNING("field separator FS is empty");
163 break;
164 case 'v': /* -v a=1 to be done NOW. one -v for each */
165 if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
166 setclvar(argv[1]);
167 break;
168 case 'd':
169 dbg = atoi(&argv[1][2]);
170 if (dbg == 0)
171 dbg = 1;
172 printf("awk %s\n", version);
173 break;
174 default:
175 WARNING("unknown option %s ignored", argv[1]);
176 break;
178 argc--;
179 argv++;
181 /* argv[1] is now the first argument */
182 if (npfile == 0) { /* no -f; first argument is program */
183 if (argc <= 1) {
184 if (dbg)
185 exit(0);
186 FATAL("no program given");
188 dprintf( ("program = |%s|\n", argv[1]) );
189 lexprog = argv[1];
190 argc--;
191 argv++;
193 recinit(recsize);
194 syminit();
195 compile_time = 1;
196 argv[0] = cmdname; /* put prog name at front of arglist */
197 dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
198 arginit(argc, argv);
199 if (!safe)
200 envinit(environ);
201 yyparse();
202 setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
203 if (fs)
204 *FS = qstring(fs, '\0');
205 dprintf( ("errorflag=%d\n", errorflag) );
206 if (errorflag == 0) {
207 compile_time = 0;
208 run(winner);
209 } else
210 bracecheck();
211 return(errorflag);
214 int pgetc(void) /* get 1 character from awk program */
216 int c;
218 for (;;) {
219 if (yyin == NULL) {
220 if (curpfile >= npfile)
221 return EOF;
222 if (strcmp(pfile[curpfile], "-") == 0)
223 yyin = stdin;
224 else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
225 FATAL("can't open file %s", pfile[curpfile]);
226 lineno = 1;
228 if ((c = getc(yyin)) != EOF)
229 return c;
230 if (yyin != stdin)
231 fclose(yyin);
232 yyin = NULL;
233 curpfile++;
237 char *cursource(void) /* current source file name */
239 if (npfile > 0)
240 return pfile[curpfile];
241 else
242 return NULL;