/// <summary> /// Makes the usage string for the target object. /// </summary> /// <param name="target"> /// The target object that usage is to be prepared for. /// </param> /// <param name="wrap"> /// The width of the output string to wrap at. /// </param> /// <param name="format"> /// Indicates how the usage text should be formatted. /// </param> /// <param name="usageSummary">The usage summary.</param> /// <returns> /// Returns the usage string. /// </returns> public static string MakeUsageString( object target, int wrap, CommandLineUsageFormat format, string usageSummary ) { if( wrap == -1 ) { try { wrap = Console.BufferWidth; } catch( IOException ) { wrap = 80; } } var usage = new WrappedStringWriter {Wrap = wrap}; var args = Environment.GetCommandLineArgs(); var exe = Path.GetFileName( args[ 0 ] ); var advanced = Environment.CommandLine.IndexOf( "/?+" ) > -1 || Environment.CommandLine.IndexOf( "-?+" ) > -1 || Environment.CommandLine.IndexOf( "/help+" ) > -1 || Environment.CommandLine.IndexOf( "-help+" ) > -1; ArrayList records; Hashtable nameIndex, shortNameIndex; ArgumentRecord defaultArg; ParseKnownArguments( target, out records, out nameIndex, out shortNameIndex, out defaultArg ); if( usageSummary != null ) usage.WriteLine( usageSummary ); else { usage.Write( "usage: " ); usage.Write( exe ); records.Reverse(); var compress = ( format & CommandLineUsageFormat.CompressOptions ) != 0; if( compress ) usage.Write( " [options]" ); foreach( ArgumentRecord record in records ) { if( ( record.ArgumentAttribute.ArgumentOptions & ArgumentOptions.Hidden ) != 0 ) continue; if( ( record.ArgumentAttribute.ArgumentOptions & ( ArgumentOptions.Common | ArgumentOptions.Required ) ) > 0 ) { if( !compress || ( record.ArgumentAttribute.ArgumentOptions & ArgumentOptions.Required ) != 0 || record.ArgumentAttribute.Default ) { usage.Write( ' ' ); var optional = ( record.ArgumentAttribute.ArgumentOptions & ArgumentOptions.Common ) > 0 && ( record.ArgumentAttribute.ArgumentOptions & ArgumentOptions.Required ) == 0; if( optional ) usage.Write( '[' ); if( ( record.ArgumentAttribute.ArgumentOptions & ArgumentOptions.None ) > 0 ) {} else { var isDefault = record.ArgumentAttribute.Default; if( !isDefault || record.PropertyType == typeof( bool ) || record.PropertyType.Name == "TriBool" ) { usage.Write( '/' ); if( record.ShortName != null && record.ShortName.Length > 0 ) usage.Write( record.ShortName ); else { usage.Write( record.ArgumentAttribute.CaseSensitive ? record.Name : record.Name.ToLowerInvariant() ); } } if( record.PropertyType != typeof( bool ) && record.PropertyType.Name != "TriBool" ) { if( !isDefault && record.ArgumentAttribute.RequiredParameters > 0 ) usage.Write( ":" ); for( var ix = 0; ix < record.ArgumentAttribute.RequiredParameters; ix++ ) { if( ix > 0 ) usage.Write( " " ); usage.Write( '<' ); usage.Write( record.ValueNames[ ix ] ); usage.Write( '>' ); } } if( optional ) usage.Write( ']' ); } } } } usage.WriteLine( "\r\n" ); records.Reverse(); } string groupName = null; var commandWidth = ( format & CommandLineUsageFormat.NoValues ) == CommandLineUsageFormat.NoValues ? 12 : 24; switch( format & CommandLineUsageFormat.ValueMask ) { case CommandLineUsageFormat.NoValues: commandWidth = 12; break; case CommandLineUsageFormat.ValuesSameLine: commandWidth = 24; break; case CommandLineUsageFormat.ValuesSecondLine: commandWidth = wrap - 1; break; } foreach( ArgumentRecord record in records ) { if( ( record.ArgumentAttribute.ArgumentOptions & ArgumentOptions.Hidden ) != 0 ) continue; if( advanced || ( ( record.ArgumentAttribute.ArgumentOptions & ArgumentOptions.Advanced ) == 0 ) ) { if( record.ArgumentAttribute.Group != groupName ) { groupName = record.ArgumentAttribute.Group; if( groupName != null && groupName.Length > 0 ) { usage.Write( usage.NewLine ); usage.Write( String.Format( CultureInfo.InvariantCulture, "- {0} -", groupName ), usage.Wrap - 1, TextAlignment.Center, null, ' ' ); } } var optional = ( record.ArgumentAttribute.ArgumentOptions & ArgumentOptions.Required ) == 0; var isDefault = record.ArgumentAttribute.Default && record.PropertyType != typeof( bool ) && record.PropertyType.Name != "TriBool"; if( !isDefault ) { if( record.PropertyType == typeof( bool ) || record.PropertyType.Name == "TriBool" ) { usage.Write( String.Format( CultureInfo.InvariantCulture, ( ( format & CommandLineUsageFormat.ValueMask ) == CommandLineUsageFormat.NoValues || ( record.ArgumentAttribute.ArgumentOptions & ArgumentOptions.IsCommand ) != 0 ) ? "/{0}" : "/{0}[+/-]", record.Name ), commandWidth, TextAlignment.Left, "", ' ' ); } else { var line = new StringBuilder( wrap ); line.Append( '/' ); line.Append( record.Name ); if( ( format & CommandLineUsageFormat.ValueMask ) != CommandLineUsageFormat.NoValues ) { for( var ix = 0; ix < record.ValueNames.Length; ix++ ) { line.Append( ' ' ); if( ix >= record.ArgumentAttribute.RequiredParameters ) line.Append( '[' ); line.Append( '<' ); line.Append( record.ValueNames[ ix ] ); line.Append( '>' ); if( ix >= record.ArgumentAttribute.RequiredParameters ) line.Append( ']' ); } } usage.Write( line.ToString(), commandWidth, TextAlignment.Left, "", ' ' ); } } else usage.Write( record.ValueNames[ 0 ], commandWidth, TextAlignment.Left, "", ' ' ); if( ( format & CommandLineUsageFormat.ValueMask ) == CommandLineUsageFormat.ValuesSecondLine ) usage.WriteLine( "" ); switch( format & CommandLineUsageFormat.ValueMask ) { case CommandLineUsageFormat.NoValues: usage.Indent = 3; break; case CommandLineUsageFormat.ValuesSameLine: usage.Indent = 6; break; case CommandLineUsageFormat.ValuesSecondLine: usage.Indent = 1; break; } if( ! optional ) usage.Write( "Required. " ); usage.Write( record.HelpText ); if( ! record.ArgumentAttribute.Default && record.SearchShortName != null && record.SearchShortName.Length > 0 && record.SearchShortName != record.SearchName ) { usage.Write( " (Short form: /" ); usage.Write( record.SearchShortName ); usage.Write( ")" ); } usage.Indent = 0; usage.Write( usage.NewLine ); } } usage.Flush(); var ur = usage.ToString(); return ur; }
/// <summary> /// Displays a list of errors or the usage text. /// </summary> /// <param name="target"> /// The target object that usage is to be prepared for. /// </param> /// <param name="showHelp"> /// Indicates if the usage help should be displayed. /// </param> /// <param name="wrap"> /// The width of the output string to wrap at. /// </param> /// <param name="format"> /// Indicates how the usage text should be formatted. /// </param> /// <param name="usageSummary">The usage summary.</param> /// <returns> /// Returns 1 if errors occurred during parsing and were displayed, otherwise 0. /// </returns> public static int ShowErrorOrUsage( object target, bool showHelp, int wrap, CommandLineUsageFormat format, string usageSummary) { var args = Environment.GetCommandLineArgs(); var exe = Path.GetFileName( args[ 0 ] ); if( _errors.Count > 0 ) { var tw = ReportErrorsToErrorStream ? Console.Error : Console.Out; var fore = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; foreach( object err in _errors ) { tw.WriteLine( "ERROR: " + err ); } Console.ForegroundColor = fore; #if DEBUG if( Debugger.IsAttached ) { Console.WriteLine( "Press any key to continue..." ); try { Console.Read(); } catch( IOException ) {} } #endif return 1; } else if( showHelp ) Console.WriteLine( MakeUsageString( target, wrap, format, usageSummary ) ); return 0; }