diff options
-rwxr-xr-x | ship/build | 102 |
1 files changed, 56 insertions, 46 deletions
@@ -5,6 +5,14 @@ set -euf # [debug=true] build compile SRCFILE DSTFILE # [debug=true] build deps SRCFILE... build() { + + # usage_pattern is used to extract build directive declarations. + usage_pattern='## usage: \(.*\) -> \([^ ]\+\) \(.*\)' + + script='s/^'"$usage_pattern"'$/\2_directive='"'"'\1'"'"'/p' \ + setf build_x_directive_loader '$(sed -n "$script" "$%s")' 0 + eval "$build_x_directive_loader" + case "$1" in compile) build_compile "$2" "$3";; deps) shift; build_deps "$@";; @@ -12,28 +20,7 @@ build() { esac } -# usage: debug_script VARNAME [DESCRIPTION] -debug_script() { - if test "${debug-false}" = true; then - printf '[35m====== %s%s[m\n%s\n' \ - "$1" \ - "${2+" ($2)"}" \ - "$(eval echo \"\$$1\" | nl -b a)" >&2 - fi -} - -## 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:" -debug_script input_parser - -## usage: build_include LINENO LIBNAME +## usage: #@include \([0-9A-Za-z]\+\) -> build_include \1 \2 build_include() { cat<<EOF $1a\\ # begin $2 @@ -43,7 +30,7 @@ $1a\\ EOF } -## usage: build_info LINENO +## usage: #@info -> build_info \1 build_info() { cat<<EOF $1a\\ # this file was generated by //ship/build\\ @@ -54,37 +41,36 @@ EOF ## usage: build_compile SRCFILE DSTFILE build_compile() { - srcfile="$(cat "$1")" - debug_script srcfile 'SRCFILE' - while needs_compilation "$srcfile"; do - script="$(make_sedscript_maker_shellscript "$srcfile")" - srcfile="$(echo "$srcfile" | sed -n "$script")" - debug_script srcfile 'sed sedscript srcfile' + script='s/^'"$usage_pattern"'$/\2_directive/p' \ + setf build_directives '$(sed -n "$script" "$%s")' 0 + + script=' + s/^'"$usage_pattern"'$/s:^ *\\([0-9]\\+\\) \1$:\2 \3:/p + $a\ + t\ + s:^ *\\([0-9]\\+\\) .*:echo \\1p: + ' \ + setf input_parser '$(sed -n "$script" "$%s")' 0 + + setf incomplete_pattern '$(make_incomplete_pattern $%s)' build_directives + + SRCFILE="$1" setf src '$(cat "$%s")' SRCFILE + + while needs_compilation "$src" "$incomplete_pattern"; do + setf sedgen '$(echo "$%s" | nl -b a -s \ | sed "$%s")' src input_parser + setf sedscript '$(eval "$%s")' sedgen + setf src '$(echo "$%s" | sed -n "$%s")' src sedscript done - echo "$srcfile" > "$2" + echo "$src" > "$2" chmod +x "$2" } -## usage: needs_compilation SHELLSCRIPT +## usage: needs_compilation SHELLSCRIPT PATTERN # 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")" - debug_script sedscript_generator 'sed input_parser srcfile' - - sedscript="$(eval "$sedscript_generator")" - debug_script sedscript 'eval sedscript_generator' - - echo "$sedscript" + echo "$1" | grep -q "$2" } ## usage: build_deps SRCFILE... @@ -118,4 +104,28 @@ build_resolve() { } } +## usage: make_incomplete_pattern BUILD_DIRECTIVES... +make_incomplete_pattern() { + echo "^\\($( + for directive; do + eval echo \"\$$directive\" + done | + tr \\n \| | + sed 's/|/\\|/' + )\\)$" +} + +## usage: setf NAME FMT [ARG...] +setf() { + value_script="$(shift; printf "$@")" + + eval "$1=$value_script" + + if test "${debug-false}" = true; then + eval 'echo "[35m$1=\"$value_script\"[m"' + eval 'echo "'"\$$1"'"' | nl -b a + fi >&2 +} + +## main build "$@" |