private bool ScanPreProcessorDirective(bool stopAtEndOfLine, bool insideExcludedBlock, bool atTopLevel)
{
bool exclude = insideExcludedBlock;
int savedStartPos = this.startPos;
int i = this.startPos - 1;
while (i > 0 && Scanner.IsBlankSpace(this.GetChar(i)))
{
i--;
}
if (i > 0 && !this.IsLineTerminator(this.GetChar(i), 0))
{
this.HandleError(Error.BadDirectivePlacement);
goto skipToEndOfLine;
}
this.SkipBlanks(); //Check EOL/EOF?
this.startPos = this.endPos - 1;
this.ScanIdentifier();
switch (this.GetIdentifierString())
{
case "define":
if (insideExcludedBlock) goto skipToEndOfLine;
if (stopAtEndOfLine) break;
if (!this.allowPPDefinitions)
{
this.HandleError(Error.PPDefFollowsToken);
goto skipToEndOfLine;
}
this.startPos = this.endPos;
char chr = this.SkipBlanks();
if (this.IsEndLineOrEOF(chr, 0))
{
this.HandleError(Error.ExpectedIdentifier);
break;
}
this.identifier.Length = 0;
this.endPos--;
this.startPos = this.endPos;
if (!this.IsIdentifierStartChar(chr))
this.HandleError(Error.ExpectedIdentifier);
else
{
this.ScanIdentifier();
if (this.PreprocessorDefinedSymbols == null)
this.PreprocessorDefinedSymbols = new Hashtable();
string s = this.GetIdentifierString();
if (s == "true" || s == "false" || !this.IsIdentifierStartChar(s[0]))
{
this.HandleError(Error.ExpectedIdentifier);
goto skipToEndOfLine;
}
else
this.PreprocessorDefinedSymbols[s] = s;
}
break;
case "undef":
if (insideExcludedBlock) goto skipToEndOfLine;
if (stopAtEndOfLine) break;
if (!this.allowPPDefinitions)
{
this.HandleError(Error.PPDefFollowsToken);
goto skipToEndOfLine;
}
this.startPos = this.endPos;
chr = this.SkipBlanks();
if (this.IsEndLineOrEOF(chr, 0))
{
this.HandleError(Error.ExpectedIdentifier);
break;
}
this.identifier.Length = 0;
this.endPos--;
this.startPos = this.endPos;
if (!this.IsIdentifierStartChar(chr))
this.HandleError(Error.ExpectedIdentifier);
else
{
this.ScanIdentifier();
if (this.PreprocessorDefinedSymbols == null)
{
this.PreprocessorDefinedSymbols = new Hashtable();
this.PreprocessorDefinedSymbols["true"] = "true";
}
string s = this.GetIdentifierString();
if (s == "true" || s == "false" || !this.IsIdentifierStartChar(s[0]))
{
this.HandleError(Error.ExpectedIdentifier);
goto skipToEndOfLine;
}
else
this.PreprocessorDefinedSymbols[s] = null;
}
break;
case "if":
if (insideExcludedBlock)
{
this.endIfCount++;
goto skipToEndOfLine;
}
if (stopAtEndOfLine) break;
char c = (char)0;
exclude = !this.ScanPPExpression(ref c);
if (!exclude) this.includeCount++;
this.endIfCount++;
if (this.IsEndLineOrEOF(c, 0)) return exclude;
break;
case "elif":
if (insideExcludedBlock && !atTopLevel) goto skipToEndOfLine;
if (stopAtEndOfLine) break;
if (this.elseCount == this.endIfCount)
{
this.HandleError(Error.UnexpectedDirective);
goto skipToEndOfLine;
}
c = (char)0;
exclude = !this.ScanPPExpression(ref c);
if (this.includeCount == this.endIfCount)
{
exclude = true;
break;
}
if (!exclude) this.includeCount++;
if (this.IsEndLineOrEOF(c, 0)) return exclude;
break;
case "else":
if (insideExcludedBlock && !atTopLevel) goto skipToEndOfLine;
if (stopAtEndOfLine) break;
if (this.elseCount == this.endIfCount)
{
this.HandleError(Error.UnexpectedDirective);
goto skipToEndOfLine;
}
this.elseCount++;
if (this.includeCount == this.endIfCount)
{
exclude = true;
break;
}
exclude = false;
this.includeCount++;
break;
case "endif":
if (stopAtEndOfLine) break;
if (this.endIfCount <= 0)
{
this.endIfCount = 0;
this.HandleError(Error.UnexpectedDirective);
goto skipToEndOfLine;
}
this.elseCount = this.includeCount = --this.endIfCount;
break;
case "line":
if (insideExcludedBlock) goto skipToEndOfLine;
if (stopAtEndOfLine) break;
c = this.SkipBlanks();
int lnum = -1;
if ('0' <= c && c <= '9')
{
this.startPos = --this.endPos;
while ('0' <= (c = this.GetChar(++this.endPos)) && c <= '9') ;
try
{
lnum = int.Parse(this.GetTokenSource(), CultureInfo.InvariantCulture);
if (lnum <= 0)
{
this.startPos = this.endPos;
this.HandleError(Error.InvalidLineNumber);
goto skipToEndOfLine;
}
else if (this.IsEndLineOrEOF(c, 0))
goto setLineInfo;
}
catch (OverflowException)
{
this.startPos++;
this.HandleError(Error.IntOverflow);
goto skipToEndOfLine;
}
}
else
{
this.startPos = this.endPos - 1;
this.ScanIdentifier();
if (this.startPos != this.endPos - 1)
{
string str = this.GetIdentifierString();
if (str == "default")
{
this.document = this.originalDocument;
break;
}
if (str == "hidden")
{
this.document = new Document(this.document.Name, this.document.LineNumber, this.document.Text, this.document.DocumentType, this.document.Language, this.document.LanguageVendor);
this.document.Hidden = true;
break;
}
}
this.HandleError(Error.InvalidLineNumber);
goto skipToEndOfLine;
}
c = this.SkipBlanks();
this.startPos = this.endPos - 1;
if (c == '/')
{
if (this.GetChar(this.endPos) == '/')
{
this.endPos--;
goto setLineInfo;
}
else
{
this.startPos = this.endPos - 1;
this.HandleError(Error.EndOfPPLineExpected);
goto skipToEndOfLine;
}
}
if (c == '"')
{
while ((c = this.GetChar(this.endPos++)) != '"' && !this.IsEndLineOrEOF(c, 0)) ;
if (c != '"')
{
this.HandleError(Error.MissingPPFile);
goto skipToEndOfLine;
}
this.startPos++;
this.endPos--;
string filename = this.GetTokenSource();
this.endPos++;
this.document = new Document(filename, 1, this.document.Text, this.document.DocumentType, this.document.Language, this.document.LanguageVendor);
}
else if (!this.IsEndLineOrEOF(c, 0))
{
this.HandleError(Error.MissingPPFile);
goto skipToEndOfLine;
}
setLineInfo:
this.document = new Document(this.document.Name, 1, this.document.Text, this.document.DocumentType, this.document.Language, this.document.LanguageVendor);
int offset = lnum - this.document.GetLine(this.startPos);
this.document.LineNumber = offset;
if (this.IsEndLineOrEOF(c, 0)) return exclude;
break;
case "error":
if (insideExcludedBlock) goto skipToEndOfLine;
if (stopAtEndOfLine) break;
this.SkipBlanks();
this.startPos = --this.endPos;
this.ScanString((char)0);
this.HandleError(Error.ErrorDirective, this.unescapedString);
break;
case "warning":
if (insideExcludedBlock) goto skipToEndOfLine;
if (stopAtEndOfLine) break;
this.SkipBlanks();
this.startPos = --this.endPos;
this.ScanString((char)0);
this.HandleError(Error.WarningDirective, this.unescapedString);
break;
case "region":
if (insideExcludedBlock) goto skipToEndOfLine;
if (stopAtEndOfLine) break;
this.endRegionCount++;
goto skipToEndOfLine;
case "endregion":
if (insideExcludedBlock) goto skipToEndOfLine;
if (stopAtEndOfLine) break;
if (this.endRegionCount <= 0)
this.HandleError(Error.UnexpectedDirective);
else
this.endRegionCount--;
goto skipToEndOfLine;
default:
if (insideExcludedBlock) goto skipToEndOfLine;
if (stopAtEndOfLine)
{
this.endPos = this.startPos;
break;
}
this.HandleError(Error.PPDirectiveExpected);
goto skipToEndOfLine;
}
if (stopAtEndOfLine)
{
this.startPos = savedStartPos;
return false;
}
char ch = this.SkipBlanks();
if (this.IsEndLineOrEOF(ch, 0)) return exclude;
if (ch == '/' && (ch = this.GetChar(this.endPos++)) == '/') goto skipToEndOfLine;
this.startPos = this.endPos - 1;
this.HandleError(Error.EndOfPPLineExpected);
skipToEndOfLine:
this.SkipSingleLineComment();
return exclude;
}