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