private static void MapValuesToProperties(ParseResult result, object instance, IDictionary cfgValues) { foreach (Argument arg in cfgValues.Values) { // Try with the name given. var configParamAttribute = (ConfigParamAttribute) paramMap[arg.Name]; if (configParamAttribute == null) { // If not, try mapping it from long->short or short->long to see if we find it var altName = nameMap[arg.Name]; if (altName != null) configParamAttribute = (ConfigParamAttribute) paramMap[altName]; } // If it's still null, give up, there's no param identified with that name if (configParamAttribute == null) { result.UpdateStatus(false, arg.Index, arg.RawValue, "Unrecognized parameter '{0}'", arg.RawName); return; } // Check for required value if (configParamAttribute.ValueRequired && (arg.Value == null || arg.Value.Trim().Length == 0)) { result.UpdateStatus(false, arg.Index, arg.Value, "A value is required for parameter '{0}'", arg.Name); } // Check for group stuff if (configParamAttribute.Group != null) { var paramGroup = (ParamGroup) groupMap[configParamAttribute.Group]; if (paramGroup.ValueParamName != null) { result.UpdateStatus(false, arg.Index, arg.Value, "Cannot specifiy more than one {0} argument (both '{1}' and '{2}' were specified)", paramGroup.Name, configParamAttribute.ParamNameLong, paramGroup.ValueParamName); return; } paramGroup.ValueParamName = configParamAttribute.ParamNameLong; paramGroup.Value = arg.Value; } if ((configParamAttribute.ValidValues != null && configParamAttribute.ValidValues.Length > 0) && (arg.Value == null || arg.Value.Trim().Length == 0)) { result.UpdateStatus(false, arg.Index, arg.Value, "Value for argument '{0}' is not valid. Valid values are: {1}", arg.Name, String.Join(", ", configParamAttribute.ValidValues)); return; } // Verify that it's among the required values if (configParamAttribute.ValidValues != null) { var valueFound = false; foreach (var value in configParamAttribute.ValidValues) { if (String.Compare(value, arg.Value, true) != 0) continue; valueFound = true; break; } if (! valueFound) { result.UpdateStatus(false, arg.Index, arg.Value, "Value for argument '{0}' is not valid. Valid values are: {1}", arg.Name, String.Join(", ", configParamAttribute.ValidValues)); return; } } // Assign the value object realVal; try { realVal = Convert.ChangeType(arg.Value ?? configParamAttribute.DefaultValue, configParamAttribute.Property.PropertyType); } catch { result.UpdateStatus(false, arg.Index, arg.Value, "Invalid value format (cannot parse)"); return; } configParamAttribute.Property.SetValue(instance, realVal, BindingFlags.Static, null, null, null); } }
public static ParseResult ParseCommandLine(string[] args) { var cfgValues = new Hashtable(StringComparer.InvariantCulture); if (args == null) throw new ArgumentNullException("args"); var parseResult = new ParseResult(); for (var i = 0; i < args.Length; i++) { var argument = args[i]; if (argument[0] == '/' || argument[0] == '-') { var argInst = new Argument {Index = i, RawName = argument, Name = argument.Substring(1)}; if (argument.Length == 1) { parseResult.UpdateStatus(false, i, argument); } // Look for a value after /foo in the next arg if ((i + 1) < args.Length) { string nextArg = args[i + 1]; argInst.RawValue = nextArg; //make sure the next arg isn't another arg (/bar) // NOTE: you can escape values that start with "/" or "-" with "//" or "--" // respectively if (nextArg[0] == '/') { if (nextArg.Length > 1) { if (nextArg[1] == '/') { // Remove the escaped '/' argInst.Value = nextArg.Substring(1); i++; } // else, the next arg is an actual /foo-type command, so just // let the next loop iteration pick it up } else { argInst.Value = nextArg; i++; } } else if (nextArg[0] == '-') { if (nextArg.Length > 1) { if (nextArg[1] == '-') { // Remove the escaped '-' argInst.Value = nextArg.Substring(1); i++; } // else, the next arg is an actual -foo-type command, so just // let the next loop iteration pick it up } else { argInst.Value = nextArg; i++; } } else { argInst.Value = nextArg; i++; } } cfgValues.Add(argInst.Name, argInst); } else { parseResult.UpdateStatus(false, i, argument); break; } } MapValuesToProperties(parseResult, null, cfgValues); // Check for unfulfilled required groups foreach (ParamGroup g in groupMap.Values) { if (g.Required && g.ValueParamName == null) { parseResult.UpdateStatus(false, g.Name); break; } } return parseResult; }