diff --git a/source/build/src/scriptfile.cpp b/source/build/src/scriptfile.cpp index 3f05dc600..0cae0e0bc 100644 --- a/source/build/src/scriptfile.cpp +++ b/source/build/src/scriptfile.cpp @@ -61,7 +61,7 @@ int32_t scriptfile_getnumber(scriptfile *sf, int32_t *num) { char *p = sf->textptr; skipovertoken(sf); - Printf("Error on line %s:%d: expecting int32_t, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),p); + Printf("Error on line %s:%d: expecting int, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),p); return -2; } return 0; diff --git a/source/common/engine/sc_man.cpp b/source/common/engine/sc_man.cpp index bbd47cfc1..d7aa3e3a6 100644 --- a/source/common/engine/sc_man.cpp +++ b/source/common/engine/sc_man.cpp @@ -505,6 +505,7 @@ bool FScanner::ScanString (bool tokens) const char *marker, *tok; bool return_val; + ParseError = false; CheckOpen(); if (AlreadyGot) { @@ -545,7 +546,7 @@ bool FScanner::GetString () return ScanString (false); } -//========================================================================== +//============================================ ============================== // // FScanner :: MustGetString // @@ -723,7 +724,7 @@ bool FScanner::CheckToken (int token, bool evaluate) // //========================================================================== -bool FScanner::GetNumber () +bool FScanner::GetNumber (bool evaluate) { char *stopper; @@ -740,6 +741,19 @@ bool FScanner::GetNumber () Number = (int)BigNumber;// clamp(BigNumber, 0, UINT_MAX); if (*stopper != 0) { + if (evaluate && symbols.CountUsed()) + { + auto sym = symbols.CheckKey(String); + if (sym && sym->tokenType == TK_IntConst) + { + BigNumber = sym->Number; + Number = (int)sym->Number; + Float = sym->Float; + // String will retain the actual symbol name. + return true; + } + + } ScriptError ("SC_GetNumber: Bad numeric constant \"%s\".", String); } } @@ -758,9 +772,9 @@ bool FScanner::GetNumber () // //========================================================================== -void FScanner::MustGetNumber () +void FScanner::MustGetNumber (bool evaluate) { - if (GetNumber() == false) + if (GetNumber(evaluate) == false) { ScriptError ("Missing integer (unexpected end of file)."); } @@ -775,7 +789,7 @@ void FScanner::MustGetNumber () // //========================================================================== -bool FScanner::CheckNumber () +bool FScanner::CheckNumber (bool evaluate) { char *stopper; @@ -797,6 +811,19 @@ bool FScanner::CheckNumber () Number = (int)BigNumber;// clamp(BigNumber, 0, UINT_MAX); if (*stopper != 0) { + if (evaluate && symbols.CountUsed()) + { + auto sym = symbols.CheckKey(String); + if (sym && sym->tokenType == TK_IntConst) + { + BigNumber = sym->Number; + Number = (int)sym->Number; + Float = sym->Float; + // String will retain the actual symbol name. + return true; + } + + } UnGet(); return false; } @@ -818,7 +845,7 @@ bool FScanner::CheckNumber () // //========================================================================== -bool FScanner::CheckFloat () +bool FScanner::CheckFloat (bool evaluate) { char *stopper; @@ -833,6 +860,20 @@ bool FScanner::CheckFloat () Float = strtod (String, &stopper); if (*stopper != 0) { + if (evaluate && symbols.CountUsed()) + { + auto sym = symbols.CheckKey(String); + if (sym && sym->tokenType == TK_IntConst && sym->tokenType != TK_FloatConst) + { + BigNumber = sym->Number; + Number = (int)sym->Number; + Float = sym->Float; + // String will retain the actual symbol name. + return true; + } + + } + UnGet(); return false; } @@ -851,7 +892,7 @@ bool FScanner::CheckFloat () // //========================================================================== -bool FScanner::GetFloat () +bool FScanner::GetFloat (bool evaluate) { char *stopper; @@ -861,6 +902,19 @@ bool FScanner::GetFloat () Float = strtod (String, &stopper); if (*stopper != 0) { + if (evaluate && symbols.CountUsed()) + { + auto sym = symbols.CheckKey(String); + if (sym && sym->tokenType == TK_IntConst && sym->tokenType != TK_FloatConst) + { + BigNumber = sym->Number; + Number = (int)sym->Number; + Float = sym->Float; + // String will retain the actual symbol name. + return true; + } + } + ScriptError ("SC_GetFloat: Bad numeric constant \"%s\".", String); } Number = (int)Float; @@ -878,9 +932,9 @@ bool FScanner::GetFloat () // //========================================================================== -void FScanner::MustGetFloat () +void FScanner::MustGetFloat (bool evaluate) { - if (GetFloat() == false) + if (GetFloat(evaluate) == false) { ScriptError ("Missing floating-point number (unexpected end of file)."); } @@ -1115,6 +1169,12 @@ void FScanner::ScriptError (const char *message, ...) va_end (arglist); } + if (NoFatalErrors) + { + Printf(TEXTCOLOR_RED "Script error, \"%s\"" TEXTCOLOR_RED " line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(), + AlreadyGot ? AlreadyGotLine : Line, composed.GetChars()); + return; + } I_Error ("Script error, \"%s\" line %d:\n%s\n", ScriptName.GetChars(), AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); } diff --git a/source/common/engine/sc_man.h b/source/common/engine/sc_man.h index 001c5973c..4022964ee 100644 --- a/source/common/engine/sc_man.h +++ b/source/common/engine/sc_man.h @@ -82,6 +82,7 @@ public: void SetCMode(bool cmode); void SetNoOctals(bool cmode) { NoOctals = cmode; } + void SetNoFatalErrors(bool cmode) { NoFatalErrors = cmode; } void SetEscape(bool esc); void SetStateMode(bool stately); void DisableStateOptions(); @@ -108,13 +109,13 @@ public: bool CheckToken(int token, bool evaluate = false); bool CheckTokenId(ENamedName id); - bool GetNumber(); - void MustGetNumber(); - bool CheckNumber(); + bool GetNumber(bool evaluate = false); + void MustGetNumber(bool evaluate = false); + bool CheckNumber(bool evaluate = false); - bool GetFloat(); - void MustGetFloat(); - bool CheckFloat(); + bool GetFloat(bool evaluate = false); + void MustGetFloat(bool evaluate = false); + bool CheckFloat(bool evaluate = false); double *LookupConstant(FName name) { @@ -148,6 +149,7 @@ public: double Float; int Line; bool End; + bool ParseError = false; bool Crossed; int LumpNum; FString ScriptName; @@ -176,6 +178,7 @@ protected: int LastGotLine; bool CMode; bool NoOctals = false; + bool NoFatalErrors = false; uint8_t StateMode; bool StateOptions; bool Escape; diff --git a/source/sw/src/scrip2.cpp b/source/sw/src/scrip2.cpp index 209a13fc5..f3c33b3eb 100644 --- a/source/sw/src/scrip2.cpp +++ b/source/sw/src/scrip2.cpp @@ -463,6 +463,8 @@ void LoadCustomInfoFromScript(const char *filename) sc.OpenLumpNum(lump); sc.SetNoOctals(true); + sc.SetCMode(true); + sc.SetNoFatalErrors(true); // predefine constants for some stuff to give convenience and eliminate the need for a 'define' directive sc.AddSymbol("INV_ARMOR", 1+InvDecl_Armor); @@ -484,61 +486,60 @@ void LoadCustomInfoFromScript(const char *filename) } MapRecord* curMap = nullptr; - while (sc.GetToken()) + while (sc.GetString()) { - sc.TokenMustBe(TK_Identifier); switch (cm_transtok(sc.String, cm_tokens, cm_numtokens)) { case CM_MAP: { - sc.MustGetValue(false, true); - int mapno = sc.Number; + sc.MustGetNumber(true); + int mapno = sc.ParseError? -1 : sc.Number; curMap = FindMapByLevelNum(mapno); if (!curMap) { curMap = AllocateMap(); curMap->levelNumber = mapno; } - sc.MustGetToken('{'); + if (sc.CheckString("{")) - while (!sc.CheckToken('}')) + while (!sc.CheckString("}")) { - sc.MustGetToken(TK_Identifier); + sc.MustGetString(); switch (cm_transtok(sc.String, cm_map_tokens, cm_map_numtokens)) { case CM_FILENAME: { - sc.MustGetToken(TK_StringConst, true); + sc.MustGetString(); curMap->SetFileName(sc.String); break; } case CM_SONG: { - sc.MustGetToken(TK_StringConst, true); + sc.MustGetString(); curMap->music = sc.String; break; } case CM_TITLE: { - sc.MustGetToken(TK_StringConst, true); + sc.MustGetString(); curMap->SetName(sc.String); break; } case CM_BESTTIME: { - sc.MustGetValue(false); + sc.MustGetNumber(); curMap->designerTime = sc.Number; break; } case CM_PARTIME: { - sc.MustGetValue(false); + sc.MustGetNumber(); curMap->parTime = sc.Number; break; } case CM_CDATRACK: { - sc.MustGetValue(false); + sc.MustGetNumber(); curMap->cdSongId = sc.Number; break; } @@ -554,31 +555,32 @@ void LoadCustomInfoFromScript(const char *filename) { int curep; - sc.MustGetValue(false, true); + sc.MustGetNumber(); curep = sc.Number; - if ((unsigned)--curep >= 2u) + if (sc.ParseError) curep = -1; + else if ((unsigned)--curep >= 2u) { sc.ScriptMessage("Episode number %d not in range 1-2\n", curep + 1); curep = -1; break; } - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) + if (sc.CheckString("{")) + while (!sc.CheckString("}")) { - sc.MustGetToken(TK_Identifier); + sc.MustGetString(); switch (cm_transtok(sc.String, cm_episode_tokens, cm_episode_numtokens)) { case CM_TITLE: { - sc.MustGetToken(TK_StringConst, true); + sc.MustGetString(); if (curep != -1) gVolumeNames[curep] = sc.String; break; } case CM_SUBTITLE: { - sc.MustGetToken(TK_StringConst, true); + sc.MustGetString(); if (curep != -1) gVolumeSubtitles[curep] = sc.String; break; } @@ -593,8 +595,9 @@ void LoadCustomInfoFromScript(const char *filename) case CM_SKILL: { int curskill; - sc.MustGetValue(false, true); + sc.MustGetNumber(); curskill = sc.Number; + if (sc.ParseError) curskill = -1; if ((unsigned)--curskill >= 4u) { sc.ScriptMessage("Skill number %d not in range 1-4 on line %s:%d\n", curskill + 1); @@ -602,15 +605,15 @@ void LoadCustomInfoFromScript(const char *filename) break; } - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) + if (sc.CheckString("{")) + while (!sc.CheckString("}")) { - sc.MustGetToken(TK_Identifier); + sc.MustGetString(); switch (cm_transtok(sc.String, cm_skill_tokens, cm_skill_numtokens)) { case CM_TITLE: { - sc.MustGetToken(TK_StringConst, true); + sc.MustGetString(); if (curskill != -1) gSkillNames[curskill] = sc.String; break; } @@ -625,10 +628,10 @@ void LoadCustomInfoFromScript(const char *filename) case CM_COOKIE: { int fc = 0; - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) + if (sc.CheckString("{")) + while (!sc.CheckString("}")) { - sc.MustGetToken(TK_StringConst, true); + sc.MustGetString(); if (fc < MAX_FORTUNES) { quoteMgr.InitializeQuote(QUOTE_COOKIE + fc, sc.String); @@ -640,10 +643,10 @@ void LoadCustomInfoFromScript(const char *filename) case CM_GOTKEY: { int fc = 0; - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) + if (sc.CheckString("{")) + while (!sc.CheckString("}")) { - sc.MustGetToken(TK_StringConst, true); + sc.MustGetString(); if (fc < MAX_KEYS) { quoteMgr.InitializeQuote(QUOTE_KEYMSG + fc, sc.String); @@ -655,10 +658,10 @@ void LoadCustomInfoFromScript(const char *filename) case CM_NEEDKEY: { int fc = 0; - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) + if (sc.CheckString("{")) + while (!sc.CheckString("}")) { - sc.MustGetToken(TK_StringConst, true); + sc.MustGetString(); if (fc < MAX_KEYS) { quoteMgr.InitializeQuote(QUOTE_DOORMSG + fc, sc.String); @@ -673,9 +676,10 @@ void LoadCustomInfoFromScript(const char *filename) FString name; int amt = -1; - sc.MustGetValue(false, true); + sc.MustGetNumber(); in = sc.Number; + if (sc.ParseError) in = -1; if ((unsigned)--in >= (unsigned)InvDecl_TOTAL) { sc.ScriptMessage("Inventory item number %d not in range 1-%d\n", in, InvDecl_TOTAL); @@ -683,10 +687,10 @@ void LoadCustomInfoFromScript(const char *filename) break; } - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) + if (sc.CheckString("{")) + while (!sc.CheckString("}")) { - sc.MustGetToken(TK_Identifier); + sc.MustGetString(); switch (cm_transtok(sc.String, cm_inventory_tokens, cm_inventory_numtokens)) { case CM_TITLE: @@ -694,7 +698,7 @@ void LoadCustomInfoFromScript(const char *filename) name = sc.String; break; case CM_AMOUNT: - sc.MustGetValue(false, true); + sc.MustGetNumber(); amt = sc.Number; break; default: @@ -720,9 +724,10 @@ void LoadCustomInfoFromScript(const char *filename) int maxammo = -1, damagemin = -1, damagemax = -1, pickup = -1, wpickup = -1; int in,id; - sc.MustGetValue(false, true); + sc.MustGetNumber(); in = sc.Number; + if (sc.ParseError) in = -1; if ((unsigned)--in >= (unsigned)SIZ(weaponmap)) { sc.ScriptMessage("Error: weapon number %d not in range 1-%d", in+1, (int)SIZ(weaponmap)); @@ -730,10 +735,10 @@ void LoadCustomInfoFromScript(const char *filename) break; } - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) + if (sc.CheckString("{")) + while (!sc.CheckString("}")) { - sc.MustGetToken(TK_Identifier); + sc.MustGetString(); switch (cm_transtok(sc.String, cm_weapons_tokens, cm_weapons_numtokens)) { case CM_TITLE: @@ -745,23 +750,23 @@ void LoadCustomInfoFromScript(const char *filename) ammo = sc.String; break; case CM_MAXAMMO: - sc.MustGetValue(false, true); + sc.MustGetNumber(); maxammo = sc.Number; break; case CM_DAMAGEMIN: - sc.MustGetValue(false, true); + sc.MustGetNumber(); damagemin = sc.Number; break; case CM_DAMAGEMAX: - sc.MustGetValue(false, true); + sc.MustGetNumber(); damagemax = sc.Number; break; case CM_AMOUNT: - sc.MustGetValue(false, true); + sc.MustGetNumber(); pickup = sc.Number; break; case CM_WEAPON: - sc.MustGetValue(false, true); + sc.MustGetNumber(); wpickup = sc.Number; break; default: @@ -801,18 +806,19 @@ void LoadCustomInfoFromScript(const char *filename) int trak = -1; int curtheme; - sc.MustGetValue(false, true); + sc.MustGetNumber(); curtheme = sc.Number; - if ((unsigned)--curtheme >= 6u) + if (sc.ParseError) curtheme = -1; + if ((unsigned)--curtheme >= 6u) { sc.ScriptMessage("Theme number %d not in range 1-6", curtheme+1); curtheme = -1; } - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) + if (sc.CheckString("{")) + while (!sc.CheckString("}")) { - sc.MustGetToken(TK_Identifier); + sc.MustGetString(); switch (cm_transtok(sc.String, cm_theme_tokens, cm_theme_numtokens)) { case CM_SONG: @@ -820,7 +826,7 @@ void LoadCustomInfoFromScript(const char *filename) name = sc.String; break; case CM_CDATRACK: - sc.MustGetValue(false, true); + sc.MustGetNumber(); trak = sc.Number; break; default: