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 10#include "SkOSFile.h" 11#include "SkOSPath.h" 12 13bool Catalog::appendFile(const string& path) { 14 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); 24 SkAssertResult(sz == (int)fread(buffer, 1, sz, file)); 25 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 53bool 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 64bool 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) { 82 if (!INHERITED::parseSetup(path)) { 83 return false; 84 } 85 fIndent = 4; 86 this->writeString("var text = {"); 87 this->lf(1); 88 fTextOut = true; 89 TextParser::Save save(this); 90 if (!parseFiddles()) { 91 return false; 92 } 93 this->lf(1); 94 this->writeString("}"); 95 this->lf(2); 96 this->writeString("var pngs = {"); 97 fTextOut = false; 98 fPngOut = true; 99 save.restore(); 100 fContinuation = false; 101 return parseFiddles(); 102} 103 104bool Catalog::pngOut(Definition* example) { 105 string result; 106 if (!example->exampleToScript(&result, Definition::ExampleOptions::kPng)) { 107 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 121bool Catalog::textOut(Definition* def, const char* stdOutStart, 122 const char* stdOutEnd) { 123 string result; 124 if (!def->exampleToScript(&result, Definition::ExampleOptions::kText)) { 125 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; 141 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 } 150 while ((size_t) pos < len) { 151 example += '"' == stdOutStart[pos] ? "\\\"" : 152 '\\' == stdOutStart[pos] ? "\\\\" : 153 '\n' == stdOutStart[pos] ? "\\\\n" : 154 string(&stdOutStart[pos], 1); 155 if (outVolatile && '\n' == stdOutStart[pos]) { 156 ++pos; 157 while ((size_t) pos < len && ' ' == stdOutStart[pos]) { 158 ++pos; 159 } 160 continue; 161 } 162 ++pos; 163 } 164 if (outVolatile) { 165 example += "\\\\n"; 166 } 167 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} 175