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 #include <sys/cdefs.h> 26 __FBSDID("$FreeBSD$"); 27 28 const char *version = "version 20091126 (FreeBSD)"; 29 30 #define DEBUG 31 #include <stdio.h> 32 #include <ctype.h> 33 #include <locale.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <signal.h> 37 #include "awk.h" 38 #include "ytab.h" 39 40 extern char **environ; 41 extern int nfields; 42 43 int dbg = 0; 44 char *cmdname; /* gets argv[0] for error messages */ 45 extern FILE *yyin; /* lex input file */ 46 char *lexprog; /* points to program argument if it exists */ 47 extern int errorflag; /* non-zero if any syntax errors; set by yyerror */ 48 int compile_time = 2; /* for error printing: */ 49 /* 2 = cmdline, 1 = compile, 0 = running */ 50 51 #define MAX_PFILE 20 /* max number of -f's */ 52 53 char *pfile[MAX_PFILE]; /* program filenames from -f's */ 54 int npfile = 0; /* number of filenames */ 55 int curpfile = 0; /* current filename */ 56 57 int safe = 0; /* 1 => "safe" mode */ 58 59 int main(int argc, char *argv[]) 60 { 61 const char *fs = NULL; 62 63 setlocale(LC_CTYPE, ""); 64 setlocale(LC_COLLATE, ""); 65 setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */ 66 cmdname = argv[0]; 67 if (argc == 1) { 68 fprintf(stderr, 69 "usage: %s [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]\n", 70 cmdname); 71 exit(1); 72 } 73 signal(SIGFPE, fpecatch); 74 yyin = NULL; 75 symtab = makesymtab(NSYMTAB/NSYMTAB); 76 while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') { 77 if (strcmp(argv[1],"-version") == 0 || strcmp(argv[1],"--version") == 0) { 78 printf("awk %s\n", version); 79 exit(0); 80 break; 81 } 82 if (strncmp(argv[1], "--", 2) == 0) { /* explicit end of args */ 83 argc--; 84 argv++; 85 break; 86 } 87 switch (argv[1][1]) { 88 case 's': 89 if (strcmp(argv[1], "-safe") == 0) 90 safe = 1; 91 break; 92 case 'f': /* next argument is program filename */ 93 if (argv[1][2] != 0) { /* arg is -fsomething */ 94 if (npfile >= MAX_PFILE - 1) 95 FATAL("too many -f options"); 96 pfile[npfile++] = &argv[1][2]; 97 } else { /* arg is -f something */ 98 argc--; argv++; 99 if (argc <= 1) 100 FATAL("no program filename"); 101 if (npfile >= MAX_PFILE - 1) 102 FATAL("too many -f options"); 103 pfile[npfile++] = argv[1]; 104 } 105 break; 106 case 'F': /* set field separator */ 107 if (argv[1][2] != 0) { /* arg is -Fsomething */ 108 if (argv[1][2] == 't' && argv[1][3] == 0) /* wart: t=>\t */ 109 fs = "\t"; 110 else if (argv[1][2] != 0) 111 fs = &argv[1][2]; 112 } else { /* arg is -F something */ 113 argc--; argv++; 114 if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0) /* wart: t=>\t */ 115 fs = "\t"; 116 else if (argc > 1 && argv[1][0] != 0) 117 fs = &argv[1][0]; 118 } 119 if (fs == NULL || *fs == '\0') 120 WARNING("field separator FS is empty"); 121 break; 122 case 'v': /* -v a=1 to be done NOW. one -v for each */ 123 if (argv[1][2] != 0) { /* arg is -vsomething */ 124 if (argv[1][2] != 0) 125 setclvar(&argv[1][2]); 126 } else { /* arg is -v something */ 127 argc--; argv++; 128 if (argc > 1 && isclvar(argv[1])) 129 setclvar(argv[1]); 130 } 131 break; 132 case 'd': 133 dbg = atoi(&argv[1][2]); 134 if (dbg == 0) 135 dbg = 1; 136 printf("awk %s\n", version); 137 break; 138 default: 139 WARNING("unknown option %s ignored", argv[1]); 140 break; 141 } 142 argc--; 143 argv++; 144 } 145 /* argv[1] is now the first argument */ 146 if (npfile == 0) { /* no -f; first argument is program */ 147 if (argc <= 1) { 148 if (dbg) 149 exit(0); 150 FATAL("no program given"); 151 } 152 dprintf( ("program = |%s|\n", argv[1]) ); 153 lexprog = argv[1]; 154 argc--; 155 argv++; 156 } 157 recinit(recsize); 158 syminit(); 159 compile_time = 1; 160 argv[0] = cmdname; /* put prog name at front of arglist */ 161 dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) ); 162 arginit(argc, argv); 163 if (!safe) 164 envinit(environ); 165 yyparse(); 166 setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */ 167 if (fs) 168 *FS = qstring(fs, '\0'); 169 dprintf( ("errorflag=%d\n", errorflag) ); 170 if (errorflag == 0) { 171 compile_time = 0; 172 run(winner); 173 } else 174 bracecheck(); 175 return(errorflag); 176 } 177 178 int pgetc(void) /* get 1 character from awk program */ 179 { 180 int c; 181 182 for (;;) { 183 if (yyin == NULL) { 184 if (curpfile >= npfile) 185 return EOF; 186 if (strcmp(pfile[curpfile], "-") == 0) 187 yyin = stdin; 188 else if ((yyin = fopen(pfile[curpfile], "r")) == NULL) 189 FATAL("can't open file %s", pfile[curpfile]); 190 lineno = 1; 191 } 192 if ((c = getc(yyin)) != EOF) 193 return c; 194 if (yyin != stdin) 195 fclose(yyin); 196 yyin = NULL; 197 curpfile++; 198 } 199 } 200 201 char *cursource(void) /* current source file name */ 202 { 203 if (npfile > 0) 204 return pfile[curpfile]; 205 else 206 return NULL; 207 } 208