diff options
Diffstat (limited to 'ship')
| -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 "$@" | 
