/// <summary> /// <para> /// Overridden. Provides the actual paramater parsing mechanism, outputting results to the /// <paramref name="output"/> collection. /// </para> /// </summary> /// <param name="rawCommandLine"> /// A collection of <see cref="System.String"/> - the raw collection of string arguments received via the /// commandline. /// </param> /// <param name="longAliases"> /// A dictionary of <see cref="System.String"/> and a collection of <see cref="IParameter"/> /// </param> /// <param name="shortAliases"> /// A dictionary of <see cref="System.String"/> and a collection of <see cref="IParameter"/> /// </param> /// <param name="output"> /// A <see cref="ParsedParameters"/> /// </param> /// <returns> /// A <see cref="ParsedParameters"/> /// </returns> protected override void Parse(IList<string> rawCommandLine, IDictionary<string, IList<IParameter>> longAliases, IDictionary<string, IList<IParameter>> shortAliases, ref ParsedParameters output) { IList<IParameter> previousParameters = null; string previousArgument = null; foreach(string argument in rawCommandLine) { IList<IParameter> currentParameters = this.GetMatchingParameters(argument, longAliases, shortAliases); if(previousParameters != null && previousParameters.Count > 0 && previousParameters[0].Type == ParameterType.ValueRequired) { /* We are dealing with the value from a value-required parameter, store the results and remove the * reference to the previous parameter. */ foreach(IParameter param in previousParameters) { output.StoreResult(param, argument); } previousParameters = null; } else if(previousParameters != null && previousParameters.Count > 0 && previousParameters[0].Type == ParameterType.ValueOptional && currentParameters == null) { /* We are dealing with a value from a value-optional parameter - the argument does not look like a parameter * itself and so we treat it as the value, exactly as above. */ foreach(IParameter param in previousParameters) { output.StoreResult(param, argument); } previousParameters = null; } else if(currentParameters != null) { /* We are dealing with a new parameter definition. If there are parameters waiting to be stored then store * them and then deal with this new parameter. */ if(previousParameters != null) { foreach(IParameter param in previousParameters) { output.StoreResult(param, null); } previousParameters = null; } previousParameters = currentParameters; } else { // We are dealing with a non-parameter argument; store it. output.StoreResult(argument); } previousArgument = argument; } /* After we have finished parsing everything else, if we still have 'previous parameters' buffered and not * stored then store them unless they are "value required" parameters, in which case add their argument as a * non-parameter argument. */ if(previousParameters != null) { foreach(IParameter param in previousParameters) { if(param.Type != ParameterType.ValueRequired) { output.StoreResult(param, null); } else { output.StoreResult(previousArgument); } } } }
/// <summary> /// Parse the controller classes and the input parameters. /// Pass execution to a controller. /// </summary> /// <param name="args">Command line arguments</param> public static async Task <int> Run(string[] args) { CLI.ParseMetadata(); var cmd = new ParsedParameters(args); if (cmd.ShowHelpScreen) { // TODO: Show help screen return(1); } if (!controllers.ContainsKey(cmd.Controller)) { throw new CommandParserException($"Controller '{cmd.Controller}' is unknown."); } var ctr = controllers[cmd.Controller]; if (!ctr.Entries.ContainsKey(cmd.EntryPoint)) { throw new CommandParserException($"Controller '{cmd.Controller}' has no entry point '{cmd.EntryPoint}'."); } var entryPoint = ctr.Entries[cmd.EntryPoint]; /* * Invoke a method */ if (!entryPoint.MethodInfo.IsStatic) { throw new CommandParserException($"The method for entry point {cmd.Controller}/{cmd.EntryPoint} " + $"is not static. Method name: '{entryPoint.MethodInfo.Name}'"); } foreach (var p in entryPoint.Params) { if (!p.Value.Param.Optional && !cmd.Params.ContainsKey(p.Value.Param.Name)) { throw new CommandParserException($"Missing parameter '{p.Value.Param.Name}'."); } } object[] plist = null; if (entryPoint.Params.Count > 0) { plist = cmd.generateInvokeArray(entryPoint.Params.Values.Select(x => x.ParameterInfo).ToList()); } try { if (entryPoint.MethodInfo.ReturnType.Name.StartsWith("Task")) { await(Task) entryPoint.MethodInfo.Invoke(null, plist); } else { entryPoint.MethodInfo.Invoke(null, plist); } } catch (TargetInvocationException ex) { if (ex.InnerException != null) { throw(ex.InnerException); } else { throw ex; } } return(0); }