If an output file name is specified, tr "cC" "hH" on the extension gives the default header file name output. This causes conflict if the output file name extension does not contain [cC]. This patch uses the selected language's header extension in that case instead.
If no output file name is specified and the input file name does not ends in ".y", tr "yY" "cC" and tr "yY" "hH" are used on the input file extension to get the output and default header file names. This causes the input file to be overwritten if the the input file name extension does not contain [yY]. Overwriting the input file is not such a good idea. This patch uses the selected language's source extension in that case instead. This patch also checks that the input file name is not used as an output file name in check_file_name_check, with a fatal error if it is. Tested with "make -k check" on Cygwin one expected failure. See http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00008.html Di-an Jan 2008-10-05 Di-an Jan <[EMAIL PROTECTED]> Make sure generated file name extensions are changed. src/files.c (compute_exts_from_gf): Use extensions from language if the input file extension contains no [yY]. (compute_exts_from_src): Use header extension from language if the output file extension contains no [cC]. (output_file_name_check): Fatal error if using input file for output. tests/output.at: (Output files): Add 6 tests. (AT_CHECK_CONFLICTING_OUTPUT): Add return status argument. (Conflicting output files): Add test. diff --git a/src/files.c b/src/files.c index 0499a35..3fc6626 --- a/src/files.c +++ b/src/files.c @@ -149,7 +149,7 @@ tr (char *s, char from, char to) static void compute_exts_from_gf (const char *ext) { - if (strcmp (ext, ".y") == 0) + if (strcmp (ext, ".y") == 0 || ! (strchr (ext, 'y') || strchr (ext, 'Y'))) { src_extension = xstrdup (language->src_extension); header_extension = xstrdup (language->header_extension); @@ -173,9 +173,16 @@ compute_exts_from_src (const char *ext) 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'); + if (! (strchr (src_extension, 'c') || strchr (src_extension, 'C'))) + { + header_extension = xstrdup (language->header_extension); + } + else + { + header_extension = xstrdup (ext); + tr (header_extension, 'c', 'h'); + tr (header_extension, 'C', 'H'); + } } @@ -351,6 +358,9 @@ compute_output_file_names (void) void output_file_name_check (char const *file_name) { + if (0 == strcmp (file_name, grammar_file)) + fatal (_("refusing to overwrite the input file %s"), quote (file_name)); + { int i; for (i = 0; i < file_names_count; i++) diff --git a/tests/output.at b/tests/output.at index 6e21dc9..864e3a5 --- a/tests/output.at +++ b/tests/output.at @@ -40,11 +40,15 @@ AT_CLEANUP AT_CHECK_OUTPUT([foo.y], [], [-dv], [foo.output foo.tab.c foo.tab.h]) +AT_CHECK_OUTPUT([foo.xxx], [], [-dv], + [foo.output foo.tab.c foo.tab.h]) AT_CHECK_OUTPUT([foo.y], [], [-dv], [foo.output foo.tab.c foo.tab.h], [>&-]) AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.c], [foo.c foo.h foo.output]) +AT_CHECK_OUTPUT([foo.xxx], [], [-dv -o foo.c], + [foo.c foo.h foo.output]) AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.tab.c], [foo.output foo.tab.c foo.tab.h]) AT_CHECK_OUTPUT([foo.y], [], [-dv -y], @@ -57,6 +61,8 @@ AT_CHECK_OUTPUT([foo.y], [], [-dv -g -o foo.c], AT_CHECK_OUTPUT([foo.y], [%defines %verbose], [], [foo.output foo.tab.c foo.tab.h]) +AT_CHECK_OUTPUT([foo.xxx], [%defines %verbose], [], + [foo.output foo.tab.c foo.tab.h]) AT_CHECK_OUTPUT([foo.y], [%defines %verbose %yacc],[], [y.output y.tab.c y.tab.h]) @@ -66,6 +72,8 @@ AT_CHECK_OUTPUT([foo.yy], [%defines %verbose %yacc],[], # Exercise %output and %file-prefix including deprecated `=' AT_CHECK_OUTPUT([foo.y], [%file-prefix "bar" %defines %verbose], [], [bar.output bar.tab.c bar.tab.h]) +AT_CHECK_OUTPUT([foo.xxx], [%file-prefix "bar" %defines %verbose], [], + [bar.output bar.tab.c bar.tab.h]) AT_CHECK_OUTPUT([foo.y], [%output="bar.c" %defines %verbose %yacc],[], [bar.output bar.c bar.h]) AT_CHECK_OUTPUT([foo.y], @@ -93,6 +101,9 @@ AT_CHECK_OUTPUT([foo.yy], [], [-o foo.c++ --graph=foo.gph], [foo.c++ foo.gph]) +AT_CHECK_OUTPUT([foo.y], [%language "Java"], [], [foo.java]) +AT_CHECK_OUTPUT([foo.xxx], [%language "Java"], [], [foo.java]) + ## ------------ ## ## C++ output. ## @@ -117,8 +128,8 @@ AT_CHECK_OUTPUT([subdir/foo.yy], [%skeleton "lalr1.cc" %defines %verbose], [], [AT_CHECK_NO_SUBDIR_PART([subdir/foo])]) -# AT_CHECK_CONFLICTING_OUTPUT(INPUT-FILE, DIRECTIVES, FLAGS, STDERR) -# ----------------------------------------------------------------------------- +# AT_CHECK_CONFLICTING_OUTPUT(INPUT-FILE, DIRECTIVES, FLAGS, STDERR, EXIT-STATUS) +# ------------------------------------------------------------------------------- m4_define([AT_CHECK_CONFLICTING_OUTPUT], [AT_SETUP([Conflicting output files: $2 $3]) case "$1" in @@ -130,7 +141,7 @@ AT_DATA([$1], foo: {}; ]]) -AT_BISON_CHECK([$3 $1], 0, [], [$4]) +AT_BISON_CHECK([$3 $1], $5, [], [$4]) AT_CLEANUP ]) @@ -149,6 +160,10 @@ AT_CHECK_CONFLICTING_OUTPUT([foo.y], [foo.y: warning: conflicting outputs to file `location.hh' ]) +AT_CHECK_CONFLICTING_OUTPUT([foo.y], [], [-o foo.y], +[foo.y: fatal error: refusing to overwrite the input file `foo.y' +], 1) + # AT_CHECK_OUTPUT_FILE_NAME(FILE-NAME-PREFIX, [ADDITIONAL-TESTS]) # -----------------------------------------------------------------------------
