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
|
// Copyright © Microsoft Corporation.
// This source file is subject to the Microsoft Permissive License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.
using System;
using System.IO;
using System.Collections.Generic;
using System.Collections;
namespace Microsoft.Ddue.Tools.CommandLine {
public sealed class OptionCollection : ICollection < Option >, ICollection, IEnumerable < Option >, IEnumerable {
private Dictionary < string, Option > map = new Dictionary < string, Option >();
private List < Option > options = new List < Option >();
public int Count {
get {
return (options.Count);
}
}
// Extras for ICollection<Option>
bool ICollection < Option >.IsReadOnly {
get {
return (false);
}
}
// Extras for ICollection
bool ICollection.IsSynchronized {
get {
return (false);
}
}
Object ICollection.SyncRoot {
get {
return (this);
}
}
public Option this[string name] {
get {
Option option;
if (map.TryGetValue(name, out option)) {
return (option);
} else {
return (null);
}
}
}
public void Add(Option option) {
if (option == null) throw new ArgumentNullException("option");
map.Add(option.Name, option);
options.Add(option);
}
public void Clear() {
options.Clear();
map.Clear();
}
bool ICollection < Option >.Contains(Option option) {
return (options.Contains(option));
}
void ICollection < Option >.CopyTo(Option[] array, int startIndex) {
options.CopyTo(array, startIndex);
}
void ICollection.CopyTo(Array array, int startIndex) {
((ICollection)options).CopyTo(array, startIndex);
}
// Extras for IEnumerable<Option>
IEnumerator < Option > IEnumerable < Option >.GetEnumerator() {
return (options.GetEnumerator());
}
// Extras for IEnumerable
IEnumerator IEnumerable.GetEnumerator() {
return (options.GetEnumerator());
}
// Parse arguments -- the main show
public ParseArgumentsResult ParseArguments(string[] args) {
// keep track of results
ParseArgumentsResult results = new ParseArgumentsResult();
results.options = this;
// parse arguments
ParseArguments(args, results);
return (results);
}
public bool Remove(Option option) {
int index = options.IndexOf(option);
if (index < 0) return (false);
options.RemoveAt(index);
map.Remove(option.Name);
return (true);
}
// Print help
public void WriteOptionSummary(TextWriter writer) {
if (writer == null) throw new ArgumentNullException("writer");
foreach (Option option in options) {
writer.WriteLine();
option.WriteTemplate(writer);
writer.WriteLine(option.Description);
}
}
private void ParseArguments(string[] args, ParseArgumentsResult results) {
foreach (string arg in args) {
if (arg.Length == 0) continue;
if (arg[0] == '/') {
// option processing
// find the named option
int index = 1;
while (index < arg.Length) {
if ((!Char.IsLetter(arg, index)) && (arg[index] != '?')) break;
index++;
}
string key = arg.Substring(1, index - 1);
string value = arg.Substring(index);
// invoke the appropriate logic
if (map.ContainsKey(key)) {
Option option = (Option)map[key];
ParseResult result = option.ParseArgument(value);
if (result != ParseResult.Success) {
results.errors.Add(arg, result);
}
} else {
results.errors.Add(arg, ParseResult.UnrecognizedOption);
}
} else if (arg[0] == '@') {
string responseFile = arg.Substring(1);
List < string > responses = new List < string >();
using (TextReader reader = File.OpenText(responseFile)) {
while (true) {
string response = reader.ReadLine();
if (response == null) break;
responses.Add(response);
}
}
ParseArguments(responses.ToArray(), results);
} else {
// non-option processing
results.nonoptions.Add(arg);
}
}
// make sure the required arguments were present
foreach (Option option in map.Values) {
option.processed = true;
if ((option.IsRequired) && (!option.IsPresent)) {
results.errors.Add(option.Name, ParseResult.MissingOption);
}
}
}
}
}
|