aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/bookmaker
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-01-04 16:11:51 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-04 21:41:09 +0000
commit7cfcbca7168f3e36961fe32e75a5630426097e5c (patch)
treefa02b27923c4c75ab617f4e19c1fb14989f5468b /tools/bookmaker
parent94b7e5425683996c8bc3ca0e7b549ab7235c1180 (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.cpp2
-rw-r--r--tools/bookmaker/bookmaker.h13
-rw-r--r--tools/bookmaker/includeParser.cpp97
-rw-r--r--tools/bookmaker/includeWriter.cpp32
-rw-r--r--tools/bookmaker/mdOut.cpp191
-rw-r--r--tools/bookmaker/parserCommon.cpp46
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) {