private static void SetValue(CommandProcessorOptions options, string optionName, object value) { try { options.SetValue(optionName, value); } catch (Exception ex) { if (Utils.IsFatalOrUnexpected(ex)) { throw; } options.AddError(ex); } }
// Instead of throwing exceptions we pass the first exception that happens as an out parameter. This lets us parse as many // arguments as we can correctly so we can respect options like noLogo and verbosity when showing errors. internal static CommandProcessorOptions ParseCommand(string[] cmd) { var options = new CommandProcessorOptions(); // work around https://github.com/dotnet/core-setup/issues/619 to ignore additionalprobingpath cmd = cmd.Where(c => !c.ToLowerInvariant().Contains("additionalprobingpath")).ToArray(); for (int i = 0; i < cmd.Length; i++) { string arg = cmd[i]?.Trim('\"').Trim(); if (string.IsNullOrWhiteSpace(arg)) { continue; } // if argument does not start with switch indicator, place into "default" arguments if (IsArgumentValue(arg)) { SetValue(options, CommandProcessorOptions.InputsKey, Environment.ExpandEnvironmentVariables(arg)); continue; } // check if this switch exists in the list of possible switches var argSwitch = CommandSwitch.FindSwitch(arg); var argValue = cmd.Length > i + 1 ? cmd[i + 1] : null; if (argSwitch == null) { options.AddError(string.Format(SR.ErrUnknownSwitchFormat, arg)); continue; } // we have a valid switch, now validate value. // make sure there's a value for the parameter. switch (argSwitch.SwitchType) { case SwitchType.Flag: argValue = "true"; break; case SwitchType.FlagOrSingletonValue: argValue = (argValue == null || !IsArgumentValue(argValue)) ? string.Empty : argValue; break; case SwitchType.SingletonValue: case SwitchType.ValueList: if (string.IsNullOrWhiteSpace(argValue) || !IsArgumentValue(argValue)) { options.AddError(string.Format(SR.ErrArgumentWithoutValue, argSwitch.Name)); continue; } break; } // check if switch is allowed to be specified multiple times // if not and it has already been specified and a new value has been parsed. if (argSwitch.SwitchType != SwitchType.ValueList && options.GetValue <object>(argSwitch.Name) != null) { options.AddError(string.Format(SR.ErrSingleUseSwitchFormat, argSwitch.Name)); continue; } SetValue(options, argSwitch.Name, argValue.Trim('\"').Trim()); if (argSwitch.SwitchType != SwitchType.Flag && argValue != string.Empty && IsArgumentValue(argValue)) { i++; // move to next input. } } return(options); }