@@ -33,6 +33,36 @@ bool windows_platform = false;
3333bool dry_run = false ;
3434bool verbose_dry_run = false ;
3535int verbose = 0 ;
36+ int debug_expansions = 0 ;
37+
38+ DebugExpand debug_expand;
39+
40+ class DebugExpandReport {
41+ public:
42+ DebugExpandReport (DebugExpand::const_iterator source,
43+ ExpandResultCount::const_iterator result) :
44+ _source (source),
45+ _result (result)
46+ { }
47+
48+ const string &get_source () const {
49+ return (*_source).first ;
50+ }
51+ const string &get_result () const {
52+ return (*_result).first ;
53+ }
54+ int get_count () const {
55+ return (*_result).second ;
56+ }
57+
58+ bool operator < (const DebugExpandReport &other) const {
59+ return get_count () > other.get_count ();
60+ }
61+
62+ DebugExpand::const_iterator _source;
63+ ExpandResultCount::const_iterator _result;
64+ };
65+
3666
3767static void
3868usage () {
@@ -74,9 +104,15 @@ usage() {
74104 " -I Report the compiled-in default for INSTALL_DIR, and exit.\n "
75105 " -v Turn on verbose output (may help in debugging .pp files).\n "
76106 " -vv Be very verbose (if you're getting desperate).\n "
107+ " -x count Print a histogram of the count most-frequently expanded strings\n "
108+ " and their results. Useful to optimize .pp scripts so that\n "
109+ " variables are not needlessly repeatedly expanded.\n\n "
110+
77111 " -P Report the current platform name, and exit.\n\n "
112+
78113 " -D pp.dep Examine the given dependency file, and re-run ppremake\n "
79114 " only if the dependency file is stale.\n\n "
115+
80116 " -d Instead of generating makefiles, report the set of\n "
81117 " subdirectories that the named subdirectory depends on.\n "
82118 " Directories are named by their local name, not by the\n "
@@ -229,7 +265,7 @@ main(int argc, char *argv[]) {
229265 string progname = argv[0 ];
230266 extern char *optarg;
231267 extern int optind;
232- const char *optstr = " hVIvPD :drnNp:c:s:" ;
268+ const char *optstr = " hVIvx:PD :drnNp:c:s:" ;
233269
234270 bool any_d = false ;
235271 bool dependencies_stale = false ;
@@ -268,6 +304,10 @@ main(int argc, char *argv[]) {
268304 ++verbose;
269305 break ;
270306
307+ case ' x' :
308+ debug_expansions = atoi (optarg);
309+ break ;
310+
271311 case ' P' :
272312 report_platform ();
273313 exit (0 );
@@ -408,6 +448,32 @@ main(int argc, char *argv[]) {
408448 }
409449 }
410450
451+ if (debug_expansions > 0 ) {
452+ // Now report the worst expansion offenders. These are the
453+ // strings that were most often expanded to the same thing.
454+ cerr << " \n Expansion report:\n " ;
455+ vector<DebugExpandReport> report;
456+
457+ DebugExpand::const_iterator dei;
458+ for (dei = debug_expand.begin (); dei != debug_expand.end (); ++dei) {
459+ const ExpandResultCount &result_count = (*dei).second ;
460+ ExpandResultCount::const_iterator rci;
461+ for (rci = result_count.begin (); rci != result_count.end (); ++rci) {
462+ report.push_back (DebugExpandReport (dei, rci));
463+ }
464+ }
465+
466+ sort (report.begin (), report.end ());
467+
468+ int num_reports = min ((int )report.size (), debug_expansions);
469+ for (int i = 0 ; i < num_reports; i++) {
470+ cerr << " \" " << report[i].get_source () << " \" -> \" "
471+ << report[i].get_result ()
472+ << " \" (" << report[i].get_count () << " )\n " ;
473+ }
474+ cerr << " \n " ;
475+ }
476+
411477 cerr << " No errors.\n " ;
412478 return (0 );
413479}
0 commit comments