[jsword-svn] r1787 - in trunk/common/src/main/java/org/crosswire/common: options util

dmsmith at www.crosswire.org dmsmith at www.crosswire.org
Sun Apr 6 18:48:55 MST 2008


Author: dmsmith
Date: 2008-04-06 18:48:54 -0700 (Sun, 06 Apr 2008)
New Revision: 1787

Modified:
   trunk/common/src/main/java/org/crosswire/common/options/GetOptions.java
   trunk/common/src/main/java/org/crosswire/common/util/StringUtil.java
Log:
more options work


Modified: trunk/common/src/main/java/org/crosswire/common/options/GetOptions.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/options/GetOptions.java	2008-04-04 21:31:04 UTC (rev 1786)
+++ trunk/common/src/main/java/org/crosswire/common/options/GetOptions.java	2008-04-07 01:48:54 UTC (rev 1787)
@@ -22,6 +22,11 @@
 
 package org.crosswire.common.options;
 
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * GetOptions parses an argument list for requested arguments given by an
  * OptionList.<br/>
@@ -67,14 +72,212 @@
  */
 public class GetOptions
 {
-    public GetOptions(String programName, String[] args, OptionList options)
+    public GetOptions(String programName, String[] args, OptionList programOptions)
     {
         this.programName = programName;
         this.args = args;
-        this.options = options;
+        this.programOptions = programOptions;
+        // Initially, we have not started to process an argument
+        this.nonOptionArgs = new ArrayList();
+        this.suppliedOptions = new LinkedHashMap();
+        
+        parse();
     }
 
+    private void parse()
+    {
+        int nargs = args.length;
+        for (int i = 0; i < nargs; i++)
+        {
+            String nextArg = args[i];
+            // All options are 2 or more characters long and begin with a '-'.
+            // If this is a non-option then note it and advance
+            if (nextArg.length() < 2 || nextArg.charAt(0) != '-')
+            {
+                nonOptionArgs.add(nextArg);
+                continue;
+            }
+
+            // If we are at the end of all options, '--', we need to skip this and copy what follows to the end
+            if ("--".equals(nextArg)) //$NON-NLS-1$
+            {
+               for (int j = i + 1; j < nargs; j++)
+               {
+                   nonOptionArgs.add(args[j]);
+               }
+               return;
+            }
+
+            // At this point we are on a short option, a short option sequence or a long option.
+            // Invariant: the length > 1.
+            if (nextArg.charAt(1) == '-')
+            {
+                // Process a long argument
+                // This can be of the form --flag or --flag argument or --flag=argument
+                int equalPos = nextArg.indexOf('=');
+                String flag = (equalPos != -1) ? nextArg.substring(2, equalPos) : nextArg.substring(2);
+                List opts = programOptions.getLongOptions(flag);
+                if (opts.size() == 0)
+                {
+                    throw new IllegalArgumentException("Illegal option --" + flag); //$NON-NLS-1$
+                }
+                if (opts.size() > 1)
+                {
+                    throw new IllegalArgumentException("Ambiguous option --" + flag); //$NON-NLS-1$
+                }
+                Option option = (Option) opts.get(0);
+                if (option.getArgumentType().equals(ArgumentType.NO_ARGUMENT))
+                {
+                    // Add option with null argument to options
+                    suppliedOptions.put(option, null);
+                    continue;
+                }
+                // An argument is allowed or required
+                if (equalPos != -1)
+                {
+                    // Add option with argument to options
+                    // Check for empty argument
+                    String argument = (equalPos + 1 < nextArg.length()) ? nextArg.substring(equalPos + 1) : ""; //$NON-NLS-1$
+                    suppliedOptions.put(option, argument);
+                    continue;
+                }
+                // An argument is required, so take the next one.
+                if (option.getArgumentType().equals(ArgumentType.REQUIRED_ARGUMENT))
+                {
+                    if (i + 1 < nargs)
+                    {
+                        // Add option with following argument to options
+                        String argument = args[i++];
+                        suppliedOptions.put(option, argument);
+                        continue;
+                    }
+                    throw new IllegalArgumentException("Option missing required argument"); //$NON-NLS-1$
+                }
+            }
+            else
+            {
+                // Process a short argument or short argument sequence
+                
+                // for each letter after the '-'
+                int shortSeqSize = nextArg.length();
+                for (int j = 1; j < shortSeqSize; j++)
+                {
+                    char curChar = nextArg.charAt(j);
+                    Option option = programOptions.getShortOption(curChar);
+                    if (option == null)
+                    {
+                        throw new IllegalArgumentException("Illegal option -" + curChar); //$NON-NLS-1$
+                    }
+                    if (option.getArgumentType().equals(ArgumentType.NO_ARGUMENT))
+                    {
+                        // Add option with null argument to options
+                        suppliedOptions.put(option, null);
+                        continue;
+                    }
+                    // This option allows or requires an argument
+                    if (j < shortSeqSize)
+                    {
+                        // since there is stuff that follows the flag, it is the argument.
+                        String argument = nextArg.substring(j + 1);
+                        suppliedOptions.put(option, argument);
+                        continue;
+                    }
+                    if (option.getArgumentType().equals(ArgumentType.REQUIRED_ARGUMENT))
+                    {
+                        if (i + 1 < nargs)
+                        {
+                            // Add option with following argument to options
+                            String argument = args[i++];
+                            suppliedOptions.put(option, argument);
+                            continue;
+                        }
+                        throw new IllegalArgumentException("Option missing required argument"); //$NON-NLS-1$
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Swap adjacent blocks in an array.
+     * 
+     * @param array The array to modify in place
+     * @param firstStart the index of the start of the first block
+     * @param firstEnd the index of the end of the first block
+     * @param secondEnd the index of the end of the second block. Note: the start of the second block is firstEnd + 1
+     */
+    public static void swap(Object[] array, int firstStart, int firstEnd, int secondEnd)
+    {
+        // Note: this is currently unused.
+        // If we implement the traditional GNU extensions GetOpts interface we will need it.
+        // We copy the smaller block to the longer block.
+        
+        // The performance of this is linear with respect to the size of the larger block.
+        // If the blocks are equal the number of swaps is equal to the "larger" block size otherwise it is one greater.
+
+        // if the first block is smaller we start at the start of both and swap 
+        // Otherwise we start at the end of both and swap from the end to the start
+
+        // Set variables for the second block to be larger
+        int sourcePos = firstStart;
+        int destPos = firstEnd + 1;
+        int increment = 1;
+        int destStop = secondEnd;
+        int firstSize = firstEnd - firstStart + 1;
+        int secondSize = secondEnd - firstEnd;
+        int swapCount = secondSize + 1;
+
+        if (firstSize > secondSize)
+        {
+            // first block is bigger or equal
+            sourcePos = secondEnd;
+            destPos = firstEnd;
+            destStop = firstStart;
+            increment = -1;
+            swapCount = firstSize + 1;
+        }
+        
+        if (firstSize == secondSize)
+        {
+            swapCount--;
+        }
+
+        while (swapCount-- > 0)
+        {
+            Object temp = array[destPos];
+            array[destPos] = array[sourcePos];
+            array[sourcePos] = temp;
+            if (sourcePos != destStop)
+            {
+                sourcePos += increment;
+            }
+            if (destPos != destStop)
+            {
+                destPos += increment;
+            }
+
+        }
+    }
+
+//    public static void main(String[] args)
+//    {
+//        String[] a = {"a","b","c","d","e"};
+//        swap(a, 0, 2, 4);
+//        swap(a, 0, 1, 4);
+//        swap(a, 0, 0, 1);
+//        swap(a, 0, 0, 1);
+//        swap(a, 1, 2, 4);
+//        swap(a, 1, 2, 4);
+//    }
+
     private String     programName;
     private String[]   args;
-    private OptionList options;
+    private OptionList programOptions;
+
+    /**
+     * The position in the array that is currently being studied.
+     */
+    private List nonOptionArgs;
+    private Map suppliedOptions;
+    
 }

Modified: trunk/common/src/main/java/org/crosswire/common/util/StringUtil.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/util/StringUtil.java	2008-04-04 21:31:04 UTC (rev 1786)
+++ trunk/common/src/main/java/org/crosswire/common/util/StringUtil.java	2008-04-07 01:48:54 UTC (rev 1787)
@@ -52,7 +52,7 @@
     /**
      * This method reads an InputStream <b>In its entirety</b>, and passes
      * The text back as a string. If you are reading from a source that can
-     * block then be preapred for a long wait for this to return.
+     * block then be prepared for a long wait for this to return.
      * @param in The Stream to read from.
      * @return A string containing all the text from the Stream.
      */




More information about the jsword-svn mailing list