#!/bin/sh
####################################################################
#
#   Copyright (C) 2006   Andrew Tomazos <andrew@tomazos.com>
#
#	This program is free software; you can redistribute it and/or
#	modify it under the terms of the GNU General Public License
#	as published by the Free Software Foundation; either version 2
#	of the License, or (at your option) any later version.
#
####################################################################
#
#	jjrun 1.0d1
#
#	- Build and execute a JavaCC .jj file in one command
#
#	- Requires javacc, java, make and sh
#
#	- TODO: If you use something other than SimpleCharStream you
#	  will need to modify the OBJECTS variable below
#
#	- TODO: Only tested on GNU/Linux
#
####################################################################

# $PROGFILE: This programs file path
PROGFILE=$0

# $VERSION: This programs version
VERSION=1.0d1

# $PROGNAME: This programs name
PROGNAME=`basename $0`

# If project not specified output usage and exit
if [ ! $1 ]
then
	echo "USAGE: $PROGNAME <jjfile>"
	exit 1
fi

# $PROJECT: The jj file to run
PROJECT=`basename $1 .jj`

# $MAKEFILE: An automatically generated makefile
MAKEFILE=$PROJECT.mk

# $FORCE: forces the regeneration of the makefile
FORCE=$2


# If the specified project does not exist than exit
if [ ! -f $PROJECT.jj ]
then
	echo ERROR: $PROGNAME: File not found $PROJECT.jj
	exit 1
fi

# If forcing makefile regeneration than delete the makefile
if [ $FORCE ]
then
	rm $MAKEFILE
fi

# If the makefile does not exist than generate it
if [ ! -f $MAKEFILE ]
then
	echo $PROGNAME: Generating $MAKEFILE...

#### START jjrun_makefile_header_here_doc
cat > $MAKEFILE <<jjrun_makefile_header_here_doc
# Automatically generated makefile for $PROJECT by $PROGNAME $VERSION

#   Copyright (C) 2006   Andrew Tomazos <andrew@tomazos.com>
#
#	This program is free software; you can redistribute it and/or
#	modify it under the terms of the GNU General Public License
#	as published by the Free Software Foundation; either version 2
#	of the License, or (at your option) any later version.

# ${PROJECT}: Name of the project
PROJECT=$PROJECT

# ${MAKEFILE}: Filename of this makefile
MAKEFILE=$MAKEFILE

# ${PROGFILE}: Filepath of $PROGNAME
PROGFILE=$PROGFILE

jjrun_makefile_header_here_doc
#### END jjrun_makefile_header_here_doc

#### START jjrun_makefile_main_here_doc
cat >> $MAKEFILE <<'jjrun_makefile_main_here_doc'

# ${JJ}: The original .jj file
JJ=${PROJECT}.jj

# ${AUTOGENS}: The automatically generated classed of javacc
AUTOGENS=					\
	${PROJECT}				\
	${PROJECT}Constants		\
	${PROJECT}TokenManager

# ${BOILERS}: The boilerplate classes generated by javacc
BOILERS=					\
	SimpleCharStream		\
	ParseException			\
	Token					\
	TokenMgrError

# ${OBJECTS}: The names of the classes output by javacc
OBJECTS=${AUTOGENS} ${BOILERS} 

# ${BOILERSOURCES}: The boilerplater sources files output by javacc
BOILERSOURCES=$(addsuffix .java, ${BOILERS})

# ${SOURCES}: The source files output by javacc
SOURCES=$(addsuffix .java, ${OBJECTS})

# ${CLASSES}: The class files compiled with javac from the output of javacc
CLASSES=$(addsuffix .class, ${OBJECTS})

# ${MANIFEST}: filename of the manifest for the final jar file
MANIFEST=${PROJECT}.mf

# ${JAR}: filename of the final jar file
JAR=${PROJECT}.jar

# make build rule to make JAR
build: ${JAR}

# make ${JAR}: build the jar file 
${JAR}: ${SOURCES} ${MANIFEST}
	@echo ${MAKEFILE}: Building ${JAR}...
	/usr/pkg/java/openjdk17/bin/javac ${SOURCES}
	/usr/pkg/java/openjdk17/bin/jar cvfm ${JAR} ${MANIFEST} ${CLASSES}
	rm ${CLASSES}

# make clean: remove all generated jar files
clean:
	@echo ${MAKEFILE}: Cleaning ${PROJECT}...
	@-rm ${JAR} ${SOURCES} ${MANIFEST}

# make ${SOURCES}: compile the jj file into java sources
${SOURCES}: ${JJ}
	@echo ${MAKEFILE}: Compiling ${JJ}...
	/usr/pkg/bin/javacc ${JJ}
	touch -c ${BOILERSOURCES}

# make ${MANIFEST}: rule to make
${MANIFEST}:
	@echo ${MAKEFILE}: Creating manifest...
	@echo Manifest-Version: 1.0 > ${MANIFEST}
	@echo Main-Class: ${PROJECT} >> ${MANIFEST}

${MAKEFILE}: ${PROGFILE}
	@echo ${MAKEFILE}: Regenerating ${MAKEFILE}
	@${PROGFILE} ${PROJECT} FORCE

jjrun_makefile_main_here_doc
# END jjrun_makefile_main_here_doc

fi

# If this was a forced regeneration than stop here
if [ $FORCE ]
then
	exit 0
fi

# Execute the makefile to rebuild the jar file if necessary
echo $PROGNAME: Executing $MAKEFILE...
make -f $MAKEFILE

# Execute the jar file
echo $PROGNAME: Executing $PROJECT.jar...
/usr/pkg/java/openjdk17/bin/java -jar $PROJECT.jar

