1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2017 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef bookmaker_DEFINED
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define bookmaker_DEFINED
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCommandLineFlags.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkData.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkJSONCPP.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <algorithm>
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <cmath>
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <cctype>
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <forward_list>
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <list>
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <string>
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <unordered_map>
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <vector>
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// std::to_string isn't implemented on android
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <sstream>
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <typename T>
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::string to_string(T value)
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot{
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    std::ostringstream os ;
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    os << value ;
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return os.str() ;
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotusing std::forward_list;
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotusing std::list;
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotusing std::unordered_map;
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotusing std::string;
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotusing std::vector;
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum class KeyWord {
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kNone,
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSK_API,
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSK_BEGIN_REQUIRE_DENSE,
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kBool,
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kChar,
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kClass,
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kConst,
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kConstExpr,
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kDefine,
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kDouble,
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kElif,
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kElse,
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kEndif,
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kEnum,
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kError,
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kFloat,
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kFriend,
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kIf,
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kIfdef,
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kIfndef,
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kInclude,
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kInline,
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kInt,
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kOperator,
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kPrivate,
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kProtected,
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kPublic,
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSigned,
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSize_t,
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kStatic,
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kStruct,
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kTemplate,
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kTypedef,
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kUint16_t,
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kUint32_t,
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kUint64_t,
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kUint8_t,
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kUnion,
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kUnsigned,
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kVoid,
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum class MarkType {
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kNone,
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kAnchor,
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kAlias,
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kBug,
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kClass,
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kCode,
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kColumn,
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kComment,
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kConst,
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kDefine,
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kDefinedBy,
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kDeprecated,
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kDescription,
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kDoxygen,
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kDuration,
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kEnum,
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kEnumClass,
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kExample,
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kExperimental,
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kExternal,
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kFile,
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kFormula,
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kFunction,
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kHeight,
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kImage,
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	kIn,
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kLegend,
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	kLine,
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kLink,
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kList,
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kLiteral,  // don't lookup hyperlinks, do substitution, etc
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kMarkChar,
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kMember,
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kMethod,
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kNoExample,
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kOutdent,
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kParam,
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kPlatform,
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kPopulate,
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kPrivate,
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kReturn,
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kRoot,
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kRow,
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSeeAlso,
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSet,
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kStdOut,
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kStruct,
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSubstitute,
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSubtopic,
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kTable,
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kTemplate,
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kText,
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kTime,
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kToDo,
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kTopic,
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kTrack,
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kTypedef,
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kUnion,
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kVolatile,
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kWidth,
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum {
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Last_MarkType = (int) MarkType::kWidth,
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum class Bracket {
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kNone,
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kParen,
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSquare,
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kBrace,
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kAngle,
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kString,
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kChar,
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSlashStar,
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSlashSlash,
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kPound,
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kColon,
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kDebugCode,  // parens get special treatment so SkDEBUGCODE( isn't treated as method
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum class Punctuation {  // catch-all for misc symbols tracked in C
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kNone,
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kAsterisk,  // for pointer-to
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSemicolon,  // e.g., to delinate xxx() const ; const int* yyy()
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kLeftBrace,
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kColon,     // for foo() : bar(1), baz(2) {}
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum class KeyProperty {
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kNone,
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kClassSection,
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kFunction,
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kModifier,
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kNumber,
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kObject,
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kPreprocessor,
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum class StatusFilter {
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kCompleted,
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kInProgress,
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kUnknown,
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct IncludeKey {
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fName;
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    KeyWord fKeyWord;
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    KeyProperty fProperty;
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotextern const IncludeKey kKeyWords[];
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic inline bool has_nonwhitespace(const string& s) {
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool nonwhite = false;
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (const char& c : s) {
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (' ' < c) {
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            nonwhite = true;
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return nonwhite;
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic inline void trim_end(string &s) {
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    s.erase(std::find_if(s.rbegin(), s.rend(),
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic inline void trim_end_spaces(string &s) {
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    while (s.length() > 0 && ' ' == s.back()) {
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        s.pop_back();
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic inline void trim_start(string &s) {
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    s.erase(s.begin(), std::find_if(s.begin(), s.end(),
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            std::not1(std::ptr_fun<int, int>(std::isspace))));
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic inline void trim_start_end(string& s) {
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    trim_start(s);
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    trim_end(s);
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass NonAssignable {
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    NonAssignable(NonAssignable const&) = delete;
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    NonAssignable& operator=(NonAssignable const&) = delete;
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    NonAssignable() {}
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass Definition;
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass TextParser : public NonAssignable {
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TextParser() {}  // only for ParserCommon to call
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    friend class ParserCommon;
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual ~TextParser() {}
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class Save {
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    public:
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Save(TextParser* parser) {
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fParser = parser;
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fLine = parser->fLine;
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fChar = parser->fChar;
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fLineCount = parser->fLineCount;
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void restore() const {
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fParser->fLine = fLine;
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fParser->fChar = fChar;
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fParser->fLineCount = fLineCount;
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    private:
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TextParser* fParser;
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* fLine;
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* fChar;
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int fLineCount;
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TextParser(const string& fileName, const char* start, const char* end, int lineCount)
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : fFileName(fileName)
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fStart(start)
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fLine(start)
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fChar(start)
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fEnd(end)
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fLineCount(lineCount)
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TextParser(const Definition* );
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* anyOf(const char* str) const {
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* ptr = fChar;
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (ptr < fEnd) {
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (strchr(str, ptr[0])) {
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return ptr;
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++ptr;
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* anyOf(const char* wordStart, const char* wordList[], size_t wordListCount) const {
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char** wordPtr = wordList;
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char** wordEnd = wordPtr + wordListCount;
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const size_t matchLen = fChar - wordStart;
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (wordPtr < wordEnd) {
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* word = *wordPtr++;
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (strlen(word) == matchLen && !strncmp(wordStart, word, matchLen)) {
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return word;
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    char backup(const char* pattern) const {
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t len = strlen(pattern);
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* start = fChar - len;
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (start <= fStart) {
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return '\0';
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (strncmp(start, pattern, len)) {
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return '\0';
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return start[-1];
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool contains(const char* match, const char* lineEnd, const char** loc) const {
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        *loc = this->strnstr(match, lineEnd);
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return *loc;
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* doubleLF() const {
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int count = 0;
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* ptr = fChar;
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* doubleStart = nullptr;
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (ptr < fEnd) {
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if ('\n' == ptr[0]) {
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (++count == 1) {
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    doubleStart = ptr;
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return doubleStart;
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else if (' ' < ptr[0]) {
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                count = 0;
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++ptr;
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool endsWith(const char* match) {
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int matchLen = strlen(match);
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (matchLen > fChar - fLine) {
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return !strncmp(fChar - matchLen, match, matchLen);
344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool eof() const { return fChar >= fEnd; }
347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* lineEnd() const {
349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* ptr = fChar;
350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        do {
351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (ptr >= fEnd) {
352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return ptr;
353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            char test = *ptr++;
355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (test == '\n' || test == '\0') {
356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } while (true);
359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return ptr;
360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ptrdiff_t lineLength() const {
363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return this->lineEnd() - fLine;
364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool match(TextParser* );
367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    char next() {
369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(fChar < fEnd);
370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        char result = *fChar++;
371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if ('\n' == result) {
372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++fLineCount;
373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fLine = fChar;
374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return result;
376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    char peek() const { SkASSERT(fChar < fEnd); return *fChar; }
379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void restorePlace(const TextParser& save) {
381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fChar = save.fChar;
382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLine = save.fLine;
383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLineCount = save.fLineCount;
384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void savePlace(TextParser* save) {
387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        save->fChar = fChar;
388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        save->fLine = fLine;
389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        save->fLineCount = fLineCount;
390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reportError(const char* errorStr) const;
393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reportWarning(const char* errorStr) const;
394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    template <typename T> T reportError(const char* errorStr) const {
396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->reportError(errorStr);
397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return T();
398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool sentenceEnd(const char* check) const {
401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (check > fStart) {
402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            --check;
403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (' ' < check[0] && '.' != check[0]) {
404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return false;
405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if ('.' == check[0]) {
407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return ' ' >= check[1];
408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if ('\n' == check[0] && '\n' == check[1]) {
410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return true;
411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipToEndBracket(char endBracket, const char* end = nullptr) {
417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (nullptr == end) {
418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            end = fEnd;
419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (fChar[0] != endBracket) {
421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fChar >= end) {
422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return false;
423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            (void) this->next();
425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipToEndBracket(const char* endBracket) {
430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t len = strlen(endBracket);
431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (strncmp(fChar, endBracket, len)) {
432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fChar >= fEnd) {
433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return false;
434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            (void) this->next();
436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipLine() {
441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return skipToEndBracket('\n');
442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void skipTo(const char* skip) {
445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot       while (fChar < skip) {
446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot           this->next();
447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot       }
448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void skipToAlpha() {
451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (fChar < fEnd && !isalpha(fChar[0])) {
452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fChar++;
453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void skipToAlphaNum() {
457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (fChar < fEnd && !isalnum(fChar[0])) {
458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fChar++;
459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipExact(const char* pattern) {
463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!this->startsWith(pattern)) {
464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->skipName(pattern);
467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // differs from skipToNonAlphaNum in that a.b isn't considered a full name,
471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // since a.b can't be found as a named definition
472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void skipFullName() {
473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (fChar < fEnd && (isalnum(fChar[0])
474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                || '_' == fChar[0]  /* || '-' == fChar[0] */
475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                || (':' == fChar[0] && fChar +1 < fEnd && ':' == fChar[1]))) {
476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (':' == fChar[0] && fChar +1 < fEnd && ':' == fChar[1]) {
477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fChar++;
478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fChar++;
480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipToLineStart() {
484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!this->skipLine()) {
485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!this->eof()) {
488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return this->skipWhiteSpace();
489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void skipToNonAlphaNum() {
494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (fChar < fEnd && (isalnum(fChar[0])
495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                || '_' == fChar[0] || '-' == fChar[0]
496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                || (':' == fChar[0] && fChar + 1 < fEnd && ':' == fChar[1])
497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                || ('.' == fChar[0] && fChar + 1 < fEnd && isalpha(fChar[1])))) {
498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (':' == fChar[0] && fChar +1 < fEnd && ':' == fChar[1]) {
499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fChar++;
500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fChar++;
502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void skipToSpace() {
506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (fChar < fEnd && ' ' != fChar[0]) {
507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fChar++;
508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void skipToWhiteSpace() {
512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (fChar < fEnd && ' ' < fChar[0]) {
513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fChar++;
514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipName(const char* word) {
518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t len = strlen(word);
519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (len <= (size_t) (fEnd - fChar) && !strncmp(word, fChar, len)) {
520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (size_t i = 0; i < len; ++i) {
521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->next();
522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return this->eof() || ' ' >= fChar[0];
525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipSpace() {
528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (' ' == this->peek()) {
529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            (void) this->next();
530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fChar >= fEnd) {
531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return false;
532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipWord(const char* word) {
538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!this->skipWhiteSpace()) {
539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* save = fChar;
542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!this->skipName(word)) {
543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fChar = save;
544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!this->skipWhiteSpace()) {
547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipWhiteSpace() {
553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (' ' >= this->peek()) {
554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            (void) this->next();
555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fChar >= fEnd) {
556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return false;
557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool startsWith(const char* str) const {
563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t len = strlen(str);
564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ptrdiff_t lineLen = fEnd - fChar;
565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return len <= (size_t) lineLen && 0 == strncmp(str, fChar, len);
566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // ignores minor white space differences
569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool startsWith(const char* str, size_t oLen) const {
570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t tIndex = 0;
571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t tLen = fEnd - fChar;
572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t oIndex = 0;
573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (oIndex < oLen && tIndex < tLen) {
574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            bool tSpace = ' ' >= fChar[tIndex];
575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            bool oSpace = ' ' >= str[oIndex];
576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (tSpace != oSpace) {
577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (tSpace) {
580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                do {
581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    ++tIndex;
582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } while (tIndex < tLen && ' ' >= fChar[tIndex]);
583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                do {
584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    ++oIndex;
585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } while (oIndex < oLen && ' ' >= str[oIndex]);
586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fChar[tIndex] != str[oIndex]) {
589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++tIndex;
592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++oIndex;
593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return oIndex >= oLen;
595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* strnchr(char ch, const char* end) const {
598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* ptr = fChar;
599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (ptr < end) {
600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (ptr[0] == ch) {
601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return ptr;
602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++ptr;
604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* strnstr(const char *match, const char* end) const {
609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t matchLen = strlen(match);
610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(matchLen > 0);
611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ptrdiff_t len = end - fChar;
612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(len >= 0);
613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if ((size_t) len < matchLen ) {
614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return nullptr;
615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t count = len - matchLen;
617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (size_t index = 0; index <= count; index++) {
618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (0 == strncmp(&fChar[index], match, matchLen)) {
619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return &fChar[index];
620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* trimmedBracketEnd(const char bracket) const {
626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int max = (int) (this->lineLength());
627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int index = 0;
628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (index < max && bracket != fChar[index]) {
629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++index;
630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(index < max);
632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (index > 0 && ' ' >= fChar[index - 1]) {
633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            --index;
634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fChar + index;
636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* trimmedLineEnd() const {
639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* result = this->lineEnd();
640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (result > fChar && ' ' >= result[-1]) {
641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            --result;
642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return result;
644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void trimEnd() {
647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (fEnd > fStart && ' ' >= fEnd[-1]) {
648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            --fEnd;
649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // FIXME: nothing else in TextParser knows from C++ --
653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // there could be a class between TextParser and ParserCommon
654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual string typedefName();
655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* wordEnd() const {
657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* end = fChar;
658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (isalnum(end[0]) || '_' == end[0] || '-' == end[0]) {
659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++end;
660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return end;
662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fFileName;
665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fStart;
666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fLine;
667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fChar;
668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fEnd;
669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t fLineCount;
670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass EscapeParser : public TextParser {
673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    EscapeParser(const char* start, const char* end) :
675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TextParser("", start, end, 0) {
676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* reader = fStart;
677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fStorage = new char[end - start];
678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        char* writer = fStorage;
679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (reader < fEnd) {
680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            char ch = *reader++;
681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (ch != '\\') {
682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                *writer++ = ch;
683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                char ctrl = *reader++;
685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (ctrl == 'u') {
686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    unsigned unicode = 0;
687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    for (int i = 0; i < 4; ++i) {
688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        unicode <<= 4;
689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT((reader[0] >= '0' && reader[0] <= '9') ||
690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            (reader[0] >= 'A' && reader[0] <= 'F') ||
691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            (reader[0] >= 'a' && reader[0] <= 'f'));
692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        int nibble = *reader++ - '0';
693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (nibble > 9) {
694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            nibble = (nibble & ~('a' - 'A')) - 'A' + '9' + 1;
695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        unicode |= nibble;
697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(unicode < 256);
699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    *writer++ = (unsigned char) unicode;
700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(ctrl == 'n');
702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    *writer++ = '\n';
703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fStart = fLine = fChar = fStorage;
707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fEnd = writer;
708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~EscapeParser() override {
711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        delete fStorage;
712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    char* fStorage;
715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass RootDefinition;
718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass Definition : public NonAssignable {
720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum Type {
722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNone,
723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kWord,
724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kMark,
725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kKeyWord,
726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBracket,
727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kPunctuation,
728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kFileType,
729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class TrimExtract {
732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNo,
733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kYes
734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class ExampleOptions {
737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kText,
738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kPng,
739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kAll
740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class MethodType {
743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNone,
744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kConstructor,
745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kDestructor,
746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kOperator,
747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class Operator {
750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kUnknown,
751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kAdd,
752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kAddTo,
753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kArray,
754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kCast,
755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kCopy,
756fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kDelete,
757fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kDereference,
758fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kEqual,
759fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kMinus,
760fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kMove,
761fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kMultiply,
762fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kMultiplyBy,
763fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNew,
764fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNotEqual,
765fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kSubtract,
766fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kSubtractFrom,
767fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
768fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
769fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition() {}
770fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
771fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition(const char* start, const char* end, int line, Definition* parent)
772fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : fStart(start)
773fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fContentStart(start)
774fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fContentEnd(end)
775fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fParent(parent)
776fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fLineCount(line)
777fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fType(Type::kWord) {
778fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (parent) {
779fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(parent->fFileName.length() > 0);
780fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fFileName = parent->fFileName;
781fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
782fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setParentIndex();
783fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
784fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
785fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition(MarkType markType, const char* start, int line, Definition* parent)
786fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : Definition(markType, start, nullptr, line, parent) {
787fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
788fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
789fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition(MarkType markType, const char* start, const char* end, int line, Definition* parent)
790fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : Definition(start, end, line, parent) {
791fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fMarkType = markType;
792fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fType = Type::kMark;
793fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
794fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
795fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition(Bracket bracket, const char* start, int lineCount, Definition* parent)
796fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : Definition(start, nullptr, lineCount, parent) {
797fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fBracket = bracket;
798fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fType = Type::kBracket;
799fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
800fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
801fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition(KeyWord keyWord, const char* start, const char* end, int lineCount,
802fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            Definition* parent)
803fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : Definition(start, end, lineCount, parent) {
804fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fKeyWord = keyWord;
805fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fType = Type::kKeyWord;
806fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
807fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
808fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition(Punctuation punctuation, const char* start, int lineCount, Definition* parent)
809fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : Definition(start, nullptr, lineCount, parent) {
810fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPunctuation = punctuation;
811fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fType = Type::kPunctuation;
812fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
813fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
814fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual ~Definition() {}
815fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
816fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual RootDefinition* asRoot() { SkASSERT(0); return nullptr; }
817fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual const RootDefinition* asRoot() const { SkASSERT(0); return nullptr; }
818fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool boilerplateIfDef(Definition* parent);
819fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool boilerplateDef(Definition* parent);
820fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
821fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool boilerplateEndIf() {
822fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
823fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
824fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
825fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool checkMethod() const;
826fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool crossCheck2(const Definition& includeToken) const;
827fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool crossCheck(const Definition& includeToken) const;
828fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool crossCheckInside(const char* start, const char* end, const Definition& includeToken) const;
829fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
830fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* csParent() const {
831fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Definition* test = fParent;
832fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (test) {
833fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (MarkType::kStruct == test->fMarkType || MarkType::kClass == test->fMarkType) {
834fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return test;
835fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
836fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            test = test->fParent;
837fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
838fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
839fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
840fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
841fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool exampleToScript(string* result, ExampleOptions ) const;
842fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string extractText(TrimExtract trimExtract) const;
843fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fiddleName() const;
844fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string formatFunction() const;
845fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* hasChild(MarkType markType) const;
846fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool hasMatch(const string& name) const;
847fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* hasParam(const string& ref) const;
848fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool isClone() const { return fClone; }
849fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
850fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* iRootParent() {
851fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Definition* test = fParent;
852fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (test) {
853fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Type::kKeyWord == test->fType && KeyWord::kClass == test->fKeyWord) {
854fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return test;
855fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
856fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            test = test->fParent;
857fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
858fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
859fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
860fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
861fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual bool isRoot() const { return false; }
862fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool isStructOrClass() const;
863fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
864fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int length() const {
865fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return (int) (fContentEnd - fContentStart);
866fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
867fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
868fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool methodHasReturn(const string& name, TextParser* methodParser) const;
869fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string methodName() const;
870fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool nextMethodParam(TextParser* methodParser, const char** nextEndPtr,
871fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         string* paramName) const;
872fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static string NormalizedName(string name);
873fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool paramsMatch(const string& fullRef, const string& name) const;
874fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseOperator(size_t doubleColons, string& result);
875fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
876fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string printableName() const {
877fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string result(fName);
878fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        std::replace(result.begin(), result.end(), '_', ' ');
879fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return result;
880fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
881fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
882fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    template <typename T> T reportError(const char* errorStr) const {
883fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TextParser tp(this);
884fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        tp.reportError(errorStr);
885fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return T();
886fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
887fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
888fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual RootDefinition* rootParent() { SkASSERT(0); return nullptr; }
889fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual const RootDefinition* rootParent() const { SkASSERT(0); return nullptr; }
890fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setCanonicalFiddle();
891fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
892fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setParentIndex() {
893fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fParentIndex = fParent ? (int) fParent->fTokens.size() : -1;
894fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
895fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
896fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setWrapper();
897fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
898fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fText;  // if text is constructed instead of in a file, it's put here
899fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fStart = nullptr;  // .. in original text file, or the start of fText
900fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fContentStart;  // start past optional markup name
901fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fName;
902fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fFiddle;  // if its a constructor or operator, fiddle name goes here
903fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fContentEnd = nullptr;  // the end of the contained text
904fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fTerminator = nullptr;  // the end of the markup, normally ##\n or \n
905fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fParent = nullptr;
906fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    list<Definition> fTokens;
907fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    vector<Definition*> fChildren;
908fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fHash;  // generated by fiddle
909fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fFileName;
910fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    mutable string fWrapper; // used by Example to wrap into proper function
911fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t fLineCount = 0;
912fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fParentIndex = 0;
913fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    MarkType fMarkType = MarkType::kNone;
914fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    KeyWord fKeyWord = KeyWord::kNone;
915fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Bracket fBracket = Bracket::kNone;
916fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Punctuation fPunctuation = Punctuation::kNone;
917fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    MethodType fMethodType = MethodType::kNone;
918fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Operator fOperator = Operator::kUnknown;
919fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Type fType = Type::kNone;
920fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fClone = false;
921fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fCloned = false;
922fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fOperatorConst = false;
923fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fPrivate = false;
924fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fShort = false;
925fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fMemberStart = false;
926fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fAnonymous = false;
927fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    mutable bool fVisited = false;
928fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
929fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
930fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass RootDefinition : public Definition {
931fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
932fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class AllowParens {
933fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNo,
934fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kYes,
935fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
936fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
937fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RootDefinition() {
938fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
939fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
940fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RootDefinition(MarkType markType, const char* start, int line, Definition* parent)
941fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            : Definition(markType, start, line, parent) {
942fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
943fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
944fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RootDefinition(MarkType markType, const char* start, const char* end, int line,
945fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            Definition* parent) : Definition(markType, start, end,  line, parent) {
946fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
947fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
948fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~RootDefinition() override {
949fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (auto& iter : fBranches) {
950fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            delete iter.second;
951fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
952fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
953fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
954fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RootDefinition* asRoot() override { return this; }
955fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const RootDefinition* asRoot() const override { return this; }
956fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void clearVisited();
957fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool dumpUnVisited();
958fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* find(const string& ref, AllowParens ) const;
959fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool isRoot() const override { return true; }
960fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RootDefinition* rootParent() override { return fRootParent; }
961fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const RootDefinition* rootParent() const override { return fRootParent; }
962fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setRootParent(RootDefinition* rootParent) { fRootParent = rootParent; }
963fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
964fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, RootDefinition*> fBranches;
965fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition> fLeaves;
966fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
967fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RootDefinition* fRootParent = nullptr;
968fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
969fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
970fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct IClassDefinition : public Definition {
971fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition*> fEnums;
972fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition*> fMembers;
973fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition*> fMethods;
974fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition*> fStructs;
975fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition*> fTypedefs;
976fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
977fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
978fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct Reference {
979fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Reference()
980fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : fLocation(nullptr)
981fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fDefinition(nullptr) {
982fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
983fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
984fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fLocation;  // .. in original text file
985fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fDefinition;
986fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
987fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
988fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct TypeNames {
989fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fName;
990fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    MarkType fMarkType;
991fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
992fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
993fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ParserCommon : public TextParser {
994fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
995fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
996fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ParserCommon() : TextParser()
997fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fParent(nullptr)
998fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fDebugOut(false)
999fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
1000fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1001fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1002fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~ParserCommon() override {
1003fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1004fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1005fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addDefinition(Definition* def) {
1006fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fParent->fChildren.push_back(def);
1007fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fParent = def;
1008fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1009fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1010fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void indentToColumn(int column) {
1011fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(column >= fColumn);
1012fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fDebugOut) {
1013fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("%*s", column - fColumn, "");
1014fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1015fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fprintf(fOut, "%*s", column - fColumn, "");
1016fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fColumn = column;
1017fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fSpaces += column - fColumn;
1018fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1019fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1020fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool leadingPunctuation(const char* str, size_t len) const {
1021fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!fPendingSpace) {
1022fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
1023fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1024fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (len < 2) {
1025fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
1026fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1027fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if ('.' != str[0] && ',' != str[0] && ';' != str[0] && ':' != str[0]) {
1028fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
1029fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1030fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return ' ' >= str[1];
1031fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1032fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1033fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void lf(int count) {
1034fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPendingLF = SkTMax(fPendingLF, count);
1035fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->nl();
1036fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1037fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1038fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void lfAlways(int count) {
1039fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(count);
1040fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writePending();
1041fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1042fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1043fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void lfcr() {
1044fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1045fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1046fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1047fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void nl() {
1048fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLinefeeds = 0;
1049fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fSpaces = 0;
1050fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fColumn = 0;
1051fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPendingSpace = 0;
1052fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1053fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1054fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseFile(const char* file, const char* suffix);
1055fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseStatus(const char* file, const char* suffix, StatusFilter filter);
1056fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual bool parseFromFile(const char* path) = 0;
1057fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseSetup(const char* path);
1058fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1059fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void popObject() {
1060fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fParent->fContentEnd = fParent->fTerminator = fChar;
1061fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fParent = fParent->fParent;
1062fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1063fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1064fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* ReadToBuffer(string filename, int* size);
1065fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1066fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void reset() = 0;
1067fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1068fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void resetCommon() {
1069fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLine = fChar = fStart;
1070fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLineCount = 0;
1071fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fParent = nullptr;
1072fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndent = 0;
1073fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fOut = nullptr;
1074fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fMaxLF = 2;
1075fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPendingLF = 0;
1076fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPendingSpace = 0;
1077fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fOutdentNext = false;
1078fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        nl();
1079fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot   }
1080fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1081fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setAsParent(Definition* definition) {
1082fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fParent) {
1083fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fParent->fChildren.push_back(definition);
1084fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            definition->fParent = fParent;
1085fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1086fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fParent = definition;
1087fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1088fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1089fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void singleLF() {
1090fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fMaxLF = 1;
1091fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1092fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1093fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeBlock(int size, const char* data) {
1094fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkAssertResult(writeBlockTrim(size, data));
1095fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1096fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1097fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeBlockIndent(int size, const char* data);
1098fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool writeBlockTrim(int size, const char* data);
1099fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeCommentHeader() {
1101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(2);
1102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("/**");
1103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeSpace();
1104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeCommentTrailer() {
1107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("*/");
1108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lfcr();
1109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writePending();
1112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // write a pending space, so that two consecutive calls
1114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // don't double write, and trailing spaces on lines aren't written
1115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeSpace(int count = 1) {
1116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(!fPendingLF);
1117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(!fLinefeeds);
1118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(fColumn > 0);
1119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(!fSpaces);
1120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPendingSpace = count;
1121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeString(const char* str);
1124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeString(const string& str) {
1126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(str.c_str());
1127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool writtenFileDiffers(string filename, string readname);
1130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, sk_sp<SkData>> fRawData;
1132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, vector<char>> fLFOnly;
1133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fParent;
1134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    FILE* fOut;
1135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fLinefeeds;    // number of linefeeds last written, zeroed on non-space
1136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fMaxLF;        // number of linefeeds allowed
1137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fPendingLF;    // number of linefeeds to write (can be suppressed)
1138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fSpaces;       // number of spaces (indent) last written, zeroed on non-space
1139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fColumn;       // current column; number of chars past last linefeed
1140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fIndent;       // desired indention
1141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fPendingSpace; // one or two spaces should preceed the next string or block
1142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    char fLastChar;    // last written
1143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fDebugOut;    // set true to write to std out
1144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fOutdentNext; // set at end of embedded struct to prevent premature outdent
1145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
1146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef TextParser INHERITED;
1147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
1148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct JsonStatus {
1150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Json::Value& fObject;
1151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Json::Value::iterator fIter;
1152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fName;
1153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
1154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass StatusIter : public ParserCommon {
1156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
1157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    StatusIter(const char* statusFile, const char* suffix, StatusFilter);
1158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~StatusIter() override {}
1159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string baseDir();
1160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool empty() { return fStack.empty(); }
1161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool next(string* file);
1162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
1163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseFromFile(const char* path) override;
1164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reset() override;
1165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
1166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    vector<JsonStatus> fStack;
1167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Json::Value fRoot;
1168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fSuffix;
1169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    StatusFilter fFilter;
1170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
1171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass BmhParser : public ParserCommon {
1173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
1174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class MarkLookup {
1175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kRequire,
1176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kAllowUnknown,
1177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class Resolvable {
1180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNo,    // neither resolved nor output
1181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kYes,   // resolved, output
1182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kOut,   // not resolved, but output
1183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kLiteral, // output untouched (FIXME: is this really different from kOut?)
1184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		kClone, // resolved, output, with references to clones as well
1185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class Exemplary {
1188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNo,
1189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kYes,
1190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kOptional,
1191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class TableState {
1194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNone,
1195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kColumnStart,
1196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kColumnEnd,
1197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define M(mt) (1LL << (int) MarkType::k##mt)
1200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define M_D M(Description)
1201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define M_CS M(Class) | M(Struct)
1202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define M_ST M(Subtopic) | M(Topic)
1203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define M_CSST M_CS | M_ST
1204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef M_E
1205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef M_E
1206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
1207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define M_E M(Enum) | M(EnumClass)
1208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define R_Y Resolvable::kYes
1210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define R_N Resolvable::kNo
1211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define R_O Resolvable::kOut
1212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define R_C Resolvable::kClone
1213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define E_Y Exemplary::kYes
1215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define E_N Exemplary::kNo
1216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define E_O Exemplary::kOptional
1217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    BmhParser(bool skip) : ParserCommon()
1219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fMaps {
1220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// names without formal definitions (e.g. Column) aren't included
1221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// fill in other names once they're actually used
1222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot  { "",            nullptr,      MarkType::kNone,         R_Y, E_N, 0 }
1223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "A",           nullptr,      MarkType::kAnchor,       R_N, E_N, 0 }
1224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Alias",       nullptr,      MarkType::kAlias,        R_N, E_N, 0 }
1225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Bug",         nullptr,      MarkType::kBug,          R_N, E_N, 0 }
1226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Class",       &fClassMap,   MarkType::kClass,        R_Y, E_O, M_CSST | M(Root) }
1227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Code",        nullptr,      MarkType::kCode,         R_O, E_N, M_CSST | M_E | M(Method) }
1228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "",            nullptr,      MarkType::kColumn,       R_Y, E_N, M(Row) }
1229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "",            nullptr,      MarkType::kComment,      R_N, E_N, 0 }
1230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Const",       &fConstMap,   MarkType::kConst,        R_Y, E_N, M_E | M_ST  }
1231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Define",      nullptr,      MarkType::kDefine,       R_O, E_N, M_ST }
1232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "DefinedBy",   nullptr,      MarkType::kDefinedBy,    R_N, E_N, M(Method) }
1233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Deprecated",  nullptr,      MarkType::kDeprecated,   R_Y, E_N, 0 }
1234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Description", nullptr,      MarkType::kDescription,  R_Y, E_N, M(Example) | M(NoExample) }
1235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Doxygen",     nullptr,      MarkType::kDoxygen,      R_Y, E_N, 0 }
1236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Duration",    nullptr,      MarkType::kDuration,     R_N, E_N, M(Example) | M(NoExample) }
1237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Enum",        &fEnumMap,    MarkType::kEnum,         R_Y, E_O, M_CSST | M(Root) }
1238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "EnumClass",   &fClassMap,   MarkType::kEnumClass,    R_Y, E_O, M_CSST | M(Root) }
1239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Example",     nullptr,      MarkType::kExample,      R_O, E_N, M_CSST | M_E | M(Method) }
1240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Experimental", nullptr,     MarkType::kExperimental, R_Y, E_N, 0 }
1241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "External",    nullptr,      MarkType::kExternal,     R_Y, E_N, M(Root) }
1242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "File",        nullptr,      MarkType::kFile,         R_N, E_N, M(Track) }
1243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Formula",     nullptr,      MarkType::kFormula,      R_O, E_N,
1244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                    M(Column) | M_ST | M(Member) | M(Method) | M_D }
1245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Function",    nullptr,      MarkType::kFunction,     R_O, E_N, M(Example) | M(NoExample) }
1246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Height",      nullptr,      MarkType::kHeight,       R_N, E_N, M(Example) | M(NoExample) }
1247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Image",       nullptr,      MarkType::kImage,        R_N, E_N, M(Example) | M(NoExample) }
1248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "In",          nullptr,      MarkType::kIn,           R_N, E_N,
1249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                             M_CSST | M_E | M(Method) | M(Typedef) }
1250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Legend",      nullptr,      MarkType::kLegend,       R_Y, E_N, M(Table) }
1251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Line",        nullptr,      MarkType::kLine,         R_N, E_N,
1252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                             M_CSST | M_E | M(Method) | M(Typedef) }
1253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "",            nullptr,      MarkType::kLink,         R_N, E_N, M(Anchor) }
1254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "List",        nullptr,      MarkType::kList,         R_Y, E_N, M(Method) | M_CSST | M_E | M_D }
1255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Literal",     nullptr,      MarkType::kLiteral,      R_N, E_N, M(Code) }
1256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "",            nullptr,      MarkType::kMarkChar,     R_N, E_N, 0 }
1257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Member",      nullptr,      MarkType::kMember,       R_Y, E_N, M_CSST }
1258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Method",      &fMethodMap,  MarkType::kMethod,       R_Y, E_Y, M_CSST }
1259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "NoExample",   nullptr,      MarkType::kNoExample,    R_O, E_N, M_CSST | M_E | M(Method) }
1260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Outdent",     nullptr,      MarkType::kOutdent,      R_N, E_N, M(Code) }
1261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Param",       nullptr,      MarkType::kParam,        R_Y, E_N, M(Method) }
1262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Platform",    nullptr,      MarkType::kPlatform,     R_N, E_N, M(Example) | M(NoExample) }
1263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Populate",    nullptr,      MarkType::kPopulate,     R_N, E_N, M(Subtopic) }
1264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Private",     nullptr,      MarkType::kPrivate,      R_N, E_N, 0 }
1265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Return",      nullptr,      MarkType::kReturn,       R_Y, E_N, M(Method) }
1266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "",            nullptr,      MarkType::kRoot,         R_Y, E_N, 0 }
1267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "",            nullptr,      MarkType::kRow,          R_Y, E_N, M(Table) | M(List) }
1268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "SeeAlso",     nullptr,      MarkType::kSeeAlso,      R_C, E_N,
1269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                             M_CSST | M_E | M(Method) | M(Typedef) }
1270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Set",         nullptr,      MarkType::kSet,          R_N, E_N, M(Example) | M(NoExample) }
1271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "StdOut",      nullptr,      MarkType::kStdOut,       R_N, E_N, M(Example) | M(NoExample) }
1272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Struct",      &fClassMap,   MarkType::kStruct,       R_Y, E_O, M(Class) | M(Root) | M_ST }
1273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Substitute",  nullptr,      MarkType::kSubstitute,   R_N, E_N, M_ST }
1274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Subtopic",    nullptr,      MarkType::kSubtopic,     R_Y, E_Y, M_CSST }
1275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Table",       nullptr,      MarkType::kTable,        R_Y, E_N, M(Method) | M_CSST | M_E }
1276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Template",    nullptr,      MarkType::kTemplate,     R_Y, E_N, 0 }
1277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "",            nullptr,      MarkType::kText,         R_N, E_N, 0 }
1278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Time",        nullptr,      MarkType::kTime,         R_Y, E_N, M(Track) }
1279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "ToDo",        nullptr,      MarkType::kToDo,         R_N, E_N, 0 }
1280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Topic",       nullptr,      MarkType::kTopic,        R_Y, E_Y, M_CS | M(Root) | M(Topic) }
1281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Track",       nullptr,      MarkType::kTrack,        R_Y, E_N, M_E | M_ST }
1282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Typedef",     &fTypedefMap, MarkType::kTypedef,      R_Y, E_N, M(Class) | M_ST }
1283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "",            nullptr,      MarkType::kUnion,        R_Y, E_N, 0 }
1284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Volatile",    nullptr,      MarkType::kVolatile,     R_N, E_N, M(StdOut) }
1285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, { "Width",       nullptr,      MarkType::kWidth,        R_N, E_N, M(Example) | M(NoExample) } }
1286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot, fSkip(skip)
1287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        {
1288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->reset();
1289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef R_O
1292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef R_N
1293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef R_Y
1294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef M_E
1296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef M_CSST
1297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef M_ST
1298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef M_CS
1299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef M_D
1300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef M
1301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~BmhParser() override {}
1303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool addDefinition(const char* defStart, bool hasEnd, MarkType markType,
1305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const vector<string>& typeNameBuilder);
1306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool checkExamples() const;
1307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool checkParamReturn(const Definition* definition) const;
1308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool dumpExamples(const char* fiddleJsonFileName) const;
1309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool childOf(MarkType markType) const;
1310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string className(MarkType markType);
1311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool collectExternals();
1312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int endHashCount() const;
1313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool endTableColumn(const char* end, const char* terminator);
1314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RootDefinition* findBmhObject(MarkType markType, const string& typeName) const {
1316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        auto map = fMaps[(int) markType].fBmh;
1317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!map) {
1318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return nullptr;
1319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return &(*map)[typeName];
1321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool findDefinitions();
1324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    MarkType getMarkType(MarkLookup lookup) const;
1325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool hasEndToken() const;
1326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string memberName();
1327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string methodName();
1328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* parentSpace() const;
1329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseFromFile(const char* path) override {
1331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!INHERITED::parseSetup(path)) {
1332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
1333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fCheckMethods = !strstr(path, "undocumented.bmh");
1335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return findDefinitions();
1336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool popParentStack(Definition* definition);
1339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reportDuplicates(const Definition& def, const string& dup) const;
1340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reset() override {
1342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        INHERITED::resetCommon();
1343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fRoot = nullptr;
1344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fWorkingColumn = nullptr;
1345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fRow = nullptr;
1346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fTableState = TableState::kNone;
1347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fMC = '#';
1348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInChar = false;
1349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInCharCommentString = false;
1350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInComment = false;
1351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInEnum = false;
1352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInString = false;
1353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fCheckMethods = false;
1354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipNoName();
1357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool skipToDefinitionEnd(MarkType markType);
1358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	bool skipToString();
1359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void spellCheck(const char* match, SkCommandLineFlags::StringArray report) const;
1360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void spellStatus(const char* match, SkCommandLineFlags::StringArray report) const;
1361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    vector<string> topicName();
1362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    vector<string> typeName(MarkType markType, bool* expectEnd);
1363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string typedefName() override;
1364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string uniqueName(const string& base, MarkType markType);
1365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string uniqueRootName(const string& base, MarkType markType);
1366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void validate() const;
1367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string word(const string& prefix, const string& delimiter);
1368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
1370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct DefinitionMap {
1371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* fName;
1372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unordered_map<string, RootDefinition>* fBmh;
1373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        MarkType fMarkType;
1374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Resolvable fResolve;
1375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Exemplary fExemplary;  // worthy of an example
1376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        uint64_t fParentMask;
1377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    DefinitionMap fMaps[Last_MarkType + 1];
1380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    forward_list<RootDefinition> fTopics;
1381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    forward_list<Definition> fMarkup;
1382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    forward_list<RootDefinition> fExternals;
1383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    vector<string> fInputFiles;
1384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, RootDefinition> fClassMap;
1385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, RootDefinition> fConstMap;
1386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, RootDefinition> fEnumMap;
1387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, RootDefinition> fMethodMap;
1388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, RootDefinition> fTypedefMap;
1389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition*> fTopicMap;
1390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition*> fAliasMap;
1391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RootDefinition* fRoot;
1392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fWorkingColumn;
1393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fRow;
1394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fColStart;
1395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TableState fTableState;
1396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    mutable char fMC;  // markup character
1397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fAnonymous;
1398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fCloned;
1399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInChar;
1400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInCharCommentString;
1401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInEnum;
1402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInComment;
1403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInString;
1404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fCheckMethods;
1405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fSkip = false;
1406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fWroteOut = false;
1407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
1408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef ParserCommon INHERITED;
1409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
1410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass IncludeParser : public ParserCommon {
1412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
1413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class IsStruct {
1414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNo,
1415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kYes,
1416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    IncludeParser() : ParserCommon()
1419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fMaps {
1420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot          { nullptr,        MarkType::kNone }
1421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kAnchor }
1422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kAlias }
1423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kBug }
1424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kClass }
1425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kCode }
1426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kColumn }
1427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kComment }
1428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kConst }
1429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { &fIDefineMap,   MarkType::kDefine }
1430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kDefinedBy }
1431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kDeprecated }
1432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kDescription }
1433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kDoxygen }
1434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kDuration }
1435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { &fIEnumMap,     MarkType::kEnum }
1436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { &fIEnumMap,     MarkType::kEnumClass }
1437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kExample }
1438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kExperimental }
1439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kExternal }
1440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kFile }
1441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kFormula }
1442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kFunction }
1443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kHeight }
1444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		, { nullptr,        MarkType::kImage }
1445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		, { nullptr,        MarkType::kIn }
1446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		, { nullptr,        MarkType::kLegend }
1447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		, { nullptr,        MarkType::kLine }
1448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		, { nullptr,        MarkType::kLink }
1449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kList }
1450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kLiteral }
1451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kMarkChar }
1452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kMember }
1453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kMethod }
1454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kNoExample }
1455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kOutdent }
1456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kParam }
1457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kPlatform }
1458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kPopulate }
1459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kPrivate }
1460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kReturn }
1461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kRoot }
1462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kRow }
1463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kSeeAlso }
1464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kSet }
1465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kStdOut }
1466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { &fIStructMap,   MarkType::kStruct }
1467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kSubstitute }
1468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kSubtopic }
1469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kTable }
1470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { &fITemplateMap, MarkType::kTemplate }
1471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kText }
1472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kTime }
1473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kToDo }
1474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kTopic }
1475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kTrack }
1476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { &fITypedefMap,  MarkType::kTypedef }
1477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { &fIUnionMap,    MarkType::kUnion }
1478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kVolatile }
1479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , { nullptr,        MarkType::kWidth } }
1480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
1481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->reset();
1482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~IncludeParser() override {}
1485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addKeyword(KeyWord keyWord);
1487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addPunctuation(Punctuation punctuation) {
1489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fParent->fTokens.emplace_back(punctuation, fChar, fLineCount, fParent);
1490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addWord() {
1493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fParent->fTokens.emplace_back(fIncludeWord, fChar, fLineCount, fParent);
1494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIncludeWord = nullptr;
1495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void checkForMissingParams(const vector<string>& methodParams,
1498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                               const vector<string>& foundParams);
1499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool checkForWord();
1500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string className() const;
1501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool crossCheck(BmhParser& );
1502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    IClassDefinition* defineClass(const Definition& includeDef, const string& className);
1503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void dumpClassTokens(IClassDefinition& classDef);
1504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void dumpComment(const Definition& );
1505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void dumpEnum(const Definition& , const string& name);
1506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void dumpMethod(const Definition& );
1507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void dumpMember(const Definition& );
1508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool dumpTokens(const string& directory);
1509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool dumpTokens(const string& directory, const string& skClassName);
1510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool findComments(const Definition& includeDef, Definition* markupDef);
1511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* findIncludeObject(const Definition& includeDef, MarkType markType,
1513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const string& typeName) {
1514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        typedef Definition* DefinitionPtr;
1515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unordered_map<string, Definition>* map = fMaps[(int) markType].fInclude;
1516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!map) {
1517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return reportError<DefinitionPtr>("invalid mark type");
1518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string name = this->uniqueName(*map, typeName);
1520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Definition& markupDef = (*map)[name];
1521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (markupDef.fStart) {
1522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return reportError<DefinitionPtr>("definition already defined");
1523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fFileName = fFileName;
1525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fStart = includeDef.fStart;
1526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fContentStart = includeDef.fStart;
1527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fName = name;
1528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fContentEnd = includeDef.fContentEnd;
1529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fTerminator = includeDef.fTerminator;
1530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fParent = fParent;
1531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fLineCount = includeDef.fLineCount;
1532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fMarkType = markType;
1533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fKeyWord = includeDef.fKeyWord;
1534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        markupDef.fType = Definition::Type::kMark;
1535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return &markupDef;
1536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static KeyWord FindKey(const char* start, const char* end);
1539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool internalName(const Definition& ) const;
1540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseChar();
1541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseComment(const string& filename, const char* start, const char* end, int lineCount,
1542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            Definition* markupDef);
1543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseClass(Definition* def, IsStruct);
1544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseDefine();
1545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseEnum(Definition* child, Definition* markupDef);
1546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseFromFile(const char* path) override {
1548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->reset();
1549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!INHERITED::parseSetup(path)) {
1550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
1551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string name(path);
1553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return this->parseInclude(name);
1554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseInclude(const string& name);
1557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseMember(Definition* child, Definition* markupDef);
1558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseMethod(Definition* child, Definition* markupDef);
1559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseObject(Definition* child, Definition* markupDef);
1560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseObjects(Definition* parent, Definition* markupDef);
1561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseTemplate();
1562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseTypedef(Definition* child, Definition* markupDef);
1563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseUnion();
1564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void popBracket() {
1566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(Definition::Type::kBracket == fParent->fType);
1567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->popObject();
1568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Bracket bracket = this->topBracket();
1569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setBracketShortCuts(bracket);
1570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void pushBracket(Bracket bracket) {
1573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setBracketShortCuts(bracket);
1574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fParent->fTokens.emplace_back(bracket, fChar, fLineCount, fParent);
1575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Definition* container = &fParent->fTokens.back();
1576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->addDefinition(container);
1577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static void RemoveFile(const char* docs, const char* includes);
1580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static void RemoveOneFile(const char* docs, const char* includesFileOrPath);
1581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reset() override {
1583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        INHERITED::resetCommon();
1584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fRootTopic = nullptr;
1585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInBrace = nullptr;
1586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIncludeWord = nullptr;
1587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLastObject = nullptr;
1588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPrev = '\0';
1589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInChar = false;
1590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInCharCommentString = false;
1591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInComment = false;
1592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInEnum = false;
1593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInFunction = false;
1594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInString = false;
1595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fFailed = false;
1596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPriorEnum = nullptr;
1597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setBracketShortCuts(Bracket bracket) {
1600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInComment = Bracket::kSlashSlash == bracket || Bracket::kSlashStar == bracket;
1601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInString = Bracket::kString == bracket;
1602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInChar = Bracket::kChar == bracket;
1603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInCharCommentString = fInChar || fInComment || fInString;
1604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Bracket topBracket() const {
1607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Definition* parent = fParent;
1608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (parent && Definition::Type::kBracket != parent->fType) {
1609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            parent = parent->fParent;
1610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return parent ? parent->fBracket : Bracket::kNone;
1612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    template <typename T>
1615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string uniqueName(const unordered_map<string, T>& m, const string& typeName) {
1616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string base(typeName.size() > 0 ? typeName : "_anonymous");
1617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string name(base);
1618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int anonCount = 1;
1619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        do {
1620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            auto iter = m.find(name);
1621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (iter == m.end()) {
1622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return name;
1623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            name = base + '_';
1625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            name += to_string(++anonCount);
1626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } while (true);
1627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // should never get here
1628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return string();
1629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void validate() const;
1632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeDefinition(const Definition& def) {
1634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (def.length() > 1) {
1635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->writeBlock((int) (def.fContentEnd - def.fContentStart), def.fContentStart);
1636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->lf(1);
1637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeDefinition(const Definition& def, const string& name, int spaces) {
1641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeBlock((int) (def.fContentEnd - def.fContentStart), def.fContentStart);
1642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeSpace(spaces);
1643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(name);
1644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeEndTag() {
1648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("##");
1650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeEndTag(const char* tagType) {
1654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(string("#") + tagType + " ##");
1656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeEndTag(const char* tagType, const char* tagID, int spaces = 1) {
1660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(string("#") + tagType + " " + tagID);
1662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeSpace(spaces);
1663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("##");
1664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeEndTag(const char* tagType, const string& tagID, int spaces = 1) {
1668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeEndTag(tagType, tagID.c_str(), spaces);
1669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeIncompleteTag(const char* tagType, const string& tagID, int spaces = 1) {
1672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(string("#") + tagType + " " + tagID);
1673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeSpace(spaces);
1674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("incomplete");
1675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeSpace();
1676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("##");
1677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeIncompleteTag(const char* tagType) {
1681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(string("#") + tagType + " incomplete ##");
1682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeTableHeader(const char* col1, size_t pad, const char* col2) {
1686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("#Table");
1688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("#Legend");
1690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string legend = "# ";
1692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        legend += col1;
1693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (pad > strlen(col1)) {
1694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            legend += string(pad - strlen(col1), ' ');
1695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        legend += " # ";
1697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        legend += col2;
1698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        legend += " ##";
1699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(legend);
1700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("#Legend ##");
1702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeTableRow(size_t pad, const string& col1) {
1706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string row = "# " + col1 + string(pad - col1.length(), ' ') + " # ##";
1708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(row);
1709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeTableRow(size_t pad1, const string& col1, size_t pad2, const string& col2) {
1713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string row = "# " + col1 + string(pad1 - col1.length(), ' ') + " # " +
1715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                col2 + string(pad2 - col2.length(), ' ') + " ##";
1716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(row);
1717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeTableTrailer() {
1721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("#Table ##");
1723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeTag(const char* tagType) {
1727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("#");
1729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(tagType);
1730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeTagNoLF(const char* tagType, const char* tagID) {
1733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("#");
1734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(tagType);
1735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeSpace();
1736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(tagID);
1737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeTagNoLF(const char* tagType, const string& tagID) {
1740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeTagNoLF(tagType, tagID.c_str());
1741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeTag(const char* tagType, const char* tagID) {
1744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(1);
1745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeTagNoLF(tagType, tagID);
1746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void writeTag(const char* tagType, const string& tagID) {
1749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeTag(tagType, tagID.c_str());
1750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
1753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static void ValidateKeyWords();
1754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct DefinitionMap {
1756fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unordered_map<string, Definition>* fInclude;
1757fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        MarkType fMarkType;
1758fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1759fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1760fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    DefinitionMap fMaps[Last_MarkType + 1];
1761fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition> fIncludeMap;
1762fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, IClassDefinition> fIClassMap;
1763fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition> fIDefineMap;
1764fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition> fIEnumMap;
1765fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition> fIFunctionMap;
1766fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition> fIStructMap;
1767fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition> fITemplateMap;
1768fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition> fITypedefMap;
1769fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, Definition> fIUnionMap;
1770fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fRootTopic;
1771fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fInBrace;
1772fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fLastObject;
1773fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fPriorEnum;
1774fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fPriorIndex;
1775fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fIncludeWord;
1776fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    char fPrev;
1777fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInChar;
1778fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInCharCommentString;
1779fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInComment;
1780fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInEnum;
1781fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInFunction;
1782fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInString;
1783fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fFailed;
1784fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1785fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef ParserCommon INHERITED;
1786fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
1787fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1788fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass IncludeWriter : public IncludeParser {
1789fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
1790fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class Word {
1791fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kStart,
1792fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kCap,
1793fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kFirst,
1794fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kUnderline,
1795fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kMixed,
1796fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1797fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1798fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class Phrase {
1799fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNo,
1800fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kYes,
1801fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1802fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1803fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class PunctuationState {
1804fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kStart,
1805fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kDelimiter,
1806fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kPeriod,
1807fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kSpace,
1808fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1809fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1810fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class RefType {
1811fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kUndefined,
1812fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNormal,
1813fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kExternal,
1814fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1815fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1816fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class Wrote {
1817fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNone,
1818fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kLF,
1819fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kChars,
1820fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1821fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1822fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct IterState {
1823fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        IterState (list<Definition>::iterator tIter, list<Definition>::iterator tIterEnd)
1824fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            : fDefIter(tIter)
1825fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fDefEnd(tIterEnd) {
1826fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1827fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        list<Definition>::iterator fDefIter;
1828fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        list<Definition>::iterator fDefEnd;
1829fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1830fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1831fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct ParentPair {
1832fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const Definition* fParent;
1833fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const ParentPair* fPrev;
1834fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1835fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1836fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    IncludeWriter() : IncludeParser() {
1837fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->reset();
1838fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1839fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1840fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~IncludeWriter() override {}
1841fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1842fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool contentFree(int size, const char* data) const {
1843fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (size > 0 && data[0] <= ' ') {
1844fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            --size;
1845fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++data;
1846fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1847fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (size > 0 && data[size - 1] <= ' ') {
1848fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            --size;
1849fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1850fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return 0 == size;
1851fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1852fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1853fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void descriptionOut(const Definition* def);
1854fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void enumHeaderOut(const RootDefinition* root, const Definition& child);
1855fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void enumMembersOut(const RootDefinition* root, Definition& child);
1856fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void enumSizeItems(const Definition& child);
1857fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	Definition* findMemberCommentBlock(const vector<Definition*>& bmhChildren, const string& name) const;
1858fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int lookupMethod(const PunctuationState punctuation, const Word word,
1859fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const int start, const int run, int lastWrite,
1860fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* data, bool hasIndirection);
1861fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int lookupReference(const PunctuationState punctuation, const Word word,
1862fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const int start, const int run, int lastWrite, const char last,
1863fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* data);
1864fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void methodOut(const Definition* method, const Definition& child);
1865fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool populate(Definition* def, ParentPair* parentPair, RootDefinition* root);
1866fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool populate(BmhParser& bmhParser);
1867fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1868fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reset() override {
1869fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        INHERITED::resetCommon();
1870fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fBmhMethod = nullptr;
1871fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fBmhParser = nullptr;
1872fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fEnumDef = nullptr;
1873fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fMethodDef = nullptr;
1874fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fBmhStructDef = nullptr;
1875fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fAttrDeprecated = nullptr;
1876fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInStruct = false;
1877fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fWroteMethod = false;
1878fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndentNext = false;
1879fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPendingMethod = false;
1880fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1881fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1882fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string resolveMethod(const char* start, const char* end, bool first);
1883fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string resolveRef(const char* start, const char* end, bool first, RefType* refType);
1884fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Wrote rewriteBlock(int size, const char* data, Phrase phrase);
1885fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* structMemberOut(const Definition* memberStart, const Definition& child);
1886fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void structOut(const Definition* root, const Definition& child,
1887fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* commentStart, const char* commentEnd);
1888fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void structSizeMembers(const Definition& child);
1889fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
1890fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    BmhParser* fBmhParser;
1891fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fDeferComment;
1892fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fLastComment;
1893fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fBmhMethod;
1894fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fEnumDef;
1895fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fMethodDef;
1896fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fBmhStructDef;
1897fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fAttrDeprecated;
1898fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fContinuation;  // used to construct paren-qualified method name
1899fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fAnonymousEnumCount;
1900fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fEnumItemValueTab;
1901fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fEnumItemCommentTab;
1902fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fStructMemberTab;
1903fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fStructValueTab;
1904fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fStructCommentTab;
1905fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInStruct;
1906fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fWroteMethod;
1907fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fIndentNext;
1908fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fPendingMethod;
1909fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1910fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef IncludeParser INHERITED;
1911fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
1912fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1913fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass FiddleBase : public ParserCommon {
1914fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
1915fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    FiddleBase(BmhParser* bmh) : ParserCommon()
1916fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fBmhParser(bmh)
1917fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fContinuation(false)
1918fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fTextOut(false)
1919fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fPngOut(false)
1920fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
1921fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->reset();
1922fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1923fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1924fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reset() override {
1925fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        INHERITED::resetCommon();
1926fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1927fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1928fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* findExample(const string& name) const;
1929fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseFiddles();
1930fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual bool pngOut(Definition* example) = 0;
1931fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual bool textOut(Definition* example, const char* stdOutStart,
1932fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* stdOutEnd) = 0;
1933fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1934fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    BmhParser* fBmhParser;  // must be writable; writes example hash
1935fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fFullName;
1936fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fContinuation;
1937fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fTextOut;
1938fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fPngOut;
1939fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
1940fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef ParserCommon INHERITED;
1941fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
1942fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1943fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass FiddleParser : public FiddleBase {
1944fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
1945fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    FiddleParser(BmhParser* bmh) : FiddleBase(bmh) {
1946fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot       fTextOut = true;
1947fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1948fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1949fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseFromFile(const char* path) override {
1950fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!INHERITED::parseSetup(path)) {
1951fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
1952fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1953fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return parseFiddles();
1954fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1955fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1956fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
1957fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool pngOut(Definition* example) override {
1958fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
1959fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1960fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1961fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool textOut(Definition* example, const char* stdOutStart,
1962fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* stdOutEnd) override;
1963fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1964fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef FiddleBase INHERITED;
1965fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
1966fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1967fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass Catalog : public FiddleBase {
1968fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
1969fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Catalog(BmhParser* bmh) : FiddleBase(bmh) {}
1970fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1971fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool appendFile(const string& path);
1972fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool closeCatalog();
1973fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool openCatalog(const char* inDir, const char* outDir);
1974fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool openStatus(const char* inDir, const char* outDir);
1975fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1976fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseFromFile(const char* path) override ;
1977fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
1978fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool pngOut(Definition* example) override;
1979fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool textOut(Definition* example, const char* stdOutStart,
1980fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* stdOutEnd) override;
1981fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1982fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fDocsDir;
1983fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1984fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef FiddleBase INHERITED;
1985fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
1986fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1987fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass HackParser : public ParserCommon {
1988fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
1989fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    HackParser(const BmhParser& bmhParser)
1990fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : ParserCommon()
1991fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fBmhParser(bmhParser) {
1992fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->reset();
1993fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1994fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1995fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addOneLiner(const Definition* defTable, const Definition* child, bool hasLine,
1996fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            bool lfAfter);
1997fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1998fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseFromFile(const char* path) override {
1999fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!INHERITED::parseSetup(path)) {
2000fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
2001fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
2002fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return hackFiles();
2003fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
2004fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2005fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reset() override {
2006fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        INHERITED::resetCommon();
2007fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
2008fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2009fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string searchTable(const Definition* tableHolder, const Definition* match);
2010fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2011fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void topicIter(const Definition* );
2012fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2013fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
2014fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const BmhParser& fBmhParser;
2015fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fClassesAndStructs;
2016fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fConstants;
2017fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fConstructors;
2018fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fMemberFunctions;
2019fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fMembers;
2020fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fOperators;
2021fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fRelatedFunctions;
2022fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool hackFiles();
2023fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2024fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef ParserCommon INHERITED;
2025fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
2026fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2027fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass MdOut : public ParserCommon {
2028fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
2029fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    MdOut(const BmhParser& bmh) : ParserCommon()
2030fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fBmhParser(bmh) {
2031fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->reset();
2032fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
2033fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2034fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool buildReferences(const char* docDir, const char* mdOutDirOrFile);
2035fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool buildStatus(const char* docDir, const char* mdOutDir);
2036fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2037fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr const char* kClassesAndStructs = "Classes_and_Structs";
2038fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr const char* kConstants = "Constants";
2039fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr const char* kConstructors = "Constructors";
2040fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr const char* kMemberFunctions = "Member_Functions";
2041fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr const char* kMembers = "Members";
2042fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr const char* kOperators = "Operators";
2043fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr const char* kOverview = "Overview";
2044fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr const char* kRelatedFunctions = "Related_Functions";
2045fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr const char* kSubtopics = "Subtopics";
2046fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2047fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
2048fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class TableState {
2049fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNone,
2050fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kRow,
2051fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kColumn,
2052fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
2053fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2054fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string addReferences(const char* start, const char* end, BmhParser::Resolvable );
2055fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool buildRefFromFile(const char* fileName, const char* outDir);
2056fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool checkParamReturnBody(const Definition* def) const;
2057fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void childrenOut(const Definition* def, const char* contentStart);
2058fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* csParent() const;
2059fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* findParamType();
2060fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* isDefined(const TextParser& parser, const string& ref, bool report) const;
2061fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string linkName(const Definition* ) const;
2062fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string linkRef(const string& leadingSpaces, const Definition*, const string& ref,
2063fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot			BmhParser::Resolvable ) const;
2064fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void markTypeOut(Definition* );
2065fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void mdHeaderOut(int depth) { mdHeaderOutLF(depth, 2); }
2066fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void mdHeaderOutLF(int depth, int lf);
2067fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void overviewOut();
2068fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool parseFromFile(const char* path) override { return true; }
2069fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void populateTables(const Definition* def);
2070fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2071fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    vector<const Definition*>& populator(const char* key) {
2072fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fPopulators.find(key)->second.fMembers;
2073fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
2074fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2075fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reset() override {
2076fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        INHERITED::resetCommon();
2077fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fEnumClass = nullptr;
2078fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fMethod = nullptr;
2079fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fRoot = nullptr;
2080fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLastParam = nullptr;
2081fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fTableState = TableState::kNone;
2082fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fHasFiddle = false;
2083fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInDescription = false;
2084fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fInList = false;
2085fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fRespectLeadingSpace = false;
2086fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
2087fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2088fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    BmhParser::Resolvable resolvable(const Definition* definition) const {
2089fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        MarkType markType = definition->fMarkType;
2090fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (MarkType::kCode == markType) {
2091fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (auto child : definition->fChildren) {
2092fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (MarkType::kLiteral == child->fMarkType) {
2093fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return BmhParser::Resolvable::kLiteral;
2094fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
2095fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
2096fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
2097fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if ((MarkType::kExample == markType
2098fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                || MarkType::kFunction == markType) && fHasFiddle) {
2099fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return BmhParser::Resolvable::kNo;
2100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
2101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fBmhParser.fMaps[(int) markType].fResolve;
2102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
2103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void resolveOut(const char* start, const char* end, BmhParser::Resolvable );
2105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void rowOut(const char * name, const string& description);
2106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void subtopicOut(vector<const Definition*>& data);
2107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void subtopicsOut();
2108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct TableContents {
2110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string fDescription;
2111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        vector<const Definition*> fMembers;
2112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
2113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unordered_map<string, TableContents> fPopulators;
2115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    vector<const Definition*> fClassStack;
2116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const BmhParser& fBmhParser;
2118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fEnumClass;
2119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* fMethod;
2120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const RootDefinition* fRoot;
2121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* fLastParam;
2122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TableState fTableState;
2123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fHasFiddle;
2124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInDescription;   // FIXME: for now, ignore unfound camelCase in description since it may
2125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                           // be defined in example which at present cannot be linked to
2126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fInList;
2127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fRespectLeadingSpace;
2128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef ParserCommon INHERITED;
2129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
2130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// some methods cannot be trivially parsed; look for class-name / ~ / operator
2133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass MethodParser : public TextParser {
2134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
2135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    MethodParser(const string& className, const string& fileName,
2136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* start, const char* end, int lineCount)
2137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : TextParser(fileName, start, end, lineCount)
2138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fClassName(className) {
2139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
2140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~MethodParser() override {}
2142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void skipToMethodStart() {
2144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!fClassName.length()) {
2145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->skipToAlphaNum();
2146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
2147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
2148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        while (!this->eof() && !isalnum(this->peek()) && '~' != this->peek()) {
2149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->next();
2150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
2151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
2152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void skipToMethodEnd() {
2154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (this->eof()) {
2155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
2156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
2157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fClassName.length()) {
2158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if ('~' == this->peek()) {
2159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->next();
2160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (!this->startsWith(fClassName.c_str())) {
2161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    --fChar;
2162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return;
2163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
2164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
2165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (this->startsWith(fClassName.c_str()) || this->startsWith("operator")) {
2166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                const char* ptr = this->anyOf("\n (");
2167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (ptr && '(' ==  *ptr) {
2168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->skipToEndBracket(')');
2169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkAssertResult(')' == this->next());
2170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->skipExact("_const");
2171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return;
2172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
2173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
2174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
2175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (this->startsWith("Sk") && this->wordEndsWith(".h")) {  // allow include refs
2176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->skipToNonAlphaNum();
2177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
2178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->skipFullName();
2179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (this->endsWith("operator")) {
2180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                const char* ptr = this->anyOf("\n (");
2181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (ptr && '(' ==  *ptr) {
2182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->skipToEndBracket(')');
2183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkAssertResult(')' == this->next());
2184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->skipExact("_const");
2185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
2186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
2187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
2188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
2189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool wordEndsWith(const char* str) const {
2191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* space = this->strnchr(' ', fEnd);
2192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!space) {
2193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
2194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
2195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t len = strlen(str);
2196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (space < fChar + len) {
2197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
2198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
2199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return !strncmp(str, space - len, len);
2200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
2201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
2203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fClassName;
2204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef TextParser INHERITED;
2205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
2206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SelfCheck(const BmhParser& );
2208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
2210