working on image and nightly housekeeping bot
Add more examples and docs for SkImage; still a ways to go.
Fix bit-rotted examples.
Add typedef support.
Add json driver to pick files to work on; remove special-casing.
Fix unordered map traversal that made md output unreliable.
TBR=rmistry@google.com
Docs-Preview: https://skia.org/?cl=80060
Bug: skia:6898
Change-Id: Ib8eb9fdfa5a9db61c8332e657fa2e2f4b96a665f
Reviewed-on: https://skia-review.googlesource.com/80060
Reviewed-by: Cary Clark <caryclark@skia.org>
Commit-Queue: Cary Clark <caryclark@skia.org>
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index e048375..b4db36a 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -7,6 +7,7 @@
#include "bookmaker.h"
+DEFINE_string2(status, a, "", "File containing status of documentation. (Use in place of -b -i)");
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)");
@@ -1056,6 +1057,71 @@
}
}
+string TextParser::typedefName() {
+ // look for typedef as one of three forms:
+ // typedef return-type (*NAME)(params);
+ // typedef alias NAME;
+ // typedef std::function<alias> NAME;
+ string builder;
+ const char* end = this->doubleLF();
+ if (!end) {
+ end = fEnd;
+ }
+ const char* altEnd = this->strnstr("#Typedef ##", end);
+ if (altEnd) {
+ end = this->strnchr('\n', end);
+ }
+ if (!end) {
+ return this->reportError<string>("missing typedef std::function end bracket >");
+ }
+
+ if (this->startsWith("std::function")) {
+ if (!this->skipToEndBracket('>')) {
+ return this->reportError<string>("missing typedef std::function end bracket >");
+ }
+ this->next();
+ this->skipWhiteSpace();
+ builder += string(fChar, end - fChar);
+ } else {
+ const char* paren = this->strnchr('(', end);
+ if (!paren) {
+ const char* lastWord = nullptr;
+ do {
+ this->skipToWhiteSpace();
+ if (fChar < end && isspace(fChar[0])) {
+ this->skipWhiteSpace();
+ lastWord = fChar;
+ } else {
+ break;
+ }
+ } while (true);
+ if (!lastWord) {
+ return this->reportError<string>("missing typedef name");
+ }
+ builder += string(lastWord, end - lastWord);
+ } else {
+ this->skipTo(paren);
+ this->next();
+ if ('*' != this->next()) {
+ return this->reportError<string>("missing typedef function asterisk");
+ }
+ const char* nameStart = fChar;
+ if (!this->skipToEndBracket(')')) {
+ return this->reportError<string>("missing typedef function )");
+ }
+ builder += string(nameStart, fChar - nameStart);
+ if (!this->skipToEndBracket('(')) {
+ return this->reportError<string>("missing typedef params (");
+ }
+ if (! this->skipToEndBracket(')')) {
+ return this->reportError<string>("missing typedef params )");
+ }
+ this->skipTo(end);
+ }
+ }
+ return builder;
+}
+
bool BmhParser::skipNoName() {
if ('\n' == this->peek()) {
this->next();
@@ -1253,67 +1319,12 @@
SkASSERT(fMC != this->peek());
return fParent->fName;
}
- // look for typedef as one of three forms:
- // typedef return-type (*NAME)(params);
- // typedef alias NAME;
- // typedef std::function<alias> NAME;
string builder;
- const char* end = this->doubleLF();
- if (!end) {
- end = fEnd;
+ const Definition* parent = this->parentSpace();
+ if (parent && parent->fName.length() > 0) {
+ builder = parent->fName + "::";
}
- const char* altEnd = this->strnstr("#Typedef ##", end);
- if (altEnd) {
- end = this->strnchr('\n', end);
- }
- if (!end) {
- return this->reportError<string>("missing typedef std::function end bracket >");
- }
-
- if (this->startsWith("std::function")) {
- if (!this->skipToEndBracket('>')) {
- return this->reportError<string>("missing typedef std::function end bracket >");
- }
- this->next();
- this->skipWhiteSpace();
- builder = string(fChar, end - fChar);
- } else {
- const char* paren = this->strnchr('(', end);
- if (!paren) {
- const char* lastWord = nullptr;
- do {
- this->skipToWhiteSpace();
- if (fChar < end && isspace(fChar[0])) {
- this->skipWhiteSpace();
- lastWord = fChar;
- } else {
- break;
- }
- } while (true);
- if (!lastWord) {
- return this->reportError<string>("missing typedef name");
- }
- builder = string(lastWord, end - lastWord);
- } else {
- this->skipTo(paren);
- this->next();
- if ('*' != this->next()) {
- return this->reportError<string>("missing typedef function asterisk");
- }
- const char* nameStart = fChar;
- if (!this->skipToEndBracket(')')) {
- return this->reportError<string>("missing typedef function )");
- }
- builder = string(nameStart, fChar - nameStart);
- if (!this->skipToEndBracket('(')) {
- return this->reportError<string>("missing typedef params (");
- }
- if (! this->skipToEndBracket(')')) {
- return this->reportError<string>("missing typedef params )");
- }
- this->skipTo(end);
- }
- }
+ builder += TextParser::typedefName();
return uniqueRootName(builder, MarkType::kTypedef);
}
@@ -1348,9 +1359,6 @@
return markType == def.fMarkType && def.fName == numBuilder;
};
- if (string::npos != base.find("SkMatrix::operator")) {
- SkDebugf("");
- }
string builder(base);
if (!builder.length()) {
builder = fParent->fName;
@@ -1389,9 +1397,6 @@
cloned->fCloned = true;
}
fCloned = true;
- if (string::npos != builder.find("operator")) {
- SkDebugf("");
- }
numBuilder = builder + '_' + to_string(number);
} while (++number);
return numBuilder;
@@ -1485,8 +1490,8 @@
" bookmaker -b path/to/bmh_files -e fiddle.json\n"
" ~/go/bin/fiddlecli --input fiddle.json --output fiddleout.json\n"
" bookmaker -b path/to/bmh_files -f fiddleout.json -r path/to/md_files\n"
- " bookmaker -b path/to/bmh_files -i path/to/include.h -x\n"
- " bookmaker -b path/to/bmh_files -i path/to/include.h -p\n");
+ " bookmaker -a path/to/status.json -x\n"
+ " bookmaker -a path/to/status.json -p\n");
bool help = false;
for (int i = 1; i < argc; i++) {
if (0 == strcmp("-h", argv[i]) || 0 == strcmp("--help", argv[i])) {
@@ -1505,23 +1510,38 @@
} else {
SkCommandLineFlags::PrintUsage();
const char* const commands[] = { "", "-h", "bmh", "-h", "examples", "-h", "include", "-h", "fiddle",
- "-h", "ref", "-h", "tokens",
+ "-h", "ref", "-h", "status", "-h", "tokens",
"-h", "crosscheck", "-h", "populate", "-h", "spellcheck" };
SkCommandLineFlags::Parse(SK_ARRAY_COUNT(commands), commands);
return 0;
}
- if (FLAGS_bmh.isEmpty() && FLAGS_include.isEmpty()) {
- SkDebugf("requires -b or -i\n");
+ if (FLAGS_bmh.isEmpty() && FLAGS_include.isEmpty() && FLAGS_status.isEmpty()) {
+ SkDebugf("requires at least one of: -b -i -a\n");
SkCommandLineFlags::PrintUsage();
return 1;
}
- if ((FLAGS_bmh.isEmpty() || FLAGS_fiddle.isEmpty() || FLAGS_ref.isEmpty()) && FLAGS_catalog) {
- SkDebugf("-c requires -b -f -r\n");
+ if (!FLAGS_bmh.isEmpty() && !FLAGS_status.isEmpty()) {
+ SkDebugf("requires -b or -a but not both\n");
SkCommandLineFlags::PrintUsage();
return 1;
}
- if (FLAGS_bmh.isEmpty() && !FLAGS_examples.isEmpty()) {
- SkDebugf("-e requires -b\n");
+ if (!FLAGS_include.isEmpty() && !FLAGS_status.isEmpty()) {
+ SkDebugf("requires -i or -a but not both\n");
+ SkCommandLineFlags::PrintUsage();
+ return 1;
+ }
+ if (FLAGS_bmh.isEmpty() && FLAGS_status.isEmpty() && FLAGS_catalog) {
+ SkDebugf("-c requires -b or -a\n");
+ SkCommandLineFlags::PrintUsage();
+ return 1;
+ }
+ if ((FLAGS_fiddle.isEmpty() || FLAGS_ref.isEmpty()) && FLAGS_catalog) {
+ SkDebugf("-c requires -f -r\n");
+ SkCommandLineFlags::PrintUsage();
+ return 1;
+ }
+ if (FLAGS_bmh.isEmpty() && FLAGS_status.isEmpty() && !FLAGS_examples.isEmpty()) {
+ SkDebugf("-e requires -b or -a\n");
SkCommandLineFlags::PrintUsage();
return 1;
}
@@ -1538,18 +1558,19 @@
}
return 0;
}
- if ((FLAGS_include.isEmpty() || FLAGS_bmh.isEmpty()) && FLAGS_populate) {
- SkDebugf("-p requires -b -i\n");
+ if ((FLAGS_include.isEmpty() || FLAGS_bmh.isEmpty()) && FLAGS_status.isEmpty() &&
+ FLAGS_populate) {
+ SkDebugf("-p requires -b -i or -a\n");
SkCommandLineFlags::PrintUsage();
return 1;
}
- if (FLAGS_bmh.isEmpty() && !FLAGS_ref.isEmpty()) {
- SkDebugf("-r requires -b\n");
+ if (FLAGS_bmh.isEmpty() && FLAGS_status.isEmpty() && !FLAGS_ref.isEmpty()) {
+ SkDebugf("-r requires -b or -a\n");
SkCommandLineFlags::PrintUsage();
return 1;
}
- if (FLAGS_bmh.isEmpty() && !FLAGS_spellcheck.isEmpty()) {
- SkDebugf("-s requires -b\n");
+ if (FLAGS_bmh.isEmpty() && FLAGS_status.isEmpty() && !FLAGS_spellcheck.isEmpty()) {
+ SkDebugf("-s requires -b or -a\n");
SkCommandLineFlags::PrintUsage();
return 1;
}
@@ -1558,8 +1579,9 @@
SkCommandLineFlags::PrintUsage();
return 1;
}
- if ((FLAGS_include.isEmpty() || FLAGS_bmh.isEmpty()) && FLAGS_crosscheck) {
- SkDebugf("-x requires -b -i\n");
+ if ((FLAGS_include.isEmpty() || FLAGS_bmh.isEmpty()) && FLAGS_status.isEmpty() &&
+ FLAGS_crosscheck) {
+ SkDebugf("-x requires -b -i or -a\n");
SkCommandLineFlags::PrintUsage();
return 1;
}
@@ -1568,31 +1590,51 @@
if (!bmhParser.parseFile(FLAGS_bmh[0], ".bmh")) {
return -1;
}
+ } else if (!FLAGS_status.isEmpty()) {
+ bmhParser.reset();
+ if (!bmhParser.parseStatus(FLAGS_status[0], ".bmh", StatusFilter::kInProgress)) {
+ return -1;
+ }
}
bool done = false;
- if (!FLAGS_include.isEmpty()) {
- if (FLAGS_tokens || FLAGS_crosscheck) {
+ if (!FLAGS_include.isEmpty() && FLAGS_tokens) {
+ IncludeParser includeParser;
+ includeParser.validate();
+ if (!includeParser.parseFile(FLAGS_include[0], ".h")) {
+ return -1;
+ }
+ if (FLAGS_tokens) {
+ includeParser.fDebugOut = FLAGS_stdout;
+ if (includeParser.dumpTokens(FLAGS_bmh[0])) {
+ bmhParser.fWroteOut = true;
+ }
+ done = true;
+ }
+ } else if (!FLAGS_include.isEmpty() || !FLAGS_status.isEmpty()) {
+ if (FLAGS_crosscheck) {
IncludeParser includeParser;
includeParser.validate();
- if (!includeParser.parseFile(FLAGS_include[0], ".h")) {
+ if (!FLAGS_include.isEmpty() &&
+ !includeParser.parseFile(FLAGS_include[0], ".h")) {
return -1;
}
- if (FLAGS_tokens) {
- includeParser.fDebugOut = FLAGS_stdout;
- if (includeParser.dumpTokens(FLAGS_bmh[0])) {
- bmhParser.fWroteOut = true;
- }
- done = true;
- } else if (FLAGS_crosscheck) {
- if (!includeParser.crossCheck(bmhParser)) {
- return -1;
- }
- done = true;
+ if (!FLAGS_status.isEmpty() && !includeParser.parseStatus(FLAGS_status[0], ".h",
+ StatusFilter::kCompleted)) {
+ return -1;
}
+ if (!includeParser.crossCheck(bmhParser)) {
+ return -1;
+ }
+ done = true;
} else if (FLAGS_populate) {
IncludeWriter includeWriter;
includeWriter.validate();
- if (!includeWriter.parseFile(FLAGS_include[0], ".h")) {
+ if (!FLAGS_include.isEmpty() &&
+ !includeWriter.parseFile(FLAGS_include[0], ".h")) {
+ return -1;
+ }
+ if (!FLAGS_status.isEmpty() && !includeWriter.parseStatus(FLAGS_status[0], ".h",
+ StatusFilter::kCompleted)) {
return -1;
}
includeWriter.fDebugOut = FLAGS_stdout;
@@ -1603,22 +1645,25 @@
done = true;
}
}
- if (!done && !FLAGS_catalog && !FLAGS_fiddle.isEmpty() && FLAGS_examples.isEmpty()) {
+ if (!done && !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])) {
+ Catalog cparser(&bmhParser);
+ cparser.fDebugOut = FLAGS_stdout;
+ if (!FLAGS_bmh.isEmpty() && !cparser.openCatalog(FLAGS_bmh[0], FLAGS_ref[0])) {
return -1;
}
- if (!fparser.parseFile(FLAGS_fiddle[0], ".txt")) {
+ if (!FLAGS_status.isEmpty() && !cparser.openStatus(FLAGS_status[0], FLAGS_ref[0])) {
return -1;
}
- if (!fparser.closeCatalog()) {
+ if (!cparser.parseFile(FLAGS_fiddle[0], ".txt")) {
+ return -1;
+ }
+ if (!cparser.closeCatalog()) {
return -1;
}
bmhParser.fWroteOut = true;
@@ -1627,12 +1672,20 @@
if (!done && !FLAGS_ref.isEmpty() && FLAGS_examples.isEmpty()) {
MdOut mdOut(bmhParser);
mdOut.fDebugOut = FLAGS_stdout;
- if (mdOut.buildReferences(FLAGS_bmh[0], FLAGS_ref[0])) {
+ if (!FLAGS_bmh.isEmpty() && mdOut.buildReferences(FLAGS_bmh[0], FLAGS_ref[0])) {
+ bmhParser.fWroteOut = true;
+ }
+ if (!FLAGS_status.isEmpty() && mdOut.buildStatus(FLAGS_status[0], FLAGS_ref[0])) {
bmhParser.fWroteOut = true;
}
}
if (!done && !FLAGS_spellcheck.isEmpty() && FLAGS_examples.isEmpty()) {
- bmhParser.spellCheck(FLAGS_bmh[0], FLAGS_spellcheck);
+ if (!FLAGS_bmh.isEmpty()) {
+ bmhParser.spellCheck(FLAGS_bmh[0], FLAGS_spellcheck);
+ }
+ if (!FLAGS_status.isEmpty()) {
+ bmhParser.spellStatus(FLAGS_status[0], FLAGS_spellcheck);
+ }
bmhParser.fWroteOut = true;
done = true;
}
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index 2d0f03c..d4126ce 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -10,6 +10,7 @@
#include "SkCommandLineFlags.h"
#include "SkData.h"
+#include "SkJSONCPP.h"
#include <algorithm>
#include <cmath>
@@ -175,6 +176,12 @@
kPreprocessor,
};
+enum class StatusFilter {
+ kCompleted,
+ kInProgress,
+ kUnknown,
+};
+
struct IncludeKey {
const char* fName;
KeyWord fKeyWord;
@@ -228,6 +235,7 @@
TextParser() {} // only for ParserCommon to call
friend class ParserCommon;
public:
+ virtual ~TextParser() {}
class Save {
public:
Save(TextParser* parser) {
@@ -636,6 +644,10 @@
}
}
+ // FIXME: nothing else in TextParser knows from C++ --
+ // there could be a class between TextParser and ParserCommon
+ virtual string typedefName();
+
const char* wordEnd() const {
const char* end = fChar;
while (isalnum(end[0]) || '_' == end[0] || '-' == end[0]) {
@@ -690,7 +702,7 @@
fEnd = writer;
}
- virtual ~EscapeParser() {
+ ~EscapeParser() override {
delete fStorage;
}
private:
@@ -939,6 +951,7 @@
unordered_map<string, Definition*> fMembers;
unordered_map<string, Definition*> fMethods;
unordered_map<string, Definition*> fStructs;
+ unordered_map<string, Definition*> fTypedefs;
};
struct Reference {
@@ -965,7 +978,7 @@
{
}
- virtual ~ParserCommon() {
+ ~ParserCommon() override {
}
void addDefinition(Definition* def) {
@@ -1018,6 +1031,7 @@
}
bool parseFile(const char* file, const char* suffix);
+ bool parseStatus(const char* file, const char* suffix, StatusFilter filter);
virtual bool parseFromFile(const char* path) = 0;
bool parseSetup(const char* path);
@@ -1053,7 +1067,6 @@
fMaxLF = 1;
}
-
void writeBlock(int size, const char* data) {
SkAssertResult(writeBlockTrim(size, data));
}
@@ -1109,7 +1122,28 @@
typedef TextParser INHERITED;
};
+struct JsonStatus {
+ const Json::Value& fObject;
+ Json::Value::iterator fIter;
+ string fName;
+};
+class StatusIter : public ParserCommon {
+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;
+};
class BmhParser : public ParserCommon {
public:
@@ -1290,9 +1324,10 @@
bool skipNoName();
bool skipToDefinitionEnd(MarkType markType);
void spellCheck(const char* match, SkCommandLineFlags::StringArray report) const;
+ void spellStatus(const char* match, SkCommandLineFlags::StringArray report) const;
vector<string> topicName();
vector<string> typeName(MarkType markType, bool* expectEnd);
- string typedefName();
+ string typedefName() override;
string uniqueName(const string& base, MarkType markType);
string uniqueRootName(const string& base, MarkType markType);
void validate() const;
@@ -1473,6 +1508,7 @@
bool parseEnum(Definition* child, Definition* markupDef);
bool parseFromFile(const char* path) override {
+ this->reset();
if (!INHERITED::parseSetup(path)) {
return false;
}
@@ -1486,7 +1522,7 @@
bool parseObject(Definition* child, Definition* markupDef);
bool parseObjects(Definition* parent, Definition* markupDef);
bool parseTemplate();
- bool parseTypedef();
+ bool parseTypedef(Definition* child, Definition* markupDef);
bool parseUnion();
void popBracket() {
@@ -1783,7 +1819,6 @@
fMethodDef = nullptr;
fBmhStructDef = nullptr;
fAttrDeprecated = nullptr;
- fAnonymousEnumCount = 1;
fInStruct = false;
fWroteMethod = false;
fIndentNext = false;
@@ -1883,6 +1918,7 @@
bool appendFile(const string& path);
bool closeCatalog();
bool openCatalog(const char* inDir, const char* outDir);
+ bool openStatus(const char* inDir, const char* outDir);
bool parseFromFile(const char* path) override ;
private:
@@ -1926,6 +1962,7 @@
}
bool buildReferences(const char* path, const char* outDir);
+ bool buildStatus(const char* path, const char* outDir);
private:
enum class TableState {
kNone,
@@ -2003,6 +2040,8 @@
, fClassName(className) {
}
+ ~MethodParser() override {}
+
void skipToMethodStart() {
if (!fClassName.length()) {
this->skipToAlphaNum();
diff --git a/tools/bookmaker/cataloger.cpp b/tools/bookmaker/cataloger.cpp
index 48e3b48..c227437 100644
--- a/tools/bookmaker/cataloger.cpp
+++ b/tools/bookmaker/cataloger.cpp
@@ -50,6 +50,17 @@
return true;
}
+bool Catalog::openStatus(const char* statusFile, const char* outDir) {
+ StatusIter iter(statusFile, ".bmh", StatusFilter::kInProgress);
+ string unused;
+ // FIXME: iterate through only chosen files by setting fDocsDir to iter
+ // read one file to find directory
+ if (!iter.next(&unused)) {
+ return false;
+ }
+ return openCatalog(iter.baseDir().c_str(), outDir);
+}
+
bool Catalog::closeCatalog() {
if (fOut) {
this->lf(1);
diff --git a/tools/bookmaker/definition.cpp b/tools/bookmaker/definition.cpp
index 44da2df..91592f9 100644
--- a/tools/bookmaker/definition.cpp
+++ b/tools/bookmaker/definition.cpp
@@ -541,7 +541,7 @@
break;
case MarkType::kFunction: {
// emit this, but don't wrap this in draw()
- string funcText(iter->fContentStart, iter->fContentEnd - iter->fContentStart - 1);
+ string funcText(iter->fContentStart, iter->fContentEnd - iter->fContentStart);
size_t pos = 0;
while (pos < funcText.length() && ' ' > funcText[pos]) {
++pos;
@@ -576,9 +576,6 @@
size_t end = text.length();
size_t outIndent = 0;
size_t textIndent = count_indent(text, pos, end);
- if ("MakeFromBackendTexture" == fName) {
- SkDebugf("");
- }
if (fWrapper.length() > 0) {
code += fWrapper;
code += "\\n";
@@ -899,9 +896,6 @@
const char* lastStart = methodParser.fChar;
const int limit = 100; // todo: allow this to be set by caller or in global or something
string name = this->methodName();
- if ("MakeFromBackendTextureAsRenderTarget" == name) {
- SkDebugf("");
- }
const char* nameInParser = methodParser.strnstr(name.c_str(), methodParser.fEnd);
methodParser.skipTo(nameInParser);
const char* lastEnd = methodParser.fChar;
@@ -1227,10 +1221,6 @@
if ("SkBitmap::validate()" == leaf.first) {
continue;
}
- // typedef uint32_t SaveLayerFlags not seen in SkCanvas.h, don't know why
- if ("SaveLayerFlags" == leaf.first) {
- continue;
- }
// SkPath::pathRefIsValid in #ifdef ; prefer to remove chrome dependency to fix
if ("SkPath::pathRefIsValid" == leaf.first) {
continue;
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index 955e6ef..cd6e9e3 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -426,6 +426,13 @@
SkDebugf("member missing from bmh: %s\n", fullName.c_str());
}
break;
+ case MarkType::kTypedef:
+ if (def) {
+ def->fVisited = true;
+ } else {
+ SkDebugf("typedef missing from bmh: %s\n", fullName.c_str());
+ }
+ break;
default:
SkASSERT(0); // unhandled
break;
@@ -1474,9 +1481,6 @@
break;
}
tokenIter->fName = nameStr;
- if ("operator" == nameStr) {
- SkDebugf("");
- }
tokenIter->fMarkType = MarkType::kMethod;
tokenIter->fPrivate = string::npos != nameStr.find("::");
auto testIter = child->fParent->fTokens.begin();
@@ -1538,9 +1542,6 @@
auto globalFunction = &fIFunctionMap[name];
globalFunction->fContentStart = start;
globalFunction->fName = name;
- if ("operator+" == name) {
- SkDebugf("");
- }
globalFunction->fFiddle = name;
globalFunction->fContentEnd = end;
globalFunction->fMarkType = MarkType::kMethod;
@@ -1555,9 +1556,6 @@
SkASSERT(classDef.fStart);
string uniqueName = this->uniqueName(classDef.fMethods, nameStr);
markupChild->fName = uniqueName;
- if ("operator+" == uniqueName) {
- SkDebugf("");
- }
if (!this->findComments(*child, markupChild)) {
return false;
}
@@ -1603,7 +1601,7 @@
}
break;
case KeyWord::kTypedef:
- if (!this->parseTypedef()) {
+ if (!this->parseTypedef(child, markupDef)) {
return child->reportError<bool>("failed to parse typedef");
}
break;
@@ -1720,8 +1718,29 @@
return true;
}
-bool IncludeParser::parseTypedef() {
-
+bool IncludeParser::parseTypedef(Definition* child, Definition* markupDef) {
+ TextParser typedefParser(child);
+ string nameStr = typedefParser.typedefName();
+ if (!markupDef) {
+ Definition& typedefDef = fITypedefMap[nameStr];
+ SkASSERT(!typedefDef.fStart);
+ typedefDef.fStart = child->fContentStart;
+ typedefDef.fContentStart = child->fContentStart;
+ typedefDef.fName = nameStr;
+ typedefDef.fFiddle = nameStr;
+ typedefDef.fContentEnd = child->fContentEnd;
+ typedefDef.fTerminator = child->fContentEnd;
+ typedefDef.fMarkType = MarkType::kTypedef;
+ typedefDef.fLineCount = child->fLineCount;
+ return true;
+ }
+ markupDef->fTokens.emplace_back(MarkType::kTypedef, child->fContentStart, child->fContentEnd,
+ child->fLineCount, markupDef);
+ Definition* markupChild = &markupDef->fTokens.back();
+ markupChild->fName = nameStr;
+ markupChild->fTerminator = markupChild->fContentEnd;
+ IClassDefinition& classDef = fIClassMap[markupDef->fName];
+ classDef.fTypedefs[nameStr] = markupChild;
return true;
}
diff --git a/tools/bookmaker/includeWriter.cpp b/tools/bookmaker/includeWriter.cpp
index 8c6d7a9..b18585f 100644
--- a/tools/bookmaker/includeWriter.cpp
+++ b/tools/bookmaker/includeWriter.cpp
@@ -8,9 +8,6 @@
#include "bookmaker.h"
void IncludeWriter::descriptionOut(const Definition* def) {
- if ("SkPoint_length" == def->fFiddle) {
- SkDebugf("");
- }
const char* commentStart = def->fContentStart;
int commentLen = (int) (def->fContentEnd - commentStart);
bool breakOut = false;
@@ -911,9 +908,6 @@
const Definition* requireDense = nullptr;
const Definition* startDef = nullptr;
for (auto& child : def->fTokens) {
- if (18 == child.fParentIndex) {
- SkDebugf("");
- }
if (KeyWord::kOperator == child.fKeyWord && method &&
Definition::MethodType::kOperator == method->fMethodType) {
eatOperator = true;
@@ -1034,9 +1028,6 @@
--continueEnd;
}
methodName += string(fContinuation, continueEnd - fContinuation);
- if ("SkIPoint::operator+" == methodName) {
- SkDebugf("");
- }
method = root->find(methodName, RootDefinition::AllowParens::kNo);
if (!method) {
fLineCount = child.fLineCount;
@@ -1093,9 +1084,6 @@
startDef = &child;
fStart = child.fContentStart;
methodName = root->fName + "::" + child.fName;
- if ("SkIPoint::operator+" == methodName) {
- SkDebugf("");
- }
inConstructor = root->fName == child.fName;
fContinuation = child.fContentEnd;
method = root->find(methodName, RootDefinition::AllowParens::kNo);
@@ -1447,6 +1435,7 @@
root->clearVisited();
fStart = includeMapper.second.fContentStart;
fEnd = includeMapper.second.fContentEnd;
+ fAnonymousEnumCount = 1;
allPassed &= this->populate(&includeMapper.second, nullptr, root);
this->writeBlock((int) (fEnd - fStart), fStart);
fIndent = 0;
diff --git a/tools/bookmaker/mdOut.cpp b/tools/bookmaker/mdOut.cpp
index 6b082ad..216a104 100644
--- a/tools/bookmaker/mdOut.cpp
+++ b/tools/bookmaker/mdOut.cpp
@@ -63,9 +63,6 @@
} else {
leadingSpaces = string(base, wordStart - base);
}
- if (!strncmp("SkPoint::operator-()", start, 20)) {
- SkDebugf("");
- }
t.skipToMethodEnd();
if (base == t.fChar) {
break;
@@ -77,9 +74,6 @@
continue;
}
ref = string(start, t.fChar - start);
- if (412 == t.fLineCount) {
- SkDebugf("");
- }
if (const Definition* def = this->isDefined(t, ref,
BmhParser::Resolvable::kOut != resolvable)) {
SkASSERT(def->fFiddle.length());
@@ -218,6 +212,9 @@
continue;
}
}
+ if ("RasterReleaseProc" == ref) {
+ SkDebugf("");
+ }
Definition* test = fRoot;
do {
if (!test->isRoot()) {
@@ -269,6 +266,19 @@
return true;
}
+bool MdOut::buildStatus(const char* statusFile, const char* outDir) {
+ StatusIter iter(statusFile, ".bmh", StatusFilter::kInProgress);
+ for (string file; iter.next(&file); ) {
+ SkString p = SkOSPath::Join(iter.baseDir().c_str(), file.c_str());
+ const char* hunk = p.c_str();
+ if (!this->buildRefFromFile(hunk, outDir)) {
+ SkDebugf("failed to parse %s\n", hunk);
+ return false;
+ }
+ }
+ return true;
+}
+
bool MdOut::buildRefFromFile(const char* name, const char* outDir) {
fFileName = string(name);
string filename(name);
@@ -285,8 +295,16 @@
match += ".bmh";
fOut = nullptr;
string fullName;
- for (const auto& topic : fBmhParser.fTopicMap) {
- Definition* topicDef = topic.second;
+
+ vector<string> keys;
+ keys.reserve(fBmhParser.fTopicMap.size());
+ for (const auto& it : fBmhParser.fTopicMap) {
+ keys.push_back(it.first);
+ }
+ std::sort(keys.begin(), keys.end());
+ for (auto key : keys) {
+ string s(key);
+ auto topicDef = fBmhParser.fTopicMap.at(s);
if (topicDef->fParent) {
continue;
}
@@ -723,16 +741,18 @@
gpuAndCpu = platParse.strnstr("cpu", platParse.fEnd);
}
}
- if (fHasFiddle) {
+ if (fHasFiddle && !def->hasChild(MarkType::kError)) {
+ SkASSERT(def->fHash.length() > 0);
fprintf(fOut, "<div><fiddle-embed name=\"%s\"", def->fHash.c_str());
if (showGpu) {
- fprintf(fOut, "gpu=\"true\"");
+ fprintf(fOut, " gpu=\"true\"");
if (gpuAndCpu) {
- fprintf(fOut, "cpu=\"true\"");
+ fprintf(fOut, " cpu=\"true\"");
}
}
fprintf(fOut, ">");
} else {
+ SkASSERT(def->fHash.length() == 0);
fprintf(fOut, "<pre style=\"padding: 1em 1em 1em 1em; font-size: 13px"
" width: 62.5em; background-color: #f0f0f0\">");
this->lfAlways(1);
diff --git a/tools/bookmaker/parserCommon.cpp b/tools/bookmaker/parserCommon.cpp
index 79503a6..af1031a 100644
--- a/tools/bookmaker/parserCommon.cpp
+++ b/tools/bookmaker/parserCommon.cpp
@@ -16,7 +16,6 @@
}
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);
@@ -39,9 +38,23 @@
return true;
}
+bool ParserCommon::parseStatus(const char* statusFile, const char* suffix, StatusFilter filter) {
+ StatusIter iter(statusFile, suffix, filter);
+ if (iter.empty()) {
+ return false;
+ }
+ for (string file; iter.next(&file); ) {
+ SkString p = SkOSPath::Join(iter.baseDir().c_str(), file.c_str());
+ const char* hunk = p.c_str();
+ if (!this->parseFromFile(hunk)) {
+ SkDebugf("failed to parse %s\n", hunk);
+ return false;
+ }
+ }
+ return true;
+}
bool ParserCommon::parseSetup(const char* path) {
-// this->reset();
sk_sp<SkData> data = SkData::MakeFromFileName(path);
if (nullptr == data.get()) {
SkDebugf("%s missing\n", path);
@@ -210,3 +223,105 @@
fLinefeeds = 0;
fMaxLF = 2;
}
+
+StatusIter::StatusIter(const char* statusFile, const char* suffix, StatusFilter filter)
+ : fSuffix(suffix)
+ , fFilter(filter) {
+ if (!this->parseFromFile(statusFile)) {
+ return;
+ }
+}
+
+static const char* block_names[] = {
+ "Completed",
+ "InProgress",
+};
+
+string StatusIter::baseDir() {
+ SkASSERT(fStack.back().fObject.isArray());
+ SkASSERT(fStack.size() > 2);
+ string dir;
+ for (unsigned index = 2; index < fStack.size(); ++index) {
+ dir += fStack[index].fName;
+ if (index < fStack.size() - 1) {
+ dir += SkOSPath::SEPARATOR;
+ }
+ }
+ return dir;
+}
+
+// FIXME: need to compare fBlockName against fFilter
+// need to compare fSuffix against next value returned
+bool StatusIter::next(string* str) {
+ JsonStatus* status;
+ do {
+ do {
+ if (fStack.empty()) {
+ return false;
+ }
+ status = &fStack.back();
+ if (status->fIter != status->fObject.end()) {
+ break;
+ }
+ fStack.pop_back();
+ } while (true);
+ if (1 == fStack.size()) {
+ do {
+ StatusFilter blockType = StatusFilter::kUnknown;
+ for (unsigned index = 0; index < SK_ARRAY_COUNT(block_names); ++index) {
+ if (status->fIter.key().asString() == block_names[index]) {
+ blockType = (StatusFilter) index;
+ break;
+ }
+ }
+ if (blockType <= fFilter) {
+ break;
+ }
+ status->fIter++;
+ } while (status->fIter != status->fObject.end());
+ if (status->fIter == status->fObject.end()) {
+ continue;
+ }
+ }
+ if (!status->fObject.isArray()) {
+ SkASSERT(status->fIter != status->fObject.end());
+ JsonStatus block = {
+ *status->fIter,
+ status->fIter->begin(),
+ status->fIter.key().asString()
+ };
+ fStack.emplace_back(block);
+ status = &(&fStack.back())[-1];
+ status->fIter++;
+ status = &fStack.back();
+ continue;
+ }
+ *str = status->fIter->asString();
+ status->fIter++;
+ if (str->length() - strlen(fSuffix) == str->find(fSuffix)) {
+ return true;
+ }
+ } while (true);
+ return true;
+}
+
+bool StatusIter::parseFromFile(const char* path) {
+ sk_sp<SkData> json(SkData::MakeFromFileName(path));
+ if (!json) {
+ SkDebugf("file %s:\n", path);
+ return this->reportError<bool>("file not readable");
+ }
+ Json::Reader reader;
+ const char* data = (const char*)json->data();
+ if (!reader.parse(data, data+json->size(), fRoot)) {
+ SkDebugf("file %s:\n", path);
+ return this->reportError<bool>("file not parsable");
+ }
+ JsonStatus block = { fRoot, fRoot.begin(), "" };
+ fStack.emplace_back(block);
+ return true;
+}
+
+void StatusIter::reset() {
+ fStack.clear();
+}
diff --git a/tools/bookmaker/spellCheck.cpp b/tools/bookmaker/spellCheck.cpp
index 6f50cb3..33c0578 100644
--- a/tools/bookmaker/spellCheck.cpp
+++ b/tools/bookmaker/spellCheck.cpp
@@ -96,6 +96,14 @@
checker.report(report);
}
+void BmhParser::spellStatus(const char* statusFile, SkCommandLineFlags::StringArray report) const {
+ SpellCheck checker(*this);
+ StatusIter iter(statusFile, ".bmh", StatusFilter::kInProgress);
+ string match = iter.baseDir();
+ checker.check(match.c_str());
+ checker.report(report);
+}
+
bool SpellCheck::check(const char* match) {
for (const auto& topic : fBmhParser.fTopicMap) {
Definition* topicDef = topic.second;