From 4243a1676e1be4de207c850825c0e84c00b8151a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=C3=ADa=20Andrea=20Illanes=20Albornoz?= Date: Tue, 21 Mar 2023 11:05:34 +0100 Subject: Document subr.rtl/*.subr functions, pt. IV. --- subr.rtl/rtl_fetch.subr | 2 +- subr.rtl/rtl_fetch_wget.subr | 16 ++--- subr.rtl/rtl_fileop.subr | 26 ++++---- subr.rtl/rtl_install_v2.subr | 2 +- subr.rtl/rtl_list.subr | 4 ++ subr.rtl/rtl_log.subr | 79 +++++++++++++++++++---- subr.rtl/rtl_platform.subr | 147 ++++++++++++++++++++++++++++--------------- subr.rtl/rtl_state.subr | 77 ++++++++++++++++------- 8 files changed, 246 insertions(+), 107 deletions(-) (limited to 'subr.rtl') diff --git a/subr.rtl/rtl_fetch.subr b/subr.rtl/rtl_fetch.subr index 7946b7c7..3ebd2d06 100644 --- a/subr.rtl/rtl_fetch.subr +++ b/subr.rtl/rtl_fetch.subr @@ -35,7 +35,7 @@ rtl_fetch_clean_dlcache() { if [ "${_pfdcd_skipfl}" -eq 0 ]; then _pfdcd_fname="${_pfdcd_dlcachedir}/${_pfdcd_name}/${_pfdcd_fname}"; - rtl_log_msg "verbose" "${MSG_rtl_fetch_rm_redundant}" "${_pfdcd_fname}" "${_pfdcd_name}"; + rtl_log_msgV "verbose" "${MSG_rtl_fetch_rm_redundant}" "${_pfdcd_fname}" "${_pfdcd_name}"; rtl_fileop rm "${_pfdcd_fname}"; fi; done; diff --git a/subr.rtl/rtl_fetch_wget.subr b/subr.rtl/rtl_fetch_wget.subr index 13bc347a..361603f0 100644 --- a/subr.rtl/rtl_fetch_wget.subr +++ b/subr.rtl/rtl_fetch_wget.subr @@ -13,7 +13,7 @@ # @_mirrors: optional list of mirror base URLs # # Returns: zero (0) on success, non-zero (>0) on failure -# N.B. URLs ($1) may contain `?' or '&' characters. +# N.B.: URLs ($1) may contain `?' or '&' characters. # rtl_fetch_url_wget() { local _rfuw_urls="${1}" _rfuw_sha256sum_src="${2}" _rfuw_target_dname="${3}" \ @@ -57,28 +57,28 @@ rtl_fetch_url_wget() { 0) break; ;; 1) if [ "${_rfuw_urls_count}" -ge 1 ]; then - rtl_log_msg "warning" "${MSG_rtl_fetch_lockfail_retryurl}" "${_rfuw_url}"; + rtl_log_msgV "warning" "${MSG_rtl_fetch_lockfail_retryurl}" "${_rfuw_url}"; else - rtl_log_msg "fatal" "${MSG_rtl_fetch_lockfail}" "${_rfuw_url}"; + rtl_log_msgV "fatal" "${MSG_rtl_fetch_lockfail}" "${_rfuw_url}"; rtl_fileop rm "${_rfuw_target_fname_full}"; break; fi; ;; 2) if [ "${_rfuw_urls_count}" -ge 1 ]; then - rtl_log_msg "warning" "${MSG_rtl_fetch_hashfail_retryurl}" "${_rfuw_url}" "${_rfuw_sha256sum_src}"; + rtl_log_msgV "warning" "${MSG_rtl_fetch_hashfail_retryurl}" "${_rfuw_url}" "${_rfuw_sha256sum_src}"; else if _rfuw_sha256sum_target="$(sha256sum "${_rfuw_target_fname_full}" |\ awk '{print $1}' 2>/dev/null)"; then - rtl_log_msg "fatal" "${MSG_rtl_fetch_hashfail1}" "${_rfuw_url}" "${_rfuw_sha256sum_src}" "${_rfuw_sha256sum_target}"; + rtl_log_msgV "fatal" "${MSG_rtl_fetch_hashfail1}" "${_rfuw_url}" "${_rfuw_sha256sum_src}" "${_rfuw_sha256sum_target}"; else - rtl_log_msg "fatal" "${MSG_rtl_fetch_hashfail2}" "${_rfuw_url}" "${_rfuw_sha256sum_src}"; + rtl_log_msgV "fatal" "${MSG_rtl_fetch_hashfail2}" "${_rfuw_url}" "${_rfuw_sha256sum_src}"; fi; rtl_fileop rm "${_rfuw_target_fname_full}"; break; fi; ;; *) if [ "${_rfuw_urls_count}" -ge 1 ]; then - rtl_log_msg "warning" "${MSG_rtl_fetch_fail_retryurl}" "${_rfuw_url}" "$((${_rfuw_rc}-2))"; + rtl_log_msgV "warning" "${MSG_rtl_fetch_fail_retryurl}" "${_rfuw_url}" "$((${_rfuw_rc}-2))"; else - rtl_log_msg "fatal" "${MSG_rtl_fetch_fail}" "${_rfuw_url}" "$((${_rfuw_rc}-2))"; + rtl_log_msgV "fatal" "${MSG_rtl_fetch_fail}" "${_rfuw_url}" "$((${_rfuw_rc}-2))"; rtl_fileop rm "${_rfuw_target_fname_full}"; break; fi; ;; diff --git a/subr.rtl/rtl_fileop.subr b/subr.rtl/rtl_fileop.subr index 10d741c5..0f999ad7 100644 --- a/subr.rtl/rtl_fileop.subr +++ b/subr.rtl/rtl_fileop.subr @@ -13,7 +13,7 @@ rtlp_fileop_check() { }; rtlp_fileop_log() { - rtl_log_msg "fileop" "0;${1}"; + rtl_log_msgV "fileop" "0;${1}"; }; # @@ -35,14 +35,14 @@ rtl_fileop() { case "${_rf_op}" in cd) if [ \( "${1:+1}" != 1 \) -o ! \( -L "${1}" -o -e "${1}" \) ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invalid_dir}" "${1}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invalid_dir}" "${1}"; elif rtlp_fileop_check "${PREFIX:-}" "${1}"; then rtlp_fileop_log "Changing working directory to \`${1}'."; cd -- "${1}"; _rf_rc="${?}"; fi; ;; chmod) if [ "${#}" -lt 2 ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm_chmod}" "${*}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm_chmod}" "${*}"; elif _rf_mode="${1}" && shift\ && rtlp_fileop_check "${PREFIX:-}" "${*}"; then rtlp_fileop_log "Changing file mode bits of \`${*}' to \`${_rf_mode}'."; @@ -50,7 +50,7 @@ rtl_fileop() { fi; ;; chgrp) if [ "${#}" -lt 2 ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm_chgrp}" "${*}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm_chgrp}" "${*}"; elif _rf_group="${1}" && shift\ && rtlp_fileop_check "${PREFIX:-}" "${*}"; then rtlp_fileop_log "Changing file group of \`${*}' to \`${_rf_group}'."; @@ -58,7 +58,7 @@ rtl_fileop() { fi; ;; chown) if [ "${#}" -lt 2 ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm_chown}" "${*}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm_chown}" "${*}"; elif _rf_owner="${1}" && shift\ && rtlp_fileop_check "${PREFIX:-}" "${*}"; then rtlp_fileop_log "Changing file owner of \`${*}' to \`${_rf_owner}'."; @@ -67,7 +67,7 @@ rtl_fileop() { cp_follow) if [ "${#}" -lt 2 ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm_cp_follow}" "${*}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm_cp_follow}" "${*}"; elif rtlp_fileop_check "${PREFIX:-}" "${*}"; then _rf_src="${*}"; _rf_src="${_rf_src% *}"; _rf_dst="${*}"; _rf_dst="${_rf_dst##* }"; @@ -76,7 +76,7 @@ rtl_fileop() { fi; ;; cp) if [ "${#}" -lt 2 ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm_cp}" "${*}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm_cp}" "${*}"; elif rtlp_fileop_check "${PREFIX:-}" "${*}"; then _rf_src="${*}"; _rf_src="${_rf_src% *}"; _rf_dst="${*}"; _rf_dst="${_rf_dst##* }"; @@ -86,7 +86,7 @@ rtl_fileop() { install) if [ "${#}" -lt 2 ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm_install}" "${*}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm_install}" "${*}"; else rtl_lindexV \$_rf_dst -1 "${@}"; rtl_lrangeV \$_rf_install_args 0 1 "${@}"; @@ -100,7 +100,7 @@ rtl_fileop() { ln_symbolic) if [ \( "${1:+1}" != 1 \) -o \( "${2:+1}" != 1 \) ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm_ln_symbolic}" "${*}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm_ln_symbolic}" "${*}"; elif rtlp_fileop_check "${PREFIX:-}" "${2}"; then if rtl_fileop test "${2}"; then rtl_fileop rm "${2}"; @@ -112,14 +112,14 @@ rtl_fileop() { fi; ;; mv) if [ \( "${1:+1}" != 1 \) -o \( "${2:+1}" != 1 \) ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm_mv}" "${*}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm_mv}" "${*}"; elif rtlp_fileop_check "${PREFIX:-}" "${1}" "${2}"; then rtlp_fileop_log "Moving \`${1}' to \`${2}' w/ -fs"; mv -f -- "${1}" "${2}"; _rf_rc="${?}"; fi; ;; touch) if [ "${1:+1}" != 1 ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm_touch}" "${*}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm_touch}" "${*}"; elif rtlp_fileop_check "${PREFIX:-}" "${1}"; then rtlp_fileop_log "Touching file \`${1}'${2:+ w/ timestamp \`${2}\'}."; touch ${2:+-t "${2}"} -- "${1}"; _rf_rc="${?}"; @@ -128,7 +128,7 @@ rtl_fileop() { mkdir|mkfifo|rm|source|source_opt|test) while [ \( "${?}" -eq 0 \) -a \( ""${#}"" -gt 0 \) ]; do if [ "${1:+1}" != 1 ]; then - rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm}" "${_rf_op}" "${*}"; + rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm}" "${_rf_op}" "${*}"; elif [ "${_rf_op}" = mkdir ]\ && [ ! -d "${1}" ]\ && rtlp_fileop_check "${PREFIX:-}" "${1}"; then @@ -166,7 +166,7 @@ rtl_fileop() { fi; shift; done; ;; - *) rtl_log_msg "fatalexit" "${MSG_rtl_fileop_invparm_fileop}" "${*}"; ;; + *) rtl_log_msgV "fatalexit" "${MSG_rtl_fileop_invparm_fileop}" "${*}"; ;; esac; diff --git a/subr.rtl/rtl_install_v2.subr b/subr.rtl/rtl_install_v2.subr index 480121f8..da4c3090 100644 --- a/subr.rtl/rtl_install_v2.subr +++ b/subr.rtl/rtl_install_v2.subr @@ -303,7 +303,7 @@ rtlp_install_v2_rc() { if [ "${_ri2r_nflag}" -eq 1 ]\ || [ "${_ri2r_vflag}" -gt 0 ]; then - rtl_log_msg "install" "${MSG_rtl_install_v2_rc}" "${_ri2r_fn}${_ri2r_fn:+ ${*}}"; + rtl_log_msgV "install" "${MSG_rtl_install_v2_rc}" "${_ri2r_fn}${_ri2r_fn:+ ${*}}"; fi; if [ "${_ri2r_nflag}" -eq 0 ]; then "${_ri2r_fn}" "${@}"; _ri2r_rc="${?}"; diff --git a/subr.rtl/rtl_list.subr b/subr.rtl/rtl_list.subr index 5934126f..36bc77e9 100644 --- a/subr.rtl/rtl_list.subr +++ b/subr.rtl/rtl_list.subr @@ -34,6 +34,8 @@ rtl_lassignV() { # @_rlist: inout reference to list # @_litem_new: list item(s) to concatenate with # @[_sep]: optional single non-zero, possibly multi-character, separator +# N.B.: If @_litem_new is a list of multiple items, the separator of that list +# must be the same as @[_sep] # # Returns: zero (0) on success, non-zero (>0) on failure # @@ -49,6 +51,8 @@ rtl_lconcat() { # @[_sep]: optional single non-zero, possibly multi-character, separator # # Returns: zero (0) on success, non-zero (>0) on failure +# N.B.: If @_litem_new is a list of multiple items, the separator of that list +# must be the same as @[_sep] # rtl_lconcat2() { local _rlc2_rlist_new="${1#\$}" _rlc2_rlist="${2#\$}" _rlc2_litem_new="${3}" \ diff --git a/subr.rtl/rtl_log.subr b/subr.rtl/rtl_log.subr index 1254916a..69e620bf 100644 --- a/subr.rtl/rtl_log.subr +++ b/subr.rtl/rtl_log.subr @@ -16,6 +16,13 @@ RTLP_LOG_TERMINAL_COLOURS="$(tput colors 2>/dev/null)"; # Private subroutines # +# +# rtlp_log_msg_get_attr() - get attributes e.g. ANSI escape sequences for single log tag +# @_rattr: out reference to attributes e.g. ANSI escape sequences +# @_tag: tag to log message at +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtlp_log_msg_get_attr() { local _rplmga_rattr="${1#\$}" _rplmga_tag="${2}" \ _rplmga_attr="" _rplmga_attr_state="" \ @@ -57,7 +64,16 @@ rtlp_log_msg_get_attr() { return 0; }; -rtlp_log_printf() { +# +# rtlp_log_printfV() - print single message to log file +# @_attr: attributes e.g. ANSI escape sequences to log message with +# @_fmt_pfx: printf(1) format string prefix +# @_fmt: printf(1) format string +# @...: parameters to printf(1) w/ @_fmt +# +# Returns: zero (0) on success, non-zero (>0) on failure +# +rtlp_log_printfV() { local _rplp_attr="${1}" _rplp_fmt_pfx="${2}" \ _rplp_fmt="${3#*;}" _rplp_fmt_argc="${3%%;*}"; shift 3; @@ -66,7 +82,7 @@ rtlp_log_printf() { if [ "${_rplp_fmt_argc}" -eq 0 ]; then shift "${#}"; else - rtlp_log_printf "" "" "0;==> FIXME TODO XXX MESSAGE STRING ARGUMENT COUNT MISMATCH\n"; + rtlp_log_printfV "" "" "0;==> FIXME TODO XXX MESSAGE STRING ARGUMENT COUNT MISMATCH\n"; fi; fi; _rplp_msg="$(printf "${_rplp_fmt_pfx}${_rplp_fmt}" "${@}")"; @@ -86,11 +102,23 @@ rtlp_log_printf() { # Public subroutines # +# +# rtl_log_clear_tags() - clear all log tags +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_log_clear_tags() { - RTLP_LOG_TAGS=""; return 0; + RTLP_LOG_TAGS=""; + return 0; }; -rtl_log_enable_tags() { +# +# rtl_log_enable_tagsV() - enable log tags +# @...: list of tags to enable as positional parameters +# +# Returns: zero (0) on success, non-zero (>0) on failure +# +rtl_log_enable_tagsV() { local IFS=","; set -- ${*}; while [ "${#}" -gt 0 ]; do @@ -101,17 +129,24 @@ rtl_log_enable_tags() { return 0; }; +# +# rtl_log_env_vars() - log all environment variables to log file +# @_tag: tag to log environment variables at +# @_type: type string printed in log message header +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_log_env_vars() { local _rlev_tag="${1}" _rlev_type="${2}" \ _rlev_arg_len_max=0 _rlev_list="" _rlev_msg="" _rlev_msg_=""; shift 2; - rtl_log_msg "${_rlev_tag}" "${MSG_rtl_log_vars_header}" "${_rlev_type}"; + rtl_log_msgV "${_rlev_tag}" "${MSG_rtl_log_vars_header}" "${_rlev_type}"; _rlev_list="${@}"; rtl_lmax \$_rlev_list \$_rlev_arg_len_max; while [ "${#}" -gt 0 ]; do rtl_get_var_unsafe \$_rlev_msg "${1#*=}"; rtl_llift2 \$_rlev_msg \$_rlev_msg_ "" " "; - rtl_log_msg "${_rlev_tag}" \ + rtl_log_msgV "${_rlev_tag}" \ "2;%${_rlev_arg_len_max}.${_rlev_arg_len_max}s=%s" \ "${1%%=*}" "${_rlev_msg_}"; shift; @@ -119,7 +154,20 @@ rtl_log_env_vars() { return 0; }; -rtl_log_msg() { +# +# rtl_log_msgV() - log message to log file +# @_tag: tag to log message at +# @_fmt: printf(1) format string +# @...: parameters to printf(1) w/ @_fmt +# +# Returns: zero (0) on success, non-zero (>0) on failure +# N.B.: Optional attributes e.g. ANSI escape sequences w/ which the the log message is to +# be printed are taken from the variable corresponding to @_tag named "LOG_TAG_<@_tag>", +# if present/set. +# +# @_tag must have previously been enabled w/ rtl_log_enable_tagsV() to be logged at all. +# +rtl_log_msgV() { local _rlm3_tag="${1}" _rlm3_fmt="${2}" \ _rlm3_attr="" _rlm3_date_now=0 _rlm3_exitfl=0 shift 2; @@ -132,11 +180,8 @@ rtl_log_msg() { || rtl_lmatch \$RTLP_LOG_TAGS "${_rlm3_tag}" ","; then rtlp_log_msg_get_attr \$_rlm3_attr "${_rlm3_tag}"; - if [ "${_rlm3_attr:+1}" != 1 ]; then - rtlp_log_printf "" "" "0;==> FIXME TODO XXX UNKNOWN TAG \`${_rlm3_tag}' PASSED TO rtl_log_msg()\n"; - fi; rtl_date \$_rlm3_date_now; - rtlp_log_printf "${_rlm3_attr}" "==> ${_rlm3_date_now} " "${_rlm3_fmt}" "${@}"; + rtlp_log_printfV "${_rlm3_attr}" "==> ${_rlm3_date_now} " "${_rlm3_fmt}" "${@}"; if [ "${_rlm3_exitfl}" -eq 1 ]; then exit 1; fi; @@ -144,11 +189,23 @@ rtl_log_msg() { return 0; }; +# +# rtl_log_set_fname() - set log file pathname +# @_fname: pathname to new log file +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_log_set_fname() { RTLP_LOG_FNAME="${1}"; return 0; }; +# +# rtl_log_set_no_attr() - set or clear no ANSI escape sequences in log file flag +# @_flag: either 0 to set or 1 to clear no ANSI escape sequences in log file flag +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_log_set_no_attr() { RTLP_LOG_NO_ATTR="${1}"; return 0; diff --git a/subr.rtl/rtl_platform.subr b/subr.rtl/rtl_platform.subr index 35229a98..9bcf0734 100644 --- a/subr.rtl/rtl_platform.subr +++ b/subr.rtl/rtl_platform.subr @@ -3,7 +3,14 @@ # set +o errexit -o noglob -o nounset is assumed. # -rtl_check_prereqs() { +# +# rtl_check_prereqsV() - check for existence of list of commands +# @_rstatus: out reference to status string +# @...: commands list as positional parameters +# +# Returns: zero (0) on success, non-zero (>0) on failure +# +rtl_check_prereqsV() { local _rcp_rstatus="${1#\$}" \ _rcp_cmd="" _rcp_cmds_missing="" _rcp_rc=0; shift; @@ -20,6 +27,12 @@ rtl_check_prereqs() { return "${_rcp_rc}"; }; +# +# rtl_clean_env() - unset environment variables w/ exceptions +# @_env_vars_except: list of environment variables to keep +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_clean_env() { local _rce_env_vars_except="${1}" \ _rce_env_var="" _rce_env_vars="" _rce_env_vars_unset=""; @@ -38,6 +51,13 @@ rtl_clean_env() { return 0; }; +# +# rtl_get_cpu_count() - obtain CPU count +# @_rstatus: out reference to status string +# @_rcount: out reference to CPU count +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_get_cpu_count() { local _rgcc_rstatus="${1#\$}" _rgcc_rcount="${2#\$}" \ _rgcc_line="" _rgcc_ncpus=0 _rgcc_rc=0 _rgcc_sname=""; @@ -66,8 +86,19 @@ rtl_get_cpu_count() { return "${_rgcc_rc}"; }; +# +# rtl_get_var_unsafe() - get value of variable +# @_rvval: out reference to variable value +# @[-u]: optionally convert variable name to upper case +# @_vname: variable name +# +# Returns: zero (0) on success, non-zero (>0) on failure +# N.B.: This function is *unsafe* and impossible to implement otherwise w/o filtering @_vname +# and implicitly allows for code execution and other undefined behaviour via @_vname. +# Do *not* pass untrusted input through @_vname. +# rtl_get_var_unsafe() { - local _rgvu_rvname_out="${1#\$}" \ + local _rgvu_rvval="${1#\$}" \ _rgvu_vname=""; shift; @@ -76,17 +107,33 @@ rtl_get_var_unsafe() { else _rgvu_vname="${1}"; fi; - eval ${_rgvu_rvname_out}="\${${_rgvu_vname}:-}"; + eval ${_rgvu_rvval}="\${${_rgvu_vname}:-}"; return 0; }; -rtl_get_vars_fast() { - local _rgvf_pattern="${1}"; +# +# rtl_get_vars_unsafe_fast() - get values of multiple variables w/ pattern +# @_pattern: pattern to match against set output +# +# Returns: zero (0) on success, non-zero (>0) on failure, matching variable values on stdout +# N.B.: This function is *unsafe* and impossible to implement otherwise w/o parsing set +# output properly and may produce spurious data. +# +rtl_get_vars_unsafe_fast() { + local _rgvuf_pattern="${1}"; - set | awk -F= '/'"${_rgvf_pattern}"'/{print $1}' | sort; + set | awk -F= '/'"${_rgvuf_pattern}"'/{print $1}' | sort; return 0; }; +# +# rtl_kill_tree() - kill tree of processes +# @_rpids: inout reference to list of PIDs +# @_pid: top-level PID +# @_signal: signal(7) to kill with +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_kill_tree() { local _rkt_rpids="${1#\$}" _rkt_pid="${2}" _rkt_signal="${3:-TERM}" \ _rkt_pid_child="" _rkt_pids=""; @@ -104,64 +151,64 @@ rtl_kill_tree() { return 0; }; -rtl_prompt() { - local rp_fmt="${1}" rp_choice=""; shift; - - printf "${rp_fmt}? (y|N) " "${@}"; - read -r rp_choice; - case "${rp_choice}" in - [yY]) rp_choice=1; ;; - *) rp_choice=0; ;; - esac; - return "${rp_choice}"; -}; - -rtl_rc() { - local _rr_nflag="${1}" _rr_cmd="${2}"; +# +# rtl_run_cmdlineV() - run command line w/ field splitting applied +# @_sep: single non-zero, possibly multi-character, separator +# @_cmd: command name +# @...: command arguments as positional parameters +# +# Returns: zero (0) on success, non-zero (>0) on failure +# N.B.: This is required in situations where any of the command arguments 1) are passed from +# and as a single, expanded parameter (e.g. "${MAKEFLAGS:-}") 2) the value of the parameter +# contains multiple parameters separated by @_sep that must be passed as separate arguments +# to @_cmd. +# +rtl_run_cmdlineV() { + local _rrc_sep="${1}" _rrc_cmd="${2}" \ + _rrc_cmdline="" _rrc_rc="" IFS; shift 2; - case "${_rr_nflag}" in - 1) if [ "${#}" -gt 0 ]; then - rtl_log_msg "verbose" "${MSG_rtl_platform_rc1}" "${_rr_cmd}" "${*}"; - else - rtl_log_msg "verbose" "${MSG_rtl_platform_rc2}" "${_rr_cmd}"; - fi; ;; - *) "${_rr_cmd}" "${@}"; ;; - esac; - return 0; -}; - -rtl_run_cmd_unsplit() { - local _rrcu_cmd="${1}" \ - _rrcu_cmdline="" _rrcu_rc="" IFS; - shift; - while [ ${#} -gt 0 ]; do [ "${1:+1}" = 1 ] &&\ - _rrcu_cmdline="${_rrcu_cmdline:+${_rrcu_cmdline}:}${1}"; + _rrc_cmdline="${_rrc_cmdline:+${_rrc_cmdline}${_rrc_sep}}${1}"; shift; done; - IFS=:; ${_rrcu_cmd} ${_rrcu_cmdline}; _rrcu_rc=$?; - return ${_rrcu_rc}; + IFS="${_rrc_sep}"; ${_rrc_cmd} ${_rrc_cmdline}; _rrc_rc=$?; + return ${_rrc_rc}; }; -rtl_set_var_from_cmdline() { - local _rsvfc_rstatus="${1#\$}" _rsvfc_arg="${2}" \ - _rsvfc_rc=0 _rsvfc_vname="" _rsvfc_vval=""; +# +# rtl_set_var_from_spec() - set variable from name-value specification +# @_rstatus: out reference to status string +# @_arg: variable name-value specification separated by single "=" (e.g. name=value) +# +# Returns: zero (0) on success, non-zero (>0) on failure +# +rtl_set_var_from_spec() { + local _rsvfs_rstatus="${1#\$}" _rsvfs_arg="${2}" \ + _rsvfs_rc=0 _rsvfs_vname="" _rsvfs_vval=""; - _rsvfc_vname="${_rsvfc_arg%%=*}"; - _rsvfc_vval="${_rsvfc_arg#*=}"; + _rsvfs_vname="${_rsvfs_arg%%=*}"; + _rsvfs_vval="${_rsvfs_arg#*=}"; - if [ "${_rsvfc_vval:+1}" != 1 ]; then - _rsvfc_rc=1; - rtl_setrstatus "${_rsvfc_rstatus}" 'empty value specified for \${'"${_rsvfc_vname}"'}.'; + if [ "${_rsvfs_vval:+1}" != 1 ]; then + _rsvfs_rc=1; + rtl_setrstatus "${_rsvfs_rstatus}" 'empty value specified for \${'"${_rsvfs_vname}"'}.'; else - rtl_set_var_unsafe "${_rsvfc_vname}" "${_rsvfc_vval}"; + rtl_set_var_unsafe "${_rsvfs_vname}" "${_rsvfs_vval}"; fi; - return "${_rsvfc_rc}"; + return "${_rsvfs_rc}"; }; -rtl_set_vars() { +# +# rtl_set_var() - set variable from variables w/ template +# @_vars_set_vname: list of variable names +# @_vname_dst: variable name to set +# @_vname_src_tmpls: variable name template (e.g. "DEFAULT PKG_") +# +# Returns: zero (0) on success, non-zero (>0) on failure +# +rtl_set_var() { local _rsv_vars_set_vname="${1}" _rsv_vname_dst="${2}" _rsv_vname_src_tmpls="${3}" \ _rsv_vars_set_old="" _rsv_vars_set_tmp="" _rsv_vname_src="" _rsv_vnames_src=""; diff --git a/subr.rtl/rtl_state.subr b/subr.rtl/rtl_state.subr index d5cd8b1e..3deec599 100644 --- a/subr.rtl/rtl_state.subr +++ b/subr.rtl/rtl_state.subr @@ -3,52 +3,83 @@ # set +o errexit -o noglob -o nounset is assumed. # +# +# rtl_state_clear() - clear state for item +# @_workdir: pathname to directory containing state files +# @_item_name: name of item to clear state for +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_state_clear() { - local _rsc_workdir="${1}" _rsc_pkg_name="${2}" \ - _rsc_pkg_fname=""; + local _rsc_workdir="${1}" _rsc_item_name="${2}" \ + _rsc_item_fname=""; - for _rsc_pkg_fname in $( + for _rsc_item_fname in $( find "${_rsc_workdir}" \ -maxdepth 1 \ -mindepth 1 \ - -name .${_rsc_pkg_name}.\* \ + -name .${_rsc_item_name}.\* \ -type f); do - rtl_fileop rm "${_rsc_pkg_fname}"; + rtl_fileop rm "${_rsc_item_fname}"; done; return 0; }; +# +# rtl_state_set() - set state for item +# @_workdir: pathname to directory containing state files +# @_item_name: name of item to set state for +# @_state: state to set +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_state_set() { - local _rss_workdir="${1}" _rss_pkg_fname="${2}" _rss_build_step="${3}" \ - _rss_done_fname_pfx="${1}/.${2}"; + local _rss_workdir="${1}" _rss_item_name="${2}" _rss_state="${3}" \ + _rss_done_name_pfx="${1}/.${2}"; shift 3; - rtl_fileop touch "${_rss_done_fname_pfx}.${_rss_build_step}"; + rtl_fileop touch "${_rss_done_name_pfx}.${_rss_state}"; while [ ${#} -ge 1 ]; do if [ "${#1}" -gt 0 ]; then - rtl_fileop rm "${_rss_done_fname_pfx}.${1}"; + rtl_fileop rm "${_rss_done_name_pfx}.${1}"; fi; shift; done; return 0; }; +# +# rtl_state_test() - test state(s) for item +# @_workdir: pathname to directory containing state files +# @_item_name: name of item to set state for +# @_states: state(s) to test for +# @[_lforce]: one of "ALL" (force all states to test as set,) "LAST" or "" (test all states,) +# or exclusive list of states to force to test as set +# +# Returns: zero (0) if any of state(s) set, non-zero (>0) if none of state(s) set +# rtl_state_test() { - local _rst_workdir="${1}" _rst_pkg_name="${2}" _rst_build_steps="${3}" \ - _rst_restart_at="${4:-}" _rst_build_step="" _rst_done_fname="" \ - IFS="," _rst_rc=0; - - for _rst_build_step in ${_rst_build_steps}; do - _rst_done_fname="${_rst_workdir}/.${_rst_pkg_name}.${_rst_build_step}"; - if [ "${_rst_restart_at:+1}" != 1 ]\ - || [ "${_rst_restart_at}" = "LAST" ]; then - rtl_fileop test "${_rst_done_fname}"; _rst_rc="${?}"; - elif [ "${_rst_restart_at}" = "ALL" ]; then - _rst_rc=1; - else - rtl_lmatch \$_rst_restart_at "${_rst_build_step}" ","; + local _rst_workdir="${1}" _rst_item_name="${2}" \ + _rst_states="${3}" _rst_lforce="${4:-}" \ + _rst_state="" _rst_done_fname="" IFS="," _rst_rc=0; + + for _rst_state in ${_rst_states}; do + _rst_done_fname="${_rst_workdir}/.${_rst_item_name}.${_rst_state}"; + + case "${_rst_lforce}" in + ALL) + _rst_rc=1; ;; + ""|LAST) + rtl_fileop test "${_rst_done_fname}"; _rst_rc="${?}"; ;; + *) + rtl_lmatch \$_rst_lforce "${_rst_state}" ","; _rst_rc=$((${?} ? 0 : 1)); - fi; [ "${_rst_rc}" -eq 0 ] && break; + ;; + esac; + + if [ "${_rst_rc}" -eq 0 ]; then + break; + fi; done; return "${_rst_rc}"; }; -- cgit v1.2.3