mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
Fixed flow folding, and made the separation slightly cleaner (but the whole scanscalar thing could use a major refactoring)
This commit is contained in:
@@ -19,7 +19,8 @@ namespace YAML
|
|||||||
// and different places in the above flow.
|
// and different places in the above flow.
|
||||||
std::string ScanScalar(Stream& INPUT, ScanScalarParams& params)
|
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;
|
bool emptyLine = false, moreIndented = false;
|
||||||
int foldedNewlineCount = 0;
|
int foldedNewlineCount = 0;
|
||||||
bool foldedNewlineStartedMoreIndented = false;
|
bool foldedNewlineStartedMoreIndented = false;
|
||||||
@@ -29,6 +30,8 @@ namespace YAML
|
|||||||
while(INPUT) {
|
while(INPUT) {
|
||||||
// ********************************
|
// ********************************
|
||||||
// Phase #1: scan until line ending
|
// Phase #1: scan until line ending
|
||||||
|
|
||||||
|
std::size_t lastNonWhitespaceChar = scalar.size();
|
||||||
while(!params.end.Matches(INPUT) && !Exp::Break.Matches(INPUT)) {
|
while(!params.end.Matches(INPUT) && !Exp::Break.Matches(INPUT)) {
|
||||||
if(!INPUT)
|
if(!INPUT)
|
||||||
break;
|
break;
|
||||||
@@ -48,17 +51,22 @@ namespace YAML
|
|||||||
if(params.escape == '\\' && Exp::EscBreak.Matches(INPUT)) {
|
if(params.escape == '\\' && Exp::EscBreak.Matches(INPUT)) {
|
||||||
int n = Exp::EscBreak.Match(INPUT);
|
int n = Exp::EscBreak.Match(INPUT);
|
||||||
INPUT.eat(n);
|
INPUT.eat(n);
|
||||||
|
lastNonWhitespaceChar = scalar.size();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// escape this?
|
// escape this?
|
||||||
if(INPUT.peek() == params.escape) {
|
if(INPUT.peek() == params.escape) {
|
||||||
scalar += Exp::Escape(INPUT);
|
scalar += Exp::Escape(INPUT);
|
||||||
|
lastNonWhitespaceChar = scalar.size();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, just add the damn character
|
// 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
|
// eof? if we're looking to eat something, then we throw
|
||||||
@@ -79,7 +87,11 @@ namespace YAML
|
|||||||
INPUT.eat(n);
|
INPUT.eat(n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do we remove trailing whitespace?
|
||||||
|
if(params.fold == FOLD_FLOW)
|
||||||
|
scalar.erase(lastNonWhitespaceChar);
|
||||||
|
|
||||||
// ********************************
|
// ********************************
|
||||||
// Phase #2: eat line ending
|
// Phase #2: eat line ending
|
||||||
n = Exp::Break.Match(INPUT);
|
n = Exp::Break.Match(INPUT);
|
||||||
@@ -111,27 +123,36 @@ namespace YAML
|
|||||||
// was this an empty line?
|
// was this an empty line?
|
||||||
bool nextEmptyLine = Exp::Break.Matches(INPUT);
|
bool nextEmptyLine = Exp::Break.Matches(INPUT);
|
||||||
bool nextMoreIndented = Exp::Blank.Matches(INPUT);
|
bool nextMoreIndented = Exp::Blank.Matches(INPUT);
|
||||||
if(params.fold && foldedNewlineCount == 0 && nextEmptyLine)
|
if(params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine)
|
||||||
foldedNewlineStartedMoreIndented = moreIndented;
|
foldedNewlineStartedMoreIndented = moreIndented;
|
||||||
|
|
||||||
// for block scalars, we always start with a newline, so we should ignore it (not fold or keep)
|
// for block scalars, we always start with a newline, so we should ignore it (not fold or keep)
|
||||||
if(pastOpeningBreak) {
|
if(pastOpeningBreak) {
|
||||||
if(params.fold) {
|
switch(params.fold) {
|
||||||
if(!emptyLine && !nextEmptyLine && !moreIndented && !nextMoreIndented && INPUT.column() >= params.indent)
|
case DONT_FOLD:
|
||||||
scalar += " ";
|
|
||||||
else if(nextEmptyLine)
|
|
||||||
foldedNewlineCount++;
|
|
||||||
else
|
|
||||||
scalar += "\n";
|
scalar += "\n";
|
||||||
|
break;
|
||||||
if(!nextEmptyLine && foldedNewlineCount > 0) {
|
case FOLD_BLOCK:
|
||||||
scalar += std::string(foldedNewlineCount - 1, '\n');
|
if(!emptyLine && !nextEmptyLine && !moreIndented && !nextMoreIndented && INPUT.column() >= params.indent)
|
||||||
if(foldedNewlineStartedMoreIndented || nextMoreIndented)
|
scalar += " ";
|
||||||
|
else if(nextEmptyLine)
|
||||||
|
foldedNewlineCount++;
|
||||||
|
else
|
||||||
scalar += "\n";
|
scalar += "\n";
|
||||||
foldedNewlineCount = 0;
|
|
||||||
}
|
if(!nextEmptyLine && foldedNewlineCount > 0) {
|
||||||
} else {
|
scalar += std::string(foldedNewlineCount - 1, '\n');
|
||||||
scalar += "\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 CHOMP { STRIP = -1, CLIP, KEEP };
|
||||||
enum ACTION { NONE, BREAK, THROW };
|
enum ACTION { NONE, BREAK, THROW };
|
||||||
|
enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW };
|
||||||
|
|
||||||
struct ScanScalarParams {
|
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) {}
|
trimTrailingSpaces(0), chomp(CLIP), onDocIndicator(NONE), onTabInIndentation(NONE), leadingSpaces(false) {}
|
||||||
|
|
||||||
// input:
|
// input:
|
||||||
@@ -24,7 +25,7 @@ namespace YAML
|
|||||||
bool detectIndent; // should we try to autodetect the indent?
|
bool detectIndent; // should we try to autodetect the indent?
|
||||||
bool eatLeadingWhitespace; // should we continue eating this delicious indentation after 'indent' spaces?
|
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)
|
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)
|
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)
|
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
|
// 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.end = (InFlowContext() ? Exp::EndScalarInFlow : Exp::EndScalar) || (Exp::BlankOrBreak + Exp::Comment);
|
||||||
params.eatEnd = false;
|
params.eatEnd = false;
|
||||||
params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
|
params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
|
||||||
params.fold = true;
|
params.fold = FOLD_BLOCK;
|
||||||
params.eatLeadingWhitespace = true;
|
params.eatLeadingWhitespace = true;
|
||||||
params.trimTrailingSpaces = true;
|
params.trimTrailingSpaces = true;
|
||||||
params.chomp = STRIP;
|
params.chomp = STRIP;
|
||||||
@@ -327,7 +327,7 @@ namespace YAML
|
|||||||
params.eatEnd = true;
|
params.eatEnd = true;
|
||||||
params.escape = (single ? '\'' : '\\');
|
params.escape = (single ? '\'' : '\\');
|
||||||
params.indent = 0;
|
params.indent = 0;
|
||||||
params.fold = true;
|
params.fold = FOLD_FLOW;
|
||||||
params.eatLeadingWhitespace = true;
|
params.eatLeadingWhitespace = true;
|
||||||
params.trimTrailingSpaces = false;
|
params.trimTrailingSpaces = false;
|
||||||
params.chomp = CLIP;
|
params.chomp = CLIP;
|
||||||
@@ -365,7 +365,7 @@ namespace YAML
|
|||||||
// eat block indicator ('|' or '>')
|
// eat block indicator ('|' or '>')
|
||||||
Mark mark = INPUT.mark();
|
Mark mark = INPUT.mark();
|
||||||
char indicator = INPUT.get();
|
char indicator = INPUT.get();
|
||||||
params.fold = (indicator == Keys::FoldedScalar);
|
params.fold = (indicator == Keys::FoldedScalar ? FOLD_BLOCK : DONT_FOLD);
|
||||||
|
|
||||||
// eat chomping/indentation indicators
|
// eat chomping/indentation indicators
|
||||||
params.chomp = CLIP;
|
params.chomp = CLIP;
|
||||||
|
Reference in New Issue
Block a user