main.c revision 118194
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 25118194Sruconst char *version = "version 20030729"; 2685587Sobrien 2785587Sobrien#define DEBUG 2885587Sobrien#include <stdio.h> 2985587Sobrien#include <ctype.h> 30112336Sobrien#include <locale.h> 3185587Sobrien#include <stdlib.h> 3285587Sobrien#include <string.h> 3385587Sobrien#include <signal.h> 3485587Sobrien#include "awk.h" 3585587Sobrien#include "ytab.h" 3685587Sobrien 3785587Sobrienextern char **environ; 3885587Sobrienextern int nfields; 3985587Sobrien 4085587Sobrienint dbg = 0; 4185587Sobrienchar *cmdname; /* gets argv[0] for error messages */ 4285587Sobrienextern FILE *yyin; /* lex input file */ 4385587Sobrienchar *lexprog; /* points to program argument if it exists */ 4485587Sobrienextern int errorflag; /* non-zero if any syntax errors; set by yyerror */ 4585587Sobrienint compile_time = 2; /* for error printing: */ 4685587Sobrien /* 2 = cmdline, 1 = compile, 0 = running */ 4785587Sobrien 4885587Sobrienchar *pfile[20]; /* program filenames from -f's */ 4985587Sobrienint npfile = 0; /* number of filenames */ 5085587Sobrienint curpfile = 0; /* current filename */ 5185587Sobrien 5285587Sobrienint safe = 0; /* 1 => "safe" mode */ 5385587Sobrien 5485587Sobrienint main(int argc, char *argv[]) 5585587Sobrien{ 56107806Sobrien const char *fs = NULL; 5785587Sobrien 58112336Sobrien setlocale(LC_CTYPE, ""); 59118194Sru setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */ 6085587Sobrien cmdname = argv[0]; 6185587Sobrien if (argc == 1) { 6285587Sobrien fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [files]\n", cmdname); 6385587Sobrien exit(1); 6485587Sobrien } 6585587Sobrien signal(SIGFPE, fpecatch); 6685587Sobrien yyin = NULL; 6785587Sobrien symtab = makesymtab(NSYMTAB); 6885587Sobrien while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') { 6985587Sobrien if (strcmp(argv[1], "--") == 0) { /* explicit end of args */ 7085587Sobrien argc--; 7185587Sobrien argv++; 7285587Sobrien break; 7385587Sobrien } 7485587Sobrien switch (argv[1][1]) { 7585587Sobrien case 's': 7685587Sobrien if (strcmp(argv[1], "-safe") == 0) 7785587Sobrien safe = 1; 7885587Sobrien break; 7985587Sobrien case 'f': /* next argument is program filename */ 8085587Sobrien argc--; 8185587Sobrien argv++; 8285587Sobrien if (argc <= 1) 8385587Sobrien FATAL("no program filename"); 8485587Sobrien pfile[npfile++] = argv[1]; 8585587Sobrien break; 8685587Sobrien case 'F': /* set field separator */ 8785587Sobrien if (argv[1][2] != 0) { /* arg is -Fsomething */ 8885587Sobrien if (argv[1][2] == 't' && argv[1][3] == 0) /* wart: t=>\t */ 8985587Sobrien fs = "\t"; 9085587Sobrien else if (argv[1][2] != 0) 9185587Sobrien fs = &argv[1][2]; 9285587Sobrien } else { /* arg is -F something */ 9385587Sobrien argc--; argv++; 9485587Sobrien if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0) /* wart: t=>\t */ 9585587Sobrien fs = "\t"; 9685587Sobrien else if (argc > 1 && argv[1][0] != 0) 9785587Sobrien fs = &argv[1][0]; 9885587Sobrien } 9985587Sobrien if (fs == NULL || *fs == '\0') 10085587Sobrien WARNING("field separator FS is empty"); 10185587Sobrien break; 10285587Sobrien case 'v': /* -v a=1 to be done NOW. one -v for each */ 10385587Sobrien if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1])) 10485587Sobrien setclvar(argv[1]); 10585587Sobrien break; 10685587Sobrien case 'm': /* more memory: -mr=record, -mf=fields */ 10790902Sdes /* no longer supported */ 10890902Sdes WARNING("obsolete option %s ignored", argv[1]); 10985587Sobrien break; 11085587Sobrien case 'd': 11185587Sobrien dbg = atoi(&argv[1][2]); 11285587Sobrien if (dbg == 0) 11385587Sobrien dbg = 1; 11485587Sobrien printf("awk %s\n", version); 11585587Sobrien break; 11685587Sobrien case 'V': /* added for exptools "standard" */ 11785587Sobrien printf("awk %s\n", version); 11885587Sobrien exit(0); 11985587Sobrien break; 12085587Sobrien default: 12185587Sobrien WARNING("unknown option %s ignored", argv[1]); 12285587Sobrien break; 12385587Sobrien } 12485587Sobrien argc--; 12585587Sobrien argv++; 12685587Sobrien } 12785587Sobrien /* argv[1] is now the first argument */ 12885587Sobrien if (npfile == 0) { /* no -f; first argument is program */ 12985587Sobrien if (argc <= 1) { 13085587Sobrien if (dbg) 13185587Sobrien exit(0); 13285587Sobrien FATAL("no program given"); 13385587Sobrien } 13485587Sobrien dprintf( ("program = |%s|\n", argv[1]) ); 13585587Sobrien lexprog = argv[1]; 13685587Sobrien argc--; 13785587Sobrien argv++; 13885587Sobrien } 13985587Sobrien recinit(recsize); 14085587Sobrien syminit(); 14185587Sobrien compile_time = 1; 14285587Sobrien argv[0] = cmdname; /* put prog name at front of arglist */ 14385587Sobrien dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) ); 14485587Sobrien arginit(argc, argv); 14585587Sobrien if (!safe) 14685587Sobrien envinit(environ); 14785587Sobrien yyparse(); 148118194Sru setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */ 14985587Sobrien if (fs) 15085587Sobrien *FS = qstring(fs, '\0'); 15185587Sobrien dprintf( ("errorflag=%d\n", errorflag) ); 15285587Sobrien if (errorflag == 0) { 15385587Sobrien compile_time = 0; 15485587Sobrien run(winner); 15585587Sobrien } else 15685587Sobrien bracecheck(); 15785587Sobrien return(errorflag); 15885587Sobrien} 15985587Sobrien 16085587Sobrienint pgetc(void) /* get 1 character from awk program */ 16185587Sobrien{ 16285587Sobrien int c; 16385587Sobrien 16485587Sobrien for (;;) { 16585587Sobrien if (yyin == NULL) { 16685587Sobrien if (curpfile >= npfile) 16785587Sobrien return EOF; 16885587Sobrien if (strcmp(pfile[curpfile], "-") == 0) 16985587Sobrien yyin = stdin; 17085587Sobrien else if ((yyin = fopen(pfile[curpfile], "r")) == NULL) 17185587Sobrien FATAL("can't open file %s", pfile[curpfile]); 17285587Sobrien lineno = 1; 17385587Sobrien } 17485587Sobrien if ((c = getc(yyin)) != EOF) 17585587Sobrien return c; 17685587Sobrien if (yyin != stdin) 17785587Sobrien fclose(yyin); 17885587Sobrien yyin = NULL; 17985587Sobrien curpfile++; 18085587Sobrien } 18185587Sobrien} 18285587Sobrien 18385587Sobrienchar *cursource(void) /* current source file name */ 18485587Sobrien{ 18585587Sobrien if (npfile > 0) 18685587Sobrien return pfile[curpfile]; 18785587Sobrien else 18885587Sobrien return NULL; 18985587Sobrien} 190