- migrated SW's info script parser to sc_man.

This commit is contained in:
Christoph Oelckers 2020-09-10 17:46:54 +02:00
parent 83eba019b8
commit ef5ac2319e
3 changed files with 256 additions and 220 deletions

View file

@ -47,6 +47,7 @@
#include "templates.h" #include "templates.h"
#include "zstring.h" #include "zstring.h"
#include "name.h" #include "name.h"
#include <inttypes.h>
#include "filesystem.h" #include "filesystem.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -406,6 +407,13 @@ void FScanner::RestorePos (const FScanner::SavedPos &pos)
Crossed = false; Crossed = false;
} }
long long FScanner::mystrtoll(const char* p, char** endp, int base)
{
// Do not treat a leading 0 as an octal identifier if so desired.
if (NoOctals && *p == '0' && p[1] != 'x' && p[1] != 'X' && base == 0) base = 10;
return strtoll(p, endp, base);
}
//========================================================================== //==========================================================================
// //
// FScanner :: isText // FScanner :: isText
@ -596,7 +604,7 @@ bool FScanner::CheckString (const char *name)
// //
//========================================================================== //==========================================================================
bool FScanner::GetToken () bool FScanner::GetToken (bool evaluate)
{ {
if (ScanString (true)) if (ScanString (true))
{ {
@ -614,7 +622,7 @@ bool FScanner::GetToken ()
} }
else else
{ {
BigNumber = strtoll(String, &stopper, 0); BigNumber = mystrtoll(String, &stopper, 0);
Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX); Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX);
Float = Number; Float = Number;
} }
@ -626,7 +634,19 @@ bool FScanner::GetToken ()
} }
else if (TokenType == TK_StringConst) else if (TokenType == TK_StringConst)
{ {
StringLen = strbin(String); StringLen = strbin(const_cast<char*>(String));
}
else if (TokenType == TK_Identifier && evaluate && symbols.CountUsed() > 0)
{
auto sym = symbols.CheckKey(String);
if (sym)
{
TokenType = sym->tokenType;
BigNumber = sym->Number;
Number = (int)sym->Number;
Float = sym->Float;
// String will retain the actual symbol name.
}
} }
return true; return true;
} }
@ -639,9 +659,9 @@ bool FScanner::GetToken ()
// //
//========================================================================== //==========================================================================
void FScanner::MustGetAnyToken (void) void FScanner::MustGetAnyToken (bool evaluate)
{ {
if (GetToken () == false) if (GetToken (evaluate) == false)
{ {
ScriptError ("Missing token (unexpected end of file)."); ScriptError ("Missing token (unexpected end of file).");
} }
@ -669,9 +689,9 @@ void FScanner::TokenMustBe (int token)
// //
//========================================================================== //==========================================================================
void FScanner::MustGetToken (int token) void FScanner::MustGetToken (int token, bool evaluate)
{ {
MustGetAnyToken (); MustGetAnyToken (evaluate);
TokenMustBe(token); TokenMustBe(token);
} }
@ -684,9 +704,9 @@ void FScanner::MustGetToken (int token)
// //
//========================================================================== //==========================================================================
bool FScanner::CheckToken (int token) bool FScanner::CheckToken (int token, bool evaluate)
{ {
if (GetToken ()) if (GetToken (evaluate))
{ {
if (TokenType == token) if (TokenType == token)
{ {
@ -716,7 +736,7 @@ bool FScanner::GetNumber ()
} }
else else
{ {
BigNumber = strtoll(String, &stopper, 0); BigNumber = mystrtoll(String, &stopper, 0);
Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX); Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX);
if (*stopper != 0) if (*stopper != 0)
{ {
@ -773,7 +793,7 @@ bool FScanner::CheckNumber ()
} }
else else
{ {
BigNumber = strtoll (String, &stopper, 0); BigNumber = mystrtoll (String, &stopper, 0);
Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX); Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX);
if (*stopper != 0) if (*stopper != 0)
{ {
@ -944,17 +964,17 @@ bool FScanner::Compare (const char *text)
// //
//========================================================================== //==========================================================================
bool FScanner::ScanValue(bool allowfloat) bool FScanner::ScanValue(bool allowfloat, bool evaluate)
{ {
bool neg = false; bool neg = false;
if (!GetToken()) if (!GetToken(evaluate))
{ {
return false; return false;
} }
if (TokenType == '-' || TokenType == '+') if (TokenType == '-' || TokenType == '+')
{ {
neg = TokenType == '-'; neg = TokenType == '-';
if (!GetToken()) if (!GetToken(evaluate))
{ {
return false; return false;
} }
@ -981,17 +1001,17 @@ bool FScanner::ScanValue(bool allowfloat)
return true; return true;
} }
bool FScanner::CheckValue(bool allowfloat) bool FScanner::CheckValue(bool allowfloat, bool evaluate)
{ {
auto savedstate = SavePos(); auto savedstate = SavePos();
bool res = ScanValue(allowfloat); bool res = ScanValue(allowfloat, evaluate);
if (!res) RestorePos(savedstate); if (!res) RestorePos(savedstate);
return res; return res;
} }
void FScanner::MustGetValue(bool allowfloat) void FScanner::MustGetValue(bool allowfloat, bool evaluate)
{ {
if (!ScanValue(allowfloat)) ScriptError(allowfloat ? "Numeric constant expected" : "Integer constant expected"); if (!ScanValue(allowfloat, evaluate)) ScriptError(allowfloat ? "Numeric constant expected" : "Integer constant expected");
} }
bool FScanner::CheckBoolToken() bool FScanner::CheckBoolToken()
@ -1139,6 +1159,51 @@ void FScanner::CheckOpen()
} }
} }
//==========================================================================
//
//
//
//==========================================================================
void FScanner::AddSymbol(const char *name, int64_t value)
{
Symbol sym;
sym.tokenType = TK_IntConst;
sym.Number = value;
sym.Float = value;
symbols.Insert(name, sym);
}
//==========================================================================
//
//
//
//==========================================================================
void FScanner::AddSymbol(const char* name, uint64_t value)
{
Symbol sym;
sym.tokenType = TK_UIntConst;
sym.Number = value;
sym.Float = value;
symbols.Insert(name, sym);
}
//==========================================================================
//
//
//
//==========================================================================
void FScanner::AddSymbol(const char* name, double value)
{
Symbol sym;
sym.tokenType = TK_FloatConst;
sym.Number = (int64_t)value;
sym.Float = value;
symbols.Insert(name, sym);
}
//========================================================================== //==========================================================================
// //
// a class that remembers a parser position // a class that remembers a parser position

View file

@ -47,6 +47,16 @@ public:
int SavedScriptLine; int SavedScriptLine;
}; };
struct Symbol
{
int tokenType;
int64_t Number;
double Float;
};
TMap<FName, Symbol> symbols;
// Methods ------------------------------------------------------ // Methods ------------------------------------------------------
FScanner(); FScanner();
FScanner(const FScanner &other); FScanner(const FScanner &other);
@ -71,11 +81,17 @@ public:
} }
void SetCMode(bool cmode); void SetCMode(bool cmode);
void SetNoOctals(bool cmode) { NoOctals = cmode; }
void SetEscape(bool esc); void SetEscape(bool esc);
void SetStateMode(bool stately); void SetStateMode(bool stately);
void DisableStateOptions(); void DisableStateOptions();
const SavedPos SavePos(); const SavedPos SavePos();
void RestorePos(const SavedPos &pos); void RestorePos(const SavedPos &pos);
void AddSymbol(const char* name, int64_t value);
void AddSymbol(const char* name, uint64_t value);
inline void AddSymbol(const char* name, int32_t value) { return AddSymbol(name, int64_t(value)); }
inline void AddSymbol(const char* name, uint32_t value) { return AddSymbol(name, uint64_t(value)); }
void AddSymbol(const char* name, double value);
static FString TokenName(int token, const char *string=NULL); static FString TokenName(int token, const char *string=NULL);
@ -84,11 +100,11 @@ public:
void MustGetStringName(const char *name); void MustGetStringName(const char *name);
bool CheckString(const char *name); bool CheckString(const char *name);
bool GetToken(); bool GetToken(bool evaluate = false);
void MustGetAnyToken(); void MustGetAnyToken(bool evaluate = false);
void TokenMustBe(int token); void TokenMustBe(int token);
void MustGetToken(int token); void MustGetToken(int token, bool evaluate = false);
bool CheckToken(int token); bool CheckToken(int token, bool evaluate = false);
bool CheckTokenId(ENamedName id); bool CheckTokenId(ENamedName id);
bool GetNumber(); bool GetNumber();
@ -105,8 +121,8 @@ public:
} }
// Token based variant // Token based variant
bool CheckValue(bool allowfloat); bool CheckValue(bool allowfloat, bool evaluate = true);
void MustGetValue(bool allowfloat); void MustGetValue(bool allowfloat, bool evaluate = true);
bool CheckBoolToken(); bool CheckBoolToken();
void MustGetBoolToken(); void MustGetBoolToken();
@ -136,6 +152,7 @@ public:
FString ScriptName; FString ScriptName;
protected: protected:
long long mystrtoll(const char* p, char** endp, int base);
void PrepareScript(); void PrepareScript();
void CheckOpen(); void CheckOpen();
bool ScanString(bool tokens); bool ScanString(bool tokens);
@ -157,13 +174,14 @@ protected:
const char *LastGotPtr; const char *LastGotPtr;
int LastGotLine; int LastGotLine;
bool CMode; bool CMode;
bool NoOctals = false;
uint8_t StateMode; uint8_t StateMode;
bool StateOptions; bool StateOptions;
bool Escape; bool Escape;
VersionInfo ParseVersion = { 0, 0, 0 }; // no ZScript extensions by default VersionInfo ParseVersion = { 0, 0, 0 }; // no ZScript extensions by default
bool ScanValue(bool allowfloat); bool ScanValue(bool allowfloat, bool evaluate);
}; };
enum enum

View file

@ -36,7 +36,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
#include "sprite.h" #include "sprite.h"
#include "jsector.h" #include "jsector.h"
#include "parent.h" #include "parent.h"
#include "scriptfile.h" #include "sc_man.h"
#include "menu.h" #include "menu.h"
#include "quotemgr.h" #include "quotemgr.h"
#include "mapinfo.h" #include "mapinfo.h"
@ -456,108 +456,94 @@ static struct
// FIXME: yes, we are leaking memory here at the end of the program by not freeing anything // FIXME: yes, we are leaking memory here at the end of the program by not freeing anything
void LoadCustomInfoFromScript(const char *filename) void LoadCustomInfoFromScript(const char *filename)
{ {
scriptfile *script; FScanner sc;
char *token;
char *braceend;
script = scriptfile_fromfile(filename); int lump = fileSystem.FindFile(filename);
if (!script) return; if (lump < 0) return;
sc.OpenLumpNum(lump);
sc.SetNoOctals(true);
// predefine constants for some stuff to give convenience and eliminate the need for a 'define' directive // predefine constants for some stuff to give convenience and eliminate the need for a 'define' directive
scriptfile_addsymbolvalue("INV_ARMOR", 1+InvDecl_Armor); sc.AddSymbol("INV_ARMOR", 1+InvDecl_Armor);
scriptfile_addsymbolvalue("INV_KEVLAR", 1+InvDecl_Kevlar); sc.AddSymbol("INV_KEVLAR", 1+InvDecl_Kevlar);
scriptfile_addsymbolvalue("INV_SM_MEDKIT", 1+InvDecl_SmMedkit); sc.AddSymbol("INV_SM_MEDKIT", 1+InvDecl_SmMedkit);
scriptfile_addsymbolvalue("INV_FORTUNE", 1+InvDecl_Booster); sc.AddSymbol("INV_FORTUNE", 1+InvDecl_Booster);
scriptfile_addsymbolvalue("INV_MEDKIT", 1+InvDecl_Medkit); sc.AddSymbol("INV_MEDKIT", 1+InvDecl_Medkit);
scriptfile_addsymbolvalue("INV_GAS_BOMB", 1+InvDecl_ChemBomb); sc.AddSymbol("INV_GAS_BOMB", 1+InvDecl_ChemBomb);
scriptfile_addsymbolvalue("INV_FLASH_BOMB", 1+InvDecl_FlashBomb); sc.AddSymbol("INV_FLASH_BOMB", 1+InvDecl_FlashBomb);
scriptfile_addsymbolvalue("INV_CALTROPS", 1+InvDecl_Caltrops); sc.AddSymbol("INV_CALTROPS", 1+InvDecl_Caltrops);
scriptfile_addsymbolvalue("INV_NIGHT_VIS", 1+InvDecl_NightVision); sc.AddSymbol("INV_NIGHT_VIS", 1+InvDecl_NightVision);
scriptfile_addsymbolvalue("INV_REPAIR_KIT", 1+InvDecl_RepairKit); sc.AddSymbol("INV_REPAIR_KIT", 1+InvDecl_RepairKit);
scriptfile_addsymbolvalue("INV_SMOKE_BOMB", 1+InvDecl_Cloak); sc.AddSymbol("INV_SMOKE_BOMB", 1+InvDecl_Cloak);
{ {
unsigned i; unsigned i;
for (i=0; i<SIZ(weaponmap); i++) for (i=0; i<SIZ(weaponmap); i++)
scriptfile_addsymbolvalue(weaponmap[i].sym, 1+i); sc.AddSymbol(weaponmap[i].sym, 1+i);
} }
MapRecord* curMap = nullptr; MapRecord* curMap = nullptr;
while ((token = scriptfile_gettoken(script))) while (sc.GetToken())
{ {
switch (cm_transtok(token, cm_tokens, cm_numtokens)) sc.TokenMustBe(TK_Identifier);
switch (cm_transtok(sc.String, cm_tokens, cm_numtokens))
{ {
case CM_MAP: case CM_MAP:
{ {
char *mapnumptr; sc.MustGetValue(false, true);
int mapno; int mapno = sc.Number;
if (scriptfile_getnumber(script, &mapno)) break;
mapnumptr = script->ltextptr;
if (scriptfile_getbraces(script, &braceend)) break;
curMap = FindMapByLevelNum(mapno); curMap = FindMapByLevelNum(mapno);
if (!curMap) if (!curMap)
{ {
curMap = AllocateMap(); curMap = AllocateMap();
curMap->levelNumber = mapno; curMap->levelNumber = mapno;
} }
sc.MustGetToken('{');
while (script->textptr < braceend) while (!sc.CheckToken('}'))
{ {
if (!(token = scriptfile_gettoken(script))) break; sc.MustGetToken(TK_Identifier);
if (token == braceend) break; switch (cm_transtok(sc.String, cm_map_tokens, cm_map_numtokens))
switch (cm_transtok(token, cm_map_tokens, cm_map_numtokens))
{ {
case CM_FILENAME: case CM_FILENAME:
{ {
char *t; sc.MustGetToken(TK_StringConst, true);
if (scriptfile_getstring(script, &t)) break; curMap->SetFileName(sc.String);
curMap->SetFileName(t);
break; break;
} }
case CM_SONG: case CM_SONG:
{ {
char *t; sc.MustGetToken(TK_StringConst, true);
if (scriptfile_getstring(script, &t)) break; curMap->music = sc.String;
curMap->music = t;
break; break;
} }
case CM_TITLE: case CM_TITLE:
{ {
char *t; sc.MustGetToken(TK_StringConst, true);
if (scriptfile_getstring(script, &t)) break; curMap->SetName(sc.String);
curMap->SetName(t);
break; break;
} }
case CM_BESTTIME: case CM_BESTTIME:
{ {
int n; sc.MustGetValue(false);
if (scriptfile_getnumber(script, &n)) break; curMap->designerTime = sc.Number;
curMap->designerTime = n;
break; break;
} }
case CM_PARTIME: case CM_PARTIME:
{ {
int n; sc.MustGetValue(false);
if (scriptfile_getnumber(script, &n)) break; curMap->parTime = sc.Number;
curMap->parTime = n;
break; break;
} }
case CM_CDATRACK: case CM_CDATRACK:
{ {
int n; sc.MustGetValue(false);
if (scriptfile_getnumber(script, &n)) break; curMap->cdSongId = sc.Number;
curMap->cdSongId = n;
break; break;
} }
default: default:
Printf("Error on line %s:%d\n", sc.ScriptError("Unknown keyword %d", sc.String);
script->filename,
scriptfile_getlinum(script,script->ltextptr));
break; break;
} }
} }
@ -566,45 +552,38 @@ void LoadCustomInfoFromScript(const char *filename)
case CM_EPISODE: case CM_EPISODE:
{ {
char *epnumptr;
int curep; int curep;
if (scriptfile_getnumber(script, &curep)) break;
epnumptr = script->ltextptr; sc.MustGetValue(false, true);
if (scriptfile_getbraces(script, &braceend)) break; curep = sc.Number;
if ((unsigned)--curep >= 2u) if ((unsigned)--curep >= 2u)
{ {
Printf("Error: episode number %d not in range 1-2 on line %s:%d\n", sc.ScriptMessage("Episode number %d not in range 1-2\n", curep + 1);
curep, script->filename, curep = -1;
scriptfile_getlinum(script,epnumptr));
script->textptr = braceend;
break; break;
} }
while (script->textptr < braceend) sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{ {
if (!(token = scriptfile_gettoken(script))) break; sc.MustGetToken(TK_Identifier);
if (token == braceend) break; switch (cm_transtok(sc.String, cm_episode_tokens, cm_episode_numtokens))
switch (cm_transtok(token, cm_episode_tokens, cm_episode_numtokens))
{ {
case CM_TITLE: case CM_TITLE:
{ {
char *t; sc.MustGetToken(TK_StringConst, true);
if (scriptfile_getstring(script, &t)) break; if (curep != -1) gVolumeNames[curep] = sc.String;
gVolumeNames[curep] = t;
break; break;
} }
case CM_SUBTITLE: case CM_SUBTITLE:
{ {
char *t; sc.MustGetToken(TK_StringConst, true);
if (scriptfile_getstring(script, &t)) break; if (curep != -1) gVolumeSubtitles[curep] = sc.String;
gVolumeSubtitles[curep] = t;
break; break;
} }
default: default:
Printf("Error on line %s:%d\n", sc.ScriptError("Unknown keyword %d", sc.String);
script->filename,
scriptfile_getlinum(script,script->ltextptr));
break; break;
} }
} }
@ -614,38 +593,29 @@ void LoadCustomInfoFromScript(const char *filename)
case CM_SKILL: case CM_SKILL:
{ {
int curskill; int curskill;
char *epnumptr; sc.MustGetValue(false, true);
if (scriptfile_getnumber(script, &curskill)) break; curskill = sc.Number;
epnumptr = script->ltextptr;
if (scriptfile_getbraces(script, &braceend)) break;
if ((unsigned)--curskill >= 4u) if ((unsigned)--curskill >= 4u)
{ {
Printf("Error: skill number %d not in range 1-4 on line %s:%d\n", sc.ScriptMessage("Skill number %d not in range 1-4 on line %s:%d\n", curskill + 1);
curskill, script->filename, curskill = -1;
scriptfile_getlinum(script,epnumptr));
script->textptr = braceend;
break; break;
} }
while (script->textptr < braceend) sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{ {
if (!(token = scriptfile_gettoken(script))) break; sc.MustGetToken(TK_Identifier);
if (token == braceend) break; switch (cm_transtok(sc.String, cm_skill_tokens, cm_skill_numtokens))
switch (cm_transtok(token, cm_skill_tokens, cm_skill_numtokens))
{ {
case CM_TITLE: case CM_TITLE:
{ {
char *t; sc.MustGetToken(TK_StringConst, true);
if (scriptfile_getstring(script, &t)) break; if (curskill != -1) gSkillNames[curskill] = sc.String;
gSkillNames[curskill] = t;
break; break;
} }
default: default:
Printf("Error on line %s:%d\n", sc.ScriptError("Unknown keyword %d", sc.String);
script->filename,
scriptfile_getlinum(script,script->ltextptr));
break; break;
} }
} }
@ -654,98 +624,86 @@ void LoadCustomInfoFromScript(const char *filename)
case CM_COOKIE: case CM_COOKIE:
{ {
char *t;
int fc = 0; int fc = 0;
sc.MustGetToken('{');
if (scriptfile_getbraces(script, &braceend)) break; while (!sc.CheckToken('}'))
while (script->textptr < braceend)
{ {
if (scriptfile_getstring(script, &t)) break; sc.MustGetToken(TK_StringConst, true);
if (fc < MAX_FORTUNES)
if (fc == MAX_FORTUNES) continue; {
quoteMgr.InitializeQuote(QUOTE_COOKIE + fc, sc.String);
quoteMgr.InitializeQuote(QUOTE_COOKIE + fc, t); }
fc++; fc++;
} }
break; break;
} }
case CM_GOTKEY: case CM_GOTKEY:
{ {
char *t;
int fc = 0; int fc = 0;
sc.MustGetToken('{');
if (scriptfile_getbraces(script, &braceend)) break; while (!sc.CheckToken('}'))
while (script->textptr < braceend)
{ {
if (scriptfile_getstring(script, &t)) break; sc.MustGetToken(TK_StringConst, true);
if (fc < MAX_KEYS)
if (fc == MAX_KEYS) continue; {
quoteMgr.InitializeQuote(QUOTE_KEYMSG + fc, sc.String);
quoteMgr.InitializeQuote(QUOTE_KEYMSG + fc, t); }
fc++; fc++;
} }
break; break;
} }
case CM_NEEDKEY: case CM_NEEDKEY:
{ {
char *t;
int fc = 0; int fc = 0;
sc.MustGetToken('{');
if (scriptfile_getbraces(script, &braceend)) break; while (!sc.CheckToken('}'))
while (script->textptr < braceend)
{ {
if (scriptfile_getstring(script, &t)) break; sc.MustGetToken(TK_StringConst, true);
if (fc < MAX_KEYS)
if (fc == MAX_KEYS) continue; {
quoteMgr.InitializeQuote(QUOTE_DOORMSG + fc, sc.String);
quoteMgr.InitializeQuote(QUOTE_DOORMSG + fc, t); }
fc++; fc++;
} }
break; break;
} }
case CM_INVENTORY: case CM_INVENTORY:
{ {
char *invnumptr;
int in; int in;
char *name = NULL; FString name;
int amt = -1; int amt = -1;
if (scriptfile_getsymbol(script, &in)) break; sc.MustGetValue(false, true);
invnumptr = script->ltextptr; in = sc.Number;
if (scriptfile_getbraces(script, &braceend)) break;
if ((unsigned)--in >= (unsigned)InvDecl_TOTAL) if ((unsigned)--in >= (unsigned)InvDecl_TOTAL)
{ {
Printf("Error: inventory item number not in range 1-%d on line %s:%d\n", sc.ScriptMessage("Inventory item number %d not in range 1-%d\n", in, InvDecl_TOTAL);
InvDecl_TOTAL, script->filename, in = -1;
scriptfile_getlinum(script,invnumptr));
script->textptr = braceend;
break; break;
} }
while (script->textptr < braceend) sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{ {
if (!(token = scriptfile_gettoken(script))) break; sc.MustGetToken(TK_Identifier);
if (token == braceend) break; switch (cm_transtok(sc.String, cm_inventory_tokens, cm_inventory_numtokens))
switch (cm_transtok(token, cm_inventory_tokens, cm_inventory_numtokens))
{ {
case CM_TITLE: case CM_TITLE:
if (scriptfile_getstring(script, &name)) break; sc.MustGetToken(TK_StringConst);
name = sc.String;
break; break;
case CM_AMOUNT: case CM_AMOUNT:
if (scriptfile_getnumber(script, &amt)) break; sc.MustGetValue(false, true);
amt = sc.Number;
break; break;
default: default:
Printf("Error on line %s:%d\n", sc.ScriptError("Unknown keyword %d", sc.String);
script->filename,
scriptfile_getlinum(script,script->ltextptr));
break; break;
} }
} }
if (in == -1) break;
if (name) if (name)
{ {
quoteMgr.InitializeQuote(QUOTE_INVENTORY + in, name); quoteMgr.InitializeQuote(QUOTE_INVENTORY + in, name);
@ -758,58 +716,60 @@ void LoadCustomInfoFromScript(const char *filename)
} }
case CM_WEAPON: case CM_WEAPON:
{ {
char *wpnnumptr; FString name, ammo;
char *name = NULL, *ammo = NULL;
int maxammo = -1, damagemin = -1, damagemax = -1, pickup = -1, wpickup = -1; int maxammo = -1, damagemin = -1, damagemax = -1, pickup = -1, wpickup = -1;
int in,id; int in,id;
if (scriptfile_getsymbol(script, &in)) break; sc.MustGetValue(false, true);
wpnnumptr = script->ltextptr; in = sc.Number;
if (scriptfile_getbraces(script, &braceend)) break;
if ((unsigned)--in >= (unsigned)SIZ(weaponmap)) if ((unsigned)--in >= (unsigned)SIZ(weaponmap))
{ {
Printf("Error: weapon number not in range 1-%d on line %s:%d\n", sc.ScriptMessage("Error: weapon number %d not in range 1-%d", in+1, (int)SIZ(weaponmap));
(int)SIZ(weaponmap), script->filename, in = -1;
scriptfile_getlinum(script,wpnnumptr));
script->textptr = braceend;
break; break;
} }
while (script->textptr < braceend) sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{ {
if (!(token = scriptfile_gettoken(script))) break; sc.MustGetToken(TK_Identifier);
if (token == braceend) break; switch (cm_transtok(sc.String, cm_weapons_tokens, cm_weapons_numtokens))
switch (cm_transtok(token, cm_weapons_tokens, cm_weapons_numtokens))
{ {
case CM_TITLE: case CM_TITLE:
if (scriptfile_getstring(script, &name)) break; sc.MustGetToken(TK_StringConst);
name = sc.String;
break; break;
case CM_AMMONAME: case CM_AMMONAME:
if (scriptfile_getstring(script, &ammo)) break; sc.MustGetToken(TK_StringConst);
ammo = sc.String;
break; break;
case CM_MAXAMMO: case CM_MAXAMMO:
if (scriptfile_getnumber(script, &maxammo)) break; sc.MustGetValue(false, true);
maxammo = sc.Number;
break; break;
case CM_DAMAGEMIN: case CM_DAMAGEMIN:
if (scriptfile_getnumber(script, &damagemin)) break; sc.MustGetValue(false, true);
damagemin = sc.Number;
break; break;
case CM_DAMAGEMAX: case CM_DAMAGEMAX:
if (scriptfile_getnumber(script, &damagemax)) break; sc.MustGetValue(false, true);
damagemax = sc.Number;
break; break;
case CM_AMOUNT: case CM_AMOUNT:
if (scriptfile_getnumber(script, &pickup)) break; sc.MustGetValue(false, true);
pickup = sc.Number;
break; break;
case CM_WEAPON: case CM_WEAPON:
if (scriptfile_getnumber(script, &wpickup)) break; sc.MustGetValue(false, true);
wpickup = sc.Number;
break; break;
default: default:
Printf("Error on line %s:%d\n", sc.ScriptError("Unknown keyword %d", sc.String);
script->filename,
scriptfile_getlinum(script,script->ltextptr));
break; break;
} }
} }
if (in == -1) break;
id = weaponmap[in].dmgid; id = weaponmap[in].dmgid;
if (weaponmap[in].editable & WM_DAMAGE) if (weaponmap[in].editable & WM_DAMAGE)
{ {
@ -837,40 +797,38 @@ void LoadCustomInfoFromScript(const char *filename)
} }
case CM_THEME: case CM_THEME:
{ {
char *epnumptr; FString name;
char *name = NULL;
int trak = -1; int trak = -1;
int curtheme; int curtheme;
if (scriptfile_getnumber(script, &curtheme)) break; epnumptr = script->ltextptr; sc.MustGetValue(false, true);
if (scriptfile_getbraces(script, &braceend)) break; curtheme = sc.Number;
if ((unsigned)--curtheme >= 6u) if ((unsigned)--curtheme >= 6u)
{ {
Printf("Error: theme number %d not in range 1-6 on line %s:%d\n", sc.ScriptMessage("Theme number %d not in range 1-6", curtheme+1);
curtheme, script->filename, curtheme = -1;
scriptfile_getlinum(script,epnumptr));
script->textptr = braceend;
break;
} }
while (script->textptr < braceend) sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{ {
if (!(token = scriptfile_gettoken(script))) break; sc.MustGetToken(TK_Identifier);
if (token == braceend) break; switch (cm_transtok(sc.String, cm_theme_tokens, cm_theme_numtokens))
switch (cm_transtok(token, cm_theme_tokens, cm_theme_numtokens))
{ {
case CM_SONG: case CM_SONG:
if (scriptfile_getstring(script, &name)) break; sc.MustGetToken(TK_StringConst);
name = sc.String;
break; break;
case CM_CDATRACK: case CM_CDATRACK:
if (scriptfile_getnumber(script, &trak)) break; sc.MustGetValue(false, true);
trak = sc.Number;
break; break;
default: default:
Printf("Error on line %s:%d\n", sc.ScriptError("Unknown keyword %d", sc.String);
script->filename,
scriptfile_getlinum(script,script->ltextptr));
break; break;
} }
} }
if (curtheme == -1) break;
if (name) if (name)
{ {
ThemeSongs[curtheme] = name; ThemeSongs[curtheme] = name;
@ -884,15 +842,10 @@ void LoadCustomInfoFromScript(const char *filename)
case CM_SECRET: case CM_SECRET:
case CM_QUIT: case CM_QUIT:
default: default:
Printf("Error on line %s:%d\n", sc.ScriptError("Unknown keyword %d", sc.String);
script->filename,
scriptfile_getlinum(script,script->ltextptr));
break; break;
} }
} }
scriptfile_close(script);
scriptfile_clearsymbols();
} }
END_SW_NS END_SW_NS