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/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;
 }