diff --git a/src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/OutputTextLineParser.cs b/src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/OutputTextLineParser.cs index 2a4f202121..b9d1f5ffe7 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/OutputTextLineParser.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/OutputTextLineParser.cs @@ -14,6 +14,12 @@ namespace ICSharpCode.SharpDevelop.Gui /// Parses output text in the Output Build pad window and extracts source code /// file references. /// + /// + /// Supported formats: + /// C#: "d:\somedir\somefile.ext(12,34)" + /// NUnit: "in d:\somedir\somefile.ext:line 12" (stacktrace format) + /// C++: "d:\somedir\somefile.ext(12)" (also VB and some NUnit failures) + /// public static class OutputTextLineParser { /// @@ -25,7 +31,7 @@ namespace ICSharpCode.SharpDevelop.Gui public static FileLineReference GetCSharpCompilerFileLineReference(string lineText) { if (lineText != null) { - Match match = Regex.Match(lineText, @"^.*?(\w+:[/\\].*?)\(([\d]*),([\d]*)\)"); + Match match = Regex.Match(lineText, @"\b(\w:[/\\].*?)\((\d+),(\d+)\)"); if (match.Success) { try { // Take off 1 for line/col since SharpDevelop is zero index based. @@ -33,7 +39,8 @@ namespace ICSharpCode.SharpDevelop.Gui int col = Convert.ToInt32(match.Groups[3].Value) - 1; return new FileLineReference(match.Groups[1].Value, line, col); - } catch (Exception) { + } catch (FormatException) { + } catch (OverflowException) { // Ignore. } } @@ -65,7 +72,7 @@ namespace ICSharpCode.SharpDevelop.Gui } /// - /// Extracts source code file reference from NUnit output. + /// Extracts source code file reference from NUnit output. (stacktrace format) /// /// The text line to parse. /// The text is multilined. @@ -75,20 +82,23 @@ namespace ICSharpCode.SharpDevelop.Gui { RegexOptions regexOptions = multiline ? RegexOptions.Multiline : RegexOptions.None; + FileLineReference result = null; + if (lineText != null) { - Match match = Regex.Match(lineText, @"^.*?\sin\s(.*?):line\s(\d*)?\r?$", regexOptions); - - if (match.Success) { + Match match = Regex.Match(lineText, @"\sin\s(.*?):line\s(\d+)?\r?$", regexOptions); + while (match.Success) { try { int line = Convert.ToInt32(match.Groups[2].Value) - 1; - return new FileLineReference(match.Groups[1].Value, line); - } catch (Exception) { + result = new FileLineReference(match.Groups[1].Value, line); + } catch (FormatException) { + } catch (OverflowException) { // Ignore. } + match = match.NextMatch(); } } - return null; + return result; } /// @@ -101,7 +111,7 @@ namespace ICSharpCode.SharpDevelop.Gui { if (lineText != null ) { - Match match = Regex.Match(lineText, @"^.*?(\w+:[/\\].*?)\(([\d]*)\) :"); + Match match = Regex.Match(lineText, @"\b(\w:[/\\].*?)\((\d+)\)"); if (match.Success) { try { @@ -109,7 +119,8 @@ namespace ICSharpCode.SharpDevelop.Gui int line = Convert.ToInt32(match.Groups[2].Value) - 1; return new FileLineReference(match.Groups[1].Value.Trim(), line); - } catch (Exception) { + } catch (FormatException) { + } catch (OverflowException) { // Ignore. } } diff --git a/src/Main/Base/Test/OutputTextLineParserTestFixture.cs b/src/Main/Base/Test/OutputTextLineParserTestFixture.cs index 859199d081..9dfe451775 100644 --- a/src/Main/Base/Test/OutputTextLineParserTestFixture.cs +++ b/src/Main/Base/Test/OutputTextLineParserTestFixture.cs @@ -12,7 +12,7 @@ using System; namespace ICSharpCode.SharpDevelop.Tests { [TestFixture] - public class NUnitOutputParserTestFixture + public class OutputTextLineParserTests { [Test] public void Multiline() @@ -34,5 +34,35 @@ namespace ICSharpCode.SharpDevelop.Tests Assert.AreEqual(0, lineRef.Column); } + [Test] + public void MultipleLines() + { + string output = " at NunitFoo.Tests.FooTest.Foo() in c:\\test\\NunitFoo\\NunitFoo.Tests\\FooTest.cs:line 11\r\n" + + " at NunitFoo.Tests.FooTest.Foo() in c:\\test\\NunitFoo\\NunitFoo.Tests\\FooTest.cs:line 22\r\n"; + FileLineReference lineRef = OutputTextLineParser.GetNUnitOutputFileLineReference(output, true); + Assert.AreEqual(lineRef.FileName, "c:\\test\\NunitFoo\\NunitFoo.Tests\\FooTest.cs"); + Assert.AreEqual(21, lineRef.Line); + Assert.AreEqual(0, lineRef.Column); + } + + [Test] + public void NUnitConsoleFailure() + { + string output = "c:\\test\\NunitFoo\\NunitFoo.Tests\\FooTest.cs(22)"; + FileLineReference lineRef = OutputTextLineParser.GetFileLineReference(output); + Assert.AreEqual(lineRef.FileName, "c:\\test\\NunitFoo\\NunitFoo.Tests\\FooTest.cs"); + Assert.AreEqual(21, lineRef.Line); + Assert.AreEqual(0, lineRef.Column); + } + + [Test] + public void CompilerFailure() + { + string output = "c:\\test\\NunitFoo\\NunitFoo.Tests\\FooTest.cs(22,10)"; + FileLineReference lineRef = OutputTextLineParser.GetFileLineReference(output); + Assert.AreEqual(lineRef.FileName, "c:\\test\\NunitFoo\\NunitFoo.Tests\\FooTest.cs"); + Assert.AreEqual(21, lineRef.Line); + Assert.AreEqual(9, lineRef.Column); + } } }