aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FIXES7
-rw-r--r--lex.c7
-rw-r--r--main.c2
-rwxr-xr-xtestdir/T.concat29
-rw-r--r--tran.c9
5 files changed, 50 insertions, 4 deletions
diff --git a/FIXES b/FIXES
index ad5585c..6889e30 100644
--- a/FIXES
+++ b/FIXES
@@ -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.
diff --git a/lex.c b/lex.c
index 2de0603..1c6a0b7 100644
--- a/lex.c
+++ b/lex.c
@@ -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);
}
diff --git a/main.c b/main.c
index c8a2f32..abfa312 100644
--- a/main.c
+++ b/main.c
@@ -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>
diff --git a/testdir/T.concat b/testdir/T.concat
new file mode 100755
index 0000000..c6bd016
--- /dev/null
+++ b/testdir/T.concat
@@ -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)'
diff --git a/tran.c b/tran.c
index a102feb..1fca361 100644
--- a/tran.c
+++ b/tran.c
@@ -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;
}