]> git.saurik.com Git - bison.git/commitdiff
Don't let Bison leak memory except when it complains.
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 8 Nov 2006 20:28:57 +0000 (20:28 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 8 Nov 2006 20:28:57 +0000 (20:28 +0000)
* src/files.h (parser_file_name, spec_verbose_file, spec_graph_file):
(spec_defines_file, dir_prefix): Now char *, not const char *,
since they are freed.
* src/files.c: Likewise.
(all_but_ext, all_but_tab_ext, src_extension, header_extension):
Likewise.
(tr): Now operates in-place.  All uses changed.
(compute_exts_from_gf, compute_exts_from_src): Don't leak temporary
values.
(compute_file_name_parts, compute_output_file_names): Don't store
read-only data in variables that will be freed.
(compute_output_file_names): Free all_but_ext, all_but_tab_ext,
src_extension, and header_extension.
(output_file_names_free): New public function to free
spec_verbose_file, spec_graph_file, spec_defines_file,
parser_file_name, and dir_prefix.
* src/getargs.c (getargs): Don't store read-only data in variables that
will be freed.
* src/main.c (main): Invoke output_file_names_free, code_scanner_free
(which previously existed but was unused), and quotearg_free.
* src/muscle_tab.h (muscle_insert): value arg is now a `char const *'.
* src/muscle_tab.c: Likewise.
(muscle_entry): Make the value char const *,
and add a new storage member that is char * and can be freed.
(muscle_entry_free): New private function.
(muscle_init): Use it instead of free.
(muscle_insert, muscle_grow): Update and use new storage member.
(muscle_code_grow): Free the string passed to muscle_grow
since it's not needed anymore.
* src/parse-gram.y (%union): Make `chars' member a `char const *', and
add a new `char *code' member.
("{...}"): Declare semantic type as code.
* src/scan-code.h (translate_rule_action):
(translate_symbol_action, translate_code, translate_action): Return
`char const *' rather than `char *' since external code should not free
these strings.
* src/scan-code.l: Likewise.
* src/scan-gram.l (<SC_BRACED_CODE>): Use val->code for BRACED_CODE,
which is "{...}" in the parser.
* tests/Makefile.am (maintainer-check-valgrind): Set
VALGRIND_OPTS='--leak-check=full --show-reacheable=yes' before invoking
Valgrind.
* tests/calc.at (_AT_DATA_CALC_Y): fclose the FILE* so Valgrind doesn't
complain.
* tests/testsuite.at (AT_CHECK): Redefine so that running Bison and
expecting a non-zero exit status sets --leak-check=summary and
--show-reachable=no for Valgrind.  Bison unabashedly leaks memory in
this case, and we don't want to hear about it.

14 files changed:
ChangeLog
src/files.c
src/files.h
src/getargs.c
src/main.c
src/muscle_tab.c
src/muscle_tab.h
src/parse-gram.y
src/scan-code.h
src/scan-code.l
src/scan-gram.l
tests/Makefile.am
tests/calc.at
tests/testsuite.at

index 1a7d90906d566c7014014b39d5b7b640b8da444d..451c9d00d7329f8985c3ab7afdfd25ffca6d061f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+2006-11-08  Joel E. Denny  <jdenny@ces.clemson.edu>
+       and Paul Eggert  <eggert@cs.ucla.edu>
+
+       Don't let Bison leak memory except when it complains.
+       * src/files.h (parser_file_name, spec_verbose_file, spec_graph_file):
+       (spec_defines_file, dir_prefix): Now char *, not const char *,
+       since they are freed.
+       * src/files.c: Likewise.
+       (all_but_ext, all_but_tab_ext, src_extension, header_extension):
+       Likewise.
+       (tr): Now operates in-place.  All uses changed.
+       (compute_exts_from_gf, compute_exts_from_src): Don't leak temporary
+       values.
+       (compute_file_name_parts, compute_output_file_names): Don't store
+       read-only data in variables that will be freed.
+       (compute_output_file_names): Free all_but_ext, all_but_tab_ext,
+       src_extension, and header_extension.
+       (output_file_names_free): New public function to free
+       spec_verbose_file, spec_graph_file, spec_defines_file,
+       parser_file_name, and dir_prefix.
+       * src/getargs.c (getargs): Don't store read-only data in variables that
+       will be freed.
+       * src/main.c (main): Invoke output_file_names_free, code_scanner_free
+       (which previously existed but was unused), and quotearg_free.
+       * src/muscle_tab.h (muscle_insert): value arg is now a `char const *'.
+       * src/muscle_tab.c: Likewise.
+       (muscle_entry): Make the value char const *,
+       and add a new storage member that is char * and can be freed.
+       (muscle_entry_free): New private function.
+       (muscle_init): Use it instead of free.
+       (muscle_insert, muscle_grow): Update and use new storage member.
+       (muscle_code_grow): Free the string passed to muscle_grow
+       since it's not needed anymore.
+       * src/parse-gram.y (%union): Make `chars' member a `char const *', and
+       add a new `char *code' member.
+       ("{...}"): Declare semantic type as code.
+       * src/scan-code.h (translate_rule_action):
+       (translate_symbol_action, translate_code, translate_action): Return
+       `char const *' rather than `char *' since external code should not free
+       these strings.
+       * src/scan-code.l: Likewise.
+       * src/scan-gram.l (<SC_BRACED_CODE>): Use val->code for BRACED_CODE,
+       which is "{...}" in the parser.
+       * tests/Makefile.am (maintainer-check-valgrind): Set
+       VALGRIND_OPTS='--leak-check=full --show-reacheable=yes' before invoking
+       Valgrind.
+       * tests/calc.at (_AT_DATA_CALC_Y): fclose the FILE* so Valgrind doesn't
+       complain.
+       * tests/testsuite.at (AT_CHECK): Redefine so that running Bison and
+       expecting a non-zero exit status sets --leak-check=summary and
+       --show-reachable=no for Valgrind.  Bison unabashedly leaks memory in
+       this case, and we don't want to hear about it.
+
 2006-11-08  Paul Eggert  <eggert@cs.ucla.edu>
 
        * bootstrap (runtime-po/Makevars): Derive from po/Makevars
 2006-11-08  Paul Eggert  <eggert@cs.ucla.edu>
 
        * bootstrap (runtime-po/Makevars): Derive from po/Makevars
index ecb31738f9534c8a51518cbdf53088d4f82455a2..951a7acc669ef1a3c478a4f00ab7d4be01d1d09f 100644 (file)
@@ -48,10 +48,10 @@ struct obstack post_prologue_obstack;
 char const *spec_outfile = NULL;       /* for -o. */
 char const *spec_file_prefix = NULL;   /* for -b. */
 char const *spec_name_prefix = NULL;   /* for -p. */
 char const *spec_outfile = NULL;       /* for -o. */
 char const *spec_file_prefix = NULL;   /* for -b. */
 char const *spec_name_prefix = NULL;   /* for -p. */
-char const *spec_verbose_file = NULL;  /* for --verbose. */
-char const *spec_graph_file = NULL;    /* for -g. */
-char const *spec_defines_file = NULL;  /* for --defines. */
-char const *parser_file_name;
+char *spec_verbose_file = NULL;  /* for --verbose. */
+char *spec_graph_file = NULL;    /* for -g. */
+char *spec_defines_file = NULL;  /* for --defines. */
+char *parser_file_name;
 
 uniqstr grammar_file = NULL;
 uniqstr current_file = NULL;
 
 uniqstr grammar_file = NULL;
 uniqstr current_file = NULL;
@@ -72,14 +72,14 @@ uniqstr current_file = NULL;
    empty string (meaning the current directory); otherwise it is
    `dir/'.  */
 
    empty string (meaning the current directory); otherwise it is
    `dir/'.  */
 
-static char const *all_but_ext;
-static char const *all_but_tab_ext;
-char const *dir_prefix;
+static char *all_but_ext;
+static char *all_but_tab_ext;
+char *dir_prefix;
 
 /* C source file extension (the parser source).  */
 
 /* C source file extension (the parser source).  */
-static char const *src_extension = NULL;
+static char *src_extension = NULL;
 /* Header file extension (if option ``-d'' is specified).  */
 /* Header file extension (if option ``-d'' is specified).  */
-static char const *header_extension = NULL;
+static char *header_extension = NULL;
 \f
 /*-----------------------------------------------------------------.
 | Return a newly allocated string composed of the concatenation of |
 \f
 /*-----------------------------------------------------------------.
 | Return a newly allocated string composed of the concatenation of |
@@ -136,31 +136,25 @@ xfclose (FILE *ptr)
 | Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. |
 `------------------------------------------------------------------*/
 
 | Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. |
 `------------------------------------------------------------------*/
 
-/* Replace all characters FROM by TO in the string IN.
-   and returns a new allocated string.  */
+/* In the string S, replace all characters FROM by TO.  */
 static char *
 static char *
-tr (const char *in, char from, char to)
+tr (char *s, char from, char to)
 {
 {
-  char *temp;
-  char *out = xmalloc (strlen (in) + 1);
-
-  for (temp = out; *in; in++, out++)
-    if (*in == from)
-      *out = to;
-    else
-      *out = *in;
-  *out = 0;
-  return (temp);
+  for (; *s; s++)
+    if (*s == from)
+      *s = to;
 }
 
 /* Compute extensions from the grammar file extension.  */
 static void
 compute_exts_from_gf (const char *ext)
 {
 }
 
 /* Compute extensions from the grammar file extension.  */
 static void
 compute_exts_from_gf (const char *ext)
 {
-  src_extension = tr (ext, 'y', 'c');
-  src_extension = tr (src_extension, 'Y', 'C');
-  header_extension = tr (ext, 'y', 'h');
-  header_extension = tr (header_extension, 'Y', 'H');
+  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.  */
 }
 
 /* Compute extensions from the given c source file extension.  */
@@ -171,8 +165,9 @@ 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);
      so the extenions must be computed unconditionally from the file name
      given by this option.  */
   src_extension = xstrdup (ext);
-  header_extension = tr (ext, 'c', 'h');
-  header_extension = tr (header_extension, 'C', 'H');
+  header_extension = xstrdup (ext);
+  tr (header_extension, 'c', 'h');
+  tr (header_extension, 'C', 'H');
 }
 
 
 }
 
 
@@ -270,14 +265,14 @@ compute_file_name_parts (void)
       else if (yacc_flag)
        {
          /* If --yacc, then the output is `y.tab.c'.  */
       else if (yacc_flag)
        {
          /* If --yacc, then the output is `y.tab.c'.  */
-         dir_prefix = "";
-         all_but_tab_ext = "y";
+         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'.  */
        }
       else
        {
          /* Otherwise, ALL_BUT_TAB_EXT is computed from the input
             grammar: `foo/bar.yy' => `bar'.  */
-         dir_prefix = "";
+         dir_prefix = xstrdup ("");
          all_but_tab_ext =
            xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
        }
          all_but_tab_ext =
            xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
        }
@@ -306,12 +301,14 @@ compute_output_file_names (void)
 
   /* If not yet done. */
   if (!src_extension)
 
   /* If not yet done. */
   if (!src_extension)
-    src_extension = ".c";
+    src_extension = xstrdup (".c");
   if (!header_extension)
   if (!header_extension)
-    header_extension = ".h";
+    header_extension = xstrdup (".h");
 
   name[names++] = parser_file_name =
 
   name[names++] = parser_file_name =
-    spec_outfile ? spec_outfile : concat2 (all_but_ext, src_extension);
+    (spec_outfile
+     ? xstrdup (spec_outfile)
+     : concat2 (all_but_ext, src_extension));
 
   if (defines_flag)
     {
 
   if (defines_flag)
     {
@@ -337,4 +334,19 @@ compute_output_file_names (void)
     for (i = 0; i < j; i++)
       if (strcmp (name[i], name[j]) == 0)
        warn (_("conflicting outputs to file %s"), quote (name[i]));
     for (i = 0; i < j; i++)
       if (strcmp (name[i], name[j]) == 0)
        warn (_("conflicting outputs to file %s"), quote (name[i]));
+
+  free (all_but_ext);
+  free (all_but_tab_ext);
+  free (src_extension);
+  free (header_extension);
+}
+
+void
+output_file_names_free (void)
+{
+  free (spec_verbose_file);
+  free (spec_graph_file);
+  free (spec_defines_file);
+  free (parser_file_name);
+  free (dir_prefix);
 }
 }
index e8df14e7db5e3a97bd2d3469e201621cfe1d123a..e702db65b219ba6a147b1c53c17ead38a276dae9 100644 (file)
@@ -29,7 +29,7 @@
 extern char const *spec_outfile;
 
 /* File name for the parser (i.e., the one above, or its default.) */
 extern char const *spec_outfile;
 
 /* File name for the parser (i.e., the one above, or its default.) */
-extern char const *parser_file_name;
+extern char *parser_file_name;
 
 /* Symbol prefix specified with -p, or 0 if no -p.  */
 extern const char *spec_name_prefix;
 
 /* Symbol prefix specified with -p, or 0 if no -p.  */
 extern const char *spec_name_prefix;
@@ -38,16 +38,16 @@ extern const char *spec_name_prefix;
 extern char const *spec_file_prefix;
 
 /* --verbose. */
 extern char const *spec_file_prefix;
 
 /* --verbose. */
-extern char const *spec_verbose_file;
+extern char *spec_verbose_file;
 
 /* File name specified for the output graph.  */
 
 /* File name specified for the output graph.  */
-extern char const *spec_graph_file;
+extern char *spec_graph_file;
 
 /* File name specified with --defines.  */
 
 /* File name specified with --defines.  */
-extern char const *spec_defines_file;
+extern char *spec_defines_file;
 
 /* Directory prefix of output file names.  */
 
 /* Directory prefix of output file names.  */
-extern char const *dir_prefix;
+extern char *dir_prefix;
 
 
 /* If semantic parser, output a .h file that defines YYSTYPE... */
 
 
 /* If semantic parser, output a .h file that defines YYSTYPE... */
@@ -63,6 +63,7 @@ extern uniqstr grammar_file;
 extern uniqstr current_file;
 
 void compute_output_file_names (void);
 extern uniqstr current_file;
 
 void compute_output_file_names (void);
+void output_file_names_free (void);
 
 FILE *xfopen (const char *name, const char *mode);
 void xfclose (FILE *ptr);
 
 FILE *xfopen (const char *name, const char *mode);
 void xfclose (FILE *ptr);
index 177255e70e67a634030d446102d5587371d78ed3..9a2f5307ced06eb3aa01882e369e46a794614978 100644 (file)
@@ -98,7 +98,7 @@ flags_argmatch (const char *option,
            *flags = 0;
          else
            *flags |= value;
            *flags = 0;
          else
            *flags |= value;
-          args = strtok (NULL, ",");
+         args = strtok (NULL, ",");
        }
     }
   else
        }
     }
   else
@@ -408,7 +408,7 @@ getargs (int argc, char *argv[])
        /* Here, the -g and --graph=FILE options are differentiated.  */
        graph_flag = true;
        if (optarg)
        /* Here, the -g and --graph=FILE options are differentiated.  */
        graph_flag = true;
        if (optarg)
-         spec_graph_file = AS_FILE_NAME (optarg);
+         spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
        break;
 
       case 'h':
        break;
 
       case 'h':
@@ -426,7 +426,7 @@ getargs (int argc, char *argv[])
        /* Here, the -d and --defines options are differentiated.  */
        defines_flag = true;
        if (optarg)
        /* Here, the -d and --defines options are differentiated.  */
        defines_flag = true;
        if (optarg)
-         spec_defines_file = AS_FILE_NAME (optarg);
+         spec_defines_file = xstrdup (AS_FILE_NAME (optarg));
        break;
 
       case 'k':
        break;
 
       case 'k':
index a6fafc2510914481de9de3e3df26af3f1087aee4..a2056c82bac8854f3d4cc03e60a756b185742d92 100644 (file)
@@ -26,6 +26,7 @@
 #include <bitset_stats.h>
 #include <bitset.h>
 #include <configmake.h>
 #include <bitset_stats.h>
 #include <bitset.h>
 #include <configmake.h>
+#include <quotearg.h>
 #include <timevar.h>
 
 #include "LR0.h"
 #include <timevar.h>
 
 #include "LR0.h"
@@ -43,6 +44,7 @@
 #include "print_graph.h"
 #include "reader.h"
 #include "reduce.h"
 #include "print_graph.h"
 #include "reader.h"
 #include "reduce.h"
+#include "scan-code.h"
 #include "scan-gram.h"
 #include "symtab.h"
 #include "tables.h"
 #include "scan-gram.h"
 #include "symtab.h"
 #include "tables.h"
@@ -168,12 +170,15 @@ main (int argc, char *argv[])
   reduce_free ();
   conflicts_free ();
   grammar_free ();
   reduce_free ();
   conflicts_free ();
   grammar_free ();
+  output_file_names_free ();
 
   /* The scanner memory cannot be released right after parsing, as it
      contains things such as user actions, prologue, epilogue etc.  */
   gram_scanner_free ();
   muscle_free ();
   uniqstrs_free ();
 
   /* The scanner memory cannot be released right after parsing, as it
      contains things such as user actions, prologue, epilogue etc.  */
   gram_scanner_free ();
   muscle_free ();
   uniqstrs_free ();
+  code_scanner_free ();
+  quotearg_free ();
   timevar_pop (TV_FREE);
 
   if (trace_flag & trace_bitsets)
   timevar_pop (TV_FREE);
 
   if (trace_flag & trace_bitsets)
index 2d71085ebe2f71d13886c79f1d91deed09e06977..6ceb71f332debbe5d339ec36771ebfe175d029fb 100644 (file)
@@ -1,6 +1,6 @@
 /* Muscle table manager for Bison.
 
 /* Muscle table manager for Bison.
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
    Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
    Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 #include "muscle_tab.h"
 #include "getargs.h"
 
 #include "muscle_tab.h"
 #include "getargs.h"
 
+/* A key-value pair, along with storage that can be reclaimed when
+   this pair is no longer needed.  */
 typedef struct
 {
 typedef struct
 {
-  const char *key;
-  char *value;
+  char const *key;
+  char const *value;
+  char *storage;
 } muscle_entry;
 
 /* An obstack used to create some entries.  */
 } muscle_entry;
 
 /* An obstack used to create some entries.  */
@@ -64,6 +67,14 @@ hash_muscle (const void *x, size_t tablesize)
 | Also set up the MUSCLE_OBSTACK.                                  |
 `-----------------------------------------------------------------*/
 
 | Also set up the MUSCLE_OBSTACK.                                  |
 `-----------------------------------------------------------------*/
 
+static void
+muscle_entry_free (void *entry)
+{
+  muscle_entry *mentry = entry;
+  free (mentry->storage);
+  free (mentry);
+}
+
 void
 muscle_init (void)
 {
 void
 muscle_init (void)
 {
@@ -71,7 +82,7 @@ muscle_init (void)
   obstack_init (&muscle_obstack);
 
   muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
   obstack_init (&muscle_obstack);
 
   muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
-                                 hash_compare_muscles, free);
+                                 hash_compare_muscles, muscle_entry_free);
 
   /* Version and input file.  */
   MUSCLE_INSERT_STRING ("version", VERSION);
 
   /* Version and input file.  */
   MUSCLE_INSERT_STRING ("version", VERSION);
@@ -98,7 +109,7 @@ muscle_free (void)
 `------------------------------------------------------------*/
 
 void
 `------------------------------------------------------------*/
 
 void
-muscle_insert (const char *key, char *value)
+muscle_insert (char const *key, char const *value)
 {
   muscle_entry probe;
   muscle_entry *entry;
 {
   muscle_entry probe;
   muscle_entry *entry;
@@ -112,6 +123,7 @@ muscle_insert (const char *key, char *value)
       entry = xmalloc (sizeof *entry);
       entry->key = key;
       hash_insert (muscle_table, entry);
       entry = xmalloc (sizeof *entry);
       entry->key = key;
       hash_insert (muscle_table, entry);
+      entry->storage = NULL;
     }
   entry->value = value;
 }
     }
   entry->value = value;
 }
@@ -138,19 +150,19 @@ muscle_grow (const char *key, const char *val, const char *separator)
       entry = xmalloc (sizeof *entry);
       entry->key = key;
       hash_insert (muscle_table, entry);
       entry = xmalloc (sizeof *entry);
       entry->key = key;
       hash_insert (muscle_table, entry);
-      entry->value = xstrdup (val);
+      entry->value = entry->storage = xstrdup (val);
     }
   else
     {
       /* Grow the current value. */
       char *new_val;
       obstack_sgrow (&muscle_obstack, entry->value);
     }
   else
     {
       /* Grow the current value. */
       char *new_val;
       obstack_sgrow (&muscle_obstack, entry->value);
-      free (entry->value);
+      free (entry->storage);
       obstack_sgrow (&muscle_obstack, separator);
       obstack_sgrow (&muscle_obstack, val);
       obstack_1grow (&muscle_obstack, 0);
       new_val = obstack_finish (&muscle_obstack);
       obstack_sgrow (&muscle_obstack, separator);
       obstack_sgrow (&muscle_obstack, val);
       obstack_1grow (&muscle_obstack, 0);
       new_val = obstack_finish (&muscle_obstack);
-      entry->value = xstrdup (new_val);
+      entry->value = entry->storage = xstrdup (new_val);
       obstack_free (&muscle_obstack, new_val);
     }
 }
       obstack_free (&muscle_obstack, new_val);
     }
 }
@@ -173,6 +185,7 @@ muscle_code_grow (const char *key, const char *val, location loc)
   obstack_1grow (&muscle_obstack, 0);
   extension = obstack_finish (&muscle_obstack);
   muscle_grow (key, extension, "");
   obstack_1grow (&muscle_obstack, 0);
   extension = obstack_finish (&muscle_obstack);
   muscle_grow (key, extension, "");
+  obstack_free (&muscle_obstack, extension);
 }
 
 
 }
 
 
index cffdf1bda84b1ee2d368df59976e835a9b732844..32989bc728dae604a6485eb372522d03155d872e 100644 (file)
@@ -1,5 +1,5 @@
 /* Muscle table manager for Bison,
 /* Muscle table manager for Bison,
-   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
    This file is part of Bison, the GNU Compiler Compiler.
 
@@ -24,8 +24,8 @@
 # include "location.h"
 
 void muscle_init (void);
 # include "location.h"
 
 void muscle_init (void);
-void muscle_insert (const char *key, char *value);
-char *muscle_find (const char *key);
+void muscle_insert (char const *key, char const *value);
+char *muscle_find (char const *key);
 void muscle_free (void);
 
 
 void muscle_free (void);
 
 
index 04265596a1968976255cd6a4a1e5cf738241340e..522540ac905c2d7887186d37265a232f03f96076 100644 (file)
@@ -93,13 +93,13 @@ static int current_prec = 0;
   boundary_set (&@$.end, current_file, 1, 1);
 }
 
   boundary_set (&@$.end, current_file, 1, 1);
 }
 
-/* Only NUMBERS have a value.  */
 %union
 {
   symbol *symbol;
   symbol_list *list;
   int integer;
 %union
 {
   symbol *symbol;
   symbol_list *list;
   int integer;
-  char *chars;
+  char const *chars;
+  char *code;
   assoc assoc;
   uniqstr uniqstr;
   unsigned char character;
   assoc assoc;
   uniqstr uniqstr;
   unsigned char character;
@@ -183,11 +183,12 @@ static int current_prec = 0;
 
 /* braceless is not to be used for rule or symbol actions, as it
    calls translate_code. */
 
 /* braceless is not to be used for rule or symbol actions, as it
    calls translate_code. */
-%type <chars> STRING "{...}" "%{...%}" EPILOGUE braceless content content.opt
+%type <chars> STRING "%{...%}" EPILOGUE braceless content content.opt
+%type <code> "{...}"
 %printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
 %printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
-         STRING
+        STRING
 %printer { fprintf (stderr, "{\n%s\n}", $$); }
 %printer { fprintf (stderr, "{\n%s\n}", $$); }
-         braceless content content.opt "{...}" "%{...%}" EPILOGUE
+        braceless content content.opt "{...}" "%{...%}" EPILOGUE
 
 %type <uniqstr> TYPE ID ID_COLON
 %printer { fprintf (stderr, "<%s>", $$); } TYPE
 
 %type <uniqstr> TYPE ID ID_COLON
 %printer { fprintf (stderr, "<%s>", $$); } TYPE
@@ -267,7 +268,7 @@ grammar_declaration:
       symbol_list *list;
       const char *action = translate_symbol_action ($2, @2);
       for (list = $3; list; list = list->next)
       symbol_list *list;
       const char *action = translate_symbol_action ($2, @2);
       for (list = $3; list; list = list->next)
-        symbol_list_destructor_set (list, action, @2);
+       symbol_list_destructor_set (list, action, @2);
       symbol_list_free ($3);
     }
 | "%printer" "{...}" generic_symlist
       symbol_list_free ($3);
     }
 | "%printer" "{...}" generic_symlist
@@ -275,7 +276,7 @@ grammar_declaration:
       symbol_list *list;
       const char *action = translate_symbol_action ($2, @2);
       for (list = $3; list; list = list->next)
       symbol_list *list;
       const char *action = translate_symbol_action ($2, @2);
       for (list = $3; list; list = list->next)
-        symbol_list_printer_set (list, action, @2);
+       symbol_list_printer_set (list, action, @2);
       symbol_list_free ($3);
     }
 | "%default-prec"
       symbol_list_free ($3);
     }
 | "%default-prec"
index 43073220fcb1d08a8599706cb6d552a19c45e8b8..f2d797204d18e781cefa19113f1bf064df5209fe 100644 (file)
@@ -35,13 +35,13 @@ void code_scanner_free (void);
 
 /* The action of the rule R contains $$, $1 etc. referring to the values
    of the rule R. */
 
 /* The action of the rule R contains $$, $1 etc. referring to the values
    of the rule R. */
-char *translate_rule_action (symbol_list *r);
+char const *translate_rule_action (symbol_list *r);
 
 /* The action A refers to $$ and @$ only, referring to a symbol. */
 
 /* The action A refers to $$ and @$ only, referring to a symbol. */
-char *translate_symbol_action (const char *a, location l);
+char const *translate_symbol_action (char const *a, location l);
 
 /* The action contains no special escapes, just protect M4 special
    symbols.  */
 
 /* The action contains no special escapes, just protect M4 special
    symbols.  */
-char *translate_code (const char *a, location l);
+char const *translate_code (char const *a, location l);
 
 #endif /* !SCAN_CODE_H_ */
 
 #endif /* !SCAN_CODE_H_ */
index d41c6e46043a6c78e5ed45709f97922b66d0b339..6b33e015ecfc367687156b0ea34c9a99da473d5f 100644 (file)
@@ -372,8 +372,8 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
    translation is for \a rule, in the context \a sc_context
    (SC_RULE_ACTION, SC_SYMBOL_ACTION, INITIAL).  */
 
    translation is for \a rule, in the context \a sc_context
    (SC_RULE_ACTION, SC_SYMBOL_ACTION, INITIAL).  */
 
-static char *
-translate_action (int sc_context, symbol_list *rule, const char *a, location l)
+static char const *
+translate_action (int sc_context, symbol_list *rule, char const *a, location l)
 {
   char *res;
   static bool initialized = false;
 {
   char *res;
   static bool initialized = false;
@@ -394,21 +394,21 @@ translate_action (int sc_context, symbol_list *rule, const char *a, location l)
   return res;
 }
 
   return res;
 }
 
-char *
+char const *
 translate_rule_action (symbol_list *rule)
 {
   return translate_action (SC_RULE_ACTION, rule, rule->action,
                           rule->action_location);
 }
 
 translate_rule_action (symbol_list *rule)
 {
   return translate_action (SC_RULE_ACTION, rule, rule->action,
                           rule->action_location);
 }
 
-char *
-translate_symbol_action (const char *a, location l)
+char const *
+translate_symbol_action (char const *a, location l)
 {
   return translate_action (SC_SYMBOL_ACTION, NULL, a, l);
 }
 
 {
   return translate_action (SC_SYMBOL_ACTION, NULL, a, l);
 }
 
-char *
-translate_code (const char *a, location l)
+char const *
+translate_code (char const *a, location l)
 {
   return translate_action (INITIAL, NULL, a, l);
 }
 {
   return translate_action (INITIAL, NULL, a, l);
 }
index 5e595cf6f8b370a994b53638b96e20c463a44479..6fa9f220f3ec5cc9f09f967ca768caf0a4379b30 100644 (file)
@@ -523,7 +523,7 @@ splice       (\\[ \f\t\v]*\n)*
       {
        STRING_FINISH;
        loc->start = code_start;
       {
        STRING_FINISH;
        loc->start = code_start;
-       val->chars = last_string;
+       val->code = last_string;
        BEGIN INITIAL;
        return BRACED_CODE;
       }
        BEGIN INITIAL;
        return BRACED_CODE;
       }
@@ -537,7 +537,7 @@ splice       (\\[ \f\t\v]*\n)*
     unexpected_eof (code_start, "}");
     STRING_FINISH;
     loc->start = code_start;
     unexpected_eof (code_start, "}");
     STRING_FINISH;
     loc->start = code_start;
-    val->chars = last_string;
+    val->code = last_string;
     BEGIN INITIAL;
     return BRACED_CODE;
   }
     BEGIN INITIAL;
     return BRACED_CODE;
   }
index 7cf188aa1d15e3572c88522632e02def3eb9f7b8..b5f5260efbcfe8039c630358146a8c14ba126d31 100644 (file)
@@ -88,6 +88,7 @@ maintainer-check-posix: $(TESTSUITE)
 .PHONY: maintainer-check-valgrind
 maintainer-check-valgrind: $(TESTSUITE)
        test -z '$(VALGRIND)' || \
 .PHONY: maintainer-check-valgrind
 maintainer-check-valgrind: $(TESTSUITE)
        test -z '$(VALGRIND)' || \
+          VALGRIND_OPTS='--leak-check=full --show-reachable=yes' \
           $(TESTSUITE) PREBISON='$(VALGRIND) -q' PREPARSER='$(VALGRIND) -q'
 
 .PHONY: maintainer-check
           $(TESTSUITE) PREBISON='$(VALGRIND) -q' PREPARSER='$(VALGRIND) -q'
 
 .PHONY: maintainer-check
index a3a76feb8dbe028b64e13a1ab5d6fe5807f7d514..2cc68031eb2f516b51a0185d76c141cc0367bf54 100644 (file)
@@ -337,6 +337,7 @@ main (int argc, const char **argv)
 ]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug],
 [  yydebug = 1;])])[
   status = yyparse (]AT_PARAM_IF([&result, &count])[);
 ]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug],
 [  yydebug = 1;])])[
   status = yyparse (]AT_PARAM_IF([&result, &count])[);
+  fclose (input);
   if (global_result != result)
     abort ();
   if (global_count != count)
   if (global_result != result)
     abort ();
   if (global_count != count)
index 10bb3d8949550b8adbcfd035c4173e60a0386f1e..bd5e11694a11f89ad2762ce02912f49c5e6069eb 100644 (file)
@@ -1,7 +1,7 @@
-# Process this file with autom4te to create testsuite. -*- Autotest -*-
+# Test suite for GNU Bison.                            -*- Autotest -*-
 
 
-# Test suite for GNU Bison.
-# Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 Free Software
+# Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # 02110-1301, USA.
 
 
 # 02110-1301, USA.
 
 
+# Bison often leaks memory when its exit status is non-zero, so set
+# --leak-check=summary for Valgrind in that case.
+m4_pushdef([ORIGINAL_AT_CHECK], m4_defn([AT_CHECK]))
+m4_pushdef([AT_CHECK],
+[ORIGINAL_AT_CHECK(
+   m4_if(m4_quote(m4_substr(m4_quote($1), 0, 5)), [bison],
+        m4_if([$2], [0], [],
+              [[VALGRIND_OPTS="$VALGRIND_OPTS --leak-check=summary --show-reachable=no"; export VALGRIND_OPTS; ]]))$@)])
+
 # Testing resistance to user bugs.
 m4_include([input.at])
 
 # Testing resistance to user bugs.
 m4_include([input.at])
 
@@ -64,3 +73,6 @@ m4_include([c++.at])
 m4_include([cxx-type.at])
 # Regression tests
 m4_include([glr-regression.at])
 m4_include([cxx-type.at])
 # Regression tests
 m4_include([glr-regression.at])
+
+m4_popdef([AT_CHECK])
+m4_popdef([ORIGINAL_AT_CHECK])