#!/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" "${@}" >&2 exit 2 } error() { local fmt="${1}" shift 1 printf "shpp: ${fmt}\n" "${@}" >&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 "${@}"