Home | History | Annotate | Download | only in awk
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28 /*	  All Rights Reserved  	*/
     29 
     30 #include <stdio.h>
     31 #include <ctype.h>
     32 #include <signal.h>
     33 #include <locale.h>
     34 #include <libintl.h>
     35 #include <stdarg.h>
     36 #include <errno.h>
     37 #include <values.h>
     38 #include <langinfo.h>
     39 #include "awk.h"
     40 #include "y.tab.h"
     41 
     42 char	*version = "version Oct 11, 1989";
     43 
     44 int	dbg	= 0;
     45 uchar	*cmdname;	/* gets argv[0] for error messages */
     46 uchar	*lexprog;	/* points to program argument if it exists */
     47 int	compile_time = 2;	/* for error printing: */
     48 				/* 2 = cmdline, 1 = compile, 0 = running */
     49 char	radixpoint = '.';
     50 
     51 static uchar	**pfile = NULL;	/* program filenames from -f's */
     52 static int	npfile = 0;	/* number of filenames */
     53 static int	curpfile = 0;	/* current filename */
     54 
     55 int
     56 main(int argc, char *argv[], char *envp[])
     57 {
     58 	uchar *fs = NULL;
     59 	char	*nl_radix;
     60 	/*
     61 	 * At this point, numbers are still scanned as in
     62 	 * the POSIX locale.
     63 	 * (POSIX.2, volume 2, P867, L4742-4757)
     64 	 */
     65 	(void) setlocale(LC_ALL, "");
     66 	(void) setlocale(LC_NUMERIC, "C");
     67 #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
     68 #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it weren't */
     69 #endif
     70 	(void) textdomain(TEXT_DOMAIN);
     71 	cmdname = (uchar *)argv[0];
     72 	if (argc == 1) {
     73 		(void) fprintf(stderr, gettext(
     74 		    "Usage: %s [-f programfile | 'program'] [-Ffieldsep] "
     75 		    "[-v var=value] [files]\n"), cmdname);
     76 		exit(1);
     77 	}
     78 	(void) signal(SIGFPE, fpecatch);
     79 	yyin = NULL;
     80 	syminit();
     81 	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
     82 		if (strcmp(argv[1], "--") == 0) {
     83 			/* explicit end of args */
     84 			argc--;
     85 			argv++;
     86 			break;
     87 		}
     88 		switch (argv[1][1]) {
     89 		case 'f':	/* next argument is program filename */
     90 			argc--;
     91 			argv++;
     92 			if (argc <= 1)
     93 				ERROR "no program filename" FATAL;
     94 			pfile = realloc(pfile, sizeof (uchar *) * (npfile + 1));
     95 			if (pfile == NULL)
     96 				ERROR "out of space in main" FATAL;
     97 			pfile[npfile++] = (uchar *)argv[1];
     98 			break;
     99 		case 'F':	/* set field separator */
    100 			if (argv[1][2] != 0) {	/* arg is -Fsomething */
    101 				/* wart: t=>\t */
    102 				if (argv[1][2] == 't' && argv[1][3] == 0)
    103 					fs = (uchar *) "\t";
    104 				else if (argv[1][2] != 0)
    105 					fs = (uchar *)&argv[1][2];
    106 			} else {		/* arg is -F something */
    107 				argc--; argv++;
    108 				if (argc > 1) {
    109 					/* wart: t=>\t */
    110 					if (argv[1][0] == 't' &&
    111 					    argv[1][1] == 0)
    112 						fs = (uchar *) "\t";
    113 					else if (argv[1][0] != 0)
    114 						fs = (uchar *)&argv[1][0];
    115 				}
    116 			}
    117 			if (fs == NULL || *fs == '\0')
    118 				ERROR "field separator FS is empty" WARNING;
    119 			break;
    120 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
    121 			if (argv[1][2] == '\0' && --argc > 1 &&
    122 			    isclvar((uchar *)(++argv)[1]))
    123 				setclvar((uchar *)argv[1]);
    124 			break;
    125 		case 'd':
    126 			dbg = atoi(&argv[1][2]);
    127 			if (dbg == 0)
    128 				dbg = 1;
    129 			(void) printf("awk %s\n", version);
    130 			break;
    131 		default:
    132 			ERROR "unknown option %s ignored", argv[1] WARNING;
    133 			break;
    134 		}
    135 		argc--;
    136 		argv++;
    137 	}
    138 	/* argv[1] is now the first argument */
    139 	if (npfile == 0) {	/* no -f; first argument is program */
    140 		if (argc <= 1)
    141 			ERROR "no program given" FATAL;
    142 		dprintf(("program = |%s|\n", argv[1]));
    143 		lexprog = (uchar *)argv[1];
    144 		argc--;
    145 		argv++;
    146 	}
    147 	compile_time = 1;
    148 	argv[0] = (char *)cmdname;	/* put prog name at front of arglist */
    149 	dprintf(("argc=%d, argv[0]=%s\n", argc, argv[0]));
    150 	arginit(argc, (uchar **)argv);
    151 	envinit((uchar **)envp);
    152 	(void) yyparse();
    153 	if (fs)
    154 		*FS = qstring(fs, '\0');
    155 	dprintf(("errorflag=%d\n", errorflag));
    156 	/*
    157 	 * done parsing, so now activate the LC_NUMERIC
    158 	 */
    159 	(void) setlocale(LC_ALL, "");
    160 	nl_radix = nl_langinfo(RADIXCHAR);
    161 	if (nl_radix)
    162 		radixpoint = *nl_radix;
    163 
    164 	if (errorflag == 0) {
    165 		compile_time = 0;
    166 		run(winner);
    167 	} else
    168 		bracecheck();
    169 	return (errorflag);
    170 }
    171 
    172 int
    173 pgetc(void)		/* get program character */
    174 {
    175 	int c;
    176 
    177 	for (;;) {
    178 		if (yyin == NULL) {
    179 			if (curpfile >= npfile)
    180 				return (EOF);
    181 			yyin = (strcmp((char *)pfile[curpfile], "-") == 0) ?
    182 			    stdin : fopen((char *)pfile[curpfile], "r");
    183 			if (yyin == NULL) {
    184 				ERROR "can't open file %s",
    185 				    pfile[curpfile] FATAL;
    186 			}
    187 		}
    188 		if ((c = getc(yyin)) != EOF)
    189 			return (c);
    190 		(void) fclose(yyin);
    191 		yyin = NULL;
    192 		curpfile++;
    193 	}
    194 }
    195