From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10462 invoked by alias); 21 Sep 2010 19:08:30 -0000 Received: (qmail 10453 invoked by uid 22791); 21 Sep 2010 19:08:29 -0000 X-SWARE-Spam-Status: No, hits=0.3 required=5.0 tests=AWL,BAYES_50,RCVD_IN_DNSWL_NONE,RCVD_IN_RP_RNBL,TW_WT X-Spam-Check-By: sourceware.org Received: from smtp-102-tuesday.noc.nerim.net (HELO mallaury.nerim.net) (62.4.17.102) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 21 Sep 2010 19:08:23 +0000 Received: from hector.lesours (ours.starynkevitch.net [213.41.244.95]) by mallaury.nerim.net (Postfix) with ESMTPS id DCFBBA104D; Tue, 21 Sep 2010 21:08:19 +0200 (CEST) Received: from glinka.lesours ([192.168.0.1] helo=glinka) by hector.lesours with smtp (Exim 4.72) (envelope-from ) id 1Oy8CR-0008F9-Hr; Tue, 21 Sep 2010 21:08:19 +0200 Date: Tue, 21 Sep 2010 22:07:00 -0000 From: Basile Starynkevitch To: Basile Starynkevitch Cc: gcc-patches@gcc.gnu.org Subject: gengtype improvements for plugins, thirdround! patch 2/7 [verbosity] Message-Id: <20100921210829.5f2ea8b0.basile@starynkevitch.net> In-Reply-To: <20100921210301.d92889be.basile@starynkevitch.net> References: <20100921210301.d92889be.basile@starynkevitch.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Multipart=_Tue__21_Sep_2010_21_08_29_+0200_vsgfuNKYnPclJRL3" X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2010-09/txt/msg01727.txt.bz2 This is a multi-part message in MIME format. --Multipart=_Tue__21_Sep_2010_21_08_29_+0200_vsgfuNKYnPclJRL3 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-length: 3127 Hello All, [join work by Basile Starynkevitch & Jeremie Salvucci] References: http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02060.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00616.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00663.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg01702.html The second piece [verbosity] of our serie of patches adds verbosity to gengtype. The gengtype user (either a plugin developer or a true GCC hacker) can pass the -v program flag. This flag can even be passed more than once, to increase the verbosity level. Verbose messages explain succintly to the user what gengtype is actually doing. We feel this functionality is useful for plugin developpers (who might not understand what gengtype is doing today, since it is essentially silent) and even for GCC hackers. We did took into account Laurynas comments from http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00210.html In addition of verbose messages, we added a tiny but useful feature to gengtype. When given a backup directory thru the -B program option and when it is generating a file gt-foo.h, gengtype renames the old version into the backup directory so that the user could compare the old version with the current one. Verbosity & backing up of old files go together (in verbose mode, the renaming is told to the user). Backing up is no longer by default. Per Laurynas' wish, it should be enabled by its program option. Some existing functions has been slightly improved, for instance to count the number of GTY-ed variables. The verbosity_level variable needs to be global. It will be used in file gengtype-state.c. The attached patch is relative to the previous patch 1 [declprog] sent in http://gcc.gnu.org/ml/gcc-patches/2010-09/msg01702.html This relative patch was obtained with diff -u -p -N $(svn stat | awk '/[AM]/{print $2}') \ --from-file ../thirdround_01_declprog/ > \ $HOME/Gengtype_Thirdround/patch2_verbosity-relto01.diff I am also attaching the gzipped cumulated patches against trunk 164437 as file cumulatedpatch2_verbosity__gengtypethird_r164437.diff.gz ###################################### gcc/ChangeLog entry [of the relative patch] 2010-09-20 Jeremie Salvucci Basile Starynkevitch * gengtype.c (verbosity_level, backup_dir): Added variables. (set_gc_used): Count variables for verbosity. (close_output_files): Backing up files, counting written ones verbosily. (write_types): Count emitted functions for verbosity. Added debug messages. (write_enum_defn): Count structures for verbosity. Added debug messages. (gengtype_long_options): Added "verbose". (print_usage): Ditto. (main): Verbose display of parsed files. * gengtype.h (verbosity_level): Added declaration. ##################################################### Ok for trunk? -- Basile STARYNKEVITCH http://starynkevitch.net/Basile/ email: basilestarynkevitchnet mobile: +33 6 8501 2359 8, rue de la Faiencerie, 92340 Bourg La Reine, France *** opinions {are only mine, sont seulement les miennes} *** --Multipart=_Tue__21_Sep_2010_21_08_29_+0200_vsgfuNKYnPclJRL3 Content-Type: text/x-diff; name="patch2_verbosity-relto01.diff" Content-Disposition: attachment; filename="patch2_verbosity-relto01.diff" Content-Transfer-Encoding: 7bit Content-length: 10316 --- ../thirdround_01_declprog//gengtype.c 2010-09-20 21:36:24.000000000 +0200 +++ gcc/gengtype.c 2010-09-20 22:35:07.000000000 +0200 @@ -158,6 +158,15 @@ const char *write_state_filename; int do_dump; int do_debug; +/* For verbose messages to the user. */ +int verbosity_level; + +/* The backup directory should be in the same file-system as the + generated files, otherwise the rename(2) system call would fail. + If NULL, no backup is made when overwriting a generated file. */ +static const char* backup_dir; + + static outf_p create_file (const char *, const char *); static const char * get_file_basename (const char *); @@ -1511,8 +1520,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 @@ -1901,26 +1917,56 @@ 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)) - { - FILE *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)); - } + if (!is_file_equal (of)) + { + FILE *newfile = NULL; + char *backupname = NULL; + /* Backup the old version of the output file gt-FOO.c as + BACKUPDIR/gt-FOO.c~ if we have a backup directory. */ + if (backup_dir) + { + backupname = concat (backup_dir, "/", + lbasename (of->name), "~", NULL); + if (!access (of->name, F_OK) && rename (of->name, backupname)) + fatal ("failed to backup %s as %s: %s", + of->name, backupname, xstrerror (errno)); + } + 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 && backupname) + 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); + if (backupname) + 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; @@ -2800,6 +2846,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 @@ -2894,11 +2941,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) { @@ -2910,11 +2972,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 = @@ -3108,27 +3186,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 & %d parameterized structures.\n", + progname, nbstruct, nbparamstruct); } /* Might T contain any non-pointer elements? */ @@ -4273,17 +4368,19 @@ dump_everything (void) /* Option specification for getopt_long. */ static const struct option gengtype_long_options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'V' }, - { "dump", no_argument, NULL, 'd' }, - { "debug", no_argument, NULL, 'D' }, - { "plugin", required_argument, NULL, 'P' }, - { "srcdir", required_argument, NULL, 'S' }, - { "inputs", required_argument, NULL, 'I' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { "verbose", no_argument, NULL, 'v' }, + { "dump", no_argument, NULL, 'd' }, + { "debug", no_argument, NULL, 'D' }, + { "plugin", required_argument, NULL, 'P' }, + { "srcdir", required_argument, NULL, 'S' }, + { "backupdir", required_argument, NULL, 'B' }, + { "inputs", required_argument, NULL, 'I' }, { "read-state", required_argument, NULL, 'r' }, - { "write-state", required_argument, NULL, 'w' }, + { "write-state", required_argument, NULL, 'w' }, /* Terminating NULL placeholder. */ - { NULL, no_argument, NULL, 0 }, + { NULL, no_argument, NULL, 0 }, }; @@ -4298,12 +4395,16 @@ print_usage (void) progname); printf ("\t -V | --version " " \t# Give version information.\n"); + printf ("\t -v | --verbose " + " \t# Increase verbosity. Can be given several times.\n"); printf ("\t -d | --dump " " \t# Dump state for debugging.\n"); printf ("\t -P | --plugin ... " " \t# Generate for plugin.\n"); printf ("\t -S | --srcdir " " \t# Specify the GCC source directory.\n"); + printf ("\t -B | --backupdir " + " \t# Specify the backup directory for updated files.\n"); printf ("\t -I | --inputs " " \t# Specify the file with source files list.\n"); printf ("\t -w | --write-state " @@ -4324,7 +4425,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:B:I:w:r:D", gengtype_long_options, NULL)) >= 0) { switch (opt) @@ -4332,6 +4433,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; @@ -4354,6 +4458,13 @@ parse_program_options (int argc, char**a fatal ("missing source directory"); srcdir_len = strlen (srcdir); break; + case 'B': /* --backupdir */ + if (optarg) + srcdir = optarg; + else + fatal ("missing backup directory"); + srcdir_len = strlen (srcdir); + break; case 'I': /* --inputs */ if (optarg) inputlist = optarg; @@ -4452,6 +4563,8 @@ 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 --- ../thirdround_01_declprog//gengtype.h 2010-09-20 21:12:46.000000000 +0200 +++ gcc/gengtype.h 2010-09-20 22:03:42.000000000 +0200 @@ -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; --Multipart=_Tue__21_Sep_2010_21_08_29_+0200_vsgfuNKYnPclJRL3 Content-Type: application/octet-stream; name="cumulatedpatch2_verbosity-gengtypethird-r164437.diff.gz" Content-Disposition: attachment; filename="cumulatedpatch2_verbosity-gengtypethird-r164437.diff.gz" Content-Transfer-Encoding: base64 Content-length: 11375 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 xLAoMvSANExm/geO/CZGJXAAAA== --Multipart=_Tue__21_Sep_2010_21_08_29_+0200_vsgfuNKYnPclJRL3--