main.c revision 221533
185587Sobrien/**************************************************************** 285587SobrienCopyright (C) Lucent Technologies 1997 385587SobrienAll Rights Reserved 485587Sobrien 585587SobrienPermission to use, copy, modify, and distribute this software and 685587Sobrienits documentation for any purpose and without fee is hereby 785587Sobriengranted, provided that the above copyright notice appear in all 885587Sobriencopies and that both that the copyright notice and this 985587Sobrienpermission notice and warranty disclaimer appear in supporting 1085587Sobriendocumentation, and that the name Lucent Technologies or any of 1185587Sobrienits entities not be used in advertising or publicity pertaining 1285587Sobriento distribution of the software without specific, written prior 1385587Sobrienpermission. 1485587Sobrien 1585587SobrienLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1685587SobrienINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 1785587SobrienIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 1885587SobrienSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1985587SobrienWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 2085587SobrienIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 2185587SobrienARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 2285587SobrienTHIS SOFTWARE. 2385587Sobrien****************************************************************/ 2485587Sobrien 25201989Sru#include <sys/cdefs.h> 26201989Sru__FBSDID("$FreeBSD: head/contrib/one-true-awk/main.c 221533 2011-05-06 14:21:46Z ru $"); 2785587Sobrien 28221533Sruconst char *version = "version 20110506 (FreeBSD)"; 29201989Sru 3085587Sobrien#define DEBUG 3185587Sobrien#include <stdio.h> 3285587Sobrien#include <ctype.h> 33112336Sobrien#include <locale.h> 3485587Sobrien#include <stdlib.h> 3585587Sobrien#include <string.h> 3685587Sobrien#include <signal.h> 3785587Sobrien#include "awk.h" 3885587Sobrien#include "ytab.h" 3985587Sobrien 4085587Sobrienextern char **environ; 4185587Sobrienextern int nfields; 4285587Sobrien 4385587Sobrienint dbg = 0; 44221381SruAwkfloat srand_seed = 1; 4585587Sobrienchar *cmdname; /* gets argv[0] for error messages */ 4685587Sobrienextern FILE *yyin; /* lex input file */ 4785587Sobrienchar *lexprog; /* points to program argument if it exists */ 4885587Sobrienextern int errorflag; /* non-zero if any syntax errors; set by yyerror */ 4985587Sobrienint compile_time = 2; /* for error printing: */ 5085587Sobrien /* 2 = cmdline, 1 = compile, 0 = running */ 5185587Sobrien 52146299Sru#define MAX_PFILE 20 /* max number of -f's */ 53146299Sru 54146299Sruchar *pfile[MAX_PFILE]; /* program filenames from -f's */ 5585587Sobrienint npfile = 0; /* number of filenames */ 5685587Sobrienint curpfile = 0; /* current filename */ 5785587Sobrien 5885587Sobrienint safe = 0; /* 1 => "safe" mode */ 5985587Sobrien 6085587Sobrienint main(int argc, char *argv[]) 6185587Sobrien{ 62107806Sobrien const char *fs = NULL; 6385587Sobrien 64112336Sobrien setlocale(LC_CTYPE, ""); 65201989Sru setlocale(LC_COLLATE, ""); 66118194Sru setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */ 6785587Sobrien cmdname = argv[0]; 6885587Sobrien if (argc == 1) { 69170331Srafan fprintf(stderr, 70170331Srafan "usage: %s [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]\n", 71170331Srafan cmdname); 7285587Sobrien exit(1); 7385587Sobrien } 7485587Sobrien signal(SIGFPE, fpecatch); 75221381Sru 76221381Sru srand_seed = 1; 77221381Sru srand(srand_seed); 78221381Sru 7985587Sobrien yyin = NULL; 80170331Srafan symtab = makesymtab(NSYMTAB/NSYMTAB); 8185587Sobrien while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') { 82170331Srafan if (strcmp(argv[1],"-version") == 0 || strcmp(argv[1],"--version") == 0) { 83170331Srafan printf("awk %s\n", version); 84170331Srafan exit(0); 85170331Srafan break; 86170331Srafan } 87170331Srafan if (strncmp(argv[1], "--", 2) == 0) { /* explicit end of args */ 8885587Sobrien argc--; 8985587Sobrien argv++; 9085587Sobrien break; 9185587Sobrien } 9285587Sobrien switch (argv[1][1]) { 9385587Sobrien case 's': 9485587Sobrien if (strcmp(argv[1], "-safe") == 0) 9585587Sobrien safe = 1; 9685587Sobrien break; 9785587Sobrien case 'f': /* next argument is program filename */ 98221533Sru if (argv[1][2] != 0) { /* arg is -fsomething */ 99201989Sru if (npfile >= MAX_PFILE - 1) 100201989Sru FATAL("too many -f options"); 101201989Sru pfile[npfile++] = &argv[1][2]; 102201989Sru } else { /* arg is -f something */ 103201989Sru argc--; argv++; 104201989Sru if (argc <= 1) 105201989Sru FATAL("no program filename"); 106201989Sru if (npfile >= MAX_PFILE - 1) 107201989Sru FATAL("too many -f options"); 108201989Sru pfile[npfile++] = argv[1]; 109201989Sru } 11085587Sobrien break; 11185587Sobrien case 'F': /* set field separator */ 11285587Sobrien if (argv[1][2] != 0) { /* arg is -Fsomething */ 11385587Sobrien if (argv[1][2] == 't' && argv[1][3] == 0) /* wart: t=>\t */ 11485587Sobrien fs = "\t"; 11585587Sobrien else if (argv[1][2] != 0) 11685587Sobrien fs = &argv[1][2]; 11785587Sobrien } else { /* arg is -F something */ 11885587Sobrien argc--; argv++; 11985587Sobrien if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0) /* wart: t=>\t */ 12085587Sobrien fs = "\t"; 12185587Sobrien else if (argc > 1 && argv[1][0] != 0) 12285587Sobrien fs = &argv[1][0]; 12385587Sobrien } 12485587Sobrien if (fs == NULL || *fs == '\0') 12585587Sobrien WARNING("field separator FS is empty"); 12685587Sobrien break; 12785587Sobrien case 'v': /* -v a=1 to be done NOW. one -v for each */ 128221381Sru if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1])) 129221381Sru setclvar(argv[1]); 130221381Sru else if (argv[1][2] != '\0') 131221381Sru setclvar(&argv[1][2]); 13285587Sobrien break; 13385587Sobrien case 'd': 13485587Sobrien dbg = atoi(&argv[1][2]); 13585587Sobrien if (dbg == 0) 13685587Sobrien dbg = 1; 13785587Sobrien printf("awk %s\n", version); 13885587Sobrien break; 13985587Sobrien default: 14085587Sobrien WARNING("unknown option %s ignored", argv[1]); 14185587Sobrien break; 14285587Sobrien } 14385587Sobrien argc--; 14485587Sobrien argv++; 14585587Sobrien } 14685587Sobrien /* argv[1] is now the first argument */ 14785587Sobrien if (npfile == 0) { /* no -f; first argument is program */ 14885587Sobrien if (argc <= 1) { 14985587Sobrien if (dbg) 15085587Sobrien exit(0); 15185587Sobrien FATAL("no program given"); 15285587Sobrien } 15385587Sobrien dprintf( ("program = |%s|\n", argv[1]) ); 15485587Sobrien lexprog = argv[1]; 15585587Sobrien argc--; 15685587Sobrien argv++; 15785587Sobrien } 15885587Sobrien recinit(recsize); 15985587Sobrien syminit(); 16085587Sobrien compile_time = 1; 16185587Sobrien argv[0] = cmdname; /* put prog name at front of arglist */ 16285587Sobrien dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) ); 16385587Sobrien arginit(argc, argv); 16485587Sobrien if (!safe) 16585587Sobrien envinit(environ); 16685587Sobrien yyparse(); 167118194Sru setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */ 16885587Sobrien if (fs) 16985587Sobrien *FS = qstring(fs, '\0'); 17085587Sobrien dprintf( ("errorflag=%d\n", errorflag) ); 17185587Sobrien if (errorflag == 0) { 17285587Sobrien compile_time = 0; 17385587Sobrien run(winner); 17485587Sobrien } else 17585587Sobrien bracecheck(); 17685587Sobrien return(errorflag); 17785587Sobrien} 17885587Sobrien 17985587Sobrienint pgetc(void) /* get 1 character from awk program */ 18085587Sobrien{ 18185587Sobrien int c; 18285587Sobrien 18385587Sobrien for (;;) { 18485587Sobrien if (yyin == NULL) { 18585587Sobrien if (curpfile >= npfile) 18685587Sobrien return EOF; 18785587Sobrien if (strcmp(pfile[curpfile], "-") == 0) 18885587Sobrien yyin = stdin; 18985587Sobrien else if ((yyin = fopen(pfile[curpfile], "r")) == NULL) 19085587Sobrien FATAL("can't open file %s", pfile[curpfile]); 19185587Sobrien lineno = 1; 19285587Sobrien } 19385587Sobrien if ((c = getc(yyin)) != EOF) 19485587Sobrien return c; 19585587Sobrien if (yyin != stdin) 19685587Sobrien fclose(yyin); 19785587Sobrien yyin = NULL; 19885587Sobrien curpfile++; 19985587Sobrien } 20085587Sobrien} 20185587Sobrien 20285587Sobrienchar *cursource(void) /* current source file name */ 20385587Sobrien{ 20485587Sobrien if (npfile > 0) 20585587Sobrien return pfile[curpfile]; 20685587Sobrien else 20785587Sobrien return NULL; 20885587Sobrien} 209