mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-13 06:13:02 +00:00
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.
This commit is contained in:
80
src/files.c
80
src/files.c
@@ -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_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;
|
||||
@@ -72,14 +72,14 @@ uniqstr current_file = NULL;
|
||||
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). */
|
||||
static char const *src_extension = NULL;
|
||||
static char *src_extension = NULL;
|
||||
/* Header file extension (if option ``-d'' is specified). */
|
||||
static char const *header_extension = NULL;
|
||||
static char *header_extension = NULL;
|
||||
|
||||
/*-----------------------------------------------------------------.
|
||||
| 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. |
|
||||
`------------------------------------------------------------------*/
|
||||
|
||||
/* 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 *
|
||||
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)
|
||||
{
|
||||
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. */
|
||||
@@ -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);
|
||||
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'. */
|
||||
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'. */
|
||||
dir_prefix = "";
|
||||
dir_prefix = xstrdup ("");
|
||||
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)
|
||||
src_extension = ".c";
|
||||
src_extension = xstrdup (".c");
|
||||
if (!header_extension)
|
||||
header_extension = ".h";
|
||||
header_extension = xstrdup (".h");
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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]));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user