• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "bookmaker.h"
9 
parseFiddles()10 bool FiddleBase::parseFiddles() {
11     if (!this->skipExact("{\n")) {
12         return false;
13     }
14     while (!this->eof()) {
15         if (!this->skipExact("  \"")) {
16             return false;
17         }
18         const char* nameLoc = fChar;
19         if (!this->skipToEndBracket("\"")) {
20             return false;
21         }
22         string name(nameLoc, fChar - nameLoc);
23         if (!this->skipExact("\": {\n")) {
24             return false;
25         }
26         if (!this->skipExact("    \"compile_errors\": [")) {
27             return false;
28         }
29         if (']' != this->peek()) {
30             // report compiler errors
31             int brackets = 1;
32             do {
33                 if ('[' == this->peek()) {
34                     ++brackets;
35                 } else if (']' == this->peek()) {
36                     --brackets;
37                 }
38             } while (!this->eof() && this->next() && brackets > 0);
39             this->reportError("fiddle compile error");
40         }
41         if (!this->skipExact("],\n")) {
42             return false;
43         }
44         if (!this->skipExact("    \"runtime_error\": \"")) {
45             return false;
46         }
47         if ('"' != this->peek()) {
48             if (!this->skipToEndBracket('"')) {
49                 return false;
50             }
51             this->reportError("fiddle runtime error");
52         }
53         if (!this->skipExact("\",\n")) {
54             return false;
55         }
56         if (!this->skipExact("    \"fiddleHash\": \"")) {
57             return false;
58         }
59         const char* hashStart = fChar;
60         if (!this->skipToEndBracket('"')) {
61             return false;
62         }
63         Definition* example = this->findExample(name);
64         if (!example) {
65             this->reportError("missing example");
66         }
67         string hash(hashStart, fChar - hashStart);
68         if (example) {
69             example->fHash = hash;
70         }
71         if (!this->skipExact("\",\n")) {
72             return false;
73         }
74         if (!this->skipExact("    \"text\": \"")) {
75             return false;
76         }
77         if ('"' != this->peek()) {
78             const char* stdOutStart = fChar;
79             do {
80                 if ('\\' == this->peek()) {
81                     this->next();
82                 } else if ('"' == this->peek()) {
83                     break;
84                 }
85             } while (!this->eof() && this->next());
86             const char* stdOutEnd = fChar;
87             if (example && fTextOut) {
88                 if (!this->textOut(example, stdOutStart, stdOutEnd)) {
89                     return false;
90                 }
91             }
92         } else {
93             if (example && fPngOut) {
94                 if (!this->pngOut(example)) {
95                     return false;
96                 }
97             }
98         }
99         if (!this->skipExact("\"\n")) {
100             return false;
101         }
102         if (!this->skipExact("  }")) {
103             return false;
104         }
105         if ('\n' == this->peek()) {
106             break;
107         }
108         if (!this->skipExact(",\n")) {
109             return false;
110         }
111     }
112     return true;
113 }
114 
textOut(Definition * example,const char * stdOutStart,const char * stdOutEnd)115 bool FiddleParser::textOut(Definition* example, const char* stdOutStart,
116         const char* stdOutEnd) {
117     bool foundStdOut = false;
118     for (auto& textOut : example->fChildren) {
119         if (MarkType::kStdOut != textOut->fMarkType) {
120             continue;
121         }
122         foundStdOut = true;
123         bool foundVolatile = false;
124         for (auto& stdOutChild : textOut->fChildren) {
125                 if (MarkType::kVolatile == stdOutChild->fMarkType) {
126                     foundVolatile = true;
127                     break;
128                 }
129         }
130         TextParser bmh(textOut);
131         EscapeParser fiddle(stdOutStart, stdOutEnd);
132         do {
133             bmh.skipWhiteSpace();
134             fiddle.skipWhiteSpace();
135             const char* bmhEnd = bmh.trimmedLineEnd();
136             const char* fiddleEnd = fiddle.trimmedLineEnd();
137             ptrdiff_t bmhLen = bmhEnd - bmh.fChar;
138             SkASSERT(bmhLen > 0);
139             ptrdiff_t fiddleLen = fiddleEnd - fiddle.fChar;
140             SkASSERT(fiddleLen > 0);
141             if (bmhLen != fiddleLen) {
142                 if (!foundVolatile) {
143                     bmh.reportError("mismatched stdout len\n");
144                 }
145             } else  if (strncmp(bmh.fChar, fiddle.fChar, fiddleLen)) {
146                 if (!foundVolatile) {
147                     bmh.reportError("mismatched stdout text\n");
148                 }
149             }
150             bmh.skipToLineStart();
151             fiddle.skipToLineStart();
152         } while (!bmh.eof() && !fiddle.eof());
153         if (!foundStdOut) {
154             bmh.reportError("bmh %s missing stdout\n");
155         } else if (!bmh.eof() || !fiddle.eof()) {
156             if (!foundVolatile) {
157                 bmh.reportError("%s mismatched stdout eof\n");
158             }
159         }
160     }
161     return true;
162 }
163