[cairo-commit] 13 commits - NEWS perf/cairo-perf-diff perf/cairo-perf-diff-files.c

Carl Worth cworth at kemper.freedesktop.org
Wed Apr 25 11:27:49 PDT 2007


 NEWS                         |    2 
 perf/cairo-perf-diff         |    2 
 perf/cairo-perf-diff-files.c |  670 ++++++++++++++++++++++++++-----------------
 3 files changed, 411 insertions(+), 263 deletions(-)

New commits:
diff-tree 342de46eb4033e1cccfec8b905c0002cc880c9fb (from db2a761ae7055a61d3705a76526cbd0b71fcc95d)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 25 10:25:57 2007 -0700

    Make the traditional speedup vs. slowdown report style available again
    
    Now, if you pass exactly two performance reports on the command line
    you'll get the traditional report style again, (so the tool remains
    backwards compatible). If you really want the new style with two
    reports you can get it by adding /dev/null as a third argument.

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index 2bad7d9..d534fb7 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -444,6 +444,29 @@ cairo_perf_report_load (cairo_perf_repor
 }
 
 static int
+test_diff_cmp_speedup_before_slowdown (const void *a, const void *b)
+{
+    const test_diff_t *a_diff = a;
+    const test_diff_t *b_diff = b;
+
+    /* First make all speedups come before all slowdowns. */
+    if (a_diff->change > 1.0 && b_diff->change < 1.0)
+	return -1;
+    if (a_diff->change < 1.0 && b_diff->change > 1.0)
+	return 1;
+
+    /* Reverse sort by magnitude of change so larger changes come
+     * first */
+    if (fabs (a_diff->change) > fabs (b_diff->change))
+	return -1;
+
+    if (fabs (a_diff->change) < fabs (b_diff->change))
+	return 1;
+
+    return 0;
+}
+
+static int
 test_diff_cmp (const void *a, const void *b)
 {
     const test_diff_t *a_diff = a;
@@ -507,9 +530,33 @@ print_change_bar (double change, double 
 }
 
 static void
-test_diff_print (test_diff_t			*diff,
-		 double				 max_change,
-		 cairo_perf_report_options_t	*options)
+test_diff_print_binary (test_diff_t			*diff,
+			double				 max_change,
+			cairo_perf_report_options_t	*options)
+{
+    printf ("%5s-%-4s %26s-%-3d  %6.2f %4.2f%% -> %6.2f %4.2f%%: %5.2fx ",
+	    diff->tests[0]->backend, diff->tests[0]->content,
+	    diff->tests[0]->name, diff->tests[0]->size,
+	    diff->tests[0]->stats.median_ticks / diff->tests[0]->stats.ticks_per_ms,
+	    diff->tests[0]->stats.std_dev * 100,
+	    diff->tests[1]->stats.median_ticks / diff->tests[1]->stats.ticks_per_ms,
+	    diff->tests[1]->stats.std_dev * 100,
+	    fabs (diff->change));
+
+    if (diff->change > 1.0)
+	printf ("speedup\n");
+    else
+	printf ("slowdown\n");
+
+    if (options->print_change_bars)
+	print_change_bar (fabs (diff->change), max_change,
+			  options->use_utf);
+}
+
+static void
+test_diff_print_multi (test_diff_t			*diff,
+		       double				 max_change,
+		       cairo_perf_report_options_t	*options)
 {
     int i;
     double test_time;
@@ -551,6 +598,8 @@ cairo_perf_reports_compare (cairo_perf_r
     double max_change;
     double test_time;
     cairo_bool_t seen_non_null;
+    cairo_bool_t printed_speedup = FALSE;
+    cairo_bool_t printed_slowdown = FALSE;
 
     assert (num_reports >= 2);
 
@@ -613,16 +662,41 @@ cairo_perf_reports_compare (cairo_perf_r
 	}
 	diff->change = diff->max / diff->min;
 
+	if (num_reports == 2) {
+	    double old_time, new_time;
+	    if (diff->num_tests == 1) {
+		printf ("Only in %s: %s %s\n",
+			diff->tests[0]->configuration,
+			diff->tests[0]->backend,
+			diff->tests[0]->name);
+		continue;
+	    }
+	    old_time = diff->tests[0]->stats.min_ticks;
+	    new_time = diff->tests[1]->stats.min_ticks;
+	    if (options->use_ms) {
+		old_time /= diff->tests[0]->stats.ticks_per_ms;
+		new_time /= diff->tests[1]->stats.ticks_per_ms;
+	    }
+	    diff->change = old_time / new_time;
+	    if (diff->change < 1.0)
+		diff->change = - 1.0 / diff->change;
+	}
+
 	diff++;
 	num_diffs++;
     }
 
-    qsort (diffs, num_diffs, sizeof (test_diff_t), test_diff_cmp);
+    if (num_reports == 2)
+	qsort (diffs, num_diffs, sizeof (test_diff_t),
+	       test_diff_cmp_speedup_before_slowdown);
+    else
+	qsort (diffs, num_diffs, sizeof (test_diff_t), test_diff_cmp);
 
     max_change = 1.0;
-    for (i = 0; i < num_diffs; i++)
-	if (diffs[i].change > max_change)
-	    max_change = diffs[i].change;
+    for (i = 0; i < num_diffs; i++) {
+	if (fabs (diffs[i].change) > max_change)
+	    max_change = fabs (diffs[i].change);
+    }
 
     for (i = 0; i < num_diffs; i++) {
 	diff = &diffs[i];
@@ -630,10 +704,30 @@ cairo_perf_reports_compare (cairo_perf_r
 	/* Discard as uninteresting a change which is less than the
 	 * minimum change required, (default may be overriden on
 	 * command-line). */
-	if (diff->change - 1.0 < options->min_change)
+	if (fabs (diff->change) - 1.0 < options->min_change)
 	    continue;
 
-	test_diff_print (diff, max_change, options);
+	if (num_reports == 2) {
+	    if (i == 0) {
+		printf ("old: %s\n"
+			"new: %s\n",
+			diffs->tests[0]->configuration,
+			diffs->tests[1]->configuration);
+	    }
+	    if (diff->change > 1.0 && ! printed_speedup) {
+		printf ("Speedups\n"
+			"========\n");
+		printed_speedup = TRUE;
+	    }
+	    if (diff->change < 1.0 && ! printed_slowdown) {
+		printf ("Slowdowns\n"
+			"=========\n");
+		printed_slowdown = TRUE;
+	    }
+	    test_diff_print_binary (diff, max_change, options);
+	} else {
+	    test_diff_print_multi (diff, max_change, options);
+	}
     }
 
     for (i = 0; i < num_diffs; i++)
diff-tree db2a761ae7055a61d3705a76526cbd0b71fcc95d (from 5030cfce5df507a0338e1070a5dab3851ed9df7c)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 25 08:53:46 2007 -0700

    Implement support for generating a report from more than two files
    
    This support is intended to compare the identical backends across multiple
    reports from several different configurations, (of one sort or another).
    The configuration names used in the report are taken from the filenames
    of the report files, (which will format most nicely if 8 characters or
    less).
    
    The traditional two-input report mode, (showing one line perdiff with
    all speedups before all slowdowns), is removed with this commit, but
    is intended to return again shortly.

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index c2d81f2..2bad7d9 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -37,9 +37,11 @@
 #include <errno.h>
 #include <ctype.h>
 #include <math.h>
+#include <assert.h>
 
 typedef struct _test_report {
     int id;
+    const char *configuration;
     char *backend;
     char *content;
     char *name;
@@ -57,12 +59,15 @@ typedef struct _test_report {
 } test_report_t;
 
 typedef struct _test_diff {
-    test_report_t *old;
-    test_report_t *new;
-    double speedup;
+    test_report_t **tests;
+    int num_tests;
+    double min;
+    double max;
+    double change;
 } test_diff_t;
 
 typedef struct _cairo_perf_report {
+    char *configuration;
     const char *name;
     test_report_t *tests;
     int tests_size;
@@ -143,7 +148,7 @@ do {									\
 } while (0)
 
 static test_report_status_t
-test_report_parse (test_report_t *report, char *line)
+test_report_parse (test_report_t *report, char *line, char *configuration)
 {
     char *end;
     char *s = line;
@@ -169,6 +174,7 @@ test_report_parse (test_report_t *report
 
     skip_space ();
 
+    report->configuration = configuration;
     parse_string (report->backend);
     end = strrchr (report->backend, '-');
     if (*end)
@@ -293,6 +299,7 @@ test_report_cmp_backend_then_name (const
 {
     const test_report_t *a_test = a;
     const test_report_t *b_test = b;
+
     int cmp;
 
     cmp = strcmp (a_test->backend, b_test->backend);
@@ -303,6 +310,15 @@ test_report_cmp_backend_then_name (const
     if (cmp)
 	return cmp;
 
+    /* A NULL name is a list-termination marker, so force it last. */
+    if (a_test->name == NULL)
+	if (b_test->name == NULL)
+	    return 0;
+	else
+	    return 1;
+    else if (b_test->name == NULL)
+	return -1;
+
     cmp = strcmp (a_test->name, b_test->name);
     if (cmp)
 	return cmp;
@@ -311,6 +327,7 @@ test_report_cmp_backend_then_name (const
 	return -1;
     if (a_test->size > b_test->size)
 	return 1;
+
     return 0;
 }
 
@@ -367,6 +384,15 @@ cairo_perf_report_load (cairo_perf_repor
     int line_number = 0;
     char *line = NULL;
     size_t line_size = 0;
+    char *configuration;
+    char *dot;
+
+    configuration = strdup (filename);
+    report->configuration = strdup (basename (configuration));
+    free (configuration);
+    dot = strrchr (report->configuration, '.');
+    if (dot)
+	*dot = '\0';
 
     report->name = filename;
     report->tests_size = 16;
@@ -391,7 +417,8 @@ cairo_perf_report_load (cairo_perf_repor
 	if (getline (&line, &line_size, file) == -1)
 	    break;
 
-	status = test_report_parse (&report->tests[report->tests_count], line);
+	status = test_report_parse (&report->tests[report->tests_count],
+				    line, report->configuration);
 	if (status == TEST_REPORT_STATUS_ERROR)
 	    fprintf (stderr, "Ignoring unrecognized line %d of %s:\n%s",
 		     line_number, filename, line);
@@ -403,6 +430,8 @@ cairo_perf_report_load (cairo_perf_repor
     if (line)
 	free (line);
 
+    fclose (file);
+
     cairo_perf_report_sort_and_compute_stats (report);
 
     /* Add one final report with a NULL name to terminate the list. */
@@ -419,29 +448,15 @@ test_diff_cmp (const void *a, const void
 {
     const test_diff_t *a_diff = a;
     const test_diff_t *b_diff = b;
-    double a_change, b_change;
-
-    a_change = a_diff->speedup;
-    b_change = b_diff->speedup;
 
-    /* First make all speedups come before all slowdowns. */
-    if (a_change > 1.0 && b_change < 1.0)
+    /* Reverse sort by magnitude of change so larger changes come
+     * first */
+    if (a_diff->change > b_diff->change)
 	return -1;
-    if (a_change < 1.0 && b_change > 1.0)
-	return 1;
-
-    /* Then, within each, sort by magnitude of speed change */
-    if (a_change < 1.0)
-	a_change = 1.0 / a_change;
 
-    if (b_change < 1.0)
-	b_change = 1.0 / b_change;
-
-    /* Reverse sort so larger changes come first */
-    if (a_change > b_change)
-	return -1;
-    if (a_change < b_change)
+    if (a_diff->change < b_diff->change)
 	return 1;
+
     return 0;
 }
 
@@ -491,125 +506,140 @@ print_change_bar (double change, double 
     printf ("\n");
 }
 
+static void
+test_diff_print (test_diff_t			*diff,
+		 double				 max_change,
+		 cairo_perf_report_options_t	*options)
+{
+    int i;
+    double test_time;
+    double change;
+
+    printf ("%s (backend: %s-%s, size: %d)\n",
+	    diff->tests[0]->name,
+	    diff->tests[0]->backend,
+	    diff->tests[0]->content,
+	    diff->tests[0]->size);
+
+    for (i = 0; i < diff->num_tests; i++) {
+	test_time = diff->tests[i]->stats.min_ticks;
+	if (options->use_ms)
+	    test_time /= diff->tests[i]->stats.ticks_per_ms;
+	change = diff->max / test_time;
+	printf ("%8s %6.2f: %5.2fx ",
+		diff->tests[i]->configuration,
+		diff->tests[i]->stats.min_ticks / diff->tests[i]->stats.ticks_per_ms,
+		change);
+
+	if (options->print_change_bars)
+	    print_change_bar (change, max_change, options->use_utf);
+    }
+
+    printf("\n");
+}
+
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 static void
-cairo_perf_report_diff (cairo_perf_report_t		*old,
-			cairo_perf_report_t		*new,
-			cairo_perf_report_options_t	*options)
+cairo_perf_reports_compare (cairo_perf_report_t		*reports,
+			    int				 num_reports,
+			    cairo_perf_report_options_t	*options)
 {
     int i;
-    test_report_t *o, *n;
-    int cmp;
+    test_report_t **tests, *min_test;
     test_diff_t *diff, *diffs;
-    int num_diffs = 0;
-    int printed_speedup = 0, printed_slowdown = 0;
-    double min_change = options->min_change, change, max_change;
-
-    diffs = xmalloc (MAX (old->tests_count, new->tests_count) * sizeof (test_diff_t));
-
-    o = &old->tests[0];
-    n = &new->tests[0];
-    while (o->name && n->name) {
+    int num_diffs, max_diffs;
+    double max_change;
+    double test_time;
+    cairo_bool_t seen_non_null;
+
+    assert (num_reports >= 2);
+
+    tests = xmalloc (num_reports * sizeof (test_report_t *));
+
+    max_diffs = reports[0].tests_count;
+    for (i = 0; i < num_reports; i++) {
+	tests[i] = reports[i].tests;
+	if (reports[i].tests_count > max_diffs)
+	    max_diffs = reports[i].tests_count;
+    }
+
+    diff = diffs = xmalloc (max_diffs * sizeof (test_diff_t));
+
+    num_diffs = 0;
+    while (1) {
 	/* We expect iterations values of 0 when multiple raw reports
 	 * for the same test have been condensed into the stats of the
 	 * first. So we just skip these later reports that have no
 	 * stats. */
-	if (o->stats.iterations == 0) {
-	    o++;
-	    continue;
-	}
-	if (n->stats.iterations == 0) {
-	    n++;
-	    continue;
+	seen_non_null = 0;
+	for (i = 0; i < num_reports; i++) {
+	    while (tests[i]->name && tests[i]->stats.iterations == 0)
+		tests[i]++;
+	    if (tests[i]->name)
+		seen_non_null = 1;
 	}
 
-	cmp = test_report_cmp_backend_then_name (o, n);
-	if (cmp < 0) {
-	    fprintf (stderr, "Only in old: %s %s\n", o->backend, o->name);
-	    o++;
-	    continue;
-	}
-	if (cmp > 0) {
-	    fprintf (stderr, "Only in new: %s %s\n", n->backend, n->name);
-	    n++;
-	    continue;
-	}
+	if (! seen_non_null)
+	    break;
 
-	diffs[num_diffs].old = o;
-	diffs[num_diffs].new = n;
-	if (options->use_ms) {
-	    diffs[num_diffs].speedup =
-		(double) (o->stats.median_ticks / o->stats.ticks_per_ms)
-		       / (n->stats.median_ticks / n->stats.ticks_per_ms);
-	} else {
-	    diffs[num_diffs].speedup =
-		(double) o->stats.median_ticks / n->stats.median_ticks;
+	/* Find the minimum of all current tests, (we have to do this
+	 * in case some reports don't have a particular test). */
+	min_test = tests[0];
+	for (i = 1; i < num_reports; i++)
+	    if (test_report_cmp_backend_then_name (tests[i], min_test) < 0)
+		min_test = tests[i];
+
+	/* For each report that has the current test, record it into
+	 * the diff structure. */
+	diff->num_tests = 0;
+	diff->tests = xmalloc (num_reports * sizeof (test_diff_t));
+	for (i = 0; i < num_reports; i++) {
+	    if (test_report_cmp_backend_then_name (tests[i], min_test) == 0) {
+		test_time = tests[i]->stats.min_ticks;
+		if (options->use_ms)
+		    test_time /= tests[i]->stats.ticks_per_ms;
+		if (diff->num_tests == 0) {
+		    diff->min = test_time;
+		    diff->max = test_time;
+		} else {
+		    if (test_time < diff->min)
+			diff->min = test_time;
+		    if (test_time > diff->max)
+			diff->max = test_time;
+		}
+		diff->tests[diff->num_tests++] = tests[i];
+		tests[i]++;
+	    }
 	}
-	num_diffs++;
+	diff->change = diff->max / diff->min;
 
-	o++;
-	n++;
+	diff++;
+	num_diffs++;
     }
 
     qsort (diffs, num_diffs, sizeof (test_diff_t), test_diff_cmp);
 
     max_change = 1.0;
-    for (i = 0; i < num_diffs; i++) {
-	change = diffs[i].speedup;
-	if (change < 1.0)
-	    change = 1.0 / change;
-	if (change > max_change)
-	    max_change = change;
-    }
+    for (i = 0; i < num_diffs; i++)
+	if (diffs[i].change > max_change)
+	    max_change = diffs[i].change;
 
     for (i = 0; i < num_diffs; i++) {
 	diff = &diffs[i];
 
-	change = diff->speedup;
-	if (change < 1.0)
-	    change = 1.0 / change;
-
 	/* Discard as uninteresting a change which is less than the
 	 * minimum change required, (default may be overriden on
 	 * command-line). */
-	if (change - 1.0 < min_change)
+	if (diff->change - 1.0 < options->min_change)
 	    continue;
 
-	/* Also discard as uninteresting if the change is less than
-	 * the sum each of the standard deviations. */
-	if (change - 1.0 < diff->old->stats.std_dev + diff->new->stats.std_dev)
-	    continue;
-
-	if (diff->speedup > 1.0 && ! printed_speedup) {
-	    printf ("Speedups\n"
-		    "========\n");
-	    printed_speedup = 1;
-	}
-	if (diff->speedup < 1.0 && ! printed_slowdown) {
-	    printf ("Slowdowns\n"
-		    "=========\n");
-	    printed_slowdown = 1;
-	}
-
-	printf ("%5s-%-4s %26s-%-3d  %6.2f %4.2f%% -> %6.2f %4.2f%%: %5.2fx ",
-		diff->old->backend, diff->old->content,
-		diff->old->name, diff->old->size,
-		diff->old->stats.median_ticks / diff->old->stats.ticks_per_ms,
-		diff->old->stats.std_dev * 100,
-		diff->new->stats.median_ticks / diff->new->stats.ticks_per_ms,
-		diff->new->stats.std_dev * 100,
-		change);
-
-	if (diff->speedup > 1.0)
-	    printf ("speedup\n");
-	else
-	    printf ("slowdown\n");
-
-	if (options->print_change_bars)
-	    print_change_bar (change, max_change, options->use_utf);
+	test_diff_print (diff, max_change, options);
     }
 
+    for (i = 0; i < num_diffs; i++)
+	free (diffs[i].tests);
     free (diffs);
+    free (tests);
 }
 
 static void
@@ -618,7 +648,7 @@ usage (const char *argv0)
     char const *basename = strrchr(argv0, '/');
     basename = basename ? basename+1 : argv0;
     fprintf (stderr,
-	     "Usage: %s [options] file1 file2\n\n",
+	     "Usage: %s [options] file1 file2 [...]\n\n",
 	     basename);
     fprintf (stderr,
 	     "Computes significant performance differences for cairo performance reports.\n"
@@ -695,11 +725,12 @@ main (int argc, const char *argv[])
 	}
     };
     cairo_perf_report_t *reports;
+    test_report_t *t;
     int i;
 
     parse_args (argc, argv, &args);
 
-    if (args.num_filenames != 2)
+    if (args.num_filenames < 2)
 	usage (argv[0]);
 
     reports = xmalloc (args.num_filenames * sizeof (cairo_perf_report_t));
@@ -707,7 +738,20 @@ main (int argc, const char *argv[])
     for (i = 0; i < args.num_filenames; i++ )
 	cairo_perf_report_load (&reports[i], args.filenames[i]);
 
-    cairo_perf_report_diff (&reports[0], &reports[1], &args.options);
+    cairo_perf_reports_compare (reports, args.num_filenames, &args.options);
+
+    /* Pointless memory cleanup, (would be a great place for talloc) */
+    free (args.filenames);
+    for (i = 0; i < args.num_filenames; i++) {
+	for (t = reports[i].tests; t->name; t++) {
+	    free (t->samples);
+	    free (t->backend);
+	    free (t->name);
+	}
+	free (reports[i].tests);
+	free (reports[i].configuration);
+    }
+    free (reports);
 
     return 0;
 }
diff-tree 5030cfce5df507a0338e1070a5dab3851ed9df7c (from 6121f4fccfe8d98fb09c096402da05d29d10b9e8)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Apr 19 16:32:57 2007 -0700

    cairo-perf-diff-files: Use pointers instead of indexing to iterate over reports
    
    We terminate the iteration by adding a final report with a NULL
    name. This will simplify future code that iterates over more than
    two reports simultaneously.

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index 9492c20..c2d81f2 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -404,6 +404,14 @@ cairo_perf_report_load (cairo_perf_repor
 	free (line);
 
     cairo_perf_report_sort_and_compute_stats (report);
+
+    /* Add one final report with a NULL name to terminate the list. */
+    if (report->tests_count == report->tests_size) {
+	report->tests_size *= 2;
+	report->tests = xrealloc (report->tests,
+				  report->tests_size * sizeof (test_report_t));
+    }
+    report->tests[report->tests_count].name = NULL;
 }
 
 static int
@@ -489,7 +497,7 @@ cairo_perf_report_diff (cairo_perf_repor
 			cairo_perf_report_t		*new,
 			cairo_perf_report_options_t	*options)
 {
-    int i, i_old, i_new;
+    int i;
     test_report_t *o, *n;
     int cmp;
     test_diff_t *diff, *diffs;
@@ -499,34 +507,31 @@ cairo_perf_report_diff (cairo_perf_repor
 
     diffs = xmalloc (MAX (old->tests_count, new->tests_count) * sizeof (test_diff_t));
 
-    i_old = 0;
-    i_new = 0;
-    while (i_old < old->tests_count && i_new < new->tests_count) {
-	o = &old->tests[i_old];
-	n = &new->tests[i_new];
-
+    o = &old->tests[0];
+    n = &new->tests[0];
+    while (o->name && n->name) {
 	/* We expect iterations values of 0 when multiple raw reports
 	 * for the same test have been condensed into the stats of the
 	 * first. So we just skip these later reports that have no
 	 * stats. */
 	if (o->stats.iterations == 0) {
-	    i_old++;
+	    o++;
 	    continue;
 	}
 	if (n->stats.iterations == 0) {
-	    i_new++;
+	    n++;
 	    continue;
 	}
 
 	cmp = test_report_cmp_backend_then_name (o, n);
 	if (cmp < 0) {
 	    fprintf (stderr, "Only in old: %s %s\n", o->backend, o->name);
-	    i_old++;
+	    o++;
 	    continue;
 	}
 	if (cmp > 0) {
 	    fprintf (stderr, "Only in new: %s %s\n", n->backend, n->name);
-	    i_new++;
+	    n++;
 	    continue;
 	}
 
@@ -542,8 +547,8 @@ cairo_perf_report_diff (cairo_perf_repor
 	}
 	num_diffs++;
 
-	i_old++;
-	i_new++;
+	o++;
+	n++;
     }
 
     qsort (diffs, num_diffs, sizeof (test_diff_t), test_diff_cmp);
diff-tree 6121f4fccfe8d98fb09c096402da05d29d10b9e8 (from cc03f0499e7b133a2e5c14e55207259ea000b8c2)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Apr 19 16:21:39 2007 -0700

    cairo-perf-diff-files: Simplify code to grow report->tests

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index 7b64504..9492c20 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -369,8 +369,8 @@ cairo_perf_report_load (cairo_perf_repor
     size_t line_size = 0;
 
     report->name = filename;
-    report->tests = NULL;
-    report->tests_size = 0;
+    report->tests_size = 16;
+    report->tests = xmalloc (report->tests_size * sizeof (test_report_t));
     report->tests_count = 0;
 
     file = fopen (filename, "r");
@@ -382,13 +382,9 @@ cairo_perf_report_load (cairo_perf_repor
 
     while (1) {
 	if (report->tests_count == report->tests_size) {
-	    report->tests_size = report->tests_size ? 2 * report->tests_size : 16;
-	    report->tests = realloc (report->tests,
-				     report->tests_size * sizeof (test_report_t));
-	    if (report->tests == NULL) {
-		fprintf (stderr, "Out of memory.\n");
-		exit (1);
-	    }
+	    report->tests_size *= 2;
+	    report->tests = xrealloc (report->tests,
+				      report->tests_size * sizeof (test_report_t));
 	}
 
 	line_number++;
diff-tree cc03f0499e7b133a2e5c14e55207259ea000b8c2 (from 228c83c9d2d1fdb6fa3af8a650640a47c8e21e36)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Apr 19 16:09:06 2007 -0700

    cairo-perf-diff-files: Sort and compute stats at the time of loading a report

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index e968e6c..7b64504 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -287,6 +287,78 @@ strndup (const char *s, size_t n)
 }
 #endif /* ifndef __USE_GNU */
 
+
+static int
+test_report_cmp_backend_then_name (const void *a, const void *b)
+{
+    const test_report_t *a_test = a;
+    const test_report_t *b_test = b;
+    int cmp;
+
+    cmp = strcmp (a_test->backend, b_test->backend);
+    if (cmp)
+	return cmp;
+
+    cmp = strcmp (a_test->content, b_test->content);
+    if (cmp)
+	return cmp;
+
+    cmp = strcmp (a_test->name, b_test->name);
+    if (cmp)
+	return cmp;
+
+    if (a_test->size < b_test->size)
+	return -1;
+    if (a_test->size > b_test->size)
+	return 1;
+    return 0;
+}
+
+static void
+cairo_perf_report_sort_and_compute_stats (cairo_perf_report_t *report)
+{
+    test_report_t *base, *next, *last, *t;
+
+    /* First we sort, since the diff needs both lists in the same
+     * order */
+    qsort (report->tests, report->tests_count, sizeof (test_report_t),
+	   test_report_cmp_backend_then_name);
+
+    /* The sorting also brings all related raw reports together so we
+     * can condense them and compute the stats.
+     */
+    base = &report->tests[0];
+    last = &report->tests[report->tests_count - 1];
+    while (base <= last) {
+	next = base+1;
+	if (next <= last) {
+	    while (next <= last &&
+		   test_report_cmp_backend_then_name (base, next) == 0)
+	    {
+		next++;
+	    }
+	    if (next != base) {
+		unsigned int new_samples_count = base->samples_count;
+		for (t = base + 1; t < next; t++)
+		    new_samples_count += t->samples_count;
+		if (new_samples_count > base->samples_size) {
+		    base->samples_size = new_samples_count;
+		    base->samples = xrealloc (base->samples,
+					      base->samples_size * sizeof (cairo_perf_ticks_t));
+		}
+		for (t = base + 1; t < next; t++) {
+		    memcpy (&base->samples[base->samples_count], t->samples,
+			    t->samples_count * sizeof (cairo_perf_ticks_t));
+		    base->samples_count += t->samples_count;
+		}
+	    }
+	}
+	if (base->samples)
+	    _cairo_stats_compute (&base->stats, base->samples, base->samples_count);
+	base = next;
+    }
+}
+
 static void
 cairo_perf_report_load (cairo_perf_report_t *report, const char *filename)
 {
@@ -334,6 +406,8 @@ cairo_perf_report_load (cairo_perf_repor
 
     if (line)
 	free (line);
+
+    cairo_perf_report_sort_and_compute_stats (report);
 }
 
 static int
@@ -367,77 +441,6 @@ test_diff_cmp (const void *a, const void
     return 0;
 }
 
-static int
-test_report_cmp_backend_then_name (const void *a, const void *b)
-{
-    const test_report_t *a_test = a;
-    const test_report_t *b_test = b;
-    int cmp;
-
-    cmp = strcmp (a_test->backend, b_test->backend);
-    if (cmp)
-	return cmp;
-
-    cmp = strcmp (a_test->content, b_test->content);
-    if (cmp)
-	return cmp;
-
-    cmp = strcmp (a_test->name, b_test->name);
-    if (cmp)
-	return cmp;
-
-    if (a_test->size < b_test->size)
-	return -1;
-    if (a_test->size > b_test->size)
-	return 1;
-    return 0;
-}
-
-static void
-cairo_perf_report_sort_and_compute_stats (cairo_perf_report_t *report)
-{
-    test_report_t *base, *next, *last, *t;
-
-    /* First we sort, since the diff needs both lists in the same
-     * order */
-    qsort (report->tests, report->tests_count, sizeof (test_report_t),
-	   test_report_cmp_backend_then_name);
-
-    /* The sorting also brings all related raw reports together so we
-     * can condense them and compute the stats.
-     */
-    base = &report->tests[0];
-    last = &report->tests[report->tests_count - 1];
-    while (base <= last) {
-	next = base+1;
-	if (next <= last) {
-	    while (next <= last &&
-		   test_report_cmp_backend_then_name (base, next) == 0)
-	    {
-		next++;
-	    }
-	    if (next != base) {
-		unsigned int new_samples_count = base->samples_count;
-		for (t = base + 1; t < next; t++)
-		    new_samples_count += t->samples_count;
-		if (new_samples_count > base->samples_size) {
-		    base->samples_size = new_samples_count;
-		    base->samples = xrealloc (base->samples,
-					      base->samples_size * sizeof (cairo_perf_ticks_t));
-		}
-		for (t = base + 1; t < next; t++) {
-		    memcpy (&base->samples[base->samples_count], t->samples,
-			    t->samples_count * sizeof (cairo_perf_ticks_t));
-		    base->samples_count += t->samples_count;
-		}
-	    }
-	}
-	if (base->samples)
-	    _cairo_stats_compute (&base->stats, base->samples, base->samples_count);
-	base = next;
-    }
-}
-
 #define CHANGE_BAR_WIDTH 70
 static void
 print_change_bar (double change, double max_change, int use_utf)
@@ -500,16 +503,13 @@ cairo_perf_report_diff (cairo_perf_repor
 
     diffs = xmalloc (MAX (old->tests_count, new->tests_count) * sizeof (test_diff_t));
 
-    cairo_perf_report_sort_and_compute_stats (old);
-    cairo_perf_report_sort_and_compute_stats (new);
-
     i_old = 0;
     i_new = 0;
     while (i_old < old->tests_count && i_new < new->tests_count) {
 	o = &old->tests[i_old];
 	n = &new->tests[i_new];
 
-	/* We expect iterations values of 0 when mutltiple raw reports
+	/* We expect iterations values of 0 when multiple raw reports
 	 * for the same test have been condensed into the stats of the
 	 * first. So we just skip these later reports that have no
 	 * stats. */
diff-tree 228c83c9d2d1fdb6fa3af8a650640a47c8e21e36 (from 876786b3f7316b99a51ba8225e34581be13a883d)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Apr 19 14:35:51 2007 -0700

    cairo-perf-diff: Separate command-line options within the args structure
    
    A function like cairo_perf_report_diff wants the options, but really
    doesn't want/need to see the filenames for example,

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index 290b941..e968e6c 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -75,13 +75,17 @@ typedef enum {
     TEST_REPORT_STATUS_ERROR
 } test_report_status_t;
 
-typedef struct _cairo_perf_diff_files_args {
-    const char **filenames;
-    int num_filenames;
+typedef struct _cairo_perf_report_options {
     double min_change;
     int use_utf;
     int print_change_bars;
     int use_ms;
+} cairo_perf_report_options_t;
+
+typedef struct _cairo_perf_diff_files_args {
+    const char **filenames;
+    int num_filenames;
+    cairo_perf_report_options_t options;
 } cairo_perf_diff_files_args_t;
 
 /* Ad-hoc parsing, macros with a strong dependence on the calling
@@ -482,9 +486,9 @@ print_change_bar (double change, double 
 
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 static void
-cairo_perf_report_diff (cairo_perf_report_t			*old,
-			cairo_perf_report_t			*new,
-			cairo_perf_diff_files_args_t const	*args)
+cairo_perf_report_diff (cairo_perf_report_t		*old,
+			cairo_perf_report_t		*new,
+			cairo_perf_report_options_t	*options)
 {
     int i, i_old, i_new;
     test_report_t *o, *n;
@@ -492,7 +496,7 @@ cairo_perf_report_diff (cairo_perf_repor
     test_diff_t *diff, *diffs;
     int num_diffs = 0;
     int printed_speedup = 0, printed_slowdown = 0;
-    double min_change = args->min_change, change, max_change;
+    double min_change = options->min_change, change, max_change;
 
     diffs = xmalloc (MAX (old->tests_count, new->tests_count) * sizeof (test_diff_t));
 
@@ -532,7 +536,7 @@ cairo_perf_report_diff (cairo_perf_repor
 
 	diffs[num_diffs].old = o;
 	diffs[num_diffs].new = n;
-	if (args->use_ms) {
+	if (options->use_ms) {
 	    diffs[num_diffs].speedup =
 		(double) (o->stats.median_ticks / o->stats.ticks_per_ms)
 		       / (n->stats.median_ticks / n->stats.ticks_per_ms);
@@ -600,8 +604,8 @@ cairo_perf_report_diff (cairo_perf_repor
 	else
 	    printf ("slowdown\n");
 
-	if (args->print_change_bars)
-	    print_change_bar (change, max_change, args->use_utf);
+	if (options->print_change_bars)
+	    print_change_bar (change, max_change, options->use_utf);
     }
 
     free (diffs);
@@ -646,23 +650,23 @@ parse_args(int				  argc,
 
     for (i = 1; i < argc; i++) {
 	if (strcmp (argv[i], "--no-utf") == 0) {
-	    args->use_utf = 0;
+	    args->options.use_utf = 0;
 	}
 	else if (strcmp (argv[i], "--no-bars") == 0) {
-	    args->print_change_bars = 0;
+	    args->options.print_change_bars = 0;
 	}
 	else if (strcmp (argv[i], "--use-ms") == 0) {
-	    args->use_ms = 1;
+	    args->options.use_ms = 1;
 	}
 	else if (strcmp (argv[i], "--min-change") == 0) {
 	    char *end = NULL;
 	    i++;
 	    if (i >= argc)
 		usage (argv[0]);
-	    args->min_change = strtod (argv[i], &end);
+	    args->options.min_change = strtod (argv[i], &end);
 	    if (*end) {
 		if (*end == '%') {
-		    args->min_change /= 100;
+		    args->options.min_change /= 100;
 		} else {
 		    usage (argv[0]);
 		}
@@ -683,9 +687,11 @@ main (int argc, const char *argv[])
     cairo_perf_diff_files_args_t args = {
 	NULL,			/* filenames */
 	0,			/* num_filenames */
-	0.05,			/* min change */
-	1,			/* use UTF-8? */
-	1,			/* display change bars? */
+	{
+	    0.05,		/* min change */
+	    1,			/* use UTF-8? */
+	    1,			/* display change bars? */
+	}
     };
     cairo_perf_report_t *reports;
     int i;
@@ -700,7 +706,7 @@ main (int argc, const char *argv[])
     for (i = 0; i < args.num_filenames; i++ )
 	cairo_perf_report_load (&reports[i], args.filenames[i]);
 
-    cairo_perf_report_diff (&reports[0], &reports[1], &args);
+    cairo_perf_report_diff (&reports[0], &reports[1], &args.options);
 
     return 0;
 }
diff-tree 876786b3f7316b99a51ba8225e34581be13a883d (from 90d532e08f25644c4e621b0b7e592f4531a39d88)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Apr 19 13:54:50 2007 -0700

    Move implementation of getline and strndup
    
    These kept getting in my way as I looked for structure declarations
    at the top of the file.

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index 42c2ea1..290b941 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -27,7 +27,7 @@
 
 #include "cairo-perf.h"
 
-/* We use _GNU_SOURCE for getline and strndup. */
+/* We use _GNU_SOURCE for getline and strndup if available. */
 #ifndef _GNU_SOURCE
 # define _GNU_SOURCE
 #endif
@@ -38,60 +38,6 @@
 #include <ctype.h>
 #include <math.h>
 
-/* We conditionally provide a custom implementation of getline and strndup
- * as needed. These aren't necessary full-fledged general purpose
- * implementations. They just get the job done for our purposes.
- */
-#ifndef __USE_GNU
-
-#define POORMANS_GETLINE_BUFFER_SIZE (65536)
-ssize_t
-getline (char **lineptr, size_t *n, FILE *stream)
-{
-    if (!*lineptr)
-    {
-        *n = POORMANS_GETLINE_BUFFER_SIZE;
-        *lineptr = (char *) malloc (*n);
-    }
-
-    if (!fgets (*lineptr, *n, stream))
-        return -1;
-
-    if (!feof (stream) && !strchr (*lineptr, '\n'))
-    {
-        fprintf (stderr, "The poor man's implementation of getline in "
-                          __FILE__ " needs a bigger buffer. Perhaps it's "
-                         "time for a complete implementation of getline.\n");
-        exit (0);
-    }
-
-    return strlen (*lineptr);
-}
-#undef POORMANS_GETLINE_BUFFER_SIZE
-
-char *
-strndup (const char *s, size_t n)
-{
-    size_t len;
-    char *sdup;
-
-    if (!s)
-        return NULL;
-
-    len = strlen (s);
-    len = (n < len ? n : len);
-    sdup = (char *) malloc (len + 1);
-    if (sdup)
-    {
-        memcpy (sdup, s, len);
-        sdup[len] = '\0';
-    }
-
-    return sdup;
-}
-
-#endif /* ifndef __USE_GNU */
-
 typedef struct _test_report {
     int id;
     char *backend;
@@ -285,6 +231,58 @@ test_report_parse (test_report_t *report
     return TEST_REPORT_STATUS_SUCCESS;
 }
 
+/* We conditionally provide a custom implementation of getline and strndup
+ * as needed. These aren't necessary full-fledged general purpose
+ * implementations. They just get the job done for our purposes.
+ */
+#ifndef __USE_GNU
+#define POORMANS_GETLINE_BUFFER_SIZE (65536)
+ssize_t
+getline (char **lineptr, size_t *n, FILE *stream)
+{
+    if (!*lineptr)
+    {
+        *n = POORMANS_GETLINE_BUFFER_SIZE;
+        *lineptr = (char *) malloc (*n);
+    }
+
+    if (!fgets (*lineptr, *n, stream))
+        return -1;
+
+    if (!feof (stream) && !strchr (*lineptr, '\n'))
+    {
+        fprintf (stderr, "The poor man's implementation of getline in "
+                          __FILE__ " needs a bigger buffer. Perhaps it's "
+                         "time for a complete implementation of getline.\n");
+        exit (0);
+    }
+
+    return strlen (*lineptr);
+}
+#undef POORMANS_GETLINE_BUFFER_SIZE
+
+char *
+strndup (const char *s, size_t n)
+{
+    size_t len;
+    char *sdup;
+
+    if (!s)
+        return NULL;
+
+    len = strlen (s);
+    len = (n < len ? n : len);
+    sdup = (char *) malloc (len + 1);
+    if (sdup)
+    {
+        memcpy (sdup, s, len);
+        sdup[len] = '\0';
+    }
+
+    return sdup;
+}
+#endif /* ifndef __USE_GNU */
+
 static void
 cairo_perf_report_load (cairo_perf_report_t *report, const char *filename)
 {
diff-tree 90d532e08f25644c4e621b0b7e592f4531a39d88 (from c6c17633e40f549ede5761095a0652c08adeee08)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Apr 19 13:52:03 2007 -0700

    Replace old and new reports with reports array
    
    Another baby step toward allowing comparison of more than two reports.

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index 4dadcf5..42c2ea1 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -689,17 +689,20 @@ main (int argc, const char *argv[])
 	1,			/* use UTF-8? */
 	1,			/* display change bars? */
     };
-    cairo_perf_report_t old, new;
+    cairo_perf_report_t *reports;
+    int i;
 
     parse_args (argc, argv, &args);
 
     if (args.num_filenames != 2)
 	usage (argv[0]);
 
-    cairo_perf_report_load (&old, args.filenames[0]);
-    cairo_perf_report_load (&new, args.filenames[1]);
+    reports = xmalloc (args.num_filenames * sizeof (cairo_perf_report_t));
 
-    cairo_perf_report_diff (&old, &new, &args);
+    for (i = 0; i < args.num_filenames; i++ )
+	cairo_perf_report_load (&reports[i], args.filenames[i]);
+
+    cairo_perf_report_diff (&reports[0], &reports[1], &args);
 
     return 0;
 }
diff-tree c6c17633e40f549ede5761095a0652c08adeee08 (from 1849a7a8bededb281fbb07ec0939f8d1f4954771)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Apr 19 13:31:37 2007 -0700

    Replace old_filename and new_filename with a filenames array
    
    More preparation for comparing more than two perf reports.

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index 1a91d67..4dadcf5 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -130,8 +130,8 @@ typedef enum {
 } test_report_status_t;
 
 typedef struct _cairo_perf_diff_files_args {
-    char const *old_filename;
-    char const *new_filename;
+    const char **filenames;
+    int num_filenames;
     double min_change;
     int use_utf;
     int print_change_bars;
@@ -670,27 +670,21 @@ parse_args(int				  argc,
 		}
 	    }
 	}
-	else if (!args->old_filename) {
-	    args->old_filename = argv[i];
-	}
-	else if (!args->new_filename) {
-	    args->new_filename = argv[i];
-	}
 	else {
-	    usage (argv[0]);
+	    args->num_filenames++;
+	    args->filenames = xrealloc (args->filenames,
+					args->num_filenames * sizeof (char *));
+	    args->filenames[args->num_filenames - 1] = argv[i];
 	}
     }
-    if ( !args->old_filename || !args->new_filename )
-	usage (argv[0]);
-#undef is_yesno_opt
 }
 
 int
 main (int argc, const char *argv[])
 {
     cairo_perf_diff_files_args_t args = {
-	NULL,			/* old filename */
-	NULL,			/* new filename */
+	NULL,			/* filenames */
+	0,			/* num_filenames */
 	0.05,			/* min change */
 	1,			/* use UTF-8? */
 	1,			/* display change bars? */
@@ -699,11 +693,13 @@ main (int argc, const char *argv[])
 
     parse_args (argc, argv, &args);
 
-    cairo_perf_report_load (&old, args.old_filename);
-    cairo_perf_report_load (&new, args.new_filename);
+    if (args.num_filenames != 2)
+	usage (argv[0]);
+
+    cairo_perf_report_load (&old, args.filenames[0]);
+    cairo_perf_report_load (&new, args.filenames[1]);
 
     cairo_perf_report_diff (&old, &new, &args);
 
     return 0;
 }
-
diff-tree 1849a7a8bededb281fbb07ec0939f8d1f4954771 (from ef5611df6c6bc8d9c6877af3a59c66fa6fc5c13a)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Apr 19 12:55:04 2007 -0700

    cairo-perf-diff-files: Add new --min-change option, (replacing third positional argument)
    
    An upcoming change will allow cairo-perf-diff-files to generate
    a report based on more than two files. This prepares for that by
    moving the minimum-change support from the 3rd positional argument
    to a new --min-change option.

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index b07b792..1a91d67 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -615,21 +615,26 @@ usage (const char *argv0)
     char const *basename = strrchr(argv0, '/');
     basename = basename ? basename+1 : argv0;
     fprintf (stderr,
-	     "Usage: %s [--no-utf] [--no-bars] file1 file2 [minimum_significant_change[%%]]\n\n",
+	     "Usage: %s [options] file1 file2\n\n",
 	     basename);
     fprintf (stderr,
 	     "Computes significant performance differences for cairo performance reports.\n"
 	     "Each file should be the output of the cairo-perf program (or \"make perf\").\n"
-	     "The third argument is used to supress all changes below some threshold.\n"
-	     "The default value of 5%% ignores any speeedup or slowdown of 5%% or less,\n"
-	     "A value of 0 will cause all output to be reported.\n"
+	     "The following options are available:\n"
 	     "\n"
 	     "--no-utf    Use ascii stars instead of utf-8 change bars.\n"
 	     "            Four stars are printed per factor of speedup.\n"
-	     "--no-bars   Don't display change bars at all.\n"
+	     "\n"
+	     "--no-bars   Don't display change bars at all.\n\n"
+	     "\n"
 	     "--use-ms    Use milliseconds to calculate differences.\n"
 	     "            (instead of ticks which are hardware dependant)\n"
-
+	     "\n"
+	     "--min-change threshold[%%]\n"
+	     "            Suppress all changes below the given threshold.\n"
+	     "            The default threshold of 0.05 or 5%% ignores any\n"
+	     "            speedup or slowdown of 1.05 or less. A threshold\n"
+	     "            of 0 will cause all output to be reported.\n"
 	);
     exit(1);
 }
@@ -640,7 +645,6 @@ parse_args(int				  argc,
 	   cairo_perf_diff_files_args_t  *args)
 {
     int i;
-    int have_minchange = 0;
 
     for (i = 1; i < argc; i++) {
 	if (strcmp (argv[i], "--no-utf") == 0) {
@@ -652,23 +656,26 @@ parse_args(int				  argc,
 	else if (strcmp (argv[i], "--use-ms") == 0) {
 	    args->use_ms = 1;
 	}
-	else if (!args->old_filename) {
-	    args->old_filename = argv[i];
-	}
-	else if (!args->new_filename) {
-	    args->new_filename = argv[i];
-	}
-	else if (!have_minchange) {
+	else if (strcmp (argv[i], "--min-change") == 0) {
 	    char *end = NULL;
+	    i++;
+	    if (i >= argc)
+		usage (argv[0]);
 	    args->min_change = strtod (argv[i], &end);
-	    if (*end && *end) {
-		if (0 == strcmp (end, "%")) {
+	    if (*end) {
+		if (*end == '%') {
 		    args->min_change /= 100;
 		} else {
 		    usage (argv[0]);
 		}
 	    }
 	}
+	else if (!args->old_filename) {
+	    args->old_filename = argv[i];
+	}
+	else if (!args->new_filename) {
+	    args->new_filename = argv[i];
+	}
 	else {
 	    usage (argv[0]);
 	}
diff-tree ef5611df6c6bc8d9c6877af3a59c66fa6fc5c13a (from a8d4fed67a32c6040c27615e063466d654b55a3a)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Apr 19 11:26:47 2007 -0700

    cairo-perf-diff: Fix implementation of --help
    
    Previously only "--" would givethe usage, and not "--help"
    as intended. The new approach has been tested with ash, bash,
    and dash, (hopefully that's good enough).

diff --git a/perf/cairo-perf-diff b/perf/cairo-perf-diff
index ebc8f55..c9ce23f 100755
--- a/perf/cairo-perf-diff
+++ b/perf/cairo-perf-diff
@@ -49,7 +49,7 @@ END
 }
 
 # Yes, this ugly ad-hoc option parsing could be cleaned up
-if [ $# -eq 0 ] || [ "$1" = "--" ]; then
+if [ $# -eq 0 ] || [ "${1#-}" != "$1" ]; then
     usage
 fi
 
diff-tree a8d4fed67a32c6040c27615e063466d654b55a3a (from fe9dd719561048af1f2c3c8c43e46f7d97575053)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Apr 19 10:02:22 2007 -0700

    cairo-perf-diff-files: Remove some overzealous option parsing.
    
    The code was complicated and confusing, and only existed to implement
    undocumented and unneeded command-line options.

diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index e538379..b07b792 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -639,18 +639,17 @@ parse_args(int				  argc,
 	   char const			**argv,
 	   cairo_perf_diff_files_args_t  *args)
 {
-#define is_yesno_opt(opt) !(strcmp ("--no-" opt, argv[i]) && strcmp ("--" opt, argv[i]))
     int i;
     int have_minchange = 0;
 
-    for (i=1; i<argc; i++) {
-	if (is_yesno_opt("utf")) {
-	    args->use_utf = 0 != strncmp ("--no-", argv[i], 4);
+    for (i = 1; i < argc; i++) {
+	if (strcmp (argv[i], "--no-utf") == 0) {
+	    args->use_utf = 0;
 	}
-	else if (is_yesno_opt("bars")) {
-	    args->print_change_bars = 0 != strncmp ("--no-", argv[i], 4);
+	else if (strcmp (argv[i], "--no-bars") == 0) {
+	    args->print_change_bars = 0;
 	}
-	else if (strcmp(argv[i], "--use-ms") == 0) {
+	else if (strcmp (argv[i], "--use-ms") == 0) {
 	    args->use_ms = 1;
 	}
 	else if (!args->old_filename) {
diff-tree fe9dd719561048af1f2c3c8c43e46f7d97575053 (from 29670d37665d184d78d568070cb409acf98ee797)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 18 17:01:36 2007 -0700

    Correct misattribution of Mathias' work to Chris

diff --git a/NEWS b/NEWS
index 2f6694b..600bd84 100644
--- a/NEWS
+++ b/NEWS
@@ -46,7 +46,7 @@ done, Mathias!
 Other improvements since 1.4.2
 ------------------------------
 • Centralize mutex declarations (will reduce future build breaks),
-  (Chris Wilson)
+  (Mathias Hasselmann)
 
 • Reduce malloc by caching recently freed pattern objects (Chris
   Wilson)


More information about the cairo-commit mailing list