DECORATE parser: parse errors are more detailed now.

Fixed, DECORATE parser: error status was not cleared when switching to different resource.
Fixed, DECORATE parser: fixed a parse error when DB2-specific actor properties (like "//$category") were located outside of actor's scope.
This commit is contained in:
MaxED 2014-10-23 12:48:31 +00:00
parent badd7dcea8
commit 6df641564c
8 changed files with 61 additions and 37 deletions

View file

@ -1264,19 +1264,18 @@ namespace CodeImp.DoomBuilder.Data
// Load Decorate info cumulatively (the last Decorate is added to the previous)
// I'm not sure if this is the right thing to do though.
currentreader = dr;
List<Stream> decostreams = dr.GetDecorateData("DECORATE");
foreach(Stream decodata in decostreams)
Dictionary<string, Stream> decostreams = dr.GetDecorateData("DECORATE");
foreach(KeyValuePair<string, Stream> group in decostreams)
{
// Parse the data
decodata.Seek(0, SeekOrigin.Begin);
decorate.Parse(decodata, "DECORATE");
group.Value.Seek(0, SeekOrigin.Begin);
decorate.Parse(group.Value, group.Key, true);
// Check for errors
if(decorate.HasError)
{
General.ErrorLogger.Add(ErrorType.Error, "Unable to parse DECORATE data from location " +
dr.Location.location + ". " + decorate.ErrorDescription + " on line " + decorate.ErrorLine +
" in '" + decorate.ErrorSource + "'");
General.ErrorLogger.Add(ErrorType.Error, "DECORATE error in '" + decorate.ErrorSource
+ "', line " + decorate.ErrorLine + ". " + decorate.ErrorDescription + ".");
break;
}
}
@ -1353,11 +1352,11 @@ namespace CodeImp.DoomBuilder.Data
private void LoadDecorateFromLocation(DecorateParser parser, string location)
{
//General.WriteLogLine("Including DECORATE resource '" + location + "'...");
List<Stream> decostreams = currentreader.GetDecorateData(location);
foreach(Stream decodata in decostreams)
Dictionary<string, Stream> decostreams = currentreader.GetDecorateData(location);
foreach(KeyValuePair<string, Stream> group in decostreams)
{
// Parse this data
parser.Parse(decodata, location);
parser.Parse(group.Value, Path.Combine(currentreader.Location.location, group.Key));
}
}

View file

@ -156,7 +156,7 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Decorate, Modeldef, Mapinfo, Gldefs, etc...
// When implemented, this returns the decorate lump
public virtual List<Stream> GetDecorateData(string pname) { return new List<Stream>(); }
public virtual Dictionary<string, Stream> GetDecorateData(string pname) { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the Modeldef lump
public virtual Dictionary<string, Stream> GetModeldefData() { return new Dictionary<string, Stream>(); }

View file

@ -436,9 +436,9 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Decorate
// This finds and returns a sprite stream
public override List<Stream> GetDecorateData(string pname)
public override Dictionary<string, Stream> GetDecorateData(string pname)
{
List<Stream> streams = new List<Stream>();
Dictionary<string, Stream> result = new Dictionary<string, Stream>();
string[] allfilenames;
// Error when suspended
@ -451,10 +451,13 @@ namespace CodeImp.DoomBuilder.Data
if(filename.IndexOf('.') > -1)
{
string fullName = Path.Combine(pathname, filename);
if(FileExists(fullName)) {
if(FileExists(fullName))
{
allfilenames = new string[1];
allfilenames[0] = Path.Combine(pathname, filename);
} else {
}
else
{
allfilenames = new string[0];
General.ErrorLogger.Add(ErrorType.Warning, "Unable to load DECORATE file '" + fullName + "'");
}
@ -464,14 +467,20 @@ namespace CodeImp.DoomBuilder.Data
foreach(string foundfile in allfilenames)
{
streams.Add(LoadFile(foundfile));
result.Add(foundfile, LoadFile(foundfile));
}
// Find in any of the wad files
for(int i = wads.Count - 1; i >= 0; i--)
streams.AddRange(wads[i].GetDecorateData(pname));
return streams;
{
Dictionary<string, Stream> wadresult = wads[i].GetDecorateData(pname);
foreach(KeyValuePair<string, Stream> group in wadresult)
{
result.Add(group.Key, group.Value);
}
}
return result;
}
#endregion

View file

@ -791,24 +791,24 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Decorate, Gldefs, Mapinfo, etc...
// This finds and returns a sprite stream
public override List<Stream> GetDecorateData(string pname)
public override Dictionary<string, Stream> GetDecorateData(string pname)
{
// Error when suspended
if(issuspended) throw new Exception("Data reader is suspended");
List<Stream> streams = new List<Stream>();
Dictionary<string, Stream> result = new Dictionary<string, Stream>();
// Find all lumps named 'DECORATE'
int lumpindex = file.FindLumpIndex(pname);
while(lumpindex > -1)
{
streams.Add(file.Lumps[lumpindex].Stream);
result.Add(pname, file.Lumps[lumpindex].Stream);
// Find next
lumpindex = file.FindLumpIndex(pname, lumpindex + 1);
}
return streams;
return result;
}
//mxd

View file

@ -115,7 +115,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
//load mesh
MemoryStream ms = LoadFile(containers, mde.ModelNames[i], true);
if (ms == null) {
General.ErrorLogger.Add(ErrorType.Error, "ModelLoader: error while loading '" + mde.ModelNames[i] + "': unable to find file.");
General.ErrorLogger.Add(ErrorType.Error, "Error while loading '" + mde.ModelNames[i] + "': unable to find file.");
continue;
}
@ -133,7 +133,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
//got errors?
if(!String.IsNullOrEmpty(result.Errors)) {
General.ErrorLogger.Add(ErrorType.Error, "ModelLoader: error while loading '" + mde.ModelNames[i] + "': " + result.Errors);
General.ErrorLogger.Add(ErrorType.Error, "Error while loading '" + mde.ModelNames[i] + "': " + result.Errors);
} else {
//add loaded data to ModeldefEntry
mde.Model.Meshes.AddRange(result.Meshes);
@ -198,7 +198,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
//report errors
if(errors.Count > 0) {
foreach(string e in errors)
General.ErrorLogger.Add(ErrorType.Error, "ModelLoader: error while loading '" + mde.ModelNames[i] + "': " + e);
General.ErrorLogger.Add(ErrorType.Error, "Error while loading '" + mde.ModelNames[i] + "': " + e);
}
}
}

View file

@ -150,10 +150,16 @@ namespace CodeImp.DoomBuilder.ZDoom
break;
default:
// Check if numeric
if(!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out doomednum)) {
//mxd. Property begins with $? Then the whole line is a single value
if(token.StartsWith("$"))
{
// This is for editor-only properties such as $sprite and $category
props[token] = new List<string> { (parser.SkipWhitespace(false) ? parser.ReadLine() : "") };
}
else if(!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out doomednum)) // Check if numeric
{
// Not numeric!
parser.ReportError("Expected numeric editor thing number or start of actor scope while parsing '" + classname + "'");
parser.ReportError("Expected editor thing number or start of actor scope while parsing '" + classname + "'");
return;
}
break;
@ -313,12 +319,7 @@ namespace CodeImp.DoomBuilder.ZDoom
// Property begins with $? Then the whole line is a single value
if (token.StartsWith("$")) {
// This is for editor-only properties such as $sprite and $category
List<string> values = new List<string>();
if (parser.SkipWhitespace(false))
values.Add(parser.ReadLine());
else
values.Add("");
props[token] = values;
props[token] = new List<string> { (parser.SkipWhitespace(false) ? parser.ReadLine() : "") };
} else {
// Next tokens up until the next newline are values
List<string> values = new List<string>();

View file

@ -92,9 +92,9 @@ namespace CodeImp.DoomBuilder.ZDoom
// This parses the given decorate stream
// Returns false on errors
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename);
base.Parse(stream, sourcefilename, clearerrors);
// Keep local data
Stream localstream = datastream;

View file

@ -76,6 +76,21 @@ namespace CodeImp.DoomBuilder.ZDoom
// Returns false on errors
public virtual bool Parse(Stream stream, string sourcefilename)
{
return Parse(stream, sourcefilename, false);
}
// This parses the given decorate stream (mxd)
// Returns false on errors
public virtual bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
// Clear error status (mxd)
if(clearerrors)
{
errordesc = null;
errorsource = null;
errorline = -1;
}
datastream = stream;
datareader = new BinaryReader(stream, Encoding.ASCII);
sourcename = sourcefilename;