Skip to content

Commit 109d4d1

Browse files
committed
Merge pull request #159 from vosen/master
Make debugging options page nicer
2 parents 1a6fb00 + 55d4e88 commit 109d4d1

12 files changed

+546
-121
lines changed

VisualRust.Project/EnvironmentPath.cs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
using NUnit.Framework;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace VisualRust.Project
10+
{
11+
static class EnvironmentPath
12+
{
13+
public static string FindExePath(string name)
14+
{
15+
string extensionsVariable = Environment.GetEnvironmentVariable("PATHEXT") ?? ".COM;.EXE";
16+
string[] extensions = extensionsVariable.Split(new [] {";"}, StringSplitOptions.RemoveEmptyEntries);
17+
string[] fileNames = extensions.Where(s => s.StartsWith(".")).Select(e => name + e).ToArray();
18+
foreach(string path in SplitPaths(Environment.GetEnvironmentVariable("PATH") ?? ""))
19+
{
20+
foreach(string file in fileNames)
21+
{
22+
string fullPath = Path.Combine(path, file);
23+
if(File.Exists(fullPath))
24+
return fullPath;
25+
}
26+
}
27+
return null;
28+
}
29+
30+
private static List<string> SplitPaths(string path)
31+
{
32+
int i = 0;
33+
List<string> result = new List<string>();
34+
while(i < path.Length)
35+
{
36+
int start = i;
37+
int end;
38+
if(path[start] == '"')
39+
{
40+
start++;
41+
end = path.IndexOf('"', start);
42+
if (end == -1)
43+
{
44+
end = path.Length;
45+
i = path.Length;
46+
}
47+
else
48+
{
49+
int semi = path.IndexOf(';', end);
50+
if(semi == -1)
51+
i = path.Length;
52+
else
53+
i = semi + 1;
54+
}
55+
}
56+
else
57+
{
58+
end = path.IndexOf(';', start);
59+
if (end == -1)
60+
{
61+
end = path.Length;
62+
i = path.Length;
63+
}
64+
else
65+
{
66+
i = end + 1;
67+
}
68+
}
69+
result.Add(path.Substring(start, end - start));
70+
}
71+
return result;
72+
}
73+
74+
#if TEST
75+
[TestFixture]
76+
private class Test
77+
{
78+
[Test]
79+
public void SplitPathsPlain()
80+
{
81+
CollectionAssert.AreEquivalent(
82+
new String[] { @"D:\dev\Rust\bin", @"D:\dev\LLVM\bin" },
83+
SplitPaths(@"D:\dev\LLVM\bin;D:\dev\Rust\bin"));
84+
}
85+
86+
[Test]
87+
public void SplitPathsSingleChars()
88+
{
89+
CollectionAssert.AreEquivalent(
90+
new String[] { "C", "D" },
91+
SplitPaths("C;D"));
92+
}
93+
94+
[Test]
95+
public void SplitPathsExtraSemicolon()
96+
{
97+
CollectionAssert.AreEquivalent(
98+
new String[] { @"D:\dev\Rust\bin", @"D:\dev\LLVM\bin" },
99+
SplitPaths(@"D:\dev\LLVM\bin;D:\dev\Rust\bin;"));
100+
}
101+
102+
[Test]
103+
public void SplitPathsQuoted()
104+
{
105+
CollectionAssert.AreEquivalent(
106+
new String[] { @"D:\dev\LLVM\bin", @"C:\main() {printf('%d', 42);}" },
107+
SplitPaths(@"D:\dev\LLVM\bin;""C:\main() {printf('%d', 42);}"""));
108+
}
109+
110+
[Test]
111+
public void SplitPathsQuotedExtraSemicolon()
112+
{
113+
CollectionAssert.AreEquivalent(
114+
new String[] { @"D:\dev\LLVM\bin", @"C:\main() {printf('%d', 42);}" },
115+
SplitPaths(@"D:\dev\LLVM\bin;""C:\main() {printf('%d', 42);}"";"));
116+
}
117+
}
118+
#endif
119+
}
120+
}

VisualRust.Project/Feature.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using Microsoft.VisualStudio;
2+
using Microsoft.VisualStudio.Shell.Interop;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace VisualRust.Project
10+
{
11+
public static class Feature
12+
{
13+
public static bool Gdb(IServiceProvider provider)
14+
{
15+
return IsVs14OrHigher(provider) && IsGdbEngineInstalled(provider);
16+
}
17+
18+
private static bool IsVs14OrHigher(IServiceProvider provider)
19+
{
20+
var dte = provider.GetService(typeof(SDTE)) as EnvDTE.DTE;
21+
if(dte == null)
22+
return false;
23+
Version ver;
24+
if (!Version.TryParse(dte.Version, out ver))
25+
return false;
26+
return ver.Major >= 14;
27+
}
28+
29+
private static bool IsGdbEngineInstalled(IServiceProvider provider)
30+
{
31+
var debugger = provider.GetService(typeof(SVsShellDebugger)) as IVsDebugger2;
32+
if(debugger == null)
33+
return false;
34+
Guid gdbEngine = Constants.GdbEngine;
35+
string _;
36+
return debugger.GetEngineName(ref gdbEngine, out _) == VSConstants.S_OK;
37+
}
38+
}
39+
}

VisualRust.Project/VisualRust.Project.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@
108108
<DependentUpon>Build.tt</DependentUpon>
109109
</Compile>
110110
<Compile Include="DefaultRustLauncher.cs" />
111+
<Compile Include="EnvironmentPath.cs" />
112+
<Compile Include="Feature.cs" />
111113
<Compile Include="FolderNode.cs" />
112114
<Compile Include="Forms\BuildPropertyControl.cs">
113115
<SubType>UserControl</SubType>

VisualRust/Forms/DebuggingDisabledControl.Designer.cs

Lines changed: 97 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel;
4+
using System.Drawing;
5+
using System.Data;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
using System.Windows.Forms;
10+
11+
namespace VisualRust.Forms
12+
{
13+
public partial class DebuggingDisabledControl : UserControl
14+
{
15+
public DebuggingDisabledControl()
16+
{
17+
InitializeComponent();
18+
}
19+
}
20+
}

VisualRust/Resources.resx renamed to VisualRust/Forms/DebuggingDisabledControl.resx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<!--
3-
VS SDK Notes: This resx file contains the resources that will be consumed directly by your package.
4-
For example, if you chose to create a tool window, there is a resource with ID 'CanNotCreateWindow'. This
5-
is used in VsPkg.cs to determine the string to show the user if there is an error when attempting to create
6-
the tool window.
7-
8-
Resources that are accessed directly from your package *by Visual Studio* are stored in the VSPackage.resx
9-
file.
10-
-->
112
<root>
123
<!--
134
Microsoft ResX Schema
@@ -126,4 +117,14 @@
126117
<resheader name="writer">
127118
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
128119
</resheader>
120+
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
121+
<data name="pictureBox1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
122+
<value>
123+
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1
124+
MAAA6mAAADqYAAAXb5JfxUYAAAAJcEhZcwAADsQAAA7EAZUrDhsAAACiSURBVDhPrVPBDYMwEMsIfXSQ
125+
jpANGaEjMFU/fOgC1XG+3AkrTZAgWDIgx7Y4SJKIDLFcCJ9nyspZKRWhZbft4AI1vCnQ4+T2gijAAgxL
126+
fhkpYKz0vQQFKuC1zfD7rkYu6ehlHC+wmcMIhLmlecHMBSH+BTphY7MA5BKgFXY+7i/gMO78XJfwCMMf
127+
cew3Aipc30gBLETggO2tHFDD+cN0nZI2dKMrgybRTIQAAAAASUVORK5CYII=
128+
</value>
129+
</data>
129130
</root>

VisualRust/Forms/DebuggingOptionsPage.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,48 @@
22
using System.Runtime.InteropServices;
33
using System.Windows.Forms;
44
using Microsoft.VisualStudio.Shell;
5+
using VisualRust.Forms;
6+
using VisualRust.Project;
57

68
namespace VisualRust.Options
79
{
810
[ComVisible(true)]
911
[Guid("93F42A39-0AF6-40EE-AE2C-1C44AB5F8B15")]
1012
public partial class DebuggingOptionsPage : DialogPage
1113
{
14+
public bool UseCustomGdbPath { get; set; }
1215
public string DebuggerLocation { get; set; }
1316
public string ExtraArgs { get; set; }
1417

15-
private DebuggingOptionsPageControl _page;
18+
private IWin32Window page;
1619

1720
protected override IWin32Window Window
1821
{
1922
get
2023
{
21-
_page = new DebuggingOptionsPageControl();
22-
_page.LoadSettings(this);
23-
return _page;
24+
if(page != null)
25+
return page;
26+
if(Feature.Gdb(this.Site))
27+
page = new DebuggingOptionsPageControl(this);
28+
else
29+
page = new DebuggingDisabledControl();
30+
return page;
2431
}
2532
}
2633

2734
protected override void OnClosed(EventArgs e)
2835
{
29-
_page.LoadSettings(this);
36+
var debugControl = page as DebuggingOptionsPageControl;
37+
if(debugControl != null)
38+
debugControl.LoadSettings(this);
3039
base.OnClosed(e);
3140
}
3241

3342
protected override void OnApply(PageApplyEventArgs e)
3443
{
35-
if (e.ApplyBehavior == ApplyKind.Apply)
36-
_page.ApplySettings(this);
44+
var debugControl = page as DebuggingOptionsPageControl;
45+
if (e.ApplyBehavior == ApplyKind.Apply && debugControl != null)
46+
debugControl.ApplySettings(this);
3747
base.OnApply(e);
3848
}
3949
}

0 commit comments

Comments
 (0)