summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-10-14 08:13:31 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-10-14 08:13:31 -0700
commit68e4d78cf9f153871d9a3c07c8ce3e43eb517c3b (patch)
tree69b3947cb8bd09b49cb3015af70fc9034efadd6d
parent851ffd5c85901f1609742c162e2f992099e4b848 (diff)
downloadtxr-68e4d78cf9f153871d9a3c07c8ce3e43eb517c3b.tar.gz
txr-68e4d78cf9f153871d9a3c07c8ce3e43eb517c3b.tar.bz2
txr-68e4d78cf9f153871d9a3c07c8ce3e43eb517c3b.zip
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.
-rw-r--r--ChangeLog32
-rw-r--r--parser.h3
-rw-r--r--parser.l6
-rw-r--r--parser.y4
-rw-r--r--regex.c4
-rw-r--r--txr.c2
6 files changed, 42 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 498251e2..fb23e8e8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,37 @@
2014-10-14 Kaz Kylheku <kaz@kylheku.com>
+ 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 <kaz@kylheku.com>
+
* txr.1: Round of fixes.
2014-10-13 Kaz Kylheku <kaz@kylheku.com>
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);
}