shithub: riscv

Download patch

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: