main.c revision 221533
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: head/contrib/one-true-awk/main.c 221533 2011-05-06 14:21:46Z ru $");
2785587Sobrien
28221533Sruconst char	*version = "version 20110506 (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;
77221381Sru	srand(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 */
128221381Sru			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
129221381Sru				setclvar(argv[1]);
130221381Sru			else if (argv[1][2] != '\0')
131221381Sru				setclvar(&argv[1][2]);
13285587Sobrien			break;
13385587Sobrien		case 'd':
13485587Sobrien			dbg = atoi(&argv[1][2]);
13585587Sobrien			if (dbg == 0)
13685587Sobrien				dbg = 1;
13785587Sobrien			printf("awk %s\n", version);
13885587Sobrien			break;
13985587Sobrien		default:
14085587Sobrien			WARNING("unknown option %s ignored", argv[1]);
14185587Sobrien			break;
14285587Sobrien		}
14385587Sobrien		argc--;
14485587Sobrien		argv++;
14585587Sobrien	}
14685587Sobrien	/* argv[1] is now the first argument */
14785587Sobrien	if (npfile == 0) {	/* no -f; first argument is program */
14885587Sobrien		if (argc <= 1) {
14985587Sobrien			if (dbg)
15085587Sobrien				exit(0);
15185587Sobrien			FATAL("no program given");
15285587Sobrien		}
15385587Sobrien		   dprintf( ("program = |%s|\n", argv[1]) );
15485587Sobrien		lexprog = argv[1];
15585587Sobrien		argc--;
15685587Sobrien		argv++;
15785587Sobrien	}
15885587Sobrien	recinit(recsize);
15985587Sobrien	syminit();
16085587Sobrien	compile_time = 1;
16185587Sobrien	argv[0] = cmdname;	/* put prog name at front of arglist */
16285587Sobrien	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
16385587Sobrien	arginit(argc, argv);
16485587Sobrien	if (!safe)
16585587Sobrien		envinit(environ);
16685587Sobrien	yyparse();
167118194Sru	setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
16885587Sobrien	if (fs)
16985587Sobrien		*FS = qstring(fs, '\0');
17085587Sobrien	   dprintf( ("errorflag=%d\n", errorflag) );
17185587Sobrien	if (errorflag == 0) {
17285587Sobrien		compile_time = 0;
17385587Sobrien		run(winner);
17485587Sobrien	} else
17585587Sobrien		bracecheck();
17685587Sobrien	return(errorflag);
17785587Sobrien}
17885587Sobrien
17985587Sobrienint pgetc(void)		/* get 1 character from awk program */
18085587Sobrien{
18185587Sobrien	int c;
18285587Sobrien
18385587Sobrien	for (;;) {
18485587Sobrien		if (yyin == NULL) {
18585587Sobrien			if (curpfile >= npfile)
18685587Sobrien				return EOF;
18785587Sobrien			if (strcmp(pfile[curpfile], "-") == 0)
18885587Sobrien				yyin = stdin;
18985587Sobrien			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
19085587Sobrien				FATAL("can't open file %s", pfile[curpfile]);
19185587Sobrien			lineno = 1;
19285587Sobrien		}
19385587Sobrien		if ((c = getc(yyin)) != EOF)
19485587Sobrien			return c;
19585587Sobrien		if (yyin != stdin)
19685587Sobrien			fclose(yyin);
19785587Sobrien		yyin = NULL;
19885587Sobrien		curpfile++;
19985587Sobrien	}
20085587Sobrien}
20185587Sobrien
20285587Sobrienchar *cursource(void)	/* current source file name */
20385587Sobrien{
20485587Sobrien	if (npfile > 0)
20585587Sobrien		return pfile[curpfile];
20685587Sobrien	else
20785587Sobrien		return NULL;
20885587Sobrien}
209