aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/bookmaker/bookmaker.cpp51
-rw-r--r--tools/bookmaker/bookmaker.h44
-rw-r--r--tools/bookmaker/cataloger.cpp6
-rw-r--r--tools/bookmaker/fiddleParser.cpp141
-rw-r--r--tools/bookmaker/includeParser.cpp3
-rw-r--r--tools/bookmaker/parserCommon.cpp7
6 files changed, 142 insertions, 110 deletions
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index ffd3012e24..1b8e76ee33 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -703,6 +703,55 @@ Definition* BmhParser::findExample(string name) const {
return nullptr;
}
+static bool check_example_hashes(Definition* def) {
+ if (MarkType::kExample == def->fMarkType) {
+ if (def->fHash.length()) {
+ return true;
+ }
+ for (auto child : def->fChildren) {
+ if (MarkType::kPlatform == child->fMarkType) {
+ if (string::npos != string(child->fContentStart, child->length()).find("!fiddle")) {
+ return true;
+ }
+ }
+ }
+ return def->reportError<bool>("missing hash");
+ }
+ for (auto& child : def->fChildren) {
+ if (!check_example_hashes(child)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool BmhParser::checkExampleHashes() const {
+ for (const auto& topic : fTopicMap) {
+ if (!topic.second->fParent && !check_example_hashes(topic.second)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void reset_example_hashes(Definition* def) {
+ if (MarkType::kExample == def->fMarkType) {
+ def->fHash.clear();
+ return;
+ }
+ for (auto& child : def->fChildren) {
+ reset_example_hashes(child);
+ }
+}
+
+void BmhParser::resetExampleHashes() {
+ for (const auto& topic : fTopicMap) {
+ if (!topic.second->fParent) {
+ reset_example_hashes(topic.second);
+ }
+ }
+}
+
static void find_examples(const Definition& def, vector<string>* exampleNames) {
if (MarkType::kExample == def.fMarkType) {
exampleNames->push_back(def.fFiddle);
@@ -2640,7 +2689,7 @@ int main(int argc, char** const argv) {
}
if (!done && !FLAGS_fiddle.isEmpty() && FLAGS_examples.isEmpty()) {
FiddleParser fparser(&bmhParser);
- if (!fparser.parseFile(FLAGS_fiddle[0], ".txt", ParserCommon::OneFile::kNo)) {
+ if (!fparser.parseFromFile(FLAGS_fiddle[0])) {
return -1;
}
}
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index c695cff0e8..19ea86b68d 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -1328,19 +1328,29 @@ struct JsonStatus {
string fName;
};
-class StatusIter : public ParserCommon {
+class JsonCommon : public ParserCommon {
+public:
+ bool empty() { return fStack.empty(); }
+ bool parseFromFile(const char* path) override;
+
+ void reset() override {
+ fStack.clear();
+ INHERITED::resetCommon();
+ }
+
+ vector<JsonStatus> fStack;
+ Json::Value fRoot;
+private:
+ typedef ParserCommon INHERITED;
+};
+
+class StatusIter : public JsonCommon {
public:
StatusIter(const char* statusFile, const char* suffix, StatusFilter);
~StatusIter() override {}
string baseDir();
- bool empty() { return fStack.empty(); }
bool next(string* file);
-protected:
- bool parseFromFile(const char* path) override;
- void reset() override;
private:
- vector<JsonStatus> fStack;
- Json::Value fRoot;
const char* fSuffix;
StatusFilter fFilter;
};
@@ -1415,6 +1425,7 @@ public:
bool checkParamReturn(const Definition* definition) const;
bool dumpExamples(FILE* fiddleOut, Definition& def, bool* continuation) const;
bool dumpExamples(const char* fiddleJsonFileName) const;
+ bool checkExampleHashes() const;
bool childOf(MarkType markType) const;
string className(MarkType markType);
bool collectExternals();
@@ -1441,6 +1452,7 @@ public:
bool popParentStack(Definition* definition);
void reportDuplicates(const Definition& def, string dup) const;
+ void resetExampleHashes();
void reset() override {
INHERITED::resetCommon();
@@ -2084,10 +2096,10 @@ private:
typedef IncludeParser INHERITED;
};
-class FiddleBase : public ParserCommon {
+class FiddleBase : public JsonCommon {
protected:
- FiddleBase(BmhParser* bmh) : ParserCommon()
- , fBmhParser(bmh)
+ FiddleBase(BmhParser* bmh)
+ : fBmhParser(bmh)
, fContinuation(false)
, fTextOut(false)
, fPngOut(false)
@@ -2096,7 +2108,7 @@ protected:
}
void reset() override {
- INHERITED::resetCommon();
+ INHERITED::reset();
}
Definition* findExample(string name) const { return fBmhParser->findExample(name); }
@@ -2111,7 +2123,7 @@ protected:
bool fTextOut;
bool fPngOut;
private:
- typedef ParserCommon INHERITED;
+ typedef JsonCommon INHERITED;
};
class FiddleParser : public FiddleBase {
@@ -2121,10 +2133,14 @@ public:
}
bool parseFromFile(const char* path) override {
- if (!INHERITED::parseSetup(path)) {
+ if (!INHERITED::parseFromFile(path)) {
+ return false;
+ }
+ fBmhParser->resetExampleHashes();
+ if (!INHERITED::parseFiddles()) {
return false;
}
- return parseFiddles();
+ return fBmhParser->checkExampleHashes();
}
private:
diff --git a/tools/bookmaker/cataloger.cpp b/tools/bookmaker/cataloger.cpp
index 0e1e38ac45..c6aae74c30 100644
--- a/tools/bookmaker/cataloger.cpp
+++ b/tools/bookmaker/cataloger.cpp
@@ -79,14 +79,13 @@ bool Catalog::closeCatalog() {
}
bool Catalog::parseFromFile(const char* path) {
- if (!INHERITED::parseSetup(path)) {
+ if (!INHERITED::parseFromFile(path)) {
return false;
}
fIndent = 4;
this->writeString("var text = {");
this->lf(1);
fTextOut = true;
- TextParserSave save(this);
if (!parseFiddles()) {
return false;
}
@@ -96,7 +95,8 @@ bool Catalog::parseFromFile(const char* path) {
this->writeString("var pngs = {");
fTextOut = false;
fPngOut = true;
- save.restore();
+ JsonStatus* status = &fStack.back();
+ status->fIter = status->fObject.begin();
fContinuation = false;
return parseFiddles();
}
diff --git a/tools/bookmaker/fiddleParser.cpp b/tools/bookmaker/fiddleParser.cpp
index 524f89d020..990ff201fb 100644
--- a/tools/bookmaker/fiddleParser.cpp
+++ b/tools/bookmaker/fiddleParser.cpp
@@ -8,106 +8,73 @@
#include "bookmaker.h"
bool FiddleBase::parseFiddles() {
- if (!this->skipExact("{\n")) {
+ if (fStack.empty()) {
return false;
}
- while (!this->eof()) {
- if (!this->skipExact(" \"")) {
- return false;
- }
- const char* nameLoc = fChar;
- if (!this->skipToEndBracket("\"")) {
- return false;
- }
- string name(nameLoc, fChar - nameLoc);
- if (!this->skipExact("\": {\n")) {
- return false;
- }
- if (!this->skipExact(" \"compile_errors\": [")) {
- return false;
- }
- if (']' != this->peek()) {
- // report compiler errors
- int brackets = 1;
- do {
- if ('[' == this->peek()) {
- ++brackets;
- } else if (']' == this->peek()) {
- --brackets;
+ JsonStatus* status = &fStack.back();
+ while (status->fIter != status->fObject.end()) {
+ const char* blockName = status->fIter.memberName();
+ Definition* example = nullptr;
+ string textString;
+ if (!status->fObject.isObject()) {
+ return this->reportError<bool>("expected object");
+ }
+ for (auto iter = status->fIter->begin(); status->fIter->end() != iter; ++iter) {
+ const char* memberName = iter.memberName();
+ if (!strcmp("compile_errors", memberName)) {
+ if (!iter->isArray()) {
+ return this->reportError<bool>("expected array");
}
- } while (!this->eof() && this->next() && brackets > 0);
- this->reportError("fiddle compile error");
- }
- if (!this->skipExact("],\n")) {
- return false;
- }
- if (!this->skipExact(" \"runtime_error\": \"")) {
- return false;
- }
- if ('"' != this->peek()) {
- if (!this->skipToEndBracket('"')) {
- return false;
+ if (iter->size()) {
+ return this->reportError<bool>("fiddle compiler error");
+ }
+ continue;
}
- this->reportError("fiddle runtime error");
- }
- if (!this->skipExact("\",\n")) {
- return false;
- }
- if (!this->skipExact(" \"fiddleHash\": \"")) {
- return false;
- }
- const char* hashStart = fChar;
- if (!this->skipToEndBracket('"')) {
- return false;
- }
- Definition* example = this->findExample(name);
- if (!example) {
- this->reportError("missing example");
- }
- string hash(hashStart, fChar - hashStart);
- if (example) {
- example->fHash = hash;
- }
- if (!this->skipExact("\",\n")) {
- return false;
- }
- if (!this->skipExact(" \"text\": \"")) {
- return false;
- }
- if ('"' != this->peek()) {
- const char* stdOutStart = fChar;
- do {
- if ('\\' == this->peek()) {
- this->next();
- } else if ('"' == this->peek()) {
- break;
+ if (!strcmp("runtime_error", memberName)) {
+ if (!iter->isString()) {
+ return this->reportError<bool>("expected string 1");
+ }
+ if (iter->asString().length()) {
+ return this->reportError<bool>("fiddle runtime error");
}
- } while (!this->eof() && this->next());
- const char* stdOutEnd = fChar;
- if (example && fTextOut) {
- if (!this->textOut(example, stdOutStart, stdOutEnd)) {
- return false;
+ continue;
+ }
+ if (!strcmp("fiddleHash", memberName)) {
+ if (!iter->isString()) {
+ return this->reportError<bool>("expected string 2");
+ }
+ example = this->findExample(blockName);
+ if (!example) {
+ return this->reportError<bool>("missing example");
+ }
+ if (example->fHash.length() && example->fHash != iter->asString()) {
+ return example->reportError<bool>("mismatched hash");
}
+ example->fHash = iter->asString();
+ continue;
}
- } else {
- if (example && fPngOut) {
- if (!this->pngOut(example)) {
- return false;
+ if (!strcmp("text", memberName)) {
+ if (!iter->isString()) {
+ return this->reportError<bool>("expected string 3");
}
+ textString = iter->asString();
+ continue;
}
+ return this->reportError<bool>("unexpected key");
}
- if (!this->skipExact("\"\n")) {
- return false;
- }
- if (!this->skipExact(" }")) {
- return false;
- }
- if ('\n' == this->peek()) {
- break;
+ if (!example) {
+ return this->reportError<bool>("missing fiddleHash");
}
- if (!this->skipExact(",\n")) {
+ size_t strLen = textString.length();
+ if (strLen) {
+ if (fTextOut
+ && !this->textOut(example, textString.c_str(), textString.c_str() + strLen)) {
+ return false;
+ }
+ } else if (fPngOut && !this->pngOut(example)) {
return false;
}
+ status->fIter++;
}
return true;
}
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index fc378ddb45..d6594ea72c 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -2464,6 +2464,9 @@ bool IncludeParser::parseChar() {
if (!this->checkForWord()) {
return false;
}
+ if (!fParent->fTokens.size()) {
+ break;
+ }
{
const Definition& lastToken = fParent->fTokens.back();
if (lastToken.fType != Definition::Type::kWord) {
diff --git a/tools/bookmaker/parserCommon.cpp b/tools/bookmaker/parserCommon.cpp
index 33bf14918e..fb00b167a8 100644
--- a/tools/bookmaker/parserCommon.cpp
+++ b/tools/bookmaker/parserCommon.cpp
@@ -392,7 +392,7 @@ bool StatusIter::next(string* str) {
return true;
}
-bool StatusIter::parseFromFile(const char* path) {
+bool JsonCommon::parseFromFile(const char* path) {
sk_sp<SkData> json(SkData::MakeFromFileName(path));
if (!json) {
SkDebugf("file %s:\n", path);
@@ -400,7 +400,7 @@ bool StatusIter::parseFromFile(const char* path) {
}
Json::Reader reader;
const char* data = (const char*)json->data();
- if (!reader.parse(data, data+json->size(), fRoot)) {
+ if (!reader.parse(data, data + json->size(), fRoot)) {
SkDebugf("file %s:\n", path);
return this->reportError<bool>("file not parsable");
}
@@ -409,6 +409,3 @@ bool StatusIter::parseFromFile(const char* path) {
return true;
}
-void StatusIter::reset() {
- fStack.clear();
-}