/* (C) Copyright IBM Corp 2005-2007. */
package xtc.lang.jeannie;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import xtc.parser.Column;
import xtc.parser.ParseException;
import xtc.parser.Result;
import xtc.parser.SemanticValue;
import xtc.tree.Node;
import xtc.util.Tool;
public class Preprocessor extends Tool {
public static void main(final String[] args) {
new Preprocessor().run(args);
}
public final String getCopy() {
return "(C) 2005-2007 IBM";
}
public final String getName() {
return "Jeannie preprocessor";
}
public static final String[] BUILTINS = {
"_copyFromJava", "_copyToJava", "_newJavaString", "_stringUTFLength" };
public static final String[] KEYWORDS = { "_cancel", "_commit", "_with" };
public final void init() {
super.init();
runtime.bool("underscores", "underscores", false,
"Inhibit aliasing Jeannie keywords and builtins to versions " +
"without leading underscore. For example, copyToJava will " +
"remain unchanged, instead of being macro-expanded to _copyToJava.");
runtime.setConsole(runtime.errConsole());
}
public final String lineMarker(final Column c) {
final StringBuilder b = new StringBuilder();
b.append("\n# " + c.line + " \"" + c.file.replace('\\', '/') + "\"\n");
for (int i=0; i<c.column; i++)
b.append(' ');
return b.toString();
}
public final String jeannieDefs() {
final StringBuilder b = new StringBuilder();
b.append("\n/* start auto-injected Jeannie declarations */\n");
b.append("#include <jni.h>\n");
b.append("\n");
b.append("jint _stringUTFLength(JNIEnv* env, jstring str, jint start, jint len) {\n");
b.append(" jint result = len;\n");
b.append(" const jchar* chars = (*env)->GetStringCritical(env, str, 0x0);\n");
b.append(" jint i;\n");
b.append(" for (i=0; i<len; i++) {\n");
b.append(" const jchar c = chars[start + i];\n");
b.append(" if (c == (jchar)0x0000) result++;\n");
b.append(" else if (c >= (jchar)0x0080) {\n");
b.append(" result++;\n");
b.append(" if (c >= (jchar)0x0800) result++;\n");
b.append(" }\n");
b.append(" }\n");
b.append(" (*env)->ReleaseStringCritical(env, str, chars);\n");
b.append(" return result;\n");
b.append("}\n");
if (!runtime.test("underscores")) {
b.append("\n/* aliased builtins (use -underscores to omit these definitions) */\n");
for (final String s : BUILTINS)
b.append("#define ").append(s.substring(1)).append(" ").append(s).append('\n');
b.append("\n/* aliased keywords (use -underscores to omit these definitions) */\n");
for (final String s : KEYWORDS)
b.append("#define ").append(s.substring(1)).append(" ").append(s).append('\n');
}
b.append("/* end auto-injected Jeannie declarations */\n");
return b.toString();
}
public final Node parse(final Reader in, final File file) throws IOException, ParseException {
final PreJeannieParser parser = new PreJeannieParser(in, file.getCanonicalPath(), (int)file.length());
parser._tool = this;
final Result parseResult = parser.pFile(0);
if (parseResult.hasValue()) {
final Node result = (Node)((SemanticValue)parseResult).value;
return result;
} else {
parser.signal(parseResult.parseError());
return null;
}
}
public final void process(final Node n) {
if (null != n)
System.out.println(n.getString(0));
}
}