- improved error reporting for badly defined translations.

This needs to be handled by the caller for all use cases because the translation parser lacks the context to do a proper error report.
This commit is contained in:
Christoph Oelckers 2018-12-16 09:56:53 +01:00
parent a96b86b13b
commit a38e75db00
4 changed files with 150 additions and 138 deletions

View file

@ -633,148 +633,140 @@ bool FRemapTable::AddToTranslation(const char *range)
sc.OpenMem("translation", range, int(strlen(range))); sc.OpenMem("translation", range, int(strlen(range)));
sc.SetCMode(true); sc.SetCMode(true);
try sc.MustGetToken(TK_IntConst);
start = sc.Number;
sc.MustGetToken(':');
sc.MustGetToken(TK_IntConst);
end = sc.Number;
sc.MustGetToken('=');
if (start < 0 || start > 255 || end < 0 || end > 255)
{ {
sc.ScriptError("Palette index out of range");
return false;
}
sc.MustGetAnyToken();
if (sc.TokenType == '[')
{
// translation using RGB values
int r1,g1,b1,r2,g2,b2;
sc.MustGetToken(TK_IntConst); sc.MustGetToken(TK_IntConst);
start = sc.Number; r1 = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g1 = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b1 = sc.Number;
sc.MustGetToken(']');
sc.MustGetToken(':'); sc.MustGetToken(':');
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst); sc.MustGetToken(TK_IntConst);
end = sc.Number; r2 = sc.Number;
sc.MustGetToken('='); sc.MustGetToken(',');
if (start < 0 || start > 255 || end < 0 || end > 255)
{ sc.MustGetToken(TK_IntConst);
sc.ScriptError("Palette index out of range"); g2 = sc.Number;
return false; sc.MustGetToken(',');
}
sc.MustGetToken(TK_IntConst);
b2 = sc.Number;
sc.MustGetToken(']');
return AddColorRange(start, end, r1, g1, b1, r2, g2, b2);
}
else if (sc.TokenType == '%')
{
// translation using RGB values
double r1,g1,b1,r2,g2,b2;
sc.MustGetToken('[');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
r1 = sc.Float;
sc.MustGetToken(',');
sc.MustGetAnyToken(); sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
g1 = sc.Float;
sc.MustGetToken(',');
if (sc.TokenType == '[') sc.MustGetAnyToken();
{ if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
// translation using RGB values b1 = sc.Float;
int r1,g1,b1,r2,g2,b2; sc.MustGetToken(']');
sc.MustGetToken(':');
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst); sc.MustGetAnyToken();
r1 = sc.Number; if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
sc.MustGetToken(','); r2 = sc.Float;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst); sc.MustGetAnyToken();
g1 = sc.Number; if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
sc.MustGetToken(','); g2 = sc.Float;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst); sc.MustGetAnyToken();
b1 = sc.Number; if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
sc.MustGetToken(']'); b2 = sc.Float;
sc.MustGetToken(':'); sc.MustGetToken(']');
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst); return AddDesaturation(start, end, r1, g1, b1, r2, g2, b2);
r2 = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g2 = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b2 = sc.Number;
sc.MustGetToken(']');
return AddColorRange(start, end, r1, g1, b1, r2, g2, b2);
}
else if (sc.TokenType == '%')
{
// translation using RGB values
double r1,g1,b1,r2,g2,b2;
sc.MustGetToken('[');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
r1 = sc.Float;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
g1 = sc.Float;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
b1 = sc.Float;
sc.MustGetToken(']');
sc.MustGetToken(':');
sc.MustGetToken('[');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
r2 = sc.Float;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
g2 = sc.Float;
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
b2 = sc.Float;
sc.MustGetToken(']');
return AddDesaturation(start, end, r1, g1, b1, r2, g2, b2);
}
else if (sc.TokenType == '#')
{
// Colourise translation
int r, g, b;
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst);
r = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b = sc.Number;
sc.MustGetToken(']');
return AddColourisation(start, end, r, g, b);
}
else if (sc.TokenType == '@')
{
// Tint translation
int a, r, g, b;
sc.MustGetToken(TK_IntConst);
a = sc.Number;
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst);
r = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b = sc.Number;
sc.MustGetToken(']');
return AddTint(start, end, r, g, b, a);
}
else
{
int pal1, pal2;
sc.TokenMustBe(TK_IntConst);
pal1 = sc.Number;
sc.MustGetToken(':');
sc.MustGetToken(TK_IntConst);
pal2 = sc.Number;
return AddIndexRange(start, end, pal1, pal2);
}
} }
catch (CRecoverableError &err) else if (sc.TokenType == '#')
{ {
Printf("Error in translation '%s':\n%s\n", range, err.GetMessage()); // Colourise translation
return false; int r, g, b;
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst);
r = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b = sc.Number;
sc.MustGetToken(']');
return AddColourisation(start, end, r, g, b);
}
else if (sc.TokenType == '@')
{
// Tint translation
int a, r, g, b;
sc.MustGetToken(TK_IntConst);
a = sc.Number;
sc.MustGetToken('[');
sc.MustGetToken(TK_IntConst);
r = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
g = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
b = sc.Number;
sc.MustGetToken(']');
return AddTint(start, end, r, g, b, a);
}
else
{
int pal1, pal2;
sc.TokenMustBe(TK_IntConst);
pal1 = sc.Number;
sc.MustGetToken(':');
sc.MustGetToken(TK_IntConst);
pal2 = sc.Number;
return AddIndexRange(start, end, pal1, pal2);
} }
} }
@ -1529,7 +1521,16 @@ void R_ParseTrnslate()
do do
{ {
sc.MustGetToken(TK_StringConst); sc.MustGetToken(TK_StringConst);
NewTranslation.AddToTranslation(sc.String);
try
{
NewTranslation.AddToTranslation(sc.String);
}
catch (CRecoverableError &err)
{
sc.ScriptMessage("Error in translation '%s':\n" TEXTCOLOR_YELLOW "%s\n", sc.String, err.GetMessage());
}
} while (sc.CheckToken(',')); } while (sc.CheckToken(','));
int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom); int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom);

View file

@ -1120,7 +1120,7 @@ void FScanner::ScriptMessage (const char *message, ...)
va_end (arglist); va_end (arglist);
} }
Printf (TEXTCOLOR_RED "Script error, \"%s\" line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(), Printf (TEXTCOLOR_RED "Script error, \"%s\"" TEXTCOLOR_RED "line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(),
AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); AlreadyGot? AlreadyGotLine : Line, composed.GetChars());
} }

View file

@ -729,7 +729,6 @@ DEFINE_PROPERTY(translation, L, Actor)
else else
{ {
FRemapTable CurrentTranslation; FRemapTable CurrentTranslation;
bool success = true;
CurrentTranslation.MakeIdentity(); CurrentTranslation.MakeIdentity();
for(int i = 1; i < PROP_PARM_COUNT; i++) for(int i = 1; i < PROP_PARM_COUNT; i++)
@ -744,14 +743,17 @@ DEFINE_PROPERTY(translation, L, Actor)
else else
{ {
// parse all ranges to get a complete list of errors, if more than one range fails. // parse all ranges to get a complete list of errors, if more than one range fails.
success |= CurrentTranslation.AddToTranslation(str); try
{
CurrentTranslation.AddToTranslation(str);
}
catch (CRecoverableError &err)
{
bag.ScriptPosition.Message(MSG_WARNING, "Error in translation '%s':\n" TEXTCOLOR_CYAN "%s\n", str, err.GetMessage());
}
} }
} }
defaults->Translation = CurrentTranslation.StoreTranslation (TRANSLATION_Decorate); defaults->Translation = CurrentTranslation.StoreTranslation (TRANSLATION_Decorate);
if (!success)
{
bag.ScriptPosition.Message(MSG_WARNING, "Failed to parse translation");
}
} }
} }

View file

@ -49,6 +49,7 @@
#include "v_video.h" #include "v_video.h"
#include "v_text.h" #include "v_text.h"
#include "cmdlib.h" #include "cmdlib.h"
#include "doomerrors.h"
// On the Alpha, accessing the shorts directly if they aren't aligned on a // On the Alpha, accessing the shorts directly if they aren't aligned on a
// 4-byte boundary causes unaligned access warnings. Why it does this at // 4-byte boundary causes unaligned access warnings. Why it does this at
@ -954,7 +955,15 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init)
do do
{ {
sc.MustGetString(); sc.MustGetString();
part.Translation->AddToTranslation(sc.String);
try
{
part.Translation->AddToTranslation(sc.String);
}
catch (CRecoverableError &err)
{
sc.ScriptMessage("Error in translation '%s':\n" TEXTCOLOR_YELLOW "%s\n", sc.String, err.GetMessage());
}
} }
while (sc.CheckString(",")); while (sc.CheckString(","));
} }