#!/bin/sh
#
# Simple source file preprocessor.
# Processes *.in files, replacing lines of format
#    KEYWORD cmd
# with 'cmd' output.

preproc() {
    sed -e '
        /^ *'"${cmd_keyword} "'/{
            s|^ *'"${cmd_keyword} "'||
            e
        }'
}

require_cmds() {
    # check dependencies
    for c in "$@"; do
        type "$c" >/dev/null 2>&1 && continue
        printf '%s\n' "$c is required, but not found."
        exit 1
    done
}

check_args() {
    case $# in

    # Require at least 1 argument: keyword
    0)  printf '%s\n' \
            "Usage:" \
            "  $0 KEYWORD [TARGET_FILES...]" \
            "  $0 KEYWORD" \
            "TARGET_FILES - each 'file' is generated from proper 'file.in'." \
            "Standard input/output are used if no files specified." \
            >&2
        exit 1
    ;;
    # Enter stdin processing without files argument
    1)  preproc
        exit $?
    ;;
    esac
    cmd_keyword="$1"
}

### START ###

export PATH="$(realpath $(dirname "$0")):${PATH}"

require_cmds sed
check_args "$@"
shift

for f in "$@"; do
    if ! [ -f "${f}.in" ]
    then
        if ! [ "${notfound_first}" ]
        then
            notfound_first=1
            printf '%s\n' "Can't find files:" >&2
        fi
        printf '%s\n' "  ${f}" >&2
        continue
    fi

    f=$( realpath "${f}" )

    cap="Do not edit. Auto-generated from '$( basename "${f}.in" )'"
    case "${f}" in
    (*.c|*.cc|*.cpp|*.cxx|*.h|*.hh|*.hpp|*.hxx|*.C|*.CC|*.CPP|*.CXX|*.H |*.HH|*.HPP|*.HXX|*.java)
        cap="/* ${cap} */" ;;
    (*.sh|*.awk|*.pl|*.py )
        cap="# ${cap}" ;;
    esac

    pushd $(dirname "${f}") >/dev/null
    f=$(basename "${f}")
    printf '%s\n\n' "${cap}" > "${f}"
    preproc < "${f}.in"     >> "${f}"
    popd  >/dev/null
done

