From 68e4d78cf9f153871d9a3c07c8ce3e43eb517c3b Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 14 Oct 2014 08:13:31 -0700 Subject: C++ upkeep. TXR's support for compiling as C++ pays off: C++ compiler finds serious bugs introduced in August 2 ("Big switch to reentrant lexing and parsing"). The yyerror function was being misused; some of the calls reversed the scanner and parser arguments. Since one of the two parameters is void *, this reversal wasn't caught. * parser.l (yyerror): Fix first two arguments being reversed. (num_esc): Change previously correct call to yyerror to follow reversed arguments, so that it stays correct. * parser.y (%parse-param): Change order of these directives so that the scnr parameter is before the parser parameter. This causes the yacc-generated calls to yyerror to have the arguments in the correct order. It also has the effect of changing the signature of yyparse, reversing its parameters. (parse): Update call to yyparse to new argument order. * parser.h (yyparse): Declaration removed. (yyerror): Declaration updated. * regex.c (regex_kind_t): New enum typedef. (struct regex): Use regex_kind_t rather than an enum inside the struct, which has different scoping rules under C++. * txr.c (get_self_path): Fix signed/unsigned warning. --- ChangeLog | 32 ++++++++++++++++++++++++++++++++ parser.h | 3 +-- parser.l | 6 +++--- parser.y | 4 ++-- regex.c | 4 +++- txr.c | 2 +- 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 498251e2..fb23e8e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2014-10-14 Kaz Kylheku + + C++ upkeep. + + TXR's support for compiling as C++ pays off: C++ compiler finds + serious bugs introduced in August 2 ("Big switch to reentrant lexing + and parsing"). The yyerror function was being misused; some of + the calls reversed the scanner and parser arguments. Since one + of the two parameters is void *, this reversal wasn't caught. + + * parser.l (yyerror): Fix first two arguments being + reversed. + (num_esc): Change previously correct call to yyerror to follow reversed + arguments, so that it stays correct. + + * parser.y (%parse-param): Change order of these directives + so that the scnr parameter is before the parser parameter. + This causes the yacc-generated calls to yyerror to have + the arguments in the correct order. It also has the + effect of changing the signature of yyparse, reversing its parameters. + (parse): Update call to yyparse to new argument order. + + * parser.h (yyparse): Declaration removed. + (yyerror): Declaration updated. + + * regex.c (regex_kind_t): New enum typedef. + (struct regex): Use regex_kind_t rather than an enum + inside the struct, which has different scoping rules + under C++. + + * txr.c (get_self_path): Fix signed/unsigned warning. + 2014-10-14 Kaz Kylheku * txr.1: Round of fixes. diff --git a/parser.h b/parser.h index 305b8d7b..bb85d01c 100644 --- a/parser.h +++ b/parser.h @@ -36,8 +36,7 @@ typedef struct { extern const wchar_t *spec_file; extern val form_to_ln_hash; -int yyparse(parser_t *, void *scanner); -void yyerror(parser_t *, void *scanner, const char *s); +void yyerror(void *scanner, parser_t *, const char *s); void yyerr(void *scanner, const char *s); void yyerrorf(void *scanner, val s, ...); void yybadtoken(parser_t *, int tok, val context); diff --git a/parser.l b/parser.l index 66ccb4bd..d59955b7 100644 --- a/parser.l +++ b/parser.l @@ -78,7 +78,7 @@ int yylex_destroy(void) int yyget_column(void *); void yyset_column (int column_no , yyscan_t yyscanner); -void yyerror(parser_t *parser, void *scanner, const char *s) +void yyerror(void *scanner, parser_t *parser, const char *s) { yyerrorf(scanner, lit("~a"), string_utf8(s), nao); if (parser->prepared_msg) { @@ -141,13 +141,13 @@ static wchar_t num_esc(void *scn, char *num) { if (num[0] == 'x') { if (strlen(num) > 7) - yyerror(yyget_extra(scn), scn, "too many digits in hex character escape"); + yyerror(scn, yyget_extra(scn), "too many digits in hex character escape"); return strtol(num + 1, 0, 16); } else { if (num[0] == 'o') num++; if (strlen(num) > 8) - yyerror(yyget_extra(scn), scn, "too many digits in octal character escape"); + yyerror(scn, yyget_extra(scn), "too many digits in octal character escape"); return strtol(num, 0, 8); } } diff --git a/parser.y b/parser.y index d9b4f241..00bb15cf 100644 --- a/parser.y +++ b/parser.y @@ -72,8 +72,8 @@ int yylex(union YYSTYPE *, void *scanner); %} %pure-parser -%parse-param{parser_t *parser} %parse-param{void *scnr} +%parse-param{parser_t *parser} %lex-param{void *scnr} %union { @@ -1365,7 +1365,7 @@ int parse(val stream, val name, parser_t *parser) yyset_extra(parser, parser->scanner); - res = yyparse(parser, parser->scanner); + res = yyparse(parser->scanner, parser); yylex_destroy(parser->scanner); diff --git a/regex.c b/regex.c index e4dfee4d..87fad93e 100644 --- a/regex.c +++ b/regex.c @@ -56,8 +56,10 @@ typedef struct nfa { nfa_state_t *accept; } nfa_t; +typedef enum { REGEX_NFA, REGEX_DV } regex_kind_t; + typedef struct regex { - enum { REGEX_NFA, REGEX_DV } kind; + regex_kind_t kind; union { struct nfa nfa; val dv; diff --git a/txr.c b/txr.c index b9c11e5f..fe2ce3da 100644 --- a/txr.c +++ b/txr.c @@ -180,7 +180,7 @@ static val get_self_path(void) char self[PATH_MAX] = { 0 }; int nchar = readlink("/proc/self/exe", self, sizeof self); - if (nchar < 0 || nchar >= sizeof self) + if (nchar < 0 || nchar >= (int) sizeof self) return nil; return string_utf8(self); } -- cgit v1.2.3