internal SyntaxToken ScanXmlString(char terminatingChar, char altTerminatingChar, bool isSingle)
{
var precedingTrivia = triviaListPool.Allocate<SyntaxNode>();
SyntaxToken result;
var Here = 0;
var scratch = GetScratch();
while (CanGetCharAtOffset(Here))
{
char c = PeekAheadChar(Here);
if (c == terminatingChar || c == altTerminatingChar)
{
if (Here > 0)
{
result = XmlMakeAttributeDataToken(precedingTrivia, Here, scratch);
goto CleanUp;
}
else
{
if (isSingle)
{
result = XmlMakeSingleQuoteToken(precedingTrivia, c, isOpening: false);
}
else
{
result = XmlMakeDoubleQuoteToken(precedingTrivia, c, isOpening: false);
}
goto CleanUp;
}
}
switch (c)
{
case UCH_CR:
case UCH_LF:
Here = SkipLineBreak(c, Here);
scratch.Append(UCH_SPACE);
result = XmlMakeAttributeDataToken(precedingTrivia, Here, scratch);
goto CleanUp;
case UCH_TAB:
scratch.Append(UCH_SPACE);
Here += 1;
break;
case '<':
// This cannot be in a string. terminate the string.
if (Here > 0)
{
result = XmlMakeAttributeDataToken(precedingTrivia, Here, scratch);
goto CleanUp;
}
else
{
var data = SyntaxFactory.MissingToken(SyntaxKind.SingleQuoteToken);
if (precedingTrivia.Count > 0)
{
data = ((SyntaxToken)data.WithLeadingTrivia(precedingTrivia.ToList().Node));
}
var errInfo = ErrorFactory.ErrorInfo(isSingle ? ERRID.ERR_ExpectedSQuote : ERRID.ERR_ExpectedQuote);
result = data;
////result = ((SyntaxToken)data.SetDiagnostics(new[]
////{
//// errInfo
////}));
goto CleanUp;
}
case '&':
if (Here > 0)
{
result = XmlMakeAttributeDataToken(precedingTrivia, Here, scratch);
goto CleanUp;
}
else
{
result = ScanXmlReference(precedingTrivia);
goto CleanUp;
}
default:
var xmlCh = ScanXmlChar(Here);
if (xmlCh.Length == 0)
{
// bad char
if (Here > 0)
{
result = XmlMakeAttributeDataToken(precedingTrivia, Here, scratch);
goto CleanUp;
}
else
{
result = XmlMakeBadToken(precedingTrivia, 1, ERRID.ERR_IllegalChar);
goto CleanUp;
}
}
xmlCh.AppendTo(scratch);
Here += xmlCh.Length;
break;
}
}
// no more chars
if (Here > 0)
{
result = XmlMakeAttributeDataToken(precedingTrivia, Here, scratch);
goto CleanUp;
}
else
{
result = MakeEofToken(precedingTrivia);
goto CleanUp;
}
CleanUp:
triviaListPool.Free(precedingTrivia);
return result;
}