ref: 9cf3dc9a259cadc80e6d3840c658ef1d5f7c94a4
parent: 3f9d5e4a4f9e4f0b5fe66e4a6745a4b8c5f6e447
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Aug 12 17:34:06 EDT 2017
awk: allow string as exit status
--- a/sys/src/cmd/awk/awk.h
+++ b/sys/src/cmd/awk/awk.h
@@ -45,7 +45,7 @@
extern char *record; /* points to $0 */
extern int lineno; /* line number in awk program */
-extern int errorflag; /* 1 if error has occurred */
+extern char *exitstatus; /* exit status string */
extern int donefld; /* 1 if record broken into fields */
extern int donerec; /* 1 if record is valid (no fld has changed */
extern char inputFS[]; /* FS at time of input, for field splitting */
--- a/sys/src/cmd/awk/awkgram.y
+++ b/sys/src/cmd/awk/awkgram.y
@@ -98,7 +98,7 @@
%%
program:
- pas { if (errorflag==0)
+ pas { if (exitstatus==nil)
winner = (Node *)stat3(PROGRAM, beginloc, $1, endloc); }
| error { yyclearin; bracecheck(); SYNTAX("bailing out"); }
;
--- a/sys/src/cmd/awk/lex.c
+++ b/sys/src/cmd/awk/lex.c
@@ -355,12 +355,15 @@
if (buf == 0 && (buf = (char *) malloc(bufsz)) == nil)
FATAL("out of space for strings");
for (bp = buf; (c = input()) != '"'; ) {
- if (!adjbuf(&buf, &bufsz, bp-buf+2, 500, &bp, 0))
+ if (!adjbuf(&buf, &bufsz, bp-buf+2, 500, &bp, 0)){
+ *bp = 0;
FATAL("out of space for string %.10s...", buf);
+ }
switch (c) {
case '\n':
case '\r':
- case 0:
+ case 0:
+ *bp = 0;
SYNTAX( "non-terminated string %.10s...", buf );
lineno++;
RET(0);
--- a/sys/src/cmd/awk/lib.c
+++ b/sys/src/cmd/awk/lib.c
@@ -466,7 +466,7 @@
donerec = 1;
}
-int errorflag = 0;
+char *exitstatus = nil;
void yyerror(char *s)
{
@@ -492,7 +492,7 @@
if (curfname != nil)
Bprint(&stderr, " in function %s", curfname);
Bprint(&stderr, "\n");
- errorflag = 2;
+ exitstatus = "syntax error";
eprint();
}
--- a/sys/src/cmd/awk/main.c
+++ b/sys/src/cmd/awk/main.c
@@ -40,7 +40,6 @@
char *cmdname; /* gets argv[0] for error messages */
extern Biobuf *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 */
@@ -161,15 +160,13 @@
yyparse();
if (fs)
*FS = qstring(fs, '\0');
- dprint( ("errorflag=%d\n", errorflag) );
- if (errorflag == 0) {
+ dprint( ("exitstatus=%s\n", exitstatus) );
+ if (exitstatus == nil) {
compile_time = 0;
run(winner);
} else
bracecheck();
- if(errorflag)
- exits("error");
- exits(0);
+ exits(exitstatus);
}
int pgetc(void) /* get 1 character from awk program */
--- a/sys/src/cmd/awk/parse.c
+++ b/sys/src/cmd/awk/parse.c
@@ -217,7 +217,7 @@
{
Node *c;
- if (errorflag) /* don't link things that are wrong */
+ if (exitstatus != nil) /* don't link things that are wrong */
return a;
if (a == nil)
return(b);
--- a/sys/src/cmd/awk/run.c
+++ b/sys/src/cmd/awk/run.c
@@ -353,9 +353,11 @@
case EXIT:
if (a[0] != nil) {
y = execute(a[0]);
- errorflag = (int) getfval(y);
- if (istemp(y))
- tfree(y);
+ if((y->tval & (NUM|STR)) == STR) {
+ exitstatus = getsval(y);
+ } else if((int) getfval(y) != 0) {
+ exitstatus = "error";
+ }
}
longjmp(env, 1);
case RETURN: