diff options
author | 2017-09-01 13:39:19 -0400 | |
---|---|---|
committer | 2017-09-01 18:19:37 +0000 | |
commit | da65a0489ae429f026bad32c9a0ef2010f40e175 (patch) | |
tree | ae2b1e2b6350f120574aab8a51869de33b0a0ead /tools/bookmaker/spellCheck.cpp | |
parent | dbb24efcc5f224a0d9a73ad9b200daf8013df0a1 (diff) |
wip spelling mania
Work on spell-checker
to identify errors and
isolate more concepts
requiring definitions.
Docs-Preview: https://skia.org/?cl=41180
TBR: reed@google.com
Bug: skia: 6898
Change-Id: I0759beb42eaf6095908a9bd7decfcd0026253609
Reviewed-on: https://skia-review.googlesource.com/41180
Reviewed-by: Cary Clark <caryclark@skia.org>
Commit-Queue: Cary Clark <caryclark@skia.org>
Diffstat (limited to 'tools/bookmaker/spellCheck.cpp')
-rw-r--r-- | tools/bookmaker/spellCheck.cpp | 250 |
1 files changed, 221 insertions, 29 deletions
diff --git a/tools/bookmaker/spellCheck.cpp b/tools/bookmaker/spellCheck.cpp index e43a412eed..55ee6d56ad 100644 --- a/tools/bookmaker/spellCheck.cpp +++ b/tools/bookmaker/spellCheck.cpp @@ -34,7 +34,7 @@ public: this->reset(); } bool check(const char* match); - void report(); + void report(SkCommandLineFlags::StringArray report); private: enum class TableState { kNone, @@ -56,6 +56,7 @@ private: fTableState = TableState::kNone; fInCode = false; fInConst = false; + fInFormula = false; fInDescription = false; fInStdOut = false; } @@ -77,6 +78,7 @@ private: bool fInCode; bool fInConst; bool fInDescription; + bool fInFormula; bool fInStdOut; typedef ParserCommon INHERITED; }; @@ -88,10 +90,10 @@ private: modifiers to try to maintain a consistent voice. Maybe also look for passive verbs (e.g. 'is') and suggest active ones? */ -void BmhParser::spellCheck(const char* match) const { +void BmhParser::spellCheck(const char* match, SkCommandLineFlags::StringArray report) const { SpellCheck checker(*this); checker.check(match); - checker.report(); + checker.report(report); } bool SpellCheck::check(const char* match) { @@ -112,13 +114,22 @@ bool SpellCheck::check(const char* match) { return true; } +static bool all_lower(const string& str) { + for (auto c : str) { + if (!islower(c)) { + return false; + } + } + return true; +} + bool SpellCheck::check(Definition* def) { fFileName = def->fFileName; fLineCount = def->fLineCount; string printable = def->printableName(); const char* textStart = def->fContentStart; if (MarkType::kParam != def->fMarkType && MarkType::kConst != def->fMarkType && - TableState::kNone != fTableState) { + MarkType::kPrivate != def->fMarkType && TableState::kNone != fTableState) { fTableState = TableState::kNone; } switch (def->fMarkType) { @@ -170,11 +181,14 @@ bool SpellCheck::check(Definition* def) { break; case MarkType::kExample: break; + case MarkType::kExperimental: + break; case MarkType::kExternal: break; case MarkType::kFile: break; case MarkType::kFormula: + fInFormula = true; break; case MarkType::kFunction: break; @@ -184,12 +198,19 @@ bool SpellCheck::check(Definition* def) { break; case MarkType::kLegend: break; + case MarkType::kLink: + break; case MarkType::kList: break; + case MarkType::kMarkChar: + break; case MarkType::kMember: break; case MarkType::kMethod: { string method_name = def->methodName(); + if (all_lower(method_name)) { + method_name += "()"; + } string formattedStr = def->formatFunction(); if (!def->isClone()) { this->wordCheck(method_name); @@ -197,6 +218,8 @@ bool SpellCheck::check(Definition* def) { fTableState = TableState::kNone; fMethod = def; } break; + case MarkType::kNoExample: + break; case MarkType::kParam: { if (TableState::kNone == fTableState) { fTableState = TableState::kRow; @@ -219,6 +242,8 @@ bool SpellCheck::check(Definition* def) { } break; case MarkType::kPlatform: break; + case MarkType::kPrivate: + break; case MarkType::kReturn: break; case MarkType::kRow: @@ -240,6 +265,8 @@ bool SpellCheck::check(Definition* def) { fRoot = def->asRoot(); this->wordCheck(def->fName); break; + case MarkType::kSubstitute: + break; case MarkType::kSubtopic: this->printCheck(printable); break; @@ -263,6 +290,8 @@ bool SpellCheck::check(Definition* def) { break; case MarkType::kUnion: break; + case MarkType::kVolatile: + break; case MarkType::kWidth: break; default: @@ -284,6 +313,9 @@ bool SpellCheck::check(Definition* def) { break; case MarkType::kExample: break; + case MarkType::kFormula: + fInFormula = false; + break; case MarkType::kLegend: break; case MarkType::kMethod: @@ -336,21 +368,90 @@ void SpellCheck::childCheck(const Definition* def, const char* start) { } void SpellCheck::leafCheck(const char* start, const char* end) { - TextParser text("", start, end, fLineCount); + const char* chPtr = start; + int inAngles = 0; + int inParens = 0; + bool inQuotes = false; + bool allLower = true; + char priorCh = 0; + char lastCh = 0; + const char* wordStart = nullptr; + const char* wordEnd = nullptr; + const char* possibleEnd = nullptr; do { - const char* lineStart = text.fChar; - text.skipToAlpha(); - if (text.eof()) { + if (wordStart && wordEnd) { + if (!allLower || (!inQuotes && '\"' != lastCh && !inParens + && ')' != lastCh && !inAngles && '>' != lastCh)) { + string word(wordStart, (possibleEnd ? possibleEnd : wordEnd) - wordStart); + wordCheck(word); + } + wordStart = nullptr; + } + if (chPtr == end) { break; } - const char* wordStart = text.fChar; - text.fChar = lineStart; - text.skipTo(wordStart); // advances line number - text.skipToNonAlphaNum(); - fLineCount = text.fLineCount; - string word(wordStart, text.fChar - wordStart); - wordCheck(word); - } while (!text.eof()); + switch (*chPtr) { + case '>': + if (isalpha(lastCh)) { + --inAngles; + SkASSERT(inAngles >= 0); + } + wordEnd = chPtr; + break; + case '(': + ++inParens; + possibleEnd = chPtr; + break; + case ')': + --inParens; + if ('(' == lastCh) { + wordEnd = chPtr + 1; + } else { + wordEnd = chPtr; + } + SkASSERT(inParens >= 0); + break; + case '\"': + inQuotes = !inQuotes; + wordEnd = chPtr; + SkASSERT(inQuotes == !wordStart); + break; + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': case 'G': case 'H': case 'I': case 'J': + case 'K': case 'L': case 'M': case 'N': case 'O': + case 'P': case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': case 'Y': + case 'Z': + allLower = false; + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': case 'g': case 'h': case 'i': case 'j': + case 'k': case 'l': case 'm': case 'n': case 'o': + case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': case 'y': + case 'z': + if (!wordStart) { + wordStart = chPtr; + wordEnd = nullptr; + possibleEnd = nullptr; + allLower = 'a' <= *chPtr; + if ('<' == lastCh || ('<' == priorCh && '/' == lastCh)) { + ++inAngles; + } + } + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '_': + allLower = false; + case '-': // note that dash doesn't clear allLower + break; + default: + wordEnd = chPtr; + break; + } + priorCh = lastCh; + lastCh = *chPtr; + } while (++chPtr <= end); } void SpellCheck::printCheck(const string& str) { @@ -360,25 +461,107 @@ void SpellCheck::printCheck(const string& str) { } } -void SpellCheck::report() { - for (auto iter : fWords) { - if (string::npos != iter.second.fFile.find("undocumented.bmh")) { - continue; - } - if (string::npos != iter.second.fFile.find("markup.bmh")) { - continue; +static bool stringCompare(std::pair<string, CheckEntry>& i, std::pair<string, CheckEntry>& j) { + return i.first.compare(j.first) < 0; +} + +void SpellCheck::report(SkCommandLineFlags::StringArray report) { + vector<std::pair<string, CheckEntry>> elems(fWords.begin(), fWords.end());
+ std::sort(elems.begin(), elems.end(), stringCompare); + if (report.contains("once")) { + for (auto iter : elems) { + if (string::npos != iter.second.fFile.find("undocumented.bmh")) { + continue; + } + if (string::npos != iter.second.fFile.find("markup.bmh")) { + continue; + } + if (string::npos != iter.second.fFile.find("usingBookmaker.bmh")) { + continue; + } + if (iter.second.fCount == 1) { + SkDebugf("%s(%d): %s\n", iter.second.fFile.c_str(), iter.second.fLine, + iter.first.c_str()); + } } - if (string::npos != iter.second.fFile.find("usingBookmaker.bmh")) { - continue; + SkDebugf("\n"); + } + if (report.contains("all")) { + int column = 0; + for (auto iter : elems) { + if (string::npos != iter.second.fFile.find("undocumented.bmh")) { + continue; + } + if (string::npos != iter.second.fFile.find("markup.bmh")) { + continue; + } + if (string::npos != iter.second.fFile.find("usingBookmaker.bmh")) { + continue; + } + string check = iter.first.c_str(); + bool allLower = true; + for (auto c : check) { + if (isupper(c)) { + allLower = false; + break; + } + } + if (!allLower) { + continue; + } + if (column + check.length() > 100) { + SkDebugf("\n"); + column = 0; + } + SkDebugf("%s ", check.c_str()); + column += check.length(); } - if (iter.second.fCount == 1) { - SkDebugf("%s %s %d\n", iter.first.c_str(), iter.second.fFile.c_str(), - iter.second.fLine); + SkDebugf("\n\n"); + } + if (report.contains("mispellings")) { + const char* mispelled[] = { + "decrementing", + "differentially", + "incrementing", + "superset", + }; + const char** mispellPtr = mispelled; + const char** mispellEnd = &mispelled[SK_ARRAY_COUNT(mispelled)]; + for (auto iter : elems) { + if (string::npos != iter.second.fFile.find("undocumented.bmh")) { + continue; + } + if (string::npos != iter.second.fFile.find("markup.bmh")) { + continue; + } + if (string::npos != iter.second.fFile.find("usingBookmaker.bmh")) { + continue; + } + string check = iter.first.c_str(); + while (check.compare(*mispellPtr) > 0) { + SkDebugf("%s not found\n", *mispellPtr); + if (mispellEnd == ++mispellPtr) { + break; + } + } + if (mispellEnd == mispellPtr) { + break; + } + if (check.compare(*mispellPtr) == 0) { + SkDebugf("%s(%d): %s\n", iter.second.fFile.c_str(), iter.second.fLine, + iter.first.c_str()); + if (mispellEnd == ++mispellPtr) { + break; + } + } } } } void SpellCheck::wordCheck(const string& str) { + if ("nullptr" == str) { + return; // doesn't seem worth it, treating nullptr as a word in need of correction + } bool hasColon = false; bool hasDot = false; bool hasParen = false; @@ -433,11 +616,20 @@ void SpellCheck::wordCheck(const string& str) { && islower(str[0]) && isupper(str[1])) { inCode = true; } + bool methodParam = false; + if (fMethod) { + for (auto child : fMethod->fChildren) { + if (MarkType::kParam == child->fMarkType && str == child->fName) { + methodParam = true; + break; + } + } + } auto& mappy = hasColon ? fColons : hasDot ? fDots : hasParen ? fParens : hasUnderscore ? fUnderscores : - fInStdOut || inCode || fInConst ? fCode : + fInStdOut || fInFormula || inCode || fInConst || methodParam ? fCode : sawDigit ? fDigits : fWords; auto iter = mappy.find(str); if (mappy.end() != iter) { |