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

Akim Demaille <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches
Message-ID <[email protected]>
* 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.