You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by do...@apache.org on 2001/02/26 01:39:15 UTC

cvs commit: jakarta-avalon/proposal/4.0/src/java/org/apache/aut/cli AbstractParserControl.java CLArgsParser.java CLOption.java CLOptionDescriptor.java CLUtil.java ParserControl.java

donaldp     01/02/25 16:39:15

  Added:       proposal/4.0/src/java/org/apache/aut/cli
                        AbstractParserControl.java CLArgsParser.java
                        CLOption.java CLOptionDescriptor.java CLUtil.java
                        ParserControl.java
  Log:
  Added cli stuff to aut
  
  Revision  Changes    Path
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/aut/cli/AbstractParserControl.java
  
  Index: AbstractParserControl.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.aut.cli;
  
  /**
   * Class to inherit from so when in future when new controls are added
   * clients will no have to implement them.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class AbstractParserControl 
      implements ParserControl
  {
      public boolean isFinished( int lastOptionCode )
      {
          return false;
      }
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/aut/cli/CLArgsParser.java
  
  Index: CLArgsParser.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.aut.cli;
  
  import java.text.ParseException;
  import java.util.Arrays;
  import java.util.Vector;
  
  /**
   * Parser for command line arguments.
   *
   * This parses command lines according to the standard (?) of 
   * gnu utilities.
   *
   * Note: This is still used in 1.1 libraries so do not add 1.2+ dependancies.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class CLArgsParser
  {
      protected class Token
      {
          protected final int                m_type;
          protected final String             m_value;
  
          public Token( final int type, final String value )
          {
              m_type = type;
              m_value = value;
          }
  
          public String getValue()
          {
              return m_value;
          }
  
          public int getType()
          {
              return m_type;
          }
  
          public String toString()
          {
              return "" + m_type + ":" + m_value;
          }
      }
  
      private final static int                 STATE_NORMAL           = 0;
      private final static int                 STATE_REQUIRE_2ARGS    = 1;
      private final static int                 STATE_REQUIRE_ARG      = 2;
      private final static int                 STATE_OPTIONAL_ARG     = 3;
      private final static int                 STATE_NO_OPTIONS       = 4;
      private final static int                 STATE_OPTION_MODE      = 5;
  
      protected final static int               TOKEN_SEPERATOR        = 0;
      protected final static int               TOKEN_STRING           = 1;
  
  
      protected final static char[]            ARG2_SEPERATORS        = 
          new char[] { (char)0, '=', '-' };
  
      protected final static char[]            ARG_SEPERATORS         = 
          new char[] { (char)0, '=' };
  
      protected final static char[]            NULL_SEPERATORS        = 
          new char[] { (char)0 };
  
      protected final CLOptionDescriptor[]     m_optionDescriptors;
      protected final Vector                   m_options;
      protected final ParserControl            m_control;
  
      protected String                         m_errorMessage;
      protected String[]                       m_unparsedArgs         = new String[] {};
  
      //variables used while parsing options.
      protected char                           ch;
      protected String[]                       args;
      protected boolean                        isLong;
      protected int                            argIndex;
      protected int                            stringIndex;
      protected int                            stringLength;
  
      //cached character == Integer.MAX_VALUE when invalid
      protected final static int               INVALID         = Integer.MAX_VALUE;
      protected int                            m_lastChar      = INVALID;
  
      protected int                            m_lastOptionId;
      protected CLOption                       m_option;
      protected int                            m_state         = STATE_NORMAL;
  
      public String[] getUnparsedArgs()
      {
          return m_unparsedArgs;
      }
  
      /**
       * Retrieve a list of options that were parsed from command list.
       *
       * @return the list of options
       */
      public Vector getArguments()
      {
          //System.out.println( "Arguments: " + m_options );
          return m_options; 
      }  
  
      /**
       * Get Descriptor for option id.
       *
       * @param id the id
       * @return the descriptor
       */
      private CLOptionDescriptor getDescriptorFor( final int id )
      {
          for( int i = 0; i < m_optionDescriptors.length; i++ )
          {
              if( m_optionDescriptors[i].getId() == id )
              {
                  return m_optionDescriptors[i];
              }
          }
  
          return null;
      }
  
      /**
       * Retrieve a descriptor by name.
       *
       * @param name the name
       * @return the descriptor
       */
      private CLOptionDescriptor getDescriptorFor( final String name )
      {
          for( int i = 0; i < m_optionDescriptors.length; i++ )
          {
              if( m_optionDescriptors[i].getName().equals( name ) )
              {
                  return m_optionDescriptors[i];
              }
          }
  
          return null;
      }  
  
      /**
       * Retrieve an error message that occured during parsing if one existed.
       *
       * @return the error string
       */
      public String getErrorString() 
      {
          //System.out.println( "ErrorString: " + m_errorMessage );
          return m_errorMessage; 
      }
  
      /**
       * Requier state to be placed in for option.
       *
       * @param descriptor the Option Descriptor
       * @return the state
       */
      private int getStateFor( final CLOptionDescriptor descriptor )
      {
          int flags = descriptor.getFlags();
          if( ( flags & CLOptionDescriptor.ARGUMENTS_REQUIRED_2 ) == 
              CLOptionDescriptor.ARGUMENTS_REQUIRED_2 )
          {
              return STATE_REQUIRE_2ARGS;
          }
          else if( ( flags & CLOptionDescriptor.ARGUMENT_REQUIRED ) == 
                   CLOptionDescriptor.ARGUMENT_REQUIRED )
          {
              return STATE_REQUIRE_ARG;
          }
          else if( ( flags & CLOptionDescriptor.ARGUMENT_OPTIONAL ) == 
                   CLOptionDescriptor.ARGUMENT_OPTIONAL )
          {
              return STATE_OPTIONAL_ARG;
          }
          else
          {
              return STATE_NORMAL;
          }
      }  
  
      /**
       * Create a parser that can deals with options and parses certain args.
       *
       * @param args[] the args 
       * @param optionDescriptors[] the option descriptors
       */
      public CLArgsParser( final String[] args, 
                           final CLOptionDescriptor[] optionDescriptors,
                           final ParserControl control )
      {
          m_optionDescriptors = optionDescriptors;
          m_control = control;
          m_options = new Vector();
          this.args = args;
  
          try 
          {
              parse(); 
              checkIncompatabilities( m_options );
          }
          catch( final ParseException pe )
          {
              m_errorMessage = pe.getMessage();
          }
  
          //System.out.println( "Built : " + m_options );
          //System.out.println( "From : " + Arrays.asList( args ) );
      }
  
      /**
       * Check for duplicates of an option. 
       * It is an error to have duplicates unless appropriate flags is set in descriptor.
       *
       * @param arguments the arguments
       */
      protected void checkIncompatabilities( final Vector arguments )
          throws ParseException
      {
          final int size = arguments.size();
  
          for( int i = 0; i < size; i++ )
          {
              final CLOption option = (CLOption)arguments.elementAt( i );
              final int id = option.getId();
              final CLOptionDescriptor descriptor = getDescriptorFor( id );
  
              //this occurs when id == 0 and user has not supplied a descriptor 
              //for arguments
              if( null == descriptor ) continue;
  
              final int[] incompatable = descriptor.getIncompatble();
  
              checkIncompatable( arguments, incompatable, i );
          }
      }
      
      protected void checkIncompatable( final Vector arguments, 
                                        final int[] incompatable,
                                        final int original )
          throws ParseException
      {
          final int size = arguments.size();
          
          for( int i = 0; i < size; i++ )
          {
              if( original == i ) continue;
  
              final CLOption option = (CLOption)arguments.elementAt( i );
              final int id = option.getId();
              final CLOptionDescriptor descriptor = getDescriptorFor( id );
              
              for( int j = 0; j < incompatable.length; j++ )
              {
                  if( id == incompatable[ j ] )
                  {
                      final CLOption originalOption = (CLOption)arguments.elementAt( original );
                      final int originalId = originalOption.getId();
  
                      String message = null;
  
                      if( id == originalId )
                      {
                          message = 
                              "Duplicate options for " + describeDualOption( originalId ) +
                              " found.";
                      }
                      else
                      {
                          message = "Incompatable options -" + 
                              describeDualOption( id ) + " and " + 
                              describeDualOption( originalId ) + " found.";
                      }
                      throw new ParseException( message, 0 );
                  }
              }
          }
      }
  
      protected String describeDualOption( final int id )
      {
          final CLOptionDescriptor descriptor = getDescriptorFor( id );
          if( null == descriptor ) return "<parameter>";
          else
          {
              final StringBuffer sb = new StringBuffer();
              boolean hasCharOption = false;
  
              if( Character.isLetter( (char)id ) )
              {
                  sb.append( '-' );
                  sb.append( (char)id );
                  hasCharOption = true;
              }
              
              final String longOption = descriptor.getName();
              if( null != longOption )
              {
                  if( hasCharOption ) sb.append( '/' );
                  sb.append( "--" );
                  sb.append( longOption );
              }
  
              return sb.toString();
          }            
      }
  
      /**
       * Create a parser that can deals with options and parses certain args.
       *
       * @param args[] the args 
       * @param optionDescriptors[] the option descriptors
       */
      public CLArgsParser( final String[] args, 
                           final CLOptionDescriptor[] optionDescriptors )
      {
          this( args, optionDescriptors, null );
      }
  
      /**
       * Create a string array that is subset of input array. 
       * The sub-array should start at array entry indicated by index. That array element
       * should only include characters from charIndex onwards.
       *
       * @param array[] the original array
       * @param index the cut-point in array
       * @param charIndex the cut-point in element of array
       * @return the result array
       */
      protected String[] subArray( final String[] array,
                                   final int index,
                                   final int charIndex )
      {
          final int remaining = array.length - index;
          final String[] result = new String[ remaining ];
  
          if( remaining > 1 )
          {
              System.arraycopy( array, index + 1, result, 1, remaining - 1 );
          }
  
          result[0] = array[ index ].substring( charIndex - 1 );
          
          return result;
      }
  
      /**
       * Actually parse arguments
       *
       * @param args[] arguments
       */
      protected void parse()
          throws ParseException
      {
          if( 0 == args.length ) return;
  
          stringLength = args[ argIndex ].length();
  
          //ch = peekAtChar();
  
          while( true )
          {
              ch = peekAtChar();
  
              if( argIndex >= args.length ) break;
              
              if( null != m_control && m_control.isFinished( m_lastOptionId ) )
              {
                  //this may need mangling due to peeks
                  m_unparsedArgs = subArray( args, argIndex, stringIndex );
                  return;
              }
  
              //System.out.println( "State=" + m_state );
              //System.out.println( "Char=" + (char)ch );
  
              if( STATE_OPTION_MODE == m_state ) 
              {
                  //if get to an arg barrier then return to normal mode
                  //else continue accumulating options
                  if( 0 == ch ) 
                  {
                      getChar(); //strip the null
                      m_state = STATE_NORMAL;
                  }
                  else parseShortOption();
              }
              else if( STATE_NORMAL == m_state )
              {
                  parseNormal();
              }
              else if( STATE_NO_OPTIONS == m_state )
              {
                  //should never get to here when stringIndex != 0
                  addOption( new CLOption( args[ argIndex++ ] ) );
              }
              else if( STATE_OPTIONAL_ARG == m_state && '-' == ch )
              {
                  m_state = STATE_NORMAL;
                  addOption( m_option );
              }
              else 
              {
                  parseArguments();
              }
          }
  
          if( m_option != null )
          {
              if( STATE_OPTIONAL_ARG == m_state )
              {
                  m_options.addElement( m_option );
              }
              else if( STATE_REQUIRE_ARG == m_state )
              {
                  final CLOptionDescriptor descriptor = getDescriptorFor( m_option.getId() );
                  final String message = 
                      "Missing argument to option " + getOptionDescription( descriptor );
                  throw new ParseException( message, 0 );
              }
              else if( STATE_REQUIRE_2ARGS == m_state )
              {
                  if( 1 == m_option.getArgumentCount() )
                  {
                      m_option.addArgument( "" );
                      m_options.addElement( m_option );
                  }
                  else
                  {
                      final CLOptionDescriptor descriptor = getDescriptorFor( m_option.getId() );
                      final String message = 
                          "Missing argument to option " + getOptionDescription( descriptor );
                      throw new ParseException( message, 0 );
                  }
              }
              else
              {
                  throw new ParseException( "IllegalState " + m_state + ": " + m_option, 0 );
              }
          }
      }
  
      protected final String getOptionDescription( final CLOptionDescriptor descriptor )
      {
          if( isLong ) return "--" + descriptor.getName();
          else return "-" + (char)descriptor.getId();
      }
  
      protected final char peekAtChar()
      {
          if( INVALID == m_lastChar ) m_lastChar = readChar();
          return (char)m_lastChar;
      }
  
      protected final char getChar()
      {
          if( INVALID != m_lastChar ) 
          {
              final char result = (char)m_lastChar;
              m_lastChar = INVALID;
              return result;
          }
          else return readChar();
      }
  
      private final char readChar()
      {
          if( stringIndex >= stringLength )
          { 
              argIndex++;
              stringIndex = 0;
  
              if( argIndex < args.length ) stringLength = args[ argIndex ].length();
              else stringLength = 0;
  
              return 0;
          }
  
          if( argIndex >= args.length ) return 0;
  
          return args[ argIndex ].charAt( stringIndex++ );
      }
  
      protected final Token nextToken( final char[] seperators )
      {
          ch = getChar();
  
          if( isSeperator( ch, seperators ) ) 
          {
              ch = getChar();
              return new Token( TOKEN_SEPERATOR, null );
          }
  
          final StringBuffer sb = new StringBuffer();
  
          do
          {
              sb.append( ch );
              ch = getChar();
          }
          while( !isSeperator( ch, seperators ) );
  
          return new Token( TOKEN_STRING, sb.toString() );
      }
  
      private final boolean isSeperator( final char ch, final char[] seperators )
      {
          for( int i = 0; i < seperators.length; i++ )
          {
              if( ch == seperators[ i ] ) return true;
          }
  
          return false;
      }
  
      protected void addOption( final CLOption option )
      {
          m_options.addElement( option );
          m_lastOptionId = option.getId();
          m_option = null;
      }
  
      protected void parseOption( final CLOptionDescriptor descriptor, 
                                  final String optionString )
          throws ParseException
      {
          if( null == descriptor )
          {
              throw new ParseException( "Unknown option " + optionString, 0 );
          }
          
          m_state = getStateFor( descriptor );
          m_option = new CLOption( descriptor.getId() );
          
          if( STATE_NORMAL == m_state ) addOption( m_option );
      }
  
      protected void parseShortOption()
          throws ParseException
      {
          ch = getChar();
          final CLOptionDescriptor descriptor = getDescriptorFor( (int)ch );
          isLong = false;
          parseOption( descriptor, "-" + ch );
          
          if( STATE_NORMAL == m_state ) m_state = STATE_OPTION_MODE;
      }
  
      protected boolean parseArguments()
          throws ParseException
      {
          if( STATE_REQUIRE_ARG == m_state )
          {
              if( '=' == ch || 0 == ch ) getChar();
  
              final Token token = nextToken( NULL_SEPERATORS );
              m_option.addArgument( token.getValue() );
  
              addOption( m_option );
              m_state = STATE_NORMAL;
          }
          else if( STATE_REQUIRE_2ARGS == m_state )
          {
              if( 0 == m_option.getArgumentCount() )
              {
                  final Token token = nextToken( ARG_SEPERATORS );
  
                  if( TOKEN_SEPERATOR == token.getType() )
                  {
                      final CLOptionDescriptor descriptor = getDescriptorFor( m_option.getId() );
                      final String message = 
                          "Unable to parse first argument for option " +
                          getOptionDescription( descriptor );
                      throw new ParseException( message, 0 );
                  }
                  else
                  {
                      m_option.addArgument( token.getValue() );
                  }
              }
              else //2nd argument
              {
                  final StringBuffer sb = new StringBuffer();
  
                  ch = getChar();
                  if( '-' == ch ) m_lastChar = ch;
  
                  while( !isSeperator( ch, ARG2_SEPERATORS ) )
                  {
                      sb.append( ch );
                      ch = getChar();
                  }
  
                  final String argument = sb.toString();
  
                  //System.out.println( "Arguement:" + argument );
  
                  m_option.addArgument( argument );
                  addOption( m_option );
                  m_option = null;
                  m_state = STATE_NORMAL;
              }
          }
  
          return true;
      }
  
      /**
       * Parse Options from Normal mode.
       */
      protected void parseNormal()
          throws ParseException
      {
          if( '-' != ch )
          {
              //Parse the arguments that are not options
              final String argument = nextToken( NULL_SEPERATORS ).getValue();
              addOption( new CLOption( argument ) );
              m_state = STATE_NORMAL;
          }
          else
          {
              getChar(); // strip the -
  
              if( 0 == peekAtChar() )
              {
                  throw new ParseException( "Malformed option -", 0 );
              }
              else
              {
                  ch = peekAtChar();
                  
                  //if it is a short option then parse it else ...
                  if( '-' != ch ) parseShortOption();
                  else
                  {
                      getChar(); // strip the - 
                      //-- sequence .. it can either mean a change of state
                      //to STATE_NO_OPTIONS or else a long option
                      
                      if( 0 == peekAtChar() )
                      {
                          getChar();
                          m_state = STATE_NO_OPTIONS;
                      }
                      else
                      {
                          //its a long option
                          final String optionName = nextToken( ARG_SEPERATORS ).getValue();
                          final CLOptionDescriptor descriptor = getDescriptorFor( optionName );
                          isLong = true;
                          parseOption( descriptor, "--" + optionName );
                      }
                  }
              }
          }
      }
  }
  
  
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/aut/cli/CLOption.java
  
  Index: CLOption.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.aut.cli;
  
  import java.util.Arrays;
  
  /**
   * Basic class describing an instance of option.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class CLOption
  {
      protected final int                      m_id;
      protected String[]                       m_arguments;
  
      /**
       * Retrieve argument to option if it takes arguments.
       *
       * @return the argument
       */
      public final String getArgument()
      {
          return getArgument( 0 );
      }
      
      /**
       * Retrieve argument to option if it takes arguments.
       *
       * @return the argument
       */
      public final String getArgument( final int index )
      {
          if( null == m_arguments || index < 0 || index >= m_arguments.length ) 
          {
              return null;
          }
          else return m_arguments[ index ]; 
      }
  
      /**
       * Retrieve id of option. 
       * 
       * The id is eqivelent to character code if it can be a single letter option.
       *
       * @return the id
       */
      public final int getId() 
      {
          return m_id; 
      }
  
      /**
       * Constructor taking an id (that must be a proper character code)
       *
       * @param id the new id
       */
      public CLOption( final int id ) 
      {
          m_id = id; 
      }
  
      /**
       * Constructor taking argument for option.
       *
       * @param argument the argument
       */
      public CLOption( final String argument ) 
      {
          this( 0 );
          addArgument( argument );
      }  
  
      /**
       * Mutator fo Argument property.
       *
       * @param argument the argument
       */
      public final void addArgument( final String argument ) 
      {
          if( null == m_arguments ) m_arguments = new String[] { argument };
          else
          {
              final String[] arguments = new String[ m_arguments.length + 1 ];
              System.arraycopy( m_arguments, 0, arguments, 0, m_arguments.length );
              arguments[ m_arguments.length ] = argument;
              m_arguments = arguments;
          }
      }  
  
      public int getArgumentCount()
      {
          if( null == m_arguments ) return 0;
          else return m_arguments.length;
      }
  
      /**
       * Convert to String.
       *
       * @return the string value
       */
      public String toString()
      {
          final StringBuffer sb = new StringBuffer();
          sb.append( "[Option " );
          sb.append( (char)m_id );
  
          if( null != m_arguments )
          {
              sb.append( ", " );
              sb.append( Arrays.asList( m_arguments ) );
          }
  
          sb.append( " ]" );
          
          return sb.toString();
      }  
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/aut/cli/CLOptionDescriptor.java
  
  Index: CLOptionDescriptor.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.aut.cli;
  
  /**
   * Basic class describing an type of option.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class CLOptionDescriptor
  {
      public final static int                  ARGUMENT_REQUIRED         = 1 << 1;
      public final static int                  ARGUMENT_OPTIONAL         = 1 << 2;
      public final static int                  ARGUMENT_DISALLOWED       = 1 << 3;
      public final static int                  ARGUMENTS_REQUIRED_2      = 1 << 4;
  
      protected final int                      m_id;
      protected final int                      m_flags;
      protected final String                   m_name;
      protected final String                   m_description;
      protected final int[]                    m_incompatable;
  
      /**
       * Constructor.
       *
       * @param name the name/long option
       * @param flags the flags
       * @param id the id/character option
       * @param description description of option usage
       */
      public CLOptionDescriptor( final String name, 
                                 final int flags, 
                                 final int id,
                                 final String description )
      {
          this( name, flags, id, description, new int[] { id } );
      }
  
      /**
       * Constructor.
       *
       * @param name the name/long option
       * @param flags the flags
       * @param id the id/character option
       * @param description description of option usage
       */
      public CLOptionDescriptor( final String name, 
                                 final int flags, 
                                 final int id,
                                 final String description,
                                 final int[] incompatable )
      {
          m_id = id;
          m_name = name;
          m_flags = flags;
          m_description = description;
          m_incompatable = incompatable;
      }  
  
      protected int[] getIncompatble()
      {
          return m_incompatable;
      }
  
      /**
       * Retrieve textual description.
       *
       * @return the description 
       */
      public final String getDescription() 
      { 
          return m_description; 
      }
    
      /**
       * Retrieve flags about option.
       * Flags include details such as whether it allows parameters etc.
       *
       * @return the flags
       */
      public final int getFlags() 
      {
          return m_flags; 
      }
    
      /**
       * Retrieve the id for option.
       * The id is also the character if using single character options.
       *
       * @return the id
       */
      public final int getId() 
      { 
          return m_id; 
      }  
    
      /**
       * Retrieve name of option which is also text for long option.
       *
       * @return name/long option
       */
      public final String getName() 
      { 
          return m_name; 
      }  
  
      /**
       * Convert to String.
       *
       * @return the converted value to string.
       */
      public String toString()
      {
          return 
              "[OptionDescriptor " + m_name + 
              ", " + m_id + ", " + m_flags + 
              ", " + m_description + " ]";
      }  
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/aut/cli/CLUtil.java
  
  Index: CLUtil.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.aut.cli;
  
  /**
   * CLUtil offers basic utility operations for use both internal and external to package.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class CLUtil
  {
      protected static int              MAX_DESCRIPTION_COLUMN_LENGTH = 60;
  
      /**
       * Format options into StringBuffer and return.
       *
       * @param options[] the option descriptors
       * @return the formatted description/help for options
       */
      public static StringBuffer describeOptions( final CLOptionDescriptor[] options )
      {
          StringBuffer sb = new StringBuffer();
          for (int i = 0; i < options.length; i++)
          {
              final char ch = (char) options[i].getId();
              final String name = options[i].getName();
              String description = options[i].getDescription();
              boolean needComma = false;
          
              sb.append('\t');
          
              if( Character.isLetter(ch) )
              {
                  sb.append("-");
                  sb.append(ch);
                  needComma = true;
              }
          
              if (null != name)
              {
                  if( needComma ) sb.append(", ");
              
                  sb.append("--");
                  sb.append(name);
                  sb.append('\n');
              }
          
              if( null != description )
              {
                  while( description.length() > MAX_DESCRIPTION_COLUMN_LENGTH )
                  {
                      final String descriptionPart = 
                          description.substring( 0, MAX_DESCRIPTION_COLUMN_LENGTH );
                      description = 
                          description.substring( MAX_DESCRIPTION_COLUMN_LENGTH );
                      sb.append( "\t\t" );
                      sb.append( descriptionPart );
                      sb.append( '\n' );
                  }
              
                  sb.append( "\t\t" );
                  sb.append( description );
                  sb.append( '\n' );
              }
          }
          return sb;
      }
  
      /**
       * Private Constructor so that no instance can ever be created.
       *
       */
      private CLUtil() 
      {
      }  
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/aut/cli/ParserControl.java
  
  Index: ParserControl.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.aut.cli;
  
  /**
   * ParserControl is used to control particular behaviour of the parser.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ParserControl
  {
      boolean isFinished( int lastOptionCode );
  }