From 7e5052ca584689d07331a80a02fc4ea883c0322b Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Wed, 19 Sep 2018 17:42:39 -0300 Subject: Add named parameters You can now use named prefix parameters in FORMAT strings. Well, none of the directives support them yet, but they are accepted in the directives, and it'll be easy enough to add the support --- clformat/data/formats.sprop | 19 +++- .../java/bjc/utils/ioutils/format/CLFormatter.java | 4 +- .../bjc/utils/ioutils/format/CLParameters.java | 125 +++++++++++++++------ 3 files changed, 113 insertions(+), 35 deletions(-) diff --git a/clformat/data/formats.sprop b/clformat/data/formats.sprop index b6eac35..a32ca2e 100644 --- a/clformat/data/formats.sprop +++ b/clformat/data/formats.sprop @@ -19,10 +19,25 @@ clFormatDirective ~(?%1$s)?(?%2$s?)(?:%3$s) ## * A single character preceded by a single quote ## * The letter V (or v) ## * The character # -clFormatPrefix (?:(?:[-+]?\d+|'.|[Vv]|#|%|".*?(? namedParams; + private Map nameIndices; + /** * Create a new set of CL format parameters. * @@ -21,7 +26,30 @@ public class CLParameters { * The CL format parameters to use. */ public CLParameters(String[] params) { + this(params, new HashMap<>()); + } + + public CLParameters(Map namedParams) { + this(new String[0], namedParams); + } + + public CLParameters(String[] params, Map namedParams) { this.params = params; + + this.namedParams = namedParams; + this.nameIndices = new HashMap<>(); + } + + public void setIndexMappings(String... opts) { + for (int i = 0; i < opts.length; i++) { + String opt = opts[i]; + + if (!opt.equals("")) nameIndices.put(opt, i); + } + } + + public void setIndexMapping(String opt, int idx) { + nameIndices.put(opt, idx); } /** @@ -80,48 +108,81 @@ public class CLParameters { if (lParams.size() == 1 && lParams.get(0).equals("")) return new CLParameters(parameters.toArray(new String[0])); + Map namedParams = new HashMap<>(); + Map nameIndices = new HashMap<>(); + + int currParamNo = 0; for(String param : lParams) { - if(param.equalsIgnoreCase("V")) { - Object par = dirParams.item(); - boolean succ = dirParams.right(); + if (param.startsWith("#") && !param.equals("#")) { + boolean setIndex = false; - if(!succ) { - throw new IllegalStateException("Couldn't advance tape for parameter"); - } + int nameIdx = 0; + for (int i = 1; i < param.length(); i++) { + char ch = param.charAt(i); + + if (ch == ':' || ch == ';') { + if (ch == ';') setIndex = true; - if(par == null) { - throw new IllegalArgumentException( - "Expected a format parameter for V inline parameter"); + nameIdx = i; + break; + } } - if(par instanceof Number) { - int val = ((Number) par).intValue(); + String paramName = param.substring(0, nameIdx); + String paramVal = param.substring(nameIdx + 1); - parameters.add(Integer.toString(val)); - } else if(par instanceof Character) { - char ch = ((Character) par); + String actVal = parseParam(paramVal, dirParams); - parameters.add(Character.toString(ch)); - } else if (par instanceof String) { - parameters.add((String)par); - } else { - throw new IllegalArgumentException( - "Incorrect type of parameter for V inline parameter"); - } - } else if (param.equals("#")) { - parameters.add(Integer.toString(dirParams.size() - dirParams.position())); - } else if (param.equals("%")) { - parameters.add(Integer.toString(dirParams.position())); - } else if (param.startsWith("\"")) { - String dquote = param.substring(1, param.length() - 1); - - parameters.add(TokenUtils.descapeString(dquote)); + namedParams.put(paramName, actVal); + + if (setIndex) parameters.add(actVal); + } else { + parameters.add(parseParam(param, dirParams)); + } + + currParamNo += 1; + } + + return new CLParameters(parameters.toArray(new String[0]), namedParams); + } + + private static String parseParam(String param, Tape dirParams) { + if(param.equalsIgnoreCase("V")) { + Object par = dirParams.item(); + boolean succ = dirParams.right(); + + if(!succ) { + throw new IllegalStateException("Couldn't advance tape for parameter"); + } else if(par == null) { + throw new IllegalArgumentException( + "Expected a format parameter for V inline parameter"); + } + + if(par instanceof Number) { + int val = ((Number) par).intValue(); + + return Integer.toString(val); + } else if(par instanceof Character) { + char ch = ((Character) par); + + return Character.toString(ch); + } else if (par instanceof String) { + return (String)par; } else { - parameters.add(param); + throw new IllegalArgumentException( + "Incorrect type of parameter for V inline parameter"); } + } else if (param.equals("#")) { + return (Integer.toString(dirParams.size() - dirParams.position())); + } else if (param.equals("%")) { + return Integer.toString(dirParams.position()); + } else if (param.startsWith("\"")) { + String dquote = param.substring(1, param.length() - 1); + + return TokenUtils.descapeString(dquote); } - return new CLParameters(parameters.toArray(new String[0])); + return param; } /** @@ -305,7 +366,7 @@ public class CLParameters { throw iaex; } } - + @Override public String toString() { StringBuilder sb = new StringBuilder("["); -- cgit v1.2.3