BadScript 2
Loading...
Searching...
No Matches
CommandLine.Core.Tokenizer Class Reference

Static Public Member Functions

static Result< IEnumerable< Token >, ErrorTokenize (IEnumerable< string > arguments, Func< string, NameLookupResult > nameLookup)
 
static Result< IEnumerable< Token >, ErrorTokenize (IEnumerable< string > arguments, Func< string, NameLookupResult > nameLookup, Func< IEnumerable< Token >, IEnumerable< Token > > normalize)
 
static Result< IEnumerable< Token >, ErrorPreprocessDashDash (IEnumerable< string > arguments, Func< IEnumerable< string >, Result< IEnumerable< Token >, Error > > tokenizer)
 
static Result< IEnumerable< Token >, ErrorExplodeOptionList (Result< IEnumerable< Token >, Error > tokenizerResult, Func< string, Maybe< char > > optionSequenceWithSeparatorLookup)
 
static IEnumerable< TokenNormalize (IEnumerable< Token > tokens, Func< string, bool > nameLookup)
 Normalizes the given tokens .
 
static Func< IEnumerable< string >, IEnumerable< OptionSpecification >, Result< IEnumerable< Token >, Error > > ConfigureTokenizer (StringComparer nameComparer, bool ignoreUnknownArguments, bool enableDashDash)
 

Static Private Member Functions

static IEnumerable< TokenTokenizeShortName (string value, Func< string, NameLookupResult > nameLookup)
 
static IEnumerable< TokenTokenizeLongName (string value, Action< Error > onError)
 

Detailed Description

Definition at line 16 of file Tokenizer.cs.

Member Function Documentation

◆ ConfigureTokenizer()

static Func< IEnumerable< string >, IEnumerable< OptionSpecification >, Result< IEnumerable< Token >, Error > > CommandLine.Core.Tokenizer.ConfigureTokenizer ( StringComparer  nameComparer,
bool  ignoreUnknownArguments,
bool  enableDashDash 
)
static

Definition at line 166 of file Tokenizer.cs.

169 {
170 return (arguments, optionSpecs) =>
171 {
172 Func<IEnumerable<Token>, IEnumerable<Token>> normalize = ignoreUnknownArguments
173 ? toks => Normalize(toks,
174 name =>
175 NameLookup.Contains(name,
176 optionSpecs,
177 nameComparer
178 ) !=
179 NameLookupResult.NoOptionFound
180 )
181 : new Func<IEnumerable<Token>,
182 IEnumerable<Token>>(toks => toks);
183
184 Result<IEnumerable<Token>, Error> tokens = enableDashDash
185 ? PreprocessDashDash(arguments,
186 args =>
187 Tokenize(args,
188 name => NameLookup.Contains(name,
189 optionSpecs,
190 nameComparer
191 ),
192 normalize
193 )
194 )
195 : Tokenize(arguments,
196 name => NameLookup.Contains(name,
197 optionSpecs,
198 nameComparer
199 ),
200 normalize
201 );
202
203 Result<IEnumerable<Token>, Error> explodedTokens =
204 ExplodeOptionList(tokens, name => NameLookup.HavingSeparator(name, optionSpecs, nameComparer));
205
206 return explodedTokens;
207 };
208 }
static Result< IEnumerable< Token >, Error > ExplodeOptionList(Result< IEnumerable< Token >, Error > tokenizerResult, Func< string, Maybe< char > > optionSequenceWithSeparatorLookup)
Definition Tokenizer.cs:74
static Result< IEnumerable< Token >, Error > Tokenize(IEnumerable< string > arguments, Func< string, NameLookupResult > nameLookup)
Definition Tokenizer.cs:18
static IEnumerable< Token > Normalize(IEnumerable< Token > tokens, Func< string, bool > nameLookup)
Normalizes the given tokens .
Definition Tokenizer.cs:127
static Result< IEnumerable< Token >, Error > PreprocessDashDash(IEnumerable< string > arguments, Func< IEnumerable< string >, Result< IEnumerable< Token >, Error > > tokenizer)
Definition Tokenizer.cs:54
Represents the result of a computation.

◆ ExplodeOptionList()

static Result< IEnumerable< Token >, Error > CommandLine.Core.Tokenizer.ExplodeOptionList ( Result< IEnumerable< Token >, Error tokenizerResult,
Func< string, Maybe< char > >  optionSequenceWithSeparatorLookup 
)
static

Definition at line 74 of file Tokenizer.cs.

77 {
78 IEnumerable<Token> tokens = tokenizerResult.SucceededWith()
79 .Memoize();
80
81 List<Token> exploded = new List<Token>(tokens is ICollection<Token> coll ? coll.Count : tokens.Count());
82 Maybe<char> nothing = Maybe.Nothing<char>(); // Re-use same Nothing instance for efficiency
83 Maybe<char> separator = nothing;
84
85 foreach (Token token in tokens)
86 {
87 if (token.IsName())
88 {
89 separator = optionSequenceWithSeparatorLookup(token.Text);
90 exploded.Add(token);
91 }
92 else
93 {
94 // Forced values are never considered option values, so they should not be split
95 if (separator.MatchJust(out char sep) && sep != '\0' && !token.IsValueForced())
96 {
97 if (token.Text.Contains(sep))
98 {
99 exploded.AddRange(token.Text.Split(sep)
100 .Select(Token.ValueFromSeparator)
101 );
102 }
103 else
104 {
105 exploded.Add(token);
106 }
107 }
108 else
109 {
110 exploded.Add(token);
111 }
112
113 separator = nothing; // Only first value after a separator can possibly be split
114 }
115 }
116
117 return Result.Succeed(exploded as IEnumerable<Token>, tokenizerResult.SuccessMessages());
118 }
The Maybe type models an optional value. A value of type Maybe a either contains a value of type a (r...
Definition Maybe.cs:33

◆ Normalize()

static IEnumerable< Token > CommandLine.Core.Tokenizer.Normalize ( IEnumerable< Token tokens,
Func< string, bool >  nameLookup 
)
static

Normalizes the given tokens .

Returns
The given tokens minus all names, and their value if one was present, that are not found using nameLookup .

Definition at line 127 of file Tokenizer.cs.

129 {
130 IEnumerable<Tuple<Token, Token>> toExclude =
131 from i in
132 tokens.Select((t, i) =>
133 {
134 if (t.IsName() == false || nameLookup(t.Text))
135 {
136 return Maybe.Nothing<Tuple<Token, Token>>();
137 }
138
139 Maybe<Token> next = tokens.ElementAtOrDefault(i + 1)
140 .ToMaybe();
141
142 bool removeValue = next.MatchJust(out Token nextValue) &&
143 next.MapValueOrDefault(p => p.IsValue() &&
144 ((Value)p).ExplicitlyAssigned,
145 false
146 );
147
148 return Maybe.Just(new Tuple<Token, Token>(t, removeValue ? nextValue : null));
149 }
150 )
151 .Where(i => i.IsJust())
152 select i.FromJustOrFail();
153
154 IEnumerable<Token> normalized =
155 tokens.Where(t => toExclude.Any(e => ReferenceEquals(e.Item1, t) || ReferenceEquals(e.Item2, t)) ==
156 false
157 );
158
159 return normalized;
160 }

◆ PreprocessDashDash()

static Result< IEnumerable< Token >, Error > CommandLine.Core.Tokenizer.PreprocessDashDash ( IEnumerable< string >  arguments,
Func< IEnumerable< string >, Result< IEnumerable< Token >, Error > >  tokenizer 
)
static

Definition at line 54 of file Tokenizer.cs.

58 {
59 if (arguments.Any(arg => arg.EqualsOrdinal("--")))
60 {
61 Result<IEnumerable<Token>, Error> tokenizerResult =
62 tokenizer(arguments.TakeWhile(arg => !arg.EqualsOrdinal("--")));
63
64 IEnumerable<Token> values = arguments.SkipWhile(arg => !arg.EqualsOrdinal("--"))
65 .Skip(1)
66 .Select(Token.ValueForced);
67
68 return tokenizerResult.Map(tokens => tokens.Concat(values));
69 }
70
71 return tokenizer(arguments);
72 }

◆ Tokenize() [1/2]

static Result< IEnumerable< Token >, Error > CommandLine.Core.Tokenizer.Tokenize ( IEnumerable< string >  arguments,
Func< string, NameLookupResult nameLookup 
)
static

Definition at line 18 of file Tokenizer.cs.

20 {
21 return Tokenize(arguments, nameLookup, tokens => tokens);
22 }

◆ Tokenize() [2/2]

static Result< IEnumerable< Token >, Error > CommandLine.Core.Tokenizer.Tokenize ( IEnumerable< string >  arguments,
Func< string, NameLookupResult nameLookup,
Func< IEnumerable< Token >, IEnumerable< Token > >  normalize 
)
static

Definition at line 24 of file Tokenizer.cs.

27 {
28 List<Error> errors = new List<Error>();
29 Action<Error> onError = errors.Add;
30
31 IEnumerable<Token> tokens = (from arg in arguments
32 from token in !arg.StartsWith("-", StringComparison.Ordinal) ? new[]
33 {
34 Token.Value(arg),
35 } :
36 arg.StartsWith("--", StringComparison.Ordinal) ?
37 TokenizeLongName(arg, onError) :
38 TokenizeShortName(arg, nameLookup)
39 select token)
40 .Memoize();
41
42 IEnumerable<Token> normalized = normalize(tokens)
43 .Memoize();
44
45 IEnumerable<Token> unkTokens =
46 (from t in normalized where t.IsName() && nameLookup(t.Text) == NameLookupResult.NoOptionFound select t)
47 .Memoize();
48
49 return Result.Succeed(normalized.Where(x => !unkTokens.Contains(x)),
50 errors.Concat(from t in unkTokens select new UnknownOptionError(t.Text))
51 );
52 }
static IEnumerable< Token > TokenizeShortName(string value, Func< string, NameLookupResult > nameLookup)
Definition Tokenizer.cs:210
static IEnumerable< Token > TokenizeLongName(string value, Action< Error > onError)
Definition Tokenizer.cs:270
@ UnknownOptionError
Value of CommandLine.UnknownOptionError type.

◆ TokenizeLongName()

static IEnumerable< Token > CommandLine.Core.Tokenizer.TokenizeLongName ( string  value,
Action< Error onError 
)
staticprivate

Definition at line 270 of file Tokenizer.cs.

272 {
273 if (value.Length > 2 && value.StartsWith("--", StringComparison.Ordinal))
274 {
275 string text = value.Substring(2);
276 int equalIndex = text.IndexOf('=');
277
278 if (equalIndex <= 0)
279 {
280 yield return Token.Name(text);
281
282 yield break;
283 }
284
285 if (equalIndex == 1) // "--="
286 {
287 onError(new BadFormatTokenError(value));
288
289 yield break;
290 }
291
292 Match tokenMatch = Regex.Match(text, "^([^=]+)=([^ ].*)$");
293
294 if (tokenMatch.Success)
295 {
296 yield return Token.Name(tokenMatch.Groups[1].Value);
297 yield return Token.Value(tokenMatch.Groups[2].Value, true);
298 }
299 else
300 {
301 onError(new BadFormatTokenError(value));
302 }
303 }
304 }
@ BadFormatTokenError
Value of CommandLine.BadFormatTokenError type.

◆ TokenizeShortName()

static IEnumerable< Token > CommandLine.Core.Tokenizer.TokenizeShortName ( string  value,
Func< string, NameLookupResult nameLookup 
)
staticprivate

Definition at line 210 of file Tokenizer.cs.

212 {
213 //Allow single dash as a value
214 if (value.Length == 1 && value[0] == '-')
215 {
216 yield return Token.Value(value);
217
218 yield break;
219 }
220
221 if (value.Length > 1 && value[0] == '-' && value[1] != '-')
222 {
223 string text = value.Substring(1);
224
225 if (char.IsDigit(text[0]))
226 {
227 yield return Token.Value(value);
228
229 yield break;
230 }
231
232 if (value.Length == 2)
233 {
234 yield return Token.Name(text);
235
236 yield break;
237 }
238
239 int i = 0;
240
241 foreach (char c in text)
242 {
243 string n = new string(c, 1);
244 NameLookupResult r = nameLookup(n);
245
246 // Assume first char is an option
247 if (i > 0 && r == NameLookupResult.NoOptionFound)
248 {
249 break;
250 }
251
252 i++;
253
254 yield return Token.Name(n);
255
256 // If option expects a value (other than a boolean), assume following chars are that value
257 if (r == NameLookupResult.OtherOptionFound)
258 {
259 break;
260 }
261 }
262
263 if (i < text.Length)
264 {
265 yield return Token.Value(text.Substring(i));
266 }
267 }
268 }

The documentation for this class was generated from the following file: