#!/bin/sh
#
# Shell command language preprocessor
#
# Copyright (C) 2015 Patrick "P. J." McDermott
#
# 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 .
set -u
VERSION='0.1.0'
FS="$(printf '\034')"
die()
{
local fmt="${1}"
shift 1
printf "shpp: ${fmt}\n" "${@}"
exit 2
}
preprocess()
{
local vars="${1}"
local input="${2}"
local output="${3}"
local def=
local var=
local val=
# Open output file.
if [ "x${output}" = 'x-' ]; then
if ! exec 3>&1; then
die 'Cannot duplicate output file descriptor'
fi
else
if ! exec 3>"${outfile}~"; then
die 'Cannot open file "%s"' "${output}~"
fi
fi
IFS="${FS}"
for def in ${vars}; do
case "${def}" in
*=*)
var="${def%%=*}"
val="${def#*=}"
;;
*)
var="${def%%=*}"
val='true'
;;
esac
case "${var}" in
*[!A-Za-z0-9_]*)
error 'Invalid variable name "%s"' "${var}"
continue
;;
[0-9]*)
error 'Invalid variable name "%s"' "${var}"
continue
;;
esac
printf "%s='" "${var}" >&3
printf '%s' "${val}" | sed "s/'/'\\\\''/g" >&3
printf "'\n" >&3
done
unset IFS
# Read input file.
if ! cat "${input}" >&3; then
die 'Cannot read file "%s"' "${input}"
fi
# Close output file, make it executable, and set its name.
if ! [ "x${output}" = 'x-' ]; then
exec 3>&-
if ! mv "${output}~" "${output}"; then
die 'Cannot rename file to "%s"' "${output}"
fi
fi
}
usage()
{
printf 'Usage: %s [option ...] []\n' "${0}"
}
help()
{
usage
cat <[=] Predefine as a variable with value (default
"true")
EOF
}
version()
{
cat <.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
EOF
}
main()
{
local opt=
local vars=
local infile=
local outfile=
while getopts 'hVD:' opt; do
case "${opt}" in
'h')
help
exit
;;
'V')
version
exit
;;
'D')
vars="${vars}${OPTARG}${FS}"
;;
esac
done
shift $(($OPTIND - 1))
case ${#} in
1)
infile="${1}"
outfile='-'
;;
2)
infile="${1}"
outfile="${2}"
;;
*)
usage >&2
exit 1
esac
preprocess "${vars}" "${infile}" "${outfile}"
}
main "${@}"