bef063af14
Docs-Preview: https://skia.org/?cl=64900 Bug: skia:6898 Change-Id: Ifbaf909854680a88060f16b1559863cc124aaa7a Reviewed-on: https://skia-review.googlesource.com/64900 Commit-Queue: Cary Clark <caryclark@skia.org> Reviewed-by: Cary Clark <caryclark@skia.org>
185 lines
4.6 KiB
C++
185 lines
4.6 KiB
C++
/*
|
|
* 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"
|
|
|
|
static void debug_out(int len, const char* data) {
|
|
// convenient place to intercept arbitrary output
|
|
SkDebugf("%.*s", len, data);
|
|
}
|
|
|
|
bool ParserCommon::parseSetup(const char* path) {
|
|
// this->reset();
|
|
sk_sp<SkData> data = SkData::MakeFromFileName(path);
|
|
if (nullptr == data.get()) {
|
|
SkDebugf("%s missing\n", path);
|
|
return false;
|
|
}
|
|
const char* rawText = (const char*) data->data();
|
|
bool hasCR = false;
|
|
size_t dataSize = data->size();
|
|
for (size_t index = 0; index < dataSize; ++index) {
|
|
if ('\r' == rawText[index]) {
|
|
hasCR = true;
|
|
break;
|
|
}
|
|
}
|
|
string name(path);
|
|
if (hasCR) {
|
|
vector<char> lfOnly;
|
|
for (size_t index = 0; index < dataSize; ++index) {
|
|
char ch = rawText[index];
|
|
if ('\r' == rawText[index]) {
|
|
ch = '\n';
|
|
if ('\n' == rawText[index + 1]) {
|
|
++index;
|
|
}
|
|
}
|
|
lfOnly.push_back(ch);
|
|
}
|
|
fLFOnly[name] = lfOnly;
|
|
dataSize = lfOnly.size();
|
|
rawText = &fLFOnly[name].front();
|
|
}
|
|
fRawData[name] = data;
|
|
fStart = rawText;
|
|
fLine = rawText;
|
|
fChar = rawText;
|
|
fEnd = rawText + dataSize;
|
|
fFileName = string(path);
|
|
fLineCount = 1;
|
|
return true;
|
|
}
|
|
|
|
void ParserCommon::writeBlockIndent(int size, const char* data) {
|
|
while (size && ' ' >= data[size - 1]) {
|
|
--size;
|
|
}
|
|
bool newLine = false;
|
|
while (size) {
|
|
while (size && ' ' > data[0]) {
|
|
++data;
|
|
--size;
|
|
}
|
|
if (!size) {
|
|
return;
|
|
}
|
|
if (newLine) {
|
|
this->lf(1);
|
|
}
|
|
TextParser parser(fFileName, data, data + size, fLineCount);
|
|
const char* lineEnd = parser.strnchr('\n', data + size);
|
|
int len = lineEnd ? (int) (lineEnd - data) : size;
|
|
this->writePending();
|
|
this->indentToColumn(fIndent);
|
|
if (fDebugOut) {
|
|
debug_out(len, data);
|
|
}
|
|
fprintf(fOut, "%.*s", len, data);
|
|
size -= len;
|
|
data += len;
|
|
newLine = true;
|
|
}
|
|
}
|
|
|
|
bool ParserCommon::writeBlockTrim(int size, const char* data) {
|
|
if (fOutdentNext) {
|
|
fIndent -= 4;
|
|
fOutdentNext = false;
|
|
}
|
|
while (size && ' ' >= data[0]) {
|
|
++data;
|
|
--size;
|
|
}
|
|
while (size && ' ' >= data[size - 1]) {
|
|
--size;
|
|
}
|
|
if (size <= 0) {
|
|
fLastChar = '\0';
|
|
return false;
|
|
}
|
|
SkASSERT(size < 16000);
|
|
if (size > 3 && !strncmp("#end", data, 4)) {
|
|
fMaxLF = 1;
|
|
}
|
|
if (this->leadingPunctuation(data, (size_t) size)) {
|
|
fPendingSpace = 0;
|
|
}
|
|
this->writePending();
|
|
if (fDebugOut) {
|
|
debug_out(size, data);
|
|
}
|
|
fprintf(fOut, "%.*s", size, data);
|
|
int added = 0;
|
|
fLastChar = data[size - 1];
|
|
while (size > 0 && '\n' != data[--size]) {
|
|
++added;
|
|
}
|
|
fColumn = size ? added : fColumn + added;
|
|
fSpaces = 0;
|
|
fLinefeeds = 0;
|
|
fMaxLF = added > 2 && !strncmp("#if", &data[size + (size > 0)], 3) ? 1 : 2;
|
|
if (fOutdentNext) {
|
|
fIndent -= 4;
|
|
fOutdentNext = false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void ParserCommon::writePending() {
|
|
fPendingLF = SkTMin(fPendingLF, fMaxLF);
|
|
bool wroteLF = false;
|
|
while (fLinefeeds < fPendingLF) {
|
|
if (fDebugOut) {
|
|
SkDebugf("\n");
|
|
}
|
|
fprintf(fOut, "\n");
|
|
++fLinefeeds;
|
|
wroteLF = true;
|
|
}
|
|
fPendingLF = 0;
|
|
if (wroteLF) {
|
|
SkASSERT(0 == fColumn);
|
|
SkASSERT(fIndent >= fSpaces);
|
|
if (fDebugOut) {
|
|
SkDebugf("%*s", fIndent - fSpaces, "");
|
|
}
|
|
fprintf(fOut, "%*s", fIndent - fSpaces, "");
|
|
fColumn = fIndent;
|
|
fSpaces = fIndent;
|
|
}
|
|
for (int index = 0; index < fPendingSpace; ++index) {
|
|
if (fDebugOut) {
|
|
SkDebugf(" ");
|
|
}
|
|
fprintf(fOut, " ");
|
|
++fColumn;
|
|
}
|
|
fPendingSpace = 0;
|
|
}
|
|
|
|
void ParserCommon::writeString(const char* str) {
|
|
const size_t len = strlen(str);
|
|
SkASSERT(len > 0);
|
|
SkASSERT(' ' < str[0]);
|
|
fLastChar = str[len - 1];
|
|
SkASSERT(' ' < fLastChar);
|
|
SkASSERT(!strchr(str, '\n'));
|
|
if (this->leadingPunctuation(str, strlen(str))) {
|
|
fPendingSpace = 0;
|
|
}
|
|
this->writePending();
|
|
if (fDebugOut) {
|
|
debug_out((int) strlen(str), str);
|
|
}
|
|
fprintf(fOut, "%s", str);
|
|
fColumn += len;
|
|
fSpaces = 0;
|
|
fLinefeeds = 0;
|
|
fMaxLF = 2;
|
|
}
|