xref: /csrg-svn/contrib/awk.research/main.c (revision 65396)
165391Sbostic /****************************************************************
265391Sbostic Copyright (C) AT&T 1993
365391Sbostic All Rights Reserved
465391Sbostic 
565391Sbostic Permission to use, copy, modify, and distribute this software and
665391Sbostic its documentation for any purpose and without fee is hereby
765391Sbostic granted, provided that the above copyright notice appear in all
865391Sbostic copies and that both that the copyright notice and this
965391Sbostic permission notice and warranty disclaimer appear in supporting
1065391Sbostic documentation, and that the name of AT&T or any of its entities
1165391Sbostic not be used in advertising or publicity pertaining to
1265391Sbostic distribution of the software without specific, written prior
1365391Sbostic permission.
1465391Sbostic 
1565391Sbostic AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1665391Sbostic INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
1765391Sbostic IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
1865391Sbostic SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1965391Sbostic WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
2065391Sbostic IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
2165391Sbostic ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
2265391Sbostic THIS SOFTWARE.
2365391Sbostic ****************************************************************/
2465391Sbostic 
2565391Sbostic char	*version = "version July 23, 1993";
2665391Sbostic 
2765391Sbostic #define DEBUG
2865391Sbostic #include <stdio.h>
2965391Sbostic #include <ctype.h>
3065391Sbostic #include <stdlib.h>
3165391Sbostic #include <string.h>
3265391Sbostic #include <signal.h>
3365391Sbostic #include "awk.h"
3465391Sbostic #include "y.tab.h"
3565391Sbostic 
3665391Sbostic extern	char	**environ;
3765391Sbostic extern	int	nfields;
3865391Sbostic 
3965391Sbostic int	dbg	= 0;
4065391Sbostic uchar	*cmdname;	/* gets argv[0] for error messages */
4165391Sbostic extern	FILE	*yyin;	/* lex input file */
4265391Sbostic uchar	*lexprog;	/* points to program argument if it exists */
4365391Sbostic extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
4465391Sbostic int	compile_time = 2;	/* for error printing: */
4565391Sbostic 				/* 2 = cmdline, 1 = compile, 0 = running */
4665391Sbostic 
4765391Sbostic uchar	*pfile[20];	/* program filenames from -f's */
4865391Sbostic int	npfile = 0;	/* number of filenames */
4965391Sbostic int	curpfile = 0;	/* current filename */
5065391Sbostic 
5165391Sbostic 
main(int argc,uchar * argv[])5265391Sbostic main(int argc, uchar *argv[])
5365391Sbostic {
5465391Sbostic 	uchar *fs = NULL, *marg;
5565391Sbostic 	int temp;
5665391Sbostic 
5765391Sbostic 	cmdname = argv[0];
5865391Sbostic 	if (argc == 1) {
5965391Sbostic 		fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [-mf n] [-mr n] [files]\n", cmdname);
6065391Sbostic 		exit(1);
6165391Sbostic 	}
6265391Sbostic 	signal(SIGFPE, fpecatch);
6365391Sbostic 	yyin = NULL;
6465391Sbostic 	symtab = makesymtab(NSYMTAB);
6565391Sbostic 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
6665391Sbostic 		if (strcmp((char *) argv[1], "--") == 0) {	/* explicit end of args */
6765391Sbostic 			argc--;
6865391Sbostic 			argv++;
6965391Sbostic 			break;
7065391Sbostic 		}
7165391Sbostic 		switch (argv[1][1]) {
7265391Sbostic 		case 'f':	/* next argument is program filename */
7365391Sbostic 			argc--;
7465391Sbostic 			argv++;
7565391Sbostic 			if (argc <= 1)
7665391Sbostic 				ERROR "no program filename" FATAL;
7765391Sbostic 			pfile[npfile++] = argv[1];
7865391Sbostic 			break;
7965391Sbostic 		case 'F':	/* set field separator */
8065391Sbostic 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
8165391Sbostic 				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
8265391Sbostic 					fs = (uchar *) "\t";
8365391Sbostic 				else if (argv[1][2] != 0)
8465391Sbostic 					fs = &argv[1][2];
8565391Sbostic 			} else {		/* arg is -F something */
8665391Sbostic 				argc--; argv++;
8765391Sbostic 				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
8865391Sbostic 					fs = (uchar *) "\t";
8965391Sbostic 				else if (argc > 1 && argv[1][0] != 0)
9065391Sbostic 					fs = &argv[1][0];
9165391Sbostic 			}
9265391Sbostic 			if (fs == NULL || *fs == '\0')
9365391Sbostic 				ERROR "field separator FS is empty" WARNING;
9465391Sbostic 			break;
9565391Sbostic 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
9665391Sbostic 			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
9765391Sbostic 				setclvar(argv[1]);
9865391Sbostic 			break;
9965391Sbostic 		case 'm':	/* more memory: -mr=record, -mf=fields */
10065391Sbostic 			marg = argv[1];
10165391Sbostic 			if (argv[1][3])
10265391Sbostic 				temp = atoi(&argv[1][3]);
10365391Sbostic 			else {
10465391Sbostic 				argv++; argc--;
10565391Sbostic 				temp = atoi(&argv[1][0]);
10665391Sbostic 			}
10765391Sbostic 			switch (marg[2]) {
10865391Sbostic 			case 'r':	recsize = temp; break;
10965391Sbostic 			case 'f':	nfields = temp; break;
11065391Sbostic 			default: ERROR "unknown option %s\n", marg FATAL;
11165391Sbostic 			}
11265391Sbostic 			break;
11365391Sbostic 		case 'd':
11465391Sbostic 			dbg = atoi(&argv[1][2]);
11565391Sbostic 			if (dbg == 0)
11665391Sbostic 				dbg = 1;
11765391Sbostic 			printf("awk %s\n", version);
11865391Sbostic 			break;
11965391Sbostic 		default:
12065391Sbostic 			ERROR "unknown option %s ignored", argv[1] WARNING;
12165391Sbostic 			break;
12265391Sbostic 		}
12365391Sbostic 		argc--;
12465391Sbostic 		argv++;
12565391Sbostic 	}
12665391Sbostic 	/* argv[1] is now the first argument */
12765391Sbostic 	if (npfile == 0) {	/* no -f; first argument is program */
12865391Sbostic 		if (argc <= 1) {
12965391Sbostic 			if (dbg)
13065391Sbostic 				exit(0);
13165391Sbostic 			ERROR "no program given" FATAL;
13265391Sbostic 		}
13365391Sbostic 		dprintf( ("program = |%s|\n", argv[1]) );
13465391Sbostic 		lexprog = argv[1];
13565391Sbostic 		argc--;
13665391Sbostic 		argv++;
13765391Sbostic 	}
13865391Sbostic 	recinit(recsize);
13965391Sbostic 	syminit();
14065391Sbostic 	compile_time = 1;
14165391Sbostic 	argv[0] = cmdname;	/* put prog name at front of arglist */
14265391Sbostic 	dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
14365391Sbostic 	arginit(argc, argv);
14465391Sbostic 	envinit(environ);
14565391Sbostic 	yyparse();
14665391Sbostic 	if (fs)
14765391Sbostic 		*FS = tostring(qstring(fs, '\0'));
14865391Sbostic 	dprintf( ("errorflag=%d\n", errorflag) );
14965391Sbostic 	if (errorflag == 0) {
15065391Sbostic 		compile_time = 0;
15165391Sbostic 		run(winner);
15265391Sbostic 	} else
15365391Sbostic 		bracecheck();
15465391Sbostic 	return(errorflag);
15565391Sbostic }
15665391Sbostic 
pgetc(void)15765391Sbostic pgetc(void)		/* get 1 character from awk program */
15865391Sbostic {
15965391Sbostic 	int c;
16065391Sbostic 
16165391Sbostic 	for (;;) {
16265391Sbostic 		if (yyin == NULL) {
16365391Sbostic 			if (curpfile >= npfile)
16465391Sbostic 				return EOF;
16565391Sbostic 			if (strcmp((char *) pfile[curpfile], "-") == 0)
16665391Sbostic 				yyin = stdin;
16765391Sbostic 			else if ((yyin = fopen((char *) pfile[curpfile], "r")) == NULL)
16865391Sbostic 				ERROR "can't open file %s", pfile[curpfile] FATAL;
16965391Sbostic 		}
17065391Sbostic 		if ((c = getc(yyin)) != EOF)
17165391Sbostic 			return c;
17265391Sbostic 		if (yyin != stdin)
17365391Sbostic 			fclose(yyin);
17465391Sbostic 		yyin = NULL;
17565391Sbostic 		curpfile++;
17665391Sbostic 	}
17765391Sbostic }
178*65396Sbostic 
init_input_source(void)179*65396Sbostic void init_input_source(void)
180*65396Sbostic {
181*65396Sbostic 	if (yyin == NULL) {
182*65396Sbostic 		if (pfile[curpfile] == 0)
183*65396Sbostic 			return;
184*65396Sbostic 		if (strcmp((char *) pfile[curpfile], "-") == 0)
185*65396Sbostic 			yyin = stdin;
186*65396Sbostic 		else if ((yyin = fopen((char *) pfile[curpfile], "r")) == NULL)
187*65396Sbostic 			ERROR "can't open file %s", pfile[curpfile] FATAL;
188*65396Sbostic 	}
189*65396Sbostic }
190