Whilst learning the internals of the GTY code I noticed that gtype.state's s-expressions are all aligned to the left-hand margin.
The following patch to gengtype-state.c rewrites how they are written out to introduce indentation, showing the nesting structure of the s-expressions, which makes the generated gtype.state file somewhat more human-readable (to this human, at least). You can see before/after gtype.state files here: Before the patch: http://dmalcolm.fedorapeople.org/gcc/2013-05-03/gtype.state.old.txt After the patch: http://dmalcolm.fedorapeople.org/gcc/2013-05-03/gtype.state.new.txt Comparison with "diff -b" shows that it only contains whitespace changes, which read_a_state_token () ignores. Successfully bootstrapped against gcc-4.7.2-2.fc17.x86_64 --- gcc/ChangeLog | 40 +++++++++++ gcc/gengtype-state.c | 198 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 193 insertions(+), 45 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cafda6e..9c9ce2a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,43 @@ +2013-05-03 David Malcolm <dmalc...@redhat.com> + + * gengtype-state.c: (indent_amount): New variable, + (had_recent_newline): likewise + (write_new_line): New function + (write_any_indent): likewise + (write_open_paren): likewise + (write_close_paren): likewise + (write_state_fileloc): Use the new functions above to write + indentation into the gtype.state output file to visually represent + the hierarchical structure of the list structures + (write_state_fields): ditto + (write_state_a_string): ditto + (write_state_string_option): ditto + (write_state_type_option): ditto + (write_state_nested_option): ditto + (write_state_option): ditto + (write_state_options): ditto + (write_state_lang_bitmap): ditto + (write_state_version): ditto + (write_state_scalar_type): ditto + (write_state_string_type): ditto + (write_state_undefined_type): ditto + (write_state_struct_union_type): ditto + (write_state_user_struct_type): ditto + (write_state_lang_struct_type): ditto + (write_state_param_struct_type): ditto + (write_state_pointer_type): ditto + (write_state_array_type): ditto + (write_state_gc_used): ditto + (write_state_type): ditto + (write_state_pair): ditto + (write_state_typedefs): ditto + (write_state_structures): ditto + (write_state_param_structs): ditto + (write_state_variables): ditto + (write_state_variables): ditto + (write_state_files_list): ditto + (write_state_languages): ditto + 2013-05-02 David Malcolm <dmalc...@redhat.com> * testsuite/gcc.dg/plugin/one_time_plugin.c (one_pass_gate): example diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c index 6092dad..86fa8aa 100644 --- a/gcc/gengtype-state.c +++ b/gcc/gengtype-state.c @@ -141,6 +141,57 @@ static long state_bol = 0; /* offset of beginning of line */ /* Counter of written types. */ static int state_written_type_count = 0; +static int indent_amount = 0; +static int had_recent_newline = 0; + +static void +write_new_line (void) +{ + /* don't add a newline if we've just had one */ + if (!had_recent_newline) + { + fprintf (state_file, "\n"); + had_recent_newline = 1; + } +} + +/* + If we've just had a newline, write the indentation amount, + potentially modified. + + The modifier exists to support code that writes strings with leading + space (e.g " foo") which might occur within a line, or could be the first + thing on a line. By passing a modifier of -1, when such a string is the + first thing on a line, the modifier swallows the leading space into the + indentation, and all the fields line up correctly. +*/ +static void +write_any_indent (int modifier) +{ + int i; + if (had_recent_newline) + for (i = 0; i < indent_amount + modifier; i++) + fprintf (state_file, " "); + had_recent_newline = 0; +} + +static void +write_open_paren (const char *tag) +{ + write_new_line (); + write_any_indent (0); + fprintf (state_file, "(!%s ", tag); + indent_amount++; +} + +static void +write_close_paren (void) +{ + indent_amount--; + write_any_indent (0); + fprintf (state_file, ")"); + write_new_line (); +} /* Fatal error messages when reading the state. They are extremely unlikely, and only appear when this gengtype-state.c file is buggy, @@ -565,16 +616,16 @@ write_state_fileloc (struct fileloc *floc) srcrelpath = get_file_srcdir_relative_path (floc->file); if (srcrelpath != NULL) { - fprintf (state_file, "\n(!srcfileloc "); + write_open_paren ("srcfileloc"); write_state_a_string (srcrelpath); } else { - fprintf (state_file, "\n(!fileloc "); + write_open_paren ("fileloc"); write_state_a_string (get_input_file_name (floc->file)); } fprintf (state_file, " %d", floc->line); - fprintf (state_file, ")\n"); + write_close_paren (); /* "(!srcfileloc" or "(!fileloc" */ } else fprintf (state_file, "nil "); @@ -586,10 +637,11 @@ write_state_fields (pair_p fields) { int nbfields = pair_list_length (fields); int nbpairs = 0; - fprintf (state_file, "\n(!fields %d ", nbfields); + write_open_paren ("fields"); + fprintf (state_file, "%d ", nbfields); nbpairs = write_state_pair_list (fields); gcc_assert (nbpairs == nbfields); - fprintf (state_file, ")\n"); + write_close_paren (); /* (!fields */ } /* Write a null-terminated string in our lexical convention, very @@ -599,6 +651,8 @@ write_state_a_string (const char *s) { char c; + write_any_indent (-1); + fputs (" \"", state_file); for (; *s != 0; s++) { @@ -646,6 +700,7 @@ write_state_a_string (const char *s) static void write_state_string_option (options_p current) { + write_any_indent (0); fprintf (state_file, "string "); if (current->info.string != NULL) write_state_a_string (current->info.string); @@ -656,6 +711,7 @@ write_state_string_option (options_p current) static void write_state_type_option (options_p current) { + write_any_indent (0); fprintf (state_file, "type "); write_state_type (current->info.type); } @@ -663,24 +719,32 @@ write_state_type_option (options_p current) static void write_state_nested_option (options_p current) { + write_any_indent (0); fprintf (state_file, "nested "); write_state_type (current->info.nested->type); if (current->info.nested->convert_from != NULL) write_state_a_string (current->info.nested->convert_from); else - fprintf (state_file, " nil "); + { + write_any_indent (-1); + fprintf (state_file, " nil "); + } if (current->info.nested->convert_to != NULL) write_state_a_string (current->info.nested->convert_to); else - fprintf (state_file, " nil "); + { + write_any_indent (-1); + fprintf (state_file, " nil "); + } } static void write_state_option (options_p current) { - fprintf (state_file, "\n(!option "); + write_open_paren ("option"); + write_any_indent (0); if (current->name != NULL) fprintf (state_file, "%s ", current->name); else @@ -701,7 +765,7 @@ write_state_option (options_p current) fatal ("Option tag unknown"); } - fprintf (state_file, ")\n"); + write_close_paren (); /* (!option */ } @@ -714,14 +778,15 @@ write_state_options (options_p opt) if (opt == NULL) { - fprintf (state_file, "nil "); + write_any_indent (0); + fprintf (state_file, "nil "); return; } - fprintf (state_file, "\n(!options "); + write_open_paren ("options"); for (current = opt; current != NULL; current = current->next) write_state_option (current); - fprintf (state_file, ")\n"); + write_close_paren (); /* (!options */ } @@ -729,16 +794,17 @@ write_state_options (options_p opt) static void write_state_lang_bitmap (lang_bitmap bitmap) { - fprintf (state_file, "%d ", (int) bitmap); + write_any_indent (0); + fprintf (state_file, "%d ", (int) bitmap); } /* Write version information. */ static void write_state_version (const char *version) { - fprintf (state_file, "\n(!version "); + write_open_paren ("version"); write_state_a_string (version); - fprintf (state_file, ")\n"); + write_close_paren (); /* (!version */ } /* Common routine to write the common content of all types. */ @@ -748,6 +814,7 @@ static void write_state_common_type_content (type_p current); static void write_state_scalar_type (type_p current) { + write_any_indent (0); if (current == &scalar_nonchar) fprintf (state_file, "scalar_nonchar "); else if (current == &scalar_char) @@ -764,6 +831,7 @@ write_state_string_type (type_p current) { if (current == &string_type) { + write_any_indent (0); fprintf (state_file, "string "); write_state_common_type_content (current); } @@ -777,13 +845,17 @@ write_state_undefined_type (type_p current) { DBGPRINTF ("undefined type @ %p #%d '%s'", (void *) current, current->state_number, current->u.s.tag); + write_any_indent (0); fprintf (state_file, "undefined "); gcc_assert (current->gc_used == GC_UNUSED); write_state_common_type_content (current); if (current->u.s.tag != NULL) write_state_a_string (current->u.s.tag); else - fprintf (state_file, "nil"); + { + write_any_indent (0); + fprintf (state_file, "nil"); + } write_state_fileloc (type_lineloc (current)); } @@ -795,12 +867,16 @@ write_state_struct_union_type (type_p current, const char *kindstr) { DBGPRINTF ("%s type @ %p #%d '%s'", kindstr, (void *) current, current->state_number, current->u.s.tag); + write_any_indent (0); fprintf (state_file, "%s ", kindstr); write_state_common_type_content (current); if (current->u.s.tag != NULL) write_state_a_string (current->u.s.tag); else - fprintf (state_file, "nil"); + { + write_any_indent (0); + fprintf (state_file, "nil"); + } write_state_fileloc (type_lineloc (current)); write_state_fields (current->u.s.fields); @@ -823,12 +899,16 @@ write_state_user_struct_type (type_p current) { DBGPRINTF ("user_struct type @ %p #%d '%s'", (void *) current, current->state_number, current->u.s.tag); + write_any_indent (0); fprintf (state_file, "user_struct "); write_state_common_type_content (current); if (current->u.s.tag != NULL) write_state_a_string (current->u.s.tag); else - fprintf (state_file, "nil"); + { + write_any_indent (0); + fprintf (state_file, "nil"); + } write_state_fileloc (type_lineloc (current)); write_state_fields (current->u.s.fields); } @@ -869,10 +949,11 @@ write_state_lang_struct_type (type_p current) homoname = hty->u.s.tag; gcc_assert (strcmp (homoname, hty->u.s.tag) == 0); } - fprintf (state_file, "(!homotypes %d\n", nbhomontype); + write_open_paren ("homotypes"); + fprintf (state_file, "%d", nbhomontype); for (hty = current->u.s.lang_struct; hty != NULL; hty = hty->next) write_state_type (hty); - fprintf (state_file, ")\n"); + write_close_paren (); /* (!homotypes */ } /* Write a parametrized structure GTY type. */ @@ -881,6 +962,7 @@ write_state_param_struct_type (type_p current) { int i; + write_any_indent (0); fprintf (state_file, "param_struct "); write_state_common_type_content (current); write_state_type (current->u.param_struct.stru); @@ -889,7 +971,10 @@ write_state_param_struct_type (type_p current) if (current->u.param_struct.param[i] != NULL) write_state_type (current->u.param_struct.param[i]); else + { + write_any_indent (0); fprintf (state_file, "nil "); + } } write_state_fileloc (¤t->u.param_struct.line); } @@ -898,6 +983,7 @@ write_state_param_struct_type (type_p current) static void write_state_pointer_type (type_p current) { + write_any_indent (0); fprintf (state_file, "pointer "); write_state_common_type_content (current); write_state_type (current->u.p); @@ -907,13 +993,18 @@ write_state_pointer_type (type_p current) static void write_state_array_type (type_p current) { + write_any_indent (0); fprintf (state_file, "array "); write_state_common_type_content (current); if (current->u.a.len != NULL) write_state_a_string (current->u.a.len); else - fprintf (state_file, " nil"); + { + write_any_indent (-1); + fprintf (state_file, " nil"); + } + write_any_indent (-1); fprintf (state_file, " "); write_state_type (current->u.a.p); } @@ -922,6 +1013,7 @@ write_state_array_type (type_p current) static void write_state_gc_used (enum gc_used_enum gus) { + write_any_indent (-1); switch (gus) { case GC_UNUSED: @@ -946,6 +1038,7 @@ write_state_gc_used (enum gc_used_enum gus) static void write_state_common_type_content (type_p current) { + write_any_indent (0); fprintf (state_file, "%d ", current->state_number); /* We do not write the next type, because list of types are explicitly written. However, lang_struct are special in that @@ -961,16 +1054,20 @@ write_state_common_type_content (type_p current) static void write_state_type (type_p current) { + write_any_indent (0); if (current == NULL) { fprintf (state_file, "nil "); return; } - fprintf (state_file, "\n(!type "); + write_open_paren ("type"); if (current->state_number > 0) - fprintf (state_file, "already_seen %d", current->state_number); + { + write_any_indent (0); + fprintf (state_file, "already_seen %d", current->state_number); + } else { state_written_type_count++; @@ -1014,7 +1111,7 @@ write_state_type (type_p current) } } - fprintf (state_file, ")\n"); + write_close_paren (); /* (!type */ } @@ -1024,11 +1121,12 @@ write_state_pair (pair_p current) { if (current == NULL) { + write_any_indent (0); fprintf (state_file, "nil)"); return; } - fprintf (state_file, "\n(!pair "); + write_open_paren ("pair"); if (current->name != NULL) write_state_a_string (current->name); @@ -1038,8 +1136,7 @@ write_state_pair (pair_p current) write_state_type (current->type); write_state_fileloc (&(current->line)); write_state_options (current->opt); - - fprintf (state_file, ")"); + write_close_paren (); /* (!pair */ } /* Write a pair list and return the number of pairs written. */ @@ -1069,10 +1166,11 @@ write_state_typedefs (void) { int nbtypedefs = pair_list_length (typedefs); int nbpairs = 0; - fprintf (state_file, "\n(!typedefs %d\n", nbtypedefs); + write_open_paren ("typedefs"); + fprintf (state_file, "%d", nbtypedefs); nbpairs = write_state_pair_list (typedefs); gcc_assert (nbpairs == nbtypedefs); - fprintf (state_file, ")\n"); + write_close_paren (); /* (!typedefs */ if (verbosity_level >= 2) printf ("%s wrote %d typedefs\n", progname, nbtypedefs); } @@ -1087,12 +1185,16 @@ write_state_structures (void) for (current = structures; current != NULL; current = current->next) nbstruct++; - fprintf (state_file, "\n(!structures %d\n", nbstruct); + write_open_paren ("structures"); + fprintf (state_file, "%d", nbstruct); for (current = structures; current != NULL; current = current->next) - write_state_type (current); + { + write_new_line (); + write_state_type (current); + } - fprintf (state_file, ")\n"); + write_close_paren (); /* (!structures */ if (verbosity_level >= 2) printf ("%s wrote %d structures in state\n", progname, nbstruct); } @@ -1107,12 +1209,13 @@ write_state_param_structs (void) for (current = param_structs; current != NULL; current = current->next) nbparamstruct++; - fprintf (state_file, "\n(!param_structs %d\n", nbparamstruct); + write_open_paren ("param_structs"); + fprintf (state_file, "%d", nbparamstruct); for (current = param_structs; current != NULL; current = current->next) write_state_type (current); - fprintf (state_file, ")\n"); + write_close_paren (); /* (!param_structs */ } /* Write our variables. */ @@ -1121,10 +1224,11 @@ write_state_variables (void) { int nbvars = pair_list_length (variables); int nbpairs = 0; - fprintf (state_file, "\n(!variables %d\n", nbvars); + write_open_paren ("variables"); + fprintf (state_file, "%d", nbvars); nbpairs = write_state_pair_list (variables); gcc_assert (nbpairs == nbvars); - fprintf (state_file, ")\n"); + write_close_paren (); /* (!variables */ if (verbosity_level >= 2) printf ("%s wrote %d variables.\n", progname, nbvars); } @@ -1134,9 +1238,9 @@ write_state_variables (void) static void write_state_srcdir (void) { - fprintf (state_file, "\n(!srcdir "); + write_open_paren ("srcdir"); write_state_a_string (srcdir); - fprintf (state_file, ")\n"); + write_close_paren (); /* (!srcdir */ } /* Count and write the list of our files. */ @@ -1145,7 +1249,8 @@ write_state_files_list (void) { int i = 0; /* Write the list of files with their lang_bitmap. */ - fprintf (state_file, "\n(!fileslist %d\n", (int) num_gt_files); + write_open_paren ("fileslist"); + fprintf (state_file, "%d", (int) num_gt_files); for (i = 0; i < (int) num_gt_files; i++) { const char *cursrcrelpath = NULL; @@ -1155,17 +1260,19 @@ write_state_files_list (void) cursrcrelpath = get_file_srcdir_relative_path (curfil); if (cursrcrelpath) { - fprintf (state_file, "(!srcfile %d ", get_lang_bitmap (curfil)); + write_open_paren ("srcfile"); + fprintf (state_file, "%d ", get_lang_bitmap (curfil)); write_state_a_string (cursrcrelpath); } else { - fprintf (state_file, "(!file %d ", get_lang_bitmap (curfil)); + write_open_paren ("file"); + fprintf (state_file, "%d ", get_lang_bitmap (curfil)); write_state_a_string (get_input_file_name (curfil)); } - fprintf (state_file, ")\n"); + write_close_paren (); /* (!srcfile or (!file */ } - fprintf (state_file, ")\n"); + write_close_paren (); /* (!fileslist */ } /* Write the list of GCC front-end languages. */ @@ -1173,7 +1280,8 @@ static void write_state_languages (void) { int i = 0; - fprintf (state_file, "\n(!languages %d", (int) num_lang_dirs); + write_open_paren ("languages"); + fprintf (state_file, "%d", (int) num_lang_dirs); for (i = 0; i < (int) num_lang_dirs; i++) { /* Languages names are identifiers, we expect only letters or @@ -1181,7 +1289,7 @@ write_state_languages (void) valid language name, but cp is valid. */ fprintf (state_file, " %s", lang_dir_names[i]); } - fprintf (state_file, ")\n"); + write_close_paren (); /* (!languages */ } /* Write the trailer. */ -- 1.7.11.7