X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fbin%2Fargparser%2FArgParser.java;h=6d1251ce97bc1adf581676f7d9f691b992a7a79c;hb=b382fe5af3f138ede6db2ab1efc05ddd0819eea6;hp=223cc53bacb9a8edd0e3c8f14fca7f18c441b519;hpb=ec24991b1786e17158a43f713c8ae9c4f8647393;p=jalview.git diff --git a/src/jalview/bin/argparser/ArgParser.java b/src/jalview/bin/argparser/ArgParser.java index 223cc53..6d1251c 100644 --- a/src/jalview/bin/argparser/ArgParser.java +++ b/src/jalview/bin/argparser/ArgParser.java @@ -38,11 +38,14 @@ import jalview.bin.Cache; import jalview.bin.Console; import jalview.bin.Jalview; import jalview.bin.argparser.Arg.Opt; +import jalview.bin.argparser.Arg.Type; import jalview.util.FileUtils; import jalview.util.HttpUtils; public class ArgParser { + protected static final String SINGLEDASH = "-"; + protected static final String DOUBLEDASH = "--"; protected static final char EQUALS = '='; @@ -55,6 +58,9 @@ public class ArgParser // 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 + protected static final String MATCHOPENEDLINKEDIDS = "open*"; + // the counter added to the default linked id prefix private int defaultLinkedIdCounter = 0; @@ -78,6 +84,11 @@ public class ArgParser // 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 + private static final String LINKEDIDEXTENSION = "{extension}"; + // the linked id substitution string used to use the base filename of --append // or --open private static final String LINKEDIDBASENAME = "{basename}"; @@ -106,12 +117,18 @@ public class ArgParser // 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; + protected static final Map argMap; protected Map linkedArgs = new HashMap<>(); protected List linkedOrder = new ArrayList<>(); + protected List storedLinkedIds = new ArrayList<>(); + protected List argList = new ArrayList<>(); private static final char ARGFILECOMMENT = '#'; @@ -130,8 +147,7 @@ public class ArgParser if (argMap.containsKey(argName)) { Console.warn("Trying to add argument name multiple times: '" - + argName + "'"); // RESTORE THIS WHEN - // MERGED + + argName + "'"); if (argMap.get(argName) != a) { Console.error( @@ -228,13 +244,17 @@ public class ArgParser openEachInitialFilenames = false; } - String argName = null; - String val = null; - List globVals = null; // for Opt.GLOB only - SubVals globSubVals = null; // also for use by Opt.GLOB only - String linkedId = null; + // look for double-dash, e.g. --arg if (arg.startsWith(DOUBLEDASH)) { + String argName = null; + String val = null; + List globVals = null; // for Opt.GLOB only + SubVals globSubVals = null; // also for use by Opt.GLOB only + String linkedId = null; + Type type = null; + + // look for equals e.g. --arg=value int equalPos = arg.indexOf(EQUALS); if (equalPos > -1) { @@ -245,17 +265,38 @@ public class ArgParser { argName = arg.substring(DOUBLEDASH.length()); } + + // look for linked ID e.g. --arg[linkedID] int idOpen = argName.indexOf('['); int idClose = argName.indexOf(']'); - if (idOpen > -1 && idClose == argName.length() - 1) { linkedId = argName.substring(idOpen + 1, idClose); argName = argName.substring(0, idOpen); } + // look for type modification e.g. --help-opening + int dashPos = argName.indexOf(SINGLEDASH); + if (dashPos > -1) + { + String potentialArgName = argName.substring(0, dashPos); + Arg potentialArg = argMap.get(potentialArgName); + if (potentialArg != null && potentialArg.hasOption(Opt.HASTYPE)) + { + String typeName = argName.substring(dashPos + 1); + try + { + type = Type.valueOf(typeName); + } catch (IllegalArgumentException e) + { + type = Type.INVALID; + } + argName = argName.substring(0, dashPos); + } + } + Arg a = argMap.get(argName); - // check for boolean prepended by "no" + // check for boolean prepended by "no" e.g. --nowrap boolean negated = false; if (a == null && argName.startsWith(NEGATESTRING) && argMap .containsKey(argName.substring(NEGATESTRING.length()))) @@ -376,6 +417,18 @@ public class ArgParser else if (a == Arg.ALL) { allLinkedIds = !negated; + openedLinkedIds = false; + } + else if (a == Arg.OPENED) + { + openedLinkedIds = !negated; + allLinkedIds = false; + } + + if (a.hasOption(Opt.STORED)) + { + // reset the lastOpenedLinkedIds list + this.storedLinkedIds = new ArrayList<>(); } // this is probably only Arg.NEW and Arg.OPEN @@ -386,17 +439,43 @@ public class ArgParser } String autoCounterString = null; - boolean usingAutoCounterLinkedId = false; String defaultLinkedId = defaultLinkedId(false); boolean usingDefaultLinkedId = false; if (a.hasOption(Opt.LINKED)) { if (linkedId == null) { - if (allLinkedIds && a.hasOption(Opt.ALLOWALL)) + if (a.hasOption(Opt.OUTPUT) && a.hasOption(Opt.ALLOWALL) + && val.startsWith(MATCHALLLINKEDIDS)) + { + // --output=*.ext is shorthand for --all --output {basename}.ext + // (or --image=*.ext) + allLinkedIds = true; + openedLinkedIds = false; + linkedId = MATCHALLLINKEDIDS; + val = LINKEDIDDIRNAME + File.separator + LINKEDIDBASENAME + + val.substring(MATCHALLLINKEDIDS.length()); + } + else if (a.hasOption(Opt.OUTPUT) && 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)) { linkedId = MATCHALLLINKEDIDS; } + else if (openedLinkedIds && a.hasOption(Opt.ALLOWALL)) + { + linkedId = MATCHOPENEDLINKEDIDS; + } else { // use default linkedId for linked arguments @@ -412,7 +491,6 @@ public class ArgParser autoCounterString = Integer.toString(linkedIdAutoCounter); linkedId = linkedId.replace(LINKEDIDAUTOCOUNTER, autoCounterString); - usingAutoCounterLinkedId = true; Console.debug( "Changing linkedId to '" + linkedId + "' from " + arg); } @@ -422,7 +500,6 @@ public class ArgParser autoCounterString = Integer.toString(++linkedIdAutoCounter); linkedId = linkedId.replace(INCREMENTLINKEDIDAUTOCOUNTER, autoCounterString); - usingAutoCounterLinkedId = true; Console.debug( "Changing linkedId to '" + linkedId + "' from " + arg); } @@ -470,7 +547,7 @@ public class ArgParser { String v = gve.nextElement(); SubVals vsv = new SubVals(globSubVals, v); - addValue(linkedId, avs, vsv, v, argIndex++, true); + addValue(linkedId, type, avs, vsv, v, argIndex++, true); // if we're using defaultLinkedId and the arg increments the // counter: if (gve.hasMoreElements() && usingDefaultLinkedId @@ -486,22 +563,25 @@ public class ArgParser } else { - addValue(linkedId, avs, val, argIndex, true); + addValue(linkedId, type, avs, val, argIndex, true); } } else if (a.hasOption(Opt.BOOLEAN)) { - setBoolean(linkedId, avs, !negated, argIndex); + setBoolean(linkedId, type, avs, !negated, argIndex); setNegated(linkedId, avs, negated); } else if (a.hasOption(Opt.UNARY)) { - setBoolean(linkedId, avs, true, argIndex); + setBoolean(linkedId, type, avs, true, argIndex); } - // remove the '*' linkedId that should be empty if it was created - if (MATCHALLLINKEDIDS.equals(linkedId) + // remove the '*' or 'open*' linkedId that should be empty if it was + // created + if ((MATCHALLLINKEDIDS.equals(linkedId) && linkedArgs.containsKey(linkedId)) + || (MATCHOPENEDLINKEDIDS.equals(linkedId) + && linkedArgs.containsKey(linkedId))) { linkedArgs.remove(linkedId); } @@ -582,6 +662,10 @@ public class ArgParser { rest = rest.replace(LINKEDIDBASENAME, avm.getBasename()); } + if (rest.contains(LINKEDIDEXTENSION)) + { + rest = rest.replace(LINKEDIDEXTENSION, avm.getExtension()); + } if (rest.contains(LINKEDIDDIRNAME)) { rest = rest.replace(LINKEDIDDIRNAME, avm.getDirname()); @@ -915,143 +999,182 @@ public class ArgParser } // the following methods look for the "*" linkedId and add the argvalue to all - // linkedId ArgValues if it does - private void addValue(String linkedId, ArgValues avs, SubVals sv, - String v, int argIndex, boolean doSubs) + // linkedId ArgValues if it does. + // 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) { - Arg a = avs.arg(); - if (MATCHALLLINKEDIDS.equals(linkedId) && a.hasOption(Opt.ALLOWALL)) - { - for (String id : getLinkedIds()) - { - if (id == null || MATCHALLLINKEDIDS.equals(id)) - continue; - ArgValuesMap avm = linkedArgs.get(id); - if (a.hasOption(Opt.REQUIREINPUT) - && !avm.hasArgWithOption(Opt.INPUT)) - continue; - ArgValues tavs = avm.getOrCreateArgValues(a); - String val = v; - if (doSubs) - { - val = makeSubstitutions(v, id); - sv = new SubVals(sv, val); - } - tavs.addValue(sv, val, argIndex); - finaliseStoringArgValue(id, tavs); - } - } - else - { - String val = v; - if (doSubs) - { - val = makeSubstitutions(v, linkedId); - sv = new SubVals(sv, val); - } - avs.addValue(sv, val, argIndex); - finaliseStoringArgValue(linkedId, avs); - } + this.argValueOperation(Op.ADDVALUE, linkedId, type, avs, sv, v, false, + argIndex, doSubs); } - private void addValue(String linkedId, ArgValues avs, String v, + private void addValue(String linkedId, Type type, ArgValues avs, String v, int argIndex, boolean doSubs) { - Arg a = avs.arg(); - if (MATCHALLLINKEDIDS.equals(linkedId) && a.hasOption(Opt.ALLOWALL)) - { - for (String id : getLinkedIds()) - { - if (id == null || MATCHALLLINKEDIDS.equals(id)) - continue; - ArgValuesMap avm = linkedArgs.get(id); - // don't set an output if there isn't an input - if (a.hasOption(Opt.REQUIREINPUT) - && !avm.hasArgWithOption(Opt.INPUT)) - continue; - ArgValues tavs = avm.getOrCreateArgValues(a); - String val = doSubs ? makeSubstitutions(v, id) : v; - tavs.addValue(val, argIndex); - finaliseStoringArgValue(id, tavs); - } - } - else - { - String val = doSubs ? makeSubstitutions(v, linkedId) : v; - avs.addValue(val, argIndex); - finaliseStoringArgValue(linkedId, avs); - } + this.argValueOperation(Op.ADDVALUE, linkedId, type, avs, null, v, false, + argIndex, doSubs); } - private void setBoolean(String linkedId, ArgValues avs, boolean b, - int argIndex) + private void setBoolean(String linkedId, Type type, ArgValues avs, + boolean b, int argIndex) { - Arg a = avs.arg(); - if (MATCHALLLINKEDIDS.equals(linkedId) && a.hasOption(Opt.ALLOWALL)) - { - for (String id : getLinkedIds()) - { - if (id == null || MATCHALLLINKEDIDS.equals(id)) - continue; - ArgValuesMap avm = linkedArgs.get(id); - if (a.hasOption(Opt.REQUIREINPUT) - && !avm.hasArgWithOption(Opt.INPUT)) - continue; - ArgValues tavs = avm.getOrCreateArgValues(a); - tavs.setBoolean(b, argIndex); - finaliseStoringArgValue(id, tavs); - } - } - else - { - avs.setBoolean(b, argIndex); - finaliseStoringArgValue(linkedId, avs); - } + this.argValueOperation(Op.SETBOOLEAN, linkedId, type, avs, null, null, + b, argIndex, false); } private void setNegated(String linkedId, ArgValues avs, boolean b) { + this.argValueOperation(Op.SETNEGATED, linkedId, null, avs, null, null, + b, 0, false); + } + + private void incrementCount(String linkedId, ArgValues avs) + { + this.argValueOperation(Op.INCREMENTCOUNT, linkedId, null, avs, null, + null, false, 0, false); + } + + private enum Op + { + ADDVALUE, SETBOOLEAN, SETNEGATED, INCREMENTCOUNT + } + + // 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. + private void argValueOperation(Op op, String linkedId, Type type, + ArgValues avs, SubVals sv, String v, boolean b, int argIndex, + boolean doSubs) + { Arg a = avs.arg(); - if (MATCHALLLINKEDIDS.equals(linkedId) && a.hasOption(Opt.ALLOWALL)) + + List wildcardLinkedIds = null; + if (a.hasOption(Opt.ALLOWALL)) { - for (String id : getLinkedIds()) + switch (linkedId) { - if (id == null || MATCHALLLINKEDIDS.equals(id)) - continue; - ArgValuesMap avm = linkedArgs.get(id); - if (a.hasOption(Opt.REQUIREINPUT) - && !avm.hasArgWithOption(Opt.INPUT)) - continue; - ArgValues tavs = avm.getOrCreateArgValues(a); - tavs.setNegated(b); + case MATCHALLLINKEDIDS: + wildcardLinkedIds = getLinkedIds(); + break; + case MATCHOPENEDLINKEDIDS: + wildcardLinkedIds = this.storedLinkedIds; + break; } } - else + + // if we're not a wildcard linkedId and the arg is marked to be stored, add + // to storedLinkedIds + if (linkedId != null && wildcardLinkedIds == null + && a.hasOption(Opt.STORED) + && !storedLinkedIds.contains(linkedId)) { - avs.setNegated(b); + storedLinkedIds.add(linkedId); } - } - private void incrementCount(String linkedId, ArgValues avs) - { - Arg a = avs.arg(); - if (MATCHALLLINKEDIDS.equals(linkedId) && a.hasOption(Opt.ALLOWALL)) + // if we are a wildcard linkedId, apply the arg and value to all appropriate + // linkedIds + if (wildcardLinkedIds != null) { - for (String id : getLinkedIds()) + for (String id : wildcardLinkedIds) { - if (id == null || MATCHALLLINKEDIDS.equals(id)) + // 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) && !avm.hasArgWithOption(Opt.INPUT)) continue; + ArgValues tavs = avm.getOrCreateArgValues(a); - tavs.incrementCount(); + switch (op) + { + + case ADDVALUE: + String val = v; + if (sv != null) + { + if (doSubs) + { + val = makeSubstitutions(v, id); + sv = new SubVals(sv, val); + } + tavs.addValue(sv, type, val, argIndex, true); + } + else + { + if (doSubs) + { + val = makeSubstitutions(v, id); + } + tavs.addValue(type, val, argIndex, true); + } + finaliseStoringArgValue(id, tavs); + break; + + case SETBOOLEAN: + tavs.setBoolean(type, b, argIndex, true); + finaliseStoringArgValue(id, tavs); + break; + + case SETNEGATED: + tavs.setNegated(b, true); + break; + + case INCREMENTCOUNT: + tavs.incrementCount(); + break; + + default: + break; + + } + } } - else + else // no wildcard linkedId -- do it simpler { - avs.incrementCount(); + switch (op) + { + case ADDVALUE: + String val = v; + if (sv != null) + { + if (doSubs) + { + val = makeSubstitutions(v, linkedId); + sv = new SubVals(sv, val); + } + avs.addValue(sv, type, val, argIndex, false); + } + else + { + if (doSubs) + { + val = makeSubstitutions(v, linkedId); + } + avs.addValue(type, val, argIndex, false); + } + finaliseStoringArgValue(linkedId, avs); + break; + + case SETBOOLEAN: + avs.setBoolean(type, b, argIndex, false); + finaliseStoringArgValue(linkedId, avs); + break; + + case SETNEGATED: + avs.setNegated(b, false); + break; + + case INCREMENTCOUNT: + avs.incrementCount(); + break; + + default: + break; + } } }