diff options
author | paltherr <paltherr@epfl.ch> | 2003-04-14 09:31:03 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2003-04-14 09:31:03 +0000 |
commit | 6b71c4960af53ebcc5456a4d70145a73c16c7c95 (patch) | |
tree | 871828f8346d31959d33cc746e7f7852103e86e9 | |
parent | 8bfdf09fe8c1c823a9f620fb23d3e39c7ff65b5f (diff) | |
download | scala-6b71c4960af53ebcc5456a4d70145a73c16c7c95.tar.gz scala-6b71c4960af53ebcc5456a4d70145a73c16c7c95.tar.bz2 scala-6b71c4960af53ebcc5456a4d70145a73c16c7c95.zip |
- Added AbstractFileExpander.java
- Added TextExpander.java
- Added TextWriter.java
-rw-r--r-- | config/list/meta.lst | 4 | ||||
-rw-r--r-- | sources/meta/util/AbstractFileExpander.java | 126 | ||||
-rw-r--r-- | sources/meta/util/TextExpander.java | 275 | ||||
-rw-r--r-- | sources/meta/util/TextWriter.java | 248 |
4 files changed, 653 insertions, 0 deletions
diff --git a/config/list/meta.lst b/config/list/meta.lst index 25f932474f..0438674c3a 100644 --- a/config/list/meta.lst +++ b/config/list/meta.lst @@ -3,4 +3,8 @@ ############################################################################## # $Id$ +util/AbstractFileExpander.java +util/TextExpander.java +util/TextWriter.java + ############################################################################## diff --git a/sources/meta/util/AbstractFileExpander.java b/sources/meta/util/AbstractFileExpander.java new file mode 100644 index 0000000000..580fa08bd8 --- /dev/null +++ b/sources/meta/util/AbstractFileExpander.java @@ -0,0 +1,126 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package meta.util; + +import java.io.File; + +/** A base class for file expanders. */ +public abstract class AbstractFileExpander { + + //######################################################################## + // Private Constants + + /** The meta package */ + private static final String meta = "meta"; + + /** The meta name prefix */ + private static final String Meta = "Meta"; + + //######################################################################## + // Public Methods + + /** Returns the TextWriter in which this expander writes. */ + public abstract TextWriter getTextWriter(); + + /** + * Returns the package associated with this expander or null if + * there no such package. The default implementation returns the + * package of this instance's class. If the outermost package is + * named "meta", this package is omitted. + */ + public String getPackage() { + String fullname = getClass().getName(); + int end = fullname.lastIndexOf('.'); + if (end < 0) return null; + int start = fullname.startsWith(meta + ".") ? meta.length() + 1 : 0; + return fullname.substring(start, end); + } + + /** + * Returns the name associated with this expander. The default + * implementation returns the name of this instance's class. If + * that name starts with "Meta", this prefix is omitted. + */ + public String getName() { + String fullname = getClass().getName(); + int index = fullname.lastIndexOf('.'); + String name = index < 0 ? fullname : fullname.substring(index + 1); + return name.startsWith(Meta) ? name.substring(Meta.length()) : name; + } + + /** + * Returns the directory of the target file. The default + * implementation returns the directory corresponding to the + * this instance's associated package. + */ + public String getTargetDirectory() { + String peckage = getPackage(); + return peckage == null ? "." : peckage.replace('.',File.separatorChar); + } + + /** + * Returns the base name of the target file. The default + * implementation returns this instance's associated name. + */ + public String getTargetBaseName() { + return getName(); + } + + /** + * Returns the suffix of the target file or null if it has no + * suffix. The default implementation returns null. + */ + public String getTargetSuffix() { + return null; + } + + /** Returns the target file. */ + public File getTargetFile(File root) { + String suffix = getTargetSuffix(); + String name = getTargetBaseName(); + if (suffix != null) name = name + "." + suffix; + return new File(new File(root, getTargetDirectory()), name); + } + + /** + * Returns the directory of the source file. The default + * implementation returns the directory of the target file. + */ + public String getSourceDirectory() { + return getTargetDirectory(); + } + + /** + * Returns the base name of the source file. The default + * implementation returns the target base name. + */ + public String getSourceBaseName() { + return getTargetBaseName(); + } + + /** + * Returns the suffix of the source file or null if it has no + * suffix. The default implementation returns the target suffix + * suffixed with ".tmpl". + */ + public String getSourceSuffix() { + String suffix = getTargetSuffix(); + return (suffix == null ? "" : suffix + ".") + "tmpl"; + } + + /** Returns the source file. */ + public File getSourceFile(File root) { + String suffix = getSourceSuffix(); + String name = getSourceBaseName(); + if (suffix != null) name = name + "." + suffix; + return new File(new File(root, getSourceDirectory()), name); + } + + //######################################################################## +} diff --git a/sources/meta/util/TextExpander.java b/sources/meta/util/TextExpander.java new file mode 100644 index 0000000000..5fe7fbdb38 --- /dev/null +++ b/sources/meta/util/TextExpander.java @@ -0,0 +1,275 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package meta.util; + +import java.io.File; +import java.io.FileReader; +import java.io.BufferedReader; +import java.io.IOException; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + +/** A macro expander with support for indentation */ +public class TextExpander { + + //######################################################################## + // Public Constants + + /** Default macro name prefix */ + public static final String MACRO_PREFIX = "print"; + + /** Default macro left quote */ + public static final String MACRO_LQUOTE = "{#"; + + /** Default macro right quote */ + public static final String MACRO_RQUOTE = "#}"; + + /** Do not edit warning */ + public static final String DO_NOT_EDIT = + "DO NOT EDIT. Automatically generated file!"; + + //######################################################################## + // Private Constants + + /** An empty array of Classes */ + private static final Class [] NO_PARAMS = new Class[0]; + + /** An empty array of Objects */ + private static final Object[] NO_ARGS = new Object[0]; + + //######################################################################## + // Private Fields + + /** The output text writer */ + private final TextWriter writer; + + /** The macro expander */ + private final Object expander; + + /** The current macro name prefix */ + private String prefix; + + /** The current macro left quote */ + private String lquote; + + /** The current macro right quote */ + private String rquote; + + /** The current input name */ + private String name; + + /** The current input line number */ + private int line; + + /** The current error count */ + private int errors; + + //######################################################################## + // Public Constructors + + /** Creates a new TextExpander. */ + public TextExpander(TextWriter writer, Object expander) { + this.writer = writer; + this.expander = expander; + this.prefix = MACRO_PREFIX; + this.lquote = MACRO_LQUOTE; + this.rquote = MACRO_RQUOTE; + } + + //######################################################################## + // Public Methods - Text expansion + + /** Expands the text from the given file. */ + public void expandText(File file) { + setInputName(file.toString()); + setInputLine(0); + try { + BufferedReader reader = new BufferedReader(new FileReader(file)); + expandText(reader); + reader.close(); + } catch (IOException exception) { + error("input error", exception); + } + } + + /** Expands the text from the given character stream. */ + public void expandText(BufferedReader reader) { + try { + for (String line; (line = reader.readLine()) != null;) { + this.line++; + expandLine(line); + } + } catch (IOException exception) { + error("input error", exception); + } + } + + /** Expands the given line. */ + public void expandLine(String line) { + int index = 0; + int column = 0; + for (; index < line.length(); index++) { + switch (line.charAt(index)) { + case ' ' : column += 1; continue; + case '\t': column += 8 - (column % 8); continue; + } + break; + } + if (index < line.length()) { + int width = writer.getIndentWidth(); + writer.setIndentLevel(column / width); + for (int i = 0; i < column % width; i++) writer.print(' '); + line = line.substring(index); + if (line.indexOf("$Id") >= 0) + line = line.replaceFirst("[$]Id.*[$]", DO_NOT_EDIT); + expand(line); + } + writer.println(); + } + + /** Expands the given string. */ + public void expand(String input) { + int start = 0; + while (true) { + int lindex = input.indexOf(lquote, start); + if (lindex < 0) break; + int rindex = input.indexOf(rquote, lindex + lquote.length()); + if (rindex < 0) { error("unclosed macro"); break; } + String macro = input.substring(lindex + lquote.length(), rindex); + if (macro.indexOf(lquote) >= 0) { error("unclosed macro"); break; } + if (start < lindex) writer.print(input.substring(start, lindex)); + expandMacro(macro); + start = rindex + rquote.length(); + } + if (start < input.length()) writer.print(input.substring(start)); + } + + //######################################################################## + // Public Methods - Macro expansion + + /** Expands the given macro. */ + public void expandMacro(String macro) { + String member = prefix + macro; + Class clasz = expander.getClass(); + try { + expandMacro(macro, clasz.getMethod(member, NO_PARAMS)); + } catch (NoSuchMethodException exception) { + error("macro '" + macro + "' is undefined"); + writer.print(lquote + macro + rquote); + } + } + + /** Expands the given macro by invoking the given method. */ + public void expandMacro(String macro, Method method) { + try { + method.invoke(expander, NO_ARGS); + } catch (IllegalAccessException exception) { + error("macro '" + macro + "' could not access method " + method); + writer.print(lquote + macro + rquote); + } catch (InvocationTargetException exception) { + error("macro '" + macro + "' raised an exception"); + exception.getTargetException().printStackTrace(); + } + } + + //######################################################################## + // Public Methods - Error messages + + /** Prints an error message. */ + public void error(String error) { + String prefix = name != null ? name + ":" : "error:"; + if (line > 0) prefix = prefix + line + ":"; + System.err.println(prefix + " " + error); + errors++; + } + + /** Prints an error message. */ + public void error(String error, Throwable exception) { + if (exception.getMessage() != null) + error(exception.getMessage()); + else + error(error + " (" + exception.getClass().getName() + ")"); + } + + //######################################################################## + // Public Methods - Getters + + /** Returns the output text writer. */ + public TextWriter getOutputWriter() { + return writer; + } + + /** Returns the macro expander. */ + public Object getMacroExpander() { + return expander; + } + + /** Returns the current macro name prefix. */ + public String getMacroPrefix() { + return prefix; + } + + /** Returns the current macro left quote. */ + public String getMacroLeftQuote() { + return lquote; + } + + /** Returns the current macro right quote. */ + public String getMacroRightQuote() { + return lquote; + } + + /** Returns the current input name. */ + public String getInputName() { + return name; + } + + /** Returns the current input line. */ + public int getInputLine() { + return line; + } + + /** Returns the current error count. */ + public int getErrorCount() { + return errors; + } + + //######################################################################## + // Public Methods - Setters + + /** Sets the current macro name prefix. */ + public void setMacroPrefix(String prefix) { + this.prefix = prefix; + } + + /** Sets the current macro quotes. */ + public void setMacroQuotes(String lquote, String rquote) { + this.lquote = lquote; + this.rquote = rquote; + } + + /** Sets the current input name. */ + public void setInputName(String name) { + this.name = name; + } + + /** Sets the current input line. */ + public void setInputLine(int line) { + this.line = line; + } + + /** Sets the current error count. */ + public void setErrorCount(int errors) { + this.errors = errors; + } + + //######################################################################## +} diff --git a/sources/meta/util/TextWriter.java b/sources/meta/util/TextWriter.java new file mode 100644 index 0000000000..7d78f75b9c --- /dev/null +++ b/sources/meta/util/TextWriter.java @@ -0,0 +1,248 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package meta.util; + +/** A string generator with support for indentation and spacing. */ +public class TextWriter { + + //######################################################################## + // Private Constants + + /** The line separator */ + private static final String LINE = System.getProperty("line.separator"); + + /** The default width of an indentation level */ + private static final String STEP = " "; + + //######################################################################## + // Private Fields + + /** The output buffer */ + private final StringBuffer buffer; + + /** The width of an indentation level */ + private final String step; + + /** The current indentation level */ + private int level; + + /** Do we need to align? */ + private boolean align; + + /** Do we need to print a white space? */ + private boolean space; + + /** Is there already a empty line? */ + private boolean line; + + //######################################################################## + // Public Constructors + + /** Creates a new TextWriter. */ + public TextWriter() { + this(new StringBuffer()); + } + + /** Creates a new TextWriter. */ + public TextWriter(String step) { + this(new StringBuffer(), step); + } + + /** Creates a new TextWriter. */ + public TextWriter(String step, int level) { + this(new StringBuffer(), step, level); + } + + /** Creates a new TextWriter. */ + public TextWriter(StringBuffer buffer) { + this(buffer, STEP, 0); + } + + /** Creates a new TextWriter. */ + public TextWriter(StringBuffer buffer, String step) { + this(buffer, step, 0); + } + + /** Creates a new TextWriter. */ + public TextWriter(StringBuffer buffer, String step, int level) { + this.buffer = buffer; + this.step = step; + this.level = level; + this.align = false; + this.space = false; + this.line = false; + } + + //######################################################################## + // Public Methods - Printing + + /** Prints a new line. */ + public TextWriter println() { + return line(); + } + + /** Prints the boolean value followed by a new line. */ + public TextWriter println(boolean value) { + return print(value).line(); + } + + /** Prints the byte value followed by a new line. */ + public TextWriter println(byte value) { + return print(value).line(); + } + + /** Prints the short value followed by a new line. */ + public TextWriter println(short value) { + return print(value).line(); + } + + /** Prints the char value followed by a new line. */ + public TextWriter println(char value) { + return print(value).line(); + } + + /** Prints the int value followed by a new line. */ + public TextWriter println(int value) { + return print(value).line(); + } + + /** Prints the long value followed by a new line. */ + public TextWriter println(long value) { + return print(value).line(); + } + + /** Prints the float value followed by a new line. */ + public TextWriter println(float value) { + return print(value).line(); + } + + /** Prints the double value followed by a new line. */ + public TextWriter println(double value) { + return print(value).line(); + } + + /** Prints the string followed by a new line. */ + public TextWriter println(String value) { + return print(value).line(); + } + + /** Prints the boolean value. */ + public TextWriter print(boolean value) { + return print(String.valueOf(value)); + } + + /** Prints the byte value. */ + public TextWriter print(byte value) { + return print(String.valueOf(value)); + } + + /** Prints the short value. */ + public TextWriter print(short value) { + return print(String.valueOf(value)); + } + + /** Prints the char value. */ + public TextWriter print(char value) { + return print(String.valueOf(value)); + } + + /** Prints the int value. */ + public TextWriter print(int value) { + return print(String.valueOf(value)); + } + + /** Prints the long value. */ + public TextWriter print(long value) { + return print(String.valueOf(value)); + } + + /** Prints the float value. */ + public TextWriter print(float value) { + return print(String.valueOf(value)); + } + + /** Prints the long value. */ + public TextWriter print(double value) { + return print(String.valueOf(value)); + } + + /** Prints the string. */ + public TextWriter print(String value) { + if (align) for (int i = 0; i < level; i++) buffer.append(step); + if (space) buffer.append(' '); + buffer.append(value); + align = false; + space = false; + line = false; + return this; + } + + //######################################################################## + // Public Methods - Formating + + /** Returns the indentation width. */ + public int getIndentWidth() { + return step == null ? -1 : step.length(); + } + + /** Returns the indentation level. */ + public int getIndentLevel() { + return level; + } + + /** Returns the indentation level. */ + public TextWriter setIndentLevel(int level) { + this.level = level; + return this; + } + + /** Increases the indentation level by one. */ + public TextWriter indent() { + level++; + return this; + } + + /** Decreases the indentation level by one. */ + public TextWriter undent() { + level--; + return this; + } + + /** Starts a new line. */ + public TextWriter line() { + if (step == null) return space(); + if (line) return this; + buffer.append(LINE); + line = align; + align = true; + space = false; + return this; + } + + /** Inserts a white space. */ + public TextWriter space() { + space = !align; + return this; + } + + //######################################################################## + // Public Methods - Accessing + + /** Returns the underlying StringBuffer. */ + public StringBuffer getBuffer() { + return buffer; + } + + /** Returns the generated string. */ + public String toString() { + return buffer.toString(); + } + + //######################################################################## +} |