1*8ce597b3Sdoug /* $OpenBSD: main.c,v 1.18 2015/10/10 20:04:28 doug Exp $ */ 26ab05f83Stholo /**************************************************************** 307edfa4aSkstailey Copyright (C) Lucent Technologies 1997 46ab05f83Stholo All Rights Reserved 56ab05f83Stholo 66ab05f83Stholo Permission to use, copy, modify, and distribute this software and 76ab05f83Stholo its documentation for any purpose and without fee is hereby 86ab05f83Stholo granted, provided that the above copyright notice appear in all 96ab05f83Stholo copies and that both that the copyright notice and this 106ab05f83Stholo permission notice and warranty disclaimer appear in supporting 1107edfa4aSkstailey documentation, and that the name Lucent Technologies or any of 1207edfa4aSkstailey its entities not be used in advertising or publicity pertaining 1307edfa4aSkstailey to distribution of the software without specific, written prior 1407edfa4aSkstailey permission. 156ab05f83Stholo 1607edfa4aSkstailey LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1707edfa4aSkstailey INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 1807edfa4aSkstailey IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 1907edfa4aSkstailey SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 2007edfa4aSkstailey WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 2107edfa4aSkstailey IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 2207edfa4aSkstailey ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 2307edfa4aSkstailey THIS SOFTWARE. 246ab05f83Stholo ****************************************************************/ 256ab05f83Stholo 26000399a4Smillert const char *version = "version 20110810"; 276ab05f83Stholo 286ab05f83Stholo #define DEBUG 296ab05f83Stholo #include <stdio.h> 306ab05f83Stholo #include <ctype.h> 31b2698ba9Smillert #include <locale.h> 326ab05f83Stholo #include <stdlib.h> 336ab05f83Stholo #include <string.h> 346ab05f83Stholo #include <signal.h> 35*8ce597b3Sdoug #include <unistd.h> 366ab05f83Stholo #include "awk.h" 3707edfa4aSkstailey #include "ytab.h" 386ab05f83Stholo 396ab05f83Stholo extern char **environ; 406ab05f83Stholo extern int nfields; 41a4fa8700Smillert extern char *__progname; 426ab05f83Stholo 436ab05f83Stholo int dbg = 0; 44000399a4Smillert Awkfloat srand_seed = 1; 456ab05f83Stholo char *cmdname; /* gets argv[0] for error messages */ 466ab05f83Stholo extern FILE *yyin; /* lex input file */ 476ab05f83Stholo char *lexprog; /* points to program argument if it exists */ 486ab05f83Stholo extern int errorflag; /* non-zero if any syntax errors; set by yyerror */ 496ab05f83Stholo int compile_time = 2; /* for error printing: */ 506ab05f83Stholo /* 2 = cmdline, 1 = compile, 0 = running */ 516ab05f83Stholo 5280b86fb0Smillert #define MAX_PFILE 20 /* max number of -f's */ 5380b86fb0Smillert 54466ccf10Smillert char *pfile[MAX_PFILE]; /* program filenames from -f's */ 556ab05f83Stholo int npfile = 0; /* number of filenames */ 566ab05f83Stholo int curpfile = 0; /* current filename */ 576ab05f83Stholo 5807edfa4aSkstailey int safe = 0; /* 1 => "safe" mode */ 5907edfa4aSkstailey 606ab05f83Stholo int main(int argc, char *argv[]) 616ab05f83Stholo { 629a69093aSmillert const char *fs = NULL; 636ab05f83Stholo 64*8ce597b3Sdoug if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1) { 65*8ce597b3Sdoug fprintf(stderr, "%s: pledge: incorrect arguments\n", 66*8ce597b3Sdoug cmdname); 67*8ce597b3Sdoug exit(1); 68*8ce597b3Sdoug } 69*8ce597b3Sdoug 7028f4856aStholo setlocale(LC_ALL, ""); 7123cb51abSmillert setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */ 72a4fa8700Smillert cmdname = __progname; 736ab05f83Stholo if (argc == 1) { 74f0b76118Sjmc fprintf(stderr, "usage: %s [-safe] [-V] [-d[n]] [-F fs] " 75f0b76118Sjmc "[-v var=value] [prog | -f progfile]\n\tfile ...\n", 76a54e3325Saaron cmdname); 776ab05f83Stholo exit(1); 786ab05f83Stholo } 796ab05f83Stholo signal(SIGFPE, fpecatch); 80000399a4Smillert 816ab05f83Stholo yyin = NULL; 826ab05f83Stholo symtab = makesymtab(NSYMTAB); 836ab05f83Stholo while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') { 8407edfa4aSkstailey if (strcmp(argv[1], "--") == 0) { /* explicit end of args */ 856ab05f83Stholo argc--; 866ab05f83Stholo argv++; 876ab05f83Stholo break; 886ab05f83Stholo } 896ab05f83Stholo switch (argv[1][1]) { 9007edfa4aSkstailey case 's': 9107edfa4aSkstailey if (strcmp(argv[1], "-safe") == 0) 9207edfa4aSkstailey safe = 1; 9307edfa4aSkstailey break; 946ab05f83Stholo case 'f': /* next argument is program filename */ 95000399a4Smillert if (argv[1][2] != 0) { /* arg is -fsomething */ 96466ccf10Smillert if (npfile >= MAX_PFILE - 1) 977b11b857Smillert FATAL("too many -f options"); 98000399a4Smillert pfile[npfile++] = &argv[1][2]; 99000399a4Smillert } else { /* arg is -f something */ 100000399a4Smillert argc--; argv++; 1016ab05f83Stholo if (argc <= 1) 1027b11b857Smillert FATAL("no program filename"); 10380b86fb0Smillert if (npfile >= MAX_PFILE - 1) 10480b86fb0Smillert FATAL("too many -f options"); 1056ab05f83Stholo pfile[npfile++] = argv[1]; 106000399a4Smillert } 1076ab05f83Stholo break; 1086ab05f83Stholo case 'F': /* set field separator */ 1096ab05f83Stholo if (argv[1][2] != 0) { /* arg is -Fsomething */ 1106ab05f83Stholo if (argv[1][2] == 't' && argv[1][3] == 0) /* wart: t=>\t */ 11107edfa4aSkstailey fs = "\t"; 1126ab05f83Stholo else if (argv[1][2] != 0) 1136ab05f83Stholo fs = &argv[1][2]; 1146ab05f83Stholo } else { /* arg is -F something */ 1156ab05f83Stholo argc--; argv++; 1166ab05f83Stholo if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0) /* wart: t=>\t */ 11707edfa4aSkstailey fs = "\t"; 1186ab05f83Stholo else if (argc > 1 && argv[1][0] != 0) 1196ab05f83Stholo fs = &argv[1][0]; 1206ab05f83Stholo } 1216ab05f83Stholo if (fs == NULL || *fs == '\0') 1227b11b857Smillert WARNING("field separator FS is empty"); 1236ab05f83Stholo break; 1246ab05f83Stholo case 'v': /* -v a=1 to be done NOW. one -v for each */ 125000399a4Smillert if (argv[1][2] != 0) { /* arg is -vsomething */ 126000399a4Smillert if (isclvar(&argv[1][2])) 127d6972635Smillert setclvar(&argv[1][2]); 128000399a4Smillert else 129000399a4Smillert FATAL("invalid -v option argument: %s", &argv[1][2]); 130000399a4Smillert } else { /* arg is -v something */ 131000399a4Smillert argc--; argv++; 132000399a4Smillert if (argc <= 1) 133000399a4Smillert FATAL("no variable name"); 134000399a4Smillert if (isclvar(argv[1])) 135000399a4Smillert setclvar(argv[1]); 136000399a4Smillert else 137000399a4Smillert FATAL("invalid -v option argument: %s", argv[1]); 138000399a4Smillert } 1396ab05f83Stholo break; 1406ab05f83Stholo case 'd': 1416ab05f83Stholo dbg = atoi(&argv[1][2]); 1426ab05f83Stholo if (dbg == 0) 1436ab05f83Stholo dbg = 1; 1446ab05f83Stholo printf("awk %s\n", version); 1456ab05f83Stholo break; 146a4fa8700Smillert case 'V': /* added for exptools "standard" */ 147a4fa8700Smillert printf("awk %s\n", version); 148a4fa8700Smillert exit(0); 149a4fa8700Smillert break; 1506ab05f83Stholo default: 1517b11b857Smillert WARNING("unknown option %s ignored", argv[1]); 1526ab05f83Stholo break; 1536ab05f83Stholo } 1546ab05f83Stholo argc--; 1556ab05f83Stholo argv++; 1566ab05f83Stholo } 157*8ce597b3Sdoug 158*8ce597b3Sdoug if (safe) { 159*8ce597b3Sdoug if (pledge("stdio rpath", NULL) == -1) { 160*8ce597b3Sdoug fprintf(stderr, "%s: pledge: incorrect arguments\n", 161*8ce597b3Sdoug cmdname); 162*8ce597b3Sdoug exit(1); 163*8ce597b3Sdoug } 164*8ce597b3Sdoug } 165*8ce597b3Sdoug 1666ab05f83Stholo /* argv[1] is now the first argument */ 1676ab05f83Stholo if (npfile == 0) { /* no -f; first argument is program */ 1686ab05f83Stholo if (argc <= 1) { 1696ab05f83Stholo if (dbg) 1706ab05f83Stholo exit(0); 1717b11b857Smillert FATAL("no program given"); 1726ab05f83Stholo } 1736ab05f83Stholo dprintf( ("program = |%s|\n", argv[1]) ); 1746ab05f83Stholo lexprog = argv[1]; 1756ab05f83Stholo argc--; 1766ab05f83Stholo argv++; 1776ab05f83Stholo } 1786ab05f83Stholo recinit(recsize); 1796ab05f83Stholo syminit(); 1806ab05f83Stholo compile_time = 1; 1816ab05f83Stholo argv[0] = cmdname; /* put prog name at front of arglist */ 1826ab05f83Stholo dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) ); 1836ab05f83Stholo arginit(argc, argv); 18407edfa4aSkstailey if (!safe) 1856ab05f83Stholo envinit(environ); 1866ab05f83Stholo yyparse(); 18723cb51abSmillert setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */ 1886ab05f83Stholo if (fs) 18907edfa4aSkstailey *FS = qstring(fs, '\0'); 1906ab05f83Stholo dprintf( ("errorflag=%d\n", errorflag) ); 1916ab05f83Stholo if (errorflag == 0) { 1926ab05f83Stholo compile_time = 0; 1936ab05f83Stholo run(winner); 1946ab05f83Stholo } else 1956ab05f83Stholo bracecheck(); 1966ab05f83Stholo return(errorflag); 1976ab05f83Stholo } 1986ab05f83Stholo 1996ab05f83Stholo int pgetc(void) /* get 1 character from awk program */ 2006ab05f83Stholo { 2016ab05f83Stholo int c; 2026ab05f83Stholo 2036ab05f83Stholo for (;;) { 2046ab05f83Stholo if (yyin == NULL) { 2056ab05f83Stholo if (curpfile >= npfile) 2066ab05f83Stholo return EOF; 20707edfa4aSkstailey if (strcmp(pfile[curpfile], "-") == 0) 2086ab05f83Stholo yyin = stdin; 20907edfa4aSkstailey else if ((yyin = fopen(pfile[curpfile], "r")) == NULL) 2107b11b857Smillert FATAL("can't open file %s", pfile[curpfile]); 211271018d0Smillert lineno = 1; 2126ab05f83Stholo } 2136ab05f83Stholo if ((c = getc(yyin)) != EOF) 2146ab05f83Stholo return c; 2156ab05f83Stholo if (yyin != stdin) 2166ab05f83Stholo fclose(yyin); 2176ab05f83Stholo yyin = NULL; 2186ab05f83Stholo curpfile++; 2196ab05f83Stholo } 2206ab05f83Stholo } 221271018d0Smillert 222271018d0Smillert char *cursource(void) /* current source file name */ 223271018d0Smillert { 224271018d0Smillert if (npfile > 0) 225271018d0Smillert return pfile[curpfile]; 226271018d0Smillert else 227271018d0Smillert return NULL; 228271018d0Smillert } 229