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