fatbase

portable OpenBSD tools
git clone git://git.2f30.org/fatbase
Log | Files | Refs

main.c (5842B)


      1 /*	$OpenBSD: main.c,v 1.17 2011/09/28 19:27:18 millert Exp $	*/
      2 /****************************************************************
      3 Copyright (C) Lucent Technologies 1997
      4 All Rights Reserved
      5 
      6 Permission to use, copy, modify, and distribute this software and
      7 its documentation for any purpose and without fee is hereby
      8 granted, provided that the above copyright notice appear in all
      9 copies and that both that the copyright notice and this
     10 permission notice and warranty disclaimer appear in supporting
     11 documentation, and that the name Lucent Technologies or any of
     12 its entities not be used in advertising or publicity pertaining
     13 to distribution of the software without specific, written prior
     14 permission.
     15 
     16 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     17 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
     18 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
     19 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
     21 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
     22 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
     23 THIS SOFTWARE.
     24 ****************************************************************/
     25 
     26 const char	*version = "version 20110810";
     27 
     28 #define DEBUG
     29 #include <stdio.h>
     30 #include <ctype.h>
     31 #include <locale.h>
     32 #include <stdlib.h>
     33 #include <string.h>
     34 #include <signal.h>
     35 #include "awk.h"
     36 #include "ytab.h"
     37 
     38 extern	char	**environ;
     39 extern	int	nfields;
     40 extern	char	*__progname;
     41 
     42 int	dbg	= 0;
     43 Awkfloat	srand_seed = 1;
     44 char	*cmdname;	/* gets argv[0] for error messages */
     45 extern	FILE	*yyin;	/* lex input file */
     46 char	*lexprog;	/* points to program argument if it exists */
     47 extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
     48 int	compile_time = 2;	/* for error printing: */
     49 				/* 2 = cmdline, 1 = compile, 0 = running */
     50 
     51 #define	MAX_PFILE	20	/* max number of -f's */
     52 
     53 char	*pfile[MAX_PFILE];	/* program filenames from -f's */
     54 int	npfile = 0;	/* number of filenames */
     55 int	curpfile = 0;	/* current filename */
     56 
     57 int	safe	= 0;	/* 1 => "safe" mode */
     58 
     59 int main(int argc, char *argv[])
     60 {
     61 	const char *fs = NULL;
     62 
     63 	setlocale(LC_ALL, "");
     64 	setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
     65 	cmdname = __progname;
     66 	if (argc == 1) {
     67 		fprintf(stderr, "usage: %s [-safe] [-V] [-d[n]] [-F fs] "
     68 		    "[-v var=value] [prog | -f progfile]\n\tfile ...\n",
     69 		    cmdname);
     70 		exit(1);
     71 	}
     72 	signal(SIGFPE, fpecatch);
     73 
     74 	yyin = NULL;
     75 	symtab = makesymtab(NSYMTAB);
     76 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
     77 		if (strcmp(argv[1], "--") == 0) {	/* explicit end of args */
     78 			argc--;
     79 			argv++;
     80 			break;
     81 		}
     82 		switch (argv[1][1]) {
     83 		case 's':
     84 			if (strcmp(argv[1], "-safe") == 0)
     85 				safe = 1;
     86 			break;
     87 		case 'f':	/* next argument is program filename */
     88 			if (argv[1][2] != 0) {  /* arg is -fsomething */
     89 				if (npfile >= MAX_PFILE - 1)
     90 					FATAL("too many -f options"); 
     91 				pfile[npfile++] = &argv[1][2];
     92 			} else {		/* arg is -f something */
     93 				argc--; argv++;
     94 				if (argc <= 1)
     95 					FATAL("no program filename");
     96 				if (npfile >= MAX_PFILE - 1)
     97 					FATAL("too many -f options"); 
     98 				pfile[npfile++] = argv[1];
     99 			}
    100 			break;
    101 		case 'F':	/* set field separator */
    102 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
    103 				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
    104 					fs = "\t";
    105 				else if (argv[1][2] != 0)
    106 					fs = &argv[1][2];
    107 			} else {		/* arg is -F something */
    108 				argc--; argv++;
    109 				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
    110 					fs = "\t";
    111 				else if (argc > 1 && argv[1][0] != 0)
    112 					fs = &argv[1][0];
    113 			}
    114 			if (fs == NULL || *fs == '\0')
    115 				WARNING("field separator FS is empty");
    116 			break;
    117 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
    118 			if (argv[1][2] != 0) {  /* arg is -vsomething */
    119 				if (isclvar(&argv[1][2]))
    120 					setclvar(&argv[1][2]);
    121 				else
    122 					FATAL("invalid -v option argument: %s", &argv[1][2]);
    123 			} else {		/* arg is -v something */
    124 				argc--; argv++;
    125 				if (argc <= 1)
    126 					FATAL("no variable name");
    127 				if (isclvar(argv[1]))
    128 					setclvar(argv[1]);
    129 				else
    130 					FATAL("invalid -v option argument: %s", argv[1]);
    131 			}
    132 			break;
    133 		case 'd':
    134 			dbg = atoi(&argv[1][2]);
    135 			if (dbg == 0)
    136 				dbg = 1;
    137 			printf("awk %s\n", version);
    138 			break;
    139 		case 'V':	/* added for exptools "standard" */
    140 			printf("awk %s\n", version);
    141 			exit(0);
    142 			break;
    143 		default:
    144 			WARNING("unknown option %s ignored", argv[1]);
    145 			break;
    146 		}
    147 		argc--;
    148 		argv++;
    149 	}
    150 	/* argv[1] is now the first argument */
    151 	if (npfile == 0) {	/* no -f; first argument is program */
    152 		if (argc <= 1) {
    153 			if (dbg)
    154 				exit(0);
    155 			FATAL("no program given");
    156 		}
    157 		   dprintf( ("program = |%s|\n", argv[1]) );
    158 		lexprog = argv[1];
    159 		argc--;
    160 		argv++;
    161 	}
    162 	recinit(recsize);
    163 	syminit();
    164 	compile_time = 1;
    165 	argv[0] = cmdname;	/* put prog name at front of arglist */
    166 	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
    167 	arginit(argc, argv);
    168 	if (!safe)
    169 		envinit(environ);
    170 	yyparse();
    171 	setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
    172 	if (fs)
    173 		*FS = qstring(fs, '\0');
    174 	   dprintf( ("errorflag=%d\n", errorflag) );
    175 	if (errorflag == 0) {
    176 		compile_time = 0;
    177 		run(winner);
    178 	} else
    179 		bracecheck();
    180 	return(errorflag);
    181 }
    182 
    183 int pgetc(void)		/* get 1 character from awk program */
    184 {
    185 	int c;
    186 
    187 	for (;;) {
    188 		if (yyin == NULL) {
    189 			if (curpfile >= npfile)
    190 				return EOF;
    191 			if (strcmp(pfile[curpfile], "-") == 0)
    192 				yyin = stdin;
    193 			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
    194 				FATAL("can't open file %s", pfile[curpfile]);
    195 			lineno = 1;
    196 		}
    197 		if ((c = getc(yyin)) != EOF)
    198 			return c;
    199 		if (yyin != stdin)
    200 			fclose(yyin);
    201 		yyin = NULL;
    202 		curpfile++;
    203 	}
    204 }
    205 
    206 char *cursource(void)	/* current source file name */
    207 {
    208 	if (npfile > 0)
    209 		return pfile[curpfile];
    210 	else
    211 		return NULL;
    212 }