/// <summary> /// Constructor /// </summary> /// <param name="optDefs">The supported options</param> /// <param name="valuesDictionary">The dictionary that will be used to store /// the values of the options</param> public DictionaryParserHelper(OptionDefinition[] optDefs, IDictionary valuesDictionary) { _optionsByName = new Hashtable(); _optionsByLowerName = new Hashtable(); foreach (OptionDefinition optDef in optDefs) { if (optDef.LongNames != null) { foreach (string name in optDef.LongNames) { _optionsByName.Add(name, optDef); // allow duplicate definitions of lower case names (don't use add) _optionsByLowerName[name.ToLower()] = optDef; } } if (optDef.ShortNames != null) { foreach (char name in optDef.ShortNames) { _optionsByName.Add(name, optDef); // allow duplicate definitions of lower case names (don't use add) _optionsByLowerName[char.ToLower(name)] = optDef; } } } _results = valuesDictionary; }
/// <summary> /// Helper method to create <c>OptionDefinition</c> instances /// for each <c>string</c> in <c>definitions</c> /// </summary> /// <param name="definitions">Definitions (See <see cref="OptionDefinition(string)"/>)</param> /// <returns><c>OptionDefinition</c> instances</returns> public static OptionDefinition[] CreateDefinitions(string[] definitions) { OptionDefinition[] defs = new OptionDefinition[definitions.Length]; for (int i = 0; i < definitions.Length; i++) defs[i] = new OptionDefinition(definitions[i]); return defs; }
/// <summary> /// Check if the option definition does not allow a value and if a value was given /// </summary> /// <param name="optDef">The option definition</param> /// <param name="value">The value given or null if one was not given</param> /// <exception cref="ParseException">Thrown if value was given to a type /// that doesn't support a value</exception> private void CheckIfValueless(OptionDefinition optDef, string value) { // make sure value is not null (or empty) if (value == null || value == string.Empty) { return; } switch (optDef.Type) { // types that allow values: case OptValType.MultValue: case OptValType.ValueOpt: case OptValType.ValueReq: return; default: throw new ParseException( string.Format("Value given to option {0} that does not support a value", optDef.ID)); } }
private OptionDefinition BuildOptDef(OptDefAttribute defAttr, MemberInfo info) { ArrayList nameDefinitions; Attribute[] attrs; CategoryAttribute catAttr; DefaultValueAttribute defValAttr; DescriptionAttribute descAttr; OptionDefinition def; UseNameAsLongOptionAttribute useNameAttr; Type type; bool useName = false; char[] shortNames = null; string category; string description; string[] longNames = null; // Get the description descAttr = (DescriptionAttribute)GetAttribute(typeof(DescriptionAttribute), info); description = (descAttr == null) ? info.Name : descAttr.Description; // Get the category catAttr = (CategoryAttribute)GetAttribute(typeof(CategoryAttribute), info); category = (catAttr == null) ? null : catAttr.Category; // use the name as a value? useNameAttr = (UseNameAsLongOptionAttribute)GetAttribute( typeof(UseNameAsLongOptionAttribute), info); useName = (useNameAttr == null) ? true : useNameAttr.UseName; nameDefinitions = new ArrayList(); attrs = (Attribute[])info.GetCustomAttributes(typeof(ShortOptionNameAttribute), true); if (attrs != null) { int counter = 0; shortNames = new char[attrs.Length]; foreach (ShortOptionNameAttribute attr in attrs) { shortNames[counter] = attr.Name; counter++; } } attrs = (Attribute[])info.GetCustomAttributes(typeof(LongOptionNameAttribute), true); if (attrs != null) { int count = (useName) ? attrs.Length + 1 : attrs.Length; int counter = 0; longNames = new string[count]; foreach (LongOptionNameAttribute attr in attrs) { longNames[counter] = attr.Name; counter++; } if (useName) longNames[longNames.Length - 1] = info.Name; } if (defAttr.ValueType == null) { if (defAttr.OptionValueType == OptValType.MultValue) throw new ParseException("Multiple value options must have the " + "ValueType property set in the OptDefAttribute declaration"); defAttr.ValueType = (info is FieldInfo) ? ((FieldInfo)info).FieldType : ((PropertyInfo)info).PropertyType; } if (defAttr.ValueType == null) { if (info is PropertyInfo) type = ((PropertyInfo)info).PropertyType; else type = ((FieldInfo)info).FieldType; } else type = defAttr.ValueType; def = new OptionDefinition(info.Name, defAttr.OptionValueType, type, category, description, shortNames, longNames); // Get the default value defValAttr = (DefaultValueAttribute)GetAttribute(typeof(DefaultValueAttribute), info); if (defValAttr != null) def.DefaultValue = defValAttr.Value; return def; }
private OptionResult GetResult(OptionDefinition def, MemberInfo info) { OptionResult result = new OptionResult(def); object val; if (info is FieldInfo) val = ((FieldInfo)info).GetValue(_value); else val = ((PropertyInfo)info).GetValue(_value, null); switch (result.Defintion.Type) { case OptValType.Flag: bool isSet; if (val is bool) isSet = (bool)val; else isSet = Convert.ToBoolean(val); result.NumDefinitions = 1; result.Value = isSet; break; case OptValType.IncrementalFlag: int numSet; numSet = Convert.ToInt32(val); result.NumDefinitions = numSet; result.Value = numSet; break; case OptValType.MultValue: foreach (object value in (ICollection)val) { result.NumDefinitions++; result.AddValue(value); } break; case OptValType.ValueOpt: case OptValType.ValueReq: if (val == null) { result.NumDefinitions = 0; result.Value = null; } else { result.NumDefinitions = 1; result.Value = val; } break; } return result; }
/// <summary> /// Adds an option to the output /// </summary> /// <remarks>Like <see cref="BeginOption"/>, but uses the desription from the /// option as the body of the "description" tag. Does not open a new active tag</remarks> /// <param name="opt">Option to add</param> public void AddOption(OptionDefinition opt) { BeginOption(opt); _currentNode.InnerText = opt.Description; EndOption(); }
private OptionDefinition BuildOptDef(OptDefAttribute defAttr, MemberInfo info) { ArrayList nameDefinitions; Attribute[] attrs; CategoryAttribute catAttr; DefaultValueAttribute defValAttr; DescriptionAttribute descAttr; OptionDefinition def; UseNameAsLongOptionAttribute useNameAttr; Type type; bool useName = false; char[] shortNames = null; string category; string description; string[] longNames = null; // Get the description descAttr = (DescriptionAttribute)GetAttribute(typeof(DescriptionAttribute), info); description = (descAttr == null) ? info.Name : descAttr.Description; // Get the category catAttr = (CategoryAttribute)GetAttribute(typeof(CategoryAttribute), info); category = (catAttr == null) ? null : catAttr.Category; // use the name as a value? useNameAttr = (UseNameAsLongOptionAttribute)GetAttribute( typeof(UseNameAsLongOptionAttribute), info); useName = (useNameAttr == null) ? true : useNameAttr.UseName; nameDefinitions = new ArrayList(); attrs = (Attribute[])info.GetCustomAttributes(typeof(ShortOptionNameAttribute), true); if (attrs != null) { int counter = 0; shortNames = new char[attrs.Length]; foreach (ShortOptionNameAttribute attr in attrs) { shortNames[counter] = attr.Name; counter++; } } attrs = (Attribute[])info.GetCustomAttributes(typeof(LongOptionNameAttribute), true); if (attrs != null) { int count = (useName) ? attrs.Length + 1 : attrs.Length; int counter = 0; longNames = new string[count]; foreach (LongOptionNameAttribute attr in attrs) { longNames[counter] = attr.Name; counter++; } if (useName) { longNames[longNames.Length - 1] = info.Name; } } if (defAttr.ValueType == null) { if (defAttr.OptionValueType == OptValType.MultValue) { throw new ParseException("Multiple value options must have the " + "ValueType property set in the OptDefAttribute declaration"); } defAttr.ValueType = (info is FieldInfo) ? ((FieldInfo)info).FieldType : ((PropertyInfo)info).PropertyType; } if (defAttr.ValueType == null) { if (info is PropertyInfo) { type = ((PropertyInfo)info).PropertyType; } else { type = ((FieldInfo)info).FieldType; } } else { type = defAttr.ValueType; } def = new OptionDefinition(info.Name, defAttr.OptionValueType, type, category, description, shortNames, longNames); // Get the default value defValAttr = (DefaultValueAttribute)GetAttribute(typeof(DefaultValueAttribute), info); if (defValAttr != null) { def.DefaultValue = defValAttr.Value; } return(def); }
/// <summary> /// See <see cref="P:IOptionResults.Item(OptionDefinition)"/> /// </summary> public OptionResult this[OptionDefinition def] { get { return (OptionResult)_results[def]; } set { _results[def] = value; } }
/// <summary> /// Method to start adding an option to the usage. /// <seealso cref="AddOption"/> /// </summary> /// <remarks>Leaves the "description" tag as the active tag. Allows paragraph /// and list content to be added to the description of an option beyond /// the normal description. Does not include the description body from /// the <paramref name="opt"/> (must be added manually). Call /// <see cref="EndOption"/> to close this tag.</remarks> /// <param name="opt">Option to start</param> public void BeginOption(OptionDefinition opt) { ValidateCurrentNode("options", "category"); if (_groupOptionsByCategory) { XmlNode node; string cat = opt.Category; if (cat == null) cat = _defaultOptionCategory; node = _currentNode.SelectSingleNode("category[@name='" + cat + "']"); if (node == null) { _currentNode = _currentNode.AppendChild(_usage.CreateElement("category")); _currentNode.Attributes.Append(_usage.CreateAttribute("name")).Value = cat; } else _currentNode = node; } _currentNode = _currentNode.AppendChild(_usage.CreateElement("option")); _currentNode.Attributes.Append(_usage.CreateAttribute("type")).Value = EnumDescriptorReader.GetEnumFieldDescription(opt.Type); // names _currentNode = _currentNode.AppendChild(_usage.CreateElement("names")); foreach (char name in opt.ShortNames) { _currentNode = _currentNode.AppendChild(_usage.CreateElement("name")); _currentNode.Attributes.Append(_usage.CreateAttribute("value")).Value = name.ToString(); _currentNode.Attributes.Append(_usage.CreateAttribute("type")).Value = "short"; _currentNode = _currentNode.ParentNode; } foreach (string name in opt.LongNames) { _currentNode = _currentNode.AppendChild(_usage.CreateElement("name")); _currentNode.Attributes.Append(_usage.CreateAttribute("value")).Value = name; _currentNode.Attributes.Append(_usage.CreateAttribute("type")).Value = "long"; _currentNode = _currentNode.ParentNode; } _currentNode = _currentNode.ParentNode; if (opt.ValueType != null) { if (typeof(ValueType).IsAssignableFrom(opt.ValueType) || opt.ValueType.Namespace == "System") _currentNode.AppendChild(_usage.CreateElement("valueType")).InnerText = opt.ValueType.Name; else _currentNode.AppendChild(_usage.CreateElement("valueType")).InnerText = opt.ValueType.ToString(); } if (opt.DefaultValue != null) _currentNode.AppendChild(_usage.CreateElement("defaultValue")).InnerText = opt.DefaultValue.ToString(); _currentNode = _currentNode.AppendChild(_usage.CreateElement("description")); }
/// <summary> /// Get or set result by definition /// </summary> public OptionResult this[OptionDefinition key] { get { return (OptionResult)base.Dictionary[key]; } set { base.Dictionary[key] = value; } }
/// <summary> /// See <see cref="P:IOptionResults.Item(OptionDefinition)"/> /// </summary> public OptionResult this[OptionDefinition def] { get { MemberInfo info = (MemberInfo)_memberInfoObjs[def]; if (info == null) return null; return GetResult(def, info); } set { MemberInfo info = (MemberInfo)_memberInfoObjs[def]; if (info == null) throw new ArgumentException("No such option defintion found", "def"); UpdateResult(info, value); } }
/// <summary> /// See <see cref="P:IOptionResults.Item(OptionDefinition)"/> /// </summary> public OptionResult this[OptionDefinition def] { get { return((OptionResult)_results[def]); } set { _results[def] = value; } }
/// <summary> /// Add a result /// </summary> /// <param name="key">Option definition</param> /// <param name="value">Result value</param> public void Add(OptionDefinition key, OptionResult value) { base.Dictionary.Add(key, value); }
/// <summary> /// See <see cref="IOptionContainer.GetOptions()"/> /// </summary> public OptionDefinition[] GetOptions() { OptionDefinition[] options = new OptionDefinition[_results.Count]; _results.Keys.CopyTo(options, 0); return(options); }
/// <summary> /// See <see cref="IOptionContainer.GetOptions()"/> /// </summary> public OptionDefinition[] GetOptions() { OptionDefinition[] options = new OptionDefinition[_memberInfoObjs.Count]; _memberInfoObjs.Keys.CopyTo(options, 0); return(options); }
private OptionResult GetResult(OptionDefinition def, MemberInfo info) { OptionResult result = new OptionResult(def); object val; if (info is FieldInfo) { val = ((FieldInfo)info).GetValue(_value); } else { val = ((PropertyInfo)info).GetValue(_value, null); } switch (result.Defintion.Type) { case OptValType.Flag: bool isSet; if (val is bool) { isSet = (bool)val; } else { isSet = Convert.ToBoolean(val); } result.NumDefinitions = 1; result.Value = isSet; break; case OptValType.IncrementalFlag: int numSet; numSet = Convert.ToInt32(val); result.NumDefinitions = numSet; result.Value = numSet; break; case OptValType.MultValue: foreach (object value in (ICollection)val) { result.NumDefinitions++; result.AddValue(value); } break; case OptValType.ValueOpt: case OptValType.ValueReq: if (val == null) { result.NumDefinitions = 0; result.Value = null; } else { result.NumDefinitions = 1; result.Value = val; } break; } return(result); }
/// <summary> /// Add a result /// </summary> /// <param name="key">Option definition</param> /// <param name="value">Result value</param> public void Add(OptionDefinition key, OptionResult value) { base.Dictionary.Add(key, value); }
/// <summary> /// Constructor /// </summary> /// <param name="def">Definition of the option this result if for</param> public OptionResult(OptionDefinition def) { _defintion = def; }
/// <summary> /// See <see cref="IOptionContainer.GetOptions()"/> /// </summary> public OptionDefinition[] GetOptions() { OptionDefinition[] options = new OptionDefinition[_memberInfoObjs.Count]; _memberInfoObjs.Keys.CopyTo(options, 0); return options; }
/// <summary> /// Parse an option /// </summary> /// <param name="args">All the arguments</param> /// <param name="optName">The char or string that the option was identified with</param> /// <param name="optDef">The option found</param> /// <param name="value">The value immediately following the option ([=:]value syntax)</param> /// <param name="index">The current index in the arguments which can be incremented /// by this function</param> /// <param name="dupOptHandleType">How to handle un-expected duplicate option /// definitions</param> /// <param name="unknownOptHandleType">How to handle options that were not /// defined</param> /// <param name="foundDefinitions">The option definitions already found</param> /// <param name="wasUnknown">If the option was unknown and the handle type was not /// error, this will be true so that the "option" can be added to the arguments</param> private void ParseOption(string[] args, object optName, OptionDefinition optDef, string value, ref int index, DupOptHandleType dupOptHandleType, UnknownOptHandleType unknownOptHandleType, ArrayList foundDefinitions, out bool wasUnknown) { OptionResult result; // make sure the option is found if (optDef == null) { switch (unknownOptHandleType) { case UnknownOptHandleType.Error: throw new ParseException( string.Format("Option {0} is not recoginzed", optName)); case UnknownOptHandleType.Warning: if (OptionWarning != null) OptionWarning(this, new OptionWarningEventArgs( string.Format("Option {0} is not recoginzed", optName))); break; } wasUnknown = true; return; } else wasUnknown = false; // make sure value is not given went it should not be given CheckIfValueless(optDef, value); result = _resultsHandler[optDef]; // make sure value is not duplicate when it should not be CheckIfDup(optDef, foundDefinitions, dupOptHandleType); foundDefinitions.Add(optDef); switch (optDef.Type) { case OptValType.Flag: if (result == null) result = new OptionResult(optDef); result.NumDefinitions = 1; result.Value = true; _resultsHandler[optDef] = result; break; case OptValType.IncrementalFlag: if (result == null) result = new OptionResult(optDef); result.NumDefinitions++; result.Value = result.NumDefinitions; _resultsHandler[optDef] = result; break; case OptValType.MultValue: value = GetValue(args, value, ref index); if (value == null) throw new ParseException( string.Format("Option {0} requires a value", optDef.ID)); if (result == null) result = new OptionResult(optDef); result.NumDefinitions++; result.AddValue(optDef.ConvertValue(value)); _resultsHandler[optDef] = result; break; case OptValType.ValueOpt: value = GetValue(args, value, ref index); if (result == null) result = new OptionResult(optDef); result.NumDefinitions = 1; result.Value = optDef.ConvertValue(value); _resultsHandler[optDef] = result; break; case OptValType.ValueReq: value = GetValue(args, value, ref index); if (value == null) throw new ParseException( string.Format("Option {0} requires a value", optDef.ID)); if (result == null) result = new OptionResult(optDef); result.NumDefinitions = 1; result.Value = optDef.ConvertValue(value); _resultsHandler[optDef] = result; break; } }
/// <summary> /// See <see cref="IOptionContainer.GetOptions()"/> /// </summary> public OptionDefinition[] GetOptions() { OptionDefinition[] options = new OptionDefinition[_results.Count]; _results.Keys.CopyTo(options, 0); return options; }
/// <summary> /// Check if the option is a duplicate (2nd, 3rd, etc. declaration) and the option /// does not support multiple values/declarations /// </summary> /// <param name="optDef">The option found</param> /// <param name="foundDefinitions">All of the found definitions so far</param> /// <param name="dupOptHandleType">How to handle duplicates</param> /// <returns>True if the option has already been found, and the type /// does not support duplicates</returns> private bool CheckIfDup(OptionDefinition optDef, ArrayList foundDefinitions, DupOptHandleType dupOptHandleType) { if (foundDefinitions.IndexOf(optDef) == -1) return false; switch (optDef.Type) { // types that allow duplicates: case OptValType.MultValue: case OptValType.IncrementalFlag: return false; default: switch (dupOptHandleType) { case DupOptHandleType.Error: throw new ParseException( string.Format("Option {0} does not support duplicate values", optDef.ID)); case DupOptHandleType.Warning: if (OptionWarning != null) OptionWarning(this, new OptionWarningEventArgs( string.Format("Option {0} does not support duplicate values", optDef.ID))); break; } return true; } }
/// <summary> /// Constructor /// </summary> /// <param name="def">Definition of the option this result if for</param> public OptionResult(OptionDefinition def) { _defintion = def; }
/// <summary> /// Parse an option /// </summary> /// <param name="args">All the arguments</param> /// <param name="optName">The char or string that the option was identified with</param> /// <param name="optDef">The option found</param> /// <param name="value">The value immediately following the option ([=:]value syntax)</param> /// <param name="index">The current index in the arguments which can be incremented /// by this function</param> /// <param name="dupOptHandleType">How to handle un-expected duplicate option /// definitions</param> /// <param name="unknownOptHandleType">How to handle options that were not /// defined</param> /// <param name="foundDefinitions">The option definitions already found</param> /// <param name="wasUnknown">If the option was unknown and the handle type was not /// error, this will be true so that the "option" can be added to the arguments</param> private void ParseOption(string[] args, object optName, OptionDefinition optDef, string value, ref int index, DupOptHandleType dupOptHandleType, UnknownOptHandleType unknownOptHandleType, ArrayList foundDefinitions, out bool wasUnknown) { OptionResult result; // make sure the option is found if (optDef == null) { switch (unknownOptHandleType) { case UnknownOptHandleType.Error: throw new ParseException( string.Format("Option {0} is not recoginzed", optName)); case UnknownOptHandleType.Warning: if (OptionWarning != null) { OptionWarning(this, new OptionWarningEventArgs( string.Format("Option {0} is not recoginzed", optName))); } break; } wasUnknown = true; return; } else { wasUnknown = false; } // make sure value is not given went it should not be given CheckIfValueless(optDef, value); result = _resultsHandler[optDef]; // make sure value is not duplicate when it should not be CheckIfDup(optDef, foundDefinitions, dupOptHandleType); foundDefinitions.Add(optDef); switch (optDef.Type) { case OptValType.Flag: if (result == null) { result = new OptionResult(optDef); } result.NumDefinitions = 1; result.Value = true; _resultsHandler[optDef] = result; break; case OptValType.IncrementalFlag: if (result == null) { result = new OptionResult(optDef); } result.NumDefinitions++; result.Value = result.NumDefinitions; _resultsHandler[optDef] = result; break; case OptValType.MultValue: value = GetValue(args, value, ref index); if (value == null) { throw new ParseException( string.Format("Option {0} requires a value", optDef.ID)); } if (result == null) { result = new OptionResult(optDef); } result.NumDefinitions++; result.AddValue(optDef.ConvertValue(value)); _resultsHandler[optDef] = result; break; case OptValType.ValueOpt: value = GetValue(args, value, ref index); if (result == null) { result = new OptionResult(optDef); } result.NumDefinitions = 1; result.Value = optDef.ConvertValue(value); _resultsHandler[optDef] = result; break; case OptValType.ValueReq: value = GetValue(args, value, ref index); if (value == null) { throw new ParseException( string.Format("Option {0} requires a value", optDef.ID)); } if (result == null) { result = new OptionResult(optDef); } result.NumDefinitions = 1; result.Value = optDef.ConvertValue(value); _resultsHandler[optDef] = result; break; } }
/// <summary> /// Add multiple options to the output /// </summary> /// <remarks>Can only be called if the active tag is "section"</remarks> /// <param name="options">All the options for the program</param> public void AddOptions(OptionDefinition[] options) { BeginOptions(); foreach (OptionDefinition opt in options) AddOption(opt); EndOptions(); }
/// <summary> /// Adds an option to the output /// </summary> /// <remarks>Like <see cref="BeginOption"/>, but uses the desription from the /// option as the body of the "description" tag. Does not open a new active tag</remarks> /// <param name="opt">Option to add</param> public void AddOption(OptionDefinition opt) { BeginOption(opt); _currentNode.InnerText = opt.Description; EndOption(); }
/// <summary> /// Check if the option definition does not allow a value and if a value was given /// </summary> /// <param name="optDef">The option definition</param> /// <param name="value">The value given or null if one was not given</param> /// <exception cref="ParseException">Thrown if value was given to a type /// that doesn't support a value</exception> private void CheckIfValueless(OptionDefinition optDef, string value) { // make sure value is not null (or empty) if (value == null || value == string.Empty) return; switch (optDef.Type) { // types that allow values: case OptValType.MultValue: case OptValType.ValueOpt: case OptValType.ValueReq: return; default: throw new ParseException( string.Format("Value given to option {0} that does not support a value", optDef.ID)); } }
/// <summary> /// Get or set result by definition /// </summary> public OptionResult this[OptionDefinition key] { get { return((OptionResult)base.Dictionary[key]); } set { base.Dictionary[key] = value; } }
/// <summary> /// Build a parser /// </summary> /// <param name="optDefs">The supported options</param> /// <param name="valuesDictionary">The dictionary to store the option results in</param> /// <returns>Parser instance</returns> public static Parser BuildParser(OptionDefinition[] optDefs, OptionResultsDictionary valuesDictionary) { return new Parser(new DictionaryParserHelper(optDefs, valuesDictionary)); }
/// <summary> /// Method to start adding an option to the usage. /// <seealso cref="AddOption"/> /// </summary> /// <remarks>Leaves the "description" tag as the active tag. Allows paragraph /// and list content to be added to the description of an option beyond /// the normal description. Does not include the description body from /// the <paramref name="opt"/> (must be added manually). Call /// <see cref="EndOption"/> to close this tag.</remarks> /// <param name="opt">Option to start</param> public void BeginOption(OptionDefinition opt) { ValidateCurrentNode("options", "category"); if (_groupOptionsByCategory) { XmlNode node; string cat = opt.Category; if (cat == null) { cat = _defaultOptionCategory; } node = _currentNode.SelectSingleNode("category[@name='" + cat + "']"); if (node == null) { _currentNode = _currentNode.AppendChild(_usage.CreateElement("category")); _currentNode.Attributes.Append(_usage.CreateAttribute("name")).Value = cat; } else { _currentNode = node; } } _currentNode = _currentNode.AppendChild(_usage.CreateElement("option")); _currentNode.Attributes.Append(_usage.CreateAttribute("type")).Value = EnumDescriptorReader.GetEnumFieldDescription(opt.Type); // names _currentNode = _currentNode.AppendChild(_usage.CreateElement("names")); foreach (char name in opt.ShortNames) { _currentNode = _currentNode.AppendChild(_usage.CreateElement("name")); _currentNode.Attributes.Append(_usage.CreateAttribute("value")).Value = name.ToString(); _currentNode.Attributes.Append(_usage.CreateAttribute("type")).Value = "short"; _currentNode = _currentNode.ParentNode; } foreach (string name in opt.LongNames) { _currentNode = _currentNode.AppendChild(_usage.CreateElement("name")); _currentNode.Attributes.Append(_usage.CreateAttribute("value")).Value = name; _currentNode.Attributes.Append(_usage.CreateAttribute("type")).Value = "long"; _currentNode = _currentNode.ParentNode; } _currentNode = _currentNode.ParentNode; if (opt.ValueType != null) { if (typeof(ValueType).IsAssignableFrom(opt.ValueType) || opt.ValueType.Namespace == "System") { _currentNode.AppendChild(_usage.CreateElement("valueType")).InnerText = opt.ValueType.Name; } else { _currentNode.AppendChild(_usage.CreateElement("valueType")).InnerText = opt.ValueType.ToString(); } } if (opt.DefaultValue != null) { _currentNode.AppendChild(_usage.CreateElement("defaultValue")).InnerText = opt.DefaultValue.ToString(); } _currentNode = _currentNode.AppendChild(_usage.CreateElement("description")); }