FileDocCategorySizeDatePackage
Jpp.javaAPI DocphoneME MR2 API (J2ME)9234Wed May 02 17:59:58 BST 2007None

Jpp

public class Jpp extends Object
A simple Java preprocessor. It process the following kind of directives in Java code: \/\* #ifdef

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.
Constructors Summary
Methods Summary
java.lang.StringgetToken(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);
    
booleanisDefined(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 voidmain(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 voidprUsage()

	System.err.println(
	    "java Jpp <input>.jpp -D<label1> ... -D<labeln> " +
	    "[-d <output directory>] [-o <output file>] [-nospace] [-trace]");
	System.exit(-1);
    
voidprocess(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);
	}
    
booleanprocessCode(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;
    
voidreplaceCR(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]);
	}
    
voidskipComments(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;
	    }
	}
    
voidtrace(java.lang.String tk1, java.lang.String tk2, int level)

	for (; level > 0; level--)
	    System.out.print("  ");
	System.out.println(tk1 + " " + tk2);