diff options
author | Cary Clark <caryclark@skia.org> | 2018-01-04 16:11:51 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-01-04 21:41:09 +0000 |
commit | 7cfcbca7168f3e36961fe32e75a5630426097e5c (patch) | |
tree | fa02b27923c4c75ab617f4e19c1fb14989f5468b /tools/bookmaker | |
parent | 94b7e5425683996c8bc3ca0e7b549ab7235c1180 (diff) |
limit bookmaker status output
streamline 'working as intended' output
notify when output changed
fix bug which appended output incorrectly to SkBitmap.h
fix bug that hid bad SkSurface.h from detection
Docs-Preview: https://skia.org/?cl=90162
Bug: skia:6898
Change-Id: I067cfe5bbad706345fb5cd540cdc3835ce22d822
Reviewed-on: https://skia-review.googlesource.com/90162
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.cpp | 2 | ||||
-rw-r--r-- | tools/bookmaker/bookmaker.h | 13 | ||||
-rw-r--r-- | tools/bookmaker/includeParser.cpp | 97 | ||||
-rw-r--r-- | tools/bookmaker/includeWriter.cpp | 32 | ||||
-rw-r--r-- | tools/bookmaker/mdOut.cpp | 191 | ||||
-rw-r--r-- | tools/bookmaker/parserCommon.cpp | 46 |
6 files changed, 281 insertions, 100 deletions
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp index b7aa044885..eb1ce1e366 100644 --- a/tools/bookmaker/bookmaker.cpp +++ b/tools/bookmaker/bookmaker.cpp @@ -16,7 +16,7 @@ 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 -f)"); +DEFINE_string2(ref, r, "", "Resolve refs and write *.md files to path. (Requires -b -f)"); DEFINE_string2(spellcheck, s, "", "Spell-check [once, all, mispelling]. (Requires -b)"); DEFINE_bool2(tokens, t, false, "Write bmh from include. (Requires -b -i)"); DEFINE_bool2(crosscheck, x, false, "Check bmh against includes. (Requires -b -i)"); diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h index f309d795c9..792f7d9249 100644 --- a/tools/bookmaker/bookmaker.h +++ b/tools/bookmaker/bookmaker.h @@ -1041,6 +1041,8 @@ public: fParent = fParent->fParent; } + const char* ReadToBuffer(string filename, int* size); + virtual void reset() = 0; void resetCommon() { @@ -1104,6 +1106,7 @@ public: this->writeString(str.c_str()); } + bool writtenFileDiffers(string filename, string readname); unordered_map<string, sk_sp<SkData>> fRawData; unordered_map<string, vector<char>> fLFOnly; @@ -1195,7 +1198,7 @@ public: // names without formal definitions (e.g. Column) aren't included // fill in other names once they're actually used { "", nullptr, MarkType::kNone, R_Y, E_N, 0 } -, { "A", nullptr, MarkType::kAnchor, R_Y, E_N, 0 } +, { "A", nullptr, MarkType::kAnchor, R_N, E_N, 0 } , { "Alias", nullptr, MarkType::kAlias, R_N, E_N, 0 } , { "Bug", nullptr, MarkType::kBug, R_N, E_N, 0 } , { "Class", &fClassMap, MarkType::kClass, R_Y, E_O, M_CSST | M(Root) } @@ -1556,6 +1559,7 @@ public: fInFunction = false; fInString = false; fFailed = false; + fPriorEnum = nullptr; } void setBracketShortCuts(Bracket bracket) { @@ -1724,6 +1728,8 @@ protected: Definition* fRootTopic; Definition* fInBrace; Definition* fLastObject; + Definition* fPriorEnum; + int fPriorIndex; const char* fIncludeWord; char fPrev; bool fInChar; @@ -1837,7 +1843,6 @@ public: void structOut(const Definition* root, const Definition& child, const char* commentStart, const char* commentEnd); void structSizeMembers(const Definition& child); - private: BmhParser* fBmhParser; Definition* fDeferComment; @@ -1966,8 +1971,8 @@ public: this->reset(); } - bool buildReferences(const char* path, const char* outDir); - bool buildStatus(const char* path, const char* outDir); + bool buildReferences(const char* docDir, const char* mdOutDirOrFile); + bool buildStatus(const char* docDir, const char* mdOutDir); private: enum class TableState { kNone, diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp index 363aacc650..fa5ad325fd 100644 --- a/tools/bookmaker/includeParser.cpp +++ b/tools/bookmaker/includeParser.cpp @@ -449,6 +449,8 @@ bool IncludeParser::crossCheck(BmhParser& bmhParser) { } } } + int crossChecks = 0; + string firstCheck; for (auto& classMapper : fIClassMap) { string className = classMapper.first; auto finder = bmhParser.fClassMap.find(className); @@ -460,7 +462,19 @@ bool IncludeParser::crossCheck(BmhParser& bmhParser) { SkDebugf("some struct elements not found; struct finding in includeParser is missing\n"); fFailed = true; } - SkDebugf("cross-checked %s\n", className.c_str()); + if (crossChecks) { + SkDebugf("."); + } else { + SkDebugf("cross-check"); + firstCheck = className; + } + ++crossChecks; + } + if (crossChecks) { + if (1 == crossChecks) { + SkDebugf("%s", firstCheck.c_str()); + } + SkDebugf("\n"); } bmhParser.fWroteOut = true; return !fFailed; @@ -1338,22 +1352,21 @@ bool IncludeParser::parseEnum(Definition* child, Definition* markupDef) { } markupChild->fChildren.push_back(member); } while (true); - for (auto count : child->fChildren) { - if (Definition::Type::kBracket == count->fType) { + for (auto outsideMember : child->fChildren) { + if (Definition::Type::kBracket == outsideMember->fType) { continue; } - SkASSERT(Definition::Type::kKeyWord == count->fType); - if (KeyWord::kClass == count->fKeyWord) { + SkASSERT(Definition::Type::kKeyWord == outsideMember->fType); + if (KeyWord::kClass == outsideMember->fKeyWord) { continue; } - SkASSERT(KeyWord::kStatic == count->fKeyWord); - markupChild->fTokens.emplace_back(MarkType::kMember, count->fContentStart, - count->fContentEnd, count->fLineCount, markupChild); + SkASSERT(KeyWord::kStatic == outsideMember->fKeyWord); + markupChild->fTokens.emplace_back(MarkType::kMember, outsideMember->fContentStart, + outsideMember->fContentEnd, outsideMember->fLineCount, markupChild); Definition* member = &markupChild->fTokens.back(); - member->fName = count->fName; + member->fName = outsideMember->fName; // FIXME: ? add comment as well ? markupChild->fChildren.push_back(member); - break; } IClassDefinition& classDef = fIClassMap[markupDef->fName]; SkASSERT(classDef.fStart); @@ -1493,9 +1506,6 @@ bool IncludeParser::parseMethod(Definition* child, Definition* markupDef) { } tokenIter->fName = nameStr; tokenIter->fMarkType = MarkType::kMethod; - if (string::npos != nameStr.find("defined")) { - SkDebugf(""); - } tokenIter->fPrivate = string::npos != nameStr.find("::"); auto testIter = child->fParent->fTokens.begin(); SkASSERT(child->fParentIndex > 0); @@ -2036,6 +2046,7 @@ bool IncludeParser::parseChar() { fInEnum = false; } this->popObject(); + fPriorEnum = nullptr; } else if (Definition::Type::kBracket == fParent->fType && fParent->fParent && Definition::Type::kKeyWord == fParent->fParent->fType && KeyWord::kStruct == fParent->fParent->fKeyWord) { @@ -2069,27 +2080,31 @@ bool IncludeParser::parseChar() { for (auto nameType = baseIter; nameType != namedIter; ++nameType) { member->fChildren.push_back(&*nameType); } - } + fPriorEnum = nullptr; } else if (fParent->fChildren.size() > 0) { auto lastIter = fParent->fChildren.end(); - Definition* priorEnum; - while (fParent->fChildren.begin() != lastIter) { - std::advance(lastIter, -1); - priorEnum = *lastIter; - if (Definition::Type::kBracket != priorEnum->fType || - (Bracket::kSlashSlash != priorEnum->fBracket - && Bracket::kSlashStar != priorEnum->fBracket)) { - break; + Definition* priorEnum = fPriorEnum; + fPriorEnum = nullptr; + if (!priorEnum) { + while (fParent->fChildren.begin() != lastIter) { + std::advance(lastIter, -1); + priorEnum = *lastIter; + if (Definition::Type::kBracket != priorEnum->fType || + (Bracket::kSlashSlash != priorEnum->fBracket + && Bracket::kSlashStar != priorEnum->fBracket)) { + break; + } } + fPriorIndex = priorEnum->fParentIndex; } if (Definition::Type::kKeyWord == priorEnum->fType && KeyWord::kEnum == priorEnum->fKeyWord) { auto tokenWalker = fParent->fTokens.begin(); - std::advance(tokenWalker, priorEnum->fParentIndex); - SkASSERT(KeyWord::kEnum == tokenWalker->fKeyWord); + std::advance(tokenWalker, fPriorIndex); while (tokenWalker != fParent->fTokens.end()) { std::advance(tokenWalker, 1); + ++fPriorIndex; if (Punctuation::kSemicolon == tokenWalker->fPunctuation) { break; } @@ -2103,6 +2118,7 @@ bool IncludeParser::parseChar() { break; } } + auto saveTokenWalker = tokenWalker; Definition* start = &*tokenWalker; bool foundExpected = true; for (KeyWord expected : {KeyWord::kStatic, KeyWord::kConstExpr, KeyWord::kInt}){ @@ -2116,6 +2132,36 @@ bool IncludeParser::parseChar() { } std::advance(tokenWalker, 1); } + if (!foundExpected) { + foundExpected = true; + tokenWalker = saveTokenWalker; + for (KeyWord expected : {KeyWord::kStatic, KeyWord::kConst, KeyWord::kNone}){ + const Definition* test = &*tokenWalker; + if (expected != test->fKeyWord) { + foundExpected = false; + break; + } + if (tokenWalker == fParent->fTokens.end()) { + break; + } + if (KeyWord::kNone != expected) { + std::advance(tokenWalker, 1); + } + } + if (foundExpected) { + auto nameToken = priorEnum->fTokens.begin(); + string enumName = string(nameToken->fContentStart, + nameToken->fContentEnd - nameToken->fContentStart); + const Definition* test = &*tokenWalker; + string constType = string(test->fContentStart, + test->fContentEnd - test->fContentStart); + if (enumName != constType) { + foundExpected = false; + } else { + std::advance(tokenWalker, 1); + } + } + } if (foundExpected && tokenWalker != fParent->fTokens.end()) { const char* nameStart = tokenWalker->fStart; std::advance(tokenWalker, 1); @@ -2125,7 +2171,8 @@ bool IncludeParser::parseChar() { start->fName = string(nameStart, tp.fChar - nameStart); start->fContentEnd = fChar; priorEnum->fChildren.emplace_back(start); - } + fPriorEnum = priorEnum; + } } } } diff --git a/tools/bookmaker/includeWriter.cpp b/tools/bookmaker/includeWriter.cpp index c34fc9391f..463ac92c91 100644 --- a/tools/bookmaker/includeWriter.cpp +++ b/tools/bookmaker/includeWriter.cpp @@ -486,7 +486,7 @@ void IncludeWriter::enumSizeItems(const Definition& child) { int longestValue = 0; int valueLen = 0; const char* lastEnd = nullptr; - SkASSERT(child.fChildren.size() == 1 || child.fChildren.size() == 2); +// SkASSERT(child.fChildren.size() == 1 || child.fChildren.size() == 2); auto brace = child.fChildren[0]; if (KeyWord::kClass == brace->fKeyWord) { brace = brace->fChildren[0]; @@ -585,6 +585,9 @@ void IncludeWriter::enumSizeItems(const Definition& child) { // walk children and output complete method doxygen description void IncludeWriter::methodOut(const Definition* method, const Definition& child) { + if (string::npos != method->fName.find("validate")) { + SkDebugf(""); + } if (fPendingMethod) { fIndent -= 4; fPendingMethod = false; @@ -1076,12 +1079,22 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 : fAttrDeprecated ? fAttrDeprecated->fContentStart - 1 : child.fContentStart; + if (Definition::Type::kBracket == def->fType && Bracket::kDebugCode == def->fBracket) { + auto tokenIter = def->fParent->fTokens.begin(); + std::advance(tokenIter, def->fParentIndex - 1); + Definition* prior = &*tokenIter; + if (Definition::Type::kBracket == def->fType && + Bracket::kSlashStar == prior->fBracket) { + bodyEnd = prior->fContentStart - 1; + } + } // FIXME: roll end-trimming into writeBlockTrim call while (fStart < bodyEnd && ' ' >= bodyEnd[-1]) { --bodyEnd; } int blockSize = (int) (bodyEnd - fStart); if (blockSize) { + string debugstr(fStart, blockSize); this->writeBlock(blockSize, fStart); } startDef = &child; @@ -1445,7 +1458,22 @@ bool IncludeWriter::populate(BmhParser& bmhParser) { this->lfcr(); this->writePending(); fclose(fOut); - SkDebugf("wrote %s\n", fileName.c_str()); + fflush(fOut); + size_t slash = fFileName.find_last_of('/'); + if (string::npos == slash) { + slash = 0; + } + size_t back = fFileName.find_last_of('\\'); + if (string::npos == back) { + back = 0; + } + string dir = fFileName.substr(0, SkTMax(slash, back) + 1); + string readname = dir + fileName; + if (this->writtenFileDiffers(fileName, readname)) { + SkDebugf("wrote updated %s\n", fileName.c_str()); + } else { + remove(fileName.c_str()); + } } return allPassed; } diff --git a/tools/bookmaker/mdOut.cpp b/tools/bookmaker/mdOut.cpp index d6069e4b3a..0443199155 100644 --- a/tools/bookmaker/mdOut.cpp +++ b/tools/bookmaker/mdOut.cpp @@ -10,6 +10,12 @@ #include "SkOSFile.h" #include "SkOSPath.h" +#define FPRINTF(...) \ + if (fDebugOut) { \ + SkDebugf(__VA_ARGS__); \ + } \ + fprintf(fOut, __VA_ARGS__) + static void add_ref(const string& leadingSpaces, const string& ref, string* result) { *result += leadingSpaces + ref; } @@ -65,7 +71,11 @@ string MdOut::addReferences(const char* refStart, const char* refEnd, } t.skipToMethodEnd(); if (base == t.fChar) { - break; + if (!t.eof() && '~' == base[0] && !isalnum(base[1])) { + t.next(); + } else { + break; + } } if (start >= t.fChar) { continue; @@ -76,6 +86,10 @@ string MdOut::addReferences(const char* refStart, const char* refEnd, ref = string(start, t.fChar - start); if (const Definition* def = this->isDefined(t, ref, BmhParser::Resolvable::kOut != resolvable)) { + if (MarkType::kExternal == def->fMarkType) { + add_ref(leadingSpaces, ref, &result); + continue; + } SkASSERT(def->fFiddle.length()); if (!t.eof() && '(' == t.peek() && t.strnchr(')', t.fEnd)) { if (!t.skipToEndBracket(')')) { @@ -237,16 +251,21 @@ string MdOut::addReferences(const char* refStart, const char* refEnd, return result; } -bool MdOut::buildReferences(const char* fileOrPath, const char* outDir) { - if (!sk_isdir(fileOrPath)) { - if (!this->buildRefFromFile(fileOrPath, outDir)) { - SkDebugf("failed to parse %s\n", fileOrPath); +bool MdOut::buildReferences(const char* docDir, const char* mdFileOrPath) { + if (!sk_isdir(mdFileOrPath)) { + SkString mdFile = SkOSPath::Basename(mdFileOrPath); + SkString bmhFile = SkOSPath::Join(docDir, mdFile.c_str()); + bmhFile.remove(bmhFile.size() - 3, 3); + bmhFile += ".bmh"; + SkString mdPath = SkOSPath::Dirname(mdFileOrPath); + if (!this->buildRefFromFile(bmhFile.c_str(), mdPath.c_str())) { + SkDebugf("failed to parse %s\n", mdFileOrPath); return false; } } else { - SkOSFile::Iter it(fileOrPath, ".bmh"); + SkOSFile::Iter it(docDir, ".bmh"); for (SkString file; it.next(&file); ) { - SkString p = SkOSPath::Join(fileOrPath, file.c_str()); + SkString p = SkOSPath::Join(docDir, file.c_str()); const char* hunk = p.c_str(); if (!SkStrEndsWith(hunk, ".bmh")) { continue; @@ -254,7 +273,7 @@ bool MdOut::buildReferences(const char* fileOrPath, const char* outDir) { if (SkStrEndsWith(hunk, "markup.bmh")) { // don't look inside this for now continue; } - if (!this->buildRefFromFile(hunk, outDir)) { + if (!this->buildRefFromFile(hunk, mdFileOrPath)) { SkDebugf("failed to parse %s\n", hunk); return false; } @@ -318,7 +337,7 @@ bool MdOut::buildRefFromFile(const char* name, const char* outDir) { fullName += '/'; } fullName += filename; - fOut = fopen(fullName.c_str(), "wb"); + fOut = fopen(filename.c_str(), "wb"); if (!fOut) { SkDebugf("could not open output file %s\n", fullName.c_str()); return false; @@ -328,16 +347,26 @@ bool MdOut::buildRefFromFile(const char* name, const char* outDir) { header.replace(underscorePos, 1, " "); } SkASSERT(string::npos == header.find('_')); - fprintf(fOut, "%s", header.c_str()); + FPRINTF("%s", header.c_str()); this->lfAlways(1); - fprintf(fOut, "==="); + FPRINTF("==="); } this->markTypeOut(topicDef); } if (fOut) { this->writePending(); fclose(fOut); - SkDebugf("wrote %s\n", fullName.c_str()); + fflush(fOut); + if (this->writtenFileDiffers(filename, fullName)) { + fOut = fopen(fullName.c_str(), "wb"); + int writtenSize; + const char* written = ReadToBuffer(filename, &writtenSize); + fwrite(written, 1, writtenSize, fOut); + fclose(fOut); + fflush(fOut); + SkDebugf("wrote updated %s\n", fullName.c_str()); + } + remove(filename.c_str()); fOut = nullptr; } return true; @@ -642,35 +671,46 @@ void MdOut::markTypeOut(Definition* def) { (!def->fParent || MarkType::kConst != def->fParent->fMarkType) && TableState::kNone != fTableState) { this->writePending(); - fprintf(fOut, "</table>"); + FPRINTF("</table>"); this->lf(2); fTableState = TableState::kNone; } switch (def->fMarkType) { case MarkType::kAlias: break; - case MarkType::kAnchor: - break; + case MarkType::kAnchor: { + if (fColumn > 0) { + this->writeSpace(); + } + this->writePending(); + TextParser parser(def); + const char* start = parser.fChar; + parser.skipToEndBracket(" # "); + string anchorText(start, parser.fChar - start); + parser.skipExact(" # "); + string anchorLink(parser.fChar, parser.fEnd - parser.fChar); + FPRINTF("<a href=\"%s\">%s", anchorLink.c_str(), anchorText.c_str()); + } break; case MarkType::kBug: break; case MarkType::kClass: this->mdHeaderOut(1); - fprintf(fOut, "<a name=\"%s\"></a> Class %s", this->linkName(def).c_str(), + FPRINTF("<a name=\"%s\"></a> Class %s", this->linkName(def).c_str(), def->fName.c_str()); this->lf(1); break; case MarkType::kCode: this->lfAlways(2); - fprintf(fOut, "<pre style=\"padding: 1em 1em 1em 1em;" + FPRINTF("<pre style=\"padding: 1em 1em 1em 1em;" "width: 62.5em; background-color: #f0f0f0\">"); this->lf(1); break; case MarkType::kColumn: this->writePending(); if (fInList) { - fprintf(fOut, " <td>"); + FPRINTF(" <td>"); } else { - fprintf(fOut, "| "); + FPRINTF("| "); } break; case MarkType::kComment: @@ -678,7 +718,7 @@ void MdOut::markTypeOut(Definition* def) { case MarkType::kConst: { if (TableState::kNone == fTableState) { this->mdHeaderOut(3); - fprintf(fOut, "Constants\n" + FPRINTF("Constants\n" "\n" "<table>"); fTableState = TableState::kRow; @@ -686,19 +726,19 @@ void MdOut::markTypeOut(Definition* def) { } if (TableState::kRow == fTableState) { this->writePending(); - fprintf(fOut, " <tr>"); + FPRINTF(" <tr>"); this->lf(1); fTableState = TableState::kColumn; } this->writePending(); - fprintf(fOut, " <td><a name=\"%s\"> <code><strong>%s </strong></code> </a></td>", + FPRINTF(" <td><a name=\"%s\"> <code><strong>%s </strong></code> </a></td>", def->fFiddle.c_str(), def->fName.c_str()); const char* lineEnd = strchr(textStart, '\n'); SkASSERT(lineEnd < def->fTerminator); SkASSERT(lineEnd > textStart); SkASSERT((int) (lineEnd - textStart) == lineEnd - textStart); - fprintf(fOut, "<td>%.*s</td>", (int) (lineEnd - textStart), textStart); - fprintf(fOut, "<td>"); + FPRINTF("<td>%.*s</td>", (int) (lineEnd - textStart), textStart); + FPRINTF("<td>"); textStart = lineEnd; } break; case MarkType::kDefine: @@ -710,21 +750,21 @@ void MdOut::markTypeOut(Definition* def) { case MarkType::kDescription: fInDescription = true; this->writePending(); - fprintf(fOut, "<div>"); + FPRINTF("<div>"); break; case MarkType::kDoxygen: break; case MarkType::kEnum: case MarkType::kEnumClass: this->mdHeaderOut(2); - fprintf(fOut, "<a name=\"%s\"></a> Enum %s", def->fFiddle.c_str(), def->fName.c_str()); + FPRINTF("<a name=\"%s\"></a> Enum %s", def->fFiddle.c_str(), def->fName.c_str()); this->lf(2); break; case MarkType::kError: break; case MarkType::kExample: { this->mdHeaderOut(3); - fprintf(fOut, "Example\n" + FPRINTF("Example\n" "\n"); fHasFiddle = true; bool showGpu = false; @@ -740,21 +780,21 @@ void MdOut::markTypeOut(Definition* def) { } if (fHasFiddle && !def->hasChild(MarkType::kError)) { SkASSERT(def->fHash.length() > 0); - fprintf(fOut, "<div><fiddle-embed name=\"%s\"", def->fHash.c_str()); + FPRINTF("<div><fiddle-embed name=\"%s\"", def->fHash.c_str()); if (showGpu) { - fprintf(fOut, " gpu=\"true\""); + FPRINTF(" gpu=\"true\""); if (gpuAndCpu) { - fprintf(fOut, " cpu=\"true\""); + FPRINTF(" cpu=\"true\""); } } - fprintf(fOut, ">"); + FPRINTF(">"); } else { SkASSERT(def->fHash.length() == 0); - fprintf(fOut, "<pre style=\"padding: 1em 1em 1em 1em; font-size: 13px" + FPRINTF("<pre style=\"padding: 1em 1em 1em 1em; font-size: 13px" " width: 62.5em; background-color: #f0f0f0\">"); this->lfAlways(1); if (def->fWrapper.length() > 0) { - fprintf(fOut, "%s", def->fWrapper.c_str()); + FPRINTF("%s", def->fWrapper.c_str()); } fRespectLeadingSpace = true; } @@ -780,7 +820,7 @@ void MdOut::markTypeOut(Definition* def) { case MarkType::kList: fInList = true; this->lfAlways(2); - fprintf(fOut, "<table>"); + FPRINTF("<table>"); this->lf(1); break; case MarkType::kLiteral: @@ -794,7 +834,7 @@ void MdOut::markTypeOut(Definition* def) { tp.skipWhiteSpace(); const char* end = tp.trimmedBracketEnd('\n'); this->lfAlways(2); - fprintf(fOut, "<a name=\"%s\"> <code><strong>%.*s</strong></code> </a>", + FPRINTF("<a name=\"%s\"> <code><strong>%.*s</strong></code> </a>", def->fFiddle.c_str(), (int) (end - tp.fChar), tp.fChar); this->lf(2); } break; @@ -804,9 +844,9 @@ void MdOut::markTypeOut(Definition* def) { if (!def->isClone()) { this->lfAlways(2); - fprintf(fOut, "<a name=\"%s\"></a>", def->fFiddle.c_str()); + FPRINTF("<a name=\"%s\"></a>", def->fFiddle.c_str()); this->mdHeaderOutLF(2, 1); - fprintf(fOut, "%s", method_name.c_str()); + FPRINTF("%s", method_name.c_str()); this->lf(2); } @@ -814,7 +854,7 @@ void MdOut::markTypeOut(Definition* def) { // TODO: 50em below should match limit = 80 in formatFunction() this->writePending(); string preformattedStr = preformat(formattedStr); - fprintf(fOut, "<pre style=\"padding: 1em 1em 1em 1em;" + FPRINTF("<pre style=\"padding: 1em 1em 1em 1em;" "width: 62.5em; background-color: #f0f0f0\">\n" "%s\n" "</pre>", preformattedStr.c_str()); @@ -838,7 +878,7 @@ void MdOut::markTypeOut(Definition* def) { fTableState = TableState::kRow; } if (TableState::kRow == fTableState) { - fprintf(fOut, " <tr>"); + FPRINTF(" <tr>"); this->lf(1); fTableState = TableState::kColumn; } @@ -866,7 +906,7 @@ void MdOut::markTypeOut(Definition* def) { break; case MarkType::kReturn: this->mdHeaderOut(3); - fprintf(fOut, "Return Value"); + FPRINTF("Return Value"); if (!this->checkParamReturnBody(def)) { return; } @@ -874,13 +914,13 @@ void MdOut::markTypeOut(Definition* def) { break; case MarkType::kRow: if (fInList) { - fprintf(fOut, " <tr>"); + FPRINTF(" <tr>"); this->lf(1); } break; case MarkType::kSeeAlso: this->mdHeaderOut(3); - fprintf(fOut, "See Also"); + FPRINTF("See Also"); this->lf(2); break; case MarkType::kSet: @@ -896,23 +936,23 @@ void MdOut::markTypeOut(Definition* def) { code.skipSpace(); while (!code.eof()) { const char* end = code.trimmedLineEnd(); - fprintf(fOut, "%.*s\n", (int) (end - code.fChar), code.fChar); + FPRINTF("%.*s\n", (int) (end - code.fChar), code.fChar); code.skipToLineStart(); } - fprintf(fOut, "~~~~"); + FPRINTF("~~~~"); this->lf(2); } break; case MarkType::kStruct: fRoot = def->asRoot(); this->mdHeaderOut(1); - fprintf(fOut, "<a name=\"%s\"></a> Struct %s", def->fFiddle.c_str(), def->fName.c_str()); + FPRINTF("<a name=\"%s\"></a> Struct %s", def->fFiddle.c_str(), def->fName.c_str()); this->lf(1); break; case MarkType::kSubstitute: break; case MarkType::kSubtopic: this->mdHeaderOut(2); - fprintf(fOut, "<a name=\"%s\"></a> %s", def->fName.c_str(), printable.c_str()); + FPRINTF("<a name=\"%s\"></a> %s", def->fName.c_str(), printable.c_str()); this->lf(2); break; case MarkType::kTable: @@ -928,7 +968,7 @@ void MdOut::markTypeOut(Definition* def) { break; case MarkType::kTopic: this->mdHeaderOut(1); - fprintf(fOut, "<a name=\"%s\"></a> %s", this->linkName(def).c_str(), + FPRINTF("<a name=\"%s\"></a> %s", this->linkName(def).c_str(), printable.c_str()); this->lf(1); break; @@ -951,23 +991,28 @@ void MdOut::markTypeOut(Definition* def) { } this->childrenOut(def, textStart); switch (def->fMarkType) { // post child work, at least for tables + case MarkType::kAnchor: + if (fColumn > 0) { + this->writeSpace(); + } + break; case MarkType::kCode: this->writePending(); - fprintf(fOut, "</pre>"); + FPRINTF("</pre>"); this->lf(2); break; case MarkType::kColumn: if (fInList) { this->writePending(); - fprintf(fOut, "</td>"); + FPRINTF("</td>"); this->lf(1); } else { - fprintf(fOut, " "); + FPRINTF(" "); } break; case MarkType::kDescription: this->writePending(); - fprintf(fOut, "</div>"); + FPRINTF("</div>"); fInDescription = false; break; case MarkType::kEnum: @@ -977,22 +1022,26 @@ void MdOut::markTypeOut(Definition* def) { case MarkType::kExample: this->writePending(); if (fHasFiddle) { - fprintf(fOut, "</fiddle-embed></div>"); + FPRINTF("</fiddle-embed></div>"); } else { this->lfAlways(1); if (def->fWrapper.length() > 0) { - fprintf(fOut, "}"); + FPRINTF("}"); this->lfAlways(1); } - fprintf(fOut, "</pre>"); + FPRINTF("</pre>"); } this->lf(2); fRespectLeadingSpace = false; break; + case MarkType::kLink: + this->writeString("</a>"); + this->writeSpace(); + break; case MarkType::kList: fInList = false; this->writePending(); - fprintf(fOut, "</table>"); + FPRINTF("</table>"); this->lf(2); break; case MarkType::kLegend: { @@ -1003,15 +1052,15 @@ void MdOut::markTypeOut(Definition* def) { SkASSERT(columnCount > 0); this->writePending(); for (size_t index = 0; index < columnCount; ++index) { - fprintf(fOut, "| --- "); + FPRINTF("| --- "); } - fprintf(fOut, " |"); + FPRINTF(" |"); this->lf(1); } break; case MarkType::kMethod: fMethod = nullptr; this->lfAlways(2); - fprintf(fOut, "---"); + FPRINTF("---"); this->lf(2); break; case MarkType::kConst: @@ -1019,8 +1068,8 @@ void MdOut::markTypeOut(Definition* def) { SkASSERT(TableState::kColumn == fTableState); fTableState = TableState::kRow; this->writePending(); - fprintf(fOut, "</td>\n"); - fprintf(fOut, " </tr>"); + FPRINTF("</td>\n"); + FPRINTF(" </tr>"); this->lf(1); break; case MarkType::kReturn: @@ -1029,9 +1078,9 @@ void MdOut::markTypeOut(Definition* def) { break; case MarkType::kRow: if (fInList) { - fprintf(fOut, " </tr>"); + FPRINTF(" </tr>"); } else { - fprintf(fOut, "|"); + FPRINTF("|"); } this->lf(1); break; @@ -1051,9 +1100,9 @@ void MdOut::markTypeOut(Definition* def) { void MdOut::mdHeaderOutLF(int depth, int lf) { this->lfAlways(lf); for (int index = 0; index < depth; ++index) { - fprintf(fOut, "#"); + FPRINTF("#"); } - fprintf(fOut, " "); + FPRINTF(" "); } void MdOut::resolveOut(const char* start, const char* end, BmhParser::Resolvable resolvable) { @@ -1098,22 +1147,28 @@ void MdOut::resolveOut(const char* start, const char* end, BmhParser::Resolvable paragraph.skipToEndBracket('\n'); ptrdiff_t lineLength = paragraph.fChar - contentStart; if (lineLength) { - this->writePending(); - fprintf(fOut, "%.*s", (int) lineLength, contentStart); + while (lineLength && contentStart[lineLength - 1] <= ' ') { + --lineLength; + } + string str(contentStart, lineLength); + this->writeString(str.c_str()); } +#if 0 int linefeeds = 0; while (lineLength > 0 && '\n' == contentStart[--lineLength]) { + ++linefeeds; } if (lineLength > 0) { this->nl(); } fLinefeeds += linefeeds; +#endif if (paragraph.eof()) { break; } if ('\n' == paragraph.next()) { - linefeeds = 1; + int linefeeds = 1; if (!paragraph.eof() && '\n' == paragraph.peek()) { linefeeds = 2; } @@ -1122,7 +1177,7 @@ void MdOut::resolveOut(const char* start, const char* end, BmhParser::Resolvable } #if 0 while (end > start && end[0] == '\n') { - fprintf(fOut, "\n"); + FPRINTF("\n"); --end; } #endif diff --git a/tools/bookmaker/parserCommon.cpp b/tools/bookmaker/parserCommon.cpp index af1031ac43..cfd42f700f 100644 --- a/tools/bookmaker/parserCommon.cpp +++ b/tools/bookmaker/parserCommon.cpp @@ -224,6 +224,52 @@ void ParserCommon::writeString(const char* str) { fMaxLF = 2; } +const char* ParserCommon::ReadToBuffer(string filename, int* size) { + FILE* file = fopen(filename.c_str(), "rb"); + if (!file) { + return nullptr; + } + fseek(file, 0L, SEEK_END); + *size = (int) ftell(file); + rewind(file); + char* buffer = new char[*size]; + memset(buffer, ' ', *size); + SkAssertResult(*size == (int)fread(buffer, 1, *size, file)); + fclose(file); + fflush(file); + return buffer; +} + +bool ParserCommon::writtenFileDiffers(string filename, string readname) { + int writtenSize, readSize; + const char* written = ReadToBuffer(filename, &writtenSize); + if (!written) { + return true; + } + const char* read = ReadToBuffer(readname, &readSize); + if (!read) { + delete[] written; + return true; + } +#if 0 // enable for debugging this + int smaller = SkTMin(writtenSize, readSize); + for (int index = 0; index < smaller; ++index) { + if (written[index] != read[index]) { + SkDebugf("%.*s\n", 40, &written[index]); + SkDebugf("%.*s\n", 40, &read[index]); + break; + } + } +#endif + if (readSize != writtenSize) { + return true; + } + bool result = !!memcmp(written, read, writtenSize); + delete[] written; + delete[] read; + return result; +} + StatusIter::StatusIter(const char* statusFile, const char* suffix, StatusFilter filter) : fSuffix(suffix) , fFilter(filter) { |