Commit e4540f2c authored by jbeder's avatar jbeder
Browse files

Fixed flow folding, and made the separation slightly cleaner (but the whole...

Fixed flow folding, and made the separation slightly cleaner (but the whole scanscalar thing could use a major refactoring)
parent 1d52e037
......@@ -19,7 +19,8 @@ namespace YAML
// and different places in the above flow.
std::string ScanScalar(Stream& INPUT, ScanScalarParams& params)
{
bool foundNonEmptyLine = false, pastOpeningBreak = false;
bool foundNonEmptyLine = false;
bool pastOpeningBreak = (params.fold == FOLD_FLOW);
bool emptyLine = false, moreIndented = false;
int foldedNewlineCount = 0;
bool foldedNewlineStartedMoreIndented = false;
......@@ -29,6 +30,8 @@ namespace YAML
while(INPUT) {
// ********************************
// Phase #1: scan until line ending
std::size_t lastNonWhitespaceChar = scalar.size();
while(!params.end.Matches(INPUT) && !Exp::Break.Matches(INPUT)) {
if(!INPUT)
break;
......@@ -48,17 +51,22 @@ namespace YAML
if(params.escape == '\\' && Exp::EscBreak.Matches(INPUT)) {
int n = Exp::EscBreak.Match(INPUT);
INPUT.eat(n);
lastNonWhitespaceChar = scalar.size();
continue;
}
// escape this?
if(INPUT.peek() == params.escape) {
scalar += Exp::Escape(INPUT);
lastNonWhitespaceChar = scalar.size();
continue;
}
// otherwise, just add the damn character
scalar += INPUT.get();
char ch = INPUT.get();
scalar += ch;
if(ch != ' ' && ch != '\t')
lastNonWhitespaceChar = scalar.size();
}
// eof? if we're looking to eat something, then we throw
......@@ -79,7 +87,11 @@ namespace YAML
INPUT.eat(n);
break;
}
// do we remove trailing whitespace?
if(params.fold == FOLD_FLOW)
scalar.erase(lastNonWhitespaceChar);
// ********************************
// Phase #2: eat line ending
n = Exp::Break.Match(INPUT);
......@@ -111,27 +123,36 @@ namespace YAML
// was this an empty line?
bool nextEmptyLine = Exp::Break.Matches(INPUT);
bool nextMoreIndented = Exp::Blank.Matches(INPUT);
if(params.fold && foldedNewlineCount == 0 && nextEmptyLine)
if(params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine)
foldedNewlineStartedMoreIndented = moreIndented;
// for block scalars, we always start with a newline, so we should ignore it (not fold or keep)
if(pastOpeningBreak) {
if(params.fold) {
if(!emptyLine && !nextEmptyLine && !moreIndented && !nextMoreIndented && INPUT.column() >= params.indent)
scalar += " ";
else if(nextEmptyLine)
foldedNewlineCount++;
else
switch(params.fold) {
case DONT_FOLD:
scalar += "\n";
if(!nextEmptyLine && foldedNewlineCount > 0) {
scalar += std::string(foldedNewlineCount - 1, '\n');
if(foldedNewlineStartedMoreIndented || nextMoreIndented)
break;
case FOLD_BLOCK:
if(!emptyLine && !nextEmptyLine && !moreIndented && !nextMoreIndented && INPUT.column() >= params.indent)
scalar += " ";
else if(nextEmptyLine)
foldedNewlineCount++;
else
scalar += "\n";
foldedNewlineCount = 0;
}
} else {
scalar += "\n";
if(!nextEmptyLine && foldedNewlineCount > 0) {
scalar += std::string(foldedNewlineCount - 1, '\n');
if(foldedNewlineStartedMoreIndented || nextMoreIndented)
scalar += "\n";
foldedNewlineCount = 0;
}
break;
case FOLD_FLOW:
if(nextEmptyLine)
scalar += "\n";
else if(!emptyLine && !nextEmptyLine)
scalar += " ";
break;
}
}
......
......@@ -12,9 +12,10 @@ namespace YAML
{
enum CHOMP { STRIP = -1, CLIP, KEEP };
enum ACTION { NONE, BREAK, THROW };
enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW };
struct ScanScalarParams {
ScanScalarParams(): eatEnd(false), indent(0), detectIndent(false), eatLeadingWhitespace(0), escape(0), fold(false),
ScanScalarParams(): eatEnd(false), indent(0), detectIndent(false), eatLeadingWhitespace(0), escape(0), fold(DONT_FOLD),
trimTrailingSpaces(0), chomp(CLIP), onDocIndicator(NONE), onTabInIndentation(NONE), leadingSpaces(false) {}
// input:
......@@ -24,7 +25,7 @@ namespace YAML
bool detectIndent; // should we try to autodetect the indent?
bool eatLeadingWhitespace; // should we continue eating this delicious indentation after 'indent' spaces?
char escape; // what character do we escape on (i.e., slash or single quote) (0 for none)
bool fold; // do we fold line ends?
FOLD fold; // how do we fold line ends?
bool trimTrailingSpaces; // do we remove all trailing spaces (at the very end)
CHOMP chomp; // do we strip, clip, or keep trailing newlines (at the very end)
// Note: strip means kill all, clip means keep at most one, keep means keep all
......
......@@ -287,7 +287,7 @@ namespace YAML
params.end = (InFlowContext() ? Exp::EndScalarInFlow : Exp::EndScalar) || (Exp::BlankOrBreak + Exp::Comment);
params.eatEnd = false;
params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
params.fold = true;
params.fold = FOLD_BLOCK;
params.eatLeadingWhitespace = true;
params.trimTrailingSpaces = true;
params.chomp = STRIP;
......@@ -327,7 +327,7 @@ namespace YAML
params.eatEnd = true;
params.escape = (single ? '\'' : '\\');
params.indent = 0;
params.fold = true;
params.fold = FOLD_FLOW;
params.eatLeadingWhitespace = true;
params.trimTrailingSpaces = false;
params.chomp = CLIP;
......@@ -365,7 +365,7 @@ namespace YAML
// eat block indicator ('|' or '>')
Mark mark = INPUT.mark();
char indicator = INPUT.get();
params.fold = (indicator == Keys::FoldedScalar);
params.fold = (indicator == Keys::FoldedScalar ? FOLD_BLOCK : DONT_FOLD);
// eat chomping/indentation indicators
params.chomp = CLIP;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment