diff options
-rw-r--r-- | dm/DM.cpp | 16 | ||||
-rw-r--r-- | dm/DMTask.cpp | 11 | ||||
-rw-r--r-- | dm/DMTask.h | 7 | ||||
-rw-r--r-- | dm/DMWriteTask.cpp | 51 | ||||
-rw-r--r-- | dm/DMWriteTask.h | 8 | ||||
-rw-r--r-- | include/core/SkString.h | 4 | ||||
-rw-r--r-- | src/core/SkString.cpp | 12 | ||||
-rw-r--r-- | tests/StringTest.cpp | 13 |
8 files changed, 81 insertions, 41 deletions
@@ -6,6 +6,7 @@ #include "SkCommandLineFlags.h" #include "SkForceLinking.h" #include "SkGraphics.h" +#include "SkString.h" #include "gm.h" #include "DMReporter.h" @@ -39,19 +40,6 @@ DEFINE_string(config, "8888 gpu", __SK_FORCE_IMAGE_DECODER_LINKING; -// Split str on any characters in delimiters into out. (Think, strtok with a sane API.) -static void split(const char* str, const char* delimiters, SkTArray<SkString>* out) { - const char* end = str + strlen(str); - while (str != end) { - // Find a token. - const size_t len = strcspn(str, delimiters); - out->push_back().set(str, len); - str += len; - // Skip any delimiters. - str += strspn(str, delimiters); - } -} - // "FooBar" -> "foobar". Obviously, ASCII only. static SkString lowercase(SkString s) { for (size_t i = 0; i < s.size(); i++) { @@ -134,7 +122,7 @@ int tool_main(int argc, char** argv) { GM::SetResourcePath(FLAGS_resources[0]); SkTArray<SkString> configs; for (int i = 0; i < FLAGS_config.count(); i++) { - split(FLAGS_config[i], ", ", &configs); + SkStrSplit(FLAGS_config[i], ", ", &configs); } SkTDArray<GMRegistry::Factory> gms; diff --git a/dm/DMTask.cpp b/dm/DMTask.cpp index ba74a5f409..a5c75f0f8a 100644 --- a/dm/DMTask.cpp +++ b/dm/DMTask.cpp @@ -8,14 +8,15 @@ namespace DM { Task::Task(Reporter* reporter, TaskRunner* taskRunner) - : fReporter(reporter), fTaskRunner(taskRunner) { + : fReporter(reporter), fTaskRunner(taskRunner), fDepth(0) { fReporter->start(); } -Task::Task(const Task& that) - : INHERITED(that) - , fReporter(that.fReporter) - , fTaskRunner(that.fTaskRunner) { +Task::Task(const Task& parent) + : INHERITED(parent) + , fReporter(parent.fReporter) + , fTaskRunner(parent.fTaskRunner) + , fDepth(parent.depth()+1) { fReporter->start(); } diff --git a/dm/DMTask.h b/dm/DMTask.h index 5388196ffd..0d3ef74cc3 100644 --- a/dm/DMTask.h +++ b/dm/DMTask.h @@ -18,7 +18,7 @@ class TaskRunner; class Task : public SkRunnable { public: Task(Reporter* reporter, TaskRunner* taskRunner); - Task(const Task& that); + Task(const Task& parent); virtual ~Task(); void run() SK_OVERRIDE; @@ -28,6 +28,10 @@ public: virtual bool shouldSkip() const = 0; virtual SkString name() const = 0; + // Returns the number of parents above this task. + // Top-level tasks return 0, their children 1, and so on. + int depth() const { return fDepth; } + protected: void spawnChild(Task* task); void fail(); @@ -36,6 +40,7 @@ private: // Both unowned. Reporter* fReporter; TaskRunner* fTaskRunner; + int fDepth; typedef SkRunnable INHERITED; }; diff --git a/dm/DMWriteTask.cpp b/dm/DMWriteTask.cpp index 011b339540..c86381f78a 100644 --- a/dm/DMWriteTask.cpp +++ b/dm/DMWriteTask.cpp @@ -3,41 +3,54 @@ #include "DMUtil.h" #include "SkCommandLineFlags.h" #include "SkImageEncoder.h" - -#include <string.h> +#include "SkString.h" DEFINE_string2(writePath, w, "", "If set, write GMs here as .pngs."); namespace DM { -WriteTask::WriteTask(const Task& parent, SkBitmap bitmap) - : Task(parent) - , fBitmap(bitmap) { - // Split parent's name <gmName>_<config> into gmName and config. - const char* parentName = parent.name().c_str(); - const char* fromLastUnderscore = strrchr(parentName, '_'); - const ptrdiff_t gmNameLength = fromLastUnderscore - parentName; +WriteTask::WriteTask(const Task& parent, SkBitmap bitmap) : Task(parent), fBitmap(bitmap) { + const int suffixes = parent.depth() + 1; + const char* name = parent.name().c_str(); + SkTArray<SkString> split; + SkStrSplit(name, "_", &split); + int totalSuffixLength = 0; + for (int i = 0; i < suffixes; i++) { + // We're splitting off suffixes from the back to front. + fSuffixes.push_back(split[split.count()-i-1]); + totalSuffixLength += fSuffixes.back().size() + 1; + } + fGmName.set(name, strlen(name)-totalSuffixLength); +} - fConfig.set(fromLastUnderscore+1); - fGmName.set(parentName, gmNameLength); +void WriteTask::makeDirOrFail(SkString dir) { + if (!sk_mkdir(dir.c_str())) { + this->fail(); + } } void WriteTask::draw() { - const char* root = FLAGS_writePath[0]; - const SkString dir = SkOSPath::SkPathJoin(root, fConfig.c_str()); - if (!sk_mkdir(root) || - !sk_mkdir(dir.c_str()) || - !SkImageEncoder::EncodeFile(Png(SkOSPath::SkPathJoin(dir.c_str(), fGmName.c_str())).c_str(), + SkString dir(FLAGS_writePath[0]); + this->makeDirOrFail(dir); + for (int i = 0; i < fSuffixes.count(); i++) { + dir = SkOSPath::SkPathJoin(dir.c_str(), fSuffixes[i].c_str()); + this->makeDirOrFail(dir); + } + if (!SkImageEncoder::EncodeFile(Png(SkOSPath::SkPathJoin(dir.c_str(), fGmName.c_str())).c_str(), fBitmap, SkImageEncoder::kPNG_Type, - 100/*quality*/)) - { + 100/*quality*/)) { this->fail(); } } SkString WriteTask::name() const { - return SkStringPrintf("writing %s/%s.png", fConfig.c_str(), fGmName.c_str()); + SkString name("writing "); + for (int i = 0; i < fSuffixes.count(); i++) { + name.appendf("%s/", fSuffixes[i].c_str()); + } + name.append(fGmName.c_str()); + return name; } bool WriteTask::shouldSkip() const { diff --git a/dm/DMWriteTask.h b/dm/DMWriteTask.h index 7a9b4faf8a..82a26bc928 100644 --- a/dm/DMWriteTask.h +++ b/dm/DMWriteTask.h @@ -4,6 +4,7 @@ #include "DMTask.h" #include "SkBitmap.h" #include "SkString.h" +#include "SkTArray.h" // Writes a bitmap to a file. @@ -12,7 +13,8 @@ namespace DM { class WriteTask : public Task { public: - WriteTask(const Task& parent, SkBitmap bitmap); + WriteTask(const Task& parent, // WriteTask must be a child Task. Pass its parent here. + SkBitmap bitmap); // Bitmap to write. virtual void draw() SK_OVERRIDE; virtual bool usesGpu() const SK_OVERRIDE { return false; } @@ -20,9 +22,11 @@ public: virtual SkString name() const SK_OVERRIDE; private: - SkString fConfig; + SkTArray<SkString> fSuffixes; SkString fGmName; const SkBitmap fBitmap; + + void makeDirOrFail(SkString dir); }; } // namespace DM diff --git a/include/core/SkString.h b/include/core/SkString.h index 291bd65696..ce87312f12 100644 --- a/include/core/SkString.h +++ b/include/core/SkString.h @@ -11,6 +11,7 @@ #define SkString_DEFINED #include "SkScalar.h" +#include "SkTArray.h" #include <stdarg.h> @@ -244,4 +245,7 @@ template <> inline void SkTSwap(SkString& a, SkString& b) { a.swap(b); } +// Split str on any characters in delimiters into out. (Think, strtok with a sane API.) +void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out); + #endif diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp index e30b89f199..643dfb1372 100644 --- a/src/core/SkString.cpp +++ b/src/core/SkString.cpp @@ -634,5 +634,17 @@ SkString SkStringPrintf(const char* format, ...) { return formattedOutput; } +void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out) { + const char* end = str + strlen(str); + while (str != end) { + // Find a token. + const size_t len = strcspn(str, delimiters); + out->push_back().set(str, len); + str += len; + // Skip any delimiters. + str += strspn(str, delimiters); + } +} + #undef VSNPRINTF #undef SNPRINTF diff --git a/tests/StringTest.cpp b/tests/StringTest.cpp index 462fcfadaf..c8c10e1925 100644 --- a/tests/StringTest.cpp +++ b/tests/StringTest.cpp @@ -192,3 +192,16 @@ static void TestString(skiatest::Reporter* reporter) { #include "TestClassDef.h" DEFINE_TESTCLASS("String", StringTestClass, TestString) + +DEF_TEST(String_SkStrSplit, r) { + SkTArray<SkString> results; + + SkStrSplit("a-_b_c-dee--f-_-_-g-", "-_", &results); + REPORTER_ASSERT(r, results.count() == 6); + REPORTER_ASSERT(r, results[0].equals("a")); + REPORTER_ASSERT(r, results[1].equals("b")); + REPORTER_ASSERT(r, results[2].equals("c")); + REPORTER_ASSERT(r, results[3].equals("dee")); + REPORTER_ASSERT(r, results[4].equals("f")); + REPORTER_ASSERT(r, results[5].equals("g")); +} |