c++: support absolute api.location.file names

In the case a user wants to create location.hh elsewhere, it can be
helpful to define api.location.file to some possibly absolute path
such as -Dapi.location.file='"$(top_srcdir)/include/ast/location.hh"'.
Currently this does not work with `-o foo/parser.cc`, as we join foo/
and $(top_srcdir) together, the latter starting with slash.

We should not try to do that in m4, manipulating file names is quite
complex when you through Windows file name in.  Let m4 delegate this
to gnulib.

* src/scan-skel.l (at_output): Accept up to two arguments.
* data/bison.m4 (b4_output): Adjust.
* tests/skeletons.at (Fatal errors but M4 continues producing output):
Adjust to keep the error.

* data/location.cc, data/stack.hh: Leave the concatenation to @output.
* tests/output.at: Exercise api.location.file with an absolute path.
This commit is contained in:
Akim Demaille
2018-10-06 13:03:59 +02:00
parent 57d69b04b2
commit 50b8d4ba5a
6 changed files with 22 additions and 13 deletions

View File

@@ -65,14 +65,16 @@ version 2.2 of Bison.])])
## Output. ## ## Output. ##
## -------- ## ## -------- ##
# b4_output_begin(FILE) # b4_output_begin(FILE1, FILE2)
# --------------------- # -----------------------------
# Enable output, i.e., send to diversion 0, expand after "#", and # Enable output, i.e., send to diversion 0, expand after "#", and
# generate the tag to output into FILE. Must be followed by EOL. # generate the tag to output into FILE. Must be followed by EOL.
# FILE is FILE1 concatenated to FILE2. FILE2 can be empty, or be
# absolute: do the right thing.
m4_define([b4_output_begin], m4_define([b4_output_begin],
[m4_changecom() [m4_changecom()
m4_divert_push(0)dnl m4_divert_push(0)dnl
@output(m4_unquote([$1])@)@dnl @output(m4_unquote([$1])@,m4_unquote([$2])@)@dnl
]) ])

View File

@@ -305,7 +305,7 @@ m4_define([b4_location_define],
m4_ifdef([b4_position_file], [[ m4_ifdef([b4_position_file], [[
]b4_output_begin([b4_dir_prefix[]b4_position_file])[ ]b4_output_begin([b4_dir_prefix], [b4_position_file])[
// Starting with Bison 3.2, this file is useless: the structure it // Starting with Bison 3.2, this file is useless: the structure it
// used to define is now defined in "]b4_location_file[". // used to define is now defined in "]b4_location_file[".
// //
@@ -323,7 +323,7 @@ m4_ifdef([b4_position_file], [[
m4_ifdef([b4_location_file], [[ m4_ifdef([b4_location_file], [[
]b4_output_begin([b4_dir_prefix[]b4_location_file])[ ]b4_output_begin([b4_dir_prefix], [b4_location_file])[
]b4_copyright([Locations for Bison parsers in C++])[ ]b4_copyright([Locations for Bison parsers in C++])[
/** /**

View File

@@ -140,7 +140,7 @@ m4_define([b4_stack_define],
m4_ifdef([b4_stack_file], m4_ifdef([b4_stack_file],
[b4_output_begin([b4_dir_prefix[]b4_stack_file])[ [b4_output_begin([b4_dir_prefix], [b4_stack_file])[
// Starting with Bison 3.2, this file is useless: the structure it // Starting with Bison 3.2, this file is useless: the structure it
// used to define is now defined with the parser itself. // used to define is now defined with the parser itself.
// //

View File

@@ -29,8 +29,9 @@
#define FLEX_PREFIX(Id) skel_ ## Id #define FLEX_PREFIX(Id) skel_ ## Id
#include <src/flex-scanner.h> #include <src/flex-scanner.h>
#include <dirname.h>
#include <error.h> #include <error.h>
#include <dirname.h>
#include <path-join.h>
#include <quotearg.h> #include <quotearg.h>
#include <src/complain.h> #include <src/complain.h>
@@ -236,14 +237,14 @@ at_complain (int argc, char *argv[], char **out_namep, int *out_linenop)
static void static void
at_output (int argc, char *argv[], char **out_namep, int *out_linenop) at_output (int argc, char *argv[], char **out_namep, int *out_linenop)
{ {
if (2 < argc) if (3 < argc)
fail_for_at_directive_too_many_args (argv[0]); fail_for_at_directive_too_many_args (argv[0]);
if (*out_namep) if (*out_namep)
{ {
free (*out_namep); free (*out_namep);
xfclose (yyout); xfclose (yyout);
} }
*out_namep = xstrdup (argv[1]); *out_namep = xpath_join (argv[1], 2 < argc ? argv[2] : NULL);
output_file_name_check (out_namep, true); output_file_name_check (out_namep, true);
/* If there were errors, do not generate the output. */ /* If there were errors, do not generate the output. */
yyout = xfopen (complaint_status ? "/dev/null" : *out_namep, "w"); yyout = xfopen (complaint_status ? "/dev/null" : *out_namep, "w");

View File

@@ -45,9 +45,13 @@ done
[$2[ [$2[
%% %%
foo: %empty {}; foo: %empty {};
]])[ ]])
]AT_BISON_CHECK([$3 $1], [$5], [], [ignore])[ # There is not AT_DATA_UNQUOTED.
AT_CHECK([$PERL -pi -e 's{\$at_dir}'"{$at_group_dir}g" $1])
AT_BISON_CHECK([$3 $1], [$5], [], [ignore])[
# Ignore the files non-generated files # Ignore the files non-generated files
]AT_CHECK_FILES([$4], [$1])[ ]AT_CHECK_FILES([$4], [$1])[
]$6[ ]$6[
@@ -206,8 +210,10 @@ AT_CHECK_OUTPUT([foo.yy],
[%skeleton "lalr1.cc" %defines %locations %define api.location.file "foo.loc.hh"], [%skeleton "lalr1.cc" %defines %locations %define api.location.file "foo.loc.hh"],
[], [],
[foo.loc.hh foo.tab.cc foo.tab.hh]) [foo.loc.hh foo.tab.cc foo.tab.hh])
# Absolute paths.
AT_CHECK_OUTPUT([foo.yy], AT_CHECK_OUTPUT([foo.yy],
[%skeleton "lalr1.cc" %defines %define api.stack.file none %locations %define api.location.file "foo.loc.hh"], [%skeleton "lalr1.cc" %defines %locations %define api.location.file "$at_dir/foo.loc.hh"],
[], [],
[foo.loc.hh foo.tab.cc foo.tab.hh]) [foo.loc.hh foo.tab.cc foo.tab.hh])

View File

@@ -306,7 +306,7 @@ use strict;
my $M4 = "m4"; my $M4 = "m4";
my $DNL = "d"."nl"; my $DNL = "d"."nl";
print "${M4}_divert_push(0)$DNL\n"; print "${M4}_divert_push(0)$DNL\n";
print '@output(@,@)', "\n"; print '@output(@,@,@)', "\n";
(print "garbage"x10, "\n") for (1..1000); (print "garbage"x10, "\n") for (1..1000);
print "${M4}_divert_pop(0)\n"; print "${M4}_divert_pop(0)\n";
]]) ]])