bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 4/4] add support for --html


From: Akim Demaille
Subject: [PATCH 4/4] add support for --html
Date: Sat, 12 Sep 2020 17:38:24 +0200

* bootstrap.conf: We need the "execute" module.
* src/files.h, src/files.c (spec_html_file, html_flag): New.
* src/getargs.h, src/getargs.c (--html): New.
* src/print-xml.h, src/print-xml.c (print_html): New.
* src/main.c: Use them.
* tests/output.at, tests/report.at: Check --html.
---
 NEWS                 |  9 +++++++++
 bootstrap.conf       |  2 +-
 lib/.gitignore       |  2 ++
 lib/timevar.def      |  1 +
 m4/.gitignore        |  1 +
 src/files.c          |  9 +++++++++
 src/files.h          |  5 ++++-
 src/getargs.c        | 14 ++++++++++++++
 src/getargs.h        |  1 +
 src/main.c           | 10 +++++++++-
 src/print-xml.c      | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/print-xml.h      |  3 +++
 src/reader.c         |  1 +
 tests/diagnostics.at |  2 +-
 tests/local.mk       |  2 +-
 tests/output.at      |  7 +++++++
 tests/report.at      | 34 +++++++++++-----------------------
 17 files changed, 117 insertions(+), 28 deletions(-)

diff --git a/NEWS b/NEWS
index 6cd331f6..70d480f6 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,15 @@ GNU Bison NEWS
   %header supersedes %defines.  Both --defines and %defines are, of course,
   maintained for backward compatibility.
 
+*** Option --html
+
+  Since version 2.4 Bison can be used to generate HTML reports.  However it
+  was a two-step process: first bison must be invoked with option --xml, and
+  then xsltproc must be run to the convert the XML reports into HTML.
+
+  The new option --html combines these steps.  The xsltproc program must be
+  available.
+
 *** A C++ native GLR parser
 
   A new version of the generated C++ GLR parser was added as "glr2.cc". It
diff --git a/bootstrap.conf b/bootstrap.conf
index 577e30e5..6efae84b 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -22,7 +22,7 @@ gnulib_modules='
   calloc-posix close closeout config-h c-strcase
   configmake
   dirname
-  error extensions
+  error execute extensions
   fdl fopen-safer fstrcmp
   getopt-gnu
   gettext-h git-version-gen gitlog-to-changelog
diff --git a/lib/.gitignore b/lib/.gitignore
index 337cdb74..37e857dd 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -67,6 +67,8 @@
 /errno.in.h
 /error.c
 /error.h
+/execute.c
+/execute.h
 /exitfail.c
 /exitfail.h
 /fatal-signal.c
diff --git a/lib/timevar.def b/lib/timevar.def
index 6e0d6ff0..39eb8405 100644
--- a/lib/timevar.def
+++ b/lib/timevar.def
@@ -53,6 +53,7 @@ DEFTIMEVAR (tv_conflicts             , "conflicts")
 /* Time spent outputting results.  */
 DEFTIMEVAR (tv_report                , "outputting report")
 DEFTIMEVAR (tv_graph                 , "outputting graph")
+DEFTIMEVAR (tv_html                  , "outputting html")
 DEFTIMEVAR (tv_xml                   , "outputting xml")
 DEFTIMEVAR (tv_actions               , "parser action tables")
 DEFTIMEVAR (tv_parser                , "outputting parser")
diff --git a/m4/.gitignore b/m4/.gitignore
index 57bb666a..f8e06389 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -19,6 +19,7 @@
 /environ.m4
 /errno_h.m4
 /error.m4
+/execute.m4
 /exponentd.m4
 /exponentf.m4
 /exponentl.m4
diff --git a/src/files.c b/src/files.c
index 6675bb2c..1cf04c51 100644
--- a/src/files.c
+++ b/src/files.c
@@ -55,6 +55,7 @@ char const *spec_name_prefix = NULL;   /* for -p. */
 location spec_name_prefix_loc = EMPTY_LOCATION_INIT;
 char *spec_verbose_file = NULL;  /* for --verbose. */
 char *spec_graph_file = NULL;    /* for -g. */
+char *spec_html_file = NULL;     /* for --html. */
 char *spec_xml_file = NULL;      /* for -x. */
 char *spec_header_file = NULL;   /* for --header. */
 char *spec_mapped_header_file = NULL;
@@ -425,6 +426,13 @@ compute_output_file_names (void)
       output_file_name_check (&spec_graph_file, false);
     }
 
+  if (html_flag)
+    {
+      if (! spec_html_file)
+        spec_html_file = concat2 (all_but_tab_ext, ".html");
+      output_file_name_check (&spec_html_file, false);
+    }
+
   if (xml_flag)
     {
       if (! spec_xml_file)
@@ -526,6 +534,7 @@ output_file_names_free (void)
   free (all_but_ext);
   free (spec_verbose_file);
   free (spec_graph_file);
+  free (spec_html_file);
   free (spec_xml_file);
   free (spec_header_file);
   free (spec_mapped_header_file);
diff --git a/src/files.h b/src/files.h
index dafdbc95..5d3ee8fa 100644
--- a/src/files.h
+++ b/src/files.h
@@ -44,7 +44,10 @@ extern char *spec_verbose_file;
 /* File name specified for the output graph.  */
 extern char *spec_graph_file;
 
-/* File name specified for the xml output.  */
+/* File name specified for the HTML output.  */
+extern char *spec_html_file;
+
+/* File name specified for the XML output.  */
 extern char *spec_xml_file;
 
 /* File name specified with --header.  */
diff --git a/src/getargs.c b/src/getargs.c
index df2c6da1..dc7b7915 100644
--- a/src/getargs.c
+++ b/src/getargs.c
@@ -40,6 +40,7 @@
 
 bool header_flag = false;
 bool graph_flag = false;
+bool html_flag = false;
 bool xml_flag = false;
 bool no_lines_flag = false;
 bool token_table_flag = false;
@@ -432,6 +433,7 @@ Output Files:\n\
   -b, --file-prefix=PREFIX      specify a PREFIX for output files\n\
   -o, --output=FILE             leave output to FILE\n\
   -g, --graph[=FILE]            also output a graph of the automaton\n\
+      --html[=FILE]             also output an HTML report of the automaton\n\
   -x, --xml[=FILE]              also output an XML report of the automaton\n\
   -M, --file-prefix-map=OLD=NEW replace prefix OLD with NEW when writing file 
paths\n\
                                 in output files\n\
@@ -572,6 +574,7 @@ enum
 {
   COLOR_OPTION = CHAR_MAX + 1,
   FIXED_OUTPUT_FILES_OPTION,
+  HTML_OPTION,
   LOCATIONS_OPTION,
   PRINT_DATADIR_OPTION,
   PRINT_LOCALEDIR_OPTION,
@@ -616,6 +619,7 @@ static struct option const long_options[] =
   { "file-prefix",     required_argument,   0,   'b' },
   { "output",          required_argument,   0,   'o' },
   { "graph",           optional_argument,   0,   'g' },
+  { "html",            optional_argument,   0,   HTML_OPTION },
   { "xml",             optional_argument,   0,   'x' },
   { "file-prefix-map", required_argument,   0,   'M' },
 
@@ -839,6 +843,16 @@ getargs (int argc, char *argv[])
         /* Handled in getargs_colors. */
         break;
 
+      case HTML_OPTION:
+        html_flag = true;
+        xml_flag = true;
+        if (optarg)
+          {
+            free (spec_html_file);
+            spec_html_file = xstrdup (optarg);
+          }
+        break;
+
       case FIXED_OUTPUT_FILES_OPTION:
         complain (&loc, Wdeprecated,
                   _("deprecated option: %s, use %s"),
diff --git a/src/getargs.h b/src/getargs.h
index c8b2f659..9e78d074 100644
--- a/src/getargs.h
+++ b/src/getargs.h
@@ -36,6 +36,7 @@ extern char const *include;
 
 extern bool header_flag;                /* for -d/-H */
 extern bool graph_flag;                 /* for -g */
+extern bool html_flag;                  /* for --html */
 extern bool xml_flag;                   /* for -x */
 extern bool no_lines_flag;              /* for -l */
 extern bool token_table_flag;           /* for -k */
diff --git a/src/main.c b/src/main.c
index 70954d5b..946e32d7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -188,12 +188,20 @@ main (int argc, char *argv[])
         }
 
       /* Output xml.  */
-      if (xml_flag)
+      if (html_flag || xml_flag)
         {
           timevar_push (tv_xml);
           print_xml ();
           timevar_pop (tv_xml);
         }
+
+      /* Output html.  */
+      if (html_flag)
+        {
+          timevar_push (tv_html);
+          print_html ();
+          timevar_pop (tv_html);
+        }
     }
 
   /* Stop if there were errors, to avoid trashing previous output
diff --git a/src/print-xml.c b/src/print-xml.c
index c509089f..7b833bac 100644
--- a/src/print-xml.c
+++ b/src/print-xml.c
@@ -27,12 +27,16 @@
 #include <stdarg.h>
 
 #include "closure.h"
+#include "complain.h"
 #include "conflicts.h"
+#include "execute.h"
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
 #include "lalr.h"
 #include "lr0.h"
+#include "muscle-tab.h"
+#include "path-join.h"
 #include "print.h"
 #include "reader.h"
 #include "reduce.h"
@@ -531,3 +535,41 @@ print_xml (void)
 
   xfclose (out);
 }
+
+
+void
+print_html (void)
+{
+  assert (xml_flag);
+
+  char *xml2html = xpath_join (pkgdatadir (), "xslt/xml2xhtml.xsl");
+
+  char const *argv[11];
+  int i = 0;
+  argv[i++] = muscle_percent_define_get ("tool.xsltproc");
+  argv[i++] = "-o";
+  argv[i++] = spec_html_file;
+  argv[i++] = xml2html;
+  argv[i++] = spec_xml_file;
+  argv[i++] = NULL;
+  aver (i <= ARRAY_CARDINALITY (argv));
+
+  if (trace_flag & trace_tools)
+    {
+      fputs ("running:", stderr);
+      for (int j = 0; argv[j]; ++j)
+        fprintf (stderr, " %s", argv[j]);
+      fputc ('\n', stderr);
+    }
+
+  int status
+    = execute (argv[0],
+               argv[0], (char **)(void*)(argv),
+               /* ignore_sigpipe */ false,
+               /* null_stdin, null_stdout, null_stderr */ true, true, true,
+               /* slave_process */ true, /* exit_on_error */ false,
+               NULL);
+  if (status)
+    complain (NULL, complaint, _("%s failed with status %d"), argv[0], status);
+  free (xml2html);
+}
diff --git a/src/print-xml.h b/src/print-xml.h
index 51d3c15c..9c6be7e2 100644
--- a/src/print-xml.h
+++ b/src/print-xml.h
@@ -30,4 +30,7 @@ char const *xml_escape_n (int n, char const *str);
 char const *xml_escape (char const *str);
 void print_xml (void);
 
+/* Use xsltproc to generate HTML from XML output.  */
+void print_html (void);
+
 #endif /* !PRINT_XML_H_ */
diff --git a/src/reader.c b/src/reader.c
index 1526ab4e..0f9b7ee4 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -735,6 +735,7 @@ prepare_percent_define_front_end_variables (void)
       muscle_percent_define_default ("lr.default-reduction", "accepting");
     free (lr_type);
   }
+  muscle_percent_define_default ("tool.xsltproc", "xsltproc");
 
   /* Check %define front-end variables.  */
   {
diff --git a/tests/diagnostics.at b/tests/diagnostics.at
index 42b6d3a8..109eaa97 100644
--- a/tests/diagnostics.at
+++ b/tests/diagnostics.at
@@ -33,7 +33,7 @@ m4_if(m4_index([$1], [Counterexample]), [-1], [], 
[AT_KEYWORDS([cex])])
 # We need UTF-8 support for correct screen-width computation of UTF-8
 # characters.  Skip the test if not available.
 locale=`locale -a | $EGREP '^en_US\.(UTF-8|utf8)$' | sed 1q`
-AT_SKIP_IF([test x == x"$locale"])
+AT_SKIP_IF([[test x = x"$locale"]])
 
 m4_ifval([$6],
 [AT_SKIP_IF([$6])])
diff --git a/tests/local.mk b/tests/local.mk
index a14ba8fb..71e1f7a3 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -131,7 +131,7 @@ maintainer-check-posix: $(RUN_TESTSUITE_deps)
 VALGRIND_OPTS = --leak-check=full --show-reachable=yes --gen-suppressions=all \
   $(VALGRIND_OPTS_SUPPRESSION)
 maintainer-check-valgrind: $(RUN_TESTSUITE_deps)
-       test 'x$(VALGRIND)' == x ||                                     \
+       test 'x$(VALGRIND)' = x ||                                      \
          $(RUN_TESTSUITE)                                              \
            PREBISON='$(VALGRIND) -q' PREPARSER='$(VALGRIND) -q'        \
            VALGRIND_OPTS="$(VALGRIND_OPTS)"
diff --git a/tests/output.at b/tests/output.at
index a13aaf81..a69fbdff 100644
--- a/tests/output.at
+++ b/tests/output.at
@@ -36,6 +36,8 @@ m4_define([AT_CHECK_FILES],
 # -----------------------------------------------------------------
 m4_define([AT_CHECK_OUTPUT],
 [AT_SETUP([[Output files: ]$2 $3])[
+]m4_bmatch([$3], [--html],
+           [AT_SKIP_IF([[test x"$XSLTPROC" = x]])])[
 ]$7[
 for file in ]$1 $4[; do
   case $file in
@@ -90,6 +92,11 @@ AT_CHECK_OUTPUT([foo.y], [%define api.header.include 
{"./foo.h"}], [-dv -y],
 AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.tab.c],
                 [foo.output foo.tab.c foo.tab.h])
 
+AT_CHECK_OUTPUT([foo.y], [], [--fixed-output-files -dv -g --html],
+                [y.dot y.html y.output y.tab.c y.tab.h y.xml])
+AT_CHECK_OUTPUT([foo.y], [], [-Hfoo.header -v -gfoo.gv --html=foo.html],
+                [foo.gv foo.header foo.html foo.output foo.tab.c foo.xml])
+
 AT_CHECK_OUTPUT([foo.y], [], [-dv -g --xml --fixed-output-files],
                 [y.dot y.output y.tab.c y.tab.h y.xml])
 AT_CHECK_OUTPUT([foo.y], [], [-dv -g --xml -y],
diff --git a/tests/report.at b/tests/report.at
index 35493b93..a90c23ab 100644
--- a/tests/report.at
+++ b/tests/report.at
@@ -59,7 +59,8 @@ exp:
 | "number"      { std::swap ($$, $1); };
 ]])
 
-AT_BISON_CHECK([-o input.cc -v --graph=input.gv --xml input.yy])
+AT_SKIP_IF([[test x"$XSLTPROC" = x]])
+AT_BISON_CHECK([-o input.cc -v --graph=input.gv --html --xml input.yy])
 
 # Check the contents of the report.
 AT_CHECK([cat input.output], [],
@@ -304,7 +305,8 @@ State 19
 
 
 # Now generate verbose reports.
-AT_BISON_CHECK([-o input.cc -rall --graph=input.gv --xml input.yy])
+AT_SKIP_IF([[test x"$XSLTPROC" = x]])
+AT_BISON_CHECK([-o input.cc -rall --graph=input.gv --html --xml input.yy])
 
 # Check the contents of the report.
 AT_CHECK([cat input.output], [],
@@ -1138,14 +1140,7 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
 ]])
 
 # Check HTML output.
-if test x"$XSLTPROC" != x""; then
-  AT_CHECK([[$XSLTPROC \
-           `]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2xhtml.xsl \
-           input.xml | \
-           sed -e 's/GNU Bison [0-9][-.0-9a-z]*/GNU Bison VERSION/' \
-           >input.html]])
-
-  AT_CHECK([cat input.html], [],
+AT_CHECK([[sed -e 's/GNU Bison [0-9][-.0-9a-z]*/GNU Bison VERSION/g' 
input.html]], [],
 [[<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
 <html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:bison="http://www.gnu.org/software/bison/";>
@@ -1503,7 +1498,6 @@ if test x"$XSLTPROC" != x""; then
       permitted in any medium, provided this notice is preserved.</div></body>
 </html>
 ]])
-fi
 
 AT_BISON_OPTION_POPDEFS
 AT_CLEANUP
@@ -1520,7 +1514,9 @@ AT_KEYWORDS([cex report])
 # We need UTF-8 support for correct screen-width computation of UTF-8
 # characters.  Skip the test if not available.
 locale=`locale -a | $EGREP '^en_US\.(UTF-8|utf8)$' | sed 1q`
-AT_SKIP_IF([test x == x"$locale"])
+AT_SKIP_IF([[test x = x"$locale"]])
+
+AT_SKIP_IF([[test x"$XSLTPROC" = x]])
 
 AT_BISON_OPTION_PUSHDEFS
 AT_DATA([input.y],
@@ -1534,7 +1530,7 @@ exp
 | "Ñùṃéℝô"
 ]])
 
-AT_CHECK([LC_ALL="$locale" bison -fno-caret -o input.cc -rall -Wcex 
--graph=input.gv --xml input.y], [], [],
+AT_CHECK([LC_ALL="$locale" bison -fno-caret -o input.cc -rall -Wcex 
--graph=input.gv --html --xml input.y], [], [],
 [[input.y: warning: 3 shift/reduce conflicts [-Wconflicts-sr]
 input.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
 input.y: warning: shift/reduce conflict on token "⊕" [-Wcounterexamples]
@@ -2155,15 +2151,8 @@ AT_CHECK([[sed -e 's/bison-xml-report 
version="[^"]*"/bison-xml-report version="
 </bison-xml-report>
 ]])
 
-# Check HTML output.
-if test x"$XSLTPROC" != x""; then
-  AT_CHECK([[$XSLTPROC \
-           `]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2xhtml.xsl \
-           input.xml | \
-           sed -e 's/GNU Bison [0-9][-.0-9a-z]*/GNU Bison VERSION/' \
-           >input.html]])
-
-  AT_CHECK([cat input.html], [],
+
+AT_CHECK([[sed -e 's/GNU Bison [0-9][-.0-9a-z]*/GNU Bison VERSION/g' 
input.html]], [],
 [[<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
 <html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:bison="http://www.gnu.org/software/bison/";>
@@ -2391,7 +2380,6 @@ if test x"$XSLTPROC" != x""; then
       permitted in any medium, provided this notice is preserved.</div></body>
 </html>
 ]])
-fi
 
 AT_BISON_OPTION_POPDEFS
 AT_CLEANUP
-- 
2.28.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]