aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/bookmaker/spellCheck.cpp
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2017-09-01 13:39:19 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-01 18:19:37 +0000
commitda65a0489ae429f026bad32c9a0ef2010f40e175 (patch)
treeae2b1e2b6350f120574aab8a51869de33b0a0ead /tools/bookmaker/spellCheck.cpp
parentdbb24efcc5f224a0d9a73ad9b200daf8013df0a1 (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.cpp250
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) {