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
25201989Sru#include <sys/cdefs.h>
26201989Sru__FBSDID("$FreeBSD$");
2785587Sobrien
28244988Sdelphijconst char	*version = "version 20121220 (FreeBSD)";
29201989Sru
3085587Sobrien#define DEBUG
3185587Sobrien#include <stdio.h>
3285587Sobrien#include <ctype.h>
33112336Sobrien#include <locale.h>
3485587Sobrien#include <stdlib.h>
3585587Sobrien#include <string.h>
3685587Sobrien#include <signal.h>
3785587Sobrien#include "awk.h"
3885587Sobrien#include "ytab.h"
3985587Sobrien
4085587Sobrienextern	char	**environ;
4185587Sobrienextern	int	nfields;
4285587Sobrien
4385587Sobrienint	dbg	= 0;
44221381SruAwkfloat	srand_seed = 1;
4585587Sobrienchar	*cmdname;	/* gets argv[0] for error messages */
4685587Sobrienextern	FILE	*yyin;	/* lex input file */
4785587Sobrienchar	*lexprog;	/* points to program argument if it exists */
4885587Sobrienextern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
4985587Sobrienint	compile_time = 2;	/* for error printing: */
5085587Sobrien				/* 2 = cmdline, 1 = compile, 0 = running */
5185587Sobrien
52146299Sru#define	MAX_PFILE	20	/* max number of -f's */
53146299Sru
54146299Sruchar	*pfile[MAX_PFILE];	/* program filenames from -f's */
5585587Sobrienint	npfile = 0;	/* number of filenames */
5685587Sobrienint	curpfile = 0;	/* current filename */
5785587Sobrien
5885587Sobrienint	safe	= 0;	/* 1 => "safe" mode */
5985587Sobrien
6085587Sobrienint main(int argc, char *argv[])
6185587Sobrien{
62107806Sobrien	const char *fs = NULL;
6385587Sobrien
64112336Sobrien	setlocale(LC_CTYPE, "");
65201989Sru	setlocale(LC_COLLATE, "");
66118194Sru	setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
6785587Sobrien	cmdname = argv[0];
6885587Sobrien	if (argc == 1) {
69170331Srafan		fprintf(stderr,
70170331Srafan		  "usage: %s [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]\n",
71170331Srafan		  cmdname);
7285587Sobrien		exit(1);
7385587Sobrien	}
7485587Sobrien	signal(SIGFPE, fpecatch);
75221381Sru
76221381Sru	srand_seed = 1;
77271879Spfg	srandom((unsigned long) srand_seed);
78221381Sru
7985587Sobrien	yyin = NULL;
80170331Srafan	symtab = makesymtab(NSYMTAB/NSYMTAB);
8185587Sobrien	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
82170331Srafan		if (strcmp(argv[1],"-version") == 0 || strcmp(argv[1],"--version") == 0) {
83170331Srafan			printf("awk %s\n", version);
84170331Srafan			exit(0);
85170331Srafan			break;
86170331Srafan		}
87170331Srafan		if (strncmp(argv[1], "--", 2) == 0) {	/* explicit end of args */
8885587Sobrien			argc--;
8985587Sobrien			argv++;
9085587Sobrien			break;
9185587Sobrien		}
9285587Sobrien		switch (argv[1][1]) {
9385587Sobrien		case 's':
9485587Sobrien			if (strcmp(argv[1], "-safe") == 0)
9585587Sobrien				safe = 1;
9685587Sobrien			break;
9785587Sobrien		case 'f':	/* next argument is program filename */
98221533Sru			if (argv[1][2] != 0) {  /* arg is -fsomething */
99201989Sru				if (npfile >= MAX_PFILE - 1)
100201989Sru					FATAL("too many -f options");
101201989Sru				pfile[npfile++] = &argv[1][2];
102201989Sru			} else {		/* arg is -f something */
103201989Sru				argc--; argv++;
104201989Sru				if (argc <= 1)
105201989Sru					FATAL("no program filename");
106201989Sru				if (npfile >= MAX_PFILE - 1)
107201989Sru					FATAL("too many -f options");
108201989Sru				pfile[npfile++] = argv[1];
109201989Sru			}
11085587Sobrien			break;
11185587Sobrien		case 'F':	/* set field separator */
11285587Sobrien			if (argv[1][2] != 0) {	/* arg is -Fsomething */
11385587Sobrien				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
11485587Sobrien					fs = "\t";
11585587Sobrien				else if (argv[1][2] != 0)
11685587Sobrien					fs = &argv[1][2];
11785587Sobrien			} else {		/* arg is -F something */
11885587Sobrien				argc--; argv++;
11985587Sobrien				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
12085587Sobrien					fs = "\t";
12185587Sobrien				else if (argc > 1 && argv[1][0] != 0)
12285587Sobrien					fs = &argv[1][0];
12385587Sobrien			}
12485587Sobrien			if (fs == NULL || *fs == '\0')
12585587Sobrien				WARNING("field separator FS is empty");
12685587Sobrien			break;
12785587Sobrien		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
128224731Sru			if (argv[1][2] != 0) {  /* arg is -vsomething */
129224731Sru				if (isclvar(&argv[1][2]))
130224731Sru					setclvar(&argv[1][2]);
131224731Sru				else
132224731Sru					FATAL("invalid -v option argument: %s", &argv[1][2]);
133224731Sru			} else {		/* arg is -v something */
134224731Sru				argc--; argv++;
135224731Sru				if (argc <= 1)
136224731Sru					FATAL("no variable name");
137224731Sru				if (isclvar(argv[1]))
138224731Sru					setclvar(argv[1]);
139224731Sru				else
140224731Sru					FATAL("invalid -v option argument: %s", argv[1]);
141224731Sru			}
14285587Sobrien			break;
14385587Sobrien		case 'd':
14485587Sobrien			dbg = atoi(&argv[1][2]);
14585587Sobrien			if (dbg == 0)
14685587Sobrien				dbg = 1;
14785587Sobrien			printf("awk %s\n", version);
14885587Sobrien			break;
14985587Sobrien		default:
15085587Sobrien			WARNING("unknown option %s ignored", argv[1]);
15185587Sobrien			break;
15285587Sobrien		}
15385587Sobrien		argc--;
15485587Sobrien		argv++;
15585587Sobrien	}
15685587Sobrien	/* argv[1] is now the first argument */
15785587Sobrien	if (npfile == 0) {	/* no -f; first argument is program */
15885587Sobrien		if (argc <= 1) {
15985587Sobrien			if (dbg)
16085587Sobrien				exit(0);
16185587Sobrien			FATAL("no program given");
16285587Sobrien		}
16385587Sobrien		   dprintf( ("program = |%s|\n", argv[1]) );
16485587Sobrien		lexprog = argv[1];
16585587Sobrien		argc--;
16685587Sobrien		argv++;
16785587Sobrien	}
16885587Sobrien	recinit(recsize);
16985587Sobrien	syminit();
17085587Sobrien	compile_time = 1;
17185587Sobrien	argv[0] = cmdname;	/* put prog name at front of arglist */
17285587Sobrien	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
17385587Sobrien	arginit(argc, argv);
17485587Sobrien	if (!safe)
17585587Sobrien		envinit(environ);
17685587Sobrien	yyparse();
177118194Sru	setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
17885587Sobrien	if (fs)
17985587Sobrien		*FS = qstring(fs, '\0');
18085587Sobrien	   dprintf( ("errorflag=%d\n", errorflag) );
18185587Sobrien	if (errorflag == 0) {
18285587Sobrien		compile_time = 0;
18385587Sobrien		run(winner);
18485587Sobrien	} else
18585587Sobrien		bracecheck();
18685587Sobrien	return(errorflag);
18785587Sobrien}
18885587Sobrien
18985587Sobrienint pgetc(void)		/* get 1 character from awk program */
19085587Sobrien{
19185587Sobrien	int c;
19285587Sobrien
19385587Sobrien	for (;;) {
19485587Sobrien		if (yyin == NULL) {
19585587Sobrien			if (curpfile >= npfile)
19685587Sobrien				return EOF;
19785587Sobrien			if (strcmp(pfile[curpfile], "-") == 0)
19885587Sobrien				yyin = stdin;
19985587Sobrien			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
20085587Sobrien				FATAL("can't open file %s", pfile[curpfile]);
20185587Sobrien			lineno = 1;
20285587Sobrien		}
20385587Sobrien		if ((c = getc(yyin)) != EOF)
20485587Sobrien			return c;
20585587Sobrien		if (yyin != stdin)
20685587Sobrien			fclose(yyin);
20785587Sobrien		yyin = NULL;
20885587Sobrien		curpfile++;
20985587Sobrien	}
21085587Sobrien}
21185587Sobrien
21285587Sobrienchar *cursource(void)	/* current source file name */
21385587Sobrien{
21485587Sobrien	if (npfile > 0)
21585587Sobrien		return pfile[curpfile];
21685587Sobrien	else
21785587Sobrien		return NULL;
21885587Sobrien}
219