forked from de4dot/de4dot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOption.cs
207 lines (161 loc) · 5.48 KB
/
Option.cs
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*
Copyright (C) 2011-2015 [email protected]
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Text.RegularExpressions;
namespace de4dot.code {
public abstract class Option {
const string SHORTNAME_PREFIX = "-";
const string LONGNAME_PREFIX = "--";
string shortName;
string longName;
string description;
object defaultVal;
public string ShortName => shortName;
public string LongName => longName;
public string Description => description;
public object Default {
get => defaultVal;
protected set => defaultVal = value;
}
public virtual bool NeedArgument => true;
public virtual string ArgumentValueName => "value";
// Returns true if the new value is set, or false on error. error string is also updated.
public abstract bool Set(string val, out string error);
public Option(string shortName, string longName, string description) {
if (shortName != null)
this.shortName = SHORTNAME_PREFIX + shortName;
if (longName != null)
this.longName = LONGNAME_PREFIX + longName;
this.description = description;
}
}
public class BoolOption : Option {
bool val;
public BoolOption(string shortName, string longName, string description, bool val)
: base(shortName, longName, description) => Default = this.val = val;
public override string ArgumentValueName => "bool";
public override bool Set(string newVal, out string error) {
if (string.Equals(newVal, "false", StringComparison.OrdinalIgnoreCase) ||
string.Equals(newVal, "off", StringComparison.OrdinalIgnoreCase) ||
string.Equals(newVal, "0", StringComparison.OrdinalIgnoreCase)) {
val = false;
}
else
val = true;
error = "";
return true;
}
public bool Get() => val;
}
public class IntOption : Option {
int val;
public IntOption(string shortName, string longName, string description, int val)
: base(shortName, longName, description) => Default = this.val = val;
public override string ArgumentValueName => "int";
public override bool Set(string newVal, out string error) {
if (!int.TryParse(newVal, out int newInt)) {
error = $"Not an integer: '{newVal}'";
return false;
}
val = newInt;
error = "";
return true;
}
public int Get() => val;
}
public class StringOption : Option {
string val;
public override string ArgumentValueName => "string";
public StringOption(string shortName, string longName, string description, string val)
: base(shortName, longName, description) => Default = this.val = val;
public override bool Set(string newVal, out string error) {
val = newVal;
error = "";
return true;
}
public string Get() => val;
}
public class NameRegexOption : Option {
NameRegexes val;
public override string ArgumentValueName => "regex";
public NameRegexOption(string shortName, string longName, string description, string val)
: base(shortName, longName, description) => Default = this.val = new NameRegexes(val);
public override bool Set(string newVal, out string error) {
try {
var regexes = new NameRegexes();
regexes.Set(newVal);
val = regexes;
}
catch (ArgumentException) {
error = $"Could not parse regex '{newVal}'";
return false;
}
error = "";
return true;
}
public NameRegexes Get() => val;
}
public class RegexOption : Option {
Regex val;
public override string ArgumentValueName => "regex";
public RegexOption(string shortName, string longName, string description, string val)
: base(shortName, longName, description) => Default = this.val = new Regex(val);
public override bool Set(string newVal, out string error) {
try {
val = new Regex(newVal);
}
catch (ArgumentException) {
error = $"Could not parse regex '{newVal}'";
return false;
}
error = "";
return true;
}
public Regex Get() => val;
}
public class NoArgOption : Option {
Action action;
bool triggered;
public override bool NeedArgument => false;
public NoArgOption(string shortName, string longName, string description)
: this(shortName, longName, description, null) {
}
public NoArgOption(string shortName, string longName, string description, Action action)
: base(shortName, longName, description) => this.action = action;
public override bool Set(string val, out string error) {
triggered = true;
action?.Invoke();
error = "";
return true;
}
public bool Get() => triggered;
}
public class OneArgOption : Option {
Action<string> action;
string typeName;
public override string ArgumentValueName => typeName;
public OneArgOption(string shortName, string longName, string description, string typeName, Action<string> action)
: base(shortName, longName, description) {
this.typeName = typeName ?? "value";
this.action = action;
Default = null;
}
public override bool Set(string val, out string error) {
action(val);
error = "";
return true;
}
}
}