diff options
| author | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2018-09-19 17:42:39 -0300 |
|---|---|---|
| committer | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2018-09-19 17:42:39 -0300 |
| commit | 7e5052ca584689d07331a80a02fc4ea883c0322b (patch) | |
| tree | dd6f10e3f2b29e066b4f74acf6fe6c14d0604f4c | |
| parent | 6261466749a5a351ed1ae0890e5f4359d8d58031 (diff) | |
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
| -rw-r--r-- | clformat/data/formats.sprop | 19 | ||||
| -rw-r--r-- | clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java | 4 | ||||
| -rw-r--r-- | clformat/src/main/java/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 ~(?<params>%1$s)?(?<modifiers>%2$s?)(?:%3$s) ## * A single character preceded by a single quote ## * The letter V (or v) ## * The character # -clFormatPrefix (?:(?:[-+]?\d+|'.|[Vv]|#|%|".*?(?<!\\)")?) +## * The character % +## * A double-quoted string +clFormatPrefixParam (?:(?:[-+]?\d+|'.|[Vv]|#|%|".*?(?<!\\)")?) + +## Matches a (possibly named) format string prefix parameter +## +## Parameters are seperated by ',' +## +## Named parameters are indicated by a preceeding #, which is followed by a +## parameter name (any sequence of non-space, non-seperator (',', ':', ';') +## printing characters), a seperator (: or ;), then the value of the parameter +clFormatPrefix (?:(?:#[\S&&[^,:;]][:;]%1$s)|%1$s) ## Match a format string modifier -## A modifier is any combination of $, :, * and @; duplicates don't matter though +## A modifier is any combination of the following characters +## * '$' * ':' +## * '*' * '@' +## +## Duplicates have no effect clFormatModifier (?:[@$:*]+) ## Matches a directive name. diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java b/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java index 2a8f443..9c79ec5 100644 --- a/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java +++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLFormatter.java @@ -46,7 +46,9 @@ public class CLFormatter { throw new RuntimeException("Couldn't load formats for formatter"); } - prefixParam = props.get("clFormatPrefix"); + String seqPrefixParam = props.get("clFormatPrefixParam"); + + prefixParam = String.format(props.get("clFormatPrefix"), seqPrefixParam); formatMod = props.get("clFormatModifier"); directiveName = props.get("clFormatName"); diff --git a/clformat/src/main/java/bjc/utils/ioutils/format/CLParameters.java b/clformat/src/main/java/bjc/utils/ioutils/format/CLParameters.java index 29494b2..a72adbe 100644 --- a/clformat/src/main/java/bjc/utils/ioutils/format/CLParameters.java +++ b/clformat/src/main/java/bjc/utils/ioutils/format/CLParameters.java @@ -1,7 +1,9 @@ package bjc.utils.ioutils.format; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import bjc.utils.esodata.Tape; import bjc.utils.parserutils.TokenUtils; @@ -14,6 +16,9 @@ import bjc.utils.parserutils.TokenUtils; public class CLParameters { private String[] params; + private Map<String, String> namedParams; + private Map<String, Integer> 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<String, String> namedParams) { + this(new String[0], namedParams); + } + + public CLParameters(String[] params, Map<String, String> 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<String, String> namedParams = new HashMap<>(); + Map<String, Integer> 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<Object> 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("["); |
