bison-patches
[Top][All Lists]
Advanced

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

[PATCH] Adopt new naming rules if `--output' is given.


From: Paolo Bonzini
Subject: [PATCH] Adopt new naming rules if `--output' is given.
Date: Sun, 2 Nov 2008 13:41:24 +0100

This is the big one.  It is a big overhaul of the logic in files.c,
minimizing the places where we care about .tab/_tab and making (I
think) the logic clearer.  It may be a little worse when %language
is chosen, but it is much better a) when it isn't, b) for C++, when
the preferred language extensions are not .cc/.hh

The documentation is adjusted.  The advantage here is that we can
explain simple naming rules for the case of -o SOMETHING-WITHOUT-TAB.c.

* NEWS: Deprecate simultaneous use of `--file-prefix' and `--output'.
* data/bison.m4 (b4_compute_parser_file_name): Do not use spec_outfile.
(b4_compute_defines_file_name): Delete.
(_b4_compute_defines_file_name_and_ext,
b4_compute_defines_file_name_and_ext): New.
* data/c.m4 (b4_compute_defines_file_name): New.
* data/c++.m4 (b4_compute_defines_file_name): New.
* doc/bison.texinfo (Output Files): Mostly rewrite.
(Directives, Options): Specify conflict between -b and -o.
* src/files.c (all_but_ext): Remove.
(all_but_tab_ext): Change to file_prefix.
(DOTTABLEN): New.
(file_name_split): Use it instead of dottablen.  Change TAB argument
to the return value.  Make BASE optional.
(compute_file_name_parts_new): Rename to compute_file_name_parts,
refactor, do not consider Yacc naming rules here.
(compute_exts_from_src): Remove, logic now in m4 files.
(compute_exts_from_gf, compute_file_name_parts_old): Refactor into...
(compute_output_file_names_old): ... this.
(compute_output_file_names): Warn for conflicting options, set up
parser_file_name and defines_file_name before computing the dir_prefix
and file_prefix.  Compute the parser_file_name and defines_file_name
according to the old rules if requested, but do not trigger the old
rules if an output file name was given.  Replace all_but_tab_ext
with file_prefix.
(output_file_names_free): Adjust.
* src/files.h (dir_prefix, file_prefix): Group together.
(all_but_ext): Remove.
* src/output.c (spec_file_prefix, file_name_all_but_ext): Remove.
(file_prefix): Add.
* tests/output.at (AT_CHECK_OUTPUT): Ignore warnings.  Change the
output file names for output files named .C or .cpp.
---
 NEWS              |    9 ++-
 data/bison.m4     |   35 +++++---
 data/c++.m4       |    7 ++
 data/c.m4         |    7 ++
 doc/bison.texinfo |  173 +++++++++++++++++++---------------------
 src/files.c       |  228 ++++++++++++++++++++++------------------------------
 src/files.h       |    8 +-
 src/output.c      |    4 +-
 tests/output.at   |   37 +++++----
 9 files changed, 248 insertions(+), 260 deletions(-)

diff --git a/NEWS b/NEWS
index 9e42e0a..985d34b 100644
--- a/NEWS
+++ b/NEWS
@@ -9,9 +9,16 @@ Changes in version ?.? (????-??-??):
   activates a set of simplified naming rules that is more appropriate as Bison
   evolves to handle new output languages.  This new behavior is an additional
   reason that we recommend using %language instead of %skeleton to select
-  official Bison skeletons.  See the new section `Output Files' in the Bison
+  official Bison skeletons, especially if your makefile does not employ the
+  `-o'/`--output' option.  See the new section `Output Files' in the Bison
   manual for details.
 
+* Deprecated simultaneous use of `--file-prefix' and `--output'
+
+  The simultaneous use of `--file-prefix' and `--output' has been deprecated
+  because the file names it produces are often unintuitive.  The warning
+  may be changed into an error in future releases of Bison.
+
 Changes in version 2.3b (2008-05-27):
 
 * The quotes around NAME that used to be required in the following directive
diff --git a/data/bison.m4 b/data/bison.m4
index f5ec6af..c3ec51e 100644
--- a/data/bison.m4
+++ b/data/bison.m4
@@ -261,20 +261,29 @@ b4_define_flag_if([yacc])         # Whether POSIX Yacc is 
emulated.
 #
 #   b4_compute_parser_file_name([[.c]])
 m4_define([b4_compute_parser_file_name],
-[m4_ifval(b4_spec_outfile, [b4_spec_outfile],
-          [m4_ifval(b4_parser_file_name, [b4_parser_file_name],
-                    [b4_file_name_all_but_ext[]$1])])])
-
-# b4_compute_defines_file_name(DEFAULT_EXT)
-# -----------------------------------------
-# Compute the parser header file name using the default extension DEFAULT_EXT.
-# For example:
-#
-#   b4_compute_defines_file_name([[.h]])
-m4_define([b4_compute_defines_file_name],
-[m4_ifval(b4_spec_defines_file, [b4_spec_defines_file],
-          [m4_ifval(b4_defines_file_name, [b4_defines_file_name],
-                    [b4_file_name_all_but_ext[]$1])])])
+[m4_ifval(b4_parser_file_name, [b4_parser_file_name],
+          [b4_file_prefix[]$1])])
+
+# _b4_compute_defines_file_name_and_ext(FILE, EXT, DEFAULT-EXT,
+#                                       TRANSLIT-FROM, TRANSLIT-TO)
+# ---------------------------------------------------------------------------
+# Helper macro for b4_compute_defines_file_name.
+m4_define([_b4_compute_defines_file_name_and_ext],
+[$1[]m4_translit([$2], [$3], [$4])])
+
+# b4_compute_defines_file_name_and_ext(DEFAULT-PARSER-EXT, DEFAULT-DEFINES-EXT,
+#                                      TRANSLIT-FROM, TRANSLIT-TO)
+# ----------------------------------------------------------------------------
+# Compute the parser header file name from the parser file name, by applying
+# the transliteration given by the other two arguments.   For example:
+#
+#   b4_compute_defines_file_name([[.c]], [[.h]], [[cC]], [[hH]])
+m4_define([b4_compute_defines_file_name_and_ext],
+[m4_ifval(b4_defines_file_name, [b4_defines_file_name],
+         [m4_if(m4_index(b4_compute_parser_file_name([$1]), .), -1,
+                [b4_compute_parser_file_name([$1])$2],
+                [_$0(m4_bpatsubst(m4_quote(b4_compute_parser_file_name([$1])),
+                     [^\(.*\)\(\..*\)], [[\1], [\2]]), [$3], [$4])])])])
 
 
 
diff --git a/data/c++.m4 b/data/c++.m4
index 593390d..fb852d8 100644
--- a/data/c++.m4
+++ b/data/c++.m4
@@ -35,6 +35,13 @@ b4_percent_define_default([[define_location_comparison]],
                                  [std::string], [[true]], [[false]])])
 
 
+## ------------ ##
+## Extensions.  ##
+## ------------ ##
+
+m4_define([b4_compute_defines_file_name],
+[b4_compute_defines_file_name_and_ext([[.cc]], [$1], [[cC]], [[hH]])])
+
 ## ----------- ##
 ## Namespace.  ##
 ## ----------- ##
diff --git a/data/c.m4 b/data/c.m4
index 1fe4bc5..2508ce5 100644
--- a/data/c.m4
+++ b/data/c.m4
@@ -66,6 +66,13 @@ m4_define_default([b4_union_name], [YYSTYPE])
 # If the %name-prefix is not given, it is yy.
 m4_define_default([b4_prefix], [yy])
 
+## ------------ ##
+## Extensions.  ##
+## ------------ ##
+
+m4_define([b4_compute_defines_file_name],
+[b4_compute_defines_file_name_and_ext([[.c]], [$1], [[cC]], [[hH]])])
+
 ## ------------------------ ##
 ## Pure/impure interfaces.  ##
 ## ------------------------ ##
diff --git a/doc/bison.texinfo b/doc/bison.texinfo
index e084591..52e487e 100644
--- a/doc/bison.texinfo
+++ b/doc/bison.texinfo
@@ -5050,6 +5050,10 @@ discarded symbols.  @xref{Destructor Decl, , Freeing 
Discarded Symbols}.
 Specify a prefix to use for all Bison output file names.  The names are
 chosen as if the input file were named @address@hidden
 @xref{Output Files}, for further details.
+
+Specifying @code{%file-prefix} together with @code{%output} or
address@hidden is deprecated, and will cause this directive to
+be ignored.
 @end deffn
 
 @deffn {Directive} %language "@var{language}"
@@ -7732,11 +7736,24 @@ For example, the following directive declares the 
output language as C:
 @noindent Declaring the output language currently has two effects.
 First, Bison automatically selects the appropriate code skeleton for the
 combination of the specified language and other parser options, such as GLR.
-Second, it activates simplified rules for computing the output file names, many
-of which are based on the output language.
-For each file name or file name part in these simplified rules, the following
-table shows the default value that Bison computes as well as any command-line
-options or grammar directives that can override the default:
+
+Second, it activates simplified rules for computing the output file
+names, many of which are based on the output language.  We dislike the
+old rules because they increase complexity, thus they are less intuitive,
+their tab concept is archaic, and they do not extend nicely to languages
+besides C and C++.
+
+However, the new rules are designed to match the old ones in at least
+one common case.  Many legacy parsers do not use @code{%language},
+but instead use the @option{-o} option to specify an output file name.
+This method is also okay; we suggest to pick an output file name that
+does not include the special suffixes @file{_tab} or @file{.tab}, since
+that is also equivalent to the simplified rules.
+
+For each file name or file name part, the following table shows the
+default value that Bison computes as well as any command-line options
+or grammar directives that can override the default.  You can safely
+ignore in most cases the backwards-compatibility rules in the table.
 
 @enumerate
 @item File Prefix
@@ -7757,12 +7774,26 @@ extension.
 @item       @code{foo/bar/baz.y}   @tab @code{baz}
 @end multitable
 
address@hidden Yacc Default: If the output language is C and you request Yacc
-compatibility (by @code{-y}, @code{--yacc}, or @code{%yacc}), then the default
-is instead simply @code{y}.
address@hidden The file prefix is set according to different command-line 
options
+and directives.
 
address@hidden Options: @code{-b @var{PREFIX}}, @address@hidden
address@hidden Directives: @code{%file-prefix "@var{PREFIX}"}
+Options @code{-b @var{PREFIX}} and @address@hidden, and
+grammar directive @code{%file-prefix "@var{PREFIX}"} set the file prefix
+directly.
+
+Options @code{-o @var{OUTPUT-FILE}} and @address@hidden,
+and grammar directive @code{%output "@var{OUTPUT-FILE}"} set the file
+prefix to @var{OUTPUT-FILE} minus the extension.  So, for example,
+if the output language is C the two options @samp{-ofoo.c} and
address@hidden are equivalent.
+
address@hidden Backwards compatiblity rules: If the output language is C and you
+request Yacc compatibility (by @code{-y}, @code{--yacc}, or @code{%yacc}),
+then the default is instead simply @code{y}.
+
+If @var{OUTPUT-FILE} ends with @address@hidden or
address@hidden@var{EXT}}, the @file{.tab} or @file{_tab} part is also
+stripped from the file prefix.
 @end itemize
 
 @item Parser Source Code File
@@ -7778,12 +7809,26 @@ is instead simply @code{y}.
 @item       Java     @tab @code{foo}    @tab @code{foo.java}
 @end multitable
 
address@hidden Yacc Default: If the output language is C and you request Yacc
-compatibility (by @code{-y}, @code{--yacc}, or @code{%yacc}), then the default
-is instead the file prefix plus @code{.tab.c}.
address@hidden The parser source code file can be overridden with options
address@hidden @var{FILE}}, @address@hidden or directive
address@hidden "@var{FILE}"}.
+
address@hidden Backwards compatibility rules: If neither the language nor the
+output file are set in the grammar or command line, the extension is
+constructed according to different rules.  Unless in Yacc compatibility
+mode, @code{y} is replaced with @code{c} and @code{Y} with @code{C}
+in the grammar file address@hidden rules may lead to
+  unexpected file names in some cases even for C and C++.  For example,
+  if you name your grammar file @code{parser.yacc}, these rules choose the
+  default names @code{parser.tab.hacc} and @code{parser.tab.cacc}, but the
+  new rules choose the default names @code{parser.h} and @code{parser.c}
+  for C and @code{parser.hh} and @code{parser.cc} for C++.}.
+However, if there is no grammar file extension or you request Yacc
+compatibility, then the default extension is just @code{.c}.
 
address@hidden Options: @code{-o @var{FILE}}, @address@hidden
address@hidden Directives: @code{%output "@var{FILE}"}
+Furthermore, @code{.tab}, or @code{_tab} if the former is not allowed
+by the file system, if added to the parser source code file before
+the extension.
 @end itemize
 
 @item Parser Header File
@@ -7791,21 +7836,27 @@ is instead the file prefix plus @code{.tab.c}.
 @itemize
 @item Purpose: Main parser declarations, if supported by the specified language
 and if you request it (by @code{-d}, @code{--defines}, or @code{%defines}).
address@hidden Default: File prefix plus a language-specific extension.
-
address@hidden {Language}    {File Prefix}      {not supported}
address@hidden   Language @tab File Prefix   @tab Default
address@hidden       C        @tab @code{foo}    @tab @code{foo.h}
address@hidden       C++      @tab @code{foo}    @tab @code{foo.hh}
address@hidden       Java     @tab @code{foo}    @tab not supported
address@hidden Default: Parser source code file, with the extension replaced
+according to language-specific rules.
+
address@hidden {Language}    {Output File}   {not supported}
address@hidden   Language @tab Output File     @tab Default
address@hidden       C        @tab @code{foo.c}    @tab @code{foo.h}
address@hidden       C        @tab @code{foo}      @tab @code{foo.h}
address@hidden       C++      @tab @code{foo.C}    @tab @address@hidden@file{C} 
and @file{c} are replaced respectively by @file{H} and @file{h}.}
address@hidden       C++      @tab @code{foo.cc}   @tab @code{foo.hh}
address@hidden       C++      @tab @code{foo.cpp}  @tab @code{foo.hpp}
address@hidden       C++      @tab @code{foo}      @tab @code{foo.hh}
address@hidden       Java     @tab @code{foo}      @tab not supported
 @end multitable
 
address@hidden Yacc Default: If the output language is C and you request Yacc
-compatibility (by @code{-y}, @code{--yacc}, or @code{%yacc}), then the default
-is instead the file prefix plus @code{.tab.h}.
-
 @item Options: @address@hidden
 @item Directives: @code{%defines "@var{FILE}"}
+
address@hidden Backwards compatibility rules: If neither the language nor the
+output file are set in the grammar or command line, the extension added
+to the file prefix is @code{.tab.h}, or @code{_tab} if the former is
+not allowed by the file system.
 @end itemize
 
 @item Auxiliary Code Files
@@ -7829,71 +7880,6 @@ The names of these files do not depend on the selected 
output language, so we
 discuss them further in the following sections.
 @end enumerate
 
-When the output language is not declared with @code{-L}, @code{--language}, or
address@hidden, the rules for computing the output file names become more
-complicated.
-This behavior is for backward compatibility.
-The differences are as follows:
-
address@hidden
address@hidden File prefix from parser source code file.
-
-If you explicitly specify a parser source code file name, then Bison (1)
-extracts the file prefix from it instead of from the grammar file name and (2)
-ignores any file prefix that you explicitly specify.
-
address@hidden Tab.
-
-If the file prefix is extracted from the parser source code file name, then
-Bison removes any trailing @code{_tab} or @code{.tab} from the resulting file
-prefix while computing the automaton file names.
-If not, Bison appends a @code{.tab} to the file prefix while computing the
-parser source code and header file names.
-This is problematic for languages like Java.
-
address@hidden Parser source code file extension from grammar file extension.
-
-The default parser source code file extension is constructed by replacing
address@hidden with @code{c} and @code{Y} with @code{C} in the grammar file
-extension.
-However, if there is no grammar file extension or you request Yacc
-compatibility, then the default extension is just @code{.c}.
-
address@hidden Parser header file extension from source code file extension.
-
-The default parser header file extension is constructed by replacing @code{c}
-with @code{h} and @code{C} with @code{H} in the parser source code file
-extension.
address@hidden enumerate
-
-We dislike the old rules because they increase complexity, thus they are less
-intuitive, their tab concept is archaic, and they do not extend nicely to
-languages besides C and C++.
-Moreover, they lead to unexpected file names in some cases even for C and C++.
-For example, if you name your grammar file @code{parser.yacc}, the old rules
-choose the default names @code{parser.tab.hacc} and @code{parser.tab.cacc}, but
-the new rules choose the default names @code{parser.h} and @code{parser.c} for
-C and @code{parser.hh} and @code{parser.cc} for C++.
-If you name your grammar file @code{parser.bison}, the old rules name both
-files @code{parser.tab.bison} by default, but the new rules again choose
address@hidden and @code{parser.c} for C and @code{parser.hh} and
address@hidden for C++.
-If you find that you really prefer the names chosen by the old rules but you
-still wish to use @code{%language}, you can always request whatever file names
-you want explicitly with, for example, @code{--output} and @code{--defines}.
-
-If you are a developer working on an experimental Bison skeleton, you should be
-aware that the Bison front-end does not dictate the names of output files.
-Thus, until @code{%language} support is implemented for your skeleton, you can
-declare @code{%language} with perhaps a bogus argument to get the newer output
-file naming rules, you can use @code{%skeleton} to select your skeleton, and
-your skeleton can still choose file names with extensions that are appropriate
-for its output language.
-However, your skeleton should choose names that follow the conventions
-documented in original table above.
-Also, once @code{%language} support has been implemented for your skeleton, any
-new file name extensions should be documented in that table.
-
 @node Bison Options
 @section Bison Options
 
@@ -8067,6 +8053,11 @@ with other short options.
 Pretend that @code{%file-prefix} was specified, i.e., specify prefix to use
 for all Bison output file names.  @xref{Decl Summary}.
 
+Specifying @code{--file-prefix} together with @code{%output} or
address@hidden is deprecated, and will cause this command-line
+option to be ignored.  If the grammar file uses @code{%output},
+you should use @option{--output} instead.
+
 @item -r @var{things}
 @itemx address@hidden
 Write an extra output file containing verbose description of the comma
diff --git a/src/files.c b/src/files.c
index c6e5587..27f4b1d 100644
--- a/src/files.c
+++ b/src/files.c
@@ -59,23 +59,22 @@ uniqstr grammar_file = NULL;
 uniqstr current_file = NULL;
 
 /* If --output=dir/foo.c was specified,
-   DIR_PREFIX is `dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are `dir/foo'.
+   DIR_PREFIX is `dir/' and ALL_BUT_TAB_EXT is `dir/foo'.
 
    If --output=dir/foo.tab.c was specified, DIR_PREFIX is `dir/',
-   ALL_BUT_EXT is `dir/foo.tab', and ALL_BUT_TAB_EXT is `dir/foo'.
+   and ALL_BUT_TAB_EXT is `dir/foo'.
 
    If --output was not specified but --file-prefix=dir/foo was specified,
-   ALL_BUT_EXT = `foo.tab' and ALL_BUT_TAB_EXT = `foo'.
+   and ALL_BUT_TAB_EXT = `foo'.
 
    If neither --output nor --file was specified but the input grammar
-   is name dir/foo.y, ALL_BUT_EXT and ALL_BUT_TAB_EXT are `foo'.
+   is name dir/foo.y, ALL_BUT_TAB_EXT is `foo'.
 
    If neither --output nor --file was specified, DIR_PREFIX is the
    empty string (meaning the current directory); otherwise it is
    `dir/'.  */
 
-char *all_but_ext;
-static char *all_but_tab_ext;
+char *file_prefix;
 char *dir_prefix;
 
 /* C source file extension (the parser source).  */
@@ -166,27 +165,30 @@ xfclose (FILE *ptr)
 
    'foo' -> *BASE = 'foo', *TAB = NULL, *EXT = NULL.  */
 
-static void
+#define DOTTABLEN      4
+
+static int
 file_name_split (const char *file_name,
-                const char **base, const char **tab, const char **ext)
+                const char **base, const char **ext)
 {
-  *base = last_component (file_name);
+  if (base)
+    *base = last_component (file_name);
 
   /* Look for the extension, i.e., look for the last dot. */
-  *ext = strrchr (*base, '.');
-  *tab = NULL;
+  *ext = strrchr (file_name, '.');
 
   /* If there is an extension, check if there is a `.tab' part right
      before.  */
   if (*ext)
     {
-      size_t baselen = *ext - *base;
-      size_t dottablen = 4;
-      if (dottablen < baselen
-         && (strncmp (*ext - dottablen, ".tab", dottablen) == 0
-             || strncmp (*ext - dottablen, "_tab", dottablen) == 0))
-       *tab = *ext - dottablen;
+      size_t baselen = *ext - file_name;
+      if (DOTTABLEN < baselen
+         && (strncmp (*ext - DOTTABLEN, ".tab", DOTTABLEN) == 0
+         || strncmp (*ext - DOTTABLEN, "_tab", DOTTABLEN) == 0))
+       return 1;
     }
+
+  return 0;   
 }
 
 
@@ -199,99 +201,77 @@ tr (char *s, char from, char to)
       *s = to;
 }
 
-/* Compute extensions from the grammar file extension.  */
-static void
-compute_exts_from_gf (const char *ext)
-{
-  src_extension = xstrdup (ext);
-  header_extension = xstrdup (ext);
-  tr (src_extension, 'y', 'c');
-  tr (src_extension, 'Y', 'C');
-  tr (header_extension, 'y', 'h');
-  tr (header_extension, 'Y', 'H');
-}
 
-/* Compute extensions from the given c source file extension.  */
 static void
-compute_exts_from_src (const char *ext)
+compute_file_name_parts (void)
 {
-  /* We use this function when the user specifies `-o' or `--output',
-     so the extenions must be computed unconditionally from the file name
-     given by this option.  */
-  src_extension = xstrdup (ext);
-  header_extension = xstrdup (ext);
-  tr (header_extension, 'c', 'h');
-  tr (header_extension, 'C', 'H');
-}
-
+  const char *base, *ext;
 
-static void
-compute_file_name_parts_new (char const **extp)
-{
-  char const *base, *tab, *ext;
-  file_name_split (grammar_file, &base, &tab, &ext);
-  if (extp)
-    *extp = ext;
+  /* If --file-prefix=foo was specified, FILE_PREFIX = `foo'.
+     `.tab' is never added.  FILE_PREFIX only applies to non-source
+     files if --output is given too.  */
   if (spec_file_prefix)
     {
-      /* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = `foo'.  */
       dir_prefix =
         xstrndup (spec_file_prefix,
                   last_component (spec_file_prefix) - spec_file_prefix);
-      all_but_tab_ext = xstrdup (spec_file_prefix);
-    }
-  else if (yacc_flag && 0 == c_strcasecmp (language->language, "c"))
-    {
-      /* If --yacc, then the output is `y.tab.c'.  */
-      dir_prefix = xstrdup ("");
-      all_but_tab_ext = xstrdup ("y");
-    }
-  else
-    {
-      /* Otherwise, ALL_BUT_TAB_EXT is computed from the input
-         grammar: `foo/bar.yy' => `bar'.  */
-      dir_prefix = xstrdup ("");
-      all_but_tab_ext =
-        xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
-    }
-}
-
-static void
-compute_file_name_parts_old (void)
-{
-  const char *base, *tab, *ext;
 
-  /* Compute ALL_BUT_EXT and ALL_BUT_TAB_EXT from SPEC_OUTFILE
-     or GRAMMAR_FILE.
+      file_prefix = xstrdup (spec_file_prefix);
+      return;
+    }
 
-     The precise -o name will be used for FTABLE.  For other output
-     files, remove the ".c" or ".tab.c" suffix.  */
+  /* If --output=foo.c was specified, FILE_PREFIX = `foo'.
+     If --output=foo.tab.c was specified, FILE_PREFIX = `foo' too (sigh).  */
   if (spec_outfile)
     {
-      file_name_split (spec_outfile, &base, &tab, &ext);
+      int tab = file_name_split (spec_outfile, &base, &ext);
       dir_prefix = xstrndup (spec_outfile, base - spec_outfile);
 
-      /* ALL_BUT_EXT goes up the EXT, excluding it. */
-      all_but_ext =
-       xstrndup (spec_outfile,
-                 (strlen (spec_outfile) - (ext ? strlen (ext) : 0)));
-
-      /* ALL_BUT_TAB_EXT goes up to TAB, excluding it.  */
-      all_but_tab_ext =
+      /* Exclude `.tab' from the file prefix.  The m4 backend however
+        will produce file names including `.tab', because it computes
+        the default header file name from spec_outfile too.  */
+      file_prefix =
        xstrndup (spec_outfile,
                  (strlen (spec_outfile)
-                  - (tab ? strlen (tab) : (ext ? strlen (ext) : 0))));
-
-      if (ext)
-       compute_exts_from_src (ext);
+                  - (tab ? DOTTABLEN : 0) - (ext ? strlen (ext) : 0)));
+      return;
     }
+
+  /* Otherwise, unless in yacc mode, the file prefix comes from the
+     GRAMMAR_FILE, but the output is in the current directory.  */
+  file_name_split (grammar_file, &base, &ext);
+  dir_prefix = xstrdup ("");
+  if (yacc_flag)
+    file_prefix = xstrdup ("y");
   else
+    file_prefix = xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
+}
+
+void
+compute_output_file_names_old ()
+{
+  const char *ext;
+  char *src_extension;
+
+  /* In compatibility mode, extensions are computed from the grammar file
+     unless in yacc mode (sigh).  With `.tab', too (double sigh).  */
+  file_name_split (grammar_file, NULL, &ext);
+  if (yacc_flag && 0 == c_strcasecmp (language->language, "c") || !ext)
+    ext = ".y";
+
+  src_extension = xstrdup (ext);
+  tr (src_extension, 'y', 'c');
+  tr (src_extension, 'Y', 'C');
+  parser_file_name = concat2 (file_prefix, src_extension);
+  free (src_extension);
+
+  if (!defines_file_name)
     {
-      compute_file_name_parts_new (&ext);
-      all_but_ext = concat2 (all_but_tab_ext, TAB_EXT);
-      /* Compute the extensions from the grammar file name.  */
-      if (ext && !yacc_flag)
-       compute_exts_from_gf (ext);
+      char *header_extension = xstrdup (ext);
+      tr (header_extension, 'y', 'h');
+      tr (header_extension, 'Y', 'H');
+      defines_file_name = concat2 (file_prefix, header_extension);
+      free (header_extension);
     }
 }
 
@@ -303,67 +283,53 @@ compute_file_name_parts_old (void)
 void
 compute_output_file_names (void)
 {
-  if (language_prio == default_prio)
-    {
-      /* Old logic for computing output file names.  Used when %language or
-       * equivalent is not specified.  */
-      compute_file_name_parts_old ();
-
-      /* If not yet done. */
-      if (!src_extension)
-        src_extension = xstrdup (".c");
-      if (!header_extension)
-        header_extension = xstrdup (".h");
-
-      parser_file_name =
-        (spec_outfile
-         ? xstrdup (spec_outfile)
-         : concat2 (all_but_ext, src_extension));
-
-      if (defines_flag)
-        {
-          if (spec_defines_file)
-            defines_file_name = xstrdup (spec_defines_file);
-          else
-            defines_file_name = concat2 (all_but_ext, header_extension);
-        }
-
-      free (src_extension);
-      free (header_extension);
-    }
-  else
+  /* Look for conflicting options.  */
+  if (spec_outfile && spec_file_prefix)
     {
-      /* New logic for computing output file names.  Used when %language or
-       * equivalent is specified.  */
-      compute_file_name_parts_new (NULL);
-      if (yacc_flag && 0 == c_strcasecmp (language->language, "c"))
-        all_but_ext = concat2 (all_but_tab_ext, TAB_EXT);
-      else
-        all_but_ext = xstrdup (all_but_tab_ext);
+      warn (_("specifying the output file and the file prefix at the"));
+      warn (_("same time is deprecated; considering output file only"));
+      spec_file_prefix = NULL;
     }
 
+  /* See if the user gave us file names.  */
+  if (spec_outfile)
+    parser_file_name = xstrdup (spec_outfile);
+  if (spec_defines_file)
+    defines_file_name = xstrdup (spec_defines_file);
+
+  /* Compute dir_prefix and file_prefix.  */
+  compute_file_name_parts ();
+
   if (graph_flag)
     {
       if (! spec_graph_file)
-       spec_graph_file = concat2 (all_but_tab_ext, ".dot");
+       spec_graph_file = concat2 (file_prefix, ".dot");
       output_file_name_check (spec_graph_file);
     }
 
   if (xml_flag)
     {
       if (! spec_xml_file)
-       spec_xml_file = concat2 (all_but_tab_ext, ".xml");
+       spec_xml_file = concat2 (file_prefix, ".xml");
       output_file_name_check (spec_xml_file);
     }
 
   if (report_flag)
     {
       if (!spec_verbose_file)
-        spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT);
+        spec_verbose_file = concat2 (file_prefix, OUTPUT_EXT);
       output_file_name_check (spec_verbose_file);
     }
 
-  free (all_but_tab_ext);
+  if (yacc_flag || language_prio == default_prio)
+    {
+      char *new_prefix = concat2 (file_prefix, TAB_EXT);
+      free (file_prefix);
+      file_prefix = new_prefix;
+    }
+
+  if (!parser_file_name && language_prio == default_prio)
+    compute_output_file_names_old ();
 }
 
 void
@@ -384,13 +350,13 @@ output_file_name_check (char const *file_name)
 void
 output_file_names_free (void)
 {
-  free (all_but_ext);
   free (spec_verbose_file);
   free (spec_graph_file);
   free (spec_xml_file);
   free (parser_file_name);
   free (defines_file_name);
   free (dir_prefix);
+  free (file_prefix);
   {
     int i;
     for (i = 0; i < file_names_count; i++)
diff --git a/src/files.h b/src/files.h
index 4e08fd6..c93783f 100644
--- a/src/files.h
+++ b/src/files.h
@@ -50,9 +50,6 @@ extern char *spec_graph_file;
 /* File name specified for the xml output.  */
 extern char *spec_xml_file;
 
-/* Directory prefix of output file names.  */
-extern char *dir_prefix;
-
 /* The file name as given on the command line.
    Not named "input_file" because Flex uses this name for an argument,
    and therefore GCC warns about a name clash. */
@@ -61,8 +58,9 @@ extern uniqstr grammar_file;
 /* The current file name.  Might change with %include, or with #line.  */
 extern uniqstr current_file;
 
-/* The computed base for output file names.  */
-extern char *all_but_ext;
+/* The computed base for output file names; directory and file components.  */
+extern char *dir_prefix;
+extern char *file_prefix;
 
 void compute_output_file_names (void);
 void output_file_names_free (void);
diff --git a/src/output.c b/src/output.c
index 209e524..d83eeb7 100644
--- a/src/output.c
+++ b/src/output.c
@@ -617,15 +617,13 @@ prepare (void)
   if (spec_name_prefix)
     MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
 
-  MUSCLE_INSERT_STRING ("file_name_all_but_ext", all_but_ext);
-
 #define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "")
   DEFINE (dir_prefix);
+  DEFINE (file_prefix);
   DEFINE (parser_file_name);
   DEFINE (defines_file_name);
   DEFINE (spec_outfile);
   DEFINE (spec_defines_file);
-  DEFINE (spec_file_prefix);
   DEFINE (spec_graph_file);
   DEFINE (spec_name_prefix);
   DEFINE (spec_verbose_file);
diff --git a/tests/output.at b/tests/output.at
index e62b38e..0b3728e 100644
--- a/tests/output.at
+++ b/tests/output.at
@@ -34,7 +34,7 @@ AT_DATA([$1],
 foo: {};
 ]])
 
-AT_BISON_CHECK([$3 $1 $5], 0)
+AT_BISON_CHECK([$3 $1 $5], 0, [], [ignore])
 AT_CHECK([ls $4], [], [ignore])
 $6
 AT_CLEANUP
@@ -142,9 +142,9 @@ AT_CHECK_OUTPUT([[foo.bison]],, [[-LJava -v -g -x]],
 AT_CHECK_OUTPUT([[foo.bison]],, [[-LC -dv -g -x -y]],
                 [[y.tab.c y.tab.h y.output y.dot y.xml]])
 AT_CHECK_OUTPUT([[foo.bison]],, [[-LC++ -dv -g -x -y]],
-                [[foo.cc foo.hh foo.output foo.dot foo.xml ]cpp_aux])
+                [[y.tab.cc y.tab.hh y.output y.dot y.xml ]cpp_aux])
 AT_CHECK_OUTPUT([[foo.bison]],, [[-LJava -v -g -x -y]],
-                [[foo.java foo.output foo.dot foo.xml]])
+                [[y.tab.java y.output y.dot y.xml]])
 
 # Override file prefix.
 AT_CHECK_OUTPUT([[foo.bison]],, [[-LC -dv -g -x -bdir/b]],
@@ -156,25 +156,30 @@ AT_CHECK_OUTPUT([[foo.bison]],, [[-LC++ -dv -g -x 
-bdir/b]],
 AT_CHECK_OUTPUT([[foo.bison]],, [[-LJava -v -g -x -bdir/b]],
                 [[dir/b.java dir/b.output dir/b.dot dir/b.xml]])
 
-# Override file prefix and parser source code file.
-AT_CHECK_OUTPUT([[foo.bison]],, [[-LC -dv -g -x -bdir/b -obar-c]],
-                [[bar-c dir/b.h dir/b.output dir/b.dot dir/b.xml]])
-AT_CHECK_OUTPUT([[foo.bison]],, [[-LC -dv -g -x -bdir/b -obar-c -y]],
-                [[bar-c dir/b.tab.h dir/b.output dir/b.dot dir/b.xml]])
-AT_CHECK_OUTPUT([[foo.bison]],, [[-LC++ -dv -g -x -bdir/b -obar.cpp]],
-                [[bar.cpp dir/b.hh dir/b.output dir/b.dot dir/b.xml 
]cpp_aux([[dir/]])])
-AT_CHECK_OUTPUT([[foo.bison]],, [[-LJava -v -g -x -bdir/b -obar.Java]],
-                [[bar.Java dir/b.output dir/b.dot dir/b.xml]])
+# Override file prefix and parser source code file.  This is deprecated,
+# so we do not test it in conjunction with -L.
+dnl AT_CHECK_OUTPUT([[foo.bison]],, [[-LC -dv -g -x -bdir/b -obar-c]],
+dnl                 [[bar-c dir/b.h dir/b.output dir/b.dot dir/b.xml]])
+dnl AT_CHECK_OUTPUT([[foo.bison]],, [[-LC -dv -g -x -bdir/b -obar-c -y]],
+dnl                 [[bar-c dir/b.tab.h dir/b.output dir/b.dot dir/b.xml]])
+dnl AT_CHECK_OUTPUT([[foo.bison]],, [[-LC++ -dv -g -x -bdir/b -obar.C]],
+dnl                 [[bar.C dir/b.H dir/b.output dir/b.dot dir/b.xml 
]cpp_aux([[dir/]])])
+dnl AT_CHECK_OUTPUT([[foo.bison]],, [[-LC++ -dv -g -x -bdir/b -obar.cpp]],
+dnl                 [[bar.cpp dir/b.hpp dir/b.output dir/b.dot dir/b.xml 
]cpp_aux([[dir/]])])
+dnl AT_CHECK_OUTPUT([[foo.bison]],, [[-LJava -v -g -x -bdir/b -obar.Java]],
+dnl                 [[bar.Java dir/b.output dir/b.dot dir/b.xml]])
 
 # Override parser source code file.
 AT_CHECK_OUTPUT([[foo.bison]],, [[-LC -dv -g -x -obar-c]],
-                [[bar-c foo.h foo.output foo.dot foo.xml]])
+                [[bar-c bar-c.h bar-c.output bar-c.dot bar-c.xml]])
 AT_CHECK_OUTPUT([[foo.bison]],, [[-LC -dv -g -x -obar-c -y]],
-                [[bar-c y.tab.h y.output y.dot y.xml]])
+                [[bar-c bar-c.h bar-c.output bar-c.dot bar-c.xml]])
+AT_CHECK_OUTPUT([[foo.bison]],, [[-LC++ -dv -g -x -obar.C]],
+                [[bar.C bar.H bar.output bar.dot bar.xml ]cpp_aux])
 AT_CHECK_OUTPUT([[foo.bison]],, [[-LC++ -dv -g -x -obar.cpp]],
-                [[bar.cpp foo.hh foo.output foo.dot foo.xml ]cpp_aux])
+                [[bar.cpp bar.hpp bar.output bar.dot bar.xml ]cpp_aux])
 AT_CHECK_OUTPUT([[foo.bison]],, [[-LJava -v -g -x -odir/bar.Java]],
-                [[dir/bar.Java foo.output foo.dot foo.xml]])
+                [[dir/bar.Java dir/bar.output dir/bar.dot dir/bar.xml]])
 
 # Other overrides.
 AT_CHECK_OUTPUT([[foo.bison]],,
-- 
1.5.5





reply via email to

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