xref: /plan9-contrib/sys/src/cmd/awk/main.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 /*
2 Copyright (c) 1989 AT&T
3 	All Rights Reserved
4 
5 THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.
6 
7 The copyright notice above does not evidence any
8 actual or intended publication of such source code.
9 */
10 
11 char	*version = "version April 22, 1994";
12 
13 #define DEBUG
14 #include <stdio.h>
15 #include <ctype.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <signal.h>
19 #include "awk.h"
20 #include "y.tab.h"
21 
22 extern	char	**environ;
23 extern	int	nfields;
24 
25 int	dbg	= 0;
26 uchar	*cmdname;	/* gets argv[0] for error messages */
27 extern	FILE	*yyin;	/* lex input file */
28 uchar	*lexprog;	/* points to program argument if it exists */
29 extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
30 int	compile_time = 2;	/* for error printing: */
31 				/* 2 = cmdline, 1 = compile, 0 = running */
32 
33 uchar	*pfile[20];	/* program filenames from -f's */
34 int	npfile = 0;	/* number of filenames */
35 int	curpfile = 0;	/* current filename */
36 
37 
38 main(int argc, uchar *argv[])
39 {
40 	uchar *fs = NULL, *marg;
41 	int temp;
42 
43 	cmdname = argv[0];
44 	if (argc == 1) {
45 		fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [-mf n] [-mr n] [files]\n", cmdname);
46 		exit(1);
47 	}
48 	signal(SIGFPE, fpecatch);
49 	yyin = NULL;
50 	symtab = makesymtab(NSYMTAB);
51 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
52 		if (strcmp((char *) argv[1], "--") == 0) {	/* explicit end of args */
53 			argc--;
54 			argv++;
55 			break;
56 		}
57 		switch (argv[1][1]) {
58 		case 'f':	/* next argument is program filename */
59 			argc--;
60 			argv++;
61 			if (argc <= 1)
62 				ERROR "no program filename" FATAL;
63 			pfile[npfile++] = argv[1];
64 			break;
65 		case 'F':	/* set field separator */
66 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
67 				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
68 					fs = (uchar *) "\t";
69 				else if (argv[1][2] != 0)
70 					fs = &argv[1][2];
71 			} else {		/* arg is -F something */
72 				argc--; argv++;
73 				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
74 					fs = (uchar *) "\t";
75 				else if (argc > 1 && argv[1][0] != 0)
76 					fs = &argv[1][0];
77 			}
78 			if (fs == NULL || *fs == '\0')
79 				ERROR "field separator FS is empty" WARNING;
80 			break;
81 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
82 			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
83 				setclvar(argv[1]);
84 			break;
85 		case 'm':	/* more memory: -mr=record, -mf=fields */
86 			marg = argv[1];
87 			if (argv[1][3])
88 				temp = atoi(&argv[1][3]);
89 			else {
90 				argv++; argc--;
91 				temp = atoi(&argv[1][0]);
92 			}
93 			switch (marg[2]) {
94 			case 'r':	recsize = temp; break;
95 			case 'f':	nfields = temp; break;
96 			default: ERROR "unknown option %s\n", marg FATAL;
97 			}
98 			break;
99 		case 'd':
100 			dbg = atoi(&argv[1][2]);
101 			if (dbg == 0)
102 				dbg = 1;
103 			printf("awk %s\n", version);
104 			break;
105 		default:
106 			ERROR "unknown option %s ignored", argv[1] WARNING;
107 			break;
108 		}
109 		argc--;
110 		argv++;
111 	}
112 	/* argv[1] is now the first argument */
113 	if (npfile == 0) {	/* no -f; first argument is program */
114 		if (argc <= 1) {
115 			if (dbg)
116 				exit(0);
117 			ERROR "no program given" FATAL;
118 		}
119 		dprintf( ("program = |%s|\n", argv[1]) );
120 		lexprog = argv[1];
121 		argc--;
122 		argv++;
123 	}
124 	recinit(recsize);
125 	syminit();
126 	compile_time = 1;
127 	argv[0] = cmdname;	/* put prog name at front of arglist */
128 	dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
129 	arginit(argc, argv);
130 	envinit(environ);
131 	yyparse();
132 	if (fs)
133 		*FS = tostring(qstring(fs, '\0'));
134 	dprintf( ("errorflag=%d\n", errorflag) );
135 	if (errorflag == 0) {
136 		compile_time = 0;
137 		run(winner);
138 	} else
139 		bracecheck();
140 	return(errorflag);
141 }
142 
143 pgetc(void)		/* get 1 character from awk program */
144 {
145 	int c;
146 
147 	for (;;) {
148 		if (yyin == NULL) {
149 			if (curpfile >= npfile)
150 				return EOF;
151 			if (strcmp((char *) pfile[curpfile], "-") == 0)
152 				yyin = stdin;
153 			else if ((yyin = fopen((char *) pfile[curpfile], "r")) == NULL)
154 				ERROR "can't open file %s", pfile[curpfile] FATAL;
155 		}
156 		if ((c = getc(yyin)) != EOF)
157 			return c;
158 		if (yyin != stdin)
159 			fclose(yyin);
160 		yyin = NULL;
161 		curpfile++;
162 	}
163 }
164