scanBlockScalarIndicators is now @nogc.
This commit is contained in:
parent
537eccc597
commit
ea3b696a8e
|
@ -1156,6 +1156,8 @@ final class Scanner
|
||||||
reader_.forward();
|
reader_.forward();
|
||||||
|
|
||||||
const indicators = scanBlockScalarIndicators(startMark);
|
const indicators = scanBlockScalarIndicators(startMark);
|
||||||
|
throwIfError();
|
||||||
|
|
||||||
const chomping = indicators[0];
|
const chomping = indicators[0];
|
||||||
const increment = indicators[1];
|
const increment = indicators[1];
|
||||||
scanBlockScalarIgnoredLine(startMark);
|
scanBlockScalarIgnoredLine(startMark);
|
||||||
|
@ -1228,50 +1230,87 @@ final class Scanner
|
||||||
return scalarToken(startMark, endMark, utf32To8(appender_.data), style);
|
return scalarToken(startMark, endMark, utf32To8(appender_.data), style);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scan chomping and indentation indicators of a scalar token.
|
/// Scan chomping and indentation indicators of a scalar token.
|
||||||
|
///
|
||||||
|
/// In case of an error, error_ is set. Use throwIfError() to handle this.
|
||||||
Tuple!(Chomping, int) scanBlockScalarIndicators(const Mark startMark)
|
Tuple!(Chomping, int) scanBlockScalarIndicators(const Mark startMark)
|
||||||
@safe pure
|
@safe pure nothrow @nogc
|
||||||
{
|
{
|
||||||
auto chomping = Chomping.Clip;
|
auto chomping = Chomping.Clip;
|
||||||
int increment = int.min;
|
int increment = int.min;
|
||||||
dchar c = reader_.peek();
|
dchar c = reader_.peek();
|
||||||
|
|
||||||
///Get chomping indicator, if detected. Return false otherwise.
|
/// Indicators can be in any order.
|
||||||
bool getChomping()
|
if(getChomping(c, chomping))
|
||||||
{
|
{
|
||||||
if(!"+-"d.canFind(c)){return false;}
|
getIncrement(c, increment, startMark);
|
||||||
chomping = c == '+' ? Chomping.Keep : Chomping.Strip;
|
if(error_) { return tuple(Chomping.init, int.max); }
|
||||||
reader_.forward();
|
}
|
||||||
c = reader_.peek();
|
else
|
||||||
return true;
|
{
|
||||||
|
const gotIncrement = getIncrement(c, increment, startMark);
|
||||||
|
if(error_) { return tuple(Chomping.init, int.max); }
|
||||||
|
if(gotIncrement) { getChomping(c, chomping); }
|
||||||
}
|
}
|
||||||
|
|
||||||
///Get increment indicator, if detected. Return false otherwise.
|
if(!" \0\n\r\u0085\u2028\u2029"d.canFind(c))
|
||||||
bool getIncrement()
|
|
||||||
{
|
{
|
||||||
if(!isDigit(c)){return false;}
|
setError("While scanning a block scalar", startMark,
|
||||||
increment = to!int(""d ~ c);
|
buildMsg("expected chomping or indentation indicator, but found ", c),
|
||||||
enforce(increment != 0,
|
reader_.mark);
|
||||||
new Error("While scanning a block scalar", startMark,
|
return tuple(Chomping.init, int.max);
|
||||||
"expected indentation indicator in range 1-9, but found 0",
|
|
||||||
reader_.mark));
|
|
||||||
reader_.forward();
|
|
||||||
c = reader_.peek();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///Indicators can be in any order.
|
|
||||||
if(getChomping()) {getIncrement();}
|
|
||||||
else if(getIncrement()){getChomping();}
|
|
||||||
|
|
||||||
enforce(" \0\n\r\u0085\u2028\u2029"d.canFind(c),
|
|
||||||
new Error("While scanning a block scalar", startMark,
|
|
||||||
"expected chomping or indentation indicator, but found "
|
|
||||||
~ to!string(c), reader_.mark));
|
|
||||||
|
|
||||||
return tuple(chomping, increment);
|
return tuple(chomping, increment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get chomping indicator, if detected. Return false otherwise.
|
||||||
|
///
|
||||||
|
/// Used in scanBlockScalarIndicators.
|
||||||
|
///
|
||||||
|
/// Params:
|
||||||
|
///
|
||||||
|
/// c = The character that may be a chomping indicator.
|
||||||
|
/// chomping = Write the chomping value here, if detected.
|
||||||
|
bool getChomping(ref dchar c, ref Chomping chomping) @safe pure nothrow @nogc
|
||||||
|
{
|
||||||
|
if(!"+-"d.canFind(c)) { return false; }
|
||||||
|
chomping = c == '+' ? Chomping.Keep : Chomping.Strip;
|
||||||
|
reader_.forward();
|
||||||
|
c = reader_.peek();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get increment indicator, if detected. Return false otherwise.
|
||||||
|
///
|
||||||
|
/// Used in scanBlockScalarIndicators.
|
||||||
|
///
|
||||||
|
/// Params:
|
||||||
|
///
|
||||||
|
/// c = The character that may be an increment indicator.
|
||||||
|
/// If an increment indicator is detected, this will be updated to
|
||||||
|
/// the next character in the Reader.
|
||||||
|
/// increment = Write the increment value here, if detected.
|
||||||
|
/// startMark = Mark for error messages.
|
||||||
|
bool getIncrement(ref dchar c, ref int increment, const Mark startMark)
|
||||||
|
@safe pure nothrow @nogc
|
||||||
|
{
|
||||||
|
if(!c.isDigit) { return false; }
|
||||||
|
// Convert a digit to integer.
|
||||||
|
increment = c - '0';
|
||||||
|
assert(increment < 10 && increment >= 0, "Digit has invalid value");
|
||||||
|
if(increment == 0)
|
||||||
|
{
|
||||||
|
setError("While scanning a block scalar", startMark,
|
||||||
|
"expected indentation indicator in range 1-9, but found 0",
|
||||||
|
reader_.mark);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
reader_.forward();
|
||||||
|
c = reader_.peek();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
///Scan (and ignore) ignored line in a block scalar.
|
///Scan (and ignore) ignored line in a block scalar.
|
||||||
void scanBlockScalarIgnoredLine(const Mark startMark) @safe pure
|
void scanBlockScalarIgnoredLine(const Mark startMark) @safe pure
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue