Improved build system
This fixes a lot of the problems with the build by using a normal Makefile as it is intended to be used. To do this, tamed was created. See the manual and commit messages for more information. bin/tame{,d} also have more information. More information will follow in the manual in the future. There is also more cleanup to follow; I just want to get this committed so that people can take advantage of it and stop some of the suffering.master v3.3.0
commit
01671f8345
|
@ -7,6 +7,7 @@
|
|||
*.info
|
||||
|
||||
# autotools- and configure-generated
|
||||
/bin/dslc
|
||||
/Makefile.in
|
||||
/Makefile
|
||||
/aclocal.m4
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
SUBDIRS = doc progtest
|
||||
SUBDIRS = src/current/src doc progtest
|
||||
|
||||
path_src = src
|
||||
path_test = test
|
||||
|
|
33
README.md
33
README.md
|
@ -14,12 +14,13 @@ designed to aid in the development, understanding, and maintenance of systems
|
|||
performing numerous calculations on a complex graph of dependencies,
|
||||
conditions, and a large number of inputs.
|
||||
|
||||
This system was developed at LoVullo Associates to handle the complexity of
|
||||
comparative insurance rating systems. It is a domain-specific language (DSL)
|
||||
that itself encourages, through the use of templates, the creation of sub-DSLs.
|
||||
TAME itself is at heart a calculator—processing only numerical input and
|
||||
output—driven by quantifiers as predicates. Calculations and quantifiers are
|
||||
written declaratively without concern for order of execution.
|
||||
This system was developed at R-T Specialty (formerly LoVullo Associates) to
|
||||
handle the complexity of comparative insurance rating systems. It is a
|
||||
domain-specific language (DSL) that itself encourages, through the use of
|
||||
templates, the creation of sub-DSLs. TAME itself is at heart a
|
||||
calculator—processing only numerical input and output—driven by quantifiers
|
||||
as predicates. Calculations and quantifiers are written declaratively
|
||||
without concern for order of execution.
|
||||
|
||||
The system has powerful dependency resolution and data flow capabilities.
|
||||
|
||||
|
@ -27,15 +28,10 @@ TAME consists of a macro processor (implementing a metalanguage), numerous
|
|||
compilers for various targets (JavaScript, HTML documentation and debugging
|
||||
environment, LaTeX, and others), linkers, and supporting tools. The input
|
||||
grammar is XML, and the majority of the project (including the macro processor,
|
||||
compilers, and linkers) are written in XSLT. There is a reason for that odd
|
||||
compilers, and linkers) is written in XSLT. There is a reason for that odd
|
||||
choice; until an explanation is provided, know that someone is perverted enough
|
||||
to implement a full compiler in XSLT.
|
||||
|
||||
More information will become available as various portions are liberated
|
||||
during refactoring. [tame-core](https://github.com/lovullo/tame-core) is
|
||||
TAME's core library, and [hoxsl](https://savannah.nongnu.org/projects/hoxsl)
|
||||
was developed as a supporting library.
|
||||
|
||||
|
||||
## "Current"
|
||||
The current state of the project as used in production is found in
|
||||
|
@ -54,6 +50,19 @@ instance. Available formats are:
|
|||
- [Info][doc-info]
|
||||
|
||||
|
||||
## Getting Started
|
||||
To get started, make sure Saxon version 9 or later is available and its path
|
||||
set as `SAXON_CP`; that the path to hoxsl is set via `HOXSL`; and then run
|
||||
the `bootstrap` script:
|
||||
|
||||
```bash
|
||||
$ export SAXON_CP=/path/to/saxon9he.jar
|
||||
$ export HOXSL=/path/to/hoxsl/root
|
||||
|
||||
$ ./boostrap
|
||||
```
|
||||
|
||||
|
||||
## Hacking
|
||||
Information for TAME developers can be found in the file `HACKING`.
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
# Listen for TAME commands (compilers, linker, etc)
|
||||
#
|
||||
# Copyright (C) 2018 R-T Specialty, LLC.
|
||||
#
|
||||
# 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# @AUTOGENERATED@
|
||||
##
|
||||
|
||||
declare -r mypath=$( dirname "$( readlink -f "$0" )" )
|
||||
declare -r dslc_jar="$mypath/../src/current/src/dslc.jar"
|
||||
|
||||
|
||||
CLASSPATH="$CLASSPATH:@DSLC_CLASSPATH@:$dslc_jar" \
|
||||
"@JAVA@" @JAVA_OPTS@ \
|
||||
com.lovullo.dslc.DslCompiler
|
|
@ -0,0 +1,240 @@
|
|||
#!/bin/bash
|
||||
# Client for TAME daemon (tamed)
|
||||
#
|
||||
# Copyright (C) 2018 R-T Specialty, LLC.
|
||||
#
|
||||
# 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
declare -r mypath=$( dirname "$( readlink -f "$0" )" )
|
||||
|
||||
declare -ri EX_NOTAMED=1 # tried to start tamed but failed
|
||||
declare -ri EX_USAGE=64 # incorrect usage; sysexits.h
|
||||
|
||||
|
||||
# Send a single command to a runner and observe the result
|
||||
#
|
||||
# stdin will be directed to the runner. stdout of the runner will be
|
||||
# echoed until a line beginning with "DONE" is found, after which this
|
||||
# procedure will return with the exit code indicated by the runner.
|
||||
command-runner()
|
||||
{
|
||||
local -ri id="${1?Missing id}"
|
||||
local -r root="${2?Missing root run path}"
|
||||
shift 2
|
||||
|
||||
local -r base="$root/$id"
|
||||
local -ri pid=$( cat "$base/pid" )
|
||||
|
||||
# TODO flock
|
||||
|
||||
verify-runner "$base" "$pid"
|
||||
|
||||
# forward signals to runner so that build is actually halted
|
||||
# (rather than continuing in background after we die)
|
||||
trap 'kill -TERM $pid &>/dev/null' INT TERM
|
||||
|
||||
# all remaining arguments are passed to the runner
|
||||
echo "$@" > "$base/0"
|
||||
|
||||
# output lines from runner until we reach a line stating "DONE"
|
||||
while read line; do
|
||||
# don't parse words in the initial read because we may be
|
||||
# dealing with a lot of lines
|
||||
if [ "${line:0:5}" == "DONE " ]; then
|
||||
read _ code _ <<< "$line"
|
||||
return "$code"
|
||||
fi
|
||||
|
||||
echo "$line"
|
||||
done < "$base/1"
|
||||
}
|
||||
|
||||
|
||||
# Verify that a runner is available
|
||||
#
|
||||
# If the runner is offline or not owned by $UID, then exit with
|
||||
# a non-zero status.
|
||||
verify-runner()
|
||||
{
|
||||
local -r base="${1?Missing base}"
|
||||
local -ri pid="${2?Missing pid}"
|
||||
|
||||
ps "$pid" &>/dev/null || {
|
||||
echo "error: runner $id ($pid) is offline!" >&2
|
||||
exit "$EX_NOTAMED"
|
||||
}
|
||||
|
||||
test -O "$base/0" || {
|
||||
echo "error: runner $id ($pid) is not owned by $USER!" >&2
|
||||
exit "$EX_NOTAMED"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Wait somewhat impatiently for tamed
|
||||
#
|
||||
# Assumes that tamed's runner 0 is running once the pidfile becomes
|
||||
# available. Polls for a maximum of six seconds before giving up
|
||||
# and exiting with a non-zero status.
|
||||
wait-for-tamed()
|
||||
{
|
||||
local -r base="${1?Missing base}"
|
||||
|
||||
# we could use inotify, but that is not installed by default
|
||||
# on Debian systems, so let's just poll rather than introduce
|
||||
# another dependency (give up after 6 seconds)
|
||||
local -i i=12
|
||||
while test $((i--)); do
|
||||
test ! -f "$base/0/pid" || return 0
|
||||
sleep 0.5
|
||||
done
|
||||
|
||||
# still not available
|
||||
echo 'error: tamed still unavailable; giving up' >&2
|
||||
exit "$EX_NOTAMED"
|
||||
}
|
||||
|
||||
|
||||
# Start tamed if it is not already running
|
||||
#
|
||||
# If tamed is already running, nothing will happen; otherwise, start
|
||||
# tamed and wait impatiently for the runner to become available.
|
||||
#
|
||||
# Even if tamed is started, wait for runner 0 to become available;
|
||||
# this ensures that tamed is initialized even if this script is run
|
||||
# after tamed is started but before it has fully come online (e.g
|
||||
# parallel make).
|
||||
start-tamed()
|
||||
{
|
||||
local -r root="${1?Missing root}"
|
||||
|
||||
local -ri pid=$( cat "$root/pid" 2>/dev/null )
|
||||
|
||||
ps "$pid" &>/dev/null || {
|
||||
echo "starting tamed at $root..."
|
||||
|
||||
# tell tamed to clean up so that we eliminate race conditions
|
||||
# with wait-for-tamed (this will also kill any stray processes
|
||||
# that a previous tamed may have spawned but didn't get the
|
||||
# chance to clean up)
|
||||
kill-tamed "$root" || true
|
||||
|
||||
# start tamed and allow it to persist for future commands
|
||||
"$mypath/tamed" "$root" & disown
|
||||
}
|
||||
|
||||
# wait for tamed even if it was already started (just in
|
||||
# case this script was executed right after tamed started
|
||||
# but before it is done initializing)
|
||||
wait-for-tamed "$root"
|
||||
}
|
||||
|
||||
|
||||
# Kill tamed
|
||||
#
|
||||
# Ask tamed to kill itself.
|
||||
kill-tamed()
|
||||
{
|
||||
local -r root="${1?Missing root}"
|
||||
|
||||
"$mypath/tamed" --kill "$root"
|
||||
}
|
||||
|
||||
|
||||
# Filter dslc output to essential information
|
||||
#
|
||||
# The original output of dslc is quite noisy; this filters it down
|
||||
# to only errors and warnings.
|
||||
#
|
||||
# Eventually, dslc out to be modified to handle filtering its own
|
||||
# output rather than wasting cycles doing this filtering.
|
||||
saneout()
|
||||
{
|
||||
awk ' \
|
||||
/^~~~~\[begin /,/^~~~~\[end / { next } \
|
||||
/^rm / { next } \
|
||||
/^COMMAND / { next } \
|
||||
/^Exception|^\t+at / { \
|
||||
if ( /^E/ ) { \
|
||||
print; \
|
||||
print "Stack trace written to run-*.log"; \
|
||||
} \
|
||||
next; \
|
||||
} \
|
||||
/([Ww]arning|[Nn]otice)[: ]/ { printf "\033[0;33m"; w++; out=1; } \
|
||||
/[Ff]atal:/ { printf "\033[0;31m"; out=1; } \
|
||||
/!|[Ee]rror:/ { printf "\033[0;31m"; e++; out=1; } \
|
||||
/internal:/ { printf "\033[0;35m"; out=1; } \
|
||||
/internal error:/ { printf "\033[1m"; out=1; } \
|
||||
/^[^[]/ || out { print; printf "\033[0;0m"; out=0; } \
|
||||
'
|
||||
}
|
||||
|
||||
|
||||
# Output usage information and exit
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Usage: $0 [-v|--verbose] cmdline
|
||||
Or: $0 --kill
|
||||
Send command line CMDLINE to a tamed runner. Start tamed if
|
||||
not already running.
|
||||
|
||||
Options:
|
||||
--help show this message
|
||||
--kill kill tamed
|
||||
-v, --verbose show runner logs
|
||||
|
||||
Environment Variables:
|
||||
TAME_VERBOSE when greater than zero, show runner logs
|
||||
(see also --verbose)
|
||||
EOF
|
||||
|
||||
exit $EX_USAGE
|
||||
}
|
||||
|
||||
|
||||
# Run tame
|
||||
main()
|
||||
{
|
||||
local -r root=/run/user/$UID/tamed
|
||||
|
||||
local outcmd=saneout
|
||||
|
||||
test $# -gt 0 || usage
|
||||
|
||||
case "${1:-}" in
|
||||
--kill) kill-tamed "$root"; exit;;
|
||||
-v|--verbose) outcmd=cat;;
|
||||
--help) usage;;
|
||||
esac
|
||||
|
||||
# alternative to --verbose
|
||||
if [ "${TAME_VERBOSE:-0}" -ge 1 ]; then
|
||||
outcmd=cat
|
||||
fi
|
||||
|
||||
start-tamed "$root"
|
||||
|
||||
# for now we only support a single runner
|
||||
command-runner 0 "$root" "$@" \
|
||||
| tee -a "run-0.log" \
|
||||
| "$outcmd"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
#!/bin/bash
|
||||
# Daemon for accepting TAME commands (compilers, linker, etc)
|
||||
#
|
||||
# Copyright (C) 2018 R-T Specialty, LLC.
|
||||
#
|
||||
# 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
declare -r mypath=$( dirname "$( readlink -f "$0" )" )
|
||||
|
||||
declare -ri EX_RUNNING=1
|
||||
declare -ri EX_USAGE=64 # incorrect usage; sysexits.h
|
||||
declare -ri EX_CANTCREAT=73 # cannot create file; sysexits.h
|
||||
|
||||
# number of seconds before runners are considered unused and terminate
|
||||
declare -ri TAMED_STALL_SECONDS="${TAMED_STALL_SECONDS:-30}"
|
||||
|
||||
# set by `main', global for `cleanup'
|
||||
declare root=
|
||||
|
||||
|
||||
# Create FIFOs for runner
|
||||
#
|
||||
# The FIFOs are intended to be attached to stderr and stdout
|
||||
# of the runner and will be created relative to the given
|
||||
# root path ROOT.
|
||||
#
|
||||
# If a FIFO cannot be created, exit with EX_CANTCREAT.
|
||||
mkfifos()
|
||||
{
|
||||
local -r root="${1?Missing root path}"
|
||||
|
||||
mkdir -p "$root"
|
||||
|
||||
# note that there's no stderr; see `add-runner'
|
||||
for n in 0 1; do
|
||||
rm -f "$root-$n"
|
||||
|
||||
mkfifo -m 0600 "$root/$n" || {
|
||||
echo "fatal: failed to create FIFO at $in"
|
||||
exit $EX_CANTCREAT
|
||||
}
|
||||
|
||||
# keep FIFOs open so we don't get EOF from writers
|
||||
tail -f >"$root/$n" &
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# Spawn a runner
|
||||
#
|
||||
# A new runner is created by spawning dslc and attaching
|
||||
# new FIFOs under the given id ID relative to the given
|
||||
# run path ROOT. The PID of the runner will be stored
|
||||
# alongside the FIFOs in a pidfile `pid'.
|
||||
spawn-runner()
|
||||
{
|
||||
local -ri id="${1?Missing id}"
|
||||
local -r root="${2?Missing root run path}"
|
||||
|
||||
local -r base="$root/$id"
|
||||
|
||||
mkfifos "$base"
|
||||
|
||||
# monitor runner usage and kill when inactive
|
||||
stall-monitor "$base" &
|
||||
|
||||
# loop to restart runner in case of crash
|
||||
while true; do
|
||||
"$mypath/dslc" < "$base/0" &> "$base/1"
|
||||
echo "warning: runner $id exited with code ${PIPESTATUS[0]}; restarting" >&2
|
||||
done &
|
||||
|
||||
echo "$!" > "$base/pid"
|
||||
|
||||
echo "runner $id ($!): $base"
|
||||
}
|
||||
|
||||
|
||||
# Kill runner at BASE when it becomes inactive for TAMED_STALL_SECONDS
|
||||
# seconds
|
||||
#
|
||||
# This monitors the modification time on the stdout FIFO. stdin does not
|
||||
# need to be monitored since dslc immediately echoes back commands it
|
||||
# receives.
|
||||
#
|
||||
# dslc is pretty chatty at the time of writing this, so TAMED_STALL_SECONDS
|
||||
# can easily be <=30s even for large packages. This may need to change in
|
||||
# the future if it becomes too much less chatty. Increase that environment
|
||||
# variable if runners stall unexpectedly in the middle of builds.
|
||||
stall-monitor()
|
||||
{
|
||||
local -r base="${1?Missing base}"
|
||||
|
||||
# monitor output FIFO modification time
|
||||
while true; do
|
||||
local -i since=$( date +%s )
|
||||
sleep "$TAMED_STALL_SECONDS"
|
||||
local -i last=$( stat -c%Y "$base/1" )
|
||||
|
||||
# keep waiting if there has been activity since $since
|
||||
test "$last" -le "$since" || continue
|
||||
|
||||
# no activity; kill
|
||||
local -r pid=$( cat "$base/pid" )
|
||||
kill "$pid"
|
||||
wait "$pid" 2>/dev/null
|
||||
|
||||
# this stall subprocess is no longer needed
|
||||
break
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# Exit if tamed is already running at path ROOT
|
||||
#
|
||||
# If tamed is already running at ROOT, exit with status
|
||||
# EX_RUNNING; otherwise, do nothing except output a warning
|
||||
# if a stale pid file exists.
|
||||
abort-if-running()
|
||||
{
|
||||
local -r root="${1?Missing root rundir}"
|
||||
|
||||
local -ri pid=$( cat "$root/pid" 2>/dev/null )
|
||||
|
||||
test "$pid" -gt 0 || return 0
|
||||
|
||||
! ps "$pid" &>/dev/null || {
|
||||
echo "fatal: tamed is already running at $root (pid $pid)!"
|
||||
exit $EX_RUNNING
|
||||
}
|
||||
|
||||
test -z "$pid" || {
|
||||
echo "warning: clearing stale tamed (pid $pid)"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Kill running tamed at path ROOT
|
||||
#
|
||||
# If no pidfile is found at ROOT, do nothing. This sends a
|
||||
# signal only to the parent tamed process, _not_ individual
|
||||
# runners; the target tamed is expected to clean up itself.
|
||||
# Consequently, if a tamed terminated abnormally without
|
||||
# cleaning up, this will not solve that problem.
|
||||
kill-running()
|
||||
{
|
||||
local -r root="${1?Missing root}"
|
||||
|
||||
local -r pid=$( cat "$root"/pid 2>/dev/null )
|
||||
|
||||
test -n "$pid" || return 0
|
||||
|
||||
echo "killing tamed at $root ($pid)..."
|
||||
kill "$pid"
|
||||
}
|
||||
|
||||
|
||||
# Clean up child processes before exit
|
||||
#
|
||||
# This should be called before exit (perhaps by a trap). Kills
|
||||
# the entire process group.
|
||||
#
|
||||
# Do not attach this to a SIGTERM trap or it will infinitely
|
||||
# recurse.
|
||||
cleanup()
|
||||
{
|
||||
rm -rf "$root"
|
||||
kill 0
|
||||
}
|
||||
|
||||
|
||||
# Output usage information and exit
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Usage: $0 [--kill] [runpath]
|
||||
Start tamed and runners. Do not fork into background process.
|
||||
|
||||
The default value of RUNPATH is \`/run/user/$UID/tamed'.
|
||||
|
||||
Only one runner is currently supported. tamed exits once all
|
||||
runners have terminated. Runners will be killed once they are
|
||||
inactive for at least TAMED_STALL_SECONDS (default 30).
|
||||
|
||||
Options:
|
||||
--help show this message
|
||||
--kill kill a runing tamed at path RUNPATH
|
||||
|
||||
Environment Variables:
|
||||
TAMED_STALL_SECONDS number of seconds of runner inactivity before
|
||||
runner is automatically killed (default 30)
|
||||
EOF
|
||||
|
||||
exit $EX_USAGE
|
||||
}
|
||||
|
||||
|
||||
# Run tamed
|
||||
main()
|
||||
{
|
||||
local kill=
|
||||
case "${1:-}" in
|
||||
--kill) kill=1; shift;;
|
||||
--help) usage;;
|
||||
esac
|
||||
|
||||
root="${1:-/run/user/$UID/tamed}"
|
||||
|
||||
# kill if requested
|
||||
test -z "$kill" || {
|
||||
kill-running "$root"
|
||||
exit
|
||||
}
|
||||
|
||||
abort-if-running "$root"
|
||||
|
||||
# clean up background processes before we exit
|
||||
trap exit TERM
|
||||
trap cleanup EXIT
|
||||
|
||||
# start fresh
|
||||
rm -rf "$root"; mkdir -p "$root"
|
||||
echo $$ > "$root/pid"
|
||||
|
||||
# only a single runner for now
|
||||
spawn-runner 0 "$root"
|
||||
|
||||
wait -n
|
||||
}
|
||||
|
||||
main "$@"
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/bash
|
||||
# Bootstrap from source repository
|
||||
#
|
||||
# Copyright (C) 2018 R-T Specialty, LLC.
|
||||
#
|
||||
# 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
export SAXON_CP="${SAXON_CP?Missing path to saxon9he.jar}"
|
||||
export RATER_CLASSPATH="${RATER_CLASSPATH:-$SAXON_CP}"
|
||||
export HOXSL="${HOXSL?Missing path to hoxsl}"
|
||||
|
||||
test "${1:-}" = -n || git submodule update --init --recursive
|
||||
|
||||
cd progtest \
|
||||
&& { which npm && npm install || true; } \
|
||||
&& ./autogen.sh && ./configure \
|
||||
&& cd - \
|
||||
&& { test -e hoxsl || ln -s ../hoxsl; } \
|
||||
&& autoreconf -fvi \
|
||||
&& ./configure \
|
||||
&& make all
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
# @configure_input@
|
||||
#
|
||||
# Compiles packages written in the Calc DSL.
|
||||
#
|
||||
# Copyright (C) 2018 R-T Specialty, LLC.
|
||||
#
|
||||
# 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Note that this build process is unconventional in order to avoid the startup
|
||||
# costs that would be associated with executing dslc with each and every package
|
||||
# (see the other Makefile for more information). Therefore, everything is
|
||||
# written to .cqueue for later processing by dslc.
|
||||
#
|
||||
# The issue of re-building based on timestamps---which Make would normally take
|
||||
# care of exclusively---must also be given special care now that we are handling
|
||||
# the building separately from Make. Each enqueued request also touches the
|
||||
# destination file to update its timestamp, ensuring that it is seen by Make as
|
||||
# modified (as if it were compiled) and therefore will trigger the building of
|
||||
# the targets that depend upon it. In the case of the object files (xmlo), a
|
||||
# temporary file is created when it is enqueued. As part of the queued request
|
||||
# for compilation is a request to delete this temporary file. In the event that
|
||||
# the build fails, this temporary file will be seen and will force a rebuild of
|
||||
# the file, despite its timestamp.
|
||||
#
|
||||
# The same issue does not exist for xmle, js, and html files, since they have
|
||||
# linear dependency trees and dslc will rm the file on failure, which
|
||||
# obliterates the timestamp.
|
||||
# #
|
||||
|
||||
path_rates := $(path_suppliers)/rates
|
||||
path_map := map
|
||||
path_c1map := $(path_map)/c1
|
||||
path_dsl := rater
|
||||
path_ui := ui
|
||||
path_suppliers := suppliers
|
||||
path_lv := lovullo
|
||||
path_srv := srv
|
||||
|
||||
src_suppliers := $(wildcard $(path_suppliers)/*.xml)
|
||||
src_map := $(wildcard $(path_map)/*.xml)
|
||||
src_c1map := $(wildcard $(path_c1map)/*.xml)
|
||||
|
||||
dest_summary_html := $(patsubst \
|
||||
$(path_suppliers)/%.xml, \
|
||||
$(path_suppliers)/%.html, \
|
||||
$(src_suppliers))
|
||||
dest_standalone := $(patsubst \
|
||||
$(path_suppliers)/%.xml, \
|
||||
$(path_suppliers)/%.js, \
|
||||
$(src_suppliers))
|
||||
dest_map := $(patsubst \
|
||||
$(path_map)/%.xml, \
|
||||
$(path_map)/%.xmle, \
|
||||
$(src_map))
|
||||
dest_c1map := $(patsubst \
|
||||
$(path_c1map)/%.xml, \
|
||||
$(path_c1map)/%.php, \
|
||||
$(src_c1map))
|
||||
|
||||
compiled_suppliers := $(src_suppliers:.xml=.xmlo)
|
||||
linked_suppliers := $(src_suppliers:.xml=.xmle)
|
||||
|
||||
comma := ,
|
||||
extless_supp_delim := $(subst .xml,,$(subst .xml ,$(comma),$(src_suppliers)))
|
||||
|
||||
cqueue=.cqueue
|
||||
|
||||
ant = @ANT@ -e
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
.PHONY: default clean \
|
||||
interp-rate-tables summary-html c1map \
|
||||
standalones program-ui program-ui-immediate program-data-copy \
|
||||
do-build version FORCE
|
||||
|
||||
# these files will never be deleted when Make considers them to be intermediate
|
||||
# (e.g. when building summary pages), since they are still needed or take a
|
||||
# while to build
|
||||
.PRECIOUS: %.js %.xml %.xmle %.xmlo
|
||||
|
||||
SHELL = /bin/bash -O extglob
|
||||
|
||||
default: program-ui c1map FORCE
|
||||
|
||||
program-ui: standalones ui/package.js ui/Program.js program-ui-immediate
|
||||
program-ui-immediate: ui/html/index.phtml
|
||||
|
||||
include suppliers.mk
|
||||
|
||||
# starts with a fresh cqueue
|
||||
prexmlo:
|
||||
@>$(cqueue)
|
||||
|
||||
summary-html: $(dest_summary_html) ;
|
||||
|
||||
%.html: %.js
|
||||
@echo "summary $*.xmle $@" >>.cqueue
|
||||
@touch $@
|
||||
|
||||
standalones: $(dest_standalone)
|
||||
%.xmle: %.xmlo
|
||||
@echo "link $< $@" >>.cqueue
|
||||
@touch $@
|
||||
%.js: %.xmle
|
||||
@echo "standalone $< $@" >>.cqueue
|
||||
@touch $@
|
||||
|
||||
# C1 XML (specific recipes are in suppliers.mk)
|
||||
c1map: $(dest_c1map)
|
||||
|
||||
%.dot: %.xmlo
|
||||
@echo "dot $< $@" >> .cqueue
|
||||
%.dote: %.xmle
|
||||
@echo "dot $< $@" >> .cqueue
|
||||
|
||||
%.svg: %.dote
|
||||
dot -Tsvg "$<" > "$@"
|
||||
%.svg: %.dot
|
||||
dot -Tsvg "$<" > "$@"
|
||||
|
||||
%.xml: %.dat
|
||||
rater/tools/tdat2xml $< > $@
|
||||
|
||||
%.xml: %.typelist
|
||||
rater/tame/build-aux/list2typedef $(*F) < $< > $@
|
||||
|
||||
%.csvo: %.csvm
|
||||
rater/tools/csvm2csv $< > $@
|
||||
%.csvo: %.csvi
|
||||
rater/tools/csvi $< > $@
|
||||
%.csvo: %.csv
|
||||
cp $< $@
|
||||
|
||||
%.xml: %.csvo
|
||||
rater/tools/csv2xml $< > $@
|
||||
|
||||
version: .version.xml
|
||||
.version.xml: FORCE
|
||||
git log HEAD^.. -1 --pretty=format:'<version>%h</version>' > .version.xml
|
||||
|
||||
ui/program.expanded.xml: ui/program.xml | .version.xml
|
||||
@echo "progui-expand $< $@" >> .cqueue
|
||||
ui/Program.js: ui/program.expanded.xml ui/package.js
|
||||
@echo "progui-class $< $@ include-path=../../../ui/" >> .cqueue
|
||||
ui/html/index.phtml: ui/program.expanded.xml
|
||||
@echo "progui-html $< $@ out-path=./" >> .cqueue
|
||||
ui/package-dfns.xmlo: ui/package-dfns.xml
|
||||
ui/package-dfns.xml: ui/program.expanded.xml
|
||||
@echo "progui-pkg $< $@" >> .cqueue
|
||||
ui/package-map.xmlo: ui/package-map.xml
|
||||
ui/package-map.xml: ui/program.expanded.xml ui/package-dfns.xml
|
||||
@echo "progui-pkg-map $< $@" >> .cqueue
|
||||
|
||||
# for the time being, this does not depend on clean-rate-tables because $(ant) will
|
||||
specs:
|
||||
$(MAKE) -C doc/specs
|
||||
#
|
||||
# this will eventually go away once we don't have X-repo klugery
|
||||
|
||||
# for the time being, this does not depend on clean-rate-tables because ant will
|
||||
# run it
|
||||
clean:
|
||||
find $(path_suppliers) $(path_map) $(path_c1map) common/ rater/core rater/lv \( \
|
||||
-name '*.xmlo' \
|
||||
-o -name '*.xmle' \
|
||||
-o -name '*.js' \
|
||||
-o -name '*.html' \
|
||||
-o -name '*.dep' \
|
||||
-o -name '*.tmp' \
|
||||
\) -exec rm -v {} \;
|
||||
rm -rf $(path_ui)/package-dfns.* \
|
||||
$(path_ui)/package-map.* \
|
||||
$(path_ui)/program.expanded.xml \
|
||||
$(path_ui)/include.js \
|
||||
$(path_ui)/Program.js \
|
||||
$(path_ui)/html
|
||||
find . -path '*/tables/*.csvm' -o -path '*/territories/*.dat' \
|
||||
| sed 's/\.csvm$$/\.xml/; s/\.dat$$/\.xml/' \
|
||||
| xargs rm -fv
|
||||
|
||||
# generates a Makefile that will properly build all package dependencies; note
|
||||
# that territory and rate packages also have includes; see top of this file for
|
||||
# an explanation
|
||||
suppliers.mk:
|
||||
$(ant) pkg-dep \
|
||||
&& mv $(path_ui)/program.dep $(path_ui)/package-dfns.dep
|
||||
xmlo_cmd='@echo "validate $$(patsubst %.tmp,%.xml,$$<) $$@" >> .cqueue \
|
||||
&& echo "compile $$(patsubst %.tmp,%.xml,$$<) $$@" >> .cqueue \
|
||||
&& echo "rm $$(patsubst %.xmlo,%.tmp,$$@)" >> .cqueue \
|
||||
&& touch $$@ \
|
||||
&& touch -d +1sec $$(patsubst %.xmlo,%.tmp,$$@) >> .cqueue' \
|
||||
./rater/tame/build-aux/gen-make common/ $(path_suppliers)/ $(path_dsl)/ $(path_map)/ $(path_ui)/ >$@ \
|
||||
&& ./rater/tame/build-aux/gen-c1make $(path_c1map)/*.xml >>$@
|
||||
|
||||
me-a-sandwich:
|
||||
@test $$EUID -eq 0 \
|
||||
&& echo 'You actually ran me as root? Are you insane!?' \
|
||||
|| echo 'Make it yourself.'
|
||||
|
||||
# simply forces a job to run, thereby forcing the invocation of the secondary
|
||||
# Makefile (this is not explicitly required, because of prepare, but signifies
|
||||
# intent and is self-documenting)
|
||||
FORCE: ;
|
|
@ -16,15 +16,7 @@
|
|||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# This fragment exists as a kluge to provide support for running a command
|
||||
# after all targets have been run (in this case, dslc).
|
||||
#
|
||||
# A list of everything to be compiled is output into .cqueue, which is then
|
||||
# picked up by dslc; this avoids the overhead of starting the JVM,
|
||||
# recompiling XSL stylesheets, etc, which is quite substantial.
|
||||
#
|
||||
# !!! Unfortunately, this does not yet support parallel job execution.
|
||||
##
|
||||
|
||||
path_rates := $(path_suppliers)/rates
|
||||
path_map := map
|
||||
|
@ -38,63 +30,153 @@ path_srv := srv
|
|||
path_lvroot := lvroot
|
||||
path_intralov_root := "intralov-root/@program@"
|
||||
|
||||
.PHONY: FORCE prepare program-data-copy lvroot program-ui-immediate test
|
||||
src_suppliers := $(wildcard $(path_suppliers)/*.xml)
|
||||
src_map := $(wildcard $(path_map)/*.xml)
|
||||
src_c1map := $(wildcard $(path_c1map)/*.xml)
|
||||
|
||||
JAVA_HEAP_SIZE ?= 5120M
|
||||
JAVA_STACK_SIZE ?= 5M
|
||||
dest_summary_html := $(patsubst \
|
||||
$(path_suppliers)/%.xml, \
|
||||
$(path_suppliers)/%.html, \
|
||||
$(src_suppliers))
|
||||
dest_standalone := $(patsubst \
|
||||
$(path_suppliers)/%.xml, \
|
||||
$(path_suppliers)/%.js, \
|
||||
$(src_suppliers))
|
||||
dest_map := $(patsubst \
|
||||
$(path_map)/%.xml, \
|
||||
$(path_map)/%.xmle, \
|
||||
$(src_map))
|
||||
dest_c1map := $(patsubst \
|
||||
$(path_c1map)/%.xml, \
|
||||
$(path_c1map)/%.php, \
|
||||
$(src_c1map))
|
||||
|
||||
compiled_suppliers := $(src_suppliers:.xml=.xmlo)
|
||||
linked_suppliers := $(src_suppliers:.xml=.xmle)
|
||||
|
||||
comma := ,
|
||||
extless_supp_delim := $(subst .xml,,$(subst .xml ,$(comma),$(src_suppliers)))
|
||||
|
||||
ant = @ANT@ -e
|
||||
|
||||
.PHONY: FORCE default program-data-copy lvroot program-ui-immediate test \
|
||||
default clean interp-rate-tables summary-html c1map standalones \
|
||||
program-ui version FORCE
|
||||
|
||||
default: program-ui c1map FORCE
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
# less verbose output; all to runlog
|
||||
define saneout
|
||||
time -f 'total time: %E' awk ' \
|
||||
BEGIN { e=0; w=0; } \
|
||||
{ printf "[%d] ", systime() >> ".runlog"; print >> ".runlog"; } \
|
||||
/^~~~~\[begin /,/^~~~~\[end / { next } \
|
||||
/^rm / { next } \
|
||||
/^Exception|^\t+at / { \
|
||||
if ( /^E/ ) { \
|
||||
print; \
|
||||
print "Stack trace written to .runlog"; \
|
||||
} \
|
||||
next; \
|
||||
} \
|
||||
/[Ww]arning:|[Nn]otice:/ { printf "\033[0;33m"; w++; out=1; } \
|
||||
/[Ff]atal:/ { printf "\033[0;31m"; out=1; } \
|
||||
/!|[Ee]rror:/ { printf "\033[0;31m"; e++; out=1; } \
|
||||
/internal:/ { printf "\033[0;35m"; out=1; } \
|
||||
/internal error:/ { printf "\033[1m"; out=1; } \
|
||||
/^[^[]/ || out { print; printf "\033[0;0m"; out=0; } \
|
||||
END { printf "%d error(s); %d warning(s).\n", e, w; } \
|
||||
'
|
||||
endef
|
||||
|
||||
define _go
|
||||
touch .cqueue \
|
||||
&& ( test -s .cqueue || echo "Nothing to be done for \`$@'." ) \
|
||||
&& echo "$(JAVA_HEAP_SIZE) $(JAVA_STACK_SIZE)" \ \
|
||||
&& CLASSPATH="$(RATER_CLASSPATH):rater/src/dslc.jar" \
|
||||
$(JAVA) -Xmx$(JAVA_HEAP_SIZE) -Xss$(JAVA_STACK_SIZE) \
|
||||
com.lovullo.dslc.DslCompiler < .cqueue 2>&1 \
|
||||
| $(saneout); \
|
||||
exit $${PIPESTATUS[0]}; \
|
||||
@>.cqueue
|
||||
endef
|
||||
.NOTPARALLEL:
|
||||
|
||||
SHELL = /bin/bash -O extglob
|
||||
|
||||
# these files will never be deleted when Make considers them to be intermediate
|
||||
# (e.g. when building summary pages), since they are still needed or take a
|
||||
# while to build
|
||||
.SECONDARY: %.js %.xml %.xmle %.xmlo
|
||||
|
||||
all: program-data-copy
|
||||
|
||||
program-ui-immediate:
|
||||
@>.cqueue
|
||||
@$(MAKE) --no-print-directory -f Makefile.2 program-ui-immediate
|
||||
@$(MAKE) program-data-copy
|
||||
@$(_go)
|
||||
program-ui: standalones ui/package.js ui/Program.js program-ui-immediate
|
||||
program-ui-immediate: ui/html/index.phtml
|
||||
|
||||
program-data-copy:
|
||||
@>.cqueue
|
||||
@$(MAKE) --no-print-directory -f Makefile.2 standalones program-ui c1map
|
||||
@$(_go)
|
||||
# Note the `$()' here to prevent Automake from inlining this file---it is
|
||||
# to be generated when imports change, which can be at any time.
|
||||
include $()suppliers.mk
|
||||
|
||||
summary-html: $(dest_summary_html) ;
|
||||
|
||||
%.html: %.js
|
||||
$(TAME) summary $*.xmle $@
|
||||
|
||||
standalones: $(dest_standalone)
|
||||
%.xmle: %.xmlo
|
||||
$(TAME) link $< $@
|
||||
%.js: %.xmle
|
||||
$(TAME) standalone $< $@
|
||||
|
||||
# C1 XML (specific recipes are in suppliers.mk)
|
||||
c1map: $(dest_c1map)
|
||||
|
||||
%.dot: %.xmlo
|
||||
$(TAME) dot $< $@
|
||||
%.dote: %.xmle
|
||||
$(TAME) dot $< $@
|
||||
|
||||
%.svg: %.dote
|
||||
dot -Tsvg "$<" > "$@"
|
||||
%.svg: %.dot
|
||||
dot -Tsvg "$<" > "$@"
|
||||
|
||||
%.xml: %.dat
|
||||
rater/tools/tdat2xml $< > $@
|
||||
|
||||
%.xml: %.typelist
|
||||
rater/tame/build-aux/list2typedef $(*F) < $< > $@
|
||||
|
||||
%.csvo: %.csvm
|
||||
rater/tools/csvm2csv $< > $@
|
||||
%.csvo: %.csvi
|
||||
rater/tools/csvi $< > $@
|
||||
%.csvo: %.csv
|
||||
cp $< $@
|
||||
|
||||
%.xml: %.csvo
|
||||
rater/tools/csv2xml $< > $@
|
||||
|
||||
version: .version.xml
|
||||
.version.xml: FORCE
|
||||
git log HEAD^.. -1 --pretty=format:'<version>%h</version>' > .version.xml
|
||||
|
||||
ui/program.expanded.xml: ui/program.xml
|
||||
$(TAME) progui-expand $< $@
|
||||
ui/Program.js: ui/program.expanded.xml ui/package.js
|
||||
$(TAME) progui-class $< $@ include-path=../../../ui/
|
||||
ui/html/index.phtml: ui/program.expanded.xml
|
||||
$(TAME) progui-html $< $@ out-path=./
|
||||
ui/package-dfns.xmlo: ui/package-dfns.xml
|
||||
ui/package-dfns.xml: ui/program.expanded.xml
|
||||
$(TAME) progui-pkg $< $@
|
||||
ui/package-map.xmlo: ui/package-map.xml
|
||||
ui/package-map.xml: ui/program.expanded.xml ui/package-dfns.xml
|
||||
$(TAME) progui-pkg-map $< $@
|
||||
|
||||
# for the time being, this does not depend on clean-rate-tables because $(ant) will
|
||||
specs:
|
||||
$(MAKE) -C doc/specs
|
||||
|
||||
# for the time being, this does not depend on clean-rate-tables because ant will
|
||||
# run it
|
||||
clean:
|
||||
find -L $(path_suppliers) $(path_map) $(path_c1map) common/ rater/core rater/lv \( \
|
||||
-name '*.xmlo' \
|
||||
-o -name '*.xmle' \
|
||||
-o -name '*.js' \
|
||||
-o -name '*.html' \
|
||||
-o -name '*.dep' \
|
||||
-o -name '*.tmp' \
|
||||
-o -name '*.php' \
|
||||
\) -exec rm -v {} \;
|
||||
rm -rf $(path_ui)/package-dfns.* \
|
||||
$(path_ui)/package-map.* \
|
||||
$(path_ui)/program.expanded.xml \
|
||||
$(path_ui)/include.js \
|
||||
$(path_ui)/Program.js \
|
||||
$(path_ui)/html
|
||||
find . -path '*/tables/*.csvm' -o -path '*/territories/*.dat' \
|
||||
| sed 's/\.csvm$$/\.xml/; s/\.dat$$/\.xml/' \
|
||||
| xargs rm -fv
|
||||
|
||||
# generates a Makefile that will properly build all package dependencies; note
|
||||
# that territory and rate packages also have includes; see top of this file for
|
||||
# an explanation
|
||||
suppliers.mk:
|
||||
$(ant) pkg-dep
|
||||
mv $(path_ui)/program.dep $(path_ui)/package-dfns.dep
|
||||
./rater/tame/build-aux/gen-make common/ $(path_suppliers)/ $(path_dsl)/ $(path_map)/ $(path_ui)/ >$@
|
||||
./rater/tame/build-aux/gen-c1make $(path_c1map)/*.xml >>$@
|
||||
|
||||
program-data-copy: standalones program-ui c1map .version.xml
|
||||
mkdir -p "$(path_lv)/src/node/program/rater/programs/@program@"
|
||||
mkdir -p "$(path_lv)/src/node/program/classify"
|
||||
mkdir -p "$(path_lv)/src/node/program/ui/custom"
|
||||
|
@ -124,7 +206,7 @@ program-data-copy:
|
|||
ant -f "$(path_lv)/build.xml" js-mod-order
|
||||
|
||||
# TODO: merge this and the above
|
||||
lvroot: prepare
|
||||
lvroot: summary-html
|
||||
mkdir -p "$(path_lvroot)/src/node/program/rater/programs/@program@"
|
||||
mkdir -p "$(path_lvroot)/src/node/program/classify"
|
||||
mkdir -p "$(path_lvroot)/src/node/program/ui/custom"
|
||||
|
@ -155,28 +237,18 @@ intralov-root: summary-html
|
|||
ln -fL $(path_dsl)/scripts/*.js "$(path_intralov_root)/rater/scripts/"
|
||||
ln -fL $(path_suppliers)/*.{html,js} "$(path_intralov_root)/suppliers"
|
||||
|
||||
|
||||
# because of the crazy wildcard target below, we want to ignore
|
||||
# some Automake-generated stuff
|
||||
%.am:
|
||||
%.m4:
|
||||
%.ac:
|
||||
|
||||
%: prepare
|
||||
@if [[ "$@" != [Mm]akefile ]]; then \
|
||||
$(MAKE) --no-print-directory -f Makefile.2 $@; \
|
||||
$(_go); \
|
||||
fi
|
||||
|
||||
clean:
|
||||
$(MAKE) --no-print-directory -f Makefile.2 clean
|
||||
|
||||
prepare: FORCE
|
||||
@>.cqueue
|
||||
|
||||
test: check
|
||||
check-am: standalones ui/package.js
|
||||
@$(path_dsl)/build-aux/progtest-runner $(path_suppliers) $(path_tests)
|
||||
@$(path_dsl)/build-aux/progtest-runner ui/package.xml $(path_tests)/ui
|
||||
|
||||
kill-tamed: tamed-die
|
||||
tamed-die:
|
||||
$(TAME) --kill
|
||||
|
||||
me-a-sandwich:
|
||||
@test $$EUID -eq 0 \
|
||||
&& echo 'You actually ran me as root? Are you insane!?' \
|
||||
|| echo 'Make it yourself.'
|
||||
|
||||
FORCE: ;
|
||||
|
|
|
@ -75,8 +75,7 @@ c1recipe()
|
|||
)
|
||||
|
||||
echo "$dir/$base.php: $file $includes"
|
||||
echo -e '\t@echo "c1map $< $@" >> .cqueue'
|
||||
echo -e '\t@touch $@'
|
||||
echo -e '\t$(TAME) c1map $< $@'
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -54,16 +54,8 @@ resolv-path()
|
|||
|
||||
# rule for building
|
||||
[ -z "$GEN_MAKE" ] && {
|
||||
echo "%.xmlo:: %.tmp"
|
||||
echo -e "\t@rm -f \$@ \$<"
|
||||
[ -n "$xmlo_cmd" ] \
|
||||
&& echo -e "\t$xmlo_cmd" \
|
||||
|| echo -e "\ttouch \$@"
|
||||
|
||||
echo "%.xmlo:: %.xml | prexmlo"
|
||||
[ -n "$xmlo_cmd" ] \
|
||||
&& echo -e "\t$xmlo_cmd" \
|
||||
|| echo -e "\ttouch \$@"
|
||||
echo "%.xmlo: %.xml"
|
||||
echo -e '\t$(TAME) compile $< $@'
|
||||
|
||||
export GEN_MAKE="$( pwd )/$0"
|
||||
exec "$GEN_MAKE" "$@"
|
||||
|
@ -119,6 +111,8 @@ until [ $# -eq 0 ]; do (
|
|||
# recurse on every subdirectory
|
||||
for p in */; do
|
||||
[ "$p" == ./ -o "$p" == ../ ] && continue
|
||||
[ "$p" == node_modules/ -o "$p" == tame/ ] && continue
|
||||
|
||||
[ ! -d "$p" ] || ( cd "$OLDPWD" && "$GEN_MAKE" "$path/$p" ) || {
|
||||
echo "fatal: failed to recurse on $( pwd )/$path/$p" >&2
|
||||
exit 1
|
||||
|
|
|
@ -33,13 +33,10 @@ AM_INIT_AUTOMAKE([foreign])
|
|||
AC_ARG_VAR([JAVA], [The Java executable])
|
||||
AC_ARG_VAR([ANT], [Apache Ant])
|
||||
AC_ARG_VAR([DSLC_JAR], [Path to DSL Compiler JAR])
|
||||
AC_ARG_VAR([TAME], [Path to TAME])
|
||||
AC_ARG_VAR([TAME], [The TAME compiler])
|
||||
AC_ARG_VAR([RATER_CLASSPATH], [DSL Compiler Saxon class path])
|
||||
AC_ARG_VAR([PROGUI_TEST_PATH], [Path to JavaScript tests for Program UI])
|
||||
|
||||
# Required version of TAME
|
||||
AC_SUBST([tame_needed_ver], [1.0.0])
|
||||
|
||||
# Auto-discover Java and Ant paths
|
||||
AC_CHECK_PROGS(JAVA, [java])
|
||||
AC_CHECK_PROGS(ANT, [ant])
|
||||
|
@ -64,34 +61,18 @@ AS_IF([test ! "$DSLC_JAR"],
|
|||
|
||||
# TAME is the compiler (whereas dslc invokes it, keeps things in memory, etc)
|
||||
AS_IF([test ! "$TAME"],
|
||||
[AC_CHECK_FILE([$CALCROOT/tame],
|
||||
[AC_SUBST([TAME], [$CALCROOT/tame])],
|
||||
[AC_CHECK_FILE([$CALCROOT/tame/bin/tame],
|
||||
[AC_SUBST([TAME], [$CALCROOT/tame/bin/tame])],
|
||||
[AC_MSG_ERROR(
|
||||
[TAME not found])])],
|
||||
[])
|
||||
|
||||
AC_MSG_CHECKING([TAME version])
|
||||
|
||||
AC_SUBST_FILE([tame_version])
|
||||
tame_version=$( cat "$TAME/VERSION" )
|
||||
|
||||
# We get subtle errors or potential compiler bugs if the TAME version is
|
||||
# incorrect; check for >= the required version
|
||||
AS_VERSION_COMPARE([$tame_version], [$tame_needed_ver],
|
||||
[
|
||||
AC_MSG_RESULT([$tame_version])
|
||||
AC_MSG_ERROR([TAME version $tame_needed_ver or greater required])
|
||||
],
|
||||
[AC_MSG_RESULT([$tame_version])],
|
||||
[AC_MSG_RESULT([$tame_version (>$tame_needed_ver)])])
|
||||
|
||||
# @program@ in *.in files will be replaced with the program name provided by AC_INIT
|
||||
AC_SUBST([program], AC_PACKAGE_NAME)
|
||||
|
||||
# Final files to be output by `configure'. The path before the colon is the
|
||||
# destination name; after the colon is the source.
|
||||
AC_CONFIG_FILES(Makefile:m4_defn(`calc_root')/build-aux/Makefile.in
|
||||
Makefile.2:m4_defn(`calc_root')/build-aux/Makefile.2.in)
|
||||
AC_CONFIG_FILES(Makefile:m4_defn(`calc_root')/build-aux/Makefile.in)
|
||||
|
||||
# Generate configure script
|
||||
AC_OUTPUT
|
||||
|
|
10
configure.ac
10
configure.ac
|
@ -40,6 +40,7 @@ AC_SUBST(REV, m4_argn(3, ver_split))
|
|||
AC_SUBST(SUFFIX, m4_argn(4, ver_split))
|
||||
|
||||
AC_ARG_VAR([JAVA], [The Java executable])
|
||||
AC_ARG_VAR([JAVA_OPTS], [Java options])
|
||||
AC_CHECK_PROGS(JAVA, [java])
|
||||
|
||||
AC_ARG_VAR([SAXON_CP], [Saxon class path])
|
||||
|
@ -52,7 +53,16 @@ AS_IF(test ! -d "$HOXSL",
|
|||
AC_MSG_ERROR([hoxsl path '$HOXSL' does not exist!]))
|
||||
AC_MSG_RESULT(found)
|
||||
|
||||
# BC with RATER_CLASSPATH
|
||||
DSLC_CLASSPATH="${DSLC_CLASSPATH:-$RATER_CLASSPATH}"
|
||||
AC_SUBST(DSLC_CLASSPATH, [$DSLC_CLASSPATH])
|
||||
|
||||
AC_SUBST([AUTOGENERATED],
|
||||
["THIS FILE IS AUTOGENERATED! DO NOT MODIFY! See *.in."])
|
||||
|
||||
AC_CONFIG_FILES([Makefile doc/Makefile src/init.xsl VERSION])
|
||||
AC_CONFIG_FILES([bin/dslc],
|
||||
[chmod +x bin/dslc])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ stylesheets := $(shell find "$(path_src)" \
|
|||
stexi := $(stylesheets:.xsl=.texi)
|
||||
|
||||
info_TEXINFOS = tame.texi
|
||||
tame_TEXINFOS = todo.texi license.texi $(stexi) tame.css
|
||||
tame_TEXINFOS = about.texi todo.texi license.texi $(stexi) tame.css
|
||||
|
||||
MAKEINFOHTML=$(MAKEINFO) --html --css-include tame.css
|
||||
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
@c This document is part of the TAME manual.
|
||||
@c Copyright (C) 2018 R-T Specialty, LLC.
|
||||
@c Permission is granted to copy, distribute and/or modify this document
|
||||
@c under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
@c any later version published by the Free Software Foundation; with no
|
||||
@c Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
@c A copy of the license is included in the section entitled ``GNU Free
|
||||
@c Documentation License''.
|
||||
|
||||
@node About TAME
|
||||
@chapter About TAME
|
||||
@tame{} is The Adaptive Metalanguage,
|
||||
a programming language and system of tools designed to aid in the
|
||||
development; understanding; and maintenance of systems performing
|
||||
numerous calculations on a complex graph of dependencies;
|
||||
conditions; and a large number of inputs.
|
||||
|
||||
This system was developed at R-T Specialty@footnote{
|
||||
Formerly LoVullo Associates.}
|
||||
to handle the complexity of comparative insurance rating systems.
|
||||
It is a domain-specific language@tie{}(DSL) that itself encourages,
|
||||
through the use of templates,
|
||||
the creation of sub-DSLs.
|
||||
@tame{} itself is at heart a calculator@mdash{
|
||||
}processing only numerical input and output@mdash{
|
||||
}driven by quantifiers as predicates.
|
||||
Calculations and quantifiers are written declaratively without concern
|
||||
for order of execution.
|
||||
|
||||
The system has powerful dependency resolution and data flow capabilities.
|
||||
|
||||
@tame{} consists of a macro processor (implementing a metalanguage);
|
||||
numerous compilers for various targets
|
||||
(JavaScript, HTML documentation and debugging environment, LaTeX,
|
||||
and others);
|
||||
linkers; and supporting tools.
|
||||
The input grammar is XML,
|
||||
and the majority of the project
|
||||
(including the macro processor, compilers, and linkers)
|
||||
is written in XSLT.@footnote{
|
||||
There is a reason for that odd choice;
|
||||
until an explanation is provided,
|
||||
know that someone is perverted enough to implement a full
|
||||
compiler in XSLT.}
|
||||
|
||||
|
||||
|
||||
@menu
|
||||
* Getting Started:: Getting started from a source repository checkout.
|
||||
* Manual Compilation:: How to compile a source file by hand.
|
||||
* Compiling With Make:: Using the Makefile (recommended).
|
||||
@end menu
|
||||
|
||||
|
||||
@node Getting Started
|
||||
@section Getting Started
|
||||
To get started,
|
||||
make sure Saxon version@tie{}9 or later is available and its path
|
||||
set as @var{SAXON_CP};
|
||||
that the path to hoxsl is set via @var{HOXSL};
|
||||
and then run the @samp{bootstrap} script:
|
||||
|
||||
@float Figure, f:bootstrap
|
||||
@example
|
||||
$ export SAXON_CP=/path/to/saxon9he.jar
|
||||
$ export HOXSL=/path/to/hoxsl/root
|
||||
|
||||
$ ./boostrap
|
||||
@end example
|
||||
@caption{Bootstrapping TAME in a source repository checkout}
|
||||
@end float
|
||||
|
||||
|
||||
|
||||
@node Manual Compilation
|
||||
@section Manual Compilation
|
||||
@emph{Note: TAME is usually controlled through a Makefile;
|
||||
@pxref{Compiling With Make} to avoid manual compilation
|
||||
steps.}
|
||||
|
||||
@tame{} is controlled through the program in @command{bin/tame}.
|
||||
When run,
|
||||
it first spawns a daemon @command{bin/tamed} if it is not already
|
||||
running.
|
||||
@command{tamed} is needed to keep the JVM and compiled XSLT templates
|
||||
in memory,
|
||||
otherwise each file would incur a steep startup penalty.
|
||||
|
||||
@todo{Document commands.
|
||||
Most developers do not build files directly,
|
||||
so this is not essential yet.}
|
||||
|
||||
@float Figure, f:compile-ex
|
||||
@example
|
||||
$ bin/tame compile src/foo.xml src/foo.xmlo
|
||||
$ bin/tame link src/foo.xmlo src/foo.xmle
|
||||
$ bin/tame standalone src/foo.xmle src/foo.js
|
||||
$ bin/tame summary src/foo.xmle src/foo.html
|
||||
@end example
|
||||
@caption{Compiling a JavaScript executable and Summary Page}
|
||||
@end float
|
||||
|
||||
To kill the daemon,
|
||||
pass @samp{--kill} to either @file{bin/tame} or @file{bin/tamed}.
|
||||
For additional options and environment variables that influence
|
||||
operation,
|
||||
pass @samp{--help} to either command.
|
||||
|
||||
|
||||
@node Compiling With Make
|
||||
@section Compiling With Make
|
||||
TAME can generate a @url{https://gnu.org/software/make,GNU Makefile}
|
||||
for you using @url{https://gnu.org/software/automake,Automake} and
|
||||
@url{https://gnu.org/softeware/autoconf,Autoconf}.
|
||||
This greatly simplifies building projects by automatically building
|
||||
all dependencies as needed,
|
||||
and only when they have changed.@footnote{@c
|
||||
When their modification timestamps change, specifically.}
|
||||
|
||||
The Makefile is generated by a @file{configure} script,
|
||||
which itself generated by Autoconf using @file{configure.ac} in the
|
||||
project root:
|
||||
|
||||
@float Figure, f:configure-ac
|
||||
@example
|
||||
AC_INIT([PROJECT_NAME], [0.0.0], [contact@@email])
|
||||
|
||||
m4_define(`calc_root', rater)
|
||||
m4_include([rater/build-aux/m4/calcdsl.m4])
|
||||
|
||||
@end example
|
||||
@caption{Example @file{configure.ac} in project root.}
|
||||
@end float
|
||||
|
||||
By convention,
|
||||
TAME is usually available as a submodule under @file{rater/}.
|
||||
This confusing naming convention may change in the future.
|
||||
|
||||
Then, to generate the @file{Makefile}:
|
||||
|
||||
@float Figure, f:configure
|
||||
@example
|
||||
$ autoreconf -fvi
|
||||
$ ./configure SAXON_CP=/path/to/saxon9he.jar
|
||||
@end example
|
||||
@caption{Invoking @file{configure} to generate @file{Makefile}.}
|
||||
@end float
|
||||
|
||||
@todo{Add more sections.}
|
||||
|
||||
@menu
|
||||
* Common Targets:: Common Makefile targets.
|
||||
@end menu
|
||||
|
||||
|
||||
@node Common Targets
|
||||
@subsection Common Targets
|
||||
A @dfn{target} is something that can be built.
|
||||
Usually it is a specific file (e.g. @file{foo.js}),
|
||||
but it can also be a command (also called a @dfn{phony target}).
|
||||
Here are the most common phony targets that may be useful:
|
||||
|
||||
@table @samp
|
||||
@item all
|
||||
This is the default target (just type @samp{make}).
|
||||
Build the UI and all suppliers.
|
||||
Does not build the Summary Pages,
|
||||
as they are considered to be debugging tools.
|
||||
|
||||
@item summary-html
|
||||
Build all Summary Pages for programs in @file{suppliers/}.
|
||||
This is equivalent to building each @file{suppliers/*.html} target
|
||||
manually.
|
||||
|
||||
@item check
|
||||
@item test
|
||||
Run test cases in @file{test/}.
|
||||
|
||||
@item standalones
|
||||
Build JavaScript executables for each program in @file{suppliers/}.
|
||||
This is a dependency of @samp{summary-html}.
|
||||
|
||||
@item tamed-die
|
||||
@item kill-tamed
|
||||
Kill running tamed for effective user, if any
|
||||
(@pxref{Manual Compilation}).
|
||||
|
||||
@item clean
|
||||
Delete all file targets.
|
||||
This may be necessary when upgrading TAME,
|
||||
for example,
|
||||
to rebuild all files using the new version.
|
||||
@end table
|
|
@ -1,6 +1,6 @@
|
|||
\input texinfo
|
||||
@c This document is part of the TAME manual.
|
||||
@c Copyright (C) 2015, 2016 R-T Specialty, LLC.
|
||||
@c Copyright (C) 2015, 2016, 2018 R-T Specialty, LLC.
|
||||
@c Permission is granted to copy, distribute and/or modify this document
|
||||
@c under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
@c any later version published by the Free Software Foundation; with no
|
||||
|
@ -19,7 +19,7 @@
|
|||
@copying
|
||||
This manual is for TAME, version @value{VERSION}.
|
||||
|
||||
Copyright @copyright{} 2015, 2016 R-T Specialty, LLC.
|
||||
Copyright @copyright{} 2015, 2016, 2018 R-T Specialty, LLC.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
|
@ -51,6 +51,7 @@ Free Documentation License".
|
|||
@end ifnottex
|
||||
|
||||
@menu
|
||||
* About TAME:: History of TAME and how to use it
|
||||
* Preprocessor:: Metaprogramming system
|
||||
* Dependency Graph:: Dependency processing and flow analysis
|
||||
* Symbol Table:: Lookup table for all objects
|
||||
|
@ -97,6 +98,7 @@ TAME
|
|||
@definfoenclose math,\(,\)
|
||||
@end ifhtml
|
||||
|
||||
@include about.texi
|
||||
|
||||
@node Preprocessor
|
||||
@chapter Preprocessor
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# Compatibility Directory
|
||||
|
||||
This directory exists for compatibility with earlier build scripts and path
|
||||
assumptions before TAME was extracted into its own repository. A full
|
||||
transition will remove this directory.
|
||||
|
|
@ -0,0 +1 @@
|
|||
../src/current/c1map
|
|
@ -0,0 +1 @@
|
|||
../src/current/c1map.xsl
|
|
@ -0,0 +1 @@
|
|||
../src/current/calc.xsd
|
|
@ -0,0 +1 @@
|
|||
../src/current/compile.xsl
|
|
@ -0,0 +1 @@
|
|||
../src/current/compiler
|
|
@ -0,0 +1 @@
|
|||
../src/current/dot.xsl
|
|
@ -0,0 +1 @@
|
|||
../src/current/include/
|
|
@ -0,0 +1 @@
|
|||
../src/current/link.xsl
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
../src/current/standalone.xsl
|
|
@ -0,0 +1 @@
|
|||
../src/current/summary.xsl
|
|
@ -0,0 +1 @@
|
|||
../
|
|
@ -1380,8 +1380,7 @@
|
|||
|
||||
|
||||
|
||||
<xsl:function name="eseq:expand-node" as="node()*"
|
||||
override="yes">
|
||||
<xsl:function name="eseq:expand-node" as="node()*">
|
||||
<xsl:param name="node" as="node()" />
|
||||
|
||||
<xsl:apply-templates mode="preproc:macros"
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
dslc_src := $(wildcard com/lovullo/dslc/*.java)
|
||||
dslc_bin := $(dslc_src:.java=.class)
|
||||
|
||||
.PHONY: dslc clean
|
||||
.PHONY: all all-nodoc dslc clean
|
||||
|
||||
all: dslc
|
||||
dslc: dslc.jar
|
||||
|
||||
%.class: %.java
|
||||
|
|
|
@ -69,17 +69,10 @@ public class DslCompiler
|
|||
HashMap<String,String> params
|
||||
) throws Exception
|
||||
{
|
||||
if ( cmd.equals( "validate" ) )
|
||||
// validate before compilation
|
||||
if ( cmd.equals( "compile" ) )
|
||||
{
|
||||
_xsd.validate( doc );
|
||||
return;
|
||||
}
|
||||
else if ( cmd.equals( "rm" ) )
|
||||
{
|
||||
// remove file (purposely uncaught)
|
||||
( new File( src ) ).delete();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( dest.equals( "" ) )
|
||||
|
@ -105,12 +98,17 @@ public class DslCompiler
|
|||
new StreamResult( new File( dest ) ),
|
||||
params
|
||||
);
|
||||
|
||||
// TODO: more unique identifier
|
||||
System.err.println( "DONE 0 " + dest );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
// delete the output file; it's garbage
|
||||
destfile.delete();
|
||||
|
||||
System.err.println( "DONE 1 " + dest );
|
||||
|
||||
// be verbose and unprofessional.
|
||||
throw e;
|
||||
}
|
||||
|
@ -290,7 +288,8 @@ public class DslCompiler
|
|||
|
||||
private static void compileSrc( _DslCompiler dslc, String cmdline ) throws Exception
|
||||
{
|
||||
System.err.println( cmdline );
|
||||
System.err.printf( "COMMAND " + cmdline + "\n" );
|
||||
|
||||
String[] args = cmdline.split( " " );
|
||||
String dest = "";
|
||||
|
||||
|
|
Loading…
Reference in New Issue