blob: fe0084d5bf96d7b5831de17c3e43543289631133 [file] [log] [blame]
Cary Clarkbef063a2017-10-31 15:44:45 -04001/*
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
10#include "SkOSFile.h"
11#include "SkOSPath.h"
12
Cary Clark5b1f9532018-08-28 14:53:37 -040013const string kCatalogFileName("catalog.htm");
14
Cary Clark2d4bf5f2018-04-16 08:37:38 -040015bool Catalog::appendFile(string path) {
Cary Clarkbef063a2017-10-31 15:44:45 -040016 FILE* file = fopen(path.c_str(), "r");
17 if (!file) {
18 SkDebugf("could not append %s\n", path.c_str());
19 return false;
20 }
21 fseek(file, 0L, SEEK_END);
22 int sz = (int) ftell(file);
23 rewind(file);
24 char* buffer = new char[sz];
25 memset(buffer, ' ', sz);
Brian Osman028b32c2017-11-01 10:52:55 -040026 SkAssertResult(sz == (int)fread(buffer, 1, sz, file));
Cary Clarkbef063a2017-10-31 15:44:45 -040027 fclose(file);
28 this->writeBlock(sz, buffer);
29 return true;
30}
31
Cary Clark5b1f9532018-08-28 14:53:37 -040032bool Catalog::openCatalog(const char* inDir) {
Cary Clarkbef063a2017-10-31 15:44:45 -040033 fDocsDir = inDir;
34 if ('/' != fDocsDir.back()) {
35 fDocsDir += '/';
36 }
Cary Clark5b1f9532018-08-28 14:53:37 -040037 fOut = fopen(kCatalogFileName.c_str(), "wb");
38 fFullName = kCatalogFileName;
Cary Clarkbef063a2017-10-31 15:44:45 -040039 if (!fOut) {
Cary Clark5b1f9532018-08-28 14:53:37 -040040 SkDebugf("could not open output file %s\n", kCatalogFileName.c_str());
Cary Clarkbef063a2017-10-31 15:44:45 -040041 return false;
42 }
43 fContinuation = false;
44 if (!appendFile(fDocsDir + "catalogHeader.txt")) {
45 return false;
46 }
47 this->lf(1);
Cary Clark5b1f9532018-08-28 14:53:37 -040048
Cary Clarkbef063a2017-10-31 15:44:45 -040049 return true;
50}
51
Cary Clark5b1f9532018-08-28 14:53:37 -040052bool Catalog::openStatus(const char* statusFile) {
Cary Clark2f466242017-12-11 16:03:17 -050053 StatusIter iter(statusFile, ".bmh", StatusFilter::kInProgress);
Cary Clark2f466242017-12-11 16:03:17 -050054 // FIXME: iterate through only chosen files by setting fDocsDir to iter
55 // read one file to find directory
Cary Clark61313f32018-10-08 14:57:48 -040056 if (!iter.next(nullptr, nullptr)) {
Cary Clark2f466242017-12-11 16:03:17 -050057 return false;
58 }
Cary Clark5b1f9532018-08-28 14:53:37 -040059 return openCatalog(iter.baseDir().c_str());
Cary Clark2f466242017-12-11 16:03:17 -050060}
61
Cary Clark5b1f9532018-08-28 14:53:37 -040062bool Catalog::closeCatalog(const char* outDir) {
Cary Clarkbef063a2017-10-31 15:44:45 -040063 if (fOut) {
64 this->lf(1);
65 this->writeString("}");
66 this->lf(1);
67 if (!appendFile(fDocsDir + "catalogTrailer.txt")) {
68 return false;
69 }
70 this->lf(1);
71 this->writePending();
72 fclose(fOut);
Cary Clark5b1f9532018-08-28 14:53:37 -040073 string outie = outDir;
74 if ('/' != outie.back()) {
75 outie += '/';
76 }
77 string fullName = outie + kCatalogFileName;
78 if (ParserCommon::WrittenFileDiffers(fullName, kCatalogFileName)) {
79 ParserCommon::CopyToFile(fullName, kCatalogFileName);
80 SkDebugf("wrote %s\n", fullName.c_str());
Cary Clark6a1185a2018-09-04 16:15:11 -040081 } else {
82 remove(kCatalogFileName.c_str());
Cary Clark5b1f9532018-08-28 14:53:37 -040083 }
Cary Clarkbef063a2017-10-31 15:44:45 -040084 fOut = nullptr;
85 }
86 return true;
87}
88
89bool Catalog::parseFromFile(const char* path) {
Cary Clarkd7895502018-07-18 15:10:08 -040090 if (!INHERITED::parseFromFile(path)) {
Cary Clarkbef063a2017-10-31 15:44:45 -040091 return false;
92 }
93 fIndent = 4;
94 this->writeString("var text = {");
95 this->lf(1);
96 fTextOut = true;
Cary Clarkbef063a2017-10-31 15:44:45 -040097 if (!parseFiddles()) {
98 return false;
99 }
100 this->lf(1);
101 this->writeString("}");
102 this->lf(2);
103 this->writeString("var pngs = {");
104 fTextOut = false;
105 fPngOut = true;
Cary Clarkd7895502018-07-18 15:10:08 -0400106 JsonStatus* status = &fStack.back();
107 status->fIter = status->fObject.begin();
Cary Clarkbef063a2017-10-31 15:44:45 -0400108 fContinuation = false;
109 return parseFiddles();
110}
111
112bool Catalog::pngOut(Definition* example) {
113 string result;
Cary Clark1a8d7622018-03-05 13:26:16 -0500114 if (!fBmhParser->exampleToScript(example, BmhParser::ExampleOptions::kPng, &result)) {
Cary Clarkbef063a2017-10-31 15:44:45 -0400115 return false;
116 }
117 if (result.length() > 0) {
118 if (fContinuation) {
119 this->writeString(",");
120 this->lf(1);
121 } else {
122 fContinuation = true;
123 }
124 this->writeBlock(result.size(), result.c_str());
125 }
126 return true;
127}
128
Cary Clarkc896edd2017-12-12 11:38:09 -0500129bool Catalog::textOut(Definition* def, const char* stdOutStart,
Cary Clarkbef063a2017-10-31 15:44:45 -0400130 const char* stdOutEnd) {
131 string result;
Cary Clark1a8d7622018-03-05 13:26:16 -0500132 if (!fBmhParser->exampleToScript(def, BmhParser::ExampleOptions::kText, &result)) {
Cary Clarkbef063a2017-10-31 15:44:45 -0400133 return false;
134 }
135 if (result.length() > 0) {
136 if (fContinuation) {
137 this->writeString(",");
138 this->lf(1);
139 } else {
140 fContinuation = true;
141 }
142 fIndent = 8;
143 this->writeBlock(result.size(), result.c_str());
144 this->lf(1);
145 this->writeString("\"stdout\": \"");
146 size_t pos = 0;
147 size_t len = stdOutEnd - stdOutStart;
148 string example;
Cary Clarkc896edd2017-12-12 11:38:09 -0500149 const Definition* stdOut = def->hasChild(MarkType::kStdOut);
150 const Definition* outVolatile = stdOut ? stdOut->hasChild(MarkType::kVolatile) : nullptr;
151 if (outVolatile) {
152 stdOutStart = outVolatile->fContentStart;
153 while ('\n' == stdOutStart[0]) {
154 ++stdOutStart;
155 }
156 len = stdOut->fContentEnd - stdOutStart;
157 }
Cary Clarkbef063a2017-10-31 15:44:45 -0400158 while ((size_t) pos < len) {
159 example += '"' == stdOutStart[pos] ? "\\\"" :
160 '\\' == stdOutStart[pos] ? "\\\\" :
Cary Clarkc896edd2017-12-12 11:38:09 -0500161 '\n' == stdOutStart[pos] ? "\\\\n" :
Cary Clarkbef063a2017-10-31 15:44:45 -0400162 string(&stdOutStart[pos], 1);
Cary Clarkc896edd2017-12-12 11:38:09 -0500163 if (outVolatile && '\n' == stdOutStart[pos]) {
164 ++pos;
165 while ((size_t) pos < len && ' ' == stdOutStart[pos]) {
166 ++pos;
167 }
168 continue;
169 }
Cary Clarkbef063a2017-10-31 15:44:45 -0400170 ++pos;
171 }
Cary Clarkc896edd2017-12-12 11:38:09 -0500172 if (outVolatile) {
173 example += "\\\\n";
174 }
Cary Clarkbef063a2017-10-31 15:44:45 -0400175 this->writeBlock(example.length(), example.c_str());
176 this->writeString("\"");
177 this->lf(1);
178 fIndent = 4;
179 this->writeString("}");
180 }
181 return true;
182}