/** * Detect Unicode BOM in a source file. * * @param data Binary data of source file. * @param path The canonical path of source file. */ private void detectBOM(byte[] data, String path) { if (data.length > 2 && (byte) (data[0] ^ 0xEF) == 0 && (byte) (data[1] ^ 0xBB) == 0 && (byte) (data[2] ^ 0xBF) == 0) { App.exit("UTF8 BOM was found in " + path); } else if (data.length > 1 && (byte) (data[0] ^ 0xFE) == 0 && (byte) (data[1] ^ 0xFF) == 0) { App.exit("UTF16BE BOM was found in " + path); } else if (data.length > 1 && (byte) (data[0] ^ 0xFF) == 0 && (byte) (data[1] ^ 0xFE) == 0) { App.exit("UTF16LE BOM was found in " + path); } }
public App spineForm(Context ctxt, boolean drop_annos, boolean spec, boolean expand_defs) { Expr h = head; Expr prev = null; if (expand_defs) { Expr prev2 = null; while (h != prev) { prev2 = prev; prev = h; h = h.defExpandOne(ctxt, drop_annos, spec); } if (prev2 != null) prev = prev2; if (h.construct != construct && h.construct != CONST && h.construct != VAR) /* we are trying to keep these constructs in the head. */ h = prev; } if (ctxt.getFlag("debug_spine_form")) { ctxt.w.println("Computing spine form of " + toString(ctxt)); ctxt.w.println("{"); ctxt.w.println("Head expands to " + h.toString(ctxt)); ctxt.w.flush(); } App ret = this; if (h.construct == construct) { TermApp e = (TermApp) ((TermApp) h).spineForm(ctxt, drop_annos, spec, expand_defs); int eXlen = e.X.length; int newlen = X.length + eXlen; Expr[] X2 = new Expr[newlen]; boolean[] specarg2 = new boolean[newlen]; for (int i = 0; i < eXlen; i++) { X2[i] = e.X[i]; specarg2[i] = e.specarg[i]; } for (int i = 0, iend = X.length; i < iend; i++) { X2[i + eXlen] = X[i]; specarg2[i + eXlen] = specarg[i]; } ret = new TermApp(e.head, X2, specarg2); } else if (h != head) ret = new TermApp(h, X, specarg); if (ctxt.getFlag("debug_spine_form")) { ret.print(ctxt.w, ctxt); ctxt.w.println("\n}"); ctxt.w.flush(); } return ret; }
/** * Get dependencies of a source file. * * @param path The canonical path of source file. * @return Path of dependencies. */ private ArrayList<String> getDependencies(String path) { if (!dependenceMap.containsKey(path)) { ArrayList<String> dependencies = new ArrayList<String>(); Matcher m = PATTERN_REQUIRE.matcher(read(path, charset)); while (m.find()) { // Decide which root path to use. // Path wrapped in <> is related to root path. // Path wrapped in "" is related to parent folder of the source file. String root = null; if (m.group(1).equals("<")) { root = this.root; } else { root = new File(path).getParent(); } // Get path of required file. String required = m.group(2); File f = new File(root, required); if (f.exists()) { dependencies.add(canonize(f)); } else { App.exit("Cannot find required file " + required + " in " + path); } } dependenceMap.put(path, dependencies); } return dependenceMap.get(path); }
/** * Get the canonical path of a file. * * @param f The file. * @return The canonical path. */ private String canonize(File f) { String path = null; try { path = f.getCanonicalPath(); } catch (IOException e) { App.exit(e); } return path; }
/** * Get text content of a source file. * * @param path The canonical path of source file. * @param charset Source file encoding. * @return Source file content. */ public String read(String path, String charset) { String str = null; byte[] bin = read(path); try { str = Charset.forName(charset).newDecoder().decode(ByteBuffer.wrap(bin)).toString(); } catch (CharacterCodingException e) { App.exit("Cannot read " + path + " as " + charset + " encoded file"); } return str; }
/** * Get binary data of a source file. * * @param path The canonical path of source file. * @return Source file data. */ public byte[] read(String path) { if (!binaryCache.containsKey(path)) { try { BufferedInputStream bf = new BufferedInputStream(new FileInputStream(new File(path))); try { byte[] data = new byte[bf.available()]; bf.read(data); detectBOM(data, path); binaryCache.put(path, data); } finally { bf.close(); } } catch (IOException e) { App.exit(e); } } return binaryCache.get(path); }
/** * Locate root path. * * @param root The user-specified root path. */ private void locateRoot(String root) { // Locate default root folder. if (root == null) { File pwd = new File(".").getAbsoluteFile(); File f = pwd; String[] l = null; // Detect intl-style/xxx/htdocs by finding "js" and "css" in sub folders. do { f = f.getParentFile(); if (f == null) { break; } l = f.list( new FilenameFilter() { private Pattern pattern = Pattern.compile("^(?:js|css)$"); public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }); } while (l.length != 2); // If present, use intl-style/xxx/htdocs as root folder for Alibaba. if (f != null) { this.root = canonize(f); // Else use present working folder as root folder. } else { this.root = canonize(pwd); } // Use user-specified root folder. } else { File f = new File(root); if (f.exists()) { this.root = canonize(f); } else { App.exit("The user-specified root folder " + root + " does not exist."); } } }
/** * Travel dependencies tree by DFS and Post-Order algorithm. * * @param tree The initial tree which contains root node only. * @param footprint The footprint of the traversal. * @param output Output queue of combined files. */ private void travel( Stack<ArrayList<String>> tree, Stack<String> footprint, ArrayList<String> output) { for (String node : tree.peek()) { // Detect circular dependences by looking back footprint. if (footprint.contains(node)) { String msg = "Circular dependences was found\n"; for (String path : footprint) { msg += " " + path + " ->\n"; } msg += " " + node; App.exit(msg); } // Skip visited node. if (output.contains(node)) { continue; } // Move forward. footprint.push(node); // Add sub nodes. tree.push(getDependencies(node)); // Travel sub nodes. travel(tree, footprint, output); // Clean visited nodes. tree.pop(); // Move backward. footprint.pop(); // Add first visited node to output queue. output.add(node); } }
public static void main(String[] args) { App app = new App(); CommandPrinter commandPrinter = new CommandPrinter(); String[] fileNames = {"learn_and_teach", "logo", "right_angle"}; for (String fileName : fileNames) { try (Scanner scanner = new Scanner(Paths.get("test/" + fileName + ".in"))) { String line; int row = -1; while (scanner.hasNext()) { line = scanner.nextLine(); if (row == -1) { String[] sizeNums = line.trim().split(" "); int rowNum = Integer.parseInt(sizeNums[0]); int colNum = Integer.parseInt(sizeNums[1]); app.board = new Board(rowNum, colNum); } else { for (int col = 0; col < app.board.colNum; col++) { app.board.cells[row][col] = line.charAt(col); } } row++; } } catch (IOException e) { e.printStackTrace(); } List<Command> allCommands = new ArrayList<>(); app.board.prettyPrint(); // Processing / Computation SquareProcessor squareProcessor = new SquareProcessor(app.board); squareProcessor.process(); allCommands.addAll(squareProcessor.squareCommands); allCommands.addAll(squareProcessor.eraseCellCommands); app.board.prettyPrint(); LineProcessor lineProcessor = new LineProcessor(app.board); lineProcessor.process(); allCommands.addAll(lineProcessor.lineCommands); app.board.prettyPrint(); SingleCellProcessor singleCellProcessor = new SingleCellProcessor(app.board); singleCellProcessor.process(); allCommands.addAll(singleCellProcessor.cellCommands); app.board.prettyPrint(); System.out.println(allCommands.size()); // allCommands.stream().forEach((Command command) -> { // System.out.println(command); // }); commandPrinter.print(allCommands, "test/" + fileName + ".out"); } }
protected void print_arg(java.io.PrintStream w, Context ctxt, int i) { if (ctxt.getFlag("show_spec_args")) if (specarg[i]) w.print("spec "); super.print_arg(w, ctxt, i); }
public void do_print(java.io.PrintStream w, Context ctxt) { w.print("("); super.do_print(w, ctxt); w.print(")"); }