private bool Directive_Define()
{
idToken token, t;
ScriptDefinition define;
if ((token = ReadLine()) == null)
{
Error("#define without name");
return(false);
}
else if (token.Type != TokenType.Name)
{
UnreadSourceToken(token);
Error("expected name after #define, found '{0}'", token.ToString());
return(false);
}
// check if the define already exists
if (_defineDict.TryGetValue(token.ToString(), out define) == true)
{
if ((define.Flags & DefineFlags.Fixed) == DefineFlags.Fixed)
{
Error("can't redefine '{0}'", token.ToString());
return(false);
}
Warning("redefinition of '{0}'", token.ToString());
// unread the define name before executing the #undef directive
UnreadSourceToken(token);
if (Directive_UnDefine() == false)
{
return(false);
}
// if the define was not removed (define->flags & DEFINE_FIXED)
define = _defineDict[token.ToString()];
}
// allocate define
define = new ScriptDefinition();
define.Name = token.ToString();
define.Parameters = new idToken[] { };
define.Tokens = new idToken[] { };
// add the define to the source
AddDefineToHash(define, _defineDict);
// if nothing is defined, just return
if ((token = ReadLine()) == null)
{
return(true);
}
// if it is a define with parameters
if ((token.WhiteSpaceBeforeToken == 0) && (token.ToString() == "("))
{
List <idToken> parameters = new List <idToken>();
// read the define parameters
if (CheckTokenString(")") == false)
{
while (true)
{
if ((token = ReadLine()) == null)
{
Error("expected define parameter");
return(false);
}
// if it isn't a name
else if (token.Type != TokenType.Name)
{
Error("invalid define parameter");
return(false);
}
else if (FindDefineParameter(define, token.ToString()) >= 0)
{
Error("two of the same define parameters");
return(false);
}
// add the define parm
t = new idToken(token);
t.ClearTokenWhiteSpace();
parameters.Add(t);
// read next token
if ((token = ReadLine()) == null)
{
Error("define parameters not terminated");
return(false);
}
if (token.ToString() == ")")
{
break;
}
// then it must be a comma
if (token.ToString() != ",")
{
Error("define not terminated");
return(false);
}
}
}
define.Parameters = parameters.ToArray();
if ((token = ReadLine()) == null)
{
return(true);
}
}
List <idToken> tokens = new List <idToken>();
do
{
t = new idToken(token);
if ((t.Type == TokenType.Name) && (t.ToString() == define.Name))
{
t.Flags |= TokenFlags.RecursiveDefine;
Warning("recursive define (removed recursion)");
}
t.ClearTokenWhiteSpace();
tokens.Add(t);
}while((token = ReadLine()) != null);
define.Tokens = tokens.ToArray();
if (define.Tokens.Length > 0)
{
// check for merge operators at the beginning or end
if ((define.Tokens[0].ToString() == "##") || (define.Tokens[define.Tokens.Length - 1].ToString() == "##"))
{
Error("define with misplaced ##");
return(false);
}
}
return(true);
}