JAL-4269 Now using --width, --height, --scale for both --image and --structureimage...
[jalview.git] / src / jalview / bin / argparser / ArgParser.java
index 1558065..fd42bb2 100644 (file)
@@ -31,12 +31,11 @@ import java.util.EnumSet;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 
-import jalview.bin.Cache;
 import jalview.bin.Console;
 import jalview.bin.Jalview;
+import jalview.bin.Jalview.ExitCode;
 import jalview.bin.argparser.Arg.Opt;
 import jalview.bin.argparser.Arg.Type;
 import jalview.util.FileUtils;
@@ -50,79 +49,109 @@ public class ArgParser
 
   public static final char EQUALS = '=';
 
+  public static final String STDOUTFILENAME = "-";
+
   protected static final String NEGATESTRING = "no";
 
-  // the default linked id prefix used for no id (not even square braces)
+  /**
+   * the default linked id prefix used for no id (ie when not even square braces
+   * are provided)
+   */
   protected static final String DEFAULTLINKEDIDPREFIX = "JALVIEW:";
 
-  // the linkedId string used to match all linkedIds seen so far
+  /**
+   * the linkedId string used to match all linkedIds seen so far
+   */
   protected static final String MATCHALLLINKEDIDS = "*";
 
-  // the linkedId string used to match all of the last --open'ed linkedIds
+  /**
+   * the linkedId string used to match all of the last --open'ed linkedIds
+   */
   protected static final String MATCHOPENEDLINKEDIDS = "open*";
 
-  // the counter added to the default linked id prefix
+  /**
+   * the counter added to the default linked id prefix
+   */
   private int defaultLinkedIdCounter = 0;
 
-  // the substitution string used to use the defaultLinkedIdCounter
+  /**
+   * the substitution string used to use the defaultLinkedIdCounter
+   */
   private static final String DEFAULTLINKEDIDCOUNTER = "{}";
 
-  // the counter added to the default linked id prefix. NOW using
-  // linkedIdAutoCounter
-  // private int openLinkedIdCounter = 0;
-
-  // the linked id prefix used for --open files. NOW the same as DEFAULT
+  /**
+   * the linked id prefix used for --open files. NOW the same as DEFAULT
+   */
   protected static final String OPENLINKEDIDPREFIX = DEFAULTLINKEDIDPREFIX;
 
-  // the counter used for {n} substitutions
+  /**
+   * the counter used for {n} substitutions
+   */
   private int linkedIdAutoCounter = 0;
 
-  // the linked id substitution string used to increment the idCounter (and use
-  // the incremented value)
+  /**
+   * the linked id substitution string used to increment the idCounter (and use
+   * the incremented value)
+   */
   private static final String INCREMENTLINKEDIDAUTOCOUNTER = "{++n}";
 
-  // the linked id substitution string used to use the idCounter
+  /**
+   * the linked id substitution string used to use the idCounter
+   */
   private static final String LINKEDIDAUTOCOUNTER = "{n}";
 
-  // the linked id substitution string used to use the filename extension of
-  // --append
-  // or --open
+  /**
+   * the linked id substitution string used to use the filename extension of
+   * --append or --open
+   */
   private static final String LINKEDIDEXTENSION = "{extension}";
 
-  // the linked id substitution string used to use the base filename of --append
-  // or --open
+  /**
+   * the linked id substitution string used to use the base filename of --append
+   */
+  /** or --open */
   private static final String LINKEDIDBASENAME = "{basename}";
 
-  // the linked id substitution string used to use the dir path of --append
-  // or --open
+  /**
+   * the linked id substitution string used to use the dir path of --append or
+   * --open
+   */
   private static final String LINKEDIDDIRNAME = "{dirname}";
 
-  // the current argfile
+  /**
+   * the current argfile
+   */
   private String argFile = null;
 
-  // the linked id substitution string used to use the dir path of the latest
-  // --argfile name
+  /**
+   * the linked id substitution string used to use the dir path of the latest
+   */
+  /** --argfile name */
   private static final String ARGFILEBASENAME = "{argfilebasename}";
 
-  // the linked id substitution string used to use the dir path of the latest
-  // --argfile name
+  /**
+   * the linked id substitution string used to use the dir path of the latest
+   * --argfile name
+   */
   private static final String ARGFILEDIRNAME = "{argfiledirname}";
 
-  // flag to say whether {n} subtitutions in output filenames should be made.
-  // Turn on and off with --substitutions and --nosubstitutions
-  // Start with it on
+  /**
+   * flag to say whether {n} subtitutions in output filenames should be made.
+   * Turn on and off with --substitutions and --nosubstitutions Start with it on
+   */
   private boolean substitutions = true;
 
-  // flag to say whether the default linkedId is the current default linked id
-  // or ALL linkedIds
+  /**
+   * flag to say whether the default linkedId is the current default linked id
+   *
+   * or ALL linkedIds
+   */
   private boolean allLinkedIds = false;
 
-  // flag to say whether the default linkedId is the current default linked id
-  // or OPENED linkedIds
-  private boolean openedLinkedIds = false;
-
-  // flag to say whether the structure arguments should be applied to all
-  // structures with this linked id
+  /**
+   * flag to say whether the structure arguments should be applied to all
+   * structures with this linked id
+   */
   private boolean allStructures = false;
 
   protected static final Map<String, Arg> argMap;
@@ -141,6 +170,15 @@ public class ArgParser
 
   private BootstrapArgs bootstrapArgs = null;
 
+  private boolean oldArguments = false;
+
+  private boolean mixedArguments = false;
+
+  /**
+   * saved examples of mixed arguments
+   */
+  private String[] mixedExamples = new String[] { null, null };
+
   static
   {
     argMap = new HashMap<>();
@@ -175,12 +213,15 @@ public class ArgParser
   public ArgParser(String[] args, boolean initsubstitutions,
           BootstrapArgs bsa)
   {
-    // Make a mutable new ArrayList so that shell globbing parser works.
-    // (When shell file globbing is used, there are a sequence of non-Arg
-    // arguments (which are the expanded globbed filenames) that need to be
-    // consumed by the --append/--argfile/etc Arg which is most easily done by
-    // removing these filenames from the list one at a time. This can't be done
-    // with an ArrayList made with only Arrays.asList(String[] args). )
+    /*
+     *  Make a mutable new ArrayList so that shell globbing parser works.
+     * (When shell file globbing is used, there are a sequence of non-Arg
+     * arguments (which are the expanded globbed filenames) that need to be
+     * consumed by the --append/--argfile/etc Arg which is most easily done
+     * by removing these filenames from the list one at a time. This can't be
+     * done with an ArrayList made with only Arrays.asList(String[] args) as
+     * that is not mutable. )
+     */
     this(new ArrayList<>(Arrays.asList(args)), initsubstitutions, false,
             bsa);
   }
@@ -202,19 +243,40 @@ public class ArgParser
       if (arg.startsWith(DOUBLEDASH))
       {
         dd = true;
-        break;
+        if (mixedExamples[1] == null)
+        {
+          mixedExamples[1] = arg;
+        }
       }
-      else if (arg.startsWith("-") || arg.equals("open"))
+      else if ((arg.startsWith("-") && !arg.equals(STDOUTFILENAME))
+              || arg.equals("open"))
       {
         d = true;
+        if (mixedExamples[0] == null)
+        {
+          mixedExamples[0] = arg;
+        }
+      }
+    }
+    if (d)
+    {
+      if (dd)
+      {
+        mixedArguments = true;
+      }
+      else
+      {
+        oldArguments = true;
       }
     }
-    if (d && !dd)
+
+    if (oldArguments || mixedArguments)
     {
       // leave it to the old style -- parse an empty list
       parse(new ArrayList<String>(), false, false);
       return;
     }
+
     if (bsa != null)
       this.bootstrapArgs = bsa;
     else
@@ -226,27 +288,30 @@ public class ArgParser
           boolean allowPrivate)
   {
     this.substitutions = initsubstitutions;
-    boolean openEachInitialFilenames = true;
-    for (int i = 0; i < args.size(); i++)
-    {
-      String arg = args.get(i);
 
-      // If the first arguments do not start with "--" or "-" or is not "open"
-      // and` is a filename that exists it is probably a file/list of files to
-      // open so we fake an Arg.OPEN argument and when adding files only add the
-      // single arg[i] and increment the defaultLinkedIdCounter so that each of
-      // these files is opened separately.
-      if (openEachInitialFilenames && !arg.startsWith(DOUBLEDASH)
-              && !arg.startsWith("-") && !arg.equals("open")
-              && (new File(arg).exists()
-                      || HttpUtils.startsWithHttpOrHttps(arg)))
-      {
-        arg = Arg.OPEN.argString();
-      }
-      else
+    /*
+     *  If the first argument does not start with "--" or "-" or is not "open",
+     *  and is a filename that exists or a URL, it is probably a file/list of
+     *  files to open so we insert an Arg.OPEN argument before it. This will
+     *  mean the list of files at the start of the arguments are all opened
+     *  separately.
+     */
+    if (args.size() > 0)
+    {
+      String arg0 = args.get(0);
+      if (arg0 != null
+              && (!arg0.startsWith(DOUBLEDASH) && !arg0.startsWith("-")
+                      && !arg0.equals("open") && (new File(arg0).exists()
+                              || HttpUtils.startsWithHttpOrHttps(arg0))))
       {
-        openEachInitialFilenames = false;
+        // insert "--open" at the start
+        args.add(0, Arg.OPEN.argString());
       }
+    }
+
+    for (int i = 0; i < args.size(); i++)
+    {
+      String arg = args.get(i);
 
       // look for double-dash, e.g. --arg
       if (arg.startsWith(DOUBLEDASH))
@@ -337,10 +402,12 @@ public class ArgParser
         {
           // arg not found
           Console.error("Argument '" + arg + "' not recognised.  Exiting.");
-          Jalview.exit("Invalid argument used." + System.lineSeparator()
-                  + "Use" + System.lineSeparator() + "jalview "
-                  + Arg.HELP.argString() + System.lineSeparator()
-                  + "for a usage statement.", 13);
+          Jalview.exit(
+                  "Invalid argument used." + System.lineSeparator() + "Use"
+                          + System.lineSeparator() + "jalview "
+                          + Arg.HELP.argString() + System.lineSeparator()
+                          + "for a usage statement.",
+                  ExitCode.INVALID_ARGUMENT);
           continue;
         }
         if (a.hasOption(Opt.PRIVATE) && !allowPrivate)
@@ -397,7 +464,7 @@ public class ArgParser
           {
             // There is no "=" so value is next arg or args (possibly shell
             // glob-expanded)
-            if ((openEachInitialFilenames ? i : i + 1) >= args.size())
+            if (i + 1 >= args.size())
             {
               // no value to take for arg, which wants a value
               Console.error("Argument '" + a.getName()
@@ -412,8 +479,7 @@ public class ArgParser
             {
               // if this is the first argument with a file list at the start of
               // the args we add filenames from index i instead of i+1
-              globVals = getShellGlobbedFilenameValues(a, args,
-                      openEachInitialFilenames ? i : i + 1);
+              globVals = getShellGlobbedFilenameValues(a, args, i + 1);
             }
             else
             {
@@ -443,12 +509,6 @@ public class ArgParser
         else if (a == Arg.ALL)
         {
           allLinkedIds = !negated;
-          openedLinkedIds = false;
-        }
-        else if (a == Arg.OPENED)
-        {
-          openedLinkedIds = !negated;
-          allLinkedIds = false;
         }
         else if (a == Arg.ALLSTRUCTURES)
         {
@@ -475,35 +535,25 @@ public class ArgParser
         {
           if (linkedId == null)
           {
-            if (a.hasOption(Opt.OUTPUTFILE) && a.hasOption(Opt.ALLOWALL)
-                    && val.startsWith(MATCHALLLINKEDIDS))
+            if (a.hasOption(Opt.OUTPUTFILE) && a.hasOption(Opt.ALLOWMULTIID)
+                    && val.contains(MATCHALLLINKEDIDS))
             {
-              // --output=*.ext is shorthand for --all --output {basename}.ext
+              // --output=*.ext is shorthand for --output {basename}.ext
+              // --output=*/*.ext is shorthand for
+              // --output {dirname}/{basename}.ext
               // (or --image=*.ext)
-              allLinkedIds = true;
-              openedLinkedIds = false;
-              linkedId = MATCHALLLINKEDIDS;
-              val = LINKEDIDDIRNAME + File.separator + LINKEDIDBASENAME
-                      + val.substring(MATCHALLLINKEDIDS.length());
+              linkedId = allLinkedIds ? MATCHALLLINKEDIDS
+                      : MATCHOPENEDLINKEDIDS;
+              val = FileUtils.convertWildcardsToPath(val, MATCHALLLINKEDIDS,
+                      LINKEDIDDIRNAME, LINKEDIDBASENAME);
             }
-            else if (a.hasOption(Opt.OUTPUTFILE)
-                    && a.hasOption(Opt.ALLOWALL)
-                    && val.startsWith(MATCHOPENEDLINKEDIDS))
-            {
-              // --output=open*.ext is shorthand for --opened --output
-              // {basename}.ext
-              // (or --image=open*.ext)
-              openedLinkedIds = true;
-              allLinkedIds = false;
-              linkedId = MATCHOPENEDLINKEDIDS;
-              val = LINKEDIDDIRNAME + File.separator + LINKEDIDBASENAME
-                      + val.substring(MATCHOPENEDLINKEDIDS.length());
-            }
-            else if (allLinkedIds && a.hasOption(Opt.ALLOWALL))
+            else if (allLinkedIds && a.hasOption(Opt.ALLOWMULTIID))
             {
               linkedId = MATCHALLLINKEDIDS;
             }
-            else if (openedLinkedIds && a.hasOption(Opt.ALLOWALL))
+            else if (a.hasOption(Opt.ALLOWMULTIID)
+                    && this.storedLinkedIds != null
+                    && this.storedLinkedIds.size() > 0)
             {
               linkedId = MATCHOPENEDLINKEDIDS;
             }
@@ -567,10 +617,9 @@ public class ArgParser
 
         // set allstructures to all non-primary structure options in this linked
         // id if --allstructures has been set
-        if (allStructures
-                && (a.getType() == Type.STRUCTURE
-                        || a.getType() == Type.STRUCTUREIMAGE)
-                && !a.hasOption(Opt.PRIMARY))
+        if (allStructures && (a.getType() == Type.STRUCTURE
+        // || a.getType() == Type.STRUCTUREIMAGE)
+        ) && !a.hasOption(Opt.PRIMARY))
         {
           if (!subvals.has(Arg.ALLSTRUCTURES.getName()))
           // && !subvals.has("structureid"))
@@ -627,9 +676,8 @@ public class ArgParser
         // remove the '*' or 'open*' linkedId that should be empty if it was
         // created
         if ((MATCHALLLINKEDIDS.equals(linkedId)
+                || MATCHOPENEDLINKEDIDS.equals(linkedId))
                 && linkedArgs.containsKey(linkedId))
-                || (MATCHOPENEDLINKEDIDS.equals(linkedId)
-                        && linkedArgs.containsKey(linkedId)))
         {
           linkedArgs.remove(linkedId);
         }
@@ -874,7 +922,7 @@ public class ArgParser
       {
         String message = Arg.ARGFILE.argString() + EQUALS + "\""
                 + argFile.getPath() + "\": File does not exist.";
-        Jalview.exit(message, 2);
+        Jalview.exit(message, ExitCode.FILE_NOT_FOUND);
       }
       try
       {
@@ -888,7 +936,7 @@ public class ArgParser
       {
         String message = Arg.ARGFILE.argString() + "=\"" + argFile.getPath()
                 + "\": File could not be read.";
-        Jalview.exit(message, 3);
+        Jalview.exit(message, ExitCode.FILE_NOT_READABLE);
       }
     }
     // Third param "true" uses Opt.PRIVATE args --setargile=argfile and
@@ -914,164 +962,17 @@ public class ArgParser
         String message = Arg.ARGFILE.argString() + "=\"" + argFile.getPath()
                 + "\": File could not be read.";
         Console.debug(message, e);
-        Jalview.exit(message, 3);
+        Jalview.exit(message, ExitCode.FILE_NOT_READABLE);
       }
     }
     return args;
   }
 
-  public static enum Position
-  {
-    FIRST, BEFORE, AFTER
-  }
-
-  // get from following Arg of type a or subval of same name (lowercase)
-  public static String getValueFromSubValOrArg(ArgValuesMap avm,
-          ArgValue av, Arg a, SubVals sv)
-  {
-    return getFromSubValArgOrPref(avm, av, a, sv, null, null, null);
-  }
-
-  // get from following Arg of type a or subval key or preference pref or
-  // default def
-  public static String getFromSubValArgOrPref(ArgValuesMap avm, ArgValue av,
-          Arg a, SubVals sv, String key, String pref, String def)
-  {
-    return getFromSubValArgOrPref(avm, a, Position.AFTER, av, sv, key, pref,
-            def);
-  }
-
-  // get from following(AFTER), first occurence of (FIRST) or previous (BEFORE)
-  // Arg of type a or subval key or preference pref or default def
-  public static String getFromSubValArgOrPref(ArgValuesMap avm, Arg a,
-          Position pos, ArgValue av, SubVals sv, String key, String pref,
-          String def)
-  {
-    return getFromSubValArgOrPrefWithSubstitutions(null, avm, a, pos, av,
-            sv, key, pref, def);
-  }
-
-  public static String getFromSubValArgOrPrefWithSubstitutions(ArgParser ap,
-          ArgValuesMap avm, Arg a, Position pos, ArgValue av, SubVals sv,
-          String key, String pref, String def)
-  {
-    if (key == null)
-      key = a.getName();
-    String value = null;
-    if (sv != null && sv.has(key) && sv.get(key) != null)
-    {
-      value = ap == null ? sv.get(key)
-              : sv.getWithSubstitutions(ap, avm.getLinkedId(), key);
-    }
-    else if (avm != null && avm.containsArg(a))
-    {
-      if (pos == Position.FIRST && avm.getValue(a) != null)
-        value = avm.getValue(a);
-      else if (pos == Position.BEFORE
-              && avm.getClosestPreviousArgValueOfArg(av, a) != null)
-        value = avm.getClosestPreviousArgValueOfArg(av, a).getValue();
-      else if (pos == Position.AFTER
-              && avm.getClosestNextArgValueOfArg(av, a) != null)
-        value = avm.getClosestNextArgValueOfArg(av, a).getValue();
-
-      // look for allstructures subval for Type.STRUCTURE*
-      Arg arg = av.getArg();
-      if (value == null && arg.hasOption(Opt.PRIMARY)
-              && arg.getType() == Type.STRUCTURE
-              && !a.hasOption(Opt.PRIMARY) && (a.getType() == Type.STRUCTURE
-                      || a.getType() == Type.STRUCTUREIMAGE))
-      {
-        ArgValue av2 = avm.getArgValueOfArgWithSubValKey(a,
-                Arg.ALLSTRUCTURES.getName());
-        if (av2 != null)
-        {
-          value = av2.getValue();
-        }
-      }
-    }
-    if (value == null)
-    {
-      value = pref != null ? Cache.getDefault(pref, def) : def;
-    }
-    return value;
-  }
-
-  public static boolean getBoolFromSubValOrArg(ArgValuesMap avm, Arg a,
-          SubVals sv)
-  {
-    return getFromSubValArgOrPref(avm, a, sv, null, null, false);
-  }
-
-  public static boolean getFromSubValArgOrPref(ArgValuesMap avm, Arg a,
-          SubVals sv, String key, String pref, boolean def)
-  {
-    return getFromSubValArgOrPref(avm, a, sv, key, pref, def, false);
-  }
-
-  public static boolean getFromSubValArgOrPref(ArgValuesMap avm, Arg a,
-          SubVals sv, String key, String pref, boolean def,
-          boolean invertPref)
-  {
-    if ((key == null && a == null) || (sv == null && a == null))
-      return false;
-
-    boolean usingArgKey = false;
-    if (key == null)
-    {
-      key = a.getName();
-      usingArgKey = true;
-    }
-
-    String nokey = ArgParser.NEGATESTRING + key;
-
-    // look for key or nokey in subvals first (if using Arg check options)
-    if (sv != null)
-    {
-      // check for true boolean
-      if (sv.has(key) && sv.get(key) != null)
-      {
-        if (usingArgKey)
-        {
-          if (!(a.hasOption(Opt.BOOLEAN) || a.hasOption(Opt.UNARY)))
-          {
-            Console.debug(
-                    "Looking for boolean in subval from non-boolean/non-unary Arg "
-                            + a.getName());
-            return false;
-          }
-        }
-        return sv.get(key).toLowerCase(Locale.ROOT).equals("true");
-      }
-
-      // check for negative boolean (subval "no..." will be "true")
-      if (sv.has(nokey) && sv.get(nokey) != null)
-      {
-        if (usingArgKey)
-        {
-          if (!(a.hasOption(Opt.BOOLEAN)))
-          {
-            Console.debug(
-                    "Looking for negative boolean in subval from non-boolean Arg "
-                            + a.getName());
-            return false;
-          }
-        }
-        return !sv.get(nokey).toLowerCase(Locale.ROOT).equals("true");
-      }
-    }
-
-    // check argvalues
-    if (avm != null && avm.containsArg(a))
-      return avm.getBoolean(a);
-
-    // return preference or default
-    boolean prefVal = pref != null ? Cache.getDefault(pref, def) : false;
-    return pref != null ? (invertPref ? !prefVal : prefVal) : def;
-  }
-
   // the following methods look for the "*" linkedId and add the argvalue to all
   // linkedId ArgValues if it does.
-  // This version inserts the subvals sv into all created values
+  /**
+   * This version inserts the subvals sv into all created values
+   */
   private void addValue(String linkedId, Type type, ArgValues avs,
           SubVals sv, String v, int argIndex, boolean doSubs)
   {
@@ -1079,13 +980,6 @@ public class ArgParser
             argIndex, doSubs);
   }
 
-  private void addValue(String linkedId, Type type, ArgValues avs, String v,
-          int argIndex, boolean doSubs)
-  {
-    this.argValueOperation(Op.ADDVALUE, linkedId, type, avs, null, v, false,
-            argIndex, doSubs);
-  }
-
   private void setBoolean(String linkedId, Type type, ArgValues avs,
           boolean b, int argIndex)
   {
@@ -1119,21 +1013,32 @@ public class ArgParser
             doSubs);
   }
 
-  /*
+  /**
    * The following operations look for the "*" and "open*" linkedIds and add the
-   * argvalue to all appropriate linkedId ArgValues if it does.
-   * If subvals are supplied, they are inserted into all new set values.
+   * argvalue to all appropriate linkedId ArgValues if it does. If subvals are
+   * supplied, they are inserted into all new set values.
    * 
-   * @param op The ArgParser.Op operation
-   * @param linkedId The String linkedId from the ArgValuesMap
-   * @param type The Arg.Type to attach to this ArgValue
-   * @param avs The ArgValues for this linkedId
-   * @param sv Use these SubVals on the ArgValue
-   * @param merge Merge the SubVals with any existing on the value.  False will replace unless sv is null
-   * @param v The value of the ArgValue (may contain subvals).
-   * @param b The boolean value of the ArgValue.
-   * @param argIndex The argIndex for the ArgValue.
-   * @param doSubs Whether to perform substitutions on the subvals and value.
+   * @param op
+   *          The ArgParser.Op operation
+   * @param linkedId
+   *          The String linkedId from the ArgValuesMap
+   * @param type
+   *          The Arg.Type to attach to this ArgValue
+   * @param avs
+   *          The ArgValues for this linkedId
+   * @param sv
+   *          Use these SubVals on the ArgValue
+   * @param merge
+   *          Merge the SubVals with any existing on the value. False will
+   *          replace unless sv is null
+   * @param v
+   *          The value of the ArgValue (may contain subvals).
+   * @param b
+   *          The boolean value of the ArgValue.
+   * @param argIndex
+   *          The argIndex for the ArgValue.
+   * @param doSubs
+   *          Whether to perform substitutions on the subvals and value.
    */
   private void argValueOperation(Op op, String linkedId, Type type,
           ArgValues avs, SubVals sv, boolean merge, String v, boolean b,
@@ -1142,7 +1047,7 @@ public class ArgParser
     Arg a = avs.arg();
 
     List<String> wildcardLinkedIds = null;
-    if (a.hasOption(Opt.ALLOWALL))
+    if (a.hasOption(Opt.ALLOWMULTIID))
     {
       switch (linkedId)
       {
@@ -1173,7 +1078,9 @@ public class ArgParser
         // skip incorrectly stored wildcard ids!
         if (id == null || MATCHALLLINKEDIDS.equals(id)
                 || MATCHOPENEDLINKEDIDS.equals(id))
+        {
           continue;
+        }
         ArgValuesMap avm = linkedArgs.get(id);
         // don't set an output if there isn't an input
         if (a.hasOption(Opt.REQUIREINPUT)
@@ -1281,4 +1188,19 @@ public class ArgParser
     return linkedArgs.get(linkedId);
   }
 
+  public boolean isOldStyle()
+  {
+    return oldArguments;
+  }
+
+  public boolean isMixedStyle()
+  {
+    return mixedArguments;
+  }
+
+  public String[] getMixedExamples()
+  {
+    return mixedExamples;
+  }
+
 }
\ No newline at end of file