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;
}
--
⑨