summaryrefslogtreecommitdiff
path: root/base/src/main/java/bjc/utils/ioutils/format/directives
diff options
context:
space:
mode:
Diffstat (limited to 'base/src/main/java/bjc/utils/ioutils/format/directives')
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java1
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/CaseDirective.java117
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java134
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/Directive.java32
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java15
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java6
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java42
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java10
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/RecursiveDirective.java49
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/TabulateDirective.java2
10 files changed, 336 insertions, 72 deletions
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java
index 4276f40..9bad6d7 100644
--- a/base/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java
@@ -21,6 +21,7 @@ public class AestheticDirective implements Directive {
@Override
public void format(ReportWriter rw, Object item, CLModifiers mods, CLParameters params, Tape<Object> tParams,
Matcher dirMatcher, CLFormatter fmt) throws IOException {
+ // System.err.printf("Aesthetic directive with item \"%s\" and params: %s\n", item, tParams);
CLFormatter.checkItem(item, 'A');
int mincol = 0, colinc = 1, minpad = 0;
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/CaseDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/CaseDirective.java
new file mode 100644
index 0000000..728bb43
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/CaseDirective.java
@@ -0,0 +1,117 @@
+
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.*;
+import bjc.utils.ioutils.ReportWriter;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.IllegalFormatConversionException;
+import java.util.List;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class CaseDirective implements Directive {
+ private static final Pattern wordPattern = Pattern.compile("(\\w+)(\\b*)");
+
+ @Override
+ public void format(ReportWriter rw, Object item, CLModifiers mods, CLParameters params, Tape<Object> tParams,
+ Matcher dirMatcher, CLFormatter fmt) throws IOException {
+ StringBuffer condBody = new StringBuffer();
+
+ int nestLevel = 1;
+
+ while (dirMatcher.find()) {
+ /* Process a list of clauses. */
+ String dirName = dirMatcher.group("name");
+
+ if (dirName != null) {
+ /* Append everything up to this directive. */
+ dirMatcher.appendReplacement(condBody, "");
+
+ if (dirName.equals("(")) {
+ if (nestLevel > 0) {
+ condBody.append(dirMatcher.group());
+ }
+
+ nestLevel += 1;
+ } else if (Directive.isOpening(dirName)) {
+ nestLevel += 1;
+
+ condBody.append(dirMatcher.group());
+ } else if (dirName.equals(")")) {
+ nestLevel = Math.max(0, nestLevel - 1);
+
+ /* End the iteration. */
+ if (nestLevel == 0) break;
+ } else if (Directive.isClosing(dirName)) {
+ nestLevel = Math.max(0, nestLevel - 1);
+ } else {
+ /* Not a special directive. */
+ condBody.append(dirMatcher.group());
+ }
+ }
+ }
+
+ String frmt = condBody.toString();
+
+ ReportWriter nrw = rw.duplicate(new StringWriter());
+
+ fmt.doFormatString(frmt, nrw, tParams, false);
+
+ String strang = nrw.toString();
+
+ if (mods.colonMod && mods.atMod) {
+ strang = strang.toUpperCase();
+ } else if (mods.colonMod) {
+ Matcher mat = wordPattern.matcher(strang);
+
+ StringBuffer sb = new StringBuffer();
+ while(!mat.find()) {
+ mat.appendReplacement(sb, "");
+
+ String word = mat.group(1);
+
+ word = word.substring(0, 1).toUpperCase() + word.substring(1);
+
+ sb.append(word);
+ sb.append(mat.group(2));
+ }
+
+ mat.appendTail(sb);
+
+ strang = sb.toString();
+ } else if (mods.atMod) {
+ Matcher mat = wordPattern.matcher(strang);
+
+ StringBuffer sb = new StringBuffer();
+ boolean doCap = true;
+ while(!mat.find()) {
+ mat.appendReplacement(sb, "");
+
+ String word = mat.group(1);
+
+ if (doCap) {
+ doCap = false;
+
+ word = word.substring(0, 1).toUpperCase() + word.substring(1);
+ }
+
+ sb.append(word);
+ sb.append(mat.group(2));
+ }
+
+ mat.appendTail(sb);
+
+ strang = sb.toString();
+
+ } else {
+ strang = strang.toLowerCase();
+ }
+
+ rw.write(strang);
+ }
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java
index 71d9e7d..ed0b39b 100644
--- a/base/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java
@@ -8,6 +8,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.IllegalFormatConversionException;
import java.util.List;
+import java.util.logging.Logger;
import java.util.regex.Matcher;
/**
@@ -17,6 +18,7 @@ import java.util.regex.Matcher;
*
*/
public class ConditionalDirective implements Directive {
+ private static Logger LOG = Logger.getLogger(ConditionalDirective.class.getName());
@Override
public void format(ReportWriter rw, Object item, CLModifiers mods, CLParameters arrParams,
@@ -24,42 +26,75 @@ public class ConditionalDirective implements Directive {
StringBuffer condBody = new StringBuffer();
List<String> clauses = new ArrayList<>();
- String defClause = null;
+
+ String defClause = null;
boolean isDefault = false;
+ int nestLevel = 1;
+
while (dirMatcher.find()) {
/* Process a list of clauses. */
String dirName = dirMatcher.group("name");
String dirMods = dirMatcher.group("modifiers");
+ //System.err.printf("Found conditional directive %s with %s mods and level %d\n", dirName, dirMods, nestLevel);
if (dirName != null) {
/* Append everything up to this directive. */
dirMatcher.appendReplacement(condBody, "");
- if (dirName.equals("]")) {
- /* End the conditional. */
- String clause = condBody.toString();
- if (isDefault) {
- defClause = clause;
- } else {
+ if (dirName.equals("[")) {
+ if (nestLevel > 0) {
+ condBody.append(dirMatcher.group());
+ }
+ nestLevel += 1;
+ } else if (Directive.isOpening(dirName)) {
+ nestLevel += 1;
+
+ condBody.append(dirMatcher.group());
+ } else if (dirName.equals("]")) {
+ nestLevel = Math.max(0, nestLevel - 1);
+
+ if (nestLevel == 0) {
+ /* End the conditional. */
+ String clause = condBody.toString();
+ // System.err.printf("Found clause \"%s]\"\n", clause);
+ condBody = new StringBuffer();
+
+ if (isDefault) {
+ defClause = clause;
+ }
clauses.add(clause);
+
+ break;
+ } else {
+ /* Not a special directive. */
+ condBody.append(dirMatcher.group());
}
+ } else if (Directive.isClosing(dirName)) {
+ nestLevel = Math.max(0, nestLevel - 1);
- break;
+ condBody.append(dirMatcher.group());
} else if (dirName.equals(";")) {
- /* End the clause. */
- String clause = condBody.toString();
- if (isDefault) {
- defClause = clause;
- } else {
+ if (nestLevel == 1) {
+ /* End the clause. */
+ String clause = condBody.toString();
+ // System.err.printf("Found clause \"%s;\"\n", clause);
+ condBody = new StringBuffer();
+
+ if (isDefault) {
+ defClause = clause;
+ }
clauses.add(clause);
- }
- /*
- * Mark the next clause as the default.
- */
- if (dirMods.contains(":")) {
- isDefault = true;
+ /*
+ * Mark the next clause as the default.
+ */
+ if (dirMods.contains(":")) {
+ isDefault = true;
+ }
+ } else {
+ /* Not a special directive. */
+ condBody.append(dirMatcher.group());
}
} else {
/* Not a special directive. */
@@ -67,18 +102,21 @@ public class ConditionalDirective implements Directive {
}
}
}
+
+ if (mods.starMod && clauses.size() > 0) defClause = clauses.get(0);
- Object par = formatParams.item();
try {
if (mods.colonMod) {
formatParams.right();
- if (par == null) {
- throw new IllegalArgumentException("No parameter provided for [ directive.");
- } else if (!(par instanceof Boolean)) {
- throw new IllegalFormatConversionException('[', par.getClass());
+ boolean res = false;
+ if (item == null) {
+ //throw new IllegalArgumentException("No parameter provided for [ directive.");
+ } else if (!(item instanceof Boolean)) {
+ throw new IllegalFormatConversionException('[', item.getClass());
+ } else {
+ res = (Boolean) item;
}
- boolean res = (Boolean) par;
String frmt;
if (res)
@@ -86,17 +124,21 @@ public class ConditionalDirective implements Directive {
else
frmt = clauses.get(0);
- fmt.doFormatString(frmt, rw, formatParams);
+ fmt.doFormatString(frmt, rw, formatParams, false);
} else if (mods.atMod) {
- if (par == null) {
- throw new IllegalArgumentException("No parameter provided for [ directive.");
- } else if (!(par instanceof Boolean)) {
- throw new IllegalFormatConversionException('[', par.getClass());
+ boolean res = false;
+ if (item == null) {
+ // throw new IllegalArgumentException("No parameter provided for [ directive.");
+ } else if (item instanceof Integer) {
+ if ((Integer)item != 0) res = true;
+ } else if (item instanceof Boolean) {
+ res = (Boolean) item;
+ } else {
+ throw new IllegalFormatConversionException('[', item.getClass());
}
- boolean res = (Boolean) par;
if (res) {
- fmt.doFormatString(clauses.get(0), rw, formatParams);
+ fmt.doFormatString(clauses.get(0), rw, formatParams, false);
} else {
formatParams.right();
}
@@ -105,21 +147,33 @@ public class ConditionalDirective implements Directive {
if (arrParams.length() >= 1) {
res = arrParams.getInt(0, "conditional choice", '[');
} else {
- if (par == null) {
+ if (item == null) {
throw new IllegalArgumentException("No parameter provided for [ directive.");
- } else if (!(par instanceof Number)) {
- throw new IllegalFormatConversionException('[', par.getClass());
+ } else if (!(item instanceof Number)) {
+ throw new IllegalFormatConversionException('[', item.getClass());
}
- res = ((Number) par).intValue();
+ res = ((Number) item).intValue();
formatParams.right();
}
- if (res < 0 || res > clauses.size()) {
- if (defClause != null)
- fmt.doFormatString(defClause, rw, formatParams);
+ if (mods.dollarMod) res -= 1;
+
+ // System.err.printf("Attempting selection of clause %d of %d (%s) (default %s)\n",
+ // res, clauses.size(), clauses, defClause);
+ if (clauses.size() == 0 || res < 0 || res >= clauses.size()) {
+ // System.err.printf("Selecting default clause (res %d, max %d): %s\n", res, clauses.size(), defClause);
+ // int clauseNo = 0;
+ // for (String clause : clauses) {
+ // System.err.printf("... clause %d: %s\n", ++clauseNo, clause);
+ // }
+
+ if (defClause != null) fmt.doFormatString(defClause, rw, formatParams, false);
} else {
- fmt.doFormatString(clauses.get(res), rw, formatParams);
+ String frmt = clauses.get(res);
+
+ // System.out.printf("Selecting clause %d of %d (params %s): %s\n", res, clauses.size(), formatParams, frmt);
+ fmt.doFormatString(frmt, rw, formatParams, false);
}
}
} catch (EscapeException eex) {
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/Directive.java b/base/src/main/java/bjc/utils/ioutils/format/directives/Directive.java
index ad9c34c..61abfc1 100644
--- a/base/src/main/java/bjc/utils/ioutils/format/directives/Directive.java
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/Directive.java
@@ -37,4 +37,36 @@ public interface Directive {
*/
public void format(ReportWriter rw, Object item, CLModifiers mods, CLParameters arrParams, Tape<Object> tParams,
Matcher dirMatcher, CLFormatter fmt) throws IOException;
+
+ public static boolean isOpening(String str) {
+ return isOpening(str.charAt(0));
+ }
+
+ public static boolean isOpening(char dir) {
+ switch(dir) {
+ case '(':
+ case '<':
+ case '[':
+ case '{':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public static boolean isClosing(String str) {
+ return isClosing(str.charAt(0));
+ }
+
+ public static boolean isClosing(char dir) {
+ switch(dir) {
+ case ')':
+ case '>':
+ case ']':
+ case '}':
+ return true;
+ default:
+ return false;
+ }
+ }
}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
index 5badff0..74488ed 100644
--- a/base/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
@@ -21,28 +21,35 @@ public class EscapeDirective implements Directive {
Tape<Object> formatParams, Matcher dirMatcher, CLFormatter fmt) {
boolean shouldExit;
+ if (mods.dollarMod) formatParams.right();
+
switch(params.length()) {
case 0:
- shouldExit = formatParams.size() == 0;
+ shouldExit = formatParams.atEnd();
break;
case 1:
int num = params.getInt(0, "condition count", '^');
+
shouldExit = num == 0;
break;
case 2:
- int left = params.getInt(0, "left-hand condition", '^');
+ int left = params.getInt(0, "left-hand condition", '^');
int right = params.getInt(1, "right-hand condition", '^');
+
shouldExit = left == right;
break;
case 3:
default:
- int low = params.getInt(0, "lower-bound condition", '^');
- int mid = params.getInt(1, "interval condition", '^');
+ int low = params.getInt(0, "lower-bound condition", '^');
+ int mid = params.getInt(1, "interval condition", '^');
int high = params.getInt(2, "upper-bound condition", '^');
+
shouldExit = (low <= mid) && (mid <= high);
break;
}
+ if (mods.dollarMod) formatParams.left();
+
/* At negates it. */
if(mods.atMod) shouldExit = !shouldExit;
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java
index ccf01d8..3eb741e 100644
--- a/base/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java
@@ -38,10 +38,10 @@ public abstract class GeneralNumberDirective implements Directive {
*/
int commaInterval = 0;
char commaChar = ',';
- if (params.length() >= (argidx + 3)) {
- commaChar = params.getCharDefault((argidx + 3), "comma character", 'R', ' ');
- }
if (params.length() >= (argidx + 4)) {
+ commaChar = params.getCharDefault((argidx + 3), "comma character", 'R', ',');
+ }
+ if (params.length() >= (argidx + 5)) {
commaInterval = params.getIntDefault((argidx + 4), "comma interval", 'R', 0);
}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java
index 97e392e..2ce6309 100644
--- a/base/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java
@@ -36,18 +36,18 @@ public class IterationDirective implements Directive {
dirMatcher.appendReplacement(condBody, "");
if (dirName.equals("}")) {
- /* End the iteration. */
break;
+ } else {
+ /* Not a special directive. */
+ condBody.append(dirMatcher.group());
}
-
- /* Not a special directive. */
- condBody.append(dirMatcher.group());
}
}
String frmt = condBody.toString();
Object iter = item;
+ // System.err.printf("Iteration format \"%s\" (iter %s)\n", frmt, item);
if (frmt.equals("")) {
/* Grab an argument. */
if (!(item instanceof String)) {
@@ -86,25 +86,29 @@ public class IterationDirective implements Directive {
Tape<Object> nParams = new SingleTape<>(nitr);
try {
- fmt.doFormatString(frmt, rw, nParams);
+ fmt.doFormatString(frmt, rw, nParams, false);
} catch (EscapeException eex) {
if (eex.endIteration) {
- if (tParams.atEnd()) throw eex;
+ if (tParams.atEnd()) {
+ throw eex;
+ }
}
}
- iter = tParams.right();
+ tParams.right();
+ iter = tParams.item();
} while (tParams.position() < tParams.size());
} catch (EscapeException eex) {
}
} else if (mods.atMod) {
try {
- while (tParams.position() < tParams.size()) {
- if (numItr > maxItr) break;
- numItr += 1;
+ while (!tParams.atEnd()) {
+ // System.err.printf("Iterating with format \"%s\"\n", frmt);
+ if (numItr > maxItr) break;
+ numItr += 1;
- fmt.doFormatString(frmt, rw, tParams);
- }
+ fmt.doFormatString(frmt, rw, tParams, false);
+ }
} catch (EscapeException eex) {
if (eex.endIteration)
throw new UnsupportedOperationException("Colon mod not allowed on escape marker without colon mod on iteration");
@@ -133,13 +137,12 @@ public class IterationDirective implements Directive {
Tape<Object> nParams = new SingleTape<>(nitr);
try {
- fmt.doFormatString(frmt, rw, nParams);
+ fmt.doFormatString(frmt, rw, nParams, false);
} catch (EscapeException eex) {
if(eex.endIteration && !itr.hasNext()) throw eex;
}
}
- }
- catch (EscapeException eex) {
+ } catch (EscapeException eex) {
}
} else {
if (!(item instanceof Iterable<?>)) {
@@ -149,16 +152,13 @@ public class IterationDirective implements Directive {
try {
@SuppressWarnings("unchecked")
Iterable<Object> itr = (Iterable<Object>) item;
-
Tape<Object> nParams = new SingleTape<>(itr);
- while (nParams.position() < nParams.size()) {
- if (numItr > maxItr)
- break;
+ while (!nParams.atEnd()) {
+ if (numItr > maxItr) break;
numItr += 1;
- fmt.doFormatString(frmt, rw, nParams);
-
+ fmt.doFormatString(frmt, rw, nParams, false);
}
} catch (EscapeException eex) {
if (eex.endIteration)
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java
index 763665d..88b3e7e 100644
--- a/base/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java
@@ -26,21 +26,25 @@ public class NumberDirective extends GeneralNumberDirective {
* @param radix
* The radix of the number to use.
*/
- public NumberDirective(int argidx, int radix) {
+ public NumberDirective(int argidx, int radix, char directive) {
this.argidx = argidx;
this.radix = radix;
+
+ this.directive = directive;
}
private int argidx;
private int radix;
+ private char directive;
+
@Override
public void format(ReportWriter rw, Object item, CLModifiers mods, CLParameters params, Tape<Object> tParams,
Matcher dirMatcher, CLFormatter fmt) throws IOException {
- CLFormatter.checkItem(item, 'B');
+ CLFormatter.checkItem(item, directive);
if (!(item instanceof Number)) {
- throw new IllegalFormatConversionException('B', item.getClass());
+ throw new IllegalFormatConversionException(directive, item.getClass());
}
long val = ((Number) item).longValue();
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/RecursiveDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/RecursiveDirective.java
new file mode 100644
index 0000000..44a25ad
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/RecursiveDirective.java
@@ -0,0 +1,49 @@
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.esodata.SingleTape;
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.*;
+import bjc.utils.ioutils.ReportWriter;
+import java.util.IllegalFormatConversionException;
+
+import java.io.IOException;
+import java.util.regex.Matcher;
+
+public class RecursiveDirective implements Directive {
+ public void format(ReportWriter rw, Object arg, CLModifiers mods, CLParameters params, Tape<Object> tParams,
+ Matcher dirMatcher, CLFormatter fmt) throws IOException {
+ tParams.right();
+
+ CLFormatter.checkItem(arg, '?');
+
+ if (mods.atMod) {
+ if (!(arg instanceof String))
+ throw new IllegalFormatConversionException('?', arg.getClass());
+
+ try {
+ fmt.doFormatString((String)arg, rw, tParams, true);
+ } catch (EscapeException eex) {
+ if (eex.endIteration)
+ throw new UnsupportedOperationException("Colon mod not allowed on escape marker without colon mod on iteration");
+ }
+ } else {
+ if (tParams.atEnd())
+ throw new IllegalArgumentException("? directive requires two format parameters");
+
+ Object o = tParams.item();
+ tParams.right();
+
+ if (!(o instanceof Iterable))
+ throw new IllegalFormatConversionException('?', o.getClass());
+
+ Iterable<Object> itb = (Iterable<Object>)o;
+ Tape<Object> newParams = new SingleTape<>(itb);
+
+ try {
+ fmt.doFormatString((String)arg, rw, newParams, true);
+ } catch (EscapeException eex) {
+ throw new UnsupportedOperationException("Colon mod not allowed on escape marker without colon mod on iteration");
+ }
+ }
+ }
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/TabulateDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/TabulateDirective.java
index 7775904..d9136f2 100644
--- a/base/src/main/java/bjc/utils/ioutils/format/directives/TabulateDirective.java
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/TabulateDirective.java
@@ -14,7 +14,7 @@ public class TabulateDirective implements Directive {
// Unsupported feature.
//
// I can't really make out what this is supposed to do from the
- // documentation, but I suspect that it depends of font glyph
+ // documentation, but I suspect that it depends on font glyph
// size, not character positions
if (mods.colonMod) {
throw new UnsupportedOperationException("Colon mod is not supported for T directive");