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#include "bookmaker.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid IncludeWriter::descriptionOut(const Definition* def) {
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* commentStart = def->fContentStart;
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int commentLen = (int) (def->fContentEnd - commentStart);
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool breakOut = false;
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(bool wroteCode = false);
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (auto prop : def->fChildren) {
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        switch (prop->fMarkType) {
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case MarkType::kCode: {
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                bool literal = false;
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                bool literalOutdent = false;
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (prop->fStart - commentStart);
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (commentLen > 0) {
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(commentLen < 1000);
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, Phrase::kNo)) {
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->lf(2);
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                size_t childSize = prop->fChildren.size();
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (childSize) {
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(1 == childSize || 2 == childSize);  // incomplete
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(MarkType::kLiteral == prop->fChildren[0]->fMarkType);
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(1 == childSize || MarkType::kOutdent == prop->fChildren[1]->fMarkType);
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    commentStart = prop->fChildren[childSize - 1]->fContentStart;
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    literal = true;
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    literalOutdent = 2 == childSize &&
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            MarkType::kOutdent == prop->fChildren[1]->fMarkType;
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (prop->fContentEnd - commentStart);
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(commentLen > 0);
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (literal) {
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!literalOutdent) {
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fIndent += 4;
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->writeBlockIndent(commentLen, commentStart);
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->lf(2);
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!literalOutdent) {
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fIndent -= 4;
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    commentStart = prop->fTerminator;
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkDEBUGCODE(wroteCode = true);
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } break;
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case MarkType::kDefinedBy:
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentStart = prop->fTerminator;
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case MarkType::kDeprecated:
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case MarkType::kPrivate:
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (prop->fStart - commentStart);
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (commentLen > 0) {
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(commentLen < 1000);
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, Phrase::kNo)) {
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->lfcr();
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentStart = prop->fContentStart;
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (prop->fContentEnd - commentStart);
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (commentLen > 0) {
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->writeBlockIndent(commentLen, commentStart);
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if ('\n' != commentStart[commentLen - 1] && '\n' == commentStart[commentLen]) {
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->lfcr();
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentStart = prop->fTerminator;
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (def->fContentEnd - commentStart);
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case MarkType::kExperimental:
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeString("EXPERIMENTAL:");
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentStart = prop->fContentStart;
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (prop->fContentEnd - commentStart);
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (commentLen > 0) {
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, Phrase::kNo)) {
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->lfcr();
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentStart = prop->fTerminator;
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (def->fContentEnd - commentStart);
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case MarkType::kFormula: {
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = prop->fStart - commentStart;
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (commentLen > 0) {
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, Phrase::kNo)) {
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (commentLen > 1 && '\n' == prop->fStart[-1] &&
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                '\n' == prop->fStart[-2]) {
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            this->lf(1);
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        } else {
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            this->writeSpace();
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                int saveIndent = fIndent;
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (fIndent < fColumn + 1) {
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    fIndent = fColumn + 1;
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeBlockIndent(prop->length(), prop->fContentStart);
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fIndent = saveIndent;
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentStart = prop->fTerminator;
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (def->fContentEnd - commentStart);
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (commentLen > 1 && '\n' == commentStart[0] && '\n' == commentStart[1]) {
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->lf(2);
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT('\n' == prop->fTerminator[0]);
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if ('.' != prop->fTerminator[1] && !fLinefeeds) {
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->writeSpace();
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } break;
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case MarkType::kIn:
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case MarkType::kLine:
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case MarkType::kToDo:
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (prop->fStart - commentStart);
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (commentLen > 0) {
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(commentLen < 1000);
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, Phrase::kNo)) {
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->lfcr();
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentStart = prop->fTerminator;
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (def->fContentEnd - commentStart);
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case MarkType::kList:
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = prop->fStart - commentStart;
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (commentLen > 0) {
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart,
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            Phrase::kNo)) {
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->lfcr();
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                for (auto row : prop->fChildren) {
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(MarkType::kRow == row->fMarkType);
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    for (auto column : row->fChildren) {
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(MarkType::kColumn == column->fMarkType);
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->writeString("-");
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->writeSpace();
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->descriptionOut(column);
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->lf(1);
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentStart = prop->fTerminator;
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (def->fContentEnd - commentStart);
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if ('\n' == commentStart[0] && '\n' == commentStart[1]) {
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->lf(2);
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            default:
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                commentLen = (int) (prop->fStart - commentStart);
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                breakOut = true;
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (breakOut) {
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(wroteCode || (commentLen > 0 && commentLen < 1500));
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (commentLen > 0) {
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid IncludeWriter::enumHeaderOut(const RootDefinition* root,
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const Definition& child) {
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* enumDef = nullptr;
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            child.fContentStart;
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeBlockTrim((int) (bodyEnd - fStart), fStart);  // may write nothing
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->lf(2);
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fIndentNext) {
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndent += 4;
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndentNext = false;
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fDeferComment = nullptr;
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fStart = child.fContentStart;
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const auto& nameDef = child.fTokens.front();
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string fullName;
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (nullptr != nameDef.fContentEnd) {
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TextParser enumClassCheck(&nameDef);
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* start = enumClassCheck.fStart;
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t len = (size_t) (enumClassCheck.fEnd - start);
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool enumClass = enumClassCheck.skipExact("class ");
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (enumClass) {
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            start = enumClassCheck.fChar;
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* end = enumClassCheck.anyOf(" \n;{");
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            len = (size_t) (end - start);
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string enumName(start, len);
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (enumClass) {
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            child.fChildren[0]->fName = enumName;
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fullName = root->fName + "::" + enumName;
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        enumDef = root->find(enumName, RootDefinition::AllowParens::kNo);
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!enumDef) {
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            enumDef = root->find(fullName, RootDefinition::AllowParens::kNo);
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(enumDef);
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // child[0] should be #Code comment starts at child[0].fTerminator
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // though skip until #Code is found (in case there's a #ToDo, etc)
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // child[1] should be #Const comment ends at child[1].fStart
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // comment becomes enum header (if any)
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string enumName(root->fName);
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        enumName += "::_anonymous";
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fAnonymousEnumCount > 1) {
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            enumName += '_' + to_string(fAnonymousEnumCount);
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        enumDef = root->find(enumName, RootDefinition::AllowParens::kNo);
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(enumDef);
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++fAnonymousEnumCount;
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* codeBlock = nullptr;
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* commentStart = nullptr;
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool wroteHeader = false;
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool lastAnchor = false;
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(bool foundConst = false);
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (auto test : enumDef->fChildren) {
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (MarkType::kCode == test->fMarkType) {
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(!codeBlock);  // FIXME: check enum for correct order earlier
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            codeBlock = test;
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentStart = codeBlock->fTerminator;
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!codeBlock) {
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* commentEnd = test->fStart;
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!wroteHeader &&
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                !this->contentFree((int) (commentEnd - commentStart), commentStart)) {
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fIndentNext) {
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fIndent += 4;
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->writeCommentHeader();
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->writeString("\\enum");
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fullName.length() > 0) {
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeString(fullName.c_str());
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fIndent += 4;
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->lfcr();
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            wroteHeader = true;
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (lastAnchor) {
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (commentEnd - commentStart > 1) {
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT('\n' == commentStart[0]);
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (' ' == commentStart[1]) {
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->writeSpace();
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            lastAnchor = false;
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->rewriteBlock((int) (commentEnd - commentStart), commentStart, Phrase::kNo);
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (MarkType::kAnchor == test->fMarkType) {
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            bool newLine = commentEnd - commentStart > 1 &&
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                '\n' == commentEnd[-1] && '\n' == commentEnd[-2];
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentStart = test->fContentStart;
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentEnd = test->fChildren[0]->fStart;
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (newLine) {
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->lf(2);
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->rewriteBlock((int) (commentEnd - commentStart), commentStart, Phrase::kNo);
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            lastAnchor = true;   // this->writeSpace();
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        commentStart = test->fTerminator;
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (MarkType::kConst == test->fMarkType) {
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(codeBlock);  // FIXME: check enum for correct order earlier
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDEBUGCODE(foundConst = true);
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(codeBlock);
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(foundConst);
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (wroteHeader) {
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndent -= 4;
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lfcr();
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeCommentTrailer();
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* braceHolder = child.fChildren[0];
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (KeyWord::kClass == braceHolder->fKeyWord) {
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        braceHolder = braceHolder->fChildren[0];
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bodyEnd = braceHolder->fContentStart;
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT('{' == bodyEnd[0]);
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ++bodyEnd;
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->lfcr();
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeBlock((int) (bodyEnd - fStart), fStart); // write include "enum Name {"
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fIndent += 4;
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->singleLF();
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fStart = bodyEnd;
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fEnumDef = enumDef;
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid IncludeWriter::enumMembersOut(const RootDefinition* root, Definition& child) {
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // iterate through include tokens and find how much remains for 1 line comments
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // put ones that fit on same line, ones that are too big on preceding line?
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* currentEnumItem = nullptr;
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* commentStart = nullptr;
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* lastEnd = nullptr;
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int commentLen = 0;
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class State {
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNoItem,
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kItemName,
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kItemValue,
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kItemComment,
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    State state = State::kNoItem;
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    vector<IterState> iterStack;
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    iterStack.emplace_back(child.fTokens.begin(), child.fTokens.end());
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    IterState* iterState = &iterStack[0];
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool preprocessorWord = false;
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* preprocessStart = nullptr;
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* preprocessEnd = nullptr;
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int onePast = 0; onePast < 2; onePast += iterState->fDefIter == iterState->fDefEnd) {
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Definition* token = onePast ? nullptr : &*iterState->fDefIter++;
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (token && Definition::Type::kBracket == token->fType) {
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Bracket::kSlashSlash == token->fBracket) {
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fStart = token->fContentEnd;
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;  // ignore old inline comments
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Bracket::kSlashStar == token->fBracket) {
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fStart = token->fContentEnd + 1;
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;  // ignore old inline comments
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Bracket::kPound == token->fBracket) {  // preprocessor wraps member
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                preprocessStart = token->fContentStart;
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (KeyWord::kIf == token->fKeyWord || KeyWord::kIfdef == token->fKeyWord) {
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    iterStack.emplace_back(token->fTokens.begin(), token->fTokens.end());
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    iterState = &iterStack.back();
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    preprocessorWord = true;
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else if (KeyWord::kEndif == token->fKeyWord) {
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    iterStack.pop_back();
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    iterState = &iterStack.back();
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    preprocessEnd = token->fContentEnd;
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(0); // incomplete
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(0); // incomplete
347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (token && Definition::Type::kWord != token->fType) {
349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(0); // incomplete
350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (preprocessorWord) {
352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            preprocessorWord = false;
353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            preprocessEnd = token->fContentEnd;
354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (token && State::kItemName == state) {
357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TextParser enumLine(token->fFileName, lastEnd,
358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    token->fContentStart, token->fLineCount);
359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* end = enumLine.anyOf(",}=");
360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(end);
361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            state = '=' == *end ? State::kItemValue : State::kItemComment;
362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (State::kItemValue == state) {  // write enum value
363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->indentToColumn(fEnumItemValueTab);
364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeString("=");
365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                lastEnd = token->fContentEnd;
367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeBlock((int) (lastEnd - token->fContentStart),
368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        token->fContentStart); // write const value if any
369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (token && State::kItemValue == state) {
373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TextParser valueEnd(token->fFileName, lastEnd,
374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    token->fContentStart, token->fLineCount);
375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* end = valueEnd.anyOf(",}");
376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!end) {  // write expression continuation
377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (' ' == lastEnd[0]) {
378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->writeSpace();
379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeBlock((int) (token->fContentEnd - lastEnd), lastEnd);
381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (State::kNoItem != state) {
385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->writeString(",");
386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(currentEnumItem);
387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (currentEnumItem->fShort) {
388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->indentToColumn(fEnumItemCommentTab);
389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeString("//!<");
390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (onePast) {
394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fIndent -= 4;
395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->lfcr();
397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (preprocessStart) {
398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(preprocessEnd);
399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                int saveIndent = fIndent;
400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fIndent = SkTMax(0, fIndent - 8);
401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->lf(2);
402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeBlock((int) (preprocessEnd - preprocessStart), preprocessStart);
403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->lfcr();
404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fIndent = saveIndent;
405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                preprocessStart = nullptr;
406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                preprocessEnd = nullptr;
407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (token && State::kItemValue == state) {
409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fStart = token->fContentStart;
410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            state = State::kNoItem;
412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(State::kNoItem == state);
414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (onePast) {
415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(token);
418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string itemName = root->fName + "::";
419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (KeyWord::kClass == child.fParent->fKeyWord) {
420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            itemName += child.fParent->fName + "::";
421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        itemName += string(token->fContentStart, (int) (token->fContentEnd - token->fContentStart));
423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (auto& enumItem : fEnumDef->fChildren) {
424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (MarkType::kConst != enumItem->fMarkType) {
425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (itemName != enumItem->fName) {
428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            currentEnumItem = enumItem;
431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(currentEnumItem);
434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // if description fits, it goes after item
435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        commentStart = currentEnumItem->fContentStart;
436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* commentEnd;
437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (currentEnumItem->fChildren.size() > 0) {
438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentEnd = currentEnumItem->fChildren[0]->fStart;
439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentEnd = currentEnumItem->fContentEnd;
441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TextParser enumComment(fFileName, commentStart, commentEnd, currentEnumItem->fLineCount);
443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (enumComment.skipToLineStart()) {  // skip const value
444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentStart = enumComment.fChar;
445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentLen = (int) (commentEnd - commentStart);
446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const Definition* privateDef = currentEnumItem->fChildren[0];
448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(MarkType::kPrivate == privateDef->fMarkType);
449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentStart = privateDef->fContentStart;
450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentLen = (int) (privateDef->fContentEnd - privateDef->fContentStart);
451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // FIXME: may assert here if there's no const value
453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // should have detected and errored on that earlier when enum fContentStart was set
454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(commentLen > 0 && commentLen < 1000);
455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!currentEnumItem->fShort) {
456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->writeCommentHeader();
457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fIndent += 4;
458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            bool wroteLineFeed = Wrote::kLF ==
459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fIndent -= 4;
461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (wroteLineFeed || fColumn > 100 - 3 /* space * / */ ) {
462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->lfcr();
463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->writeCommentTrailer();
467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lastEnd = token->fContentEnd;
469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lfcr();
470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (',' == fStart[0]) {
471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++fStart;
472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeBlock((int) (lastEnd - fStart), fStart);  // enum item name
474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fStart = token->fContentEnd;
475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        state = State::kItemName;
476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid IncludeWriter::enumSizeItems(const Definition& child) {
480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class State {
481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNoItem,
482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kItemName,
483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kItemValue,
484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kItemComment,
485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    State state = State::kNoItem;
487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int longestName = 0;
488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int longestValue = 0;
489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int valueLen = 0;
490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* lastEnd = nullptr;
491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//    SkASSERT(child.fChildren.size() == 1 || child.fChildren.size() == 2);
492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto brace = child.fChildren[0];
493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (KeyWord::kClass == brace->fKeyWord) {
494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        brace = brace->fChildren[0];
495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(Bracket::kBrace == brace->fBracket);
497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    vector<IterState> iterStack;
498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    iterStack.emplace_back(brace->fTokens.begin(), brace->fTokens.end());
499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    IterState* iterState = &iterStack[0];
500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool preprocessorWord = false;
501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    while (iterState->fDefIter != iterState->fDefEnd) {
502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        auto& token = *iterState->fDefIter++;
503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Definition::Type::kBracket == token.fType) {
504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Bracket::kSlashSlash == token.fBracket) {
505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;  // ignore old inline comments
506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Bracket::kSlashStar == token.fBracket) {
508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;  // ignore old inline comments
509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Bracket::kPound == token.fBracket) {  // preprocessor wraps member
511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (KeyWord::kIf == token.fKeyWord || KeyWord::kIfdef == token.fKeyWord) {
512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    iterStack.emplace_back(token.fTokens.begin(), token.fTokens.end());
513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    iterState = &iterStack.back();
514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    preprocessorWord = true;
515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else if (KeyWord::kEndif == token.fKeyWord) {
516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    iterStack.pop_back();
517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    iterState = &iterStack.back();
518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(0); // incomplete
520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(0); // incomplete
524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Definition::Type::kWord != token.fType) {
526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(0); // incomplete
527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (preprocessorWord) {
529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            preprocessorWord = false;
530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (State::kItemName == state) {
533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TextParser enumLine(token.fFileName, lastEnd,
534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    token.fContentStart, token.fLineCount);
535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* end = enumLine.anyOf(",}=");
536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(end);
537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            state = '=' == *end ? State::kItemValue : State::kItemComment;
538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (State::kItemValue == state) {
539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                valueLen = (int) (token.fContentEnd - token.fContentStart);
540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                lastEnd = token.fContentEnd;
541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (State::kItemValue == state) {
545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TextParser valueEnd(token.fFileName, lastEnd,
546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    token.fContentStart, token.fLineCount);
547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* end = valueEnd.anyOf(",}");
548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!end) {  // write expression continuation
549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                valueLen += (int) (token.fContentEnd - lastEnd);
550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (State::kNoItem != state) {
554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            longestValue = SkTMax(longestValue, valueLen);
555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            state = State::kNoItem;
556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(State::kNoItem == state);
558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lastEnd = token.fContentEnd;
559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        longestName = SkTMax(longestName, (int) (lastEnd - token.fContentStart));
560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        state = State::kItemName;
561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (State::kItemValue == state) {
563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        longestValue = SkTMax(longestValue, valueLen);
564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fEnumItemValueTab = longestName + fIndent + 1 /* space before = */ ;
566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (longestValue) {
567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        longestValue += 3; /* = space , */
568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fEnumItemCommentTab = fEnumItemValueTab + longestValue + 1 /* space before //!< */ ;
570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // iterate through bmh children and see which comments fit on include lines
571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (auto& enumItem : fEnumDef->fChildren) {
572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (MarkType::kConst != enumItem->fMarkType) {
573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TextParser enumLine(enumItem);
576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        enumLine.trimEnd();
577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        enumLine.skipToLineStart(); // skip const value
578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* commentStart = enumLine.fChar;
579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        enumLine.skipLine();
580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ptrdiff_t lineLen = enumLine.fChar - commentStart + 5 /* //!< space */ ;
581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!enumLine.eof()) {
582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            enumLine.skipWhiteSpace();
583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        enumItem->fShort = enumLine.eof() && fEnumItemCommentTab + lineLen < 100;
585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// walk children and output complete method doxygen description
589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid IncludeWriter::methodOut(const Definition* method, const Definition& child) {
590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fPendingMethod) {
591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndent -= 4;
592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPendingMethod = false;
593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fBmhMethod = method;
595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fMethodDef = &child;
596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fContinuation = nullptr;
597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fDeferComment = nullptr;
598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (0 == fIndent || fIndentNext) {
599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndent += 4;
600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndentNext = false;
601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeCommentHeader();
603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fIndent += 4;
604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->descriptionOut(method);
605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // compute indention column
606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t column = 0;
607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool hasParmReturn = false;
608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (auto methodPart : method->fChildren) {
609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (MarkType::kParam == methodPart->fMarkType) {
610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            column = SkTMax(column, methodPart->fName.length());
611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            hasParmReturn = true;
612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (MarkType::kReturn == methodPart->fMarkType) {
613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            hasParmReturn = true;
614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (hasParmReturn) {
617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lf(2);
618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        column += fIndent + sizeof("@return ");
619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int saveIndent = fIndent;
620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (auto methodPart : method->fChildren) {
621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* partStart = methodPart->fContentStart;
622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* partEnd = methodPart->fContentEnd;
623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (MarkType::kParam == methodPart->fMarkType) {
624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeString("@param");
625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeString(methodPart->fName.c_str());
627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else if (MarkType::kReturn == methodPart->fMarkType) {
628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeString("@return");
629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            while ('\n' == partEnd[-1]) {
633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                --partEnd;
634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            while ('#' == partEnd[-1]) { // FIXME: so wrong; should not be before fContentEnd
636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                --partEnd;
637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->indentToColumn(column);
639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            int partLen = (int) (partEnd - partStart);
640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // FIXME : detect this earlier; assert if #Return is empty
641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(partLen > 0 && partLen < 300);  // may assert if param desc is especially long
642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fIndent = column;
643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->rewriteBlock(partLen, partStart, Phrase::kYes);
644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fIndent = saveIndent;
645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->lfcr();
646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lfcr();
649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fIndent -= 4;
651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->lfcr();
652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeCommentTrailer();
653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fBmhMethod = nullptr;
654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fMethodDef = nullptr;
655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fWroteMethod = true;
656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid IncludeWriter::structOut(const Definition* root, const Definition& child,
659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* commentStart, const char* commentEnd) {
660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeCommentHeader();
661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeString("\\");
662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(MarkType::kClass == child.fMarkType || MarkType::kStruct == child.fMarkType);
663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeString(MarkType::kClass == child.fMarkType ? "class" : "struct");
664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeSpace();
665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeString(child.fName.c_str());
666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fIndent += 4;
667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->lfcr();
668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->rewriteBlock((int) (commentEnd - commentStart), commentStart, Phrase::kNo);
669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fIndent -= 4;
670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->lfcr();
671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeCommentTrailer();
672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDefinition* IncludeWriter::findMemberCommentBlock(const vector<Definition*>& bmhChildren,
675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		const string& name) const {
676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	for (auto memberDef : bmhChildren) {
677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		if (memberDef->fName.length() - name.length() == memberDef->fName.find(name)) {
678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot			return memberDef;
679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		}
680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	}
681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	for (auto memberDef : bmhChildren) {
682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		if (MarkType::kSubtopic == memberDef->fMarkType || MarkType::kTopic == memberDef->fMarkType) {
683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot			Definition* result = this->findMemberCommentBlock(memberDef->fChildren, name);
684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot			if (result) {
685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot				return result;
686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot			}
687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		}
688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	}
689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	return nullptr;
690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDefinition* IncludeWriter::structMemberOut(const Definition* memberStart, const Definition& child) {
693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* blockStart = !fWroteMethod && fDeferComment ? fLastComment->fContentEnd : fStart;
694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* blockEnd = fWroteMethod && fDeferComment ? fDeferComment->fStart - 1 :
695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            memberStart->fStart;
696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeBlockTrim((int) (blockEnd - blockStart), blockStart);
697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fIndentNext) {
698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndent += 4;
699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndentNext = false;
700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fWroteMethod = false;
702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string name(child.fContentStart, (int) (child.fContentEnd - child.fContentStart));
703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* commentBlock = this->findMemberCommentBlock(fBmhStructDef->fChildren, name);
704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	if (!commentBlock) {
705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot		return memberStart->reportError<Definition*>("member missing comment block");
706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	}
707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	const char* commentStart = commentBlock->fContentStart;
708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	ptrdiff_t commentLen = commentBlock->fContentEnd - commentStart;
709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	bool isShort = commentBlock->fShort;
710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot	SkASSERT(!isShort || commentBlock->fChildren.size() == 0);
711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!isShort) {
713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeCommentHeader();
714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool wroteLineFeed = false;
715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndent += 4;
716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (auto child : commentBlock->fChildren) {
717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentLen = child->fStart - commentStart;
718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            wroteLineFeed |= Wrote::kLF == this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (MarkType::kFormula == child->fMarkType) {
720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeBlock((int) (child->fContentEnd - child->fContentStart),
722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        child->fContentStart);
723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            commentStart = child->fTerminator;
725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        commentLen = commentBlock->fContentEnd - commentStart;
727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        wroteLineFeed |= Wrote::kLF == this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndent -= 4;
729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (wroteLineFeed || fColumn > 100 - 3 /* space * / */ ) {
730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->lfcr();
731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->writeSpace();
733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeCommentTrailer();
735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->lfcr();
737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeBlock((int) (child.fStart - memberStart->fContentStart),
738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            memberStart->fContentStart);
739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->indentToColumn(fStructMemberTab);
740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeString(name.c_str());
741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto tokenIter = child.fParent->fTokens.begin();
742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    std::advance(tokenIter, child.fParentIndex + 1);
743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* valueStart = &*tokenIter;
744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    while (Definition::Type::kPunctuation != tokenIter->fType) {
745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        std::advance(tokenIter, 1);
746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(child.fParent->fTokens.end() != tokenIter);
747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* valueEnd = &*tokenIter;
749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (valueStart != valueEnd) {
750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->indentToColumn(fStructValueTab);
751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("=");
752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeSpace();
753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeBlock((int) (valueEnd->fStart - valueStart->fContentStart),
754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                valueStart->fContentStart);
755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
756fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->writeString(";");
757fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (isShort) {
758fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->indentToColumn(fStructCommentTab);
759fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString("//!<");
760fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeSpace();
761fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
762fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
763fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->lf(2);
764fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return valueEnd;
765fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
766fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
767fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid IncludeWriter::structSizeMembers(const Definition& child) {
768fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int longestType = 0;
769fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Definition* typeStart = nullptr;
770fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int longestName = 0;
771fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int longestValue = 0;
772fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(child.fChildren.size() == 1 || child.fChildren.size() == 2);
773fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool inEnum = false;
774fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool inMethod = false;
775fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool inMember = false;
776fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto brace = child.fChildren[0];
777fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(Bracket::kBrace == brace->fBracket);
778fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (auto& token : brace->fTokens) {
779fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Definition::Type::kBracket == token.fType) {
780fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Bracket::kSlashSlash == token.fBracket) {
781fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;  // ignore old inline comments
782fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
783fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Bracket::kSlashStar == token.fBracket) {
784fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;  // ignore old inline comments
785fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
786fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Bracket::kParen == token.fBracket) {
787fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (inMethod) {
788fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    continue;
789fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
790fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
791fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
792fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(0); // incomplete
793fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
794fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Definition::Type::kKeyWord == token.fType) {
795fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            switch (token.fKeyWord) {
796fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kEnum:
797fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    inEnum = true;
798fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    break;
799fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kConst:
800fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kConstExpr:
801fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kStatic:
802fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kInt:
803fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kUint8_t:
804fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kUint16_t:
805fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kUint32_t:
806fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kUint64_t:
807fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kSize_t:
808fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kFloat:
809fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kBool:
810fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kVoid:
811fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!typeStart) {
812fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        typeStart = &token;
813fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
814fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    break;
815fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                default:
816fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    break;
817fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
818fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
819fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
820fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Definition::Type::kPunctuation == token.fType) {
821fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (inEnum) {
822fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(Punctuation::kSemicolon == token.fPunctuation);
823fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                inEnum = false;
824fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
825fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (inMethod) {
826fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (Punctuation::kColon == token.fPunctuation) {
827fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    inMethod = false;
828fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else if (Punctuation::kLeftBrace == token.fPunctuation) {
829fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    inMethod = false;
830fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else if (Punctuation::kSemicolon == token.fPunctuation) {
831fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    inMethod = false;
832fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
833fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(0);  // incomplete
834fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
835fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
836fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (inMember) {
837fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(Punctuation::kSemicolon == token.fPunctuation);
838fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                typeStart = nullptr;
839fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                inMember = false;
840fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
841fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
842fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
843fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Definition::Type::kWord != token.fType) {
844fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(0); // incomplete
845fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
846fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (MarkType::kMember == token.fMarkType) {
847fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TextParser typeStr(token.fFileName, typeStart->fContentStart, token.fContentStart,
848fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    token.fLineCount);
849fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            typeStr.trimEnd();
850fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            longestType = SkTMax(longestType, (int) (typeStr.fEnd - typeStr.fStart));
851fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            longestName = SkTMax(longestName, (int) (token.fContentEnd - token.fContentStart));
852fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            typeStart->fMemberStart = true;
853fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            inMember = true;
854fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
855fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
856fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (MarkType::kMethod == token.fMarkType) {
857fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            inMethod = true;
858fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
859fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
860fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(MarkType::kNone == token.fMarkType);
861fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (typeStart) {
862fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (inMember) {
863fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                longestValue =
864fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkTMax(longestValue, (int) (token.fContentEnd - token.fContentStart));
865fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
866fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
867fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            typeStart = &token;
868fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
869fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
870fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fStructMemberTab = longestType + fIndent + 1 /* space before name */ ;
871fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fStructValueTab = fStructMemberTab + longestName + 2 /* space ; */ ;
872fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fStructCommentTab = fStructValueTab;
873fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (longestValue) {
874fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fStructCommentTab += longestValue + 3 /* space = space */ ;
875fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fStructValueTab -= 1 /* ; */ ;
876fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
877fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // iterate through bmh children and see which comments fit on include lines
878fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (auto& member : fBmhStructDef->fChildren) {
879fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (MarkType::kMember != member->fMarkType) {
880fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
881fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
882fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TextParser memberLine(member);
883fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        memberLine.trimEnd();
884fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* commentStart = memberLine.fChar;
885fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        memberLine.skipLine();
886fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ptrdiff_t lineLen = memberLine.fChar - commentStart + 5 /* //!< space */ ;
887fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!memberLine.eof()) {
888fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            memberLine.skipWhiteSpace();
889fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
890fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        member->fShort = memberLine.eof() && fStructCommentTab + lineLen < 100;
891fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
892fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
893fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
894fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool find_start(const Definition* startDef, const char* start) {
895fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (const auto& child : startDef->fTokens) {
896fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (child.fContentStart == start) {
897fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return MarkType::kMethod == child.fMarkType;
898fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
899fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (child.fContentStart >= start) {
900fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
901fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
902fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (find_start(&child, start)) {
903fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
904fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
905fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
906fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return false;
907fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
908fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
909fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefinition* root) {
910fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ParentPair pair = { def, prevPair };
911fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // write bulk of original include up to class, method, enum, etc., excepting preceding comment
912fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // find associated bmh object
913fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // write any associated comments in Doxygen form
914fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // skip include comment
915fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // if there is a series of same named methods, write one set of comments, then write all methods
916fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string methodName;
917fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* method = nullptr;
918fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* clonedMethod = nullptr;
919fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* memberStart = nullptr;
920fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* memberEnd = nullptr;
921fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fContinuation = nullptr;
922fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool inStruct = false;
923fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool inConstructor = false;
924fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool inInline = false;
925fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool eatOperator = false;
926fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* requireDense = nullptr;
927fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* startDef = nullptr;
928fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (auto& child : def->fTokens) {
929fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (KeyWord::kOperator == child.fKeyWord && method &&
930fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                Definition::MethodType::kOperator == method->fMethodType) {
931fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            eatOperator = true;
932fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
933fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
934fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (eatOperator) {
935fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Bracket::kSquare == child.fBracket || Bracket::kParen == child.fBracket) {
936fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
937fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
938fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            eatOperator = false;
939fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fContinuation = nullptr;
940fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (KeyWord::kConst == child.fKeyWord) {
941fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
942fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
943fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
944fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (memberEnd) {
945fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (memberEnd != &child) {
946fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
947fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
948fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            startDef = &child;
949fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fStart = child.fContentStart + 1;
950fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            memberEnd = nullptr;
951fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
952fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (child.fPrivate) {
953fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (MarkType::kMethod == child.fMarkType) {
954fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                inInline = true;
955fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
956fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
957fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
958fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (inInline) {
959fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Definition::Type::kKeyWord == child.fType) {
960fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(MarkType::kMethod != child.fMarkType);
961fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
962fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
963fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Definition::Type::kPunctuation == child.fType) {
964fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (Punctuation::kLeftBrace == child.fPunctuation) {
965fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    inInline = false;
966fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
967fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(Punctuation::kAsterisk == child.fPunctuation);
968fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
969fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
970fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
971fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Definition::Type::kWord == child.fType) {
972fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                string name(child.fContentStart, child.fContentEnd - child.fContentStart);
973fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(string::npos != name.find("::"));
974fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
975fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
976fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Definition::Type::kBracket == child.fType) {
977fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(Bracket::kParen == child.fBracket);
978fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
979fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
980fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
981fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fContinuation) {
982fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Definition::Type::kKeyWord == child.fType) {
983fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (KeyWord::kFriend == child.fKeyWord ||
984fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        KeyWord::kSK_API == child.fKeyWord) {
985fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    continue;
986fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
987fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                const IncludeKey& includeKey = kKeyWords[(int) child.fKeyWord];
988fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (KeyProperty::kNumber == includeKey.fProperty) {
989fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    continue;
990fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
991fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
992fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Definition::Type::kBracket == child.fType) {
993fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (Bracket::kAngle == child.fBracket) {
994fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    continue;
995fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
996fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (Bracket::kParen == child.fBracket) {
997fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!clonedMethod) {
998fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (inConstructor) {
999fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fContinuation = child.fContentStart;
1000fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1001fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        continue;
1002fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1003fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    int alternate = 1;
1004fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    ptrdiff_t childLen = child.fContentEnd - child.fContentStart;
1005fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(')' == child.fContentStart[childLen]);
1006fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    ++childLen;
1007fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    do {
1008fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        TextParser params(clonedMethod->fFileName, clonedMethod->fStart,
1009fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            clonedMethod->fContentStart, clonedMethod->fLineCount);
1010fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        params.skipToEndBracket('(');
1011fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (params.startsWith(child.fContentStart, childLen)) {
1012fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            this->methodOut(clonedMethod, child);
1013fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            break;
1014fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1015fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        ++alternate;
1016fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        string alternateMethod = methodName + '_' + to_string(alternate);
1017fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        clonedMethod = root->find(alternateMethod,
1018fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                RootDefinition::AllowParens::kNo);
1019fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    } while (clonedMethod);
1020fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!clonedMethod) {
1021fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        return this->reportError<bool>("cloned method not found");
1022fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1023fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    clonedMethod = nullptr;
1024fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    continue;
1025fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1026fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1027fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Definition::Type::kWord == child.fType) {
1028fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (clonedMethod) {
1029fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    continue;
1030fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1031fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                size_t len = (size_t) (child.fContentEnd - child.fContentStart);
1032fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                const char operatorStr[] = "operator";
1033fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                size_t operatorLen = sizeof(operatorStr) - 1;
1034fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (len >= operatorLen && !strncmp(child.fContentStart, operatorStr, operatorLen)) {
1035fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    fContinuation = child.fContentEnd;
1036fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    continue;
1037fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1038fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1039fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Definition::Type::kPunctuation == child.fType &&
1040fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    (Punctuation::kSemicolon == child.fPunctuation ||
1041fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    Punctuation::kLeftBrace == child.fPunctuation ||
1042fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    (Punctuation::kColon == child.fPunctuation && inConstructor))) {
1043fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(fContinuation[0] == '(');
1044fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                const char* continueEnd = child.fContentStart;
1045fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                while (continueEnd > fContinuation && isspace(continueEnd[-1])) {
1046fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    --continueEnd;
1047fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1048fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                methodName += string(fContinuation, continueEnd - fContinuation);
1049fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                method = root->find(methodName, RootDefinition::AllowParens::kNo);
1050fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (!method) {
1051fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    fLineCount = child.fLineCount;
1052fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return this->reportError<bool>("method not found");
1053fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1054fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->methodOut(method, child);
1055fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1056fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1057fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Definition::Type::kPunctuation == child.fType &&
1058fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    Punctuation::kAsterisk == child.fPunctuation &&
1059fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    clonedMethod) {
1060fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1061fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1062fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (inConstructor) {
1063fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1064fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1065fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            method = root->find(methodName + "()", RootDefinition::AllowParens::kNo);
1066fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (method && MarkType::kDefinedBy == method->fMarkType) {
1067fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                method = method->fParent;
1068fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1069fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (method) {
1070fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (method->fCloned) {
1071fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    clonedMethod = method;
1072fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    continue;
1073fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1074fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->methodOut(method, child);
1075fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1076fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1077fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fLineCount = child.fLineCount;
1078fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return this->reportError<bool>("method not found");
1079fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1080fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Bracket::kSlashSlash == child.fBracket || Bracket::kSlashStar == child.fBracket) {
1081fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!fDeferComment) {
1082fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fDeferComment = &child;
1083fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1084fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fLastComment = &child;
1085fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
1086fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1087fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (MarkType::kMethod == child.fMarkType) {
1088fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (this->internalName(child)) {
1089fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1090fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1091fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
1092fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    fAttrDeprecated ? fAttrDeprecated->fContentStart - 1 :
1093fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    child.fContentStart;
1094fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Definition::Type::kBracket == def->fType && Bracket::kDebugCode == def->fBracket) {
1095fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                auto tokenIter = def->fParent->fTokens.begin();
1096fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                std::advance(tokenIter, def->fParentIndex - 1);
1097fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                Definition* prior = &*tokenIter;
1098fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (Definition::Type::kBracket == def->fType &&
1099fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        Bracket::kSlashStar == prior->fBracket) {
1100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    bodyEnd = prior->fContentStart - 1;
1101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // FIXME: roll end-trimming into writeBlockTrim call
1104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            while (fStart < bodyEnd && ' ' >= bodyEnd[-1]) {
1105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                --bodyEnd;
1106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            int blockSize = (int) (bodyEnd - fStart);
1108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (blockSize) {
1109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                string debugstr(fStart, blockSize);
1110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeBlock(blockSize, fStart);
1111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            startDef = &child;
1113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fStart = child.fContentStart;
1114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            methodName = root->fName + "::" + child.fName;
1115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            inConstructor = root->fName == child.fName;
1116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fContinuation = child.fContentEnd;
1117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            method = root->find(methodName, RootDefinition::AllowParens::kNo);
1118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//            if (!method) {
1119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//                method = root->find(methodName + "()", RootDefinition::AllowParens::kNo);
1120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//            }
1121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!method) {
1122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (method->fCloned) {
1125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                clonedMethod = method;
1126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->methodOut(method, child);
1129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fAttrDeprecated) {
1130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                startDef = fAttrDeprecated;
1131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fStart = fAttrDeprecated->fContentStart;
1132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fAttrDeprecated = nullptr;
1133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
1135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Definition::Type::kKeyWord == child.fType) {
1137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fIndentNext) {
1138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // too soon
1139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if 0  // makes struct Lattice indent when it oughtn't
1140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (KeyWord::kEnum == child.fKeyWord) {
1141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    fIndent += 4;
1142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (KeyWord::kPublic != child.fKeyWord) {
1144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    fIndentNext = false;
1145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
1147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const Definition* cIncludeStructDef = nullptr;
1149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            switch (child.fKeyWord) {
1150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kStruct:
1151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kClass:
1152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    // if struct contains members, compute their name and comment tabs
1153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (child.fChildren.size() > 0) {
1154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        const ParentPair* testPair = &pair;
1155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        while ((testPair = testPair->fPrev)) {
1156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            if (KeyWord::kClass == testPair->fParent->fKeyWord) {
1157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                inStruct = fInStruct = true;
1158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                break;
1159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            }
1160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (fInStruct) {
1163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        // try child; root+child; root->parent+child; etc.
1164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        int trial = 0;
1165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        const RootDefinition* search = root;
1166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        const Definition* parent = search->fParent;
1167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        do {
1168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            string name;
1169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            if (0 == trial) {
1170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                name = child.fName;
1171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            } else if (1 == trial) {
1172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                name = root->fName + "::" + child.fName;
1173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            } else {
1174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                SkASSERT(parent);
1175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                name = parent->fName + "::" + child.fName;
1176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                search = parent->asRoot();
1177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                parent = search->fParent;
1178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            }
1179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fBmhStructDef = search->find(name, RootDefinition::AllowParens::kNo);
1180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        } while (!fBmhStructDef && ++trial);
1181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        root = const_cast<RootDefinition*>(fBmhStructDef->asRoot());
1182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(root);
1183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fIndent += 4;
1184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->structSizeMembers(child);
1185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fIndent -= 4;
1186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(!fIndentNext);
1187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fIndentNext = true;
1188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (child.fChildren.size() > 0) {
1190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
1191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                child.fContentStart;
1192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->writeBlockTrim((int) (bodyEnd - fStart), fStart);
1193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (fPendingMethod) {
1194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fIndent -= 4;
1195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fPendingMethod = false;
1196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        startDef = requireDense ? requireDense : &child;
1198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fStart = requireDense ? requireDense->fContentStart : child.fContentStart;
1199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        requireDense = nullptr;
1200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (!fInStruct && child.fName != root->fName) {
1201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            root = &fBmhParser->fClassMap[child.fName];
1202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fRootTopic = root->fParent;
1203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            SkASSERT(!root->fVisited);
1204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            root->clearVisited();
1205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fIndent = 0;
1206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fBmhStructDef = root;
1207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (child.fName == root->fName) {
1209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            if (Definition* parent = root->fParent) {
1210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                if (MarkType::kTopic == parent->fMarkType ||
1211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                        MarkType::kSubtopic == parent->fMarkType) {
1212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    const char* commentStart = root->fContentStart;
1213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    const char* commentEnd = root->fChildren[0]->fStart;
1214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    this->structOut(root, *root, commentStart, commentEnd);
1215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                } else {
1216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    SkASSERT(0); // incomplete
1217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                }
1218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            } else {
1219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                SkASSERT(0); // incomplete
1220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            }
1221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        } else {
1222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            SkASSERT(fInStruct);
1223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                #if 0
1224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fBmhStructDef = root->find(child.fName, RootDefinition::AllowParens::kNo);
1225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            if (nullptr == fBmhStructDef) {
1226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                fBmhStructDef = root->find(root->fName + "::" + child.fName,
1227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                        RootDefinition::AllowParens::kNo);
1228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            }
1229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            if (!fBmhStructDef) {
1230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                this->lf(2);
1231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                fIndent = 0;
1232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                this->writeBlock((int) (fStart - bodyEnd), bodyEnd);
1233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                this->lfcr();
1234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                continue;
1235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            }
1236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                #endif
1237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            Definition* codeBlock = nullptr;
1238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            Definition* nextBlock = nullptr;
1239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            for (auto test : fBmhStructDef->fChildren) {
1240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                if (MarkType::kCode == test->fMarkType) {
1241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    SkASSERT(!codeBlock);  // FIXME: check enum for correct order earlier
1242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    codeBlock = test;
1243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    continue;
1244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                }
1245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                if (codeBlock) {
1246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    nextBlock = test;
1247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    break;
1248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                }
1249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            }
1250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            // FIXME: trigger error earlier if inner #Struct or #Class is missing #Code
1251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            SkASSERT(nextBlock);  // FIXME: check enum for correct order earlier
1252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            const char* commentStart = codeBlock->fTerminator;
1253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            const char* commentEnd = nextBlock->fStart;
1254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            if (fIndentNext) {
1255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//                                fIndent += 4;
1256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            }
1257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fIndentNext = true;
1258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            this->structOut(root, *fBmhStructDef, commentStart, commentEnd);
1259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fDeferComment = nullptr;
1261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    } else {
1262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                       ; // empty forward reference, nothing to do here
1263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    break;
1265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kEnum: {
1266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    fInEnum = true;
1267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->enumHeaderOut(root, child);
1268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->enumSizeItems(child);
1269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } break;
1270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kConst:
1271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kConstExpr:
1272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kStatic:
1273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kInt:
1274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kUint8_t:
1275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kUint16_t:
1276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kUint32_t:
1277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kUint64_t:
1278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kUnsigned:
1279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kSize_t:
1280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kFloat:
1281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kBool:
1282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kVoid:
1283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!memberStart) {
1284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        memberStart = &child;
1285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    break;
1287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kPublic:
1288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kPrivate:
1289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kProtected:
1290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kFriend:
1291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kInline:
1292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kSK_API:
1293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kTypedef:
1294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    break;
1295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                case KeyWord::kSK_BEGIN_REQUIRE_DENSE:
1296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    requireDense = &child;
1297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    break;
1298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                default:
1299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkASSERT(0);
1300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (cIncludeStructDef) {
1302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                TextParser structName(&child);
1303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkAssertResult(structName.skipToEndBracket('{'));
1304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                startDef = &child;
1305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fStart = structName.fChar + 1;
1306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeBlock((int) (fStart - child.fStart), child.fStart);
1307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->lf(2);
1308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fIndent += 4;
1309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (!this->populate(&child, &pair, const_cast<Definition*>(cIncludeStructDef)->asRoot())) {
1310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return false;
1311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                // output any remaining definitions at current indent level
1313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                const char* structEnd = child.fContentEnd;
1314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkAssertResult('}' == structEnd[-1]);
1315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                --structEnd;
1316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeBlockTrim((int) (structEnd - fStart), fStart);
1317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->lf(2);
1318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fStart = structEnd;
1319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fIndent -= 4;
1320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fContinuation = nullptr;
1321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fDeferComment = nullptr;
1322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else if (KeyWord::kUint8_t == child.fKeyWord) {
1323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
1325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (fInEnum && KeyWord::kClass == child.fChildren[0]->fKeyWord) {
1326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!this->populate(child.fChildren[0], &pair, root)) {
1327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        return false;
1328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
1330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!this->populate(&child, &pair, root)) {
1331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        return false;
1332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (KeyWord::kClass == child.fKeyWord || KeyWord::kStruct == child.fKeyWord) {
1334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fStructMemberTab = 0;
1335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (fInStruct) {
1336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fInStruct = false;
1337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            do {
1338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                SkASSERT(root);
1339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                root = const_cast<RootDefinition*>(root->fParent->asRoot());
1340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            } while (MarkType::kTopic == root->fMarkType ||
1341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    MarkType::kSubtopic == root->fMarkType);
1342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            SkASSERT(MarkType::kStruct == root->fMarkType ||
1343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            MarkType::kClass == root->fMarkType);
1344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fPendingMethod = false;
1345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            if (startDef) {
1346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                fPendingMethod = find_start(startDef, fStart);
1347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            }
1348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            fOutdentNext = !fPendingMethod;
1349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
1354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Definition::Type::kBracket == child.fType) {
1356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (KeyWord::kEnum == child.fParent->fKeyWord ||
1357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    (KeyWord::kClass == child.fParent->fKeyWord && child.fParent->fParent &&
1358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    KeyWord::kEnum == child.fParent->fParent->fKeyWord)) {
1359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(Bracket::kBrace == child.fBracket);
1360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->enumMembersOut(root, child);
1361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeString("};");
1362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->lf(2);
1363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                startDef = child.fParent;
1364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fStart = child.fParent->fContentEnd;
1365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(';' == fStart[0]);
1366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                ++fStart;
1367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fDeferComment = nullptr;
1368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fInEnum = false;
1369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (fIndentNext) {
1370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//                    fIndent -= 4;
1371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    fIndentNext = false;
1372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fAttrDeprecated) {
1376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fDeferComment = nullptr;
1379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (KeyWord::kClass == def->fKeyWord || KeyWord::kStruct == def->fKeyWord) {
1380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fIndentNext = true;
1381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!this->populate(&child, &pair, root)) {
1383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return false;
1384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
1386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Definition::Type::kWord == child.fType) {
1388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (MarkType::kMember == child.fMarkType) {
1389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (!memberStart) {
1390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    auto iter = def->fTokens.begin();
1391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    std::advance(iter, child.fParentIndex - 1);
1392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    memberStart = &*iter;
1393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!fStructMemberTab) {
1394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(KeyWord::kStruct == def->fParent->fKeyWord);
1395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fIndent += 4;
1396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        this->structSizeMembers(*def->fParent);
1397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fIndent -= 4;
1398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//                        SkASSERT(!fIndentNext);
1399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        fIndentNext = true;
1400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                memberEnd = this->structMemberOut(memberStart, child);
1403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                startDef = &child;
1404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fStart = child.fContentEnd + 1;
1405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fDeferComment = nullptr;
1406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (child.fMemberStart) {
1408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                memberStart = &child;
1409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char attrDeprecated[] = "SK_ATTR_DEPRECATED";
1411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const size_t attrDeprecatedLen = sizeof(attrDeprecated) - 1;
1412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (attrDeprecatedLen == child.fContentEnd - child.fContentStart &&
1413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    !strncmp(attrDeprecated, child.fStart, attrDeprecatedLen)) {
1414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fAttrDeprecated = &child;
1415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
1417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Definition::Type::kPunctuation == child.fType) {
1419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Punctuation::kSemicolon == child.fPunctuation) {
1420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                memberStart = nullptr;
1421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (inStruct) {
1422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    fInStruct = false;
1423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (Punctuation::kLeftBrace == child.fPunctuation ||
1427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    Punctuation::kColon == child.fPunctuation ||
1428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    Punctuation::kAsterisk == child.fPunctuation
1429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                ) {
1430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return true;
1435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool IncludeWriter::populate(BmhParser& bmhParser) {
1438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool allPassed = true;
1439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (auto& includeMapper : fIncludeMap) {
1440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t lastSlash = includeMapper.first.rfind('/');
1441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (string::npos == lastSlash) {
1442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            lastSlash = includeMapper.first.rfind('\\');
1443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (string::npos == lastSlash || lastSlash >= includeMapper.first.length() - 1) {
1445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return this->reportError<bool>("malformed include name");
1446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string fileName = includeMapper.first.substr(lastSlash + 1);
1448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (".h" != fileName.substr(fileName.length() - 2)) {
1449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return this->reportError<bool>("expected fileName.h");
1450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string skClassName = fileName.substr(0, fileName.length() - 2);
1452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fOut = fopen(fileName.c_str(), "wb");
1453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!fOut) {
1454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("could not open output file %s\n", fileName.c_str());
1455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
1456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (bmhParser.fClassMap.end() == bmhParser.fClassMap.find(skClassName)) {
1458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return this->reportError<bool>("could not find bmh class");
1459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fBmhParser = &bmhParser;
1461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        RootDefinition* root = &bmhParser.fClassMap[skClassName];
1462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fRootTopic = root->fParent;
1463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        root->clearVisited();
1464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fStart = includeMapper.second.fContentStart;
1465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fEnd = includeMapper.second.fContentEnd;
1466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fAnonymousEnumCount = 1;
1467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        allPassed &= this->populate(&includeMapper.second, nullptr, root);
1468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeBlock((int) (fEnd - fStart), fStart);
1469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fIndent = 0;
1470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->lfcr();
1471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writePending();
1472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fclose(fOut);
1473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fflush(fOut);
1474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t slash = fFileName.find_last_of('/');
1475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (string::npos == slash) {
1476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            slash = 0;
1477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t back = fFileName.find_last_of('\\');
1479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (string::npos == back) {
1480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            back = 0;
1481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string dir = fFileName.substr(0, SkTMax(slash, back) + 1);
1483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string readname = dir + fileName;
1484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (this->writtenFileDiffers(fileName, readname)) {
1485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("wrote updated %s\n", fileName.c_str());
1486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
1487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            remove(fileName.c_str());
1488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return allPassed;
1491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// change Xxx_Xxx to xxx xxx
1494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic string ConvertRef(const string str, bool first) {
1495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string substitute;
1496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (char c : str) {
1497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if ('_' == c) {
1498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            c = ' ';  // change Xxx_Xxx to xxx xxx
1499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (isupper(c) && !first) {
1500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            c = tolower(c);
1501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        substitute += c;
1503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        first = false;
1504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return substitute;
1506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstring IncludeWriter::resolveMethod(const char* start, const char* end, bool first) {
1509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string methodname(start, end - start);
1510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (string::npos != methodname.find("()")) {
1511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return "";
1512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string substitute;
1514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto rootDefIter = fBmhParser->fMethodMap.find(methodname);
1515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fBmhParser->fMethodMap.end() != rootDefIter) {
1516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        substitute = methodname + "()";
1517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
1518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        RootDefinition* parent = nullptr;
1519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (auto candidate : fRootTopic->fChildren) {
1520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (MarkType::kClass == candidate->fMarkType
1521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    || MarkType::kStruct == candidate->fMarkType) {
1522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                parent = candidate->asRoot();
1523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(parent);
1527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        auto defRef = parent->find(parent->fName + "::" + methodname,
1528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                RootDefinition::AllowParens::kNo);
1529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (defRef && MarkType::kMethod == defRef->fMarkType) {
1530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            substitute = methodname + "()";
1531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fMethodDef && methodname == fMethodDef->fName) {
1534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TextParser report(fBmhMethod);
1535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        report.reportError("method should not include references to itself");
1536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return "";
1537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fBmhMethod) {
1539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (auto child : fBmhMethod->fChildren) {
1540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (MarkType::kParam != child->fMarkType) {
1541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
1542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (methodname == child->fName) {
1544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return "";
1545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return substitute;
1549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstring IncludeWriter::resolveRef(const char* start, const char* end, bool first,
1552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        RefType* refType) {
1553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // look up Xxx_Xxx
1554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string undername(start, end - start);
1555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (const auto& external : fBmhParser->fExternals) {
1556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (external.fName == undername) {
1557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *refType = RefType::kExternal;
1558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return external.fName;
1559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    *refType = RefType::kNormal;
1562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(string::npos == undername.find(' '));
1563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Definition* rootDef = nullptr;
1564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
1565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        auto rootDefIter = fBmhParser->fTopicMap.find(undername);
1566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fBmhParser->fTopicMap.end() != rootDefIter) {
1567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            rootDef = rootDefIter->second;
1568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
1569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            string prefixedName = fRootTopic->fName + '_' + undername;
1570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            rootDefIter = fBmhParser->fTopicMap.find(prefixedName);
1571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fBmhParser->fTopicMap.end() != rootDefIter) {
1572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                rootDef = rootDefIter->second;
1573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else if (fBmhStructDef) {
1574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                string localPrefix = fBmhStructDef->fFiddle + '_' + undername;
1575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                rootDefIter = fBmhParser->fTopicMap.find(localPrefix);
1576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (fBmhParser->fTopicMap.end() != rootDefIter) {
1577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    rootDef = rootDefIter->second;
1578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
1580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                auto aliasIter = fBmhParser->fAliasMap.find(undername);
1581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (fBmhParser->fAliasMap.end() != aliasIter) {
1582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    rootDef = aliasIter->second->fParent;
1583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else if (!first) {
1584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkDebugf("unfound: %s\n", undername.c_str());
1585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->reportError("reference unfound");
1586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return "";
1587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string substitute;
1592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (rootDef) {
1593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (auto child : rootDef->fChildren) {
1594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (MarkType::kSubstitute == child->fMarkType) {
1595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                substitute = string(child->fContentStart,
1596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        (int) (child->fContentEnd - child->fContentStart));
1597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!substitute.length()) {
1601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (auto child : rootDef->fChildren) {
1602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (MarkType::kClass == child->fMarkType ||
1603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        MarkType::kStruct == child->fMarkType ||
1604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        (MarkType::kEnum == child->fMarkType && !child->fAnonymous) ||
1605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        MarkType::kEnumClass == child->fMarkType) {
1606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    substitute = child->fName;
1607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (MarkType::kEnum == child->fMarkType && fInEnum) {
1608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        size_t parentClassEnd = substitute.find("::");
1609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(string::npos != parentClassEnd);
1610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        substitute = substitute.substr(parentClassEnd + 2);
1611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    break;
1613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!substitute.length()) {
1617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            auto parent = rootDef->fParent;
1618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (parent) {
1619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (MarkType::kClass == parent->fMarkType ||
1620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        MarkType::kStruct == parent->fMarkType ||
1621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        (MarkType::kEnum == parent->fMarkType && !parent->fAnonymous) ||
1622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        MarkType::kEnumClass == parent->fMarkType) {
1623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (parent->fParent != fRootTopic) {
1624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        substitute = parent->fName;
1625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        size_t under = undername.find('_');
1626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(string::npos != under);
1627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        string secondHalf(&undername[under], (size_t) (undername.length() - under));
1628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        substitute += ConvertRef(secondHalf, false);
1629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    } else {
1630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        substitute += ConvertRef(undername, first);
1631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
1632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Ensure first word after period is capitalized if substitute is lower cased.
1637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (first && isupper(start[0]) && substitute.length() > 0 && islower(substitute[0])) {
1638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        substitute[0] = start[0];
1639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return substitute;
1641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotint IncludeWriter::lookupMethod(const PunctuationState punctuation, const Word word,
1644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const int lastSpace, const int run, int lastWrite, const char* data,
1645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool hasIndirection) {
1646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int wordStart = lastSpace;
1647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    while (' ' >= data[wordStart]) {
1648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++wordStart;
1649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const int wordEnd = PunctuationState::kDelimiter == punctuation ||
1651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            PunctuationState::kPeriod == punctuation ? run - 1 : run;
1652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string temp;
1653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (hasIndirection && '(' != data[wordEnd - 1] && ')' != data[wordEnd - 1]) {
1654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // FIXME: hard-coded to assume a.b or a->b is a.b() or a->b().
1655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // need to check class a for member b to see if this is so
1656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TextParser parser(fFileName, &data[wordStart], &data[wordEnd], fLineCount);
1657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* indirection = parser.anyOf(".>");
1658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (&data[wordEnd] <= &indirection[2] || 'f' != indirection[1] ||
1659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                !isupper(indirection[2])) {
1660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            temp = string(&data[wordStart], wordEnd - wordStart) + "()";
1661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
1663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        temp = this->resolveMethod(&data[wordStart], &data[wordEnd], Word::kFirst == word);
1664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (temp.length()) {
1666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (wordStart > lastWrite) {
1667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(data[wordStart - 1] >= ' ');
1668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (' ' == data[lastWrite]) {
1669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
1670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->writeBlockTrim(wordStart - lastWrite, &data[lastWrite]);
1672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (' ' == data[wordStart - 1]) {
1673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
1674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(temp[temp.length() - 1] > ' ');
1677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(temp.c_str());
1678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lastWrite = wordEnd;
1679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return lastWrite;
1681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotint IncludeWriter::lookupReference(const PunctuationState punctuation, const Word word,
1684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const int start, const int run, int lastWrite, const char last, const char* data) {
1685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const int end = PunctuationState::kDelimiter == punctuation ||
1686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            PunctuationState::kPeriod == punctuation ? run - 1 : run;
1687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RefType refType = RefType::kUndefined;
1688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string resolved = string(&data[start], (size_t) (end - start));
1689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    string temp = this->resolveRef(&data[start], &data[end], Word::kFirst == word, &refType);
1690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!temp.length()) {
1691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Word::kFirst != word && '_' != last) {
1692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            temp = ConvertRef(resolved, false);
1693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (temp.length()) {
1696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (start > lastWrite) {
1697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(data[start - 1] >= ' ');
1698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (' ' == data[lastWrite]) {
1699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
1700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->writeBlockTrim(start - lastWrite, &data[lastWrite]);
1702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (' ' == data[start - 1]) {
1703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeSpace();
1704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(temp[temp.length() - 1] > ' ');
1707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeString(temp.c_str());
1708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lastWrite = end;
1709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return lastWrite;
1711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* returns true if rewriteBlock wrote linefeeds */
1714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotIncludeWriter::Wrote IncludeWriter::rewriteBlock(int size, const char* data, Phrase phrase) {
1715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool wroteLineFeeds = false;
1716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    while (size > 0 && data[0] <= ' ') {
1717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        --size;
1718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++data;
1719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    while (size > 0 && data[size - 1] <= ' ') {
1721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        --size;
1722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (0 == size) {
1724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return Wrote::kNone;
1725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int run = 0;
1727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Word word = Word::kStart;
1728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    PunctuationState punctuation = Phrase::kNo == phrase ?
1729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            PunctuationState::kStart : PunctuationState::kSpace;
1730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int start = 0;
1731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int lastWrite = 0;
1732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int lineFeeds = 0;
1733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int lastPrintable = 0;
1734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int lastSpace = -1;
1735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    char c = 0;
1736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    char last = 0;
1737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool embeddedIndirection = false;
1738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool embeddedSymbol = false;
1739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool hasLower = false;
1740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool hasUpper = false;
1741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool hasIndirection = false;
1742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool hasSymbol = false;
1743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    while (run < size) {
1744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        last = c;
1745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        c = data[run];
1746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(' ' <= c || '\n' == c);
1747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (lineFeeds && ' ' < c) {
1748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (lastPrintable >= lastWrite) {
1749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (' ' == data[lastWrite]) {
1750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    this->writeSpace();
1751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    lastWrite++;
1752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->writeBlock(lastPrintable - lastWrite + 1, &data[lastWrite]);
1754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (lineFeeds > 1) {
1756fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                this->lf(2);
1757fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1758fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->lfcr(); // defer the indent until non-whitespace is seen
1759fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            lastWrite = run;
1760fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            lineFeeds = 0;
1761fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1762fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (' ' < c) {
1763fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            lastPrintable = run;
1764fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1765fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        switch (c) {
1766fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '\n':
1767fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                ++lineFeeds;
1768fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                wroteLineFeeds = true;
1769fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case ' ':
1770fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                switch (word) {
1771fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kStart:
1772fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1773fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kUnderline:
1774fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kCap:
1775fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kFirst:
1776fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (!hasLower) {
1777fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            break;
1778fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1779fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        lastWrite = this->lookupReference(punctuation, word, start, run,
1780fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                lastWrite, last, data);
1781fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1782fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kMixed:
1783fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (hasUpper && hasLower && !hasSymbol && lastSpace > 0) {
1784fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            lastWrite = this->lookupMethod(punctuation, word, lastSpace, run,
1785fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    lastWrite, data, hasIndirection && !hasSymbol);
1786fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1787fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1788fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    default:
1789fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(0);
1790fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1791fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                punctuation = PunctuationState::kPeriod == punctuation ||
1792fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        (PunctuationState::kStart == punctuation && ' ' >= last) ?
1793fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        PunctuationState::kStart : PunctuationState::kSpace;
1794fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                word = Word::kStart;
1795fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                embeddedIndirection = false;
1796fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                embeddedSymbol = false;
1797fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasLower = false;
1798fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasUpper = false;
1799fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasIndirection = false;
1800fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasSymbol = false;
1801fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                lastSpace = run;
1802fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1803fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '.':
1804fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                switch (word) {
1805fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kStart:
1806fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        punctuation = PunctuationState::kDelimiter;
1807fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kCap:
1808fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kFirst:
1809fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kUnderline:
1810fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kMixed:
1811fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (PunctuationState::kDelimiter == punctuation ||
1812fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                PunctuationState::kPeriod == punctuation) {
1813fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            word = Word::kMixed;
1814fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1815fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        punctuation = PunctuationState::kPeriod;
1816fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1817fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    default:
1818fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(0);
1819fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1820fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                embeddedIndirection = true;
1821fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1822fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case ',': case ';': case ':':
1823fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                switch (word) {
1824fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kStart:
1825fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        punctuation = PunctuationState::kDelimiter;
1826fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kCap:
1827fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kFirst:
1828fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kUnderline:
1829fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kMixed:
1830fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (PunctuationState::kDelimiter == punctuation ||
1831fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                PunctuationState::kPeriod == punctuation) {
1832fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            word = Word::kMixed;
1833fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1834fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        punctuation = PunctuationState::kDelimiter;
1835fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1836fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    default:
1837fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(0);
1838fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1839fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                embeddedSymbol = true;
1840fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1841fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '>':
1842fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if ('-' == last) {
1843fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    embeddedIndirection = true;
1844fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    break;
1845fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1846fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '\'': // possessive apostrophe isn't treated as delimiting punctation
1847fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '\"': // quote is passed straight through
1848fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '=':
1849fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '!':  // assumed not to be punctuation, but a programming symbol
1850fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '&': case '<': case '{': case '}': case '/': case '*': case '[': case ']':
1851fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                word = Word::kMixed;
1852fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                embeddedSymbol = true;
1853fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1854fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '(':
1855fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (' ' == last) {
1856fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    punctuation = PunctuationState::kDelimiter;
1857fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
1858fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    word = Word::kMixed;
1859fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1860fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                embeddedSymbol = true;
1861fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1862fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case ')':   // assume word type has already been set
1863fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                punctuation = PunctuationState::kDelimiter;
1864fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                embeddedSymbol = true;
1865fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1866fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '_':
1867fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                switch (word) {
1868fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kStart:
1869fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        word = Word::kMixed;
1870fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1871fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kCap:
1872fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kFirst:
1873fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kUnderline:
1874fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        word = Word::kUnderline;
1875fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1876fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kMixed:
1877fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1878fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    default:
1879fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(0);
1880fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1881fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasSymbol |= embeddedSymbol;
1882fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1883fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '+':
1884fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                // hackery to allow C++
1885fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT('C' == last || '+' == last);  // FIXME: don't allow + outside of #Formula
1886fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1887fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'A': case 'B': case 'C': case 'D': case 'E':
1888fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'F': case 'G': case 'H': case 'I': case 'J':
1889fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'K': case 'L': case 'M': case 'N': case 'O':
1890fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'P': case 'Q': case 'R': case 'S': case 'T':
1891fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'U': case 'V': case 'W': case 'X': case 'Y':
1892fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'Z':
1893fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                switch (word) {
1894fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kStart:
1895fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        word = PunctuationState::kStart == punctuation ? Word::kFirst : Word::kCap;
1896fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        start = run;
1897fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1898fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kCap:
1899fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kFirst:
1900fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if (!isupper(last) && '~' != last) {
1901fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            word = Word::kMixed;
1902fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1903fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1904fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kUnderline:
1905fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        // some word in Xxx_XXX_Xxx can be all upper, but all can't: XXX_XXX
1906fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        if ('_' != last && !isupper(last)) {
1907fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            word = Word::kMixed;
1908fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        }
1909fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1910fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kMixed:
1911fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1912fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    default:
1913fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(0);
1914fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1915fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasUpper = true;
1916fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (PunctuationState::kPeriod == punctuation ||
1917fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        PunctuationState::kDelimiter == punctuation) {
1918fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    word = Word::kMixed;
1919fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1920fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasIndirection |= embeddedIndirection;
1921fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasSymbol |= embeddedSymbol;
1922fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1923fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'a': case 'b': case 'c': case 'd': case 'e':
1924fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'f': case 'g': case 'h': case 'i': case 'j':
1925fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'k': case 'l': case 'm': case 'n': case 'o':
1926fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'p': case 'q': case 'r': case 's': case 't':
1927fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'u': case 'v': case 'w': case 'x': case 'y':
1928fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case 'z':
1929fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '0': case '1': case '2': case '3': case '4':
1930fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '5': case '6': case '7': case '8': case '9':
1931fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '-':
1932fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                switch (word) {
1933fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kStart:
1934fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        word = Word::kMixed;
1935fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1936fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kMixed:
1937fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kCap:
1938fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kFirst:
1939fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    case Word::kUnderline:
1940fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        break;
1941fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    default:
1942fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        SkASSERT(0);
1943fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1944fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasLower = true;
1945fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                punctuation = PunctuationState::kStart;
1946fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasIndirection |= embeddedIndirection;
1947fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasSymbol |= embeddedSymbol;
1948fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1949fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case '~':
1950fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(Word::kStart == word);
1951fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                word = PunctuationState::kStart == punctuation ? Word::kFirst : Word::kCap;
1952fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                start = run;
1953fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasUpper = true;
1954fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasIndirection |= embeddedIndirection;
1955fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasSymbol |= embeddedSymbol;
1956fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1957fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            default:
1958fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkASSERT(0);
1959fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1960fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++run;
1961fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1962fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if ((word == Word::kCap || word == Word::kFirst || word == Word::kUnderline) && hasLower) {
1963fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lastWrite = this->lookupReference(punctuation, word, start, run, lastWrite, last, data);
1964fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else if (word == Word::kMixed && hasUpper && hasLower && !hasSymbol && lastSpace > 0) {
1965fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lastWrite = this->lookupMethod(punctuation, word, lastSpace, run, lastWrite, data,
1966fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                hasIndirection && !hasSymbol);
1967fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1968fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (run > lastWrite) {
1969fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (' ' == data[lastWrite]) {
1970fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->writeSpace();
1971fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1972fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->writeBlock(run - lastWrite, &data[lastWrite]);
1973fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1974fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return wroteLineFeeds ? Wrote::kLF : Wrote::kChars;
1975fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1976