1*000399a4Smillert /* $OpenBSD: main.c,v 1.17 2011/09/28 19:27:18 millert 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 26*000399a4Smillert 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> 356ab05f83Stholo #include "awk.h" 3607edfa4aSkstailey #include "ytab.h" 376ab05f83Stholo 386ab05f83Stholo extern char **environ; 396ab05f83Stholo extern int nfields; 40a4fa8700Smillert extern char *__progname; 416ab05f83Stholo 426ab05f83Stholo int dbg = 0; 43*000399a4Smillert Awkfloat srand_seed = 1; 446ab05f83Stholo char *cmdname; /* gets argv[0] for error messages */ 456ab05f83Stholo extern FILE *yyin; /* lex input file */ 466ab05f83Stholo char *lexprog; /* points to program argument if it exists */ 476ab05f83Stholo extern int errorflag; /* non-zero if any syntax errors; set by yyerror */ 486ab05f83Stholo int compile_time = 2; /* for error printing: */ 496ab05f83Stholo /* 2 = cmdline, 1 = compile, 0 = running */ 506ab05f83Stholo 5180b86fb0Smillert #define MAX_PFILE 20 /* max number of -f's */ 5280b86fb0Smillert 53466ccf10Smillert char *pfile[MAX_PFILE]; /* program filenames from -f's */ 546ab05f83Stholo int npfile = 0; /* number of filenames */ 556ab05f83Stholo int curpfile = 0; /* current filename */ 566ab05f83Stholo 5707edfa4aSkstailey int safe = 0; /* 1 => "safe" mode */ 5807edfa4aSkstailey 596ab05f83Stholo int main(int argc, char *argv[]) 606ab05f83Stholo { 619a69093aSmillert const char *fs = NULL; 626ab05f83Stholo 6328f4856aStholo setlocale(LC_ALL, ""); 6423cb51abSmillert setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */ 65a4fa8700Smillert cmdname = __progname; 666ab05f83Stholo if (argc == 1) { 67f0b76118Sjmc fprintf(stderr, "usage: %s [-safe] [-V] [-d[n]] [-F fs] " 68f0b76118Sjmc "[-v var=value] [prog | -f progfile]\n\tfile ...\n", 69a54e3325Saaron cmdname); 706ab05f83Stholo exit(1); 716ab05f83Stholo } 726ab05f83Stholo signal(SIGFPE, fpecatch); 73*000399a4Smillert 746ab05f83Stholo yyin = NULL; 756ab05f83Stholo symtab = makesymtab(NSYMTAB); 766ab05f83Stholo while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') { 7707edfa4aSkstailey if (strcmp(argv[1], "--") == 0) { /* explicit end of args */ 786ab05f83Stholo argc--; 796ab05f83Stholo argv++; 806ab05f83Stholo break; 816ab05f83Stholo } 826ab05f83Stholo switch (argv[1][1]) { 8307edfa4aSkstailey case 's': 8407edfa4aSkstailey if (strcmp(argv[1], "-safe") == 0) 8507edfa4aSkstailey safe = 1; 8607edfa4aSkstailey break; 876ab05f83Stholo case 'f': /* next argument is program filename */ 88*000399a4Smillert if (argv[1][2] != 0) { /* arg is -fsomething */ 89466ccf10Smillert if (npfile >= MAX_PFILE - 1) 907b11b857Smillert FATAL("too many -f options"); 91*000399a4Smillert pfile[npfile++] = &argv[1][2]; 92*000399a4Smillert } else { /* arg is -f something */ 93*000399a4Smillert argc--; argv++; 946ab05f83Stholo if (argc <= 1) 957b11b857Smillert FATAL("no program filename"); 9680b86fb0Smillert if (npfile >= MAX_PFILE - 1) 9780b86fb0Smillert FATAL("too many -f options"); 986ab05f83Stholo pfile[npfile++] = argv[1]; 99*000399a4Smillert } 1006ab05f83Stholo break; 1016ab05f83Stholo case 'F': /* set field separator */ 1026ab05f83Stholo if (argv[1][2] != 0) { /* arg is -Fsomething */ 1036ab05f83Stholo if (argv[1][2] == 't' && argv[1][3] == 0) /* wart: t=>\t */ 10407edfa4aSkstailey fs = "\t"; 1056ab05f83Stholo else if (argv[1][2] != 0) 1066ab05f83Stholo fs = &argv[1][2]; 1076ab05f83Stholo } else { /* arg is -F something */ 1086ab05f83Stholo argc--; argv++; 1096ab05f83Stholo if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0) /* wart: t=>\t */ 11007edfa4aSkstailey fs = "\t"; 1116ab05f83Stholo else if (argc > 1 && argv[1][0] != 0) 1126ab05f83Stholo fs = &argv[1][0]; 1136ab05f83Stholo } 1146ab05f83Stholo if (fs == NULL || *fs == '\0') 1157b11b857Smillert WARNING("field separator FS is empty"); 1166ab05f83Stholo break; 1176ab05f83Stholo case 'v': /* -v a=1 to be done NOW. one -v for each */ 118*000399a4Smillert if (argv[1][2] != 0) { /* arg is -vsomething */ 119*000399a4Smillert if (isclvar(&argv[1][2])) 120d6972635Smillert setclvar(&argv[1][2]); 121*000399a4Smillert else 122*000399a4Smillert FATAL("invalid -v option argument: %s", &argv[1][2]); 123*000399a4Smillert } else { /* arg is -v something */ 124*000399a4Smillert argc--; argv++; 125*000399a4Smillert if (argc <= 1) 126*000399a4Smillert FATAL("no variable name"); 127*000399a4Smillert if (isclvar(argv[1])) 128*000399a4Smillert setclvar(argv[1]); 129*000399a4Smillert else 130*000399a4Smillert FATAL("invalid -v option argument: %s", argv[1]); 131*000399a4Smillert } 1326ab05f83Stholo break; 1336ab05f83Stholo case 'd': 1346ab05f83Stholo dbg = atoi(&argv[1][2]); 1356ab05f83Stholo if (dbg == 0) 1366ab05f83Stholo dbg = 1; 1376ab05f83Stholo printf("awk %s\n", version); 1386ab05f83Stholo break; 139a4fa8700Smillert case 'V': /* added for exptools "standard" */ 140a4fa8700Smillert printf("awk %s\n", version); 141a4fa8700Smillert exit(0); 142a4fa8700Smillert break; 1436ab05f83Stholo default: 1447b11b857Smillert WARNING("unknown option %s ignored", argv[1]); 1456ab05f83Stholo break; 1466ab05f83Stholo } 1476ab05f83Stholo argc--; 1486ab05f83Stholo argv++; 1496ab05f83Stholo } 1506ab05f83Stholo /* argv[1] is now the first argument */ 1516ab05f83Stholo if (npfile == 0) { /* no -f; first argument is program */ 1526ab05f83Stholo if (argc <= 1) { 1536ab05f83Stholo if (dbg) 1546ab05f83Stholo exit(0); 1557b11b857Smillert FATAL("no program given"); 1566ab05f83Stholo } 1576ab05f83Stholo dprintf( ("program = |%s|\n", argv[1]) ); 1586ab05f83Stholo lexprog = argv[1]; 1596ab05f83Stholo argc--; 1606ab05f83Stholo argv++; 1616ab05f83Stholo } 1626ab05f83Stholo recinit(recsize); 1636ab05f83Stholo syminit(); 1646ab05f83Stholo compile_time = 1; 1656ab05f83Stholo argv[0] = cmdname; /* put prog name at front of arglist */ 1666ab05f83Stholo dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) ); 1676ab05f83Stholo arginit(argc, argv); 16807edfa4aSkstailey if (!safe) 1696ab05f83Stholo envinit(environ); 1706ab05f83Stholo yyparse(); 17123cb51abSmillert setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */ 1726ab05f83Stholo if (fs) 17307edfa4aSkstailey *FS = qstring(fs, '\0'); 1746ab05f83Stholo dprintf( ("errorflag=%d\n", errorflag) ); 1756ab05f83Stholo if (errorflag == 0) { 1766ab05f83Stholo compile_time = 0; 1776ab05f83Stholo run(winner); 1786ab05f83Stholo } else 1796ab05f83Stholo bracecheck(); 1806ab05f83Stholo return(errorflag); 1816ab05f83Stholo } 1826ab05f83Stholo 1836ab05f83Stholo int pgetc(void) /* get 1 character from awk program */ 1846ab05f83Stholo { 1856ab05f83Stholo int c; 1866ab05f83Stholo 1876ab05f83Stholo for (;;) { 1886ab05f83Stholo if (yyin == NULL) { 1896ab05f83Stholo if (curpfile >= npfile) 1906ab05f83Stholo return EOF; 19107edfa4aSkstailey if (strcmp(pfile[curpfile], "-") == 0) 1926ab05f83Stholo yyin = stdin; 19307edfa4aSkstailey else if ((yyin = fopen(pfile[curpfile], "r")) == NULL) 1947b11b857Smillert FATAL("can't open file %s", pfile[curpfile]); 195271018d0Smillert lineno = 1; 1966ab05f83Stholo } 1976ab05f83Stholo if ((c = getc(yyin)) != EOF) 1986ab05f83Stholo return c; 1996ab05f83Stholo if (yyin != stdin) 2006ab05f83Stholo fclose(yyin); 2016ab05f83Stholo yyin = NULL; 2026ab05f83Stholo curpfile++; 2036ab05f83Stholo } 2046ab05f83Stholo } 205271018d0Smillert 206271018d0Smillert char *cursource(void) /* current source file name */ 207271018d0Smillert { 208271018d0Smillert if (npfile > 0) 209271018d0Smillert return pfile[curpfile]; 210271018d0Smillert else 211271018d0Smillert return NULL; 212271018d0Smillert } 213