Preprocessing Java with the C preprocessor
First I have to say that there is not much of a need to preprocess Java using the C preprocessor. You have to really have a specific requirement to need this sort of preprocessing control. First consider the available alternatives:
- Using Conditional Static Code Blocks
- Preprocessing using Ant's Replacetokens
- Using a Java preprocessing Ant task like JavaPP
I personally had exhausted all of these resources. I needed more control to inline method calls. I was targeting the dalvik VM and it didn't support these type of optimizations.
Here is preprocessing syntax I chose to use:
// Define a preprocessing macroThe syntax allows to add cpp macros without disturbing the existing Java code. This feature is nice if you are working in IDE's like Eclipse that highlight all the faulty syntax.
/*#define OPERATION(n, i) \
if ( pix == (block[n]) ) { \
d1 |= data[i][pix >> 4]; \
d2 |= data[i][pix]; \
}
#*/
// Condition import
//#ifdef USECLASS1
import com.brandnewreality.class1
//#else
import com.brandnewreality.class2
//#endif
Ant build.xml file.
<?xml version="1.0" ?>
<project default="main">
<target name="main" depends="preprocess,compile" description="Main target">
<echo>
Building class files
</echo>
</target>
<target name="preprocess">
<!-- Copy java files to the staging area and remove special comments -->
<copy todir="staging">
<fileset dir="src">
<include name="**/*.java"/>
</fileset>
<filterchain>
<tokenfilter>
<ReplaceRegex pattern="\/\*#" replace=""/>
<ReplaceRegex pattern="#\*\/" replace=""/>
<ReplaceRegex pattern="\/\/#" replace="#"/>
</tokenfilter>
</filterchain>
</copy>
<!-- Run the preprocessor -->
<apply executable="/usr/bin/cpp" addsourcefile="false">
<fileset dir="staging" includes="*.java"/>
<redirector>
<inputmapper type="glob" from="*" to="staging/*"/>
<outputmapper id="out" type="glob" from="*.java" to="staging/*.out"/>
</redirector>
</apply>
<!-- Replace the *.java with the preprocessed *.out files -->
<move todir="staging">
<fileset dir="staging">
<include name="**/*.out"/>
</fileset>
<mapper type="glob" from="*.out" to="*.java"/>
<!-- Clean up #'s generated by cpp -->
<filterchain>
<tokenfilter>
<ReplaceRegex pattern="^#.*" replace=""/>
</tokenfilter>
</filterchain>
</move>
</target>
<!-- Compile target -->
<target name="compile" description="Compilation target">
<javac srcdir="staging" destdir="bin" debug="on"/>
</target>
</project>