@@ -102,35 +102,13 @@ public ParseResult Process()
102102
103103 private bool ProcessNext ( )
104104 {
105- switch ( _enumerator . Current )
105+ return _enumerator . Current switch
106106 {
107- case ArgumentSeparatorArgument _:
108- if ( ! ProcessArgumentSeparator ( ) )
109- {
110- return false ;
111- }
112-
113- break ;
114- case OptionArgument arg :
115- if ( ! ProcessOption ( arg ) )
116- {
117- return false ;
118- }
119-
120- break ;
121- case CommandOrParameterArgument arg :
122- if ( ! ProcessCommandOrParameter ( arg ) )
123- {
124- return false ;
125- }
126-
127- break ;
128- default :
129- HandleUnexpectedArg ( "command or argument" ) ;
130- return false ;
131- }
132-
133- return true ;
107+ ArgumentSeparatorArgument _ => ProcessArgumentSeparator ( ) ,
108+ OptionArgument arg => ProcessOption ( arg ) ,
109+ CommandOrParameterArgument arg => ProcessCommandOrParameter ( arg ) ,
110+ _ => ProcessUnexpectedArg ( "command or argument" ) ,
111+ } ;
134112 }
135113
136114 private bool ProcessCommandOrParameter ( CommandOrParameterArgument arg )
@@ -154,14 +132,10 @@ private bool ProcessCommandOrParameter(CommandOrParameterArgument arg)
154132 if ( _currentCommandArguments . MoveNext ( ) )
155133 {
156134 _currentCommandArguments . Current . Values . Add ( arg . Raw ) ;
157- }
158- else
159- {
160- HandleUnexpectedArg ( "command or argument" ) ;
161- return false ;
135+ return true ;
162136 }
163137
164- return true ;
138+ return ProcessUnexpectedArg ( "command or argument" ) ;
165139 }
166140
167141 private bool ProcessOption ( OptionArgument arg )
@@ -173,6 +147,7 @@ private bool ProcessOption(OptionArgument arg)
173147 {
174148 if ( _currentCommand . ClusterOptions )
175149 {
150+ var options = new List < CommandOption > ( ) ;
176151 for ( var i = 0 ; i < arg . Name . Length ; i ++ )
177152 {
178153 var ch = arg . Name . Substring ( i , 1 ) ;
@@ -187,56 +162,51 @@ private bool ProcessOption(OptionArgument arg)
187162
188163 if ( option == null )
189164 {
190- HandleUnexpectedArg ( "option" , "-" + ch ) ;
191- return false ;
165+ return ProcessUnexpectedArg ( "option" , "-" + ch ) ;
166+ }
167+
168+ options . Add ( option ) ;
169+
170+ if ( option . OptionType != CommandOptionType . NoValue &&
171+ option . OptionType != CommandOptionType . SingleOrNoValue )
172+ {
173+ break ;
192174 }
175+ }
176+
177+ for ( var i = 0 ; i < options . Count - 1 ; i ++ )
178+ {
179+ option = options [ i ] ;
180+ option . TryParse ( null ) ;
193181
194182 // If we find a help/version option, show information and stop parsing
195183 if ( _currentCommand . OptionHelp == option )
196184 {
197185 _currentCommand . ShowHelp ( ) ;
198- option . TryParse ( null ) ;
199186 return false ;
200187 }
201188
202189 if ( _currentCommand . OptionVersion == option )
203190 {
204191 _currentCommand . ShowVersion ( ) ;
205- option . TryParse ( null ) ;
206192 return false ;
207193 }
194+ }
208195
209- name = ch ;
196+ option = options . Last ( ) ;
197+ // supports specifying the value as the last bit of the flag. -Xignore-whitespace
198+ var trailingName = options . Count != arg . Name . Length
199+ ? arg . Name . Substring ( options . Count )
200+ : null ;
210201
211- var isLastChar = i == arg . Name . Length - 1 ;
212- if ( option . OptionType == CommandOptionType . NoValue )
213- {
214- if ( ! isLastChar )
215- {
216- option . TryParse ( null ) ;
217- }
218- }
219- else if ( option . OptionType == CommandOptionType . SingleOrNoValue )
220- {
221- if ( ! isLastChar )
222- {
223- option . TryParse ( null ) ;
224- }
225- }
226- else if ( ! isLastChar )
227- {
228- if ( value != null )
229- {
230- // if an option was also specified using :value or =value at the end of the option
231- _currentCommand . ShowHint ( ) ;
232- throw new CommandParsingException ( _currentCommand , $ "Option '{ ch } ', which requires a value, must be the last option in a cluster") ;
233- }
234-
235- // supports specifying the value as the last bit of the flag. -Xignore-whitespace
236- value = arg . Name . Substring ( i + 1 ) ;
237- break ;
238- }
202+ if ( value != null && trailingName != null )
203+ {
204+ // if an option was also specified using :value or =value at the end of the option
205+ _currentCommand . ShowHint ( ) ;
206+ throw new CommandParsingException ( _currentCommand , $ "Option '{ option . ShortName } ', which requires a value, must be the last option in a cluster") ;
239207 }
208+
209+ value ??= trailingName ;
240210 }
241211 else
242212 {
@@ -255,8 +225,7 @@ private bool ProcessOption(OptionArgument arg)
255225
256226 if ( option == null )
257227 {
258- HandleUnexpectedArg ( "option" ) ;
259- return false ;
228+ return ProcessUnexpectedArg ( "option" ) ;
260229 }
261230
262231 // If we find a help/version option, show information and stop parsing
@@ -350,7 +319,7 @@ private bool ProcessArgumentSeparator()
350319 {
351320 if ( ! _currentCommand . AllowArgumentSeparator )
352321 {
353- HandleUnexpectedArg ( "option" ) ;
322+ return ProcessUnexpectedArg ( "option" ) ;
354323 }
355324
356325 _enumerator . DisableResponseFileLoading = true ;
@@ -363,7 +332,7 @@ private bool ProcessArgumentSeparator()
363332 return false ;
364333 }
365334
366- private void HandleUnexpectedArg ( string argTypeName , string ? argValue = null )
335+ private bool ProcessUnexpectedArg ( string argTypeName , string ? argValue = null )
367336 {
368337 switch ( _config . UnrecognizedArgumentHandling )
369338 {
@@ -381,13 +350,18 @@ private void HandleUnexpectedArg(string argTypeName, string? argValue = null)
381350 throw new UnrecognizedCommandParsingException ( _currentCommand , suggestions ,
382351 $ "Unrecognized { argTypeName } '{ value } '") ;
383352
353+ case UnrecognizedArgumentHandling . CollectAndContinue :
354+ var arg = _enumerator . Current ;
355+ _currentCommand . RemainingArguments . Add ( arg . Raw ) ;
356+ return true ;
357+
384358 case UnrecognizedArgumentHandling . StopParsingAndCollect :
359+ // All remaining arguments are stored for further use
360+ AddRemainingArgumentValues ( ) ;
361+ return false ;
385362 default :
386- break ;
363+ throw new NotImplementedException ( ) ;
387364 }
388-
389- // All remaining arguments are stored for further use
390- AddRemainingArgumentValues ( ) ;
391365 }
392366
393367 private void AddRemainingArgumentValues ( )
0 commit comments