2017-10-31 19:44:45 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2017 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "bookmaker.h"
|
|
|
|
|
|
|
|
#include "SkOSFile.h"
|
|
|
|
#include "SkOSPath.h"
|
|
|
|
|
2018-04-16 12:37:38 +00:00
|
|
|
bool Catalog::appendFile(string path) {
|
2017-10-31 19:44:45 +00:00
|
|
|
FILE* file = fopen(path.c_str(), "r");
|
|
|
|
if (!file) {
|
|
|
|
SkDebugf("could not append %s\n", path.c_str());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
fseek(file, 0L, SEEK_END);
|
|
|
|
int sz = (int) ftell(file);
|
|
|
|
rewind(file);
|
|
|
|
char* buffer = new char[sz];
|
|
|
|
memset(buffer, ' ', sz);
|
2017-11-01 14:52:55 +00:00
|
|
|
SkAssertResult(sz == (int)fread(buffer, 1, sz, file));
|
2017-10-31 19:44:45 +00:00
|
|
|
fclose(file);
|
|
|
|
this->writeBlock(sz, buffer);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Catalog::openCatalog(const char* inDir, const char* outDir) {
|
|
|
|
fDocsDir = inDir;
|
|
|
|
if ('/' != fDocsDir.back()) {
|
|
|
|
fDocsDir += '/';
|
|
|
|
}
|
|
|
|
string outie = outDir;
|
|
|
|
if ('/' != outie.back()) {
|
|
|
|
outie += '/';
|
|
|
|
}
|
|
|
|
fFullName = outie + "catalog.htm";
|
|
|
|
fOut = fopen(fFullName.c_str(), "wb");
|
|
|
|
if (!fOut) {
|
|
|
|
SkDebugf("could not open output file %s\n", fFullName.c_str());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
fContinuation = false;
|
|
|
|
if (!appendFile(fDocsDir + "catalogHeader.txt")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
this->lf(1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-12-11 21:03:17 +00:00
|
|
|
bool Catalog::openStatus(const char* statusFile, const char* outDir) {
|
|
|
|
StatusIter iter(statusFile, ".bmh", StatusFilter::kInProgress);
|
|
|
|
string unused;
|
|
|
|
// FIXME: iterate through only chosen files by setting fDocsDir to iter
|
|
|
|
// read one file to find directory
|
|
|
|
if (!iter.next(&unused)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return openCatalog(iter.baseDir().c_str(), outDir);
|
|
|
|
}
|
|
|
|
|
2017-10-31 19:44:45 +00:00
|
|
|
bool Catalog::closeCatalog() {
|
|
|
|
if (fOut) {
|
|
|
|
this->lf(1);
|
|
|
|
this->writeString("}");
|
|
|
|
this->lf(1);
|
|
|
|
if (!appendFile(fDocsDir + "catalogTrailer.txt")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
this->lf(1);
|
|
|
|
this->writePending();
|
|
|
|
fclose(fOut);
|
|
|
|
SkDebugf("wrote %s\n", fFullName.c_str());
|
|
|
|
fOut = nullptr;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Catalog::parseFromFile(const char* path) {
|
|
|
|
if (!INHERITED::parseSetup(path)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
fIndent = 4;
|
|
|
|
this->writeString("var text = {");
|
|
|
|
this->lf(1);
|
|
|
|
fTextOut = true;
|
2018-04-03 12:43:27 +00:00
|
|
|
TextParserSave save(this);
|
2017-10-31 19:44:45 +00:00
|
|
|
if (!parseFiddles()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
this->lf(1);
|
|
|
|
this->writeString("}");
|
|
|
|
this->lf(2);
|
|
|
|
this->writeString("var pngs = {");
|
|
|
|
fTextOut = false;
|
|
|
|
fPngOut = true;
|
|
|
|
save.restore();
|
|
|
|
fContinuation = false;
|
|
|
|
return parseFiddles();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Catalog::pngOut(Definition* example) {
|
|
|
|
string result;
|
2018-03-05 18:26:16 +00:00
|
|
|
if (!fBmhParser->exampleToScript(example, BmhParser::ExampleOptions::kPng, &result)) {
|
2017-10-31 19:44:45 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (result.length() > 0) {
|
|
|
|
if (fContinuation) {
|
|
|
|
this->writeString(",");
|
|
|
|
this->lf(1);
|
|
|
|
} else {
|
|
|
|
fContinuation = true;
|
|
|
|
}
|
|
|
|
this->writeBlock(result.size(), result.c_str());
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-12-12 16:38:09 +00:00
|
|
|
bool Catalog::textOut(Definition* def, const char* stdOutStart,
|
2017-10-31 19:44:45 +00:00
|
|
|
const char* stdOutEnd) {
|
|
|
|
string result;
|
2018-03-05 18:26:16 +00:00
|
|
|
if (!fBmhParser->exampleToScript(def, BmhParser::ExampleOptions::kText, &result)) {
|
2017-10-31 19:44:45 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (result.length() > 0) {
|
|
|
|
if (fContinuation) {
|
|
|
|
this->writeString(",");
|
|
|
|
this->lf(1);
|
|
|
|
} else {
|
|
|
|
fContinuation = true;
|
|
|
|
}
|
|
|
|
fIndent = 8;
|
|
|
|
this->writeBlock(result.size(), result.c_str());
|
|
|
|
this->lf(1);
|
|
|
|
this->writeString("\"stdout\": \"");
|
|
|
|
size_t pos = 0;
|
|
|
|
size_t len = stdOutEnd - stdOutStart;
|
|
|
|
string example;
|
2017-12-12 16:38:09 +00:00
|
|
|
const Definition* stdOut = def->hasChild(MarkType::kStdOut);
|
|
|
|
const Definition* outVolatile = stdOut ? stdOut->hasChild(MarkType::kVolatile) : nullptr;
|
|
|
|
if (outVolatile) {
|
|
|
|
stdOutStart = outVolatile->fContentStart;
|
|
|
|
while ('\n' == stdOutStart[0]) {
|
|
|
|
++stdOutStart;
|
|
|
|
}
|
|
|
|
len = stdOut->fContentEnd - stdOutStart;
|
|
|
|
}
|
2017-10-31 19:44:45 +00:00
|
|
|
while ((size_t) pos < len) {
|
|
|
|
example += '"' == stdOutStart[pos] ? "\\\"" :
|
|
|
|
'\\' == stdOutStart[pos] ? "\\\\" :
|
2017-12-12 16:38:09 +00:00
|
|
|
'\n' == stdOutStart[pos] ? "\\\\n" :
|
2017-10-31 19:44:45 +00:00
|
|
|
string(&stdOutStart[pos], 1);
|
2017-12-12 16:38:09 +00:00
|
|
|
if (outVolatile && '\n' == stdOutStart[pos]) {
|
|
|
|
++pos;
|
|
|
|
while ((size_t) pos < len && ' ' == stdOutStart[pos]) {
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2017-10-31 19:44:45 +00:00
|
|
|
++pos;
|
|
|
|
}
|
2017-12-12 16:38:09 +00:00
|
|
|
if (outVolatile) {
|
|
|
|
example += "\\\\n";
|
|
|
|
}
|
2017-10-31 19:44:45 +00:00
|
|
|
this->writeBlock(example.length(), example.c_str());
|
|
|
|
this->writeString("\"");
|
|
|
|
this->lf(1);
|
|
|
|
fIndent = 4;
|
|
|
|
this->writeString("}");
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|