Fix merging of concatenated string constants.

This commit is contained in:
Arnold D. Robbins 2020-01-05 21:18:36 +02:00
parent a1aad88728
commit c7eeb57210
5 changed files with 50 additions and 4 deletions

7
FIXES
View File

@ -25,6 +25,13 @@ THIS SOFTWARE.
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.

7
lex.c
View File

@ -190,7 +190,9 @@ int yylex(void)
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 @@ int string(void)
}
*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);
}

2
main.c
View File

@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
const char *version = "version 20191227";
const char *version = "version 20200105";
#define DEBUG
#include <stdio.h>

29
testdir/T.concat Executable file
View File

@ -0,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)'

9
tran.c
View File

@ -527,8 +527,15 @@ Cell *catstr(Cell *a, Cell *b) /* concatenate a and b */
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;
}