xref: /original-bsd/contrib/awk.research/main.c (revision 333da485)
1 /****************************************************************
2 Copyright (C) AT&T 1993
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 of AT&T or any of its entities
11 not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior
13 permission.
14 
15 AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 IN NO EVENT SHALL AT&T 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 char	*version = "version July 23, 1993";
26 
27 #define DEBUG
28 #include <stdio.h>
29 #include <ctype.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <signal.h>
33 #include "awk.h"
34 #include "y.tab.h"
35 
36 extern	char	**environ;
37 extern	int	nfields;
38 
39 int	dbg	= 0;
40 uchar	*cmdname;	/* gets argv[0] for error messages */
41 extern	FILE	*yyin;	/* lex input file */
42 uchar	*lexprog;	/* points to program argument if it exists */
43 extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
44 int	compile_time = 2;	/* for error printing: */
45 				/* 2 = cmdline, 1 = compile, 0 = running */
46 
47 uchar	*pfile[20];	/* program filenames from -f's */
48 int	npfile = 0;	/* number of filenames */
49 int	curpfile = 0;	/* current filename */
50 
51 
52 main(int argc, uchar *argv[])
53 {
54 	uchar *fs = NULL, *marg;
55 	int temp;
56 
57 	cmdname = argv[0];
58 	if (argc == 1) {
59 		fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [-mf n] [-mr n] [files]\n", cmdname);
60 		exit(1);
61 	}
62 	signal(SIGFPE, fpecatch);
63 	yyin = NULL;
64 	symtab = makesymtab(NSYMTAB);
65 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
66 		if (strcmp((char *) argv[1], "--") == 0) {	/* explicit end of args */
67 			argc--;
68 			argv++;
69 			break;
70 		}
71 		switch (argv[1][1]) {
72 		case 'f':	/* next argument is program filename */
73 			argc--;
74 			argv++;
75 			if (argc <= 1)
76 				ERROR "no program filename" FATAL;
77 			pfile[npfile++] = argv[1];
78 			break;
79 		case 'F':	/* set field separator */
80 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
81 				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
82 					fs = (uchar *) "\t";
83 				else if (argv[1][2] != 0)
84 					fs = &argv[1][2];
85 			} else {		/* arg is -F something */
86 				argc--; argv++;
87 				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
88 					fs = (uchar *) "\t";
89 				else if (argc > 1 && argv[1][0] != 0)
90 					fs = &argv[1][0];
91 			}
92 			if (fs == NULL || *fs == '\0')
93 				ERROR "field separator FS is empty" WARNING;
94 			break;
95 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
96 			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
97 				setclvar(argv[1]);
98 			break;
99 		case 'm':	/* more memory: -mr=record, -mf=fields */
100 			marg = argv[1];
101 			if (argv[1][3])
102 				temp = atoi(&argv[1][3]);
103 			else {
104 				argv++; argc--;
105 				temp = atoi(&argv[1][0]);
106 			}
107 			switch (marg[2]) {
108 			case 'r':	recsize = temp; break;
109 			case 'f':	nfields = temp; break;
110 			default: ERROR "unknown option %s\n", marg FATAL;
111 			}
112 			break;
113 		case 'd':
114 			dbg = atoi(&argv[1][2]);
115 			if (dbg == 0)
116 				dbg = 1;
117 			printf("awk %s\n", version);
118 			break;
119 		default:
120 			ERROR "unknown option %s ignored", argv[1] WARNING;
121 			break;
122 		}
123 		argc--;
124 		argv++;
125 	}
126 	/* argv[1] is now the first argument */
127 	if (npfile == 0) {	/* no -f; first argument is program */
128 		if (argc <= 1) {
129 			if (dbg)
130 				exit(0);
131 			ERROR "no program given" FATAL;
132 		}
133 		dprintf( ("program = |%s|\n", argv[1]) );
134 		lexprog = argv[1];
135 		argc--;
136 		argv++;
137 	}
138 	recinit(recsize);
139 	syminit();
140 	compile_time = 1;
141 	argv[0] = cmdname;	/* put prog name at front of arglist */
142 	dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
143 	arginit(argc, argv);
144 	envinit(environ);
145 	yyparse();
146 	if (fs)
147 		*FS = tostring(qstring(fs, '\0'));
148 	dprintf( ("errorflag=%d\n", errorflag) );
149 	if (errorflag == 0) {
150 		compile_time = 0;
151 		run(winner);
152 	} else
153 		bracecheck();
154 	return(errorflag);
155 }
156 
157 pgetc(void)		/* get 1 character from awk program */
158 {
159 	int c;
160 
161 	for (;;) {
162 		if (yyin == NULL) {
163 			if (curpfile >= npfile)
164 				return EOF;
165 			if (strcmp((char *) pfile[curpfile], "-") == 0)
166 				yyin = stdin;
167 			else if ((yyin = fopen((char *) pfile[curpfile], "r")) == NULL)
168 				ERROR "can't open file %s", pfile[curpfile] FATAL;
169 		}
170 		if ((c = getc(yyin)) != EOF)
171 			return c;
172 		if (yyin != stdin)
173 			fclose(yyin);
174 		yyin = NULL;
175 		curpfile++;
176 	}
177 }
178 
179 void init_input_source(void)
180 {
181 	if (yyin == NULL) {
182 		if (pfile[curpfile] == 0)
183 			return;
184 		if (strcmp((char *) pfile[curpfile], "-") == 0)
185 			yyin = stdin;
186 		else if ((yyin = fopen((char *) pfile[curpfile], "r")) == NULL)
187 			ERROR "can't open file %s", pfile[curpfile] FATAL;
188 	}
189 }
190