hello all,

this patch handles wrapping long header, footer and description texts 
with the tools' getopt Parser and OptionGroup classes.

ok to commit?


cheers;
rsn
Index: OptionGroup.java
===================================================================
RCS file: /cvsroot/classpath/classpath/tools/gnu/classpath/tools/getopt/OptionGroup.java,v
retrieving revision 1.3
diff -u -r1.3 OptionGroup.java
--- OptionGroup.java	9 May 2006 19:28:32 -0000	1.3
+++ OptionGroup.java	10 May 2006 13:17:21 -0000
@@ -39,8 +39,10 @@
 package gnu.classpath.tools.getopt;

 import java.io.PrintStream;
+import java.text.BreakIterator;
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.Locale;

 /**
  * An option group holds a collection of Options. It also has a name. Option
@@ -48,6 +50,9 @@
  */
 public class OptionGroup
 {
+  /** An 80-character string of whitespaces to use as a source for padding. */
+  private static final String FILLER = "                                        "
+                                     + "                                        ";
   private String name;

   ArrayList options = new ArrayList();
@@ -70,6 +75,85 @@
   }

   /**
+   * Print a designated text to a [EMAIL PROTECTED] PrintStream}, eventually wrapping the
+   * lines of text so as to ensure that the width of each line does not overflow
+   * [EMAIL PROTECTED] Parser#MAX_LINE_LENGTH} columns. The line-wrapping is done with a
+   * [EMAIL PROTECTED] BreakIterator} using the default [EMAIL PROTECTED] Locale}.
+   * <p>
+   * The text to print may contain <code>\n</code> characters. This method will
+   * force a line-break for each such character.
+   *
+   * @param out the [EMAIL PROTECTED] PrintStream} destination of the formatted text.
+   * @param text the text to print.
+   * @param leftMargin a positive value indicating the column position of the
+   *          start of the first line. Continuation lines, if they exist, are
+   *          printed starting at <code>leftMargin + 2</code> as per GNU
+   *          convention.
+   * @see Parser#MAX_LINE_LENGTH
+   */
+  protected static void formatText(PrintStream out, String text, int leftMargin)
+  {
+    formatText(out, text, leftMargin, Locale.getDefault());
+  }
+
+  /**
+   * Similar to the method with the same name and three arguments, except that
+   * the caller MUST specify a non-null [EMAIL PROTECTED] Locale} instance.
+   * <p>
+   * Print a designated text to a [EMAIL PROTECTED] PrintStream}, eventually wrapping the
+   * lines of text so as to ensure that the width of each line does not overflow
+   * [EMAIL PROTECTED] Parser#MAX_LINE_LENGTH} columns. The line-wrapping is done with a
+   * [EMAIL PROTECTED] BreakIterator} using the designated [EMAIL PROTECTED] Locale}.
+   * <p>
+   * The text to print may contain <code>\n</code> characters. This method will
+   * force a line-break for each such character.
+   *
+   * @param out the [EMAIL PROTECTED] PrintStream} destination of the formatted text.
+   * @param text the text to print.
+   * @param leftMargin a positive value indicating the column position of the
+   *          start of the first line. Continuation lines, if they exist, are
+   *          printed starting at <code>leftMargin + 2</code> as per GNU
+   *          convention.
+   * @param aLocale the [EMAIL PROTECTED] Locale} instance to use when constructing the
+   *          [EMAIL PROTECTED] BreakIterator}.
+   * @see Parser#MAX_LINE_LENGTH
+   */
+  protected static void formatText(PrintStream out, String text, int leftMargin,
+                                   Locale aLocale)
+  {
+    BreakIterator bit = BreakIterator.getLineInstance(aLocale);
+    String[] lines = text.split("\n");
+    int length = leftMargin;
+    String leftPadding = FILLER.substring(0, leftMargin + 2);
+    for (int i = 0; i < lines.length; i++)
+      {
+        text = lines[i];
+        bit.setText(text);
+        int start = bit.first();
+        int finish;
+        while ((finish = bit.next()) != BreakIterator.DONE)
+          {
+            String word = text.substring(start, finish);
+            length += word.length();
+            if (length >= Parser.MAX_LINE_LENGTH)
+              {
+                out.println();
+                out.print(leftPadding);
+                length = word.length() + leftMargin + 2;
+              }
+            out.print(word);
+            start = finish;
+          }
+        out.println();
+        if (i != lines.length - 1)
+          {
+            length = leftMargin + 2;
+            out.print(leftPadding);
+          }
+      }
+  }
+
+  /**
    * Add an option to this option group.
    *
    * @param opt the option to add
@@ -179,11 +263,9 @@
                 column += 1 + argName.length();
               }
           }
-        for (; column < maxArgLen; ++column)
-          out.print(' ');
         // FIXME: should have a better heuristic for padding.
-        out.print("    ");
-        out.println(option.getDescription());
+        out.print(FILLER.substring(0, maxArgLen + 4 - column));
+        formatText(out, option.getDescription(), maxArgLen + 4);
       }
   }
 }
Index: Parser.java
===================================================================
RCS file: /cvsroot/classpath/classpath/tools/gnu/classpath/tools/getopt/Parser.java,v
retrieving revision 1.4
diff -u -r1.4 Parser.java
--- Parser.java	9 May 2006 19:35:40 -0000	1.4
+++ Parser.java	10 May 2006 13:19:34 -0000
@@ -39,8 +39,10 @@
 package gnu.classpath.tools.getopt;

 import java.io.PrintStream;
+import java.text.BreakIterator;
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.Locale;

 /**
  * An instance of this class is used to parse command-line options. It does "GNU
@@ -52,6 +54,9 @@
  */
 public class Parser
 {
+  /** The maximum right column position. */
+  public static final int MAX_LINE_LENGTH = 80;
+
   private String programName;

   private String headerText;
@@ -84,6 +89,69 @@
   }

   /**
+   * Print a designated text to a [EMAIL PROTECTED] PrintStream}, eventually wrapping the
+   * lines of text so as to ensure that the width of each line does not overflow
+   * [EMAIL PROTECTED] #MAX_LINE_LENGTH} columns. The line-wrapping is done with a
+   * [EMAIL PROTECTED] BreakIterator} using the default [EMAIL PROTECTED] Locale}.
+   * <p>
+   * The text to print may contain <code>\n</code> characters. This method will
+   * force a line-break for each such character.
+   *
+   * @param out the [EMAIL PROTECTED] PrintStream} destination of the formatted text.
+   * @param text the text to print.
+   * @see Parser#MAX_LINE_LENGTH
+   */
+  protected static void formatText(PrintStream out, String text)
+  {
+    formatText(out, text, Locale.getDefault());
+  }
+
+  /**
+   * Similar to the method with the same name and two arguments, except that the
+   * caller MUST specify a non-null [EMAIL PROTECTED] Locale} instance.
+   * <p>
+   * Print a designated text to a [EMAIL PROTECTED] PrintStream}, eventually wrapping the
+   * lines of text so as to ensure that the width of each line does not overflow
+   * [EMAIL PROTECTED] #MAX_LINE_LENGTH} columns. The line-wrapping is done with a
+   * [EMAIL PROTECTED] BreakIterator} using the designated [EMAIL PROTECTED] Locale}.
+   * <p>
+   * The text to print may contain <code>\n</code> characters. This method will
+   * force a line-break for each such character.
+   *
+   * @param out the [EMAIL PROTECTED] PrintStream} destination of the formatted text.
+   * @param text the text to print.
+   * @param aLocale the [EMAIL PROTECTED] Locale} instance to use when constructing the
+   *          [EMAIL PROTECTED] BreakIterator}.
+   * @see Parser#MAX_LINE_LENGTH
+   */
+  protected static void formatText(PrintStream out, String text, Locale aLocale)
+  {
+    BreakIterator bit = BreakIterator.getLineInstance(aLocale);
+    String[] lines = text.split("\n");
+    for (int i = 0; i < lines.length; i++)
+      {
+        text = lines[i];
+        bit.setText(text);
+        int length = 0;
+        int finish;
+        int start = bit.first();
+        while ((finish = bit.next()) != BreakIterator.DONE)
+          {
+            String word = text.substring(start, finish);
+            length += word.length();
+            if (length >= MAX_LINE_LENGTH)
+              {
+                out.println();
+                length = word.length();
+              }
+            out.print(word);
+            start = finish;
+          }
+        out.println();
+      }
+  }
+
+  /**
    * Create a new parser. The program name is used when printing error messages.
    * The version string is printed verbatim in response to "--version".
    *
@@ -177,11 +245,16 @@
       optionGroups.add(optionGroups.size() - 1, group);
   }

-  void printHelp(PrintStream out)
+  public void printHelp()
+  {
+    this.printHelp(System.out);
+  }
+
+  protected void printHelp(PrintStream out)
   {
     if (headerText != null)
       {
-        out.println(headerText);
+        formatText(out, headerText);
         out.println();
       }

@@ -199,7 +272,7 @@
       }

     if (footerText != null)
-      out.println(footerText);
+      formatText(out, footerText);
   }

   private String getArgument(String request) throws OptionException

Attachment: pgpapmiIBxM7g.pgp
Description: PGP signature

Reply via email to