directiveToken no longer stores multiple values by zero-separating.
This commit is contained in:
parent
b5259e6ada
commit
db7fecf960
|
@ -346,23 +346,20 @@ final class Parser
|
||||||
while(scanner_.checkToken(TokenID.Directive))
|
while(scanner_.checkToken(TokenID.Directive))
|
||||||
{
|
{
|
||||||
immutable token = scanner_.getToken();
|
immutable token = scanner_.getToken();
|
||||||
//Name and value are separated by '\0'.
|
const value = token.value;
|
||||||
const parts = token.value.split("\0");
|
if(token.directive == DirectiveType.YAML)
|
||||||
const name = parts[0];
|
|
||||||
if(name == "YAML")
|
|
||||||
{
|
{
|
||||||
enforce(YAMLVersion_ is null,
|
enforce(YAMLVersion_ is null,
|
||||||
new Error("Duplicate YAML directive", token.startMark));
|
new Error("Duplicate YAML directive", token.startMark));
|
||||||
const minor = parts[1].split(".")[0];
|
const minor = value.split(".")[0];
|
||||||
enforce(minor == "1",
|
enforce(minor == "1",
|
||||||
new Error("Incompatible document (version 1.x is required)",
|
new Error("Incompatible document (version 1.x is required)",
|
||||||
token.startMark));
|
token.startMark));
|
||||||
YAMLVersion_ = parts[1];
|
YAMLVersion_ = value;
|
||||||
}
|
}
|
||||||
else if(name == "TAG")
|
else if(token.directive == DirectiveType.TAG)
|
||||||
{
|
{
|
||||||
assert(parts.length == 3, "Tag directive stored incorrectly in a token");
|
auto handle = value[0 .. token.valueDivider];
|
||||||
auto handle = parts[1];
|
|
||||||
|
|
||||||
foreach(ref pair; tagDirectives_)
|
foreach(ref pair; tagDirectives_)
|
||||||
{
|
{
|
||||||
|
@ -371,8 +368,10 @@ final class Parser
|
||||||
enforce(h != handle, new Error("Duplicate tag handle: " ~ handle,
|
enforce(h != handle, new Error("Duplicate tag handle: " ~ handle,
|
||||||
token.startMark));
|
token.startMark));
|
||||||
}
|
}
|
||||||
tagDirectives_ ~= TagDirective(handle, parts[2]);
|
tagDirectives_ ~= TagDirective(handle, value[token.valueDivider .. $]);
|
||||||
}
|
}
|
||||||
|
// Any other directive type is ignored (only YAML and TAG are in YAML
|
||||||
|
// 1.1/1.2, any other directives are "reserved")
|
||||||
}
|
}
|
||||||
|
|
||||||
TagDirective[] value = tagDirectives_;
|
TagDirective[] value = tagDirectives_;
|
||||||
|
|
|
@ -943,17 +943,28 @@ final class Scanner
|
||||||
throwIfError();
|
throwIfError();
|
||||||
}
|
}
|
||||||
const name = reader_.sliceBuilder.finish();
|
const name = reader_.sliceBuilder.finish();
|
||||||
const value = name == "YAML" ? scanYAMLDirectiveValue(startMark):
|
// Index where tag handle ends and suffix starts in a tag directive value.
|
||||||
name == "TAG" ? scanTagDirectiveValue(startMark) : "";
|
uint tagHandleEnd = uint.max;
|
||||||
|
const value = name == "YAML"d ? scanYAMLDirectiveValue(startMark):
|
||||||
|
name == "TAG"d ? scanTagDirectiveValue(startMark, tagHandleEnd) : "";
|
||||||
|
|
||||||
Mark endMark = reader_.mark;
|
Mark endMark = reader_.mark;
|
||||||
|
|
||||||
if(!["YAML"d, "TAG"d].canFind(name)) { scanToNextBreak(); }
|
DirectiveType directive;
|
||||||
|
if(name == "YAML"d) { directive = DirectiveType.YAML; }
|
||||||
|
else if(name == "TAG"d) { directive = DirectiveType.TAG; }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
directive = DirectiveType.Reserved;
|
||||||
|
scanToNextBreak();
|
||||||
|
}
|
||||||
|
|
||||||
scanDirectiveIgnoredLine(startMark);
|
scanDirectiveIgnoredLine(startMark);
|
||||||
throwIfError();
|
throwIfError();
|
||||||
|
|
||||||
//Storing directive name and value in a single string, separated by zero.
|
//Storing directive name and value in a single string, separated by zero.
|
||||||
return directiveToken(startMark, endMark, utf32To8(name ~ '\0' ~ value));
|
return directiveToken(startMark, endMark, utf32To8(value),
|
||||||
|
directive, tagHandleEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan name of a directive token.
|
/// Scan name of a directive token.
|
||||||
|
@ -1010,12 +1021,14 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan value of a tag directive.
|
/// Scan value of a tag directive.
|
||||||
dstring scanTagDirectiveValue(const Mark startMark) @safe pure
|
dstring scanTagDirectiveValue(const Mark startMark, ref uint handleLength)
|
||||||
|
@safe pure
|
||||||
{
|
{
|
||||||
findNextNonSpace();
|
findNextNonSpace();
|
||||||
const handle = scanTagDirectiveHandle(startMark);
|
const handle = scanTagDirectiveHandle(startMark);
|
||||||
findNextNonSpace();
|
findNextNonSpace();
|
||||||
return handle ~ '\0' ~ scanTagDirectivePrefix(startMark);
|
handleLength = cast(uint)handle.length;
|
||||||
|
return handle ~ scanTagDirectivePrefix(startMark);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scan handle of a tag directive.
|
///Scan handle of a tag directive.
|
||||||
|
|
|
@ -98,12 +98,15 @@ static assert(Token.sizeof <= 32, "Token has unexpected size");
|
||||||
|
|
||||||
/// Construct a directive token.
|
/// Construct a directive token.
|
||||||
///
|
///
|
||||||
/// Params: start = Start position of the token.
|
/// Params: start = Start position of the token.
|
||||||
/// end = End position of the token.
|
/// end = End position of the token.
|
||||||
/// value = Value of the token.
|
/// value = Value of the token.
|
||||||
Token directiveToken(const Mark start, const Mark end, const string value)
|
/// directive = Directive type (YAML or TAG in YAML 1.1).
|
||||||
|
Token directiveToken(const Mark start, const Mark end, const string value,
|
||||||
|
DirectiveType directive, const uint nameEnd)
|
||||||
{
|
{
|
||||||
return Token(value, start, end, TokenID.Directive);
|
return Token(value, start, end, TokenID.Directive, ScalarStyle.init, Encoding.init,
|
||||||
|
directive, nameEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a simple (no value) token with specified type.
|
/// Construct a simple (no value) token with specified type.
|
||||||
|
|
Loading…
Reference in a new issue