1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2017 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "bookmaker.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkOSFile.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkOSPath.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void debug_out(int len, const char* data) { 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // convenient place to intercept arbitrary output 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("%.*s", len, data); 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool ParserCommon::parseFile(const char* fileOrPath, const char* suffix) { 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!sk_isdir(fileOrPath)) { 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!this->parseFromFile(fileOrPath)) { 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("failed to parse %s\n", fileOrPath); 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkOSFile::Iter it(fileOrPath, suffix); 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (SkString file; it.next(&file); ) { 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString p = SkOSPath::Join(fileOrPath, file.c_str()); 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* hunk = p.c_str(); 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!SkStrEndsWith(hunk, suffix)) { 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot continue; 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!this->parseFromFile(hunk)) { 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("failed to parse %s\n", hunk); 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool ParserCommon::parseStatus(const char* statusFile, const char* suffix, StatusFilter filter) { 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot StatusIter iter(statusFile, suffix, filter); 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (iter.empty()) { 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (string file; iter.next(&file); ) { 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString p = SkOSPath::Join(iter.baseDir().c_str(), file.c_str()); 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* hunk = p.c_str(); 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!this->parseFromFile(hunk)) { 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("failed to parse %s\n", hunk); 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool ParserCommon::parseSetup(const char* path) { 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkData> data = SkData::MakeFromFileName(path); 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (nullptr == data.get()) { 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("%s missing\n", path); 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* rawText = (const char*) data->data(); 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool hasCR = false; 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t dataSize = data->size(); 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t index = 0; index < dataSize; ++index) { 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if ('\r' == rawText[index]) { 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot hasCR = true; 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot string name(path); 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (hasCR) { 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vector<char> lfOnly; 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t index = 0; index < dataSize; ++index) { 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot char ch = rawText[index]; 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if ('\r' == rawText[index]) { 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ch = '\n'; 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if ('\n' == rawText[index + 1]) { 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++index; 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot lfOnly.push_back(ch); 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLFOnly[name] = lfOnly; 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dataSize = lfOnly.size(); 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rawText = &fLFOnly[name].front(); 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fRawData[name] = data; 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fStart = rawText; 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLine = rawText; 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fChar = rawText; 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fEnd = rawText + dataSize; 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fFileName = string(path); 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLineCount = 1; 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid ParserCommon::writeBlockIndent(int size, const char* data) { 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (size && ' ' >= data[size - 1]) { 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot --size; 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool newLine = false; 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (size) { 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (size && ' ' > data[0]) { 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++data; 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot --size; 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!size) { 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (newLine) { 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->lf(1); 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TextParser parser(fFileName, data, data + size, fLineCount); 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* lineEnd = parser.strnchr('\n', data + size); 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int len = lineEnd ? (int) (lineEnd - data) : size; 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->writePending(); 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->indentToColumn(fIndent); 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDebugOut) { 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot debug_out(len, data); 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fprintf(fOut, "%.*s", len, data); 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size -= len; 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data += len; 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot newLine = true; 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool ParserCommon::writeBlockTrim(int size, const char* data) { 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fOutdentNext) { 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fIndent -= 4; 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fOutdentNext = false; 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (size && ' ' >= data[0]) { 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++data; 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot --size; 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (size && ' ' >= data[size - 1]) { 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot --size; 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (size <= 0) { 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLastChar = '\0'; 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(size < 16000); 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (size > 3 && !strncmp("#end", data, 4)) { 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxLF = 1; 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->leadingPunctuation(data, (size_t) size)) { 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPendingSpace = 0; 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->writePending(); 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDebugOut) { 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot debug_out(size, data); 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fprintf(fOut, "%.*s", size, data); 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int added = 0; 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLastChar = data[size - 1]; 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (size > 0 && '\n' != data[--size]) { 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++added; 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fColumn = size ? added : fColumn + added; 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSpaces = 0; 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLinefeeds = 0; 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxLF = added > 2 && !strncmp("#if", &data[size + (size > 0)], 3) ? 1 : 2; 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fOutdentNext) { 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fIndent -= 4; 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fOutdentNext = false; 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid ParserCommon::writePending() { 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPendingLF = SkTMin(fPendingLF, fMaxLF); 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool wroteLF = false; 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (fLinefeeds < fPendingLF) { 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDebugOut) { 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("\n"); 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fprintf(fOut, "\n"); 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fLinefeeds; 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot wroteLF = true; 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPendingLF = 0; 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (wroteLF) { 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(0 == fColumn); 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fIndent >= fSpaces); 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDebugOut) { 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("%*s", fIndent - fSpaces, ""); 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fprintf(fOut, "%*s", fIndent - fSpaces, ""); 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fColumn = fIndent; 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSpaces = fIndent; 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int index = 0; index < fPendingSpace; ++index) { 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDebugOut) { 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf(" "); 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fprintf(fOut, " "); 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fColumn; 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPendingSpace = 0; 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid ParserCommon::writeString(const char* str) { 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const size_t len = strlen(str); 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(len > 0); 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(' ' < str[0]); 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLastChar = str[len - 1]; 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(' ' < fLastChar); 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!strchr(str, '\n')); 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->leadingPunctuation(str, strlen(str))) { 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPendingSpace = 0; 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->writePending(); 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDebugOut) { 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot debug_out((int) strlen(str), str); 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fprintf(fOut, "%s", str); 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fColumn += len; 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSpaces = 0; 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLinefeeds = 0; 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxLF = 2; 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconst char* ParserCommon::ReadToBuffer(string filename, int* size) { 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot FILE* file = fopen(filename.c_str(), "rb"); 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!file) { 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fseek(file, 0L, SEEK_END); 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *size = (int) ftell(file); 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rewind(file); 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot char* buffer = new char[*size]; 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot memset(buffer, ' ', *size); 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAssertResult(*size == (int)fread(buffer, 1, *size, file)); 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fclose(file); 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fflush(file); 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return buffer; 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool ParserCommon::writtenFileDiffers(string filename, string readname) { 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int writtenSize, readSize; 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* written = ReadToBuffer(filename, &writtenSize); 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!written) { 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* read = ReadToBuffer(readname, &readSize); 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!read) { 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot delete[] written; 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if 0 // enable for debugging this 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int smaller = SkTMin(writtenSize, readSize); 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int index = 0; index < smaller; ++index) { 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (written[index] != read[index]) { 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("%.*s\n", 40, &written[index]); 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("%.*s\n", 40, &read[index]); 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (readSize != writtenSize) { 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool result = !!memcmp(written, read, writtenSize); 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot delete[] written; 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot delete[] read; 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return result; 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotStatusIter::StatusIter(const char* statusFile, const char* suffix, StatusFilter filter) 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fSuffix(suffix) 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fFilter(filter) { 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!this->parseFromFile(statusFile)) { 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const char* block_names[] = { 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Completed", 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "InProgress", 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstring StatusIter::baseDir() { 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fStack.back().fObject.isArray()); 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fStack.size() > 2); 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot string dir; 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (unsigned index = 2; index < fStack.size(); ++index) { 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dir += fStack[index].fName; 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (index < fStack.size() - 1) { 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dir += SkOSPath::SEPARATOR; 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return dir; 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// FIXME: need to compare fBlockName against fFilter 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// need to compare fSuffix against next value returned 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool StatusIter::next(string* str) { 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot JsonStatus* status; 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot do { 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot do { 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fStack.empty()) { 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot status = &fStack.back(); 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (status->fIter != status->fObject.end()) { 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fStack.pop_back(); 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } while (true); 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (1 == fStack.size()) { 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot do { 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot StatusFilter blockType = StatusFilter::kUnknown; 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (unsigned index = 0; index < SK_ARRAY_COUNT(block_names); ++index) { 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (status->fIter.key().asString() == block_names[index]) { 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot blockType = (StatusFilter) index; 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (blockType <= fFilter) { 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot status->fIter++; 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } while (status->fIter != status->fObject.end()); 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (status->fIter == status->fObject.end()) { 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot continue; 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!status->fObject.isArray()) { 332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(status->fIter != status->fObject.end()); 333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot JsonStatus block = { 334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *status->fIter, 335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot status->fIter->begin(), 336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot status->fIter.key().asString() 337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fStack.emplace_back(block); 339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot status = &(&fStack.back())[-1]; 340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot status->fIter++; 341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot status = &fStack.back(); 342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot continue; 343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *str = status->fIter->asString(); 345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot status->fIter++; 346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (str->length() - strlen(fSuffix) == str->find(fSuffix)) { 347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } while (true); 350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool StatusIter::parseFromFile(const char* path) { 354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkData> json(SkData::MakeFromFileName(path)); 355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!json) { 356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("file %s:\n", path); 357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->reportError<bool>("file not readable"); 358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Json::Reader reader; 360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* data = (const char*)json->data(); 361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!reader.parse(data, data+json->size(), fRoot)) { 362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("file %s:\n", path); 363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->reportError<bool>("file not parsable"); 364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot JsonStatus block = { fRoot, fRoot.begin(), "" }; 366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fStack.emplace_back(block); 367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid StatusIter::reset() { 371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fStack.clear(); 372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 373