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 This file lists all bug fixes, changes, etc., made since the AWK book
was sent to the printers in August, 1987. 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: December 27, 2019:
Fix a bug whereby a{0,3} could match four a's. Thanks to Fix a bug whereby a{0,3} could match four a's. Thanks to
"Anonymous AWK fan" for the report. "Anonymous AWK fan" for the report.

7
lex.c
View File

@ -190,7 +190,9 @@ int yylex(void)
if (isalpha(c) || c == '_') if (isalpha(c) || c == '_')
return word(buf); return word(buf);
if (isdigit(c)) { 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? */ /* should this also have STR set? */
RET(NUMBER); RET(NUMBER);
} }
@ -431,8 +433,9 @@ int string(void)
} }
*bp = 0; *bp = 0;
s = tostring(buf); s = tostring(buf);
*bp++ = ' '; *bp++ = 0; *bp++ = ' '; *bp++ = '\0';
yylval.cp = setsymtab(buf, s, 0.0, CON|STR|DONTFREE, symtab); yylval.cp = setsymtab(buf, s, 0.0, CON|STR|DONTFREE, symtab);
free(s);
RET(STRING); 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. THIS SOFTWARE.
****************************************************************/ ****************************************************************/
const char *version = "version 20191227"; const char *version = "version 20200105";
#define DEBUG #define DEBUG
#include <stdio.h> #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) if (p == NULL)
FATAL("out of space concatenating %s and %s", sa, sb); FATAL("out of space concatenating %s and %s", sa, sb);
snprintf(p, l, "%s%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(p);
free(newbuf);
return c; return c;
} }