X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fbin%2Fargparser%2FArgParser.java;h=12e1b1d5d418a569836b51b84cc59114f24d671d;hb=bc1a3842b31a35a7794f4afec4911ad421c7c3e4;hp=386237514a07bc2d3b6192c29fc901529b9f41e3;hpb=c24ec44edbedba55005373c43bf712c047b56faa;p=jalview.git diff --git a/src/jalview/bin/argparser/ArgParser.java b/src/jalview/bin/argparser/ArgParser.java index 3862375..12e1b1d 100644 --- a/src/jalview/bin/argparser/ArgParser.java +++ b/src/jalview/bin/argparser/ArgParser.java @@ -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; @@ -120,6 +119,46 @@ public class ArgParser private static final String LINKEDIDDIRNAME = "{dirname}"; /** + * On-the-fly substitution (not made at argument parsing time)! the current + * structure filename extension + */ + private static final String STRUCTUREEXTENSION = "{structureextension}"; + + /** + * On-the-fly substitution (not made at argument parsing time)! the current + * structure filename base + */ + private static final String STRUCTUREBASENAME = "{structurebasename}"; + + /** + * On-the-fly substitution (not made at argument parsing time)! the current + * structure filename dir path + */ + private static final String STRUCTUREDIRNAME = "{structuredirname}"; + + /** + * On-the-fly substitution (not made at argument parsing time)! increment the + * on-the-fly counter and substitute the incremented value + */ + private static final String INCREMENTONTHEFLYCOUNTER = "{++m}"; + + /** + * On-the-fly substitution (not made at argument parsing time)! the current + * substitute with the on-the-fly counter + */ + private static final String ONTHEFLYCOUNTER = "{m}"; + + /** + * the string used for on-the-fly structure filename substitutions + */ + private String currentStructureFilename = null; + + /** + * the counter used for on-the-fly {m} substitutions + */ + private int ontheflyCounter = 0; + + /** * the current argfile */ private String argFile = null; @@ -150,12 +189,6 @@ public class ArgParser 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 */ @@ -177,6 +210,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<>(); @@ -241,23 +283,48 @@ 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 && !dd) + if (d) + { + if (dd) + { + mixedArguments = true; + } + else + { + oldArguments = true; + } + } + + if (oldArguments || mixedArguments) { // leave it to the old style -- parse an empty list parse(new ArrayList(), false, false); return; } + if (bsa != null) + { this.bootstrapArgs = bsa; + } else + { this.bootstrapArgs = BootstrapArgs.getBootstrapArgs(args); + } parse(args, initsubstitutions, allowPrivate); } @@ -298,6 +365,8 @@ public class ArgParser List globVals = null; // for Opt.GLOB only SubVals globSubVals = null; // also for use by Opt.GLOB only String linkedId = null; + String givenLinkedId = null; // this is preserved to add to each + // "ArgValue" Type type = null; // look for equals e.g. --arg=value @@ -318,6 +387,7 @@ public class ArgParser if (idOpen > -1 && idClose == argName.length() - 1) { linkedId = argName.substring(idOpen + 1, idClose); + givenLinkedId = linkedId; argName = argName.substring(0, idOpen); } @@ -379,10 +449,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) @@ -484,12 +556,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) { @@ -516,35 +582,31 @@ 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)) + else if (allLinkedIds && a.hasOption(Opt.ALLOWMULTIID)) { - // --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()); + linkedId = MATCHALLLINKEDIDS; } - else if (allLinkedIds && a.hasOption(Opt.ALLOWALL)) + if (allLinkedIds) { - linkedId = MATCHALLLINKEDIDS; + // user has made conscious decision for these args to apply to + // all, so set givenLinkedId too + givenLinkedId = linkedId; } - else if (openedLinkedIds && a.hasOption(Opt.ALLOWALL)) + else if (a.hasOption(Opt.ALLOWMULTIID) + && this.storedLinkedIds != null + && this.storedLinkedIds.size() > 0) { linkedId = MATCHOPENEDLINKEDIDS; } @@ -608,10 +670,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.hasType(Type.STRUCTURE) + // || a.getType() == Type.STRUCTUREIMAGE) + ) && !a.hasOption(Opt.PRIMARY)) { if (!subvals.has(Arg.ALLSTRUCTURES.getName())) // && !subvals.has("structureid")) @@ -634,7 +695,8 @@ public class ArgParser { String v = gve.nextElement(); SubVals vsv = new SubVals(globSubVals, v); - addValue(linkedId, type, avs, vsv, v, argIndex++, true); + addValue(linkedId, givenLinkedId, type, avs, vsv, v, + argIndex++, true); // if we're using defaultLinkedId and the arg increments the // counter: if (gve.hasMoreElements() && usingDefaultLinkedId @@ -651,26 +713,26 @@ public class ArgParser else { // addValue(linkedId, type, avs, val, argIndex, true); - addValue(linkedId, type, avs, addNewSubVals ? subvals : null, - val, argIndex, true); + addValue(linkedId, givenLinkedId, type, avs, + addNewSubVals ? subvals : null, val, argIndex, true); } } else if (a.hasOption(Opt.BOOLEAN)) { - setBoolean(linkedId, type, avs, !negated, argIndex); + setBoolean(linkedId, givenLinkedId, type, avs, !negated, + argIndex); setNegated(linkedId, avs, negated); } else if (a.hasOption(Opt.UNARY)) { - setBoolean(linkedId, type, avs, true, argIndex); + setBoolean(linkedId, givenLinkedId, type, avs, true, argIndex); } // 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); } @@ -717,6 +779,12 @@ public class ArgParser public String makeSubstitutions(String val, String linkedId) { + return makeSubstitutions(val, linkedId, false); + } + + public String makeSubstitutions(String val, String linkedId, + boolean onthefly) + { if (!this.substitutions || val == null) return val; @@ -736,14 +804,20 @@ public class ArgParser rest = val; } if (rest.contains(LINKEDIDAUTOCOUNTER)) + { rest = rest.replace(LINKEDIDAUTOCOUNTER, String.valueOf(linkedIdAutoCounter)); + } if (rest.contains(INCREMENTLINKEDIDAUTOCOUNTER)) + { rest = rest.replace(INCREMENTLINKEDIDAUTOCOUNTER, String.valueOf(++linkedIdAutoCounter)); + } if (rest.contains(DEFAULTLINKEDIDCOUNTER)) + { rest = rest.replace(DEFAULTLINKEDIDCOUNTER, String.valueOf(defaultLinkedIdCounter)); + } ArgValuesMap avm = linkedArgs.get(linkedId); if (avm != null) { @@ -773,6 +847,32 @@ public class ArgParser FileUtils.getDirname(new File(argFile))); } } + if (onthefly) + { + if (rest.contains(ONTHEFLYCOUNTER)) + { + rest = rest.replace(ONTHEFLYCOUNTER, + String.valueOf(ontheflyCounter)); + } + if (rest.contains(INCREMENTONTHEFLYCOUNTER)) + { + rest = rest.replace(INCREMENTONTHEFLYCOUNTER, + String.valueOf(++ontheflyCounter)); + } + if (currentStructureFilename != null) + { + if (rest.contains(STRUCTUREBASENAME)) + { + rest = rest.replace(STRUCTUREBASENAME, FileUtils + .getBasename(new File(currentStructureFilename))); + } + if (rest.contains(STRUCTUREDIRNAME)) + { + rest = rest.replace(STRUCTUREDIRNAME, + FileUtils.getDirname(new File(currentStructureFilename))); + } + } + } return new StringBuilder(subvals).append(rest).toString(); } @@ -915,7 +1015,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 { @@ -929,7 +1029,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 @@ -955,203 +1055,41 @@ 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 */ - private void addValue(String linkedId, Type type, ArgValues avs, - SubVals sv, String v, int argIndex, boolean doSubs) - { - this.argValueOperation(Op.ADDVALUE, linkedId, type, avs, sv, v, false, - argIndex, doSubs); - } - - private void addValue(String linkedId, Type type, ArgValues avs, String v, - int argIndex, boolean doSubs) + private void addValue(String linkedId, String givenLinkedId, Type type, + ArgValues avs, SubVals sv, String v, int argIndex, boolean doSubs) { - this.argValueOperation(Op.ADDVALUE, linkedId, type, avs, null, v, false, - argIndex, doSubs); + this.argValueOperation(Op.ADDVALUE, linkedId, givenLinkedId, type, avs, + sv, v, false, argIndex, doSubs); } - private void setBoolean(String linkedId, Type type, ArgValues avs, - boolean b, int argIndex) + private void setBoolean(String linkedId, String givenLinkedId, Type type, + ArgValues avs, boolean b, int argIndex) { - this.argValueOperation(Op.SETBOOLEAN, linkedId, type, avs, null, null, - b, argIndex, false); + this.argValueOperation(Op.SETBOOLEAN, linkedId, givenLinkedId, 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); + this.argValueOperation(Op.SETNEGATED, linkedId, null, 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); + this.argValueOperation(Op.INCREMENTCOUNT, linkedId, null, null, avs, + null, null, false, 0, false); } private enum Op @@ -1159,13 +1097,13 @@ public class ArgParser ADDVALUE, SETBOOLEAN, SETNEGATED, INCREMENTCOUNT } - private void argValueOperation(Op op, String linkedId, Type type, - ArgValues avs, SubVals sv, String v, boolean b, int argIndex, - boolean doSubs) + private void argValueOperation(Op op, String linkedId, + String givenLinkedId, Type type, ArgValues avs, SubVals sv, + String v, boolean b, int argIndex, boolean doSubs) { // default to merge subvals if subvals are provided - argValueOperation(op, linkedId, type, avs, sv, true, v, b, argIndex, - doSubs); + argValueOperation(op, linkedId, givenLinkedId, type, avs, sv, true, v, + b, argIndex, doSubs); } /** @@ -1195,14 +1133,14 @@ public class ArgParser * @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, - int argIndex, boolean doSubs) + private void argValueOperation(Op op, String linkedId, + String givenLinkedId, Type type, ArgValues avs, SubVals sv, + boolean merge, String v, boolean b, int argIndex, boolean doSubs) { Arg a = avs.arg(); List wildcardLinkedIds = null; - if (a.hasOption(Opt.ALLOWALL)) + if (a.hasOption(Opt.ALLOWMULTIID)) { switch (linkedId) { @@ -1228,13 +1166,16 @@ public class ArgParser // linkedIds if (wildcardLinkedIds != null) { - for (String id : wildcardLinkedIds) + for (String matchedLinkedId : wildcardLinkedIds) { // skip incorrectly stored wildcard ids! - if (id == null || MATCHALLLINKEDIDS.equals(id) - || MATCHOPENEDLINKEDIDS.equals(id)) + if (matchedLinkedId == null + || MATCHALLLINKEDIDS.equals(matchedLinkedId) + || MATCHOPENEDLINKEDIDS.equals(matchedLinkedId)) + { continue; - ArgValuesMap avm = linkedArgs.get(id); + } + ArgValuesMap avm = linkedArgs.get(matchedLinkedId); // don't set an output if there isn't an input if (a.hasOption(Opt.REQUIREINPUT) && !avm.hasArgWithOption(Opt.INPUT)) @@ -1251,24 +1192,24 @@ public class ArgParser if (doSubs) { sv = new SubVals(sv, val, merge); - val = makeSubstitutions(sv.getContent(), id); + val = makeSubstitutions(sv.getContent(), matchedLinkedId); } - tavs.addValue(sv, type, val, argIndex, true); + tavs.addValue(sv, type, val, argIndex, true, givenLinkedId); } else { if (doSubs) { - val = makeSubstitutions(v, id); + val = makeSubstitutions(v, matchedLinkedId); } - tavs.addValue(type, val, argIndex, true); + tavs.addValue(type, val, argIndex, true, givenLinkedId); } - finaliseStoringArgValue(id, tavs); + finaliseStoringArgValue(matchedLinkedId, tavs); break; case SETBOOLEAN: - tavs.setBoolean(type, b, argIndex, true); - finaliseStoringArgValue(id, tavs); + tavs.setBoolean(type, b, argIndex, true, givenLinkedId); + finaliseStoringArgValue(matchedLinkedId, tavs); break; case SETNEGATED: @@ -1299,7 +1240,7 @@ public class ArgParser val = makeSubstitutions(v, linkedId); sv = new SubVals(sv, val); } - avs.addValue(sv, type, val, argIndex, false); + avs.addValue(sv, type, val, argIndex, false, givenLinkedId); } else { @@ -1307,13 +1248,13 @@ public class ArgParser { val = makeSubstitutions(v, linkedId); } - avs.addValue(type, val, argIndex, false); + avs.addValue(type, val, argIndex, false, givenLinkedId); } finaliseStoringArgValue(linkedId, avs); break; case SETBOOLEAN: - avs.setBoolean(type, b, argIndex, false); + avs.setBoolean(type, b, argIndex, false, givenLinkedId); finaliseStoringArgValue(linkedId, avs); break; @@ -1341,4 +1282,24 @@ public class ArgParser return linkedArgs.get(linkedId); } + public boolean isOldStyle() + { + return oldArguments; + } + + public boolean isMixedStyle() + { + return mixedArguments; + } + + public String[] getMixedExamples() + { + return mixedExamples; + } + + public void setStructureFilename(String s) + { + this.currentStructureFilename = s; + } + } \ No newline at end of file