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