Accept processor test seed from command line

Also adds support for uint32_t CLI flags, parsed as octal, hex, or dec.

Bug: skia:
Change-Id: I87112beb6506a65d6f541c7ca4cfb38641d55aa5
Reviewed-on: https://skia-review.googlesource.com/158040
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index cc35f90..6e241a2 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -221,6 +221,8 @@
 
 #include "SkCommandLineFlags.h"
 DEFINE_bool(randomProcessorTest, false, "Use non-deterministic seed for random processor tests?");
+DEFINE_uint32(processorSeed, 0, "Use specific seed for processor tests. Overridden by " \
+                                "--randomProcessorTest.");
 
 #if GR_TEST_UTILS
 
@@ -314,13 +316,13 @@
     auto resourceProvider = context->contextPriv().resourceProvider();
     using FPFactory = GrFragmentProcessorTestFactory;
 
-    uint32_t seed = 0;
+    uint32_t seed = FLAGS_processorSeed;
     if (FLAGS_randomProcessorTest) {
         std::random_device rd;
         seed = rd();
     }
     // If a non-deterministic bot fails this test, check the output to see what seed it used, then
-    // hard-code that value here:
+    // use --processorSeed <seed> (without --randomProcessorTest) to reproduce.
     SkRandom random(seed);
 
     // Make the destination context for the test.
diff --git a/tools/flags/SkCommandLineFlags.cpp b/tools/flags/SkCommandLineFlags.cpp
index 3924812..62625e1 100644
--- a/tools/flags/SkCommandLineFlags.cpp
+++ b/tools/flags/SkCommandLineFlags.cpp
@@ -328,6 +328,10 @@
                             i++;
                             flag->setInt(atoi(argv[i]));
                             break;
+                        case SkFlagInfo::kUint_FlagType:
+                            i++;
+                            flag->setUint(strtoul(argv[i], nullptr, 0));
+                            break;
                         case SkFlagInfo::kDouble_FlagType:
                             i++;
                             flag->setDouble(atof(argv[i]));
diff --git a/tools/flags/SkCommandLineFlags.h b/tools/flags/SkCommandLineFlags.h
index 4a22c3f..bf4a41e 100644
--- a/tools/flags/SkCommandLineFlags.h
+++ b/tools/flags/SkCommandLineFlags.h
@@ -60,8 +60,18 @@
  *
  *  double FLAGS_real;
  *
+ *  and
+ *
+ *  DEFINE_uint32(unsigned, ...);
+ *
+ *  will create
+ *
+ *  uint32_t FLAGS_unsigned;
+ *
  *  These flags can be set by specifying, for example, "--integer 7" and
- *  "--real 3.14" on the command line.
+ *  "--real 3.14" on the command line. Unsigned integers are parsed from the
+ *  command line using strtoul() so will detect the base (0 for octal, and
+ *  0x or 0X for hex, otherwise assumes decimal).
  *
  *  Unlike the others, the line
  *
@@ -263,6 +273,25 @@
 
 #define DECLARE_int32(name) extern int32_t FLAGS_##name;
 
+
+#define DEFINE_uint32(name, defaultValue, helpString)                                 \
+uint32_t FLAGS_##name;                                                                \
+SK_UNUSED static bool unused_##name = SkFlagInfo::CreateUintFlag(TO_STRING(name),     \
+                                                                 &FLAGS_##name,       \
+                                                                 defaultValue,        \
+                                                                 helpString)
+
+#define DEFINE_uint32_2(name, shortName, defaultValue, helpString)                    \
+uint32_t FLAGS_##name;                                                                \
+SK_UNUSED static bool unused_##name = SkFlagInfo::CreateUintFlag(TO_STRING(name),     \
+                                                                 TO_STRING(shortName),\
+                                                                 &FLAGS_##name,       \
+                                                                 defaultValue,        \
+                                                                 helpString)
+
+#define DECLARE_uint32(name) extern uint32_t FLAGS_##name;
+
+
 #define DEFINE_double(name, defaultValue, helpString)                       \
 double FLAGS_##name;                                                        \
 SK_UNUSED static bool unused_##name = SkFlagInfo::CreateDoubleFlag(TO_STRING(name),   \
@@ -279,6 +308,7 @@
         kBool_FlagType,
         kString_FlagType,
         kInt_FlagType,
+        kUint_FlagType,
         kDouble_FlagType,
     };
 
@@ -337,6 +367,25 @@
     /**
      *  See comments for CreateBoolFlag.
      */
+    static bool CreateUintFlag(const char* name, uint32_t* pUint,
+                               uint32_t defaultValue, const char* helpString) {
+        SkFlagInfo* info = new SkFlagInfo(name, nullptr, kUint_FlagType, helpString, nullptr);
+        info->fUintValue = pUint;
+        *info->fUintValue = info->fDefaultUint = defaultValue;
+        return true;
+    }
+
+    static bool CreateUintFlag(const char* name, const char* shortName, uint32_t* pUint,
+                               uint32_t defaultValue, const char* helpString) {
+        SkFlagInfo* info = new SkFlagInfo(name, shortName, kUint_FlagType, helpString, nullptr);
+        info->fUintValue = pUint;
+        *info->fUintValue = info->fDefaultUint = defaultValue;
+        return true;
+    }
+
+    /**
+     *  See comments for CreateBoolFlag.
+     */
     static bool CreateDoubleFlag(const char* name, double* pDouble,
                                  double defaultValue, const char* helpString) {
         SkFlagInfo* info = new SkFlagInfo(name, nullptr, kDouble_FlagType, helpString, nullptr);
@@ -386,6 +435,14 @@
         }
     }
 
+    void setUint(uint32_t value) {
+        if (kUint_FlagType == fFlagType) {
+            *fUintValue = value;
+        } else {
+            SkDEBUGFAIL("Can only call setUint on kUint_FlagType");
+        }
+    }
+
     void setDouble(double value) {
         if (kDouble_FlagType == fFlagType) {
             *fDoubleValue = value;
@@ -422,6 +479,9 @@
             case SkFlagInfo::kInt_FlagType:
                 result.printf("%i", fDefaultInt);
                 break;
+            case SkFlagInfo::kUint_FlagType:
+                result.printf("0x%08x", fDefaultUint);
+                break;
             case SkFlagInfo::kDouble_FlagType:
                 result.printf("%2.2f", fDefaultDouble);
                 break;
@@ -439,6 +499,8 @@
                 return SkString("string");
             case SkFlagInfo::kInt_FlagType:
                 return SkString("int");
+            case SkFlagInfo::kUint_FlagType:
+                return SkString("uint");
             case SkFlagInfo::kDouble_FlagType:
                 return SkString("double");
             default:
@@ -459,6 +521,8 @@
         , fDefaultBool(false)
         , fIntValue(nullptr)
         , fDefaultInt(0)
+        , fUintValue(nullptr)
+        , fDefaultUint(0)
         , fDoubleValue(nullptr)
         , fDefaultDouble(0)
         , fStrings(nullptr) {
@@ -487,6 +551,8 @@
     bool                 fDefaultBool;
     int32_t*             fIntValue;
     int32_t              fDefaultInt;
+    uint32_t*            fUintValue;
+    uint32_t             fDefaultUint;
     double*              fDoubleValue;
     double               fDefaultDouble;
     SkCommandLineFlags::StringArray* fStrings;