main.c revision 118194
185587Sobrien/****************************************************************
285587SobrienCopyright (C) Lucent Technologies 1997
385587SobrienAll Rights Reserved
485587Sobrien
585587SobrienPermission to use, copy, modify, and distribute this software and
685587Sobrienits documentation for any purpose and without fee is hereby
785587Sobriengranted, provided that the above copyright notice appear in all
885587Sobriencopies and that both that the copyright notice and this
985587Sobrienpermission notice and warranty disclaimer appear in supporting
1085587Sobriendocumentation, and that the name Lucent Technologies or any of
1185587Sobrienits entities not be used in advertising or publicity pertaining
1285587Sobriento distribution of the software without specific, written prior
1385587Sobrienpermission.
1485587Sobrien
1585587SobrienLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1685587SobrienINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
1785587SobrienIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
1885587SobrienSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1985587SobrienWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
2085587SobrienIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
2185587SobrienARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
2285587SobrienTHIS SOFTWARE.
2385587Sobrien****************************************************************/
2485587Sobrien
25118194Sruconst char	*version = "version 20030729";
2685587Sobrien
2785587Sobrien#define DEBUG
2885587Sobrien#include <stdio.h>
2985587Sobrien#include <ctype.h>
30112336Sobrien#include <locale.h>
3185587Sobrien#include <stdlib.h>
3285587Sobrien#include <string.h>
3385587Sobrien#include <signal.h>
3485587Sobrien#include "awk.h"
3585587Sobrien#include "ytab.h"
3685587Sobrien
3785587Sobrienextern	char	**environ;
3885587Sobrienextern	int	nfields;
3985587Sobrien
4085587Sobrienint	dbg	= 0;
4185587Sobrienchar	*cmdname;	/* gets argv[0] for error messages */
4285587Sobrienextern	FILE	*yyin;	/* lex input file */
4385587Sobrienchar	*lexprog;	/* points to program argument if it exists */
4485587Sobrienextern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
4585587Sobrienint	compile_time = 2;	/* for error printing: */
4685587Sobrien				/* 2 = cmdline, 1 = compile, 0 = running */
4785587Sobrien
4885587Sobrienchar	*pfile[20];	/* program filenames from -f's */
4985587Sobrienint	npfile = 0;	/* number of filenames */
5085587Sobrienint	curpfile = 0;	/* current filename */
5185587Sobrien
5285587Sobrienint	safe	= 0;	/* 1 => "safe" mode */
5385587Sobrien
5485587Sobrienint main(int argc, char *argv[])
5585587Sobrien{
56107806Sobrien	const char *fs = NULL;
5785587Sobrien
58112336Sobrien	setlocale(LC_CTYPE, "");
59118194Sru	setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
6085587Sobrien	cmdname = argv[0];
6185587Sobrien	if (argc == 1) {
6285587Sobrien		fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [files]\n", cmdname);
6385587Sobrien		exit(1);
6485587Sobrien	}
6585587Sobrien	signal(SIGFPE, fpecatch);
6685587Sobrien	yyin = NULL;
6785587Sobrien	symtab = makesymtab(NSYMTAB);
6885587Sobrien	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
6985587Sobrien		if (strcmp(argv[1], "--") == 0) {	/* explicit end of args */
7085587Sobrien			argc--;
7185587Sobrien			argv++;
7285587Sobrien			break;
7385587Sobrien		}
7485587Sobrien		switch (argv[1][1]) {
7585587Sobrien		case 's':
7685587Sobrien			if (strcmp(argv[1], "-safe") == 0)
7785587Sobrien				safe = 1;
7885587Sobrien			break;
7985587Sobrien		case 'f':	/* next argument is program filename */
8085587Sobrien			argc--;
8185587Sobrien			argv++;
8285587Sobrien			if (argc <= 1)
8385587Sobrien				FATAL("no program filename");
8485587Sobrien			pfile[npfile++] = argv[1];
8585587Sobrien			break;
8685587Sobrien		case 'F':	/* set field separator */
8785587Sobrien			if (argv[1][2] != 0) {	/* arg is -Fsomething */
8885587Sobrien				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
8985587Sobrien					fs = "\t";
9085587Sobrien				else if (argv[1][2] != 0)
9185587Sobrien					fs = &argv[1][2];
9285587Sobrien			} else {		/* arg is -F something */
9385587Sobrien				argc--; argv++;
9485587Sobrien				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
9585587Sobrien					fs = "\t";
9685587Sobrien				else if (argc > 1 && argv[1][0] != 0)
9785587Sobrien					fs = &argv[1][0];
9885587Sobrien			}
9985587Sobrien			if (fs == NULL || *fs == '\0')
10085587Sobrien				WARNING("field separator FS is empty");
10185587Sobrien			break;
10285587Sobrien		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
10385587Sobrien			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
10485587Sobrien				setclvar(argv[1]);
10585587Sobrien			break;
10685587Sobrien		case 'm':	/* more memory: -mr=record, -mf=fields */
10790902Sdes				/* no longer supported */
10890902Sdes			WARNING("obsolete option %s ignored", argv[1]);
10985587Sobrien			break;
11085587Sobrien		case 'd':
11185587Sobrien			dbg = atoi(&argv[1][2]);
11285587Sobrien			if (dbg == 0)
11385587Sobrien				dbg = 1;
11485587Sobrien			printf("awk %s\n", version);
11585587Sobrien			break;
11685587Sobrien		case 'V':	/* added for exptools "standard" */
11785587Sobrien			printf("awk %s\n", version);
11885587Sobrien			exit(0);
11985587Sobrien			break;
12085587Sobrien		default:
12185587Sobrien			WARNING("unknown option %s ignored", argv[1]);
12285587Sobrien			break;
12385587Sobrien		}
12485587Sobrien		argc--;
12585587Sobrien		argv++;
12685587Sobrien	}
12785587Sobrien	/* argv[1] is now the first argument */
12885587Sobrien	if (npfile == 0) {	/* no -f; first argument is program */
12985587Sobrien		if (argc <= 1) {
13085587Sobrien			if (dbg)
13185587Sobrien				exit(0);
13285587Sobrien			FATAL("no program given");
13385587Sobrien		}
13485587Sobrien		   dprintf( ("program = |%s|\n", argv[1]) );
13585587Sobrien		lexprog = argv[1];
13685587Sobrien		argc--;
13785587Sobrien		argv++;
13885587Sobrien	}
13985587Sobrien	recinit(recsize);
14085587Sobrien	syminit();
14185587Sobrien	compile_time = 1;
14285587Sobrien	argv[0] = cmdname;	/* put prog name at front of arglist */
14385587Sobrien	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
14485587Sobrien	arginit(argc, argv);
14585587Sobrien	if (!safe)
14685587Sobrien		envinit(environ);
14785587Sobrien	yyparse();
148118194Sru	setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
14985587Sobrien	if (fs)
15085587Sobrien		*FS = qstring(fs, '\0');
15185587Sobrien	   dprintf( ("errorflag=%d\n", errorflag) );
15285587Sobrien	if (errorflag == 0) {
15385587Sobrien		compile_time = 0;
15485587Sobrien		run(winner);
15585587Sobrien	} else
15685587Sobrien		bracecheck();
15785587Sobrien	return(errorflag);
15885587Sobrien}
15985587Sobrien
16085587Sobrienint pgetc(void)		/* get 1 character from awk program */
16185587Sobrien{
16285587Sobrien	int c;
16385587Sobrien
16485587Sobrien	for (;;) {
16585587Sobrien		if (yyin == NULL) {
16685587Sobrien			if (curpfile >= npfile)
16785587Sobrien				return EOF;
16885587Sobrien			if (strcmp(pfile[curpfile], "-") == 0)
16985587Sobrien				yyin = stdin;
17085587Sobrien			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
17185587Sobrien				FATAL("can't open file %s", pfile[curpfile]);
17285587Sobrien			lineno = 1;
17385587Sobrien		}
17485587Sobrien		if ((c = getc(yyin)) != EOF)
17585587Sobrien			return c;
17685587Sobrien		if (yyin != stdin)
17785587Sobrien			fclose(yyin);
17885587Sobrien		yyin = NULL;
17985587Sobrien		curpfile++;
18085587Sobrien	}
18185587Sobrien}
18285587Sobrien
18385587Sobrienchar *cursource(void)	/* current source file name */
18485587Sobrien{
18585587Sobrien	if (npfile > 0)
18685587Sobrien		return pfile[curpfile];
18785587Sobrien	else
18885587Sobrien		return NULL;
18985587Sobrien}
190