mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-22 11:51:25 +00:00
Fixed BCS compiler error reporting
This commit is contained in:
parent
14a494078a
commit
4e34897ac1
5 changed files with 192 additions and 89 deletions
|
@ -7,7 +7,7 @@ compilers
|
||||||
// All others are the required files (the setting names do not matter)
|
// All others are the required files (the setting names do not matter)
|
||||||
bcc
|
bcc
|
||||||
{
|
{
|
||||||
interface = "AccCompiler";
|
interface = "BccCompiler";
|
||||||
program = "bcc.exe";
|
program = "bcc.exe";
|
||||||
zcommon = "zcommon.bcs";
|
zcommon = "zcommon.bcs";
|
||||||
std = "std.acs";
|
std = "std.acs";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
URL https://ultimatedoombuilder.github.io/files/
|
URL https://ultimatedoombuilder.github.io/files/
|
||||||
FileName Builder.exe
|
FileName Builder.exe
|
||||||
UpdateName UltimateDoomBuilder-r[REVNUM]-x86.7z
|
UpdateName UltimateDoomBuilder-r[REVNUM]-x64.7z
|
||||||
InstallerName UltimateDoomBuilder-Setup-R[REVNUM]-x86.exe
|
InstallerName UltimateDoomBuilder-Setup-R[REVNUM]-x64.exe
|
||||||
UpdaterName UDB_Updater-x86.7z
|
UpdaterName UDB_Updater-x64.7z
|
|
@ -141,6 +141,7 @@
|
||||||
-->
|
-->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Compilers\AccCompiler.cs" />
|
<Compile Include="Compilers\AccCompiler.cs" />
|
||||||
|
<Compile Include="Compilers\BccCompiler.cs" />
|
||||||
<Compile Include="Compilers\NodesCompiler.cs" />
|
<Compile Include="Compilers\NodesCompiler.cs" />
|
||||||
<Compile Include="Config\ArgumentInfo.cs" />
|
<Compile Include="Config\ArgumentInfo.cs" />
|
||||||
<Compile Include="Config\ExternalCommandSettings.cs" />
|
<Compile Include="Config\ExternalCommandSettings.cs" />
|
||||||
|
|
|
@ -30,11 +30,17 @@ using CodeImp.DoomBuilder.ZDoom.Scripting;
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.Compilers
|
namespace CodeImp.DoomBuilder.Compilers
|
||||||
{
|
{
|
||||||
internal sealed class AccCompiler : Compiler
|
internal class AccCompiler : Compiler
|
||||||
{
|
{
|
||||||
#region ================== Constants
|
#region ================== Internal classes
|
||||||
|
|
||||||
private const string ACS_ERROR_FILE = "acs.err";
|
protected class CompileContext { }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Constants
|
||||||
|
|
||||||
|
private const string ACS_ERROR_FILE = "acs.err";
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -75,11 +81,101 @@ namespace CodeImp.DoomBuilder.Compilers
|
||||||
|
|
||||||
#region ================== Methods
|
#region ================== Methods
|
||||||
|
|
||||||
|
protected virtual CompileContext OnBeforeProcessStart(ProcessStartInfo info)
|
||||||
|
{
|
||||||
|
return new CompileContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnCheckError(HashSet<string> includes, ProcessStartInfo processinfo, Process process, CompileContext context)
|
||||||
|
{
|
||||||
|
int line = 0;
|
||||||
|
|
||||||
|
// Now find the error file
|
||||||
|
string errfile = Path.Combine(this.workingdir, ACS_ERROR_FILE);
|
||||||
|
if (File.Exists(errfile))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Regex to find error lines
|
||||||
|
Regex errlinematcher = new Regex(":[0-9]+: ", RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||||
|
|
||||||
|
// Read all lines
|
||||||
|
bool erroradded = false; //mxd
|
||||||
|
string[] errlines = File.ReadAllLines(errfile);
|
||||||
|
string temppath = this.tempdir.FullName + Path.DirectorySeparatorChar.ToString(); //mxd. Need trailing slash..
|
||||||
|
while (line < errlines.Length)
|
||||||
|
{
|
||||||
|
// Check line
|
||||||
|
string linestr = errlines[line];
|
||||||
|
Match match = errlinematcher.Match(linestr);
|
||||||
|
if (match.Success && (match.Index > 0))
|
||||||
|
{
|
||||||
|
CompilerError err = new CompilerError();
|
||||||
|
|
||||||
|
// The match without spaces and semicolon is the line number
|
||||||
|
string linenr = match.Value.Replace(":", "").Trim();
|
||||||
|
if (!int.TryParse(linenr, out err.linenumber))
|
||||||
|
err.linenumber = CompilerError.NO_LINE_NUMBER;
|
||||||
|
else
|
||||||
|
err.linenumber--;
|
||||||
|
|
||||||
|
// Everything before the match is the filename
|
||||||
|
err.filename = linestr.Substring(0, match.Index).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||||
|
|
||||||
|
//mxd. Get rid of temp directory path
|
||||||
|
if (err.filename.StartsWith(temppath)) err.filename = err.filename.Replace(temppath, string.Empty);
|
||||||
|
|
||||||
|
if (!Path.IsPathRooted(err.filename))
|
||||||
|
{
|
||||||
|
//mxd. If the error is in an include file, try to find it in loaded resources
|
||||||
|
if (includes.Contains(err.filename))
|
||||||
|
{
|
||||||
|
foreach (DataReader dr in General.Map.Data.Containers)
|
||||||
|
{
|
||||||
|
if (dr is DirectoryReader && dr.FileExists(err.filename))
|
||||||
|
{
|
||||||
|
err.filename = Path.Combine(dr.Location.location, err.filename);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add working directory to filename, so it could be recognized as map namespace lump in MapManager.CompileLump()
|
||||||
|
err.filename = Path.Combine(processinfo.WorkingDirectory, err.filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything after the match is the description
|
||||||
|
err.description = linestr.Substring(match.Index + match.Length).Trim();
|
||||||
|
|
||||||
|
// Report the error
|
||||||
|
ReportError(err);
|
||||||
|
erroradded = true; //mxd
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next line
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//mxd. Some ACC errors are not properly formatted. If that's the case, threat the whole acs.err as an error...
|
||||||
|
if (!erroradded && errlines.Length > 0)
|
||||||
|
{
|
||||||
|
ReportError(new CompilerError(string.Join(Environment.NewLine, errlines)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// Error reading errors (ironic, isn't it)
|
||||||
|
ReportError(new CompilerError("Failed to retrieve compiler error report. " + e.GetType().Name + ": " + e.Message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This runs the compiler
|
// This runs the compiler
|
||||||
public override bool Run()
|
public override bool Run()
|
||||||
{
|
{
|
||||||
Process process;
|
Process process;
|
||||||
int line = 0;
|
|
||||||
string sourcedir = Path.GetDirectoryName(sourcefile);
|
string sourcedir = Path.GetDirectoryName(sourcefile);
|
||||||
|
|
||||||
// Preprocess the file
|
// Preprocess the file
|
||||||
|
@ -175,6 +271,8 @@ namespace CodeImp.DoomBuilder.Compilers
|
||||||
processinfo.WindowStyle = ProcessWindowStyle.Hidden;
|
processinfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||||
processinfo.WorkingDirectory = this.workingdir;
|
processinfo.WorkingDirectory = this.workingdir;
|
||||||
|
|
||||||
|
CompileContext context = OnBeforeProcessStart(processinfo);
|
||||||
|
|
||||||
// Output info
|
// Output info
|
||||||
General.WriteLogLine("Running compiler...");
|
General.WriteLogLine("Running compiler...");
|
||||||
General.WriteLogLine("Program: " + processinfo.FileName);
|
General.WriteLogLine("Program: " + processinfo.FileName);
|
||||||
|
@ -198,86 +296,7 @@ namespace CodeImp.DoomBuilder.Compilers
|
||||||
General.WriteLogLine("Compiler process has finished.");
|
General.WriteLogLine("Compiler process has finished.");
|
||||||
General.WriteLogLine("Compile time: " + deltatime.TotalSeconds.ToString("########0.00") + " seconds");
|
General.WriteLogLine("Compile time: " + deltatime.TotalSeconds.ToString("########0.00") + " seconds");
|
||||||
|
|
||||||
// Now find the error file
|
OnCheckError(includes, processinfo, process, context);
|
||||||
string errfile = Path.Combine(this.workingdir, ACS_ERROR_FILE);
|
|
||||||
if(File.Exists(errfile))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Regex to find error lines
|
|
||||||
Regex errlinematcher = new Regex(":[0-9]+: ", RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
|
||||||
|
|
||||||
// Read all lines
|
|
||||||
bool erroradded = false; //mxd
|
|
||||||
string[] errlines = File.ReadAllLines(errfile);
|
|
||||||
string temppath = this.tempdir.FullName + Path.DirectorySeparatorChar.ToString(); //mxd. Need trailing slash..
|
|
||||||
while(line < errlines.Length)
|
|
||||||
{
|
|
||||||
// Check line
|
|
||||||
string linestr = errlines[line];
|
|
||||||
Match match = errlinematcher.Match(linestr);
|
|
||||||
if(match.Success && (match.Index > 0))
|
|
||||||
{
|
|
||||||
CompilerError err = new CompilerError();
|
|
||||||
|
|
||||||
// The match without spaces and semicolon is the line number
|
|
||||||
string linenr = match.Value.Replace(":", "").Trim();
|
|
||||||
if(!int.TryParse(linenr, out err.linenumber))
|
|
||||||
err.linenumber = CompilerError.NO_LINE_NUMBER;
|
|
||||||
else
|
|
||||||
err.linenumber--;
|
|
||||||
|
|
||||||
// Everything before the match is the filename
|
|
||||||
err.filename = linestr.Substring(0, match.Index).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
|
||||||
|
|
||||||
//mxd. Get rid of temp directory path
|
|
||||||
if(err.filename.StartsWith(temppath)) err.filename = err.filename.Replace(temppath, string.Empty);
|
|
||||||
|
|
||||||
if(!Path.IsPathRooted(err.filename))
|
|
||||||
{
|
|
||||||
//mxd. If the error is in an include file, try to find it in loaded resources
|
|
||||||
if(includes.Contains(err.filename))
|
|
||||||
{
|
|
||||||
foreach(DataReader dr in General.Map.Data.Containers)
|
|
||||||
{
|
|
||||||
if(dr is DirectoryReader && dr.FileExists(err.filename))
|
|
||||||
{
|
|
||||||
err.filename = Path.Combine(dr.Location.location, err.filename);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Add working directory to filename, so it could be recognized as map namespace lump in MapManager.CompileLump()
|
|
||||||
err.filename = Path.Combine(processinfo.WorkingDirectory, err.filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Everything after the match is the description
|
|
||||||
err.description = linestr.Substring(match.Index + match.Length).Trim();
|
|
||||||
|
|
||||||
// Report the error
|
|
||||||
ReportError(err);
|
|
||||||
erroradded = true; //mxd
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next line
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//mxd. Some ACC errors are not properly formatted. If that's the case, threat the whole acs.err as an error...
|
|
||||||
if(!erroradded && errlines.Length > 0)
|
|
||||||
{
|
|
||||||
ReportError(new CompilerError(string.Join(Environment.NewLine, errlines)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
// Error reading errors (ironic, isn't it)
|
|
||||||
ReportError(new CompilerError("Failed to retrieve compiler error report. " + e.GetType().Name + ": " + e.Message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
83
Source/Core/Compilers/BccCompiler.cs
Normal file
83
Source/Core/Compilers/BccCompiler.cs
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
using CodeImp.DoomBuilder.Config;
|
||||||
|
using CodeImp.DoomBuilder.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace CodeImp.DoomBuilder.Compilers
|
||||||
|
{
|
||||||
|
internal class BccCompiler : AccCompiler
|
||||||
|
{
|
||||||
|
public BccCompiler(CompilerInfo info) : base(info) {}
|
||||||
|
|
||||||
|
protected override CompileContext OnBeforeProcessStart(ProcessStartInfo info)
|
||||||
|
{
|
||||||
|
info.UseShellExecute = false;
|
||||||
|
info.CreateNoWindow = true;
|
||||||
|
info.RedirectStandardError = true;
|
||||||
|
info.RedirectStandardOutput = true;
|
||||||
|
return new CompileContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnCheckError(HashSet<string> includes, ProcessStartInfo processinfo, Process process, CompileContext context)
|
||||||
|
{
|
||||||
|
if (process.ExitCode != 0)
|
||||||
|
{
|
||||||
|
bool foundAnyErrors = false;
|
||||||
|
string[] errorLines = process.StandardOutput.ReadToEnd().Split('\n');
|
||||||
|
|
||||||
|
foreach (string rawErrorLine in errorLines)
|
||||||
|
{
|
||||||
|
string[] rawError = rawErrorLine.Split(new char[] { ':' }, 4);
|
||||||
|
if (rawError.Length != 4)
|
||||||
|
continue;
|
||||||
|
string errorFile = rawError[0];
|
||||||
|
int errorLine;
|
||||||
|
if (!int.TryParse(rawError[1], out errorLine))
|
||||||
|
continue;
|
||||||
|
errorLine--;
|
||||||
|
// rawError[2] is ignored. in BCC, this contains the column at which the error happened. not supported in error viewer.
|
||||||
|
string errorContent = rawError[3].Trim();
|
||||||
|
|
||||||
|
// logic copied from AccCompiler
|
||||||
|
string temppath = this.tempdir.FullName + Path.DirectorySeparatorChar.ToString(); //mxd. Need trailing slash..
|
||||||
|
if (errorFile.StartsWith(temppath)) errorFile = errorFile.Replace(temppath, string.Empty);
|
||||||
|
|
||||||
|
if (!Path.IsPathRooted(errorFile))
|
||||||
|
{
|
||||||
|
//mxd. If the error is in an include file, try to find it in loaded resources
|
||||||
|
if (includes.Contains(errorFile))
|
||||||
|
{
|
||||||
|
foreach (DataReader dr in General.Map.Data.Containers)
|
||||||
|
{
|
||||||
|
if (dr is DirectoryReader && dr.FileExists(errorFile))
|
||||||
|
{
|
||||||
|
errorFile = Path.Combine(dr.Location.location, errorFile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add working directory to filename, so it could be recognized as map namespace lump in MapManager.CompileLump()
|
||||||
|
errorFile = Path.Combine(processinfo.WorkingDirectory, errorFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end logic copied from AccCompiler
|
||||||
|
|
||||||
|
CompilerError err = new CompilerError();
|
||||||
|
err.linenumber = errorLine;
|
||||||
|
err.filename = errorFile;
|
||||||
|
err.description = errorContent;
|
||||||
|
|
||||||
|
ReportError(err);
|
||||||
|
foundAnyErrors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundAnyErrors)
|
||||||
|
ReportError(new CompilerError(string.Join(Environment.NewLine, errorLines)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue