Annotation of src/usr.bin/awk/main.c, Revision 1.34
1.34 ! millert 1: /* $OpenBSD: main.c,v 1.33 2020/06/10 21:03:36 millert Exp $ */
1.1 tholo 2: /****************************************************************
1.4 kstailey 3: Copyright (C) Lucent Technologies 1997
1.1 tholo 4: All Rights Reserved
5:
6: Permission to use, copy, modify, and distribute this software and
7: its documentation for any purpose and without fee is hereby
8: granted, provided that the above copyright notice appear in all
9: copies and that both that the copyright notice and this
10: permission notice and warranty disclaimer appear in supporting
1.4 kstailey 11: documentation, and that the name Lucent Technologies or any of
12: its entities not be used in advertising or publicity pertaining
13: to distribution of the software without specific, written prior
14: permission.
15:
16: LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
18: IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
19: SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20: WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
21: IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23: THIS SOFTWARE.
1.1 tholo 24: ****************************************************************/
25:
1.34 ! millert 26: const char *version = "version 20191110";
1.1 tholo 27:
28: #define DEBUG
29: #include <stdio.h>
30: #include <ctype.h>
1.3 millert 31: #include <locale.h>
1.1 tholo 32: #include <stdlib.h>
33: #include <string.h>
34: #include <signal.h>
1.18 doug 35: #include <unistd.h>
1.1 tholo 36: #include "awk.h"
1.4 kstailey 37: #include "ytab.h"
1.1 tholo 38:
39: extern char **environ;
40: extern int nfields;
1.6 millert 41: extern char *__progname;
1.1 tholo 42:
43: int dbg = 0;
1.17 millert 44: Awkfloat srand_seed = 1;
1.1 tholo 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 */
1.34 ! millert 49: enum compile_states compile_time = ERROR_PRINTING;
1.1 tholo 50:
1.15 millert 51: #define MAX_PFILE 20 /* max number of -f's */
52:
1.8 millert 53: char *pfile[MAX_PFILE]; /* program filenames from -f's */
1.1 tholo 54: int npfile = 0; /* number of filenames */
55: int curpfile = 0; /* current filename */
56:
1.34 ! millert 57: bool safe = false; /* true => "safe" mode */
1.4 kstailey 58:
1.1 tholo 59: int main(int argc, char *argv[])
60: {
1.12 millert 61: const char *fs = NULL;
1.2 tholo 62:
1.19 deraadt 63: setlocale(LC_ALL, "");
64: setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
65:
1.20 tb 66: cmdname = __progname;
1.18 doug 67: if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1) {
68: fprintf(stderr, "%s: pledge: incorrect arguments\n",
69: cmdname);
70: exit(1);
71: }
72:
1.1 tholo 73: if (argc == 1) {
1.14 jmc 74: fprintf(stderr, "usage: %s [-safe] [-V] [-d[n]] [-F fs] "
75: "[-v var=value] [prog | -f progfile]\n\tfile ...\n",
1.10 aaron 76: cmdname);
1.1 tholo 77: exit(1);
78: }
79: signal(SIGFPE, fpecatch);
1.17 millert 80:
1.1 tholo 81: yyin = NULL;
82: symtab = makesymtab(NSYMTAB);
83: while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
1.4 kstailey 84: if (strcmp(argv[1], "--") == 0) { /* explicit end of args */
1.1 tholo 85: argc--;
86: argv++;
87: break;
88: }
89: switch (argv[1][1]) {
1.4 kstailey 90: case 's':
91: if (strcmp(argv[1], "-safe") == 0)
1.34 ! millert 92: safe = true;
1.4 kstailey 93: break;
1.1 tholo 94: case 'f': /* next argument is program filename */
1.17 millert 95: if (argv[1][2] != 0) { /* arg is -fsomething */
96: if (npfile >= MAX_PFILE - 1)
1.30 millert 97: FATAL("too many -f options");
1.17 millert 98: pfile[npfile++] = &argv[1][2];
99: } else { /* arg is -f something */
100: argc--; argv++;
101: if (argc <= 1)
102: FATAL("no program filename");
103: if (npfile >= MAX_PFILE - 1)
1.30 millert 104: FATAL("too many -f options");
1.17 millert 105: pfile[npfile++] = argv[1];
106: }
1.1 tholo 107: break;
108: case 'F': /* set field separator */
109: if (argv[1][2] != 0) { /* arg is -Fsomething */
110: if (argv[1][2] == 't' && argv[1][3] == 0) /* wart: t=>\t */
1.4 kstailey 111: fs = "\t";
1.1 tholo 112: else if (argv[1][2] != 0)
113: fs = &argv[1][2];
114: } else { /* arg is -F something */
115: argc--; argv++;
116: if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0) /* wart: t=>\t */
1.4 kstailey 117: fs = "\t";
1.1 tholo 118: else if (argc > 1 && argv[1][0] != 0)
119: fs = &argv[1][0];
120: }
121: if (fs == NULL || *fs == '\0')
1.9 millert 122: WARNING("field separator FS is empty");
1.1 tholo 123: break;
124: case 'v': /* -v a=1 to be done NOW. one -v for each */
1.17 millert 125: if (argv[1][2] != 0) { /* arg is -vsomething */
126: if (isclvar(&argv[1][2]))
127: setclvar(&argv[1][2]);
128: else
129: FATAL("invalid -v option argument: %s", &argv[1][2]);
130: } else { /* arg is -v something */
131: argc--; argv++;
132: if (argc <= 1)
133: FATAL("no variable name");
134: if (isclvar(argv[1]))
135: setclvar(argv[1]);
136: else
137: FATAL("invalid -v option argument: %s", argv[1]);
138: }
1.1 tholo 139: break;
140: case 'd':
141: dbg = atoi(&argv[1][2]);
142: if (dbg == 0)
143: dbg = 1;
144: printf("awk %s\n", version);
1.6 millert 145: break;
146: case 'V': /* added for exptools "standard" */
147: printf("awk %s\n", version);
148: exit(0);
1.1 tholo 149: break;
150: default:
1.9 millert 151: WARNING("unknown option %s ignored", argv[1]);
1.1 tholo 152: break;
153: }
154: argc--;
155: argv++;
156: }
1.18 doug 157:
158: if (safe) {
159: if (pledge("stdio rpath", NULL) == -1) {
160: fprintf(stderr, "%s: pledge: incorrect arguments\n",
161: cmdname);
162: exit(1);
163: }
164: }
165:
1.1 tholo 166: /* argv[1] is now the first argument */
167: if (npfile == 0) { /* no -f; first argument is program */
168: if (argc <= 1) {
169: if (dbg)
170: exit(0);
1.9 millert 171: FATAL("no program given");
1.1 tholo 172: }
1.21 deraadt 173: DPRINTF( ("program = |%s|\n", argv[1]) );
1.1 tholo 174: lexprog = argv[1];
175: argc--;
176: argv++;
177: }
178: recinit(recsize);
179: syminit();
1.34 ! millert 180: compile_time = COMPILING;
1.1 tholo 181: argv[0] = cmdname; /* put prog name at front of arglist */
1.21 deraadt 182: DPRINTF( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
1.1 tholo 183: arginit(argc, argv);
1.4 kstailey 184: if (!safe)
185: envinit(environ);
1.1 tholo 186: yyparse();
1.13 millert 187: setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
1.1 tholo 188: if (fs)
1.4 kstailey 189: *FS = qstring(fs, '\0');
1.21 deraadt 190: DPRINTF( ("errorflag=%d\n", errorflag) );
1.1 tholo 191: if (errorflag == 0) {
1.34 ! millert 192: compile_time = RUNNING;
1.1 tholo 193: run(winner);
194: } else
195: bracecheck();
196: return(errorflag);
197: }
198:
199: int pgetc(void) /* get 1 character from awk program */
200: {
201: int c;
202:
203: for (;;) {
204: if (yyin == NULL) {
205: if (curpfile >= npfile)
206: return EOF;
1.4 kstailey 207: if (strcmp(pfile[curpfile], "-") == 0)
1.1 tholo 208: yyin = stdin;
1.4 kstailey 209: else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
1.9 millert 210: FATAL("can't open file %s", pfile[curpfile]);
1.7 millert 211: lineno = 1;
1.1 tholo 212: }
213: if ((c = getc(yyin)) != EOF)
214: return c;
215: if (yyin != stdin)
216: fclose(yyin);
217: yyin = NULL;
218: curpfile++;
219: }
1.7 millert 220: }
221:
222: char *cursource(void) /* current source file name */
223: {
224: if (npfile > 0)
225: return pfile[curpfile];
226: else
227: return NULL;
1.1 tholo 228: }