#! /bin/sh set -euf ## SYNOPSIS # build compile SRCFILE DSTFILE # build deps SRCFILE build() { case "$1" in compile) build_compile "$2" "$3";; deps) build_deps "$2";; *) echo "build: $1: bad command" >&2; return 23;; esac } ## build directives build_info_directive='#@info' build_include_directive='#@include \([0-9A-Za-z]\+\)' input_parser="\ s:^ *\([0-9]\+\) "$build_info_directive"$:build_info \1: s:^ *\([0-9]\+\) "$build_include_directive"$:build_include \1 \2: t s:^ *\([0-9]\+\) .*:echo \1p:" ## usage: build_include LINENO LIBNAME build_include() { cat< "$2" chmod +x "$2" } ## usage: needs_compilation SHELLSCRIPT # Returns true if SRCFILE contains compilation directives. needs_compilation() { echo "$1" | grep -q "^\\($build_include_directive\\|$build_info_directive\\)$" } ## usage: make_sedscript_maker_shellscript SRCFILE # Print a shellscript that creates a sedscript that resolves all the build # directives in SRCFILE. make_sedscript_maker_shellscript() { sedscript_generator="$(echo "$1" | nl -b a -s ' ' | sed "$input_parser")" sedscript="$(eval "$sedscript_generator")" echo "$sedscript" } ## usage: build_deps SRCFILE build_deps() { for libname in $(sed -n 's:^'"$build_include_directive"'$:\1:p' "$1"); do build_resolve "$libname" done } ## usage: build_resolve LIBNAME build_resolve() { echo "$BUILD_PATH" | tr : \\n | xargs -I: printf '%s/%s\n' : "$1" | xargs -I: ls -d : 2>/dev/null | head -n 1 | grep . || { echo "build resolve: $1: library not found" >&2 return 23 } } build "$@"