main.c revision 112336
1/**************************************************************** 2Copyright (C) Lucent Technologies 1997 3All Rights Reserved 4 5Permission to use, copy, modify, and distribute this software and 6its documentation for any purpose and without fee is hereby 7granted, provided that the above copyright notice appear in all 8copies and that both that the copyright notice and this 9permission notice and warranty disclaimer appear in supporting 10documentation, and that the name Lucent Technologies or any of 11its entities not be used in advertising or publicity pertaining 12to distribution of the software without specific, written prior 13permission. 14 15LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22THIS SOFTWARE. 23****************************************************************/ 24 25const char *version = "version 20030314"; 26 27#define DEBUG 28#include <stdio.h> 29#include <ctype.h> 30#include <locale.h> 31#include <stdlib.h> 32#include <string.h> 33#include <signal.h> 34#include "awk.h" 35#include "ytab.h" 36 37extern char **environ; 38extern int nfields; 39 40int dbg = 0; 41char *cmdname; /* gets argv[0] for error messages */ 42extern FILE *yyin; /* lex input file */ 43char *lexprog; /* points to program argument if it exists */ 44extern int errorflag; /* non-zero if any syntax errors; set by yyerror */ 45int compile_time = 2; /* for error printing: */ 46 /* 2 = cmdline, 1 = compile, 0 = running */ 47 48char *pfile[20]; /* program filenames from -f's */ 49int npfile = 0; /* number of filenames */ 50int curpfile = 0; /* current filename */ 51 52int safe = 0; /* 1 => "safe" mode */ 53 54int main(int argc, char *argv[]) 55{ 56 const char *fs = NULL; 57 58 setlocale(LC_ALL, ""); 59 setlocale(LC_COLLATE, ""); 60 setlocale(LC_CTYPE, ""); 61 setlocale(LC_MESSAGES, ""); 62 cmdname = argv[0]; 63 if (argc == 1) { 64 fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [files]\n", cmdname); 65 exit(1); 66 } 67 signal(SIGFPE, fpecatch); 68 yyin = NULL; 69 symtab = makesymtab(NSYMTAB); 70 while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') { 71 if (strcmp(argv[1], "--") == 0) { /* explicit end of args */ 72 argc--; 73 argv++; 74 break; 75 } 76 switch (argv[1][1]) { 77 case 's': 78 if (strcmp(argv[1], "-safe") == 0) 79 safe = 1; 80 break; 81 case 'f': /* next argument is program filename */ 82 argc--; 83 argv++; 84 if (argc <= 1) 85 FATAL("no program filename"); 86 pfile[npfile++] = argv[1]; 87 break; 88 case 'F': /* set field separator */ 89 if (argv[1][2] != 0) { /* arg is -Fsomething */ 90 if (argv[1][2] == 't' && argv[1][3] == 0) /* wart: t=>\t */ 91 fs = "\t"; 92 else if (argv[1][2] != 0) 93 fs = &argv[1][2]; 94 } else { /* arg is -F something */ 95 argc--; argv++; 96 if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0) /* wart: t=>\t */ 97 fs = "\t"; 98 else if (argc > 1 && argv[1][0] != 0) 99 fs = &argv[1][0]; 100 } 101 if (fs == NULL || *fs == '\0') 102 WARNING("field separator FS is empty"); 103 break; 104 case 'v': /* -v a=1 to be done NOW. one -v for each */ 105 if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1])) 106 setclvar(argv[1]); 107 break; 108 case 'm': /* more memory: -mr=record, -mf=fields */ 109 /* no longer supported */ 110 WARNING("obsolete option %s ignored", argv[1]); 111 break; 112 case 'd': 113 dbg = atoi(&argv[1][2]); 114 if (dbg == 0) 115 dbg = 1; 116 printf("awk %s\n", version); 117 break; 118 case 'V': /* added for exptools "standard" */ 119 printf("awk %s\n", version); 120 exit(0); 121 break; 122 default: 123 WARNING("unknown option %s ignored", argv[1]); 124 break; 125 } 126 argc--; 127 argv++; 128 } 129 /* argv[1] is now the first argument */ 130 if (npfile == 0) { /* no -f; first argument is program */ 131 if (argc <= 1) { 132 if (dbg) 133 exit(0); 134 FATAL("no program given"); 135 } 136 dprintf( ("program = |%s|\n", argv[1]) ); 137 lexprog = argv[1]; 138 argc--; 139 argv++; 140 } 141 recinit(recsize); 142 syminit(); 143 compile_time = 1; 144 argv[0] = cmdname; /* put prog name at front of arglist */ 145 dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) ); 146 arginit(argc, argv); 147 if (!safe) 148 envinit(environ); 149 yyparse(); 150 if (fs) 151 *FS = qstring(fs, '\0'); 152 dprintf( ("errorflag=%d\n", errorflag) ); 153 if (errorflag == 0) { 154 compile_time = 0; 155 run(winner); 156 } else 157 bracecheck(); 158 return(errorflag); 159} 160 161int pgetc(void) /* get 1 character from awk program */ 162{ 163 int c; 164 165 for (;;) { 166 if (yyin == NULL) { 167 if (curpfile >= npfile) 168 return EOF; 169 if (strcmp(pfile[curpfile], "-") == 0) 170 yyin = stdin; 171 else if ((yyin = fopen(pfile[curpfile], "r")) == NULL) 172 FATAL("can't open file %s", pfile[curpfile]); 173 lineno = 1; 174 } 175 if ((c = getc(yyin)) != EOF) 176 return c; 177 if (yyin != stdin) 178 fclose(yyin); 179 yyin = NULL; 180 curpfile++; 181 } 182} 183 184char *cursource(void) /* current source file name */ 185{ 186 if (npfile > 0) 187 return pfile[curpfile]; 188 else 189 return NULL; 190} 191