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 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 37 extern char **environ; 38 extern int nfields; 39 40 int dbg = 0; 41 char *cmdname; /* gets argv[0] for error messages */ 42 extern FILE *yyin; /* lex input file */ 43 char *lexprog; /* points to program argument if it exists */ 44 extern int errorflag; /* non-zero if any syntax errors; set by yyerror */ 45 int compile_time = 2; /* for error printing: */ 46 /* 2 = cmdline, 1 = compile, 0 = running */ 47 48 char *pfile[20]; /* program filenames from -f's */ 49 int npfile = 0; /* number of filenames */ 50 int curpfile = 0; /* current filename */ 51 52 int safe = 0; /* 1 => "safe" mode */ 53 54 int 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 161 int 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 184 char *cursource(void) /* current source file name */ 185 { 186 if (npfile > 0) 187 return pfile[curpfile]; 188 else 189 return NULL; 190 } 191