001: /* (C) Copyright IBM Corp 2005-2007. */
002: package xtc.lang.jeannie;
003:
004: import java.io.File;
005: import java.io.IOException;
006: import java.io.Reader;
007:
008: import xtc.parser.Column;
009: import xtc.parser.ParseException;
010: import xtc.parser.Result;
011: import xtc.parser.SemanticValue;
012: import xtc.tree.Node;
013: import xtc.util.Tool;
014:
015: public class Preprocessor extends Tool {
016:
017: public static void main(final String[] args) {
018: new Preprocessor().run(args);
019: }
020:
021: public final String getCopy() {
022: return "(C) 2005-2007 IBM";
023: }
024:
025: public final String getName() {
026: return "Jeannie preprocessor";
027: }
028:
029: public static final String[] BUILTINS = { "_copyFromJava",
030: "_copyToJava", "_newJavaString", "_stringUTFLength" };
031:
032: public static final String[] KEYWORDS = { "_cancel", "_commit",
033: "_with" };
034:
035: public final void init() {
036: super .init();
037: runtime
038: .bool(
039: "underscores",
040: "underscores",
041: false,
042: "Inhibit aliasing Jeannie keywords and builtins to versions "
043: + "without leading underscore. For example, copyToJava will "
044: + "remain unchanged, instead of being macro-expanded to _copyToJava.");
045: runtime.setConsole(runtime.errConsole());
046: }
047:
048: public final String lineMarker(final Column c) {
049: final StringBuilder b = new StringBuilder();
050: b.append("\n# " + c.line + " \"" + c.file.replace('\\', '/')
051: + "\"\n");
052: for (int i = 0; i < c.column; i++)
053: b.append(' ');
054: return b.toString();
055: }
056:
057: public final String jeannieDefs() {
058: final StringBuilder b = new StringBuilder();
059: b.append("\n/* start auto-injected Jeannie declarations */\n");
060: b.append("#include <jni.h>\n");
061: b.append("\n");
062: b
063: .append("jint _stringUTFLength(JNIEnv* env, jstring str, jint start, jint len) {\n");
064: b.append(" jint result = len;\n");
065: b
066: .append(" const jchar* chars = (*env)->GetStringCritical(env, str, 0x0);\n");
067: b.append(" jint i;\n");
068: b.append(" for (i=0; i<len; i++) {\n");
069: b.append(" const jchar c = chars[start + i];\n");
070: b.append(" if (c == (jchar)0x0000) result++;\n");
071: b.append(" else if (c >= (jchar)0x0080) {\n");
072: b.append(" result++;\n");
073: b.append(" if (c >= (jchar)0x0800) result++;\n");
074: b.append(" }\n");
075: b.append(" }\n");
076: b.append(" (*env)->ReleaseStringCritical(env, str, chars);\n");
077: b.append(" return result;\n");
078: b.append("}\n");
079: if (!runtime.test("underscores")) {
080: b
081: .append("\n/* aliased builtins (use -underscores to omit these definitions) */\n");
082: for (final String s : BUILTINS)
083: b.append("#define ").append(s.substring(1)).append(" ")
084: .append(s).append('\n');
085: b
086: .append("\n/* aliased keywords (use -underscores to omit these definitions) */\n");
087: for (final String s : KEYWORDS)
088: b.append("#define ").append(s.substring(1)).append(" ")
089: .append(s).append('\n');
090: }
091: b.append("/* end auto-injected Jeannie declarations */\n");
092: return b.toString();
093: }
094:
095: public final Node parse(final Reader in, final File file)
096: throws IOException, ParseException {
097: final PreJeannieParser parser = new PreJeannieParser(in, file
098: .getCanonicalPath(), (int) file.length());
099: parser._tool = this ;
100: final Result parseResult = parser.pFile(0);
101: if (parseResult.hasValue()) {
102: final Node result = (Node) ((SemanticValue) parseResult).value;
103: return result;
104: } else {
105: parser.signal(parseResult.parseError());
106: return null;
107: }
108: }
109:
110: public final void process(final Node n) {
111: if (null != n)
112: System.out.println(n.getString(0));
113: }
114: }
|