/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * This file was originally derived from the Polyglot extensible compiler framework. * * (C) Copyright 2000-2007 Polyglot project group, Cornell University * (C) Copyright IBM Corporation 2007-2012. */ package polyglot.util; import java.io.PrintWriter; import java.io.Writer; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.IOException; import java.util.Stack; /** * SimpleCodeWriter is a simple, fast, bulletproof implementation of the * CodeWriter interface. However, it does not try very hard to use vertical * space optimally or to stay within the horizontal margins. If aesthetically * appealing output is desired, use OptimalCodeWriter. */ public class SimpleCodeWriter extends CodeWriter { protected PrintWriter output; protected int width; protected int rmargin; protected int lmargin; protected Stack<State> lmargins; protected int pos; public SimpleCodeWriter(OutputStream o, int width_) { this(new PrintWriter(new OutputStreamWriter(o)), width_); } protected class State { public int lmargin; State(int m) { lmargin = m; } } public SimpleCodeWriter(PrintWriter o, int width_) { output = o; width = width_; rmargin = width; adjustRmargin(); pos = 0; lmargins = new Stack<State>(); } public SimpleCodeWriter(Writer o, int width_) { this(new PrintWriter(o), width_); } private void adjustRmargin() { rmargin -= 8; if (rmargin < width-24) rmargin = width-24; } public void write(String s) { if (s == null) write("null", 4); else if (s.length() > 0) write(s, s.length()); } public void writeln(String s) { write(s); newline(); } public void write(String s, int length) { output.print(s); pos += length; } public void begin(int n) { lmargins.push(new State(lmargin)); lmargin = pos + n; } public void end() { State s = (State)lmargins.pop(); lmargin = s.lmargin; } public void allowBreak(int n, int level, String alt, int altlen) { if (pos > width) adjustRmargin(); if (pos > rmargin) { newline(n, 1); } else { output.print(alt); pos += altlen; } } public void unifiedBreak(int n, int level, String alt, int altlen) { allowBreak(n, level, alt, altlen); } private void spaces(int n) { for (int i = 0; i < n; i++) { output.print(' '); } } public void newline() { if (pos != lmargin) { output.println(); pos = lmargin; spaces(lmargin); } } public void newline(int n, int level) { newline(); spaces(n); pos += n; } public boolean flush() throws IOException { output.flush(); pos = 0; return true; } public boolean flush(boolean format) throws IOException { return flush(); } public void close() throws IOException { flush(); output.close(); } /** * toString is not really supported by this implementation. */ public String toString() { return "<SimpleCodeWriter>"; } }