• 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 "bmhParser.h"
9 #include "fiddleParser.h"
10 
11 #include "SkOSFile.h"
12 #include "SkOSPath.h"
13 
14 const string kCatalogFileName("catalog.htm");
15 
appendFile(string path)16 bool Catalog::appendFile(string path) {
17     FILE* file = fopen(path.c_str(), "r");
18     if (!file) {
19         SkDebugf("could not append %s\n", path.c_str());
20         return false;
21     }
22     fseek(file, 0L, SEEK_END);
23     int sz = (int) ftell(file);
24     rewind(file);
25     char* buffer = new char[sz];
26     memset(buffer, ' ', sz);
27     SkAssertResult(sz == (int)fread(buffer, 1, sz, file));
28     fclose(file);
29     this->writeBlock(sz, buffer);
30     return true;
31 }
32 
openCatalog(const char * inDir)33 bool Catalog::openCatalog(const char* inDir) {
34     fDocsDir = inDir;
35     if ('/' != fDocsDir.back()) {
36         fDocsDir += '/';
37     }
38     fOut = fopen(kCatalogFileName.c_str(), "wb");
39     fFullName = kCatalogFileName;
40     if (!fOut) {
41         SkDebugf("could not open output file %s\n", kCatalogFileName.c_str());
42         return false;
43     }
44     fContinuation = false;
45     if (!appendFile(fDocsDir + "catalogHeader.txt")) {
46         return false;
47     }
48     this->lf(1);
49 
50     return true;
51 }
52 
openStatus(const char * statusFile)53 bool Catalog::openStatus(const char* statusFile) {
54     StatusIter iter(statusFile, ".bmh", StatusFilter::kInProgress);
55     // FIXME: iterate through only chosen files by setting fDocsDir to iter
56     // read one file to find directory
57     if (!iter.next(nullptr, nullptr)) {
58         return false;
59     }
60     return openCatalog(iter.baseDir().c_str());
61 }
62 
closeCatalog(const char * outDir)63 bool Catalog::closeCatalog(const char* outDir) {
64     if (fOut) {
65         this->lf(1);
66         this->writeString("}");
67         this->lf(1);
68         if (!appendFile(fDocsDir + "catalogTrailer.txt")) {
69             return false;
70         }
71         this->lf(1);
72         this->writePending();
73         fclose(fOut);
74         string outie = outDir;
75         if ('/' != outie.back()) {
76             outie += '/';
77         }
78         string fullName = outie + kCatalogFileName;
79         if (ParserCommon::WrittenFileDiffers(fullName, kCatalogFileName)) {
80             ParserCommon::CopyToFile(fullName, kCatalogFileName);
81             SkDebugf("wrote %s\n", fullName.c_str());
82         } else {
83             remove(kCatalogFileName.c_str());
84         }
85         fOut = nullptr;
86     }
87     return true;
88 }
89 
parseFromFile(const char * path)90 bool Catalog::parseFromFile(const char* path) {
91     if (!INHERITED::parseFromFile(path)) {
92         return false;
93     }
94     fIndent = 4;
95     this->writeString("var text = {");
96     this->lf(1);
97     fTextOut = true;
98     if (!parseFiddles()) {
99         return false;
100     }
101     this->lf(1);
102     this->writeString("}");
103     this->lf(2);
104     this->writeString("var pngs = {");
105     fTextOut = false;
106     fPngOut = true;
107     JsonStatus* status = &fStack.back();
108     status->fIter = status->fObject.begin();
109     fContinuation = false;
110     return parseFiddles();
111 }
112 
pngOut(Definition * example)113 bool Catalog::pngOut(Definition* example) {
114     string result;
115     if (!fBmhParser->exampleToScript(example, BmhParser::ExampleOptions::kPng, &result)) {
116         return false;
117     }
118     if (result.length() > 0) {
119         if (fContinuation) {
120             this->writeString(",");
121             this->lf(1);
122         } else {
123             fContinuation = true;
124         }
125         this->writeBlock(result.size(), result.c_str());
126     }
127     return true;
128 }
129 
textOut(Definition * def,const char * stdOutStart,const char * stdOutEnd)130 bool Catalog::textOut(Definition* def, const char* stdOutStart,
131     const char* stdOutEnd) {
132     string result;
133     if (!fBmhParser->exampleToScript(def, BmhParser::ExampleOptions::kText, &result)) {
134         return false;
135     }
136     if (result.length() > 0) {
137         if (fContinuation) {
138             this->writeString(",");
139             this->lf(1);
140         } else {
141             fContinuation = true;
142         }
143         fIndent = 8;
144         this->writeBlock(result.size(), result.c_str());
145         this->lf(1);
146         this->writeString("\"stdout\": \"");
147         size_t pos = 0;
148         size_t len = stdOutEnd - stdOutStart;
149         string example;
150         const Definition* stdOut = def->hasChild(MarkType::kStdOut);
151         const Definition* outVolatile = stdOut ? stdOut->hasChild(MarkType::kVolatile) : nullptr;
152         if (outVolatile) {
153             stdOutStart = outVolatile->fContentStart;
154             while ('\n' == stdOutStart[0]) {
155                 ++stdOutStart;
156             }
157             len = stdOut->fContentEnd - stdOutStart;
158         }
159         while ((size_t) pos < len) {
160             example += '"' == stdOutStart[pos] ? "\\\"" :
161                 '\\' == stdOutStart[pos] ? "\\\\" :
162                 '\n' == stdOutStart[pos] ? "\\\\n" :
163                 string(&stdOutStart[pos], 1);
164             if (outVolatile && '\n' == stdOutStart[pos]) {
165                 ++pos;
166                 while ((size_t) pos < len && ' ' == stdOutStart[pos]) {
167                     ++pos;
168                 }
169                 continue;
170             }
171             ++pos;
172         }
173         if (outVolatile) {
174             example += "\\\\n";
175         }
176         this->writeBlock(example.length(), example.c_str());
177         this->writeString("\"");
178         this->lf(1);
179         fIndent = 4;
180         this->writeString("}");
181     }
182     return true;
183 }
184