Add option to specify defaults configs to --config flag in gm. This makes it easier to run gm defaults configs with a delta. Also make ~ exclude a config.

Review URL: https://codereview.chromium.org/13842014

git-svn-id: http://skia.googlecode.com/svn/trunk@8842 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index d513a0e..657f225 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -1171,10 +1171,14 @@
 #endif // SK_SUPPORT_PDF
 };
 
+static const char kDefaultsConfigStr[] = "defaults";
+static const char kExcludeConfigChar = '~';
+
 static SkString configUsage() {
     SkString result;
     result.appendf("Space delimited list of which configs to run. Possible options: [");
     for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
+        SkASSERT(gRec[i].fName != kDefaultsConfigStr);
         if (i > 0) {
             result.append("|");
         }
@@ -1182,16 +1186,39 @@
     }
     result.append("]\n");
     result.appendf("The default value is: \"");
+    SkString firstDefault;
+    SkString allButFirstDefaults;
+    SkString nonDefault;
     for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
         if (gRec[i].fRunByDefault) {
             if (i > 0) {
                 result.append(" ");
             }
-            result.appendf("%s", gRec[i].fName);
+            result.append(gRec[i].fName);
+            if (firstDefault.isEmpty()) {
+                firstDefault = gRec[i].fName;
+            } else {
+                if (!allButFirstDefaults.isEmpty()) {
+                    allButFirstDefaults.append(" ");
+                }
+                allButFirstDefaults.append(gRec[i].fName);
+            }
+        } else {
+            nonDefault = gRec[i].fName;
         }
     }
-    result.appendf("\"");
-
+    result.append("\"\n");
+    result.appendf("\"%s\" evaluates to the default set of configs.\n", kDefaultsConfigStr);
+    result.appendf("Prepending \"%c\" on a config name excludes it from the set of configs to run.\n"
+                   "Exclusions always override inclusions regardless of order.\n",
+                   kExcludeConfigChar);
+    result.appendf("E.g. \"--config %s %c%s %s\" will run these configs:\n\t%s %s",
+                   kDefaultsConfigStr,
+                   kExcludeConfigChar,
+                   firstDefault.c_str(),
+                   nonDefault.c_str(),
+                   allButFirstDefaults.c_str(),
+                   nonDefault.c_str());
     return result;
 }
 
@@ -1654,12 +1681,34 @@
     }
 
     for (int i = 0; i < FLAGS_config.count(); i++) {
-        int index = findConfig(FLAGS_config[i]);
+        const char* config = FLAGS_config[i];
+        userConfig = true;
+        bool exclude = false;
+        if (*config == kExcludeConfigChar) {
+            exclude = true;
+            config += 1;
+        }
+        int index = findConfig(config);
         if (index >= 0) {
-            appendUnique<size_t>(&configs, index);
-            userConfig = true;
+            if (exclude) {
+                *excludeConfigs.append() = index;
+            } else {
+                appendUnique<size_t>(&configs, index);
+            }
+        } else if (0 == strcmp(kDefaultsConfigStr, config)) {
+            for (size_t c = 0; c < SK_ARRAY_COUNT(gRec); ++c) {
+                if (gRec[c].fRunByDefault) {
+                    if (exclude) {
+                        gm_fprintf(stderr, "%c%s is not allowed.\n",
+                                   kExcludeConfigChar, kDefaultsConfigStr);
+                        return -1;
+                    } else {
+                        appendUnique<size_t>(&configs, c);
+                    }
+                }
+            }
         } else {
-            gm_fprintf(stderr, "unrecognized config %s\n", FLAGS_config[i]);
+            gm_fprintf(stderr, "unrecognized config %s\n", config);
             return -1;
         }
     }
@@ -1773,6 +1822,19 @@
     GrContextFactory* grFactory = NULL;
 #endif
 
+    if (configs.isEmpty()) {
+        gm_fprintf(stderr, "No configs to run.");
+        return -1;
+    }
+
+    // now show the user the set of configs that will be run.
+    SkString configStr("These configs will be run: ");
+    // show the user the config that will run.
+    for (int i = 0; i < configs.count(); ++i) {
+        configStr.appendf("%s%s", gRec[configs[i]].fName, (i == configs.count() - 1) ? "\n" : " ");
+    }
+    gm_fprintf(stdout, "%s", configStr.c_str());
+
     if (FLAGS_resourcePath.count() == 1) {
         GM::SetResourcePath(FLAGS_resourcePath[0]);
     }
diff --git a/gm/tests/outputs/compared-against-different-pixels-images/output-expected/stdout b/gm/tests/outputs/compared-against-different-pixels-images/output-expected/stdout
index 02ccb62..817fc87 100644
--- a/gm/tests/outputs/compared-against-different-pixels-images/output-expected/stdout
+++ b/gm/tests/outputs/compared-against-different-pixels-images/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: reading from gm/tests/inputs/images/different-pixels
 GM: drawing... selftest1 [300 200]
 GM: Ran 1 GMs
diff --git a/gm/tests/outputs/compared-against-different-pixels-json/output-expected/stdout b/gm/tests/outputs/compared-against-different-pixels-json/output-expected/stdout
index 5e34f19..9a299c5 100644
--- a/gm/tests/outputs/compared-against-different-pixels-json/output-expected/stdout
+++ b/gm/tests/outputs/compared-against-different-pixels-json/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: reading expectations from JSON summary file gm/tests/inputs/json/different-pixels.json
 GM: drawing... selftest1 [300 200]
 GM: Ran 1 GMs
diff --git a/gm/tests/outputs/compared-against-empty-dir/output-expected/stdout b/gm/tests/outputs/compared-against-empty-dir/output-expected/stdout
index 9482216..d5a1ada 100644
--- a/gm/tests/outputs/compared-against-empty-dir/output-expected/stdout
+++ b/gm/tests/outputs/compared-against-empty-dir/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: reading from gm/tests/inputs/images/empty-dir
 GM: drawing... selftest1 [300 200]
 GM: Ran 1 GMs
diff --git a/gm/tests/outputs/compared-against-identical-bytes-images/output-expected/stdout b/gm/tests/outputs/compared-against-identical-bytes-images/output-expected/stdout
index ee43b3e..d63fca5 100644
--- a/gm/tests/outputs/compared-against-identical-bytes-images/output-expected/stdout
+++ b/gm/tests/outputs/compared-against-identical-bytes-images/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: reading from gm/tests/inputs/images/identical-bytes
 GM: drawing... selftest1 [300 200]
 GM: Ran 1 GMs
diff --git a/gm/tests/outputs/compared-against-identical-bytes-json/output-expected/stdout b/gm/tests/outputs/compared-against-identical-bytes-json/output-expected/stdout
index 92c1b9f..0c2b49c 100644
--- a/gm/tests/outputs/compared-against-identical-bytes-json/output-expected/stdout
+++ b/gm/tests/outputs/compared-against-identical-bytes-json/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: reading expectations from JSON summary file gm/tests/inputs/json/identical-bytes.json
 GM: drawing... selftest1 [300 200]
 GM: Ran 1 GMs
diff --git a/gm/tests/outputs/compared-against-identical-pixels-images/output-expected/stdout b/gm/tests/outputs/compared-against-identical-pixels-images/output-expected/stdout
index 8a3dbaf..fd1703a 100644
--- a/gm/tests/outputs/compared-against-identical-pixels-images/output-expected/stdout
+++ b/gm/tests/outputs/compared-against-identical-pixels-images/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: reading from gm/tests/inputs/images/identical-pixels
 GM: drawing... selftest1 [300 200]
 GM: Ran 1 GMs
diff --git a/gm/tests/outputs/compared-against-identical-pixels-json/output-expected/stdout b/gm/tests/outputs/compared-against-identical-pixels-json/output-expected/stdout
index 0bc0fc4..b9c1e4a 100644
--- a/gm/tests/outputs/compared-against-identical-pixels-json/output-expected/stdout
+++ b/gm/tests/outputs/compared-against-identical-pixels-json/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: reading expectations from JSON summary file gm/tests/inputs/json/identical-pixels.json
 GM: drawing... selftest1 [300 200]
 GM: Ran 1 GMs
diff --git a/gm/tests/outputs/compared-against-nonexistent-dir/output-expected/stdout b/gm/tests/outputs/compared-against-nonexistent-dir/output-expected/stdout
index e69de29..94b3f8f 100644
--- a/gm/tests/outputs/compared-against-nonexistent-dir/output-expected/stdout
+++ b/gm/tests/outputs/compared-against-nonexistent-dir/output-expected/stdout
@@ -0,0 +1 @@
+GM: These configs will be run: 8888 565
diff --git a/gm/tests/outputs/ignore-expectations-mismatch/output-expected/stdout b/gm/tests/outputs/ignore-expectations-mismatch/output-expected/stdout
index 881c121..6ccc85d 100644
--- a/gm/tests/outputs/ignore-expectations-mismatch/output-expected/stdout
+++ b/gm/tests/outputs/ignore-expectations-mismatch/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: reading expectations from JSON summary file gm/tests/inputs/json/different-pixels.json
 GM: drawing... selftest1 [300 200]
 GM: Ran 1 GMs
diff --git a/gm/tests/outputs/intentionally-skipped-tests/output-expected/stdout b/gm/tests/outputs/intentionally-skipped-tests/output-expected/stdout
index 3165dd4..f7eec19 100644
--- a/gm/tests/outputs/intentionally-skipped-tests/output-expected/stdout
+++ b/gm/tests/outputs/intentionally-skipped-tests/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: drawing... selftest2 [300 200]
 GM: drawing... selftest1 [300 200]
 GM: Ran 2 GMs
diff --git a/gm/tests/outputs/no-readpath/output-expected/stdout b/gm/tests/outputs/no-readpath/output-expected/stdout
index a892db0..7ce257b 100644
--- a/gm/tests/outputs/no-readpath/output-expected/stdout
+++ b/gm/tests/outputs/no-readpath/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: drawing... selftest1 [300 200]
 GM: Ran 1 GMs
 GM: ... over  2 configs ["8888", "565"]
diff --git a/gm/tests/outputs/nonverbose/output-expected/stdout b/gm/tests/outputs/nonverbose/output-expected/stdout
index a287200..dc59708 100644
--- a/gm/tests/outputs/nonverbose/output-expected/stdout
+++ b/gm/tests/outputs/nonverbose/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: drawing... selftest1 [300 200]
 GM: Ran 9 tests: NoGpuContext=0 IntentionallySkipped=0 RenderModeMismatch=0 ExpectationsMismatch=0 MissingExpectations=2 WritingReferenceImage=0
 GM: [*] 0 NoGpuContext:
diff --git a/gm/tests/outputs/pipe-playback-failure/output-expected/stdout b/gm/tests/outputs/pipe-playback-failure/output-expected/stdout
index 64127be..811f5a7 100644
--- a/gm/tests/outputs/pipe-playback-failure/output-expected/stdout
+++ b/gm/tests/outputs/pipe-playback-failure/output-expected/stdout
@@ -1,3 +1,4 @@
+GM: These configs will be run: 8888 565
 GM: reading expectations from JSON summary file gm/tests/inputs/json/identical-pixels.json
 GM: drawing... selftest1 [300 200]
 GM: Ran 1 GMs