# # . ./build.vars and set -o errexit are assumed. # See warning at the top of build.vars. # date() { command date +"${1:-${TIMESTAMP_FMT}}"; }; fetch_git() { [ -d ${1} ] && (cd ${1} && git pull origin main) || git clone ${3} ${2} ${1}; }; get_basename() { set -- $(get_name_without_slash ${1}); echo "${1##*/}"; }; get_var() { eval echo \${${1}}; }; # XXX set_var() { eval ${1}=\"${2}\"; }; # XXX get_name_without_slash() { while [ "x${1%/}" != "x${1}" ]; do set -- ${1%/}; done; echo ${1}; }; get_postfix_lrg() { echo "${1##*${2}}"; }; get_prefix_lrg() { echo "${1%%${2}*}"; }; get_postfix() { echo "${1#*${2}}"; }; get_prefix() { echo "${1%${2}*}"; }; match_any() { [ "x${1#*${2}*}" != "x${1}" ]; }; match_start() { [ "x${1#${2}}" != "x${1}" ]; }; push_IFS() { _IFS="${IFS}"; IFS="${1}"; }; pop_IFS() { IFS="${_IFS}"; unset _IFS; }; set_build_dir() { BUILD_DIR=${1}-${2}-${TARGET}; }; split() { push_IFS "${1}"; set -- ${2}; pop_IFS; echo "${*}"; }; unsplit() { push_IFS "${1}"; shift; set -- "${@}"; echo "${*}"; pop_IFS; }; rm_if_exists() { set_flag_vars_from_args "$@"; shift ${_nshift:-0}; [ -d ${1} ] && rm -rf ${1}; [ -f ${1} ] && rm -f ${1}; [ ${_arg_m:-0} -eq 1 ] && mkdir ${1}; [ ${_arg_c:-0} -eq 1 ] && cd ${1}; unset_flag_vars_from_args; }; set_flag_vars_from_args() { unset _flag_vars _nshift; while [ ${#} -gt 1 ]; do if [ "x${1%[a-z]}" = "x-" ]; then set_var _arg_${1#-} 1; _flag_vars="${_flag_vars:+${_flag_vars} }_arg_${1#-}"; : $((_nshift+=1)); fi; shift; done; }; unset_flag_vars_from_args() { set -- ${_flag_vars}; while [ ${#} -gt 0 ]; do unset ${1}; shift; done; unset _flag_vars _nshift; }; set_env_vars() { _val_new="${1}"; shift; while [ ${#} -gt 1 ]; do [ -z "${_val_new}" ] && unset ${1} ||\ export "${1}=${_val_new}"; shift; done; unset _val_new; }; # Download GNU bash-style patch sets into ${2}-patches-extra and # apply them to ${2} in the correct order. apply_patches() { (rm_if_exists -m -c ${2}-patches-extra; wget -c -nd -np -r -R \*.htm\* -R \*.sig ${1}; for _patch_fname in \ $(find . -type f -not -iname \*.sig | sort); do patch -b -d ../${2} -p0 \ < ${_patch_fname}; done; unset _patch_fname); }; # Check whether all supplied arguments contain non-empty valid values. check_path_vars() { while [ ${#} -gt 0 ]; do unset _val; if [ -z "${_val:=$(get_var "${1}")}" ]; then log_msg failexit "Error: variable \`${1}' is empty or unset."; elif match_any "${_val}" " "; then log_msg failexit "Error: variable \`${1}' contains one or more whitespace characters."; else shift; fi; done; unset _val; }; # Check whether all supplied command names resolve. check_prereqs() { while [ ${#} -gt 0 ]; do if ! command -v ${1} >/dev/null; then log_msg failexit "Error: missing prerequisite command \`${1}'."; fi; shift; done; }; # Clear the environment by unsetting each exported variable except # for those named by the caller. clear_env_with_except() { _vfilter="${*}"; _unset_cmds="$(mktemp -q)"; export | while read _vspec; do set -- ${_vspec}; shift; if ! match_list "${_vfilter}" " " \ $(get_prefix_lrg ${1} =); then echo unset $(get_prefix_lrg ${1} =) >> ${_unset_cmds}; fi; done; . "${_unset_cmds}"; rm -f "${_unset_cmds}" 2>/dev/null; unset _vfilter _vspec; }; fetch() { wget ${WGET_ARGS} ${1}; if [ ${#} -eq 2 ]; then set -- $(get_basename ${1}) "$(compare_hash $(get_basename ${1}) ${2})" ${2}; if [ -n "${2}" ]; then log_msg failexit "Error: hash mismatch for URL \`${1}' (is: ${2}, should be: ${3}.)"; fi; fi; }; compare_hash() { # Push the output of dgst(1SSL) and the caller-supplied hash # value to compare the former with on the pseudo-stack and # shift off# all but the last two positional parameters. # This corresponds to the hash output and caller-supplied # hash values. set -- $(openssl dgst -sha256 ${1}) ${2}; shift $((${#}-2)); [ "x${1}" = "x${2}" ] || echo "${1}"; }; compare_hash_manifest() { while [ ${#} -gt 0 ]; do if ! compare_hash ${1} ${2}; then log_msg failexit "Error: hash mismatch for patch file \`${1}'."; fi; shift; done; return 0; }; is_build_script_done() { if [ -n "${ARG_BUILD_STEPS}" ]; then if [ "${ARG_BUILD_STEPS}" = "finish" ]\ || [ -z "${ARG_BUILD_STEPS#ALL}" ]; then return 1; # Build elif ! match_list ${ARG_BUILD_STEPS} , ${1}; then return 0; # Skip else return 1; # Build fi; elif [ -f ${WORKDIR}/.${2:-$(get_basename ${SCRIPT_FNAME%.build})}.${1} ]; then return 0; # Skip else return 1; # Build fi; }; set_build_script_done() { _script_fname=${SCRIPT_FNAME##*/}; _done_fname=${WORKDIR}/.${_script_fname%.build}; while [ $# -ge 1 ]; do if [ "x${1#-}" != "x${1}" ]; then rm -f ${_done_fname}.${1#-}; else touch ${_done_fname}.${1}; log_msg info "Finished build step ${1} of build script \`${_script_fname}'."; fi; shift; done; unset _script_fname _done_fname; }; log_env_vars() { log_msg info "Variables for this build:"; while [ ${_nvar:=0} -lt ${#} ]; do _arg="$(eval echo \${${_nvar}})"; _arg="${_arg%%=*}"; if [ ${#_arg} -gt ${_arg_len_max:=0} ]; then _arg_len_max=${#_arg}; fi; : $((_nvar+=1)); done; unset _nvar _arg; while [ ${#} -gt 0 ]; do log_msg info "$(printf \ "%${_arg_len_max}.${_arg_len_max}s=%s" \ "${1%%=*}" "$(get_var ${1#*=})")"; shift; done; unset _arg_len_max; }; log_msg() { _lvl=${1}; shift; case ${_lvl} in failexit) printf "\033[${LOG_MSG_FAIL_COLOUR}m"; ;; fail) printf "\033[${LOG_MSG_FAIL_COLOUR}m"; ;; info) printf "\033[${LOG_MSG_INFO_COLOUR}m"; ;; succ) printf "\033[${LOG_MSG_SUCC_COLOUR}m"; ;; esac; if [ $# -gt 1 ]; then printf "==> %s %s %s\033[0m\n" "$(date "${TIMESTAMP_FMT}")" "${1}" "$*"; else printf "==> %s %s\033[0m\n" "$(date "${TIMESTAMP_FMT}")" "${1}"; fi; [ ${_lvl} = failexit ] && exit 1 || unset _lvl; }; match_list() { _cmp="${3}"; push_IFS "${2}"; set -- ${1}; pop_IFS; while [ ${#} -gt 0 ]; do if [ "x${1}" = "x${_cmp}" ]; then unset _cmp; return 0; fi; shift; done; unset _cmp; return 1; }; parse_args_into_vars() { _arg0="${1}"; _args_valid="${2}"; shift 2; while [ $# -gt 0 ]; do case "${1}" in --*) _aname="${1#--}"; if ! match_list "${_args_valid}" , "${_aname%%=*}"; then log_msg failexit "Unknown parameter --${_aname%%=*} specified."; elif match_start "${_aname}" "*="; then _aval="$(get_postfix "${_aname}" =)"; _aname="$(get_prefix_lrg "${_aname}" =)"; else _aval=1; fi; set_var $(echo arg_${_aname} | tr a-z- A-Z_) "${_aval}"; shift; ;; *=*) set_var "$(get_prefix_lrg "${1}" =)"\ "$(get_postfix "${1}" =)"; shift; ;; *) log_msg failexit "Invalid or unknown command line argument \`${1}'."; ;; esac; done; unset _arg0 _args_valid _aname _aval; }; parse_with_pkg_name() { PKG_NAME=${1}; shift; while [ $# -ge 0 ]; do if [ "x${PKG_NAME}" = "x${1}" ]; then _pkg_NAME=$(echo "${PKG_NAME}" | tr a-z A-Z); for _vname in ${PKG_VARS}; do _vNAME=$(echo "${_vname}" | tr a-z A-Z); if [ -n "${_vval:=$(get_var PKG_${_pkg_NAME}_${_vNAME})}" ]; then export PKG_${_vNAME}="${_vval}"; if [ "x${_vname#[A-Z]}" != "x${_vname}" ]; then export ${_vname}="${_vval}"; fi; else unset PKG_${_vNAME}; fi; unset _vval; done; unset _pkg_NAME _vname _vNAME; if [ -z "${PKG_URL}" ]; then return 1; else [ -z "${PKG_FNAME}" ] && PKG_FNAME=${PKG_URL##*/}; [ -z "${PKG_SUBDIR}" ] && PKG_SUBDIR=${PKG_FNAME%%.tar*}; return 0; fi; fi; shift; done; return 1; }; # vim:filetype=sh