<!--
    build.xml : Ant build file for CIVL
    Author: Stephen F. Siegel, University of Delaware
    Last modified:
    
    The following can be defined on command line with -Dprop=val:
    revision.  This is for the use of our SVN commit hook, which 
    runs the test suite and performs other tasks every time a commit
    is made.  The SVN revision number is just used here to insert
    into reports.
-->

<project name="CIVL" basedir="." default="jar">

	<!-- Directories -->

	<property file="build.properties" />
	<property name="src.dir" value="${basedir}/src" />
	<property name="real.src.dir" value="${src.dir}/edu/udel/cis/vsl/civl/civlc" />
	<property name="bin.dir" value="${basedir}/bin" />
	<property name="grammar.dir" value="${basedir}/grammar" />
	<property name="javadoc.dir" value="${basedir}/doc/javadoc" />
	<property name="jar-name" value="civl.jar" />
	<property name="jar-path" value="${basedir}/${jar-name}" />
	<property name="main-class" value="edu.udel.cis.vsl.civl.CIVL" />

	<!-- Junit: automated unit tester Properties  -->

	<property name="test.src.dir" location="${basedir}/test" />
	<property name="test.bin.dir" location="${basedir}/bin-test" />
	<property name="junit.dir" location="${basedir}/junit" />
	<property name="junit.data.dir" location="${junit.dir}/data" />
	<property name="junit.reports.dir" location="${junit.dir}/reports" />

	<!-- Cobertura: test coverage analyzer Properties -->

	<property name="cob.log.file" value="${basedir}/cobertura.log" />
	<property name="cob.ser.file" value="${basedir}/cobertura.ser" />
	<property name="cobertura.dir" value="${basedir}/cobertura" />
	<property name="cob.instrumented.dir" value="${cobertura.dir}/instrumented" />
	<property name="cob.reports.dir" value="${cobertura.dir}/reports" />
	<property name="cob.reports.xml.dir" value="${cob.reports.dir}/junit-xml" />
	<property name="cob.reports.html.dir" value="${cob.reports.dir}/junit-html" />
	<property name="cob.coverage.xml.dir" value="${cob.reports.dir}/cobertura-xml" />
	<property name="cob.coverage.html.dir" value="${cob.reports.dir}/cobertura-html" />

	<!-- Tell Ant about Cobertura tasks -->

	<path id="cobertura.classpath">
		<fileset dir="${cobertura.lib.dir}">
			<include name="cobertura.jar" />
			<include name="lib/**/*.jar" />
		</fileset>
	</path>

	<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />


	<!-- Running ANTLR -->

	<path id="antlr.class.path">
		<pathelement location="${antlr.jar}" />
	</path>

	<target name="parsers" depends="CivlCParser,PreprocessorExpressionParser,PreprocessorParser,PreprocessorLexer">
	</target>

	<target name="checkCivlCParserChanges">
		<uptodate property="noCivlCParserChanges">
			<srcfiles file="${grammar.dir}/CivlCParser.g" />
			<srcfiles file="${grammar.dir}/PreprocessorLexer.g" />
			<srcfiles file="${grammar.dir}/PreprocessorLexer.tokens" />
			<srcfiles file="${grammar.dir}/PreprocessorParser.g" />
			<srcfiles file="${grammar.dir}/PreprocessorParser.tokens" />
			<mapper type="merge" to="${real.src.dir}/parse/common/CivlCParser.java" />
		</uptodate>
	</target>

	<target name="CivlCParser" depends="PreprocessorParser,checkCivlCParserChanges" unless="noCivlCParserChanges">
		<java classname="org.antlr.Tool" classpathref="antlr.class.path" fork="true" failonerror="true" dir="${grammar.dir}">
			<arg value="-verbose" />
			<arg value="CivlCParser.g" />
		</java>
		<move file="${grammar.dir}/CivlCParser.java" todir="${real.src.dir}/parse/common" />
	</target>

	<target name="checkExpressionParserChanges">
		<uptodate property="noExpressionParserChanges">
			<srcfiles file="${grammar.dir}/PreprocessorExpressionParser.g" />
			<srcfiles file="${grammar.dir}/PreprocessorLexer.g" />
			<srcfiles file="${grammar.dir}/PreprocessorLexer.tokens" />
			<mapper type="merge" to="${real.src.dir}/preproc/common/PreprocessorExpressionParser.java" />
		</uptodate>
	</target>

	<target name="PreprocessorExpressionParser" depends="PreprocessorLexer,checkExpressionParserChanges" unless="noExpressionParserChanges">
		<java classname="org.antlr.Tool" classpathref="antlr.class.path" fork="true" failonerror="true" dir="${grammar.dir}">
			<arg value="-verbose" />
			<arg value="PreprocessorExpressionParser.g" />
		</java>
		<move file="${grammar.dir}/PreprocessorExpressionParser.java" todir="${real.src.dir}/preproc/common" />
	</target>

	<target name="checkParserChanges">
		<uptodate property="noParserChanges">
			<srcfiles file="${grammar.dir}/PreprocessorParser.g" />
			<srcfiles file="${grammar.dir}/PreprocessorLexer.g" />
			<srcfiles file="${grammar.dir}/PreprocessorLexer.tokens" />
			<mapper type="merge" to="${real.src.dir}/preproc/common/PreprocessorParser.java" />
		</uptodate>
	</target>

	<target name="PreprocessorParser" depends="PreprocessorLexer,checkParserChanges" unless="noParserChanges">
		<java classname="org.antlr.Tool" classpathref="antlr.class.path" fork="true" failonerror="true" dir="${grammar.dir}">
			<arg value="-verbose" />
			<arg value="PreprocessorParser.g" />
		</java>
		<move file="${grammar.dir}/PreprocessorParser.java" todir="${real.src.dir}/preproc/common" />
	</target>

	<target name="checkLexerChanges">
		<uptodate property="noLexerChanges">
			<srcfiles file="${grammar.dir}/PreprocessorLexer.g" />
			<compositemapper>
				<mapper type="merge" to="${grammar.dir}/PreprocessorLexer.tokens" />
				<mapper type="merge" to="${real.src.dir}/preproc/common/PreprocessorLexer.java" />
			</compositemapper>
		</uptodate>
	</target>

	<target name="PreprocessorLexer" depends="checkLexerChanges" unless="noLexerChanges">
		<java classname="org.antlr.Tool" classpathref="antlr.class.path" fork="true" failonerror="true" dir="${grammar.dir}">
			<arg value="-verbose" />
			<arg value="PreprocessorLexer.g" />
		</java>
		<move file="${grammar.dir}/PreprocessorLexer.java" todir="${real.src.dir}/preproc/common" />
	</target>


	<!-- Source compilation and JAR construction -->

	<path id="src.compile.classpath">
		<pathelement location="${src.dir}" />
		<pathelement location="${antlr.jar}" />
	</path>

	<target name="compile" description="Compile all java source files." depends="parsers">
		<mkdir dir="${bin.dir}" />
		<javac debug="true" srcdir="${src.dir}" destdir="${bin.dir}" includes="edu/udel/cis/vsl/civl/**" classpathref="src.compile.classpath" includeantruntime="false">
		</javac>
	</target>

	<target name="jar" depends="compile" description="Jar up all class files.">
		<jar destfile="${jar-path}">
			<fileset dir="${bin.dir}" />
			<fileset dir="${antlr.runtime.bin}" />
			<fileset dir="${basedir}/lib" />
			<manifest>
				<attribute name="Built-By" value="${user.name}" />
				<attribute name="Main-Class" value="${main-class}" />
			</manifest>
		</jar>
	</target>

	<!-- Plain JUnit tests -->

	<path id="test.compile.classpath">
		<pathelement location="${test.src.dir}" />
		<pathelement location="${bin.dir}" />
		<pathelement location="${antlr.jar}" />
		<pathelement location="${junit.jar}" />
	</path>

	<path id="test.execute.classpath">
		<pathelement location="${test.bin.dir}" />
		<pathelement location="${bin.dir}" />
		<pathelement location="${antlr.jar}" />
		<pathelement location="${junit.jar}" />
	</path>

	<target name="test-init">
		<delete dir="${junit.dir}" quiet="true" />
		<delete dir="${test.bin.dir}" quiet="true" />
		<mkdir dir="${junit.dir}" />
		<mkdir dir="${junit.data.dir}" />
		<mkdir dir="${junit.reports.dir}" />
		<mkdir dir="${test.bin.dir}" />
	</target>

	<target name="test-compile" depends="compile,test-init">
		<javac destdir="${test.bin.dir}" debug="true" failonerror="false" classpathref="test.compile.classpath" includeantruntime="true">
			<src path="${test.src.dir}" />
		</javac>
	</target>

	<target name="test" depends="test-compile">
		<junit printsummary="false" errorProperty="test.failed" failureProperty="test.failed" fork="true" timeout="300000">
			<jvmarg value="-ea" />
			<classpath refid="test.execute.classpath" />
			<formatter type="brief" usefile="false" />
			<formatter type="xml" />
			<batchtest todir="${junit.data.dir}">
				<fileset dir="${test.bin.dir}" includes="**/*Test.class" />
			</batchtest>
		</junit>
		<junitreport todir="${junit.data.dir}">
			<fileset dir="${junit.data.dir}">
				<include name="TEST-*.xml" />
			</fileset>
			<report format="frames" todir="${junit.reports.dir}">
				<param name="TITLE" expression="JUnit Report for CIVL Project, Revision ${revision}" />
			</report>
		</junitreport>
		<fail message="Tests failed. Check log and/or reports." if="test.failed" />
	</target>

	<!-- Cobertura Tasks -->

	<target name="cobertura-init" depends="test-compile">
		<delete dir="${cobertura.dir}" quiet="true" />
		<delete file="${cob.ser.file}" quiet="true" />
		<delete file="${cob.log.file}" quiet="true" />
		<mkdir dir="${cobertura.dir}" />
		<mkdir dir="${cob.instrumented.dir}" />
		<mkdir dir="${cob.reports.xml.dir}" />
		<mkdir dir="${cob.reports.html.dir}" />
		<mkdir dir="${cob.coverage.xml.dir}" />
		<mkdir dir="${cob.coverage.html.dir}" />
	</target>

	<target name="cobertura-instrument" depends="cobertura-init">
		<cobertura-instrument todir="${cob.instrumented.dir}">
			<ignore regex="org.apache.log4j.*" />
			<fileset dir="${bin.dir}">
				<include name="**/*.class" />
			</fileset>
		</cobertura-instrument>
	</target>

	<path id="instrumented.classpath">
		<pathelement location="${cob.instrumented.dir}" />
		<pathelement location="${test.bin.dir}" />
		<pathelement location="${antlr.jar}" />
		<pathelement location="${junit.jar}" />
		<pathelement location="${bin.dir}" />
	</path>

	<target name="cobertura-test" depends="cobertura-instrument">
		<junit fork="yes" dir="${basedir}" failureProperty="test.failed">
			<jvmarg value="-ea" />
			<classpath refid="instrumented.classpath" />
			<classpath refid="cobertura.classpath" />
			<formatter type="xml" />
			<batchtest todir="${cob.reports.xml.dir}">
				<fileset dir="${test.bin.dir}" includes="**/*Test.class" />
			</batchtest>
		</junit>
		<junitreport todir="${cob.reports.xml.dir}">
			<fileset dir="${cob.reports.xml.dir}">
				<include name="TEST-*.xml" />
			</fileset>
			<report format="frames" todir="${cob.reports.html.dir}">
				<param name="TITLE" expression="JUnit Report for CIVL Project, Revision ${revision}" />
			</report>
		</junitreport>
	</target>

	<target name="cobertura-html-coverage-report" depends="cobertura-test">
		<cobertura-report destdir="${cob.coverage.html.dir}">
			<fileset dir="${src.dir}">
				<include name="**/*.java" />
			</fileset>
		</cobertura-report>
	</target>

	<target name="cobertura" depends="cobertura-html-coverage-report" />

	<!-- Javadoc Tasks -->

	<path id="javadoc.classpath">
		<pathelement location="${src.dir}" />
		<pathelement location="${junit.jar}" />
		<pathelement location="${antlr.jar}" />
	</path>

	<target name="javadoc">
		<delete dir="${javadoc.dir}" quiet="true" />
		<mkdir dir="${javadoc.dir}" />
		<javadoc destdir="${javadoc.dir}" author="true" version="true" use="true" windowtitle="CIVL Project API, Revision ${revision}" access="public" classpathref="javadoc.classpath" failonerror="false">
			<fileset dir="${src.dir}" defaultexcludes="yes">
				<include name="**/*.java" />
			</fileset>
		</javadoc>
	</target>

	<!-- Clean -->

	<target name="clean" description="Delete all generated files.">
		<delete dir="${bin.dir}" />
		<delete dir="${test.bin.dir}" />
		<delete dir="${junit.dir}" />
		<delete dir="${javadoc.dir}" />
		<delete file="${jar-path}" />
		<delete dir="${cobertura.dir}" />
		<delete file="${cob.ser.file}" />
		<delete file="${cob.log.file}" />
		<delete file="${manifest-file}" />
		<delete file="${grammar.dir}/CivlCParser.tokens" />
		<delete file="${real.src.dir}/CivlCParser.java" />
		<delete file="${grammar.dir}/PreprocessorLexer.tokens" />
		<delete file="${real.src.dir}/preproc/PreprocessorLexer.java" />
		<delete file="${grammar.dir}/PreprocessorParser.tokens" />
		<delete file="${real.src.dir}/preproc/PreprocessorParser.java" />
		<delete file="${grammar.dir}/PreprocessorExpressionParser.tokens" />
		<delete file="${real.src.dir}/preproc/expr/PreprocessorExpressionParser.java" />
	</target>

	<!-- Do everything -->

	<target name="all" depends="jar,test,cobertura,javadoc" />

</project>
