-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVariableSet.cs
More file actions
133 lines (108 loc) · 4.24 KB
/
Copy pathVariableSet.cs
File metadata and controls
133 lines (108 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace JSIL.Compiler {
public class VariableSet {
private readonly Dictionary<string, Func<string>> Values = new Dictionary<string, Func<string>>();
private static readonly Regex VariableRegex = new Regex(
"\\%(?'variablename'[^\\%]*)\\%", RegexOptions.Compiled
);
public VariableSet () {
Values["jsildirectory"] = Program.GetJSILDirectory;
}
private VariableSet (VariableSet other) {
foreach (var kvp in other.Values)
Values.Add(kvp.Key, kvp.Value);
Values["jsildirectory"] = Program.GetJSILDirectory;
}
public IEnumerable<string> DefinedVariables {
get {
foreach (var key in Values.Keys)
yield return String.Format("%{0}%", key);
}
}
public void Add (string key, string value) {
Values.Add(key.ToLower(), () => value);
}
public void Add (string key, Func<string> value) {
Values.Add(key.ToLower(), value);
}
public Func<string> this[string key] {
set {
Values[key.ToLower()] = value;
}
}
private string Expander (string text, Match match) {
if (match.Groups["variablename"].Success) {
var key = match.Groups["variablename"].Value.ToLower();
Func<string> variableFn;
string variableValue;
if (Values.TryGetValue(key, out variableFn)) {
return variableFn();
} else if ((variableValue = Environment.GetEnvironmentVariable(key)) != null) {
return variableValue;
} else {
throw new VariableExpansionException(
text, this, key
);
}
}
// Expansion failed
return match.Value;
}
public string Expand (string text) {
if (text == null)
return null;
var result = text;
bool needAnotherPass = true;
while (needAnotherPass) {
needAnotherPass = false;
var expanded = VariableRegex.Replace(
result, (m) => Expander(text, m)
);
if (expanded != result) {
needAnotherPass = true;
result = expanded;
}
}
return result;
}
public string ExpandPath (string path, bool requireExists) {
var result = Expand(path);
if (result != null)
result = result.Replace('/', System.IO.Path.DirectorySeparatorChar);
if (!requireExists)
return result;
if ((result != null) && (File.Exists(result) || Directory.Exists(result)))
return result;
else
throw new FileNotFoundException(result ?? path);
}
public VariableSet Clone () {
return new VariableSet(this);
}
internal void SetAssemblyPath (string filename) {
var assemblyPath = Path.GetDirectoryName(Path.GetFullPath(filename));
this["AssemblyDirectory"] = () => assemblyPath;
this["AssemblyName"] = () => Path.GetFileName(filename);
this["AssemblyNameWithoutExtension"] = () => Path.GetFileNameWithoutExtension(filename);
}
}
public class VariableExpansionException : Exception {
public VariableExpansionException (string text, VariableSet vs, string missingKey)
: base (
MakeExceptionMessage(text, vs, missingKey)
) {
}
private static string MakeExceptionMessage (string text, VariableSet vs, string missingKey) {
return String.Format(
"Failed to expand '{0}' because the variable '{1}' does not exist.\r\nValid variables at this location:\r\n{2}",
text, missingKey,
String.Join("\r\n", vs.DefinedVariables.OrderBy((v) => v))
);
}
}
}