@@ -158,6 +158,10 @@ char *write_state_filename;
int do_dump;
int do_debug;
+/* For verbose messages to the user. */
+int verbosity_level;
+
+
static outf_p create_file (const char *, const char *);
static const char * get_file_basename (const char *);
@@ -1507,8 +1511,15 @@ static void
set_gc_used (pair_p variables)
{
pair_p p;
+ int nbvars = 0;
for (p = variables; p; p = p->next)
+ {
+ DBGPRINTF ("set_gc_used p %p '%s' nbvars %d", (void*) p, p->name, nbvars);
set_gc_used_type (p->type, GC_USED, NULL);
+ nbvars++;
+ };
+ if (verbosity_level >= 2)
+ printf ("%s used %d GTY-ed variables\n", progname, nbvars);
}
/* File mapping routines. For each input file, there is one output .c file
@@ -1897,26 +1908,46 @@ static void
close_output_files (void)
{
outf_p of;
+ int nbwrittenfiles = 0;
for (of = output_files; of; of = of->next)
{
- if (!is_file_equal(of))
+ if (!is_file_equal (of))
{
- FILE *newfile = fopen (of->name, "w");
+ FILE *newfile = NULL;
+ char *backupname = concat (of->name, "~", NULL);
+ int renamingfailed = rename (of->name, backupname);
+ newfile = fopen (of->name, "w");
if (newfile == NULL)
fatal ("opening output file %s: %s", of->name, xstrerror (errno));
if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
fatal ("writing output file %s: %s", of->name, xstrerror (errno));
if (fclose (newfile) != 0)
fatal ("closing output file %s: %s", of->name, xstrerror (errno));
+ nbwrittenfiles++;
+ if (verbosity_level >= 2 && !renamingfailed)
+ printf ("%s wrote #%-3d %s backed-up in %s\n",
+ progname, nbwrittenfiles, of->name, backupname);
+ else if (verbosity_level >= 1)
+ printf ("%s wrote #%-3d %s\n", progname, nbwrittenfiles, of->name);
+ free (backupname);
+ }
+ else
+ {
+ /* Output file remains unchanged! */
+ if (verbosity_level >= 2)
+ printf ("%s kept %s\n", progname, of->name);
}
free(of->buf);
of->buf = NULL;
of->bufused = of->buflength = 0;
}
+ if (verbosity_level >= 1)
+ printf ("%s wrote %d files.\n", progname, nbwrittenfiles);
}
+
struct flist {
struct flist *next;
int started_p;
@@ -2796,6 +2827,7 @@ write_types (outf_p output_header, type_
const struct write_types_data *wtd)
{
type_p s;
+ int nbfun = 0; /* Count the emitted functions. */
oprintf (output_header, "\n/* %s*/\n", wtd->comment);
/* We first emit the macros and the declarations. Functions' code is
@@ -2890,11 +2922,26 @@ write_types (outf_p output_header, type_
{
type_p ss;
for (ss = s->u.s.lang_struct; ss; ss = ss->next)
+ {
+ nbfun++;
+ DBGPRINTF ("writing func #%d lang_struct ss @ %p '%s'",
+ nbfun, (void*) ss, ss->u.s.tag);
write_func_for_structure (s, ss, NULL, wtd);
}
+ }
else
+ {
+ nbfun++;
+ DBGPRINTF ("writing func #%d struct s @ %p '%s'",
+ nbfun, (void*) s, s->u.s.tag);
write_func_for_structure (s, s, NULL, wtd);
}
+ }
+ else
+ DBGPRINTF ("ignored s @ %p '%s' gc_used#%d",
+ (void*)s, s->u.s.tag,
+ (int) s->gc_used);
+
for (s = param_structs; s; s = s->next)
if (s->gc_used == GC_POINTED_TO)
{
@@ -2906,11 +2953,27 @@ write_types (outf_p output_header, type_
{
type_p ss;
for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
+ {
+ nbfun++;
+ DBGPRINTF ("writing func #%d param lang_struct ss @ %p '%s'",
+ nbfun, (void*) ss, ss->u.s.tag);
write_func_for_structure (s, ss, param, wtd);
}
+ }
else
+ {
+ nbfun++;
+ DBGPRINTF ("writing func #%d param struct s @ %p stru @ %p '%s'",
+ nbfun, (void*) s,
+ (void*) stru, stru->u.s.tag);
write_func_for_structure (s, stru, param, wtd);
}
+ }
+ else
+ DBGPRINTF ("ignored s @ %p", (void*)s);
+ if (verbosity_level >= 2)
+ printf ("%s emitted %d routines for %s\n",
+ progname, nbfun, wtd->comment);
}
static const struct write_types_data ggc_wtd =
@@ -3104,27 +3167,44 @@ static void
write_enum_defn (type_p structures, type_p param_structs)
{
type_p s;
+ int nbstruct = 0;
+ int nbparamstruct = 0;
if (!header_file)
return;
oprintf (header_file, "\n/* Enumeration of types known. */\n");
oprintf (header_file, "enum gt_types_enum {\n");
+
for (s = structures; s; s = s->next)
if (USED_BY_TYPED_GC_P (s))
{
+ DBGPRINTF("write_enum_defn s @ %p nbstruct %d",
+ (void*) s, nbstruct);
+ if (UNION_OR_STRUCT_P (s))
+ DBGPRINTF ("write_enum_defn s %p #%d is unionorstruct tagged %s",
+ (void*) s, nbstruct, s->u.s.tag);
oprintf (header_file, " gt_ggc_e_");
output_mangled_typename (header_file, s);
oprintf (header_file, ",\n");
+ nbstruct++;
}
+
for (s = param_structs; s; s = s->next)
if (s->gc_used == GC_POINTED_TO)
{
+ DBGPRINTF ("write_enum_defn s %p nbparamstruct %d",
+ (void*) s, nbparamstruct);
oprintf (header_file, " gt_e_");
output_mangled_typename (header_file, s);
oprintf (header_file, ",\n");
+ nbparamstruct++;
}
+
oprintf (header_file, " gt_types_enum_last\n");
oprintf (header_file, "};\n");
+ if (verbosity_level >= 2)
+ printf("%s handled %d GTY-ed structures and %d parameterized structures.\n",
+ progname, nbstruct, nbparamstruct);
}
/* Might T contain any non-pointer elements? */
@@ -4271,6 +4351,7 @@ dump_everything (void)
static const struct option gengtype_long_options[] =
{
{ "help", no_argument, NULL, 'h' },
+ { "verbose", no_argument, NULL, 'v' },
{ "version", no_argument, NULL, 'V' },
{ "dump", no_argument, NULL, 'd' },
{ "debug", no_argument, NULL, 'D' },
@@ -4288,6 +4369,7 @@ print_usage (void)
{
printf ("Usage: %s\n", progname);
printf ("\t -h | --help \t# Give this help.\n");
+ printf ("\t -v | --verbose \t# Increase verbosity. Can be given several times.\n");
printf ("\t -D | --debug \t# Give lots of debug output to debug %s itself.\n", progname);
printf ("\t -V | --version \t# Give version information.\n");
printf ("\t -d | --dump \t# Dump state for debugging.\n");
@@ -4310,7 +4392,7 @@ static void
parse_program_options (int argc, char**argv)
{
int opt = -1;
- while ((opt = getopt_long (argc, argv, "hVdP:S:I:w:r:D",
+ while ((opt = getopt_long (argc, argv, "hvVdP:S:I:w:r:D",
gengtype_long_options, NULL)) >= 0)
{
switch (opt)
@@ -4318,6 +4400,9 @@ parse_program_options (int argc, char**a
case 'h': /* --help */
print_usage ();
break;
+ case 'v': /* --verbose */
+ verbosity_level++;
+ break;
case 'V': /* --version */
print_version ();
break;
@@ -4437,6 +4522,9 @@ main (int argc, char **argv)
}
DBGPRINT_COUNT_TYPE ("structures after parsing", structures);
DBGPRINT_COUNT_TYPE ("param_structs after parsing", param_structs);
+ if (verbosity_level >= 1)
+ printf ("%s parsed %d files\n",
+ progname, (int) num_gt_files);
}
else
@@ -154,6 +154,9 @@ enum {
FIRST_TOKEN_WITH_VALUE = PARAM_IS
};
+/* Level for verbose messages. Gengtype tells something to its user
+ when it is positive, and tells more if it is greater. */
+extern int verbosity_level;
/* For debugging purposes of gengtype itself! */
extern int do_dump;