2
2
using MatthiWare . CommandLine . Abstractions . Command ;
3
3
using MatthiWare . CommandLine . Abstractions . Models ;
4
4
using MatthiWare . CommandLine . Abstractions . Parsing ;
5
- using MatthiWare . CommandLine . Core . Command ;
6
5
using MatthiWare . CommandLine . Core . Utils ;
7
6
using System ;
8
7
using System . Collections ;
9
8
using System . Collections . Generic ;
10
- using System . Linq ;
11
- using System . Text ;
12
9
13
10
namespace MatthiWare . CommandLine . Core . Parsing
14
11
{
@@ -21,6 +18,8 @@ public class ArgumentManager2 : IArgumentManager
21
18
22
19
private ProcessingContext CurrentContext { get ; set ; }
23
20
21
+ public List < ( string key , IArgument argument ) > UnusedArguments { get ; } = new List < ( string key , IArgument argument ) > ( ) ;
22
+
24
23
public bool TryGetValue ( IArgument argument , out ArgumentModel model ) => results . TryGetValue ( argument , out model ) ;
25
24
26
25
public ArgumentManager2 ( CommandLineParserOptions options , ICommandLineCommandContainer commandContainer )
@@ -37,43 +36,76 @@ public void Process(IReadOnlyList<string> arguments)
37
36
38
37
while ( enumerator . MoveNext ( ) )
39
38
{
40
- ProcessNext ( ) ;
39
+ var processed = ProcessNext ( ) ;
40
+
41
+ if ( ! processed )
42
+ {
43
+ var item = ( enumerator . Current . RawData , CurrentContext . CurrentOption != null ? ( IArgument ) CurrentContext . CurrentOption : ( IArgument ) CurrentContext . CurrentCommand ) ;
44
+ UnusedArguments . Add ( item ) ;
45
+ }
41
46
}
42
47
}
43
48
44
- private void ProcessNext ( )
49
+ private bool ProcessNext ( )
45
50
{
46
51
switch ( enumerator . Current )
47
52
{
48
53
case OptionRecord option :
49
- ProcessOption ( option ) ;
50
- break ;
54
+ return ProcessOption ( option ) ;
51
55
case CommandOrOptionValueRecord commandOrValue :
52
- ProcessCommandOrOptionValue ( commandOrValue ) ;
53
- break ;
56
+ return ProcessCommandOrOptionValue ( commandOrValue ) ;
57
+ default :
58
+ return false ;
59
+ }
60
+ }
61
+
62
+ private bool ProcessOption ( OptionRecord rec )
63
+ {
64
+ var foundOption = FindOption ( rec ) ;
65
+
66
+ if ( foundOption == null )
67
+ {
68
+ // In case we have an option named "-1" and int value -1. This causes confusion.
69
+ return ProcessCommandOrOptionValue ( rec ) ;
54
70
}
71
+
72
+ var argumentModel = new ArgumentModel ( rec . Name , rec . Value ) ;
73
+
74
+ results . Add ( foundOption , argumentModel ) ;
75
+
76
+ return true ;
55
77
}
56
78
57
- private void ProcessOption ( OptionRecord rec )
79
+ private ICommandLineOption FindOption ( OptionRecord rec )
58
80
{
59
- foreach ( var option in CurrentContext . CurrentCommand . Options )
81
+ var context = CurrentContext ;
82
+
83
+ while ( context != null )
60
84
{
61
- if ( ! rec . Name . EqualsIgnoreCase ( rec . IsLongOption ? option . LongName : option . ShortName ) )
85
+ foreach ( var option in context . CurrentCommand . Options )
62
86
{
63
- continue ;
64
- }
87
+ if ( ! rec . Name . EqualsIgnoreCase ( rec . IsLongOption ? option . LongName : option . ShortName ) )
88
+ {
89
+ continue ;
90
+ }
65
91
66
- var argumentModel = new ArgumentModel ( rec . Name , rec . Value ) ;
92
+ if ( results . ContainsKey ( option ) )
93
+ {
94
+ continue ;
95
+ }
67
96
68
- results . Add ( option , argumentModel ) ;
97
+ context . CurrentOption = option ;
69
98
70
- CurrentContext . CurrentOption = option ;
99
+ return option ;
100
+ }
71
101
72
- break ;
102
+ context = context . Parent ;
73
103
}
104
+
105
+ return null ;
74
106
}
75
107
76
- private void ProcessCommandOrOptionValue ( CommandOrOptionValueRecord rec )
108
+ private bool ProcessCommandOrOptionValue ( ArgumentRecord rec )
77
109
{
78
110
foreach ( var cmd in CurrentContext . CurrentCommand . Commands )
79
111
{
@@ -84,50 +116,44 @@ private void ProcessCommandOrOptionValue(CommandOrOptionValueRecord rec)
84
116
85
117
results . Add ( cmd , new ArgumentModel ( cmd . Name , null ) ) ;
86
118
87
- CurrentContext . CurrentCommand = ( ICommandLineCommandContainer ) cmd ;
119
+ CurrentContext = new ProcessingContext ( CurrentContext , ( ICommandLineCommandContainer ) cmd ) ;
88
120
89
- return ;
90
- }
91
-
92
- if ( CurrentContext . CurrentOption == null )
93
- {
94
- return ;
121
+ return true ;
95
122
}
96
123
97
- if ( ! TryGetValue ( CurrentContext . CurrentOption , out var model ) )
98
- {
99
- // not sure yet what to do here..
100
- // no option yet and not matching command => unknown item
101
- return ;
102
- }
124
+ var context = CurrentContext ;
103
125
104
- if ( model . HasValue )
126
+ while ( context != null )
105
127
{
106
- throw new ArgumentException ( "model already has a value????" ) ;
107
- }
108
-
109
- model . Value = rec . RawData ;
110
- }
128
+ if ( context . CurrentOption == null )
129
+ {
130
+ context = context . Parent ;
131
+ continue ;
132
+ }
111
133
112
- private IEnumerable < ICommandLineOption > GetOptions ( IEnumerable < ICommandLineOption > options , IEnumerable < CommandLineCommandBase > commands )
113
- {
114
- foreach ( var option in options )
115
- {
116
- yield return option ;
117
- }
134
+ if ( ! TryGetValue ( context . CurrentOption , out var model ) )
135
+ {
136
+ // not sure yet what to do here..
137
+ // no option yet and not matching command => unknown item
138
+ context = context . Parent ;
139
+ continue ;
140
+ }
118
141
119
- foreach ( var command in commands )
120
- {
121
- foreach ( var cmdOption in GetOptions ( command . Options , command . Commands . Cast < CommandLineCommandBase > ( ) ) )
142
+ if ( model . HasValue )
122
143
{
123
- yield return cmdOption ;
144
+ context = context . Parent ;
145
+ continue ;
124
146
}
147
+
148
+ model . Value = rec . RawData ;
149
+ return true ;
125
150
}
151
+
152
+ return false ;
126
153
}
127
154
128
155
private class ProcessingContext
129
156
{
130
-
131
157
public ICommandLineOption CurrentOption { get ; set ; }
132
158
public ProcessingContext Parent { get ; set ; }
133
159
public ICommandLineCommandContainer CurrentCommand { get ; set ; }
@@ -232,7 +258,7 @@ public OptionRecord(string data, string postfix, bool isLongOption)
232
258
Name = tokens [ 0 ] ;
233
259
}
234
260
235
- public bool IsLongOption { get ; }
261
+ public bool IsLongOption { get ; }
236
262
public string Name { get ; }
237
263
public string Value { get ; }
238
264
}
0 commit comments