File Doc Category Size Date Package Jpp.java API Doc phoneME MR2 API (J2ME) 9234 Wed May 02 17:59:58 BST 2007 None
Jpp public class Jpp extends Object A simple Java preprocessor. It process the following kind of directives
in Java code:
\/\* #ifdef \*\/
\/\* #ifndef \*\/
\/\* #else \*\/
\/\* #endif \*\/
The directives have to be embedded in a comment.
Fields Summary FileInputStream input FileOutputStream output static String IFDEF static String IFNDEF static String ELSE static String ENDIF String[] labels int nLabels boolean space boolean trace byte[] token Extract the next token.
Methods Summary java.lang.String getToken (byte[] bary, int[] idx, byte[] cr)
int b;
int i = 0;
// Discard the leading spaces.
do {
b = input.read();
if (b < 0)
break;
bary[idx[0]++] = (byte)b;
} while (b == ' " || b == '\t" || b == '*" || b == '/" ||
b == 10 || b == 13);
while (true) {
if (b == ' " || b == '\t" || b == 10 || b == 13) {
if (cr != null && (b == 10 || b == 13))
cr[0] = (byte)b;
break;
} else
token[i++] = (byte)b;
b = input.read();
if (b < 0)
break;
bary[idx[0]++] = (byte)b;
}
if (i == 0)
return null;
return new String(token, 0, i);
boolean isDefined (java.lang.String label)Check if the label is defined.
for (int i = 0; i < nLabels; i++) {
if (label.equals(labels[i]))
return true;
}
if (System.getProperty(label) != null)
return true;
return false;
public static void main (java.lang.String[] args)
if (args.length < 1)
prUsage();
String input = null;
String labels[] = new String[256];
String destDir = null, destFile = null;
int n = 0;
boolean space = true;
boolean trace = false;
int i = 0;
while (i < args.length) {
if (args[i].startsWith("-D")) {
labels[n++] = args[i].substring(2);
} else if (args[i].equals("-d")) {
if (i == args.length)
prUsage();
i++;
destDir = args[i];
} else if (args[i].equals("-o")) {
if (i == args.length)
prUsage();
i++;
destFile = args[i];
} else if (args[i].equals("-nospace")) {
space = false;
} else if (args[i].equals("-trace")) {
trace = true;
} else {
if (args[i].endsWith(".jpp"))
input = args[i];
}
i++;
}
if (input == null)
prUsage();
if (destDir != null && destFile != null)
prUsage();
Jpp jpp = new Jpp();
jpp.process(input, labels, n, destDir, destFile, space, trace);
static void prUsage ()
System.err.println(
"java Jpp <input>.jpp -D<label1> ... -D<labeln> " +
"[-d <output directory>] [-o <output file>] [-nospace] [-trace]");
System.exit(-1);
void process (java.lang.String inFile, java.lang.String[] labels, int nLabels, java.lang.String destDir, java.lang.String destFile, boolean space, boolean trace)
this.labels = labels;
this.nLabels = nLabels;
this.space = space;
this.trace = trace;
String outFile;
String separator = System.getProperty("file.separator");
if (destFile != null) {
try {
int idx = destFile.lastIndexOf(separator);
if (idx != -1) {
String dir = destFile.substring(0, idx);
File f = new File(dir);
f.mkdirs();
}
} catch (Exception e) {
System.err.println(e);
}
outFile = destFile;
} else if (destDir != null) {
int idx = inFile.lastIndexOf(separator);
if (idx != -1)
outFile = inFile.substring(idx+1, inFile.length()-3) + "java";
else
outFile = inFile.substring(0, inFile.length()-3) + "java";
outFile = destDir + separator + outFile;
} else
outFile = inFile.substring(0, inFile.length()-3) + "java";
(new File(outFile)).getParentFile().mkdirs();
try {
input = new FileInputStream(inFile);
} catch (IOException e) {
System.err.println("Cannot open input file: " + inFile + ":\n" + e);
System.exit(-1);
}
try {
output = new FileOutputStream(outFile);
} catch (IOException e) {
System.err.println("Cannot create output file: " + outFile +
":\n" + e);
System.exit(-1);
}
try {
processCode(true, false, null, 0);
} catch (IOException e) {
System.err.println(e);
System.exit(-1);
}
boolean processCode (boolean include, boolean endif, java.lang.String token, int level)
byte bary[] = new byte[1024];
int b;
int commentCount = 0;
int idx = 0;
int bidx[] = new int[1];
byte cr[] = new byte[1];
while (true) {
b = input.read();
if (b < 0)
break;
if ((b == '/" || b == '*") && commentCount == 1) {
bary[idx++] = (byte)b;
// Found the comment block.
bidx[0] = idx;
cr[0] = -1;
String tk = getToken(bary, bidx, cr);
if (tk == null)
break;
idx = bidx[0];
if (tk.equals(IFDEF) || tk.equals(IFNDEF)) {
bidx[0] = idx;
cr[0] = -1;
String tk2 = getToken(bary, bidx, cr);
if (tk2 == null)
break;
idx = bidx[0];
skipComments(b == '/", cr[0]);
boolean elseFound;
boolean incl;
if (trace)
trace(tk, tk2, level+1);
if (include) {
if ((tk.equals(IFDEF) && isDefined(tk2)) ||
(tk.equals(IFNDEF) && !isDefined(tk2))) {
incl = true;
} else {
incl = false;
}
elseFound = processCode(incl, true, tk2, level+1);
if (elseFound)
elseFound = processCode(!incl, true, tk2, level+1);
} else {
elseFound = processCode(false, true, tk2, level+1);
if (elseFound)
elseFound = processCode(false, true, tk2, level+1);
}
if (elseFound)
throw new IOException("Unmatched #else");
idx = 0;
} else if (tk.equals(ELSE)) {
if (trace)
trace(tk, "for " + token, level);
if (!endif)
throw new IOException("Unmatched #else");
skipComments(b == '/", cr[0]);
idx = 0;
return true;
} else if (tk.equals(ENDIF)) {
if (trace)
trace(tk, "for " + token, level);
if (!endif)
throw new IOException("Unmatched #endif");
skipComments(b == '/", cr[0]);
idx = 0;
return false;
} else {
// No match.
// Write the code if it should be included.
// Otherwise, only write the CR to maintain
// the line numbers.
if (include)
output.write(bary, 0, idx);
else if (space)
replaceCR(bary, 0, idx);
idx = 0;
}
commentCount = 0;
} else if (b == '/") {
commentCount = 1;
bary[idx++] = (byte)b;
} else {
if (commentCount != 0) {
// Write the code if it should be included.
// Otherwise, only write the CR to maintain
// the line numbers.
if (include)
output.write(bary, 0, idx);
else if (space)
replaceCR(bary, 0, idx);
idx = 0;
commentCount = 0;
}
if (include)
output.write(b);
else if (space && (b == 10 || b == 13))
output.write(b);
}
}
if (endif)
throw new IOException("Missing #endif");
return false;
void replaceCR (byte[] b, int off, int len)Parse the characters to only write te CR's.
for (int i = 0; i < len; i++) {
if (space && (b[off+i] == 10 || b[off+i] == 13))
output.write(b[off+i]);
}
void skipComments (boolean slash, byte cr)
int b;
// Handle double slash type of comments.
if (slash) {
if (cr != -1) {
if (space)
output.write(cr);
return;
}
while (true) {
b = input.read();
if (b < 0)
break;
if (b == 10 || b == 13) {
if (space)
output.write(b);
break;
}
}
return;
}
int commentCount = 0;
while (true) {
b = input.read();
if (b < 0)
throw new IOException("Incomplete comments block");
if (b == '*") {
commentCount = 1;
} else if (b == '/" && commentCount == 1) {
commentCount = 0;
break;
} else {
if (space && (b == 10 || b == 13))
output.write(b);
commentCount = 0;
}
}
void trace (java.lang.String tk1, java.lang.String tk2, int level)
for (; level > 0; level--)
System.out.print(" ");
System.out.println(tk1 + " " + tk2);