mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-17 01:32:19 +00:00
6227906072
some changes to the MAPINFO parser which tried to access the texture manager to check if the level name patches exist. That check had to be moved to where the intermission screen is set up. - Fixed: 'bloodcolor' ignored the first parameter value when given a list of integers. Please note that this creates an incompatibility between old and new versions so if you want to create something that works with both 2.2.0 and current versions better use the string format version for the color parameter! - Rewrote the DECORATE property parser so that the parser is completely separated from the property handlers. This should allow reuse of all the handler code for a new format if Doomscript requires one. - Fixed: PClass::InitializeActorInfo copied too many bytes if a subclass's defaults were larger than the parent's. - Moved A_ChangeFlag to thingdef_codeptr.cpp. - Moved translation related code from thingdef_properties.cpp to r_translate.cpp and rewrote the translation parser to use FScanner instead of strtol. - replaced DECORATE's 'alpha default' by 'defaultalpha' for consistency. Since this was never used outside zdoom.pk3 it's not critical. - Removed support for game specific pickup messages because the only thing this was ever used for - Raven's invulnerability item - has already been split up into a Heretic and Hexen version. SVN r1240 (trunk)
1012 lines
22 KiB
C++
1012 lines
22 KiB
C++
|
|
//**************************************************************************
|
|
//**
|
|
//** sc_man.c : Heretic 2 : Raven Software, Corp.
|
|
//**
|
|
//** $RCSfile: sc_man.c,v $
|
|
//** $Revision: 1.3 $
|
|
//** $Date: 96/01/06 03:23:43 $
|
|
//** $Author: bgokey $
|
|
//**
|
|
//**************************************************************************
|
|
|
|
// HEADER FILES ------------------------------------------------------------
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "doomtype.h"
|
|
#include "i_system.h"
|
|
#include "sc_man.h"
|
|
#include "w_wad.h"
|
|
#include "cmdlib.h"
|
|
#include "m_misc.h"
|
|
#include "templates.h"
|
|
|
|
// MACROS ------------------------------------------------------------------
|
|
|
|
// TYPES -------------------------------------------------------------------
|
|
|
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
|
|
|
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
|
|
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
|
|
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
|
|
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
|
|
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
|
|
|
// CODE --------------------------------------------------------------------
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner Constructor
|
|
//
|
|
//==========================================================================
|
|
|
|
FScanner::FScanner()
|
|
{
|
|
ScriptOpen = false;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner Destructor
|
|
//
|
|
//==========================================================================
|
|
|
|
FScanner::~FScanner()
|
|
{
|
|
// Humm... Nothing to do in here.
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner Copy Constructor
|
|
//
|
|
//==========================================================================
|
|
|
|
FScanner::FScanner(const FScanner &other)
|
|
{
|
|
ScriptOpen = false;
|
|
*this = other;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner OpenLumpNum Constructor
|
|
//
|
|
//==========================================================================
|
|
|
|
FScanner::FScanner(int lumpnum)
|
|
{
|
|
ScriptOpen = false;
|
|
OpenLumpNum(lumpnum);
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: operator =
|
|
//
|
|
//==========================================================================
|
|
|
|
FScanner &FScanner::operator=(const FScanner &other)
|
|
{
|
|
if (this == &other)
|
|
{
|
|
return *this;
|
|
}
|
|
if (!other.ScriptOpen)
|
|
{
|
|
Close();
|
|
return *this;
|
|
}
|
|
|
|
// Copy protected members
|
|
ScriptOpen = true;
|
|
ScriptName = other.ScriptName;
|
|
ScriptBuffer = other.ScriptBuffer;
|
|
ScriptPtr = other.ScriptPtr;
|
|
ScriptEndPtr = other.ScriptEndPtr;
|
|
AlreadyGot = other.AlreadyGot;
|
|
AlreadyGotLine = other.AlreadyGotLine;
|
|
LastGotToken = other.LastGotToken;
|
|
LastGotPtr = other.LastGotPtr;
|
|
LastGotLine = other.LastGotLine;
|
|
CMode = other.CMode;
|
|
Escape = other.Escape;
|
|
|
|
// Copy public members
|
|
if (other.String == other.StringBuffer)
|
|
{
|
|
memcpy(StringBuffer, other.StringBuffer, sizeof(StringBuffer));
|
|
BigStringBuffer = "";
|
|
String = StringBuffer;
|
|
}
|
|
else
|
|
{
|
|
// Past practice means the string buffer must be writeable, which
|
|
// removes some of the benefit from using an FString to store
|
|
// the big string buffer.
|
|
BigStringBuffer = other.BigStringBuffer;
|
|
String = BigStringBuffer.LockBuffer();
|
|
}
|
|
StringLen = other.StringLen;
|
|
TokenType = other.TokenType;
|
|
Number = other.Number;
|
|
Float = other.Float;
|
|
Name = other.Name;
|
|
Line = other.Line;
|
|
End = other.End;
|
|
Crossed = other.Crossed;
|
|
|
|
return *this;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: Open
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::Open (const char *name)
|
|
{
|
|
int lump = Wads.CheckNumForFullName(name, true);
|
|
if (lump == -1)
|
|
{
|
|
I_Error("Could not find script lump '%s'\n", name);
|
|
}
|
|
OpenLumpNum(lump);
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: OpenFile
|
|
//
|
|
// Loads a script from a file. Uses new/delete for memory allocation.
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::OpenFile (const char *name)
|
|
{
|
|
BYTE *filebuf;
|
|
int filesize;
|
|
|
|
Close ();
|
|
filesize = M_ReadFile (name, &filebuf);
|
|
ScriptBuffer = FString((const char *)filebuf, filesize);
|
|
delete[] filebuf;
|
|
ScriptName = name; // This is used for error messages so the full file name is preferable
|
|
LumpNum = -1;
|
|
PrepareScript ();
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: OpenMem
|
|
//
|
|
// Prepares a script that is already in memory for parsing. The memory is
|
|
// copied, so you can do whatever you want with it after opening it.
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::OpenMem (const char *name, const char *buffer, int size)
|
|
{
|
|
Close ();
|
|
ScriptBuffer = FString(buffer, size);
|
|
ScriptName = name;
|
|
LumpNum = -1;
|
|
PrepareScript ();
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: OpenLumpNum
|
|
//
|
|
// Loads a script from the lump directory
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner :: OpenLumpNum (int lump)
|
|
{
|
|
Close ();
|
|
{
|
|
FMemLump mem = Wads.ReadLump(lump);
|
|
ScriptBuffer = mem.GetString();
|
|
}
|
|
ScriptName = Wads.GetLumpFullPath(lump);
|
|
LumpNum = lump;
|
|
PrepareScript ();
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: PrepareScript
|
|
//
|
|
// Prepares a script for parsing.
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::PrepareScript ()
|
|
{
|
|
// The scanner requires the file to end with a '\n', so add one if
|
|
// it doesn't already.
|
|
if (ScriptBuffer.Len() == 0 || ScriptBuffer[ScriptBuffer.Len() - 1] != '\n')
|
|
{
|
|
// If the last character in the buffer is a null character, change
|
|
// it to a newline. Otherwise, append a newline to the end.
|
|
if (ScriptBuffer[ScriptBuffer.Len() - 1] == '\0')
|
|
{
|
|
ScriptBuffer.LockBuffer()[ScriptBuffer.Len() - 1] = '\n';
|
|
ScriptBuffer.UnlockBuffer();
|
|
}
|
|
else
|
|
{
|
|
ScriptBuffer += '\n';
|
|
}
|
|
}
|
|
|
|
ScriptPtr = &ScriptBuffer[0];
|
|
ScriptEndPtr = &ScriptBuffer[ScriptBuffer.Len()];
|
|
Line = 1;
|
|
End = false;
|
|
ScriptOpen = true;
|
|
String = StringBuffer;
|
|
AlreadyGot = false;
|
|
LastGotToken = false;
|
|
LastGotPtr = NULL;
|
|
LastGotLine = 1;
|
|
CMode = false;
|
|
Escape = true;
|
|
StringBuffer[0] = '\0';
|
|
BigStringBuffer = "";
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: Close
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::Close ()
|
|
{
|
|
ScriptOpen = false;
|
|
ScriptBuffer = "";
|
|
BigStringBuffer = "";
|
|
StringBuffer[0] = '\0';
|
|
String = StringBuffer;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: SavePos
|
|
//
|
|
// Saves the current script location for restoration later
|
|
//
|
|
//==========================================================================
|
|
|
|
const FScanner::SavedPos FScanner::SavePos ()
|
|
{
|
|
SavedPos pos;
|
|
|
|
CheckOpen ();
|
|
if (End)
|
|
{
|
|
pos.SavedScriptPtr = NULL;
|
|
}
|
|
else
|
|
{
|
|
pos.SavedScriptPtr = ScriptPtr;
|
|
}
|
|
pos.SavedScriptLine = Line;
|
|
return pos;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: RestorePos
|
|
//
|
|
// Restores the previously saved script location
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::RestorePos (const FScanner::SavedPos &pos)
|
|
{
|
|
if (pos.SavedScriptPtr)
|
|
{
|
|
ScriptPtr = pos.SavedScriptPtr;
|
|
Line = pos.SavedScriptLine;
|
|
End = false;
|
|
}
|
|
else
|
|
{
|
|
End = true;
|
|
}
|
|
AlreadyGot = false;
|
|
LastGotToken = false;
|
|
Crossed = false;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: SetCMode
|
|
//
|
|
// Enables/disables C mode. In C mode, more characters are considered to
|
|
// be whole words than in non-C mode.
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::SetCMode (bool cmode)
|
|
{
|
|
CMode = cmode;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: SetEscape
|
|
//
|
|
// Turns the escape sequence \" in strings on or off. If it's off, that
|
|
// means you can't include quotation marks inside strings.
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::SetEscape (bool esc)
|
|
{
|
|
Escape = esc;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner::ScanString
|
|
//
|
|
// Set tokens true if you want TokenType to be set.
|
|
//
|
|
//==========================================================================
|
|
|
|
bool FScanner::ScanString (bool tokens)
|
|
{
|
|
const char *marker, *tok;
|
|
bool return_val;
|
|
|
|
CheckOpen();
|
|
if (AlreadyGot)
|
|
{
|
|
AlreadyGot = false;
|
|
if (!tokens || LastGotToken)
|
|
{
|
|
return true;
|
|
}
|
|
ScriptPtr = LastGotPtr;
|
|
Line = LastGotLine;
|
|
}
|
|
|
|
Crossed = false;
|
|
if (ScriptPtr >= ScriptEndPtr)
|
|
{
|
|
End = true;
|
|
return false;
|
|
}
|
|
|
|
LastGotPtr = ScriptPtr;
|
|
LastGotLine = Line;
|
|
|
|
// In case the generated scanner does not use marker, avoid compiler warnings.
|
|
marker;
|
|
#include "sc_man_scanner.h"
|
|
LastGotToken = tokens;
|
|
return return_val;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: GetString
|
|
//
|
|
//==========================================================================
|
|
|
|
bool FScanner::GetString ()
|
|
{
|
|
return ScanString (false);
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: MustGetString
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::MustGetString (void)
|
|
{
|
|
if (FScanner::GetString() == false)
|
|
{
|
|
ScriptError ("Missing string (unexpected end of file).");
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: MustGetStringName
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::MustGetStringName (const char *name)
|
|
{
|
|
MustGetString ();
|
|
if (Compare (name) == false)
|
|
{
|
|
ScriptError ("Expected '%s', got '%s'.", name, String);
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: CheckString
|
|
//
|
|
// Checks if the next token matches the specified string. Returns true if
|
|
// it does. If it doesn't, it ungets it and returns false.
|
|
//
|
|
//==========================================================================
|
|
|
|
bool FScanner::CheckString (const char *name)
|
|
{
|
|
if (GetString ())
|
|
{
|
|
if (Compare (name))
|
|
{
|
|
return true;
|
|
}
|
|
UnGet ();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: GetToken
|
|
//
|
|
// Sets sc_Float, sc_Number, and sc_Name based on sc_TokenType.
|
|
//
|
|
//==========================================================================
|
|
|
|
bool FScanner::GetToken ()
|
|
{
|
|
if (ScanString (true))
|
|
{
|
|
if (TokenType == TK_NameConst)
|
|
{
|
|
Name = FName(String);
|
|
}
|
|
else if (TokenType == TK_IntConst)
|
|
{
|
|
char *stopper;
|
|
Number = strtol(String, &stopper, 0);
|
|
Float = Number;
|
|
}
|
|
else if (TokenType == TK_FloatConst)
|
|
{
|
|
char *stopper;
|
|
Float = strtod(String, &stopper);
|
|
}
|
|
else if (TokenType == TK_StringConst)
|
|
{
|
|
StringLen = strbin(String);
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: MustGetAnyToken
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::MustGetAnyToken (void)
|
|
{
|
|
if (GetToken () == false)
|
|
{
|
|
ScriptError ("Missing token (unexpected end of file).");
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: TokenMustBe
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::TokenMustBe (int token)
|
|
{
|
|
if (TokenType != token)
|
|
{
|
|
FString tok1 = TokenName(token);
|
|
FString tok2 = TokenName(TokenType, String);
|
|
ScriptError ("Expected %s but got %s instead.", tok1.GetChars(), tok2.GetChars());
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: MustGetToken
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::MustGetToken (int token)
|
|
{
|
|
MustGetAnyToken ();
|
|
TokenMustBe(token);
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: CheckToken
|
|
//
|
|
// Checks if the next token matches the specified token. Returns true if
|
|
// it does. If it doesn't, it ungets it and returns false.
|
|
//
|
|
//==========================================================================
|
|
|
|
bool FScanner::CheckToken (int token)
|
|
{
|
|
if (GetToken ())
|
|
{
|
|
if (TokenType == token)
|
|
{
|
|
return true;
|
|
}
|
|
UnGet ();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: GetNumber
|
|
//
|
|
//==========================================================================
|
|
|
|
bool FScanner::GetNumber ()
|
|
{
|
|
char *stopper;
|
|
|
|
CheckOpen();
|
|
if (GetString())
|
|
{
|
|
if (strcmp (String, "MAXINT") == 0)
|
|
{
|
|
Number = INT_MAX;
|
|
}
|
|
else
|
|
{
|
|
Number = strtol (String, &stopper, 0);
|
|
if (*stopper != 0)
|
|
{
|
|
ScriptError ("SC_GetNumber: Bad numeric constant \"%s\".", String);
|
|
}
|
|
}
|
|
Float = (float)Number;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: MustGetNumber
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::MustGetNumber ()
|
|
{
|
|
if (GetNumber() == false)
|
|
{
|
|
ScriptError ("Missing integer (unexpected end of file).");
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: CheckNumber
|
|
//
|
|
// similar to GetNumber but ungets the token if it isn't a number
|
|
// and does not print an error
|
|
//
|
|
//==========================================================================
|
|
|
|
bool FScanner::CheckNumber ()
|
|
{
|
|
char *stopper;
|
|
|
|
if (GetString())
|
|
{
|
|
if (String[0] == 0)
|
|
{
|
|
UnGet();
|
|
return false;
|
|
}
|
|
else if (strcmp (String, "MAXINT") == 0)
|
|
{
|
|
Number = INT_MAX;
|
|
}
|
|
else
|
|
{
|
|
Number = strtol (String, &stopper, 0);
|
|
if (*stopper != 0)
|
|
{
|
|
UnGet();
|
|
return false;
|
|
}
|
|
}
|
|
Float = (float)Number;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: CheckFloat
|
|
//
|
|
// [GRB] Same as SC_CheckNumber, only for floats
|
|
//
|
|
//==========================================================================
|
|
|
|
bool FScanner::CheckFloat ()
|
|
{
|
|
char *stopper;
|
|
|
|
if (GetString())
|
|
{
|
|
if (String[0] == 0)
|
|
{
|
|
UnGet();
|
|
return false;
|
|
}
|
|
|
|
Float = strtod (String, &stopper);
|
|
if (*stopper != 0)
|
|
{
|
|
UnGet();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: GetFloat
|
|
//
|
|
//==========================================================================
|
|
|
|
bool FScanner::GetFloat ()
|
|
{
|
|
char *stopper;
|
|
|
|
CheckOpen ();
|
|
if (GetString())
|
|
{
|
|
Float = (float)strtod (String, &stopper);
|
|
if (*stopper != 0)
|
|
{
|
|
I_Error ("SC_GetFloat: Bad numeric constant \"%s\".\n"
|
|
"Script %s, Line %d\n", String, ScriptName.GetChars(), Line);
|
|
}
|
|
Number = (int)Float;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: MustGetFloat
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::MustGetFloat ()
|
|
{
|
|
if (GetFloat() == false)
|
|
{
|
|
ScriptError ("Missing floating-point number (unexpected end of file).");
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: UnGet
|
|
//
|
|
// Assumes there is a valid string in String.
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::UnGet ()
|
|
{
|
|
AlreadyGot = true;
|
|
AlreadyGotLine = LastGotLine; // in case of an error we want the line of the last token.
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: MatchString
|
|
//
|
|
// Returns the index of the first match to String from the passed
|
|
// array of strings, or -1 if not found.
|
|
//
|
|
//==========================================================================
|
|
|
|
int FScanner::MatchString (const char **strings)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; *strings != NULL; i++)
|
|
{
|
|
if (Compare (*strings++))
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: MustMatchString
|
|
//
|
|
//==========================================================================
|
|
|
|
int FScanner::MustMatchString (const char **strings)
|
|
{
|
|
int i;
|
|
|
|
i = MatchString (strings);
|
|
if (i == -1)
|
|
{
|
|
ScriptError (NULL);
|
|
}
|
|
return i;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: Compare
|
|
//
|
|
//==========================================================================
|
|
|
|
bool FScanner::Compare (const char *text)
|
|
{
|
|
return (stricmp (text, String) == 0);
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: TokenName
|
|
//
|
|
// Returns the name of a token.
|
|
//
|
|
//==========================================================================
|
|
|
|
FString FScanner::TokenName (int token, const char *string)
|
|
{
|
|
static const char *const names[] =
|
|
{
|
|
"identifier",
|
|
"string constant",
|
|
"name constant",
|
|
"integer constant",
|
|
"float constant",
|
|
"'...'",
|
|
"'>>='",
|
|
"'<<='",
|
|
"'+='",
|
|
"'-='",
|
|
"'*='",
|
|
"'/='",
|
|
"'%='",
|
|
"'&='",
|
|
"'^='",
|
|
"'|='",
|
|
"'>>'",
|
|
"'>>>'",
|
|
"'<<'",
|
|
"'++'",
|
|
"'--'",
|
|
"'&&'",
|
|
"'||'",
|
|
"'<='",
|
|
"'>='",
|
|
"'=='",
|
|
"'!='",
|
|
"'action'",
|
|
"'break'",
|
|
"'case'",
|
|
"'const'",
|
|
"'continue'",
|
|
"'default'",
|
|
"'do'",
|
|
"'else'",
|
|
"'for'",
|
|
"'if'",
|
|
"'return'",
|
|
"'states'",
|
|
"'switch'",
|
|
"'until'",
|
|
"'while'",
|
|
"'bool'",
|
|
"'float'",
|
|
"'double'",
|
|
"'char'",
|
|
"'byte'",
|
|
"'sbyte'",
|
|
"'short'",
|
|
"'ushort'",
|
|
"'int'",
|
|
"'uint'",
|
|
"'long'",
|
|
"'ulong'",
|
|
"'void'",
|
|
"'struct'",
|
|
"'class'",
|
|
"'mode'",
|
|
"'enum'",
|
|
"'name'",
|
|
"'string'",
|
|
"'sound'",
|
|
"'state'",
|
|
"'color'",
|
|
"'goto'",
|
|
"'abstract'",
|
|
"'foreach'",
|
|
"'true'",
|
|
"'false'",
|
|
"'none'",
|
|
"'new'",
|
|
"'instanceof'",
|
|
"'auto'",
|
|
"'exec'",
|
|
"'defaultproperties'",
|
|
"'native'",
|
|
"'out'",
|
|
"'ref'",
|
|
"'event'",
|
|
"'static'",
|
|
"'transient'",
|
|
"'volatile'",
|
|
"'final'",
|
|
"'throws'",
|
|
"'extends'",
|
|
"'public'",
|
|
"'protected'",
|
|
"'private'",
|
|
"'dot'",
|
|
"'cross'",
|
|
"'ignores'",
|
|
"'localized'",
|
|
"'latent'",
|
|
"'singular'",
|
|
"'config'",
|
|
"'coerce'",
|
|
"'iterator'",
|
|
"'optional'",
|
|
"'export'",
|
|
"'virtual'",
|
|
"'super'",
|
|
"'global'",
|
|
"'self'",
|
|
"'stop'",
|
|
"'pickup'",
|
|
"'breakable'",
|
|
"'projectile'",
|
|
"'#include'",
|
|
};
|
|
|
|
FString work;
|
|
|
|
if (token > ' ' && token < 256)
|
|
{
|
|
work = '\'';
|
|
work += token;
|
|
work += '\'';
|
|
}
|
|
else if (token >= TK_Identifier && token < TK_LastToken)
|
|
{
|
|
work = names[token - TK_Identifier];
|
|
if (string != NULL && token >= TK_Identifier && token <= TK_FloatConst)
|
|
{
|
|
work += ' ';
|
|
char quote = (token == TK_StringConst) ? '"' : '\'';
|
|
work += quote;
|
|
work += string;
|
|
work += quote;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FString work;
|
|
work.Format ("Unknown(%d)", token);
|
|
return work;
|
|
}
|
|
return work;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner::ScriptError
|
|
//
|
|
//==========================================================================
|
|
|
|
void STACK_ARGS FScanner::ScriptError (const char *message, ...)
|
|
{
|
|
FString composed;
|
|
|
|
if (message == NULL)
|
|
{
|
|
composed = "Bad syntax.";
|
|
}
|
|
else
|
|
{
|
|
va_list arglist;
|
|
va_start (arglist, message);
|
|
composed.VFormat (message, arglist);
|
|
va_end (arglist);
|
|
}
|
|
|
|
I_Error ("Script error, \"%s\" line %d:\n%s\n", ScriptName.GetChars(),
|
|
AlreadyGot? AlreadyGotLine : Line, composed.GetChars());
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner::ScriptError
|
|
//
|
|
//==========================================================================
|
|
|
|
void STACK_ARGS FScanner::ScriptMessage (const char *message, ...)
|
|
{
|
|
FString composed;
|
|
|
|
if (message == NULL)
|
|
{
|
|
composed = "Bad syntax.";
|
|
}
|
|
else
|
|
{
|
|
va_list arglist;
|
|
va_start (arglist, message);
|
|
composed.VFormat (message, arglist);
|
|
va_end (arglist);
|
|
}
|
|
|
|
Printf ("Script error, \"%s\" line %d:\n%s\n", ScriptName.GetChars(),
|
|
AlreadyGot? AlreadyGotLine : Line, composed.GetChars());
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FScanner :: CheckOpen
|
|
//
|
|
//==========================================================================
|
|
|
|
void FScanner::CheckOpen()
|
|
{
|
|
if (ScriptOpen == false)
|
|
{
|
|
I_FatalError ("SC_ call before SC_Open().");
|
|
}
|
|
}
|