You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
5.9 KiB
222 lines
5.9 KiB
/**************************************************************** |
|
Copyright (C) Lucent Technologies 1997 |
|
All Rights Reserved |
|
|
|
Permission to use, copy, modify, and distribute this software and |
|
its documentation for any purpose and without fee is hereby |
|
granted, provided that the above copyright notice appear in all |
|
copies and that both that the copyright notice and this |
|
permission notice and warranty disclaimer appear in supporting |
|
documentation, and that the name Lucent Technologies or any of |
|
its entities not be used in advertising or publicity pertaining |
|
to distribution of the software without specific, written prior |
|
permission. |
|
|
|
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. |
|
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY |
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER |
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF |
|
THIS SOFTWARE. |
|
****************************************************************/ |
|
|
|
const char *version = "version 20190125"; |
|
|
|
#define DEBUG |
|
#include <stdio.h> |
|
#include <ctype.h> |
|
#include <locale.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <signal.h> |
|
#include "awk.h" |
|
#include "ytab.h" |
|
|
|
extern char **environ; |
|
extern int nfields; |
|
|
|
int dbg = 0; |
|
Awkfloat srand_seed = 1; |
|
char *cmdname; /* gets argv[0] for error messages */ |
|
extern FILE *yyin; /* lex input file */ |
|
char *lexprog; /* points to program argument if it exists */ |
|
extern int errorflag; /* non-zero if any syntax errors; set by yyerror */ |
|
int compile_time = 2; /* for error printing: */ |
|
/* 2 = cmdline, 1 = compile, 0 = running */ |
|
|
|
#define MAX_PFILE 20 /* max number of -f's */ |
|
|
|
char *pfile[MAX_PFILE]; /* program filenames from -f's */ |
|
int npfile = 0; /* number of filenames */ |
|
int curpfile = 0; /* current filename */ |
|
|
|
int safe = 0; /* 1 => "safe" mode */ |
|
|
|
/* Can this work with recursive calls? I don't think so. |
|
void segvcatch(int n) |
|
{ |
|
FATAL("segfault. Do you have an unbounded recursive call?", n); |
|
} |
|
*/ |
|
|
|
int main(int argc, char *argv[]) |
|
{ |
|
const char *fs = NULL; |
|
|
|
setlocale(LC_CTYPE, ""); |
|
setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */ |
|
cmdname = argv[0]; |
|
if (argc == 1) { |
|
fprintf(stderr, |
|
"usage: %s [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]\n", |
|
cmdname); |
|
exit(1); |
|
} |
|
signal(SIGFPE, fpecatch); |
|
/*signal(SIGSEGV, segvcatch); experiment */ |
|
|
|
srand_seed = 1; |
|
srand(srand_seed); |
|
|
|
yyin = NULL; |
|
symtab = makesymtab(NSYMTAB/NSYMTAB); |
|
while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') { |
|
if (strcmp(argv[1],"-version") == 0 || strcmp(argv[1],"--version") == 0) { |
|
printf("awk %s\n", version); |
|
exit(0); |
|
break; |
|
} |
|
if (strcmp(argv[1], "--") == 0) { /* explicit end of args */ |
|
argc--; |
|
argv++; |
|
break; |
|
} |
|
switch (argv[1][1]) { |
|
case 's': |
|
if (strcmp(argv[1], "-safe") == 0) |
|
safe = 1; |
|
break; |
|
case 'f': /* next argument is program filename */ |
|
if (argv[1][2] != 0) { /* arg is -fsomething */ |
|
if (npfile >= MAX_PFILE - 1) |
|
FATAL("too many -f options"); |
|
pfile[npfile++] = &argv[1][2]; |
|
} else { /* arg is -f something */ |
|
argc--; argv++; |
|
if (argc <= 1) |
|
FATAL("no program filename"); |
|
if (npfile >= MAX_PFILE - 1) |
|
FATAL("too many -f options"); |
|
pfile[npfile++] = argv[1]; |
|
} |
|
break; |
|
case 'F': /* set field separator */ |
|
if (argv[1][2] != 0) { /* arg is -Fsomething */ |
|
if (argv[1][2] == 't' && argv[1][3] == 0) /* wart: t=>\t */ |
|
fs = "\t"; |
|
else if (argv[1][2] != 0) |
|
fs = &argv[1][2]; |
|
} else { /* arg is -F something */ |
|
argc--; argv++; |
|
if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0) /* wart: t=>\t */ |
|
fs = "\t"; |
|
else if (argc > 1 && argv[1][0] != 0) |
|
fs = &argv[1][0]; |
|
} |
|
if (fs == NULL || *fs == '\0') |
|
WARNING("field separator FS is empty"); |
|
break; |
|
case 'v': /* -v a=1 to be done NOW. one -v for each */ |
|
if (argv[1][2] != 0) { /* arg is -vsomething */ |
|
if (isclvar(&argv[1][2])) |
|
setclvar(&argv[1][2]); |
|
else |
|
FATAL("invalid -v option argument: %s", &argv[1][2]); |
|
} else { /* arg is -v something */ |
|
argc--; argv++; |
|
if (argc <= 1) |
|
FATAL("no variable name"); |
|
if (isclvar(argv[1])) |
|
setclvar(argv[1]); |
|
else |
|
FATAL("invalid -v option argument: %s", argv[1]); |
|
} |
|
break; |
|
case 'd': |
|
dbg = atoi(&argv[1][2]); |
|
if (dbg == 0) |
|
dbg = 1; |
|
printf("awk %s\n", version); |
|
break; |
|
default: |
|
WARNING("unknown option %s ignored", argv[1]); |
|
break; |
|
} |
|
argc--; |
|
argv++; |
|
} |
|
/* argv[1] is now the first argument */ |
|
if (npfile == 0) { /* no -f; first argument is program */ |
|
if (argc <= 1) { |
|
if (dbg) |
|
exit(0); |
|
FATAL("no program given"); |
|
} |
|
dprintf( ("program = |%s|\n", argv[1]) ); |
|
lexprog = argv[1]; |
|
argc--; |
|
argv++; |
|
} |
|
recinit(recsize); |
|
syminit(); |
|
compile_time = 1; |
|
argv[0] = cmdname; /* put prog name at front of arglist */ |
|
dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) ); |
|
arginit(argc, argv); |
|
if (!safe) |
|
envinit(environ); |
|
yyparse(); |
|
setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */ |
|
if (fs) |
|
*FS = qstring(fs, '\0'); |
|
dprintf( ("errorflag=%d\n", errorflag) ); |
|
if (errorflag == 0) { |
|
compile_time = 0; |
|
run(winner); |
|
} else |
|
bracecheck(); |
|
return(errorflag); |
|
} |
|
|
|
int pgetc(void) /* get 1 character from awk program */ |
|
{ |
|
int c; |
|
|
|
for (;;) { |
|
if (yyin == NULL) { |
|
if (curpfile >= npfile) |
|
return EOF; |
|
if (strcmp(pfile[curpfile], "-") == 0) |
|
yyin = stdin; |
|
else if ((yyin = fopen(pfile[curpfile], "r")) == NULL) |
|
FATAL("can't open file %s", pfile[curpfile]); |
|
lineno = 1; |
|
} |
|
if ((c = getc(yyin)) != EOF) |
|
return c; |
|
if (yyin != stdin) |
|
fclose(yyin); |
|
yyin = NULL; |
|
curpfile++; |
|
} |
|
} |
|
|
|
char *cursource(void) /* current source file name */ |
|
{ |
|
if (npfile > 0) |
|
return pfile[curpfile]; |
|
else |
|
return NULL; |
|
}
|
|
|