Merge branch 'master' into nf-self-assign

This commit is contained in:
onetrueawk 2019-01-21 14:09:21 -05:00 committed by GitHub
commit 4f4701e090
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 60 additions and 12 deletions

View File

@ -1,3 +1,9 @@
2018-08-29 Arnold D. Robbins <arnold@skeeve.com>
* REGRESS: Check for existence of a.out. If not there, run
make. Enable core dumps for T.arnold system status test
to work on MacOS X.
2018-08-22 Arnold D. Robbins <arnold@skeeve.com> 2018-08-22 Arnold D. Robbins <arnold@skeeve.com>
* awktest.tar (testdir/T.expr): Fix test for unary plus. * awktest.tar (testdir/T.expr): Fix test for unary plus.

5
FIXES
View File

@ -25,6 +25,11 @@ 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.
Oct 25, 2018:
Added test in maketab.c to prevent generating a proctab entry
for YYSTYPE_IS_DEFINED. It was harmless but some gcc settings
generated a warning message. Thanks to Nan Xiao for report.
Aug 27, 2018: Aug 27, 2018:
Disallow '$' in printf formats; arguments evaluated in order Disallow '$' in printf formats; arguments evaluated in order
and printed in order. and printed in order.

15
REGRESS
View File

@ -1,5 +1,15 @@
#! /bin/sh #! /bin/sh
case `uname` in
CYGWIN) EXE=a.exe ;;
*) EXE=a.out ;;
esac
if [ ! -f $EXE ]
then
make || exit 1
fi
if [ -d testdir ] if [ -d testdir ]
then then
true # do nothing true # do nothing
@ -16,5 +26,10 @@ cd testdir
pwd pwd
PATH=.:$PATH PATH=.:$PATH
export PATH export PATH
if (ulimit -c unlimited > /dev/null 2>&1)
then
# Workaround broken default on MacOS X
ulimit -c unlimited
fi
REGRESS REGRESS

View File

@ -24,6 +24,14 @@ and also if CONVFMT changed.
7. unary-plus: Unary plus on a string constant returned the string. 7. unary-plus: Unary plus on a string constant returned the string.
Instead, it should convert the value to numeric and give that value. Instead, it should convert the value to numeric and give that value.
8. missing-precision: When using the format string "%*s", the precision
argument was used without checking if it was present first.
9. fmt-overflow: The buffer used for OFMT/CONVFMT conversions was written
to with sprintf(), which meant that some conversions could write past the
end.
X. nf-self-assign: "NF = NF" wouldn't force the record to be rebuilt. X. nf-self-assign: "NF = NF" wouldn't force the record to be rebuilt.
X. negative-nf: Setting NF to a negative value caused a segmentation fault. X. negative-nf: Setting NF to a negative value caused a segmentation fault.

View File

@ -0,0 +1 @@
BEGIN { OFMT = "%.1000f"; print 1.25; }

View File

@ -0,0 +1 @@
1.2500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

View File

@ -0,0 +1 @@
BEGIN { printf("%*s"); }

View File

@ -0,0 +1,2 @@
./a.out: not enough args in printf(%*s)
source line number 1

18
lex.c
View File

@ -198,6 +198,7 @@ int yylex(void)
yylval.i = c; yylval.i = c;
switch (c) { switch (c) {
case '\n': /* {EOL} */ case '\n': /* {EOL} */
lineno++;
RET(NL); RET(NL);
case '\r': /* assume \n is coming */ case '\r': /* assume \n is coming */
case ' ': /* {WS}+ */ case ' ': /* {WS}+ */
@ -213,6 +214,7 @@ int yylex(void)
case '\\': case '\\':
if (peek() == '\n') { if (peek() == '\n') {
input(); input();
lineno++;
} else if (peek() == '\r') { } else if (peek() == '\r') {
input(); input(); /* \n */ input(); input(); /* \n */
lineno++; lineno++;
@ -370,10 +372,11 @@ int string(void)
case '\n': case '\n':
case '\r': case '\r':
case 0: case 0:
*bp = '\0';
SYNTAX( "non-terminated string %.10s...", buf ); SYNTAX( "non-terminated string %.10s...", buf );
lineno++;
if (c == 0) /* hopeless */ if (c == 0) /* hopeless */
FATAL( "giving up" ); FATAL( "giving up" );
lineno++;
break; break;
case '\\': case '\\':
c = input(); c = input();
@ -515,6 +518,7 @@ int regexpr(void)
if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, "regexpr")) if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, "regexpr"))
FATAL("out of space for reg expr %.10s...", buf); FATAL("out of space for reg expr %.10s...", buf);
if (c == '\n') { if (c == '\n') {
*bp = '\0';
SYNTAX( "newline in regular expression %.10s...", buf ); SYNTAX( "newline in regular expression %.10s...", buf );
unput('\n'); unput('\n');
break; break;
@ -553,19 +557,19 @@ int input(void) /* get next lexical input character */
lexprog++; lexprog++;
} else /* awk -f ... */ } else /* awk -f ... */
c = pgetc(); c = pgetc();
if (c == '\n') if (c == EOF)
lineno++;
else if (c == EOF)
c = 0; c = 0;
if (ep >= ebuf + sizeof ebuf) if (ep >= ebuf + sizeof ebuf)
ep = ebuf; ep = ebuf;
return *ep++ = c; *ep = c;
if (c != 0) {
ep++;
}
return (c);
} }
void unput(int c) /* put lexical character back on input */ void unput(int c) /* put lexical character back on input */
{ {
if (c == '\n')
lineno--;
if (yysptr >= yysbuf + sizeof(yysbuf)) if (yysptr >= yysbuf + sizeof(yysbuf))
FATAL("pushed back too much: %.20s...", yysbuf); FATAL("pushed back too much: %.20s...", yysbuf);
*yysptr++ = c; *yysptr++ = c;

View File

@ -34,8 +34,8 @@ CC = gcc -g -Wall -pedantic
# yacc options. pick one; this varies a lot by system. # yacc options. pick one; this varies a lot by system.
#YFLAGS = -d -S #YFLAGS = -d -S
#YACC = bison -d -y YACC = bison -d -y
YACC = yacc -d #YACC = yacc -d
# -S uses sprintf in yacc parser instead of sprint # -S uses sprintf in yacc parser instead of sprint
OFILES = b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o OFILES = b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o

View File

@ -135,6 +135,8 @@ int main(int argc, char *argv[])
n = sscanf(buf, "%1c %s %s %d", &c, def, name, &tok); n = sscanf(buf, "%1c %s %s %d", &c, def, name, &tok);
if (c != '#' || (n != 4 && strcmp(def,"define") != 0)) /* not a valid #define */ if (c != '#' || (n != 4 && strcmp(def,"define") != 0)) /* not a valid #define */
continue; continue;
if (strcmp(name, "YYSTYPE_IS_DECLARED") == 0)
continue;
if (tok < FIRSTTOKEN || tok > LASTTOKEN) { if (tok < FIRSTTOKEN || tok > LASTTOKEN) {
/* fprintf(stderr, "maketab funny token %d %s ignored\n", tok, buf); */ /* fprintf(stderr, "maketab funny token %d %s ignored\n", tok, buf); */
continue; continue;

3
run.c
View File

@ -863,6 +863,9 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
FATAL("'$' not permitted in awk formats"); FATAL("'$' not permitted in awk formats");
} }
if (*s == '*') { if (*s == '*') {
if (a == NULL) {
FATAL("not enough args in printf(%s)", os);
}
x = execute(a); x = execute(a);
a = a->nnext; a = a->nnext;
sprintf(t-1, "%d", fmtwd=(int) getfval(x)); sprintf(t-1, "%d", fmtwd=(int) getfval(x));

6
tran.c
View File

@ -395,7 +395,7 @@ Awkfloat getfval(Cell *vp) /* get float val of a Cell */
static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */ static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
{ {
char s[100]; /* BUG: unchecked */ char s[256];
double dtemp; double dtemp;
if ((vp->tval & (NUM | STR)) == 0) if ((vp->tval & (NUM | STR)) == 0)
@ -434,9 +434,9 @@ static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cel
if (freeable(vp)) \ if (freeable(vp)) \
xfree(vp->sval); \ xfree(vp->sval); \
if (modf(vp->fval, &dtemp) == 0) /* it's integral */ \ if (modf(vp->fval, &dtemp) == 0) /* it's integral */ \
sprintf(s, "%.30g", vp->fval); \ snprintf(s, sizeof (s), "%.30g", vp->fval); \
else \ else \
sprintf(s, *fmt, vp->fval); \ snprintf(s, sizeof (s), *fmt, vp->fval); \
vp->sval = tostring(s); \ vp->sval = tostring(s); \
vp->tval &= ~DONTFREE; \ vp->tval &= ~DONTFREE; \
vp->tval |= STR; \ vp->tval |= STR; \