blob: c6aae74c3061cd29b62f0f851623365abb907c4b [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 Clark2d4bf5f2018-04-16 08:37:38 -040013bool Catalog::appendFile(string path) {
Cary Clarkbef063a2017-10-31 15:44:45 -040014 FILE* file = fopen(path.c_str(), "r");
15 if (!file) {
16 SkDebugf("could not append %s\n", path.c_str());
17 return false;
18 }
19 fseek(file, 0L, SEEK_END);
20 int sz = (int) ftell(file);
21 rewind(file);
22 char* buffer = new char[sz];
23 memset(buffer, ' ', sz);
Brian Osman028b32c2017-11-01 10:52:55 -040024 SkAssertResult(sz == (int)fread(buffer, 1, sz, file));
Cary Clarkbef063a2017-10-31 15:44:45 -040025 fclose(file);
26 this->writeBlock(sz, buffer);
27 return true;
28}
29
30bool Catalog::openCatalog(const char* inDir, const char* outDir) {
31 fDocsDir = inDir;
32 if ('/' != fDocsDir.back()) {
33 fDocsDir += '/';
34 }
35 string outie = outDir;
36 if ('/' != outie.back()) {
37 outie += '/';
38 }
39 fFullName = outie + "catalog.htm";
40 fOut = fopen(fFullName.c_str(), "wb");
41 if (!fOut) {
42 SkDebugf("could not open output file %s\n", fFullName.c_str());
43 return false;
44 }
45 fContinuation = false;
46 if (!appendFile(fDocsDir + "catalogHeader.txt")) {
47 return false;
48 }
49 this->lf(1);
50 return true;
51}
52
Cary Clark2f466242017-12-11 16:03:17 -050053bool Catalog::openStatus(const char* statusFile, const char* outDir) {
54 StatusIter iter(statusFile, ".bmh", StatusFilter::kInProgress);
55 string unused;
56 // FIXME: iterate through only chosen files by setting fDocsDir to iter
57 // read one file to find directory
58 if (!iter.next(&unused)) {
59 return false;
60 }
61 return openCatalog(iter.baseDir().c_str(), outDir);
62}
63
Cary Clarkbef063a2017-10-31 15:44:45 -040064bool Catalog::closeCatalog() {
65 if (fOut) {
66 this->lf(1);
67 this->writeString("}");
68 this->lf(1);
69 if (!appendFile(fDocsDir + "catalogTrailer.txt")) {
70 return false;
71 }
72 this->lf(1);
73 this->writePending();
74 fclose(fOut);
75 SkDebugf("wrote %s\n", fFullName.c_str());
76 fOut = nullptr;
77 }
78 return true;
79}
80
81bool Catalog::parseFromFile(const char* path) {
Cary Clarkd7895502018-07-18 15:10:08 -040082 if (!INHERITED::parseFromFile(path)) {
Cary Clarkbef063a2017-10-31 15:44:45 -040083 return false;
84 }
85 fIndent = 4;
86 this->writeString("var text = {");
87 this->lf(1);
88 fTextOut = true;
Cary Clarkbef063a2017-10-31 15:44:45 -040089 if (!parseFiddles()) {
90 return false;
91 }
92 this->lf(1);
93 this->writeString("}");
94 this->lf(2);
95 this->writeString("var pngs = {");
96 fTextOut = false;
97 fPngOut = true;
Cary Clarkd7895502018-07-18 15:10:08 -040098 JsonStatus* status = &fStack.back();
99 status->fIter = status->fObject.begin();
Cary Clarkbef063a2017-10-31 15:44:45 -0400100 fContinuation = false;
101 return parseFiddles();
102}
103
104bool Catalog::pngOut(Definition* example) {
105 string result;
Cary Clark1a8d7622018-03-05 13:26:16 -0500106 if (!fBmhParser->exampleToScript(example, BmhParser::ExampleOptions::kPng, &result)) {
Cary Clarkbef063a2017-10-31 15:44:45 -0400107 return false;
108 }
109 if (result.length() > 0) {
110 if (fContinuation) {
111 this->writeString(",");
112 this->lf(1);
113 } else {
114 fContinuation = true;
115 }
116 this->writeBlock(result.size(), result.c_str());
117 }
118 return true;
119}
120
Cary Clarkc896edd2017-12-12 11:38:09 -0500121bool Catalog::textOut(Definition* def, const char* stdOutStart,
Cary Clarkbef063a2017-10-31 15:44:45 -0400122 const char* stdOutEnd) {
123 string result;
Cary Clark1a8d7622018-03-05 13:26:16 -0500124 if (!fBmhParser->exampleToScript(def, BmhParser::ExampleOptions::kText, &result)) {
Cary Clarkbef063a2017-10-31 15:44:45 -0400125 return false;
126 }
127 if (result.length() > 0) {
128 if (fContinuation) {
129 this->writeString(",");
130 this->lf(1);
131 } else {
132 fContinuation = true;
133 }
134 fIndent = 8;
135 this->writeBlock(result.size(), result.c_str());
136 this->lf(1);
137 this->writeString("\"stdout\": \"");
138 size_t pos = 0;
139 size_t len = stdOutEnd - stdOutStart;
140 string example;
Cary Clarkc896edd2017-12-12 11:38:09 -0500141 const Definition* stdOut = def->hasChild(MarkType::kStdOut);
142 const Definition* outVolatile = stdOut ? stdOut->hasChild(MarkType::kVolatile) : nullptr;
143 if (outVolatile) {
144 stdOutStart = outVolatile->fContentStart;
145 while ('\n' == stdOutStart[0]) {
146 ++stdOutStart;
147 }
148 len = stdOut->fContentEnd - stdOutStart;
149 }
Cary Clarkbef063a2017-10-31 15:44:45 -0400150 while ((size_t) pos < len) {
151 example += '"' == stdOutStart[pos] ? "\\\"" :
152 '\\' == stdOutStart[pos] ? "\\\\" :
Cary Clarkc896edd2017-12-12 11:38:09 -0500153 '\n' == stdOutStart[pos] ? "\\\\n" :
Cary Clarkbef063a2017-10-31 15:44:45 -0400154 string(&stdOutStart[pos], 1);
Cary Clarkc896edd2017-12-12 11:38:09 -0500155 if (outVolatile && '\n' == stdOutStart[pos]) {
156 ++pos;
157 while ((size_t) pos < len && ' ' == stdOutStart[pos]) {
158 ++pos;
159 }
160 continue;
161 }
Cary Clarkbef063a2017-10-31 15:44:45 -0400162 ++pos;
163 }
Cary Clarkc896edd2017-12-12 11:38:09 -0500164 if (outVolatile) {
165 example += "\\\\n";
166 }
Cary Clarkbef063a2017-10-31 15:44:45 -0400167 this->writeBlock(example.length(), example.c_str());
168 this->writeString("\"");
169 this->lf(1);
170 fIndent = 4;
171 this->writeString("}");
172 }
173 return true;
174}