aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/bookmaker
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2017-10-31 15:44:45 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-31 20:09:25 +0000
commitbef063af14d0608a5c40fe4473fbfaf1db591603 (patch)
tree9bd7cb9535b0e6f0d37182ba468b2c25ebab0140 /tools/bookmaker
parent43fd6d848583b554316c84956df0d5908402981c (diff)
cataloger
Docs-Preview: https://skia.org/?cl=64900 Bug: skia:6898 Change-Id: Ifbaf909854680a88060f16b1559863cc124aaa7a Reviewed-on: https://skia-review.googlesource.com/64900 Commit-Queue: Cary Clark <caryclark@skia.org> Reviewed-by: Cary Clark <caryclark@skia.org>
Diffstat (limited to 'tools/bookmaker')
-rw-r--r--tools/bookmaker/bookmaker.cpp79
-rw-r--r--tools/bookmaker/bookmaker.h76
-rw-r--r--tools/bookmaker/cataloger.cpp143
-rw-r--r--tools/bookmaker/fiddleParser.cpp149
-rw-r--r--tools/bookmaker/parserCommon.cpp2
5 files changed, 325 insertions, 124 deletions
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index e0694071e2..ca60084100 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -11,13 +11,14 @@
#include "SkOSPath.h"
DEFINE_string2(bmh, b, "", "Path to a *.bmh file or a directory.");
+DEFINE_bool2(catalog, c, false, "Write example catalog.htm. (Requires -b -f -r)");
DEFINE_string2(examples, e, "", "File of fiddlecli input, usually fiddle.json (For now, disables -r -f -s)");
DEFINE_string2(fiddle, f, "", "File of fiddlecli output, usually fiddleout.json.");
DEFINE_string2(include, i, "", "Path to a *.h file or a directory.");
DEFINE_bool2(hack, k, false, "Do a find/replace hack to update all *.bmh files. (Requires -b)");
DEFINE_bool2(stdout, o, false, "Write file out to standard out.");
DEFINE_bool2(populate, p, false, "Populate include from bmh. (Requires -b -i)");
-DEFINE_string2(ref, r, "", "Resolve refs and write bmh_*.md files to path. (Requires -b)");
+DEFINE_string2(ref, r, "", "Resolve refs and write bmh_*.md files to path. (Requires -b -f)");
DEFINE_string2(spellcheck, s, "", "Spell-check [once, all, mispelling]. (Requires -b)");
DEFINE_string2(tokens, t, "", "Directory to write bmh from include. (Requires -i)");
DEFINE_bool2(crosscheck, x, false, "Check bmh against includes. (Requires -b -i)");
@@ -214,7 +215,7 @@ void Definition::setCanonicalFiddle() {
fFiddle = normalized_name(result);
}
-bool Definition::exampleToScript(string* result) const {
+bool Definition::exampleToScript(string* result, ExampleOptions exampleOptions) const {
bool hasFiddle = true;
const Definition* platform = this->hasChild(MarkType::kPlatform);
if (platform) {
@@ -307,19 +308,37 @@ bool Definition::exampleToScript(string* result) const {
code += "}";
}
string example = "\"" + normalizedName + "\": {\n";
- example += " \"code\": \"" + code + "\",\n";
- example += " \"options\": {\n";
- example += " \"width\": " + widthStr + ",\n";
- example += " \"height\": " + heightStr + ",\n";
- example += " \"source\": " + imageStr + ",\n";
- example += " \"srgb\": false,\n";
- example += " \"f16\": false,\n";
- example += " \"textOnly\": " + textOutStr + ",\n";
- example += " \"animated\": false,\n";
- example += " \"duration\": 0\n";
- example += " },\n";
- example += " \"fast\": true\n";
- example += "}";
+ size_t nameStart = fFileName.find("\\", 0);
+ SkASSERT(string::npos != nameStart);
+ string baseFile = fFileName.substr(nameStart + 1, fFileName.length() - nameStart - 5);
+ if (ExampleOptions::kText == exampleOptions) {
+ example += " \"code\": \"" + code + "\",\n";
+ example += " \"hash\": \"" + fHash + "\",\n";
+ example += " \"file\": \"" + baseFile + "\",\n";
+ example += " \"name\": \"" + fName + "\",";
+ } else {
+ example += " \"code\": \"" + code + "\",\n";
+ if (ExampleOptions::kPng == exampleOptions) {
+ example += " \"width\": " + widthStr + ",\n";
+ example += " \"height\": " + heightStr + ",\n";
+ example += " \"hash\": \"" + fHash + "\",\n";
+ example += " \"file\": \"" + baseFile + "\",\n";
+ example += " \"name\": \"" + fName + "\"\n";
+ example += "}";
+ } else {
+ example += " \"options\": {\n";
+ example += " \"width\": " + widthStr + ",\n";
+ example += " \"height\": " + heightStr + ",\n";
+ example += " \"source\": " + imageStr + ",\n";
+ example += " \"srgb\": false,\n";
+ example += " \"f16\": false,\n";
+ example += " \"textOnly\": " + textOutStr + ",\n";
+ example += " \"animated\": false,\n";
+ example += " \"duration\": 0\n";
+ example += " },\n";
+ example += " \"fast\": true";
+ }
+ }
*result = example;
return true;
}
@@ -754,6 +773,7 @@ bool Definition::nextMethodParam(TextParser* methodParser, const char** nextEndP
}
bool ParserCommon::parseFile(const char* fileOrPath, const char* suffix) {
+// this->reset();
if (!sk_isdir(fileOrPath)) {
if (!this->parseFromFile(fileOrPath)) {
SkDebugf("failed to parse %s\n", fileOrPath);
@@ -1398,10 +1418,12 @@ bool BmhParser::collectExternals() {
static bool dump_examples(FILE* fiddleOut, const Definition& def, bool* continuation) {
if (MarkType::kExample == def.fMarkType) {
string result;
- if (!def.exampleToScript(&result)) {
+ if (!def.exampleToScript(&result, Definition::ExampleOptions::kAll)) {
return false;
}
if (result.length() > 0) {
+ result += "\n";
+ result += "}";
if (*continuation) {
fprintf(fiddleOut, ",\n");
} else {
@@ -2245,6 +2267,11 @@ int main(int argc, char** const argv) {
SkCommandLineFlags::PrintUsage();
return 1;
}
+ if ((FLAGS_bmh.isEmpty() || FLAGS_fiddle.isEmpty() || FLAGS_ref.isEmpty()) && FLAGS_catalog) {
+ SkDebugf("-c requires -b -f -r\n");
+ SkCommandLineFlags::PrintUsage();
+ return 1;
+ }
if (FLAGS_bmh.isEmpty() && !FLAGS_examples.isEmpty()) {
SkDebugf("-e requires -b\n");
SkCommandLineFlags::PrintUsage();
@@ -2289,6 +2316,7 @@ int main(int argc, char** const argv) {
return 1;
}
if (!FLAGS_bmh.isEmpty()) {
+ bmhParser.reset();
if (!bmhParser.parseFile(FLAGS_bmh[0], ".bmh")) {
return -1;
}
@@ -2327,11 +2355,26 @@ int main(int argc, char** const argv) {
done = true;
}
}
- FiddleParser fparser(&bmhParser);
- if (!done && !FLAGS_fiddle.isEmpty() && FLAGS_examples.isEmpty()) {
+ if (!done && !FLAGS_catalog && !FLAGS_fiddle.isEmpty() && FLAGS_examples.isEmpty()) {
+ FiddleParser fparser(&bmhParser);
+ if (!fparser.parseFile(FLAGS_fiddle[0], ".txt")) {
+ return -1;
+ }
+ }
+ if (!done && FLAGS_catalog && FLAGS_examples.isEmpty()) {
+ Catalog fparser(&bmhParser);
+ fparser.fDebugOut = FLAGS_stdout;
+ if (!fparser.openCatalog(FLAGS_bmh[0], FLAGS_ref[0])) {
+ return -1;
+ }
if (!fparser.parseFile(FLAGS_fiddle[0], ".txt")) {
return -1;
}
+ if (!fparser.closeCatalog()) {
+ return -1;
+ }
+ bmhParser.fWroteOut = true;
+ done = true;
}
if (!done && !FLAGS_ref.isEmpty() && FLAGS_examples.isEmpty()) {
MdOut mdOut(bmhParser);
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index f5f53ff7ab..167fcb24f7 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -682,6 +682,12 @@ public:
kYes
};
+ enum class ExampleOptions {
+ kText,
+ kPng,
+ kAll
+ };
+
enum class MethodType {
kNone,
kConstructor,
@@ -785,7 +791,7 @@ public:
bool crossCheck2(const Definition& includeToken) const;
bool crossCheck(const Definition& includeToken) const;
bool crossCheckInside(const char* start, const char* end, const Definition& includeToken) const;
- bool exampleToScript(string* result) const;
+ bool exampleToScript(string* result, ExampleOptions ) const;
string extractText(TrimExtract trimExtract) const {
string result;
@@ -1768,7 +1774,10 @@ public:
const ParentPair* fPrev;
};
- IncludeWriter() : IncludeParser() {}
+ IncludeWriter() : IncludeParser() {
+ this->reset();
+ }
+
~IncludeWriter() override {}
bool contentFree(int size, const char* data) const {
@@ -1843,14 +1852,41 @@ private:
typedef IncludeParser INHERITED;
};
-class FiddleParser : public ParserCommon {
-public:
- FiddleParser(BmhParser* bmh) : ParserCommon()
- , fBmhParser(bmh) {
+class FiddleBase : public ParserCommon {
+protected:
+ FiddleBase(BmhParser* bmh) : ParserCommon()
+ , fBmhParser(bmh)
+ , fContinuation(false)
+ , fTextOut(false)
+ , fPngOut(false)
+ {
this->reset();
}
+ void reset() override {
+ INHERITED::resetCommon();
+ }
+
Definition* findExample(const string& name) const;
+ bool parseFiddles();
+ virtual bool pngOut(Definition* example) = 0;
+ virtual bool textOut(Definition* example, const char* stdOutStart,
+ const char* stdOutEnd) = 0;
+
+ BmhParser* fBmhParser; // must be writable; writes example hash
+ string fFullName;
+ bool fContinuation;
+ bool fTextOut;
+ bool fPngOut;
+private:
+ typedef ParserCommon INHERITED;
+};
+
+class FiddleParser : public FiddleBase {
+public:
+ FiddleParser(BmhParser* bmh) : FiddleBase(bmh) {
+ fTextOut = true;
+ }
bool parseFromFile(const char* path) override {
if (!INHERITED::parseSetup(path)) {
@@ -1859,16 +1895,34 @@ public:
return parseFiddles();
}
- void reset() override {
- INHERITED::resetCommon();
+private:
+ bool pngOut(Definition* example) override {
+ return true;
}
+ bool textOut(Definition* example, const char* stdOutStart,
+ const char* stdOutEnd) override;
+
+ typedef FiddleBase INHERITED;
+};
+
+class Catalog : public FiddleBase {
+public:
+ Catalog(BmhParser* bmh) : FiddleBase(bmh) {}
+
+ bool appendFile(const string& path);
+ bool closeCatalog();
+ bool openCatalog(const char* inDir, const char* outDir);
+
+ bool parseFromFile(const char* path) override ;
private:
- bool parseFiddles();
+ bool pngOut(Definition* example) override;
+ bool textOut(Definition* example, const char* stdOutStart,
+ const char* stdOutEnd) override;
- BmhParser* fBmhParser; // must be writable; writes example hash
+ string fDocsDir;
- typedef ParserCommon INHERITED;
+ typedef FiddleBase INHERITED;
};
class HackParser : public ParserCommon {
diff --git a/tools/bookmaker/cataloger.cpp b/tools/bookmaker/cataloger.cpp
new file mode 100644
index 0000000000..c757b6ac9f
--- /dev/null
+++ b/tools/bookmaker/cataloger.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "bookmaker.h"
+
+#include "SkOSFile.h"
+#include "SkOSPath.h"
+
+bool Catalog::appendFile(const string& path) {
+ FILE* file = fopen(path.c_str(), "r");
+ if (!file) {
+ SkDebugf("could not append %s\n", path.c_str());
+ return false;
+ }
+ fseek(file, 0L, SEEK_END);
+ int sz = (int) ftell(file);
+ rewind(file);
+ char* buffer = new char[sz];
+ memset(buffer, ' ', sz);
+ fread(buffer, 1, sz, file);
+ fclose(file);
+ this->writeBlock(sz, buffer);
+ return true;
+}
+
+bool Catalog::openCatalog(const char* inDir, const char* outDir) {
+ fDocsDir = inDir;
+ if ('/' != fDocsDir.back()) {
+ fDocsDir += '/';
+ }
+ string outie = outDir;
+ if ('/' != outie.back()) {
+ outie += '/';
+ }
+ fFullName = outie + "catalog.htm";
+ fOut = fopen(fFullName.c_str(), "wb");
+ if (!fOut) {
+ SkDebugf("could not open output file %s\n", fFullName.c_str());
+ return false;
+ }
+ fContinuation = false;
+ if (!appendFile(fDocsDir + "catalogHeader.txt")) {
+ return false;
+ }
+ this->lf(1);
+ return true;
+}
+
+bool Catalog::closeCatalog() {
+ if (fOut) {
+ this->lf(1);
+ this->writeString("}");
+ this->lf(1);
+ if (!appendFile(fDocsDir + "catalogTrailer.txt")) {
+ return false;
+ }
+ this->lf(1);
+ this->writePending();
+ fclose(fOut);
+ SkDebugf("wrote %s\n", fFullName.c_str());
+ fOut = nullptr;
+ }
+ return true;
+}
+
+bool Catalog::parseFromFile(const char* path) {
+ if (!INHERITED::parseSetup(path)) {
+ return false;
+ }
+ fIndent = 4;
+ this->writeString("var text = {");
+ this->lf(1);
+ fTextOut = true;
+ TextParser::Save save(this);
+ if (!parseFiddles()) {
+ return false;
+ }
+ this->lf(1);
+ this->writeString("}");
+ this->lf(2);
+ this->writeString("var pngs = {");
+ fTextOut = false;
+ fPngOut = true;
+ save.restore();
+ fContinuation = false;
+ return parseFiddles();
+}
+
+bool Catalog::pngOut(Definition* example) {
+ string result;
+ if (!example->exampleToScript(&result, Definition::ExampleOptions::kPng)) {
+ return false;
+ }
+ if (result.length() > 0) {
+ if (fContinuation) {
+ this->writeString(",");
+ this->lf(1);
+ } else {
+ fContinuation = true;
+ }
+ this->writeBlock(result.size(), result.c_str());
+ }
+ return true;
+}
+
+bool Catalog::textOut(Definition* example, const char* stdOutStart,
+ const char* stdOutEnd) {
+ string result;
+ if (!example->exampleToScript(&result, Definition::ExampleOptions::kText)) {
+ return false;
+ }
+ if (result.length() > 0) {
+ if (fContinuation) {
+ this->writeString(",");
+ this->lf(1);
+ } else {
+ fContinuation = true;
+ }
+ fIndent = 8;
+ this->writeBlock(result.size(), result.c_str());
+ this->lf(1);
+ this->writeString("\"stdout\": \"");
+ size_t pos = 0;
+ size_t len = stdOutEnd - stdOutStart;
+ string example;
+ while ((size_t) pos < len) {
+ example += '"' == stdOutStart[pos] ? "\\\"" :
+ '\\' == stdOutStart[pos] ? "\\\\" :
+ string(&stdOutStart[pos], 1);
+ ++pos;
+ }
+ this->writeBlock(example.length(), example.c_str());
+ this->writeString("\"");
+ this->lf(1);
+ fIndent = 4;
+ this->writeString("}");
+ }
+ return true;
+}
diff --git a/tools/bookmaker/fiddleParser.cpp b/tools/bookmaker/fiddleParser.cpp
index 3361543301..faf551006f 100644
--- a/tools/bookmaker/fiddleParser.cpp
+++ b/tools/bookmaker/fiddleParser.cpp
@@ -20,7 +20,7 @@ static Definition* find_fiddle(Definition* def, const string& name) {
return nullptr;
}
-Definition* FiddleParser::findExample(const string& name) const {
+Definition* FiddleBase::findExample(const string& name) const {
for (const auto& topic : fBmhParser->fTopicMap) {
if (topic.second->fParent) {
continue;
@@ -33,7 +33,7 @@ Definition* FiddleParser::findExample(const string& name) const {
return nullptr;
}
-bool FiddleParser::parseFiddles() {
+bool FiddleBase::parseFiddles() {
if (!this->skipExact("{\n")) {
return false;
}
@@ -110,50 +110,15 @@ bool FiddleParser::parseFiddles() {
}
} while (!this->eof() && this->next());
const char* stdOutEnd = fChar;
- if (example) {
- bool foundStdOut = false;
- for (auto& textOut : example->fChildren) {
- if (MarkType::kStdOut != textOut->fMarkType) {
- continue;
- }
- foundStdOut = true;
- bool foundVolatile = false;
- for (auto& stdOutChild : textOut->fChildren) {
- if (MarkType::kVolatile == stdOutChild->fMarkType) {
- foundVolatile = true;
- break;
- }
- }
- TextParser bmh(textOut);
- EscapeParser fiddle(stdOutStart, stdOutEnd);
- do {
- bmh.skipWhiteSpace();
- fiddle.skipWhiteSpace();
- const char* bmhEnd = bmh.trimmedLineEnd();
- const char* fiddleEnd = fiddle.trimmedLineEnd();
- ptrdiff_t bmhLen = bmhEnd - bmh.fChar;
- SkASSERT(bmhLen > 0);
- ptrdiff_t fiddleLen = fiddleEnd - fiddle.fChar;
- SkASSERT(fiddleLen > 0);
- if (bmhLen != fiddleLen) {
- if (!foundVolatile) {
- bmh.reportError("mismatched stdout len\n");
- }
- } else if (strncmp(bmh.fChar, fiddle.fChar, fiddleLen)) {
- if (!foundVolatile) {
- bmh.reportError("mismatched stdout text\n");
- }
- }
- bmh.skipToLineStart();
- fiddle.skipToLineStart();
- } while (!bmh.eof() && !fiddle.eof());
- if (!foundStdOut) {
- bmh.reportError("bmh %s missing stdout\n");
- } else if (!bmh.eof() || !fiddle.eof()) {
- if (!foundVolatile) {
- bmh.reportError("%s mismatched stdout eof\n");
- }
- }
+ if (example && fTextOut) {
+ if (!this->textOut(example, stdOutStart, stdOutEnd)) {
+ return false;
+ }
+ }
+ } else {
+ if (example && fPngOut) {
+ if (!this->pngOut(example)) {
+ return false;
}
}
}
@@ -170,58 +135,54 @@ bool FiddleParser::parseFiddles() {
return false;
}
}
-#if 0
- // compare the text output with the expected output in the markup tree
- this->skipToSpace();
- SkASSERT(' ' == fChar[0]);
- this->next();
- const char* nameLoc = fChar;
- this->skipToNonAlphaNum();
- const char* nameEnd = fChar;
- string name(nameLoc, nameEnd - nameLoc);
- const Definition* example = this->findExample(name);
- if (!example) {
- return this->reportError<bool>("missing stdout name");
- }
- SkASSERT(':' == fChar[0]);
- this->next();
- this->skipSpace();
- const char* stdOutLoc = fChar;
- do {
- this->skipToLineStart();
- } while (!this->eof() && !this->startsWith("fiddles.htm:"));
- const char* stdOutEnd = fChar;
- for (auto& textOut : example->fChildren) {
- if (MarkType::kStdOut != textOut->fMarkType) {
- continue;
+ return true;
+}
+
+bool FiddleParser::textOut(Definition* example, const char* stdOutStart,
+ const char* stdOutEnd) {
+ bool foundStdOut = false;
+ for (auto& textOut : example->fChildren) {
+ if (MarkType::kStdOut != textOut->fMarkType) {
+ continue;
+ }
+ foundStdOut = true;
+ bool foundVolatile = false;
+ for (auto& stdOutChild : textOut->fChildren) {
+ if (MarkType::kVolatile == stdOutChild->fMarkType) {
+ foundVolatile = true;
+ break;
}
- TextParser bmh(textOut);
- TextParser fiddle(fFileName, stdOutLoc, stdOutEnd, fLineCount);
- do {
- bmh.skipWhiteSpace();
- fiddle.skipWhiteSpace();
- const char* bmhEnd = bmh.trimmedLineEnd();
- const char* fiddleEnd = fiddle.trimmedLineEnd();
- ptrdiff_t bmhLen = bmhEnd - bmh.fChar;
- SkASSERT(bmhLen > 0);
- ptrdiff_t fiddleLen = fiddleEnd - fiddle.fChar;
- SkASSERT(fiddleLen > 0);
- if (bmhLen != fiddleLen) {
- return this->reportError<bool>("mismatched stdout len");
- }
- if (strncmp(bmh.fChar, fiddle.fChar, fiddleLen)) {
- return this->reportError<bool>("mismatched stdout text");
- }
- bmh.skipToLineStart();
- fiddle.skipToLineStart();
- } while (!bmh.eof() && !fiddle.eof());
- if (!bmh.eof() || (!fiddle.eof() && !fiddle.startsWith("</pre>"))) {
- return this->reportError<bool>("mismatched stdout eof");
+ }
+ TextParser bmh(textOut);
+ EscapeParser fiddle(stdOutStart, stdOutEnd);
+ do {
+ bmh.skipWhiteSpace();
+ fiddle.skipWhiteSpace();
+ const char* bmhEnd = bmh.trimmedLineEnd();
+ const char* fiddleEnd = fiddle.trimmedLineEnd();
+ ptrdiff_t bmhLen = bmhEnd - bmh.fChar;
+ SkASSERT(bmhLen > 0);
+ ptrdiff_t fiddleLen = fiddleEnd - fiddle.fChar;
+ SkASSERT(fiddleLen > 0);
+ if (bmhLen != fiddleLen) {
+ if (!foundVolatile) {
+ bmh.reportError("mismatched stdout len\n");
+ }
+ } else if (strncmp(bmh.fChar, fiddle.fChar, fiddleLen)) {
+ if (!foundVolatile) {
+ bmh.reportError("mismatched stdout text\n");
}
- break;
+ }
+ bmh.skipToLineStart();
+ fiddle.skipToLineStart();
+ } while (!bmh.eof() && !fiddle.eof());
+ if (!foundStdOut) {
+ bmh.reportError("bmh %s missing stdout\n");
+ } else if (!bmh.eof() || !fiddle.eof()) {
+ if (!foundVolatile) {
+ bmh.reportError("%s mismatched stdout eof\n");
}
}
}
-#endif
return true;
}
diff --git a/tools/bookmaker/parserCommon.cpp b/tools/bookmaker/parserCommon.cpp
index fbfcbae728..7a6f71f7ed 100644
--- a/tools/bookmaker/parserCommon.cpp
+++ b/tools/bookmaker/parserCommon.cpp
@@ -13,7 +13,7 @@ static void debug_out(int len, const char* data) {
}
bool ParserCommon::parseSetup(const char* path) {
- this->reset();
+// this->reset();
sk_sp<SkData> data = SkData::MakeFromFileName(path);
if (nullptr == data.get()) {
SkDebugf("%s missing\n", path);