From 7ece1ed3e64770561a1e50085969dcfa6bda20a9 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Thu, 13 Jun 2019 19:07:28 -0400 Subject: Rename package Things are now in package bjc.everge, not bjc.replpair --- src/main/java/bjc/everge/Everge.java | 18 + src/main/java/bjc/everge/ReplError.java | 56 +++ src/main/java/bjc/everge/ReplOpts.java | 69 ++++ src/main/java/bjc/everge/ReplPair.java | 602 ++++++++++++++++++++++++++++ src/main/java/bjc/everge/StageStatus.java | 21 + src/main/java/bjc/replpair/ReplError.java | 56 --- src/main/java/bjc/replpair/ReplOpts.java | 69 ---- src/main/java/bjc/replpair/ReplPair.java | 602 ---------------------------- src/main/java/bjc/replpair/StageStatus.java | 21 - 9 files changed, 766 insertions(+), 748 deletions(-) create mode 100644 src/main/java/bjc/everge/Everge.java create mode 100644 src/main/java/bjc/everge/ReplError.java create mode 100644 src/main/java/bjc/everge/ReplOpts.java create mode 100644 src/main/java/bjc/everge/ReplPair.java create mode 100644 src/main/java/bjc/everge/StageStatus.java delete mode 100644 src/main/java/bjc/replpair/ReplError.java delete mode 100644 src/main/java/bjc/replpair/ReplOpts.java delete mode 100644 src/main/java/bjc/replpair/ReplPair.java delete mode 100644 src/main/java/bjc/replpair/StageStatus.java (limited to 'src/main') diff --git a/src/main/java/bjc/everge/Everge.java b/src/main/java/bjc/everge/Everge.java new file mode 100644 index 0000000..257b242 --- /dev/null +++ b/src/main/java/bjc/everge/Everge.java @@ -0,0 +1,18 @@ +package bjc.everge; + +/** + * Everge front-end application. + * + * @author Ben Culkin + */ +public class Everge { + /** + * Main method for front end, + * + * @param args + * The CLI arguments. + */ + public static void main(String[] args) { + + } +} diff --git a/src/main/java/bjc/everge/ReplError.java b/src/main/java/bjc/everge/ReplError.java new file mode 100644 index 0000000..e5a4dd0 --- /dev/null +++ b/src/main/java/bjc/everge/ReplError.java @@ -0,0 +1,56 @@ +package bjc.everge; + +/** + * Represents an error encountered parsing ReplPairs + * + * @author Ben Culkin + */ +public class ReplError { + /** + * The line the error occured on. + */ + public int line; + /** + * The number of pairs we have processed so far. + */ + public int numPairs; + + /** + * The text of the line we errored on. + */ + public String txt; + /** + * The message of the error. + */ + public String msg; + + /** + * Create a new ReplPair parse error. + * + * @param lne + * The line the error occured on. + * @param nPairs + * The number of pairs processed up to this point. + * @param msg + * The message detailing the error. + * @param txt + * The text that caused the error. + */ + public ReplError(int lne, int nPairs, String msg, String txt) { + line = lne; + numPairs = nPairs; + + this.txt = txt; + this.msg = msg; + } + + @Override + public String toString() { + String errString; + if (txt == null) errString = "No associated line"; + else if (txt.equals("")) errString = "Text of line was empty"; + else errString = "Text of line was: " + txt; + + return String.format("line %d, pair %d:%s\n\t%s", line, numPairs, msg, errString); + } +} diff --git a/src/main/java/bjc/everge/ReplOpts.java b/src/main/java/bjc/everge/ReplOpts.java new file mode 100644 index 0000000..aa836b0 --- /dev/null +++ b/src/main/java/bjc/everge/ReplOpts.java @@ -0,0 +1,69 @@ +package bjc.everge; + +/** + * Options for processing ReplPairs. + * + * @author Ben Culkin. + */ +public class ReplOpts { + /** + * The default priority. + */ + public int defPrior; + /** + * The default stage. + */ + public int defStage; + + /** + * Whether to process multi-line defns. + */ + public boolean defMulti; + + /** + * Default status. + */ + public StageStatus defStatus; + + /** + * Enable debug info. + */ + public boolean isDebug; + + /** + * Create a default set of options. + */ + public ReplOpts() { + defPrior = 0; + defStage = 0; + + defMulti = false; + + defStatus = StageStatus.BOTH; + + isDebug = false; + } + + /** + * Create a new set of repl. opts + * + * @param p + * The default priority to use + * @param s + * The default stage to use + * @param m + * Whether to process multi-line defns. + * @param t + * The default status. + */ + public ReplOpts(int p, int s, boolean m, StageStatus t, boolean d) { + defPrior = p; + defStage = s; + + defMulti = m; + + defStatus = t; + + isDebug = d; + } +} diff --git a/src/main/java/bjc/everge/ReplPair.java b/src/main/java/bjc/everge/ReplPair.java new file mode 100644 index 0000000..4f6b2ad --- /dev/null +++ b/src/main/java/bjc/everge/ReplPair.java @@ -0,0 +1,602 @@ +package bjc.everge; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import java.util.function.UnaryOperator; + +/** + * String pairs for replacements. + * + * @author Ben Culkin + */ +public class ReplPair implements Comparable, UnaryOperator { + private int lno; + + /** + * The priority for this replacement. + */ + public int priority; + + /** + * The name of this replacement. + * + * Defaults to the 'find' string. + */ + public String name; + /** + * The string to look for. + */ + public String find; + + /** + * The string to replace it with. + */ + public String replace; + + private StageStatus stat = StageStatus.BOTH; + + /** + * Create a new blank replacement pair. + */ + public ReplPair() { + this("", "", 1, null); + } + + /** + * Create a new replacement pair with a priority of 1. + * + * @param f + * The string to find. + * @param r + * The string to replace. + */ + public ReplPair(String f, String r) { + this(f, r, 1); + } + + /** + * Create a new named replacement pair with a priority of 1. + * + * @param f + * The string to find. + * @param r + * The string to replace. + * @param n + * The name of the replacement pair. + */ + public ReplPair(String f, String r, String n) { + this(f, r, 1, n); + } + + /** + * Create a new replacement pair with a set priority. + * + * @param f + * The string to find. + * @param r + * The string to replace. + * @param p + * The priority for the replacement. + */ + public ReplPair(String f, String r, int p) { + this(f, r, p, f); + } + + /** + * Create a new replacement pair with a set priority and name. + * + * @param f + * The string to find. + * @param r + * The string to replace. + * @param n + * The name of the replacement pair. + * @param p + * The priority for the replacement. + */ + public ReplPair(String f, String r, int p, String n) { + find = f; + replace = r; + + name = n; + + priority = p; + } + + /** + * Read a list of replacement pairs from an input source. + * + * @param scn + * The source to read the replacements from. + * @return + * The list of replacements. + */ + public static List readList(Scanner scn) { + List lst = new ArrayList<>(); + + return readList(lst, scn); + } + + /** + * Read a list of replacement pairs from an input source, adding them to + * an existing list. + * + * @param detals + * The list to add the replacements to. + * @param scn + * The source to read the replacements from. + * @return + * The list of replacements. + */ + public static List readList(List detals, Scanner scn) { + List errList = new ArrayList<>(); + + List rplPar = readList(detals, scn, errList); + + if (errList.size() != 0) { + String errString; + if (errList.size() == 0) errString = "An error"; + else errString = "Errors"; + + throw new IllegalArgumentException(String.format("%s occured parsing replacement pairs:\n%s", errString, errList)); + } + + return rplPar; + } + + /** + * Read a list of replacement pairs from an input source, adding them to + * an existing list. + * + * @param detals + * The list to add the replacements to. + * @param scn + * The source to read the replacements from. + * @param errs + * The list to stick errors in. + * @return + * The list of replacements. + */ + public static List readList(List detals, Scanner scn, List errs) { + return readList(detals, scn, errs, new ReplOpts()); + } + + public static List readList(List detals, Scanner scn, + List errs, ReplOpts ropts) { + int lno = 0; + int pno = 0; + + int defPrior = ropts.defPrior; + int defStage = ropts.defStage; + + boolean defMulti = ropts.defMulti; + + StageStatus defStatus = ropts.defStatus; + + boolean isDebug = ropts.isDebug; + + List> stages = new ArrayList<>(); + stages.add(new ArrayList()); + + // For every line in the source... + while (scn.hasNextLine()) { + String name = scn.nextLine().trim(); + lno += 1; + + // If its commented or blank, skip it + if (name.equals("")) continue; + if (name.startsWith("#")) continue; + + // Global control. Process it. + if (name.startsWith("|//")) { + name = name.substring(3); + + // Split out each control + String[] bits = name.split(";"); + + for (String bit : bits) { + String bitHead = bit.toUpperCase(); + String bitBody = bit; + + int idx = bit.indexOf('/'); + if (idx != -1) { + bitHead = bit.substring(0, idx).toUpperCase(); + bitBody = bit.substring(idx + 1); + } + + switch (bitHead) { + case "P": + try { + defPrior = Integer.parseInt(bitBody); + } catch (NumberFormatException nfex) { + String errMsg = String.format("'%s' is not a valid priority (must be an integer)", bitBody); + errs.add(new ReplError(lno, pno, errMsg, name)); + } + break; + case "S": + try { + int tmpStage = Integer.parseInt(bitBody); + if (tmpStage < 0) { + String errMsg = String.format("'%s' is not a valid stage (must be a positive integer)", bitBody); + errs.add(new ReplError(lno, pno, errMsg, name)); + + break; + } + defStage = tmpStage; + } catch (NumberFormatException nfex) { + String errMsg = String.format("'%s' is not a valid stage (must be a positive integer)", bitBody); + errs.add(new ReplError(lno, pno, errMsg, name)); + } + break; + case "MT": + defMulti = true; + break; + case "MF": + defMulti = false; + break; + case "M": + defMulti = Boolean.parseBoolean(bitBody); + break; + case "I": + defStatus = StageStatus.INTERNAL; + break; + case "E": + defStatus = StageStatus.EXTERNAL; + break; + case "B": + defStatus = StageStatus.BOTH; + break; + case "DT": + isDebug = true; + break; + case "DF": + isDebug = false; + break; + case "D": + isDebug = Boolean.parseBoolean(bitBody); + break; + default: + errs.add(new ReplError(lno, pno, String.format("Invalid control name '%s'", bitHead), name)); + break; + } + } + + continue; + } + + ReplPair rp = new ReplPair(); + rp.priority = defPrior; + rp.stat = defStatus; + rp.lno = lno; + + int stage = defStage; + + boolean isMulti = defMulti; + + // Name has attached controls, process them. + if (name.startsWith("//")) { + name = name.substring(2); + + int idx = name.indexOf("//"); + if (idx == -1) { + String msg = "Did not find control terminator (//) in name where it should be"; + + errs.add(new ReplError(lno, pno, msg, name)); + continue; + } + + String contName = name.substring(0, idx); + String actName = name.substring(idx + 2); + + // Split out each control + String[] bits = contName.split(";"); + + for (String bit : bits) { + String bitHead = bit.toUpperCase(); + String bitBody = bit; + + idx = bit.indexOf('/'); + if (idx != -1) { + bitHead = bit.substring(0, idx).toUpperCase(); + bitBody = bit.substring(idx + 1); + } + + switch (bitHead) { + case "N": + rp.name = bitBody; + break; + case "P": + try { + rp.priority = Integer.parseInt(bitBody); + } catch (NumberFormatException nfex) { + String errMsg = String.format("'%s' is not a valid priority (must be an integer)", bitBody); + errs.add(new ReplError(lno, pno, errMsg, name)); + } + break; + case "S": + try { + int tmpStage = Integer.parseInt(bitBody); + if (tmpStage < 0) { + String errMsg = String.format("'%s' is not a valid stage (must be a positive integer)", bitBody); + errs.add(new ReplError(lno, pno, errMsg, name)); + + break; + } + stage = tmpStage; + } catch (NumberFormatException nfex) { + String errMsg = String.format("'%s' is not a valid stage (must be a positive integer)", bitBody); + errs.add(new ReplError(lno, pno, errMsg, name)); + } + break; + case "MT": + isMulti = true; + break; + case "MF": + isMulti = false; + break; + case "M": + isMulti = Boolean.parseBoolean(bitBody); + break; + case "I": + rp.stat = StageStatus.INTERNAL; + break; + case "E": + rp.stat = StageStatus.EXTERNAL; + break; + case "B": + rp.stat = StageStatus.BOTH; + break; + default: + errs.add(new ReplError(lno, pno, String.format("Unknown control name '%s'", bitHead), name)); + break; + } + } + + // Multi-line name with a trailer + if (isMulti) { + String tmp = actName; + + while (tmp.endsWith("\\")) { + boolean incNL = tmp.endsWith("|\\"); + + if (!scn.hasNextLine()) break; + + tmp = scn.nextLine().trim(); + + if (tmp.equals("")) continue; + if (tmp.startsWith("#")) continue; + + actName = String.format("%s%s%s", actName, incNL ? "\n" : "", tmp); + } + } + + name = actName; + } + + rp.find = name; + if (rp.name == null) rp.name = name; + + // We started to process the pair, mark it as being + // started + pno += 1; + String body = null; + + // Read in the next uncommented line + do { + if (!scn.hasNextLine()) { + String msg = + "Ran out of input looking for replacement body for raw name " + name; + + errs.add(new ReplError(lno, pno, msg, null)); + break; + } + + body = scn.nextLine().trim(); + lno += 1; + } while (body.startsWith("#")); + + isMulti = defMulti; + + // Body has attached controls, process them. + if (body.startsWith("//")) { + body = body.substring(2); + + int idx = body.indexOf("//"); + if (idx == -1) { + String msg = "Did not find control terminator (//) in body where it should be"; + + errs.add(new ReplError(lno, pno, msg, body)); + continue; + } + + String contBody = body.substring(0, idx); + String actBody = body.substring(idx + 2); + + // Split out each control + String[] bits = actBody.split(";"); + + for (String bit : bits) { + String bitHead = bit.toUpperCase(); + String bitBody = bit; + + idx = bit.indexOf('/'); + if (idx != -1) { + bitHead = bit.substring(0, idx).toUpperCase(); + bitBody = bit.substring(idx + 1); + } + + switch (bitHead) { + case "MT": + isMulti = true; + break; + case "MF": + isMulti = false; + break; + case "M": + isMulti = Boolean.parseBoolean(bitBody); + break; + default: + errs.add(new ReplError(lno, pno, String.format("Invalid control name '%s'", bitHead), body)); + break; + } + } + + // Multi-line name with a trailer + if (isMulti) { + String tmp = actBody; + + while (tmp.endsWith("\\")) { + boolean incNL = tmp.endsWith("|\\"); + + if (!scn.hasNextLine()) break; + + tmp = scn.nextLine().trim(); + + if (tmp.startsWith("#")) continue; + + actBody = String.format("%s%s%s", actBody, incNL ? "\n" : "", tmp); + } + } + + body = actBody; + } + + rp.replace = body; + + List stageList = null; + if (stage == 0 || stages.size() < (stage - 1)) { + stageList = stages.get(stage); + + if (stageList == null) { + stageList = new ArrayList<>(); + + stages.add(stage, stageList); + } + } else { + for (int i = stages.size(); i <= stage; i++) { + stages.add(new ArrayList<>()); + } + + stageList = stages.get(stage); + } + + if (isDebug) { + System.err.printf("\t[DEBUG] Stage %d: Added %s\n\t\tContents: %s\n", + stage, rp, stageList); + } + + stageList.add(rp); + } + + // Special-case one-stage processing. + if (stages.size() == 1) { + if (isDebug) System.err.printf("\t[DEBUG] Executing single-stage bypass\n"); + + for (ReplPair rp : stages.iterator().next()) { + if (rp.stat == StageStatus.INTERNAL) { + if (isDebug) System.err.printf("\t[DEBUG] Excluding internal RP %s\n", rp); + + continue; + } + + detals.add(rp); + } + + detals.sort(null); + + return detals; + } + + // Handle stages + List tmpList = new ArrayList<>(); + tmpList.addAll(detals); + + if (isDebug) System.err.printf("\t[DEBUG] Stages: %s\n", stages); + + int procStg = 0; + for (List stageList : stages) { + procStg += 1; + List curStage = new ArrayList<>(); + + if (isDebug) System.err.printf("\t[DEBUG] Staging stage %d of %d: %s\n", + procStg, stageList.size(), stageList); + + for (ReplPair rp : stageList) { + // Process through every pair in the previous + // stages + for (ReplPair curPar : tmpList) { + String tmp = rp.replace.replaceAll(curPar.find, curPar.replace); + + if (isDebug && !rp.replace.equals(tmp)) { + System.err.printf("\t[DEBUG] Staged '%s' -> '%s'\t%s\n", + rp.replace, tmp, curPar); + } + + rp.replace = tmp; + } + + // If we're external; add straight to the output + if (rp.stat == StageStatus.EXTERNAL) { + if (isDebug) { + System.err.printf("\t[DEBUG] Skipped external for staging: %s\n", + rp); + } + + detals.add(rp); + } else { + if (isDebug) { + System.err.printf("\t[DEBUG] Added to stage %d: %s\n\t\tContents: %s\n", + procStg, rp, curStage); + } + + curStage.add(rp); + } + } + + tmpList.addAll(curStage); + tmpList.sort(null); + } + + // Copy over to output, excluding internals + for (ReplPair rp : tmpList) { + if (rp.stat == StageStatus.INTERNAL) { + if (isDebug) System.err.printf("\t[DEBUG] Excluded internal: %s\n", rp); + + continue; + } + + detals.add(rp); + } + + detals.sort(null); + + if (isDebug) { + System.err.printf("\t[DEBUG] Final output: %s\n", detals); + } + + return detals; + } + + @Override + public String apply(String inp) { + return inp.replaceAll(find, replace); + } + + @Override + public String toString() { + String nameStr = ""; + + if (!find.equals(name)) nameStr = String.format("(%s)", name); + + return String.format("%ss/%s/%s/p(%d)", nameStr, find, replace, priority); + } + + @Override + public int compareTo(ReplPair rp) { + if (this.priority == rp.priority) return this.lno - rp.lno; + + return rp.priority - this.priority; + } +} diff --git a/src/main/java/bjc/everge/StageStatus.java b/src/main/java/bjc/everge/StageStatus.java new file mode 100644 index 0000000..2a1fe63 --- /dev/null +++ b/src/main/java/bjc/everge/StageStatus.java @@ -0,0 +1,21 @@ +package bjc.everge; + +/** + * Possible statuses of pairs with respect to exporting. + * @author Ben Culkin + */ +public enum StageStatus { + /** + * Only use for staging pairs; don't export. + */ + INTERNAL, + /** + * Don't use for staging pairs; do export. + */ + EXTERNAL, + /** + * Use for staging pairs; do export. + */ + BOTH; +} + diff --git a/src/main/java/bjc/replpair/ReplError.java b/src/main/java/bjc/replpair/ReplError.java deleted file mode 100644 index 9d0fe02..0000000 --- a/src/main/java/bjc/replpair/ReplError.java +++ /dev/null @@ -1,56 +0,0 @@ -package bjc.replpair; - -/** - * Represents an error encountered parsing ReplPairs - * - * @author Ben Culkin - */ -public class ReplError { - /** - * The line the error occured on. - */ - public int line; - /** - * The number of pairs we have processed so far. - */ - public int numPairs; - - /** - * The text of the line we errored on. - */ - public String txt; - /** - * The message of the error. - */ - public String msg; - - /** - * Create a new ReplPair parse error. - * - * @param lne - * The line the error occured on. - * @param nPairs - * The number of pairs processed up to this point. - * @param msg - * The message detailing the error. - * @param txt - * The text that caused the error. - */ - public ReplError(int lne, int nPairs, String msg, String txt) { - line = lne; - numPairs = nPairs; - - this.txt = txt; - this.msg = msg; - } - - @Override - public String toString() { - String errString; - if (txt == null) errString = "No associated line"; - else if (txt.equals("")) errString = "Text of line was empty"; - else errString = "Text of line was: " + txt; - - return String.format("line %d, pair %d:%s\n\t%s", line, numPairs, msg, errString); - } -} diff --git a/src/main/java/bjc/replpair/ReplOpts.java b/src/main/java/bjc/replpair/ReplOpts.java deleted file mode 100644 index a1645bb..0000000 --- a/src/main/java/bjc/replpair/ReplOpts.java +++ /dev/null @@ -1,69 +0,0 @@ -package bjc.replpair; - -/** - * Options for processing ReplPairs. - * - * @author Ben Culkin. - */ -public class ReplOpts { - /** - * The default priority. - */ - public int defPrior; - /** - * The default stage. - */ - public int defStage; - - /** - * Whether to process multi-line defns. - */ - public boolean defMulti; - - /** - * Default status. - */ - public StageStatus defStatus; - - /** - * Enable debug info. - */ - public boolean isDebug; - - /** - * Create a default set of options. - */ - public ReplOpts() { - defPrior = 0; - defStage = 0; - - defMulti = false; - - defStatus = StageStatus.BOTH; - - isDebug = false; - } - - /** - * Create a new set of repl. opts - * - * @param p - * The default priority to use - * @param s - * The default stage to use - * @param m - * Whether to process multi-line defns. - * @param t - * The default status. - */ - public ReplOpts(int p, int s, boolean m, StageStatus t, boolean d) { - defPrior = p; - defStage = s; - - defMulti = m; - - defStatus = t; - - isDebug = d; - } -} diff --git a/src/main/java/bjc/replpair/ReplPair.java b/src/main/java/bjc/replpair/ReplPair.java deleted file mode 100644 index 651113b..0000000 --- a/src/main/java/bjc/replpair/ReplPair.java +++ /dev/null @@ -1,602 +0,0 @@ -package bjc.replpair; - -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; - -import java.util.function.UnaryOperator; - -/** - * String pairs for replacements. - * - * @author Ben Culkin - */ -public class ReplPair implements Comparable, UnaryOperator { - private int lno; - - /** - * The priority for this replacement. - */ - public int priority; - - /** - * The name of this replacement. - * - * Defaults to the 'find' string. - */ - public String name; - /** - * The string to look for. - */ - public String find; - - /** - * The string to replace it with. - */ - public String replace; - - private StageStatus stat = StageStatus.BOTH; - - /** - * Create a new blank replacement pair. - */ - public ReplPair() { - this("", "", 1, null); - } - - /** - * Create a new replacement pair with a priority of 1. - * - * @param f - * The string to find. - * @param r - * The string to replace. - */ - public ReplPair(String f, String r) { - this(f, r, 1); - } - - /** - * Create a new named replacement pair with a priority of 1. - * - * @param f - * The string to find. - * @param r - * The string to replace. - * @param n - * The name of the replacement pair. - */ - public ReplPair(String f, String r, String n) { - this(f, r, 1, n); - } - - /** - * Create a new replacement pair with a set priority. - * - * @param f - * The string to find. - * @param r - * The string to replace. - * @param p - * The priority for the replacement. - */ - public ReplPair(String f, String r, int p) { - this(f, r, p, f); - } - - /** - * Create a new replacement pair with a set priority and name. - * - * @param f - * The string to find. - * @param r - * The string to replace. - * @param n - * The name of the replacement pair. - * @param p - * The priority for the replacement. - */ - public ReplPair(String f, String r, int p, String n) { - find = f; - replace = r; - - name = n; - - priority = p; - } - - /** - * Read a list of replacement pairs from an input source. - * - * @param scn - * The source to read the replacements from. - * @return - * The list of replacements. - */ - public static List readList(Scanner scn) { - List lst = new ArrayList<>(); - - return readList(lst, scn); - } - - /** - * Read a list of replacement pairs from an input source, adding them to - * an existing list. - * - * @param detals - * The list to add the replacements to. - * @param scn - * The source to read the replacements from. - * @return - * The list of replacements. - */ - public static List readList(List detals, Scanner scn) { - List errList = new ArrayList<>(); - - List rplPar = readList(detals, scn, errList); - - if (errList.size() != 0) { - String errString; - if (errList.size() == 0) errString = "An error"; - else errString = "Errors"; - - throw new IllegalArgumentException(String.format("%s occured parsing replacement pairs:\n%s", errString, errList)); - } - - return rplPar; - } - - /** - * Read a list of replacement pairs from an input source, adding them to - * an existing list. - * - * @param detals - * The list to add the replacements to. - * @param scn - * The source to read the replacements from. - * @param errs - * The list to stick errors in. - * @return - * The list of replacements. - */ - public static List readList(List detals, Scanner scn, List errs) { - return readList(detals, scn, errs, new ReplOpts()); - } - - public static List readList(List detals, Scanner scn, - List errs, ReplOpts ropts) { - int lno = 0; - int pno = 0; - - int defPrior = ropts.defPrior; - int defStage = ropts.defStage; - - boolean defMulti = ropts.defMulti; - - StageStatus defStatus = ropts.defStatus; - - boolean isDebug = ropts.isDebug; - - List> stages = new ArrayList<>(); - stages.add(new ArrayList()); - - // For every line in the source... - while (scn.hasNextLine()) { - String name = scn.nextLine().trim(); - lno += 1; - - // If its commented or blank, skip it - if (name.equals("")) continue; - if (name.startsWith("#")) continue; - - // Global control. Process it. - if (name.startsWith("|//")) { - name = name.substring(3); - - // Split out each control - String[] bits = name.split(";"); - - for (String bit : bits) { - String bitHead = bit.toUpperCase(); - String bitBody = bit; - - int idx = bit.indexOf('/'); - if (idx != -1) { - bitHead = bit.substring(0, idx).toUpperCase(); - bitBody = bit.substring(idx + 1); - } - - switch (bitHead) { - case "P": - try { - defPrior = Integer.parseInt(bitBody); - } catch (NumberFormatException nfex) { - String errMsg = String.format("'%s' is not a valid priority (must be an integer)", bitBody); - errs.add(new ReplError(lno, pno, errMsg, name)); - } - break; - case "S": - try { - int tmpStage = Integer.parseInt(bitBody); - if (tmpStage < 0) { - String errMsg = String.format("'%s' is not a valid stage (must be a positive integer)", bitBody); - errs.add(new ReplError(lno, pno, errMsg, name)); - - break; - } - defStage = tmpStage; - } catch (NumberFormatException nfex) { - String errMsg = String.format("'%s' is not a valid stage (must be a positive integer)", bitBody); - errs.add(new ReplError(lno, pno, errMsg, name)); - } - break; - case "MT": - defMulti = true; - break; - case "MF": - defMulti = false; - break; - case "M": - defMulti = Boolean.parseBoolean(bitBody); - break; - case "I": - defStatus = StageStatus.INTERNAL; - break; - case "E": - defStatus = StageStatus.EXTERNAL; - break; - case "B": - defStatus = StageStatus.BOTH; - break; - case "DT": - isDebug = true; - break; - case "DF": - isDebug = false; - break; - case "D": - isDebug = Boolean.parseBoolean(bitBody); - break; - default: - errs.add(new ReplError(lno, pno, String.format("Invalid control name '%s'", bitHead), name)); - break; - } - } - - continue; - } - - ReplPair rp = new ReplPair(); - rp.priority = defPrior; - rp.stat = defStatus; - rp.lno = lno; - - int stage = defStage; - - boolean isMulti = defMulti; - - // Name has attached controls, process them. - if (name.startsWith("//")) { - name = name.substring(2); - - int idx = name.indexOf("//"); - if (idx == -1) { - String msg = "Did not find control terminator (//) in name where it should be"; - - errs.add(new ReplError(lno, pno, msg, name)); - continue; - } - - String contName = name.substring(0, idx); - String actName = name.substring(idx + 2); - - // Split out each control - String[] bits = contName.split(";"); - - for (String bit : bits) { - String bitHead = bit.toUpperCase(); - String bitBody = bit; - - idx = bit.indexOf('/'); - if (idx != -1) { - bitHead = bit.substring(0, idx).toUpperCase(); - bitBody = bit.substring(idx + 1); - } - - switch (bitHead) { - case "N": - rp.name = bitBody; - break; - case "P": - try { - rp.priority = Integer.parseInt(bitBody); - } catch (NumberFormatException nfex) { - String errMsg = String.format("'%s' is not a valid priority (must be an integer)", bitBody); - errs.add(new ReplError(lno, pno, errMsg, name)); - } - break; - case "S": - try { - int tmpStage = Integer.parseInt(bitBody); - if (tmpStage < 0) { - String errMsg = String.format("'%s' is not a valid stage (must be a positive integer)", bitBody); - errs.add(new ReplError(lno, pno, errMsg, name)); - - break; - } - stage = tmpStage; - } catch (NumberFormatException nfex) { - String errMsg = String.format("'%s' is not a valid stage (must be a positive integer)", bitBody); - errs.add(new ReplError(lno, pno, errMsg, name)); - } - break; - case "MT": - isMulti = true; - break; - case "MF": - isMulti = false; - break; - case "M": - isMulti = Boolean.parseBoolean(bitBody); - break; - case "I": - rp.stat = StageStatus.INTERNAL; - break; - case "E": - rp.stat = StageStatus.EXTERNAL; - break; - case "B": - rp.stat = StageStatus.BOTH; - break; - default: - errs.add(new ReplError(lno, pno, String.format("Unknown control name '%s'", bitHead), name)); - break; - } - } - - // Multi-line name with a trailer - if (isMulti) { - String tmp = actName; - - while (tmp.endsWith("\\")) { - boolean incNL = tmp.endsWith("|\\"); - - if (!scn.hasNextLine()) break; - - tmp = scn.nextLine().trim(); - - if (tmp.equals("")) continue; - if (tmp.startsWith("#")) continue; - - actName = String.format("%s%s%s", actName, incNL ? "\n" : "", tmp); - } - } - - name = actName; - } - - rp.find = name; - if (rp.name == null) rp.name = name; - - // We started to process the pair, mark it as being - // started - pno += 1; - String body = null; - - // Read in the next uncommented line - do { - if (!scn.hasNextLine()) { - String msg = - "Ran out of input looking for replacement body for raw name " + name; - - errs.add(new ReplError(lno, pno, msg, null)); - break; - } - - body = scn.nextLine().trim(); - lno += 1; - } while (body.startsWith("#")); - - isMulti = defMulti; - - // Body has attached controls, process them. - if (body.startsWith("//")) { - body = body.substring(2); - - int idx = body.indexOf("//"); - if (idx == -1) { - String msg = "Did not find control terminator (//) in body where it should be"; - - errs.add(new ReplError(lno, pno, msg, body)); - continue; - } - - String contBody = body.substring(0, idx); - String actBody = body.substring(idx + 2); - - // Split out each control - String[] bits = actBody.split(";"); - - for (String bit : bits) { - String bitHead = bit.toUpperCase(); - String bitBody = bit; - - idx = bit.indexOf('/'); - if (idx != -1) { - bitHead = bit.substring(0, idx).toUpperCase(); - bitBody = bit.substring(idx + 1); - } - - switch (bitHead) { - case "MT": - isMulti = true; - break; - case "MF": - isMulti = false; - break; - case "M": - isMulti = Boolean.parseBoolean(bitBody); - break; - default: - errs.add(new ReplError(lno, pno, String.format("Invalid control name '%s'", bitHead), body)); - break; - } - } - - // Multi-line name with a trailer - if (isMulti) { - String tmp = actBody; - - while (tmp.endsWith("\\")) { - boolean incNL = tmp.endsWith("|\\"); - - if (!scn.hasNextLine()) break; - - tmp = scn.nextLine().trim(); - - if (tmp.startsWith("#")) continue; - - actBody = String.format("%s%s%s", actBody, incNL ? "\n" : "", tmp); - } - } - - body = actBody; - } - - rp.replace = body; - - List stageList = null; - if (stage == 0 || stages.size() < (stage - 1)) { - stageList = stages.get(stage); - - if (stageList == null) { - stageList = new ArrayList<>(); - - stages.add(stage, stageList); - } - } else { - for (int i = stages.size(); i <= stage; i++) { - stages.add(new ArrayList<>()); - } - - stageList = stages.get(stage); - } - - if (isDebug) { - System.err.printf("\t[DEBUG] Stage %d: Added %s\n\t\tContents: %s\n", - stage, rp, stageList); - } - - stageList.add(rp); - } - - // Special-case one-stage processing. - if (stages.size() == 1) { - if (isDebug) System.err.printf("\t[DEBUG] Executing single-stage bypass\n"); - - for (ReplPair rp : stages.iterator().next()) { - if (rp.stat == StageStatus.INTERNAL) { - if (isDebug) System.err.printf("\t[DEBUG] Excluding internal RP %s\n", rp); - - continue; - } - - detals.add(rp); - } - - detals.sort(null); - - return detals; - } - - // Handle stages - List tmpList = new ArrayList<>(); - tmpList.addAll(detals); - - if (isDebug) System.err.printf("\t[DEBUG] Stages: %s\n", stages); - - int procStg = 0; - for (List stageList : stages) { - procStg += 1; - List curStage = new ArrayList<>(); - - if (isDebug) System.err.printf("\t[DEBUG] Staging stage %d of %d: %s\n", - procStg, stageList.size(), stageList); - - for (ReplPair rp : stageList) { - // Process through every pair in the previous - // stages - for (ReplPair curPar : tmpList) { - String tmp = rp.replace.replaceAll(curPar.find, curPar.replace); - - if (isDebug && !rp.replace.equals(tmp)) { - System.err.printf("\t[DEBUG] Staged '%s' -> '%s'\t%s\n", - rp.replace, tmp, curPar); - } - - rp.replace = tmp; - } - - // If we're external; add straight to the output - if (rp.stat == StageStatus.EXTERNAL) { - if (isDebug) { - System.err.printf("\t[DEBUG] Skipped external for staging: %s\n", - rp); - } - - detals.add(rp); - } else { - if (isDebug) { - System.err.printf("\t[DEBUG] Added to stage %d: %s\n\t\tContents: %s\n", - procStg, rp, curStage); - } - - curStage.add(rp); - } - } - - tmpList.addAll(curStage); - tmpList.sort(null); - } - - // Copy over to output, excluding internals - for (ReplPair rp : tmpList) { - if (rp.stat == StageStatus.INTERNAL) { - if (isDebug) System.err.printf("\t[DEBUG] Excluded internal: %s\n", rp); - - continue; - } - - detals.add(rp); - } - - detals.sort(null); - - if (isDebug) { - System.err.printf("\t[DEBUG] Final output: %s\n", detals); - } - - return detals; - } - - @Override - public String apply(String inp) { - return inp.replaceAll(find, replace); - } - - @Override - public String toString() { - String nameStr = ""; - - if (!find.equals(name)) nameStr = String.format("(%s)", name); - - return String.format("%ss/%s/%s/p(%d)", nameStr, find, replace, priority); - } - - @Override - public int compareTo(ReplPair rp) { - if (this.priority == rp.priority) return this.lno - rp.lno; - - return rp.priority - this.priority; - } -} diff --git a/src/main/java/bjc/replpair/StageStatus.java b/src/main/java/bjc/replpair/StageStatus.java deleted file mode 100644 index 2dd3c74..0000000 --- a/src/main/java/bjc/replpair/StageStatus.java +++ /dev/null @@ -1,21 +0,0 @@ -package bjc.replpair; - -/** - * Possible statuses of pairs with respect to exporting. - * @author Ben Culkin - */ -public enum StageStatus { - /** - * Only use for staging pairs; don't export. - */ - INTERNAL, - /** - * Don't use for staging pairs; do export. - */ - EXTERNAL, - /** - * Use for staging pairs; do export. - */ - BOTH; -} - -- cgit v1.2.3