mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-22 03:41:47 +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)
|
||||
bcc
|
||||
{
|
||||
interface = "AccCompiler";
|
||||
interface = "BccCompiler";
|
||||
program = "bcc.exe";
|
||||
zcommon = "zcommon.bcs";
|
||||
std = "std.acs";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
URL https://ultimatedoombuilder.github.io/files/
|
||||
FileName Builder.exe
|
||||
UpdateName UltimateDoomBuilder-r[REVNUM]-x86.7z
|
||||
InstallerName UltimateDoomBuilder-Setup-R[REVNUM]-x86.exe
|
||||
UpdaterName UDB_Updater-x86.7z
|
||||
UpdateName UltimateDoomBuilder-r[REVNUM]-x64.7z
|
||||
InstallerName UltimateDoomBuilder-Setup-R[REVNUM]-x64.exe
|
||||
UpdaterName UDB_Updater-x64.7z
|
|
@ -141,6 +141,7 @@
|
|||
-->
|
||||
<ItemGroup>
|
||||
<Compile Include="Compilers\AccCompiler.cs" />
|
||||
<Compile Include="Compilers\BccCompiler.cs" />
|
||||
<Compile Include="Compilers\NodesCompiler.cs" />
|
||||
<Compile Include="Config\ArgumentInfo.cs" />
|
||||
<Compile Include="Config\ExternalCommandSettings.cs" />
|
||||
|
|
|
@ -30,11 +30,17 @@ using CodeImp.DoomBuilder.ZDoom.Scripting;
|
|||
|
||||
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
|
||||
|
||||
|
@ -75,11 +81,101 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
|
||||
#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
|
||||
public override bool Run()
|
||||
{
|
||||
Process process;
|
||||
int line = 0;
|
||||
string sourcedir = Path.GetDirectoryName(sourcefile);
|
||||
|
||||
// Preprocess the file
|
||||
|
@ -175,6 +271,8 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
processinfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
processinfo.WorkingDirectory = this.workingdir;
|
||||
|
||||
CompileContext context = OnBeforeProcessStart(processinfo);
|
||||
|
||||
// Output info
|
||||
General.WriteLogLine("Running compiler...");
|
||||
General.WriteLogLine("Program: " + processinfo.FileName);
|
||||
|
@ -198,86 +296,7 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
General.WriteLogLine("Compiler process has finished.");
|
||||
General.WriteLogLine("Compile time: " + deltatime.TotalSeconds.ToString("########0.00") + " seconds");
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
OnCheckError(includes, processinfo, process, context);
|
||||
|
||||
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