Support for 'custom' parse.error value was added in bison-3.6. Fall back
to previous value for earlier versions.
This is harder to get right than it seems: On one hand, preprocessor
macros can't be used in parser_bison.y's declaration section and
automake forbids conditional changes to AM_YFLAGS on the other.
Another aspect complicating things is compiling with (an up to date)
parser_bison.c in place vs. without: Dist tarballs generally have it in
place, relieving users from having to provide a YACC when compiling. The
existing parser_bison.c either uses parse.error=custom or not which does
not (should not) change when compiling. Hiding yyreport_syntax_error()
behind a CPPFLAG which may be set or not depending on bison presence and
version then causes trouble if it doesn't match how parser_bison.c was
created.
Avoid these pitfalls by:
- Not relying upon a preprocessor define to control parser_bison.c
compilation, instead check existence of the bison-internal
YY_LAC_ESTABLISH macro
- Exporting the above macro existence check in a variable for use by
main.c (thereby crossing the libnftables library boundary)
Also:
- Introduce have_prebuilt_bison variable in configure.ac, unifying the
parser_bison.c existence check and solidify the latter by also
comparing its timestamp
- Report extended parser errors enableval in configure only if
parser_bison.c will be recreated, otherwise we can't quite tell if it
will turn out to be enabled or not
Suggested-by: Jan Kończak <jan.konczak@cs.put.poznan.pl>
Fixes: 67b822f2b2624 ("parser_bison: on syntax errors, output expected tokens")
Signed-off-by: Phil Sutter <phil@nwl.cc>
$(NULL)
AM_YFLAGS = -d -Wno-yacc
$(NULL)
AM_YFLAGS = -d -Wno-yacc
+if BISON_CUSTOM_ERROR
+YACC += -D parse.error=custom -D parse.lac=full
+else
+YACC += -D parse.error=verbose
+endif
if BUILD_PROFILING
AM_CFLAGS += --coverage
if BUILD_PROFILING
AM_CFLAGS += --coverage
AC_PROG_LEX([noyywrap])
AC_PROG_YACC
AC_PROG_LEX([noyywrap])
AC_PROG_YACC
-if test -z "$ac_cv_prog_YACC" -a ! -f "${srcdir}/src/parser_bison.c"
+p_bison_pfx="${srcdir}/src/parser_bison"
+if test -f "${p_bison_pfx}.c" -a "${p_bison_pfx}.c" -nt "${p_bison_pfx}.y"
+then
+ have_prebuilt_bison="yes"
+elif test -z "$ac_cv_prog_YACC"
then
echo "*** Error: No suitable bison/yacc found. ***"
echo " Please install the 'bison' package."
then
echo "*** Error: No suitable bison/yacc found. ***"
echo " Please install the 'bison' package."
+AC_ARG_ENABLE([extended_parser_errors],
+ AS_HELP_STRING([--disable-extended-parser-errors],
+ [Disable use of parse.error=custom and LAC in Bison]),
+ [], [
+ enable_extended_parser_errors=no
+ AC_SUBST([BISON], [$ac_cv_prog_YACC])
+ AX_PROG_BISON_VERSION([3.6],
+ [enable_extended_parser_errors=yes])
+ ])
+AM_CONDITIONAL([BISON_CUSTOM_ERROR],
+ [test "x$enable_extended_parser_errors" != xno])
+
AM_PROG_AR
LT_INIT([disable-static])
AC_EXEEXT
AM_PROG_AR
LT_INIT([disable-static])
AC_EXEEXT
json output support: ${with_json}
collect profiling data: ${enable_profiling}"
json output support: ${with_json}
collect profiling data: ${enable_profiling}"
+if test "x$have_prebuilt_bison" != "xyes"; then
+echo " extended parser errors: ${enable_extended_parser_errors}"
+fi
+
if test "x$unitdir" != "x"; then
AC_SUBST([unitdir])
echo " systemd unit: ${unitdir}"
if test "x$unitdir" != "x"; then
AC_SUBST([unitdir])
echo " systemd unit: ${unitdir}"
int nft_run_cmd_from_buffer(struct nft_ctx *nft, const char *buf);
int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename);
int nft_run_cmd_from_buffer(struct nft_ctx *nft, const char *buf);
int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename);
+extern bool nft_bison_have_extended_errors;
+
#ifdef __cplusplus
} /* extern "C" */
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
nft_ctx_input_get_flags;
nft_ctx_input_set_flags;
} LIBNFTABLES_3;
nft_ctx_input_get_flags;
nft_ctx_input_set_flags;
} LIBNFTABLES_3;
+
+LIBNFTABLES_5 {
+ nft_bison_have_extended_errors;
+} LIBNFTABLES_4;
static void show_version(void)
{
static void show_version(void)
{
- const char *cli, *minigmp, *json, *xt;
+ const char *cli, *minigmp, *json, *xt, *ext_bsn_err;
#if defined(HAVE_LIBREADLINE)
cli = "readline";
#if defined(HAVE_LIBREADLINE)
cli = "readline";
+ ext_bsn_err = nft_bison_have_extended_errors ? "yes" : "no";
- " cli: %s\n"
- " json: %s\n"
- " minigmp: %s\n"
- " libxtables: %s\n",
+ " cli: %s\n"
+ " json: %s\n"
+ " minigmp: %s\n"
+ " libxtables: %s\n"
+ " extended parser errors: %s\n",
PACKAGE_NAME, PACKAGE_VERSION, RELEASE_NAME,
PACKAGE_NAME, PACKAGE_VERSION, RELEASE_NAME,
- cli, json, minigmp, xt);
+ cli, json, minigmp, xt, ext_bsn_err);
%parse-param { void *scanner }
%parse-param { struct parser_state *state }
%lex-param { scanner }
%parse-param { void *scanner }
%parse-param { struct parser_state *state }
%lex-param { scanner }
-%define parse.error custom
-%define parse.lac full
%locations
%initial-action {
%locations
%initial-action {
static int
yyreport_syntax_error(const yypcontext_t *yyctx, struct nft_ctx *nft,
void *scanner, struct parser_state *state)
static int
yyreport_syntax_error(const yypcontext_t *yyctx, struct nft_ctx *nft,
void *scanner, struct parser_state *state)
+
+bool nft_bison_have_extended_errors = true;
+#else /* ! YY_LAC_ESTABLISH */
+bool nft_bison_have_extended_errors = false;
+#endif /* YY_LAC_ESTABLISH */
+EXPORT_SYMBOL(nft_bison_have_extended_errors);