shithub: trueawk

Download patch

ref: c7eeb57210cc7104df233a243295c36ffe6a2117
parent: a1aad88728f6a8bf70c9bf9fd07b062aa6540040
author: Arnold D. Robbins <arnold@skeeve.com>
date: Sun Jan 5 16:18:36 EST 2020

Fix merging of concatenated string constants.

--- a/FIXES
+++ b/FIXES
@@ -25,6 +25,13 @@
 This file lists all bug fixes, changes, etc., made since the AWK book
 was sent to the printers in August, 1987.
 
+January 5, 2020:
+	Fix a bug in the concatentation of two string constants into
+	one done in the grammar.  Fixes GitHub issue #61.  Thanks
+	to GitHub user awkfan77 for pointing out the direction for
+	the fix.  New test T.concat added to the test suite.
+	Fix a few memory leaks reported by valgrind, as well.
+
 December 27, 2019:
 	Fix a bug whereby a{0,3} could match four a's.  Thanks to
 	"Anonymous AWK fan" for the report.
--- a/lex.c
+++ b/lex.c
@@ -190,7 +190,9 @@
 		if (isalpha(c) || c == '_')
 			return word(buf);
 		if (isdigit(c)) {
-			yylval.cp = setsymtab(buf, tostring(buf), atof(buf), CON|NUM, symtab);
+			char *cp = tostring(buf);
+			yylval.cp = setsymtab(buf, cp, atof(buf), CON|NUM, symtab);
+			free(cp);
 			/* should this also have STR set? */
 			RET(NUMBER);
 		}
@@ -431,8 +433,9 @@
 	}
 	*bp = 0;
 	s = tostring(buf);
-	*bp++ = ' '; *bp++ = 0;
+	*bp++ = ' '; *bp++ = '\0';
 	yylval.cp = setsymtab(buf, s, 0.0, CON|STR|DONTFREE, symtab);
+	free(s);
 	RET(STRING);
 }
 
--- a/main.c
+++ b/main.c
@@ -22,7 +22,7 @@
 THIS SOFTWARE.
 ****************************************************************/
 
-const char	*version = "version 20191227";
+const char	*version = "version 20200105";
 
 #define DEBUG
 #include <stdio.h>
--- /dev/null
+++ b/testdir/T.concat
@@ -1,0 +1,29 @@
+echo T.concat: test constant string concatentation
+
+awk=${awk-../a.out}
+
+$awk '
+BEGIN {
+	$0 = "aaa"
+	print "abcdef" " " $0
+}
+BEGIN { print "hello" "world"; print helloworld }
+BEGIN {
+ 	print " " "hello"
+ 	print "hello" " "
+ 	print "hello" " " "world"
+ 	print "hello" (" " "world")
+}
+' > foo1
+
+cat << \EOF > foo2
+abcdef aaa
+helloworld
+
+ hello
+hello 
+hello world
+hello world
+EOF
+
+diff foo1 foo2 || echo 'BAD: T.concat (1)'
--- a/tran.c
+++ b/tran.c
@@ -527,8 +527,15 @@
 	if (p == NULL)
 		FATAL("out of space concatenating %s and %s", sa, sb);
 	snprintf(p, l, "%s%s", sa, sb);
-	c = setsymtab(p, p, 0.0, CON|STR|DONTFREE, symtab);
+	char *newbuf = malloc(strlen(p) + 2);
+	if (newbuf == NULL)
+		FATAL("out of space concatenating %s and %s", sa, sb);
+	// See string() in lex.c; a string "xx" is stored in the symbol
+	// table as "xx ".
+	sprintf(newbuf, "%s ", p);
+	c = setsymtab(newbuf, p, 0.0, CON|STR|DONTFREE, symtab);
 	free(p);
+	free(newbuf);
 	return c;
 }
 
--