From 550c1831733f61c4af8e32179dc7df39bcd7a1de Mon Sep 17 00:00:00 2001 From: LucĂ­a Andrea Illanes Albornoz Date: Mar 20 2023 18:26:38 +0000 Subject: Document subr.rtl/*.subr functions, pt. I. --- diff --git a/subr.pkg/pkg_install_libs.subr b/subr.pkg/pkg_install_libs.subr index 79a1bbf..d19c956 100644 --- a/subr.pkg/pkg_install_libs.subr +++ b/subr.pkg/pkg_install_libs.subr @@ -33,7 +33,7 @@ pkgp_install_libs_shared_link() { }; pkgp_install_libs_shared() { - local _ppils_head="" _ppils_lib_dst_path="" _ppils_lib_name="" \ + local _ppils_postfix="" _ppils_lib_dst_path="" _ppils_lib_name="" \ _ppils_lib_src_path="" _ppils_so_dst_dir="" _ppils_so_src_path=""; if [ "${PKG_BUILD_TYPE}" != "host" ]; then @@ -42,8 +42,8 @@ pkgp_install_libs_shared() { \( -name "*.so" -or -name "*.so.*" \) -print); do if [ "$(readlink -f "${_ppils_so_src_path}")" != "/dev/null" ]\ - && rtl_head "[0-9.]" "${_ppils_so_src_path##*.so}" \$_ppils_head\ - && [ "${_ppils_head:+1}" != 1 ]; then + && rtl_remove_postfix "[0-9.]" "${_ppils_so_src_path##*.so}" \$_ppils_postfix\ + && [ "${_ppils_postfix:+1}" != 1 ]; then case "${_ppils_so_src_path}" in *.so) _ppils_lib_src_path="${_ppils_so_src_path%%.so}.lib.a"; ;; *.so.*) _ppils_lib_src_path="${_ppils_so_src_path%%.so.*}.${_ppils_so_src_path##*.so.}.lib.a"; ;; diff --git a/subr.rtl/rtl_complex.subr b/subr.rtl/rtl_complex.subr index 0a475d0..64fcea5 100644 --- a/subr.rtl/rtl_complex.subr +++ b/subr.rtl/rtl_complex.subr @@ -4,9 +4,10 @@ # # -# rtl_export_vars() - -# @_unsetfl: -# +# rtl_export_vars() - export or unset list of variables +# @[-u]: unset instead of exporting variables +# @...: list of variable name-value pairs +# # Returns: zero (0) on success, non-zero (>0) on failure # rtl_export_vars() { @@ -30,21 +31,14 @@ rtl_export_vars() { return 0; }; -rtl_head() { - local _rh_pattern="${1}" _rh_s="${2}" _rh_rs_out="${3#\$}"; - - while true; do - if [ "${_rh_s%%${_rh_pattern}}" = "${_rh_s}" ]; then - break; - else - _rh_s="${_rh_s%%${_rh_pattern}}"; - fi; - done; - - eval ${_rh_rs_out}='${_rh_s}'; - return 0; -}; - +# +# rtl_percentage() - calculate percentage of two numbers +# @_in: input number +# @_max: input maximum +# @_rs_out: out reference to percentage number +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_percentage() { local _rp_in="${1}" _rp_max="${2}" _rp_rs_out="${3#\$}" \ _rp_perc; @@ -56,6 +50,14 @@ rtl_percentage() { return 0; }; +# +# rtl_percentage2() - calculate percentage of two numbers +# @_rin: in reference to input number +# @_rmax: in reference to input maximum +# @_rs_out: out reference to percentage number +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_percentage2() { local _rp_rin="${1#\$}" _rp_rmax="${2#\$}" _rp_rs_out="${3#\$}" \ _rp_in=0 _rp_max=0 _rp_perc; @@ -70,12 +72,19 @@ rtl_percentage2() { return 0; }; +# +# rtl_sunset() - unset variables +# @_rset: in reference to list of variables to unset +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_sunset() { - local _rs_rset="${1#\$}" _rs_kname="" IFS=" "; + local _rs_rset="${1#\$}" \ + IFS=" "; eval set -- "\${${_rs_rset}}"; while [ "${#}" -gt 0 ]; do - unset "${_rs_rset}${_rs_kname}"; shift; + unset "${_rs_rset}"; shift; done; unset "${_rs_rset}"; return 0; diff --git a/subr.rtl/rtl_fetch.subr b/subr.rtl/rtl_fetch.subr index ab3bd4e..7946b7c 100644 --- a/subr.rtl/rtl_fetch.subr +++ b/subr.rtl/rtl_fetch.subr @@ -3,21 +3,30 @@ # set +o errexit -o noglob -o nounset is assumed. # +# +# rtl_fetch_clean_dlcache() - clean download cache for single package +# @_dlcachedir: absolute pathname to download cache directory +# @_name: single item name +# @_fname_base: optional single item archive filename +# @_urls_git: optional list of item Git URL(s) +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_fetch_clean_dlcache() { - local _pfdcd_dlcachedir="${1}" _pfdcd_pkg_name="${2}" \ - _pfdcd_pkg_fname="${3}" _pfdcd_pkg_urls_git="${4}" \ + local _pfdcd_dlcachedir="${1}" _pfdcd_name="${2}" \ + _pfdcd_fname_base="${3}" _pfdcd_urls_git="${4}" \ _pfdcd_fname="" _pfdcd_skipfl=0 _pfdcd_url_spec="" \ _pfdcd_url_subdir=""; for _pfdcd_fname in \ - $(cd "${_pfdcd_dlcachedir}/${_pfdcd_pkg_name}" 2>/dev/null && + $(cd "${_pfdcd_dlcachedir}/${_pfdcd_name}" 2>/dev/null && find -maxdepth 1 -mindepth 1 \ - ${_pfdcd_pkg_fname:+-not -name "${_pfdcd_pkg_fname}"} \ - ${_pfdcd_pkg_fname:+-not -name "${_pfdcd_pkg_fname}.fetched"}); + ${_pfdcd_fname_base:+-not -name "${_pfdcd_fname_base}"} \ + ${_pfdcd_fname_base:+-not -name "${_pfdcd_fname_base}.fetched"}); do _pfdcd_fname="${_pfdcd_fname#./}"; _pfdcd_skipfl=0; - for _pfdcd_url_spec in ${_pfdcd_pkg_urls_git}; do + for _pfdcd_url_spec in ${_pfdcd_urls_git}; do _pfdcd_url_subdir="${_pfdcd_url_spec%%=*}"; _pfdcd_url_subdir="${_pfdcd_url_subdir##*/}"; if [ "${_pfdcd_fname%.git}" = "${_pfdcd_url_subdir}" ]; then _pfdcd_skipfl=1; break; @@ -25,8 +34,8 @@ rtl_fetch_clean_dlcache() { done; if [ "${_pfdcd_skipfl}" -eq 0 ]; then - _pfdcd_fname="${_pfdcd_dlcachedir}/${_pfdcd_pkg_name}/${_pfdcd_fname}"; - rtl_log_msg "verbose" "${MSG_rtl_fetch_rm_redundant}" "${_pfdcd_fname}" "${_pfdcd_pkg_name}"; + _pfdcd_fname="${_pfdcd_dlcachedir}/${_pfdcd_name}/${_pfdcd_fname}"; + rtl_log_msg "verbose" "${MSG_rtl_fetch_rm_redundant}" "${_pfdcd_fname}" "${_pfdcd_name}"; rtl_fileop rm "${_pfdcd_fname}"; fi; done; @@ -34,17 +43,25 @@ rtl_fetch_clean_dlcache() { return 0; }; +# +# rtl_fetch_dlcache_subdir() - create download cache subdirectory for single package +# @_dlcachedir: absolute pathname to download cache directory +# @_name: single item name +# @_inherit_from: optional name of item @_name inherits from +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_fetch_dlcache_subdir() { - local _rfds_dlcache_dir="${1}" _rfds_name="${2}" _rfds_pkg_inherit_from="${3}"; + local _rfds_dlcachedir="${1}" _rfds_name="${2}" _rfds_inherit_from="${3}"; - if [ "${_rfds_pkg_inherit_from:+1}" = 1 ]\ - && ! [ -e "${_rfds_dlcache_dir}/${_rfds_name}" ]\ - && ! rtl_fileop ln_symbolic "${_rfds_pkg_inherit_from}" "${_rfds_dlcache_dir}/${_rfds_name}"; + if [ "${_rfds_inherit_from:+1}" = 1 ]\ + && ! [ -e "${_rfds_dlcachedir}/${_rfds_name}" ]\ + && ! rtl_fileop ln_symbolic "${_rfds_inherit_from}" "${_rfds_dlcachedir}/${_rfds_name}"; then return 1; - elif [ "${_rfds_pkg_inherit_from:+1}" != 1 ]\ - && ! [ -e "${_rfds_dlcache_dir}/${_rfds_name}" ]\ - && ! rtl_fileop mkdir "${_rfds_dlcache_dir}/${_rfds_name}"; + elif [ "${_rfds_inherit_from:+1}" != 1 ]\ + && ! [ -e "${_rfds_dlcachedir}/${_rfds_name}" ]\ + && ! rtl_fileop mkdir "${_rfds_dlcachedir}/${_rfds_name}"; then return 1; else diff --git a/subr.rtl/rtl_fetch_git.subr b/subr.rtl/rtl_fetch_git.subr index 13eb672..c368225 100644 --- a/subr.rtl/rtl_fetch_git.subr +++ b/subr.rtl/rtl_fetch_git.subr @@ -3,19 +3,32 @@ # set +o errexit -o noglob -o nounset is assumed. # +# +# rtlp_fetch_url_git() - fetch Git URL for item +# @_dlcachedir: absolute pathname to download cache directory +# @_git_args: optional argument string to pass to git(1) +# @_git_branch: name of Git branch +# @_mirrors: optional list of mirror base URLs +# @_name: single item name +# @_target_subdir: target subdirectory name +# @_target_dname: target directory name +# @_url: single Git URL +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtlp_fetch_url_git() { - local _rpfug_cache_dname="${1}" _rpfug_git_args="${2}" _rpfug_git_branch="${3}" \ - _rpfug_mirrors="${4}" _rpfug_pkg_name="${5}" _rpfug_subdir="${6}" \ - _rpfug_tgtdir="${7}" _rpfug_url="${8}" \ - _rpfug_cache_dname_full="" _rpfug_clonefl=0 _rpfug_dname="" \ + local _rpfug_dlcachedir="${1}" _rpfug_git_args="${2}" _rpfug_git_branch="${3}" \ + _rpfug_mirrors="${4}" _rpfug_name="${5}" _rpfug_target_subdir="${6}" \ + _rpfug_target_dname="${7}" _rpfug_url="${8}" \ + _rpfug_dlcachedir_full="" _rpfug_clonefl=0 _rpfug_dname="" \ _rpfug_git_pull_log_fname="" _rpfug_oldpwd="" _rpfug_url_base=""; - _rpfug_cache_dname_full="${_rpfug_cache_dname}/${_rpfug_subdir##*/}"; + _rpfug_dlcachedir_full="${_rpfug_dlcachedir}/${_rpfug_target_subdir##*/}"; (set -o errexit -o noglob -o nounset; rtl_flock_acquire 4 || exit "${?}"; - trap "rm -f \"${_rpfug_cache_dname_full%%[/]}.fetching\"" EXIT; - if [ -e "${_rpfug_cache_dname_full}" ]; then - (rtl_fileop cd "${_rpfug_cache_dname_full}" || exit 1; + trap "rm -f \"${_rpfug_dlcachedir_full%%[/]}.fetching\"" EXIT; + if [ -e "${_rpfug_dlcachedir_full}" ]; then + (rtl_fileop cd "${_rpfug_dlcachedir_full}" || exit 1; _rpfug_git_pull_log_fname="$(mktemp)" || exit 1; trap 'rm -f "${_rpfug_git_pull_log_fname}" 2>/dev/null' EXIT HUP INT TERM USR1 USR2; if ! git pull ${_rpfug_git_args} origin "${_rpfug_git_branch:-main}" >"${_rpfug_git_pull_log_fname}" 2>&1; then @@ -37,14 +50,14 @@ rtlp_fetch_url_git() { else cat "${_rpfug_git_pull_log_fname}"; exit 0; fi;) || return 1; - (rtl_fileop cd "${_rpfug_cache_dname_full}" &&\ + (rtl_fileop cd "${_rpfug_dlcachedir_full}" &&\ git submodule update) || return 1; - else if git clone ${_rpfug_git_args} -b "${_rpfug_git_branch:-main}" "${_rpfug_url}" "${_rpfug_cache_dname_full}"; then + else if git clone ${_rpfug_git_args} -b "${_rpfug_git_branch:-main}" "${_rpfug_url}" "${_rpfug_dlcachedir_full}"; then _rpfug_clonefl=1; elif [ "${_rpfug_mirrors}" = "skip" ]; then return 1; else for _rpfug_url_base in ${_rpfug_mirrors}; do - if git clone ${_rpfug_git_args} -b "${_rpfug_git_branch:-main}" "${_rpfug_url_base}/${_rpfug_pkg_name}/${_rpfug_subdir}" "${_rpfug_cache_dname_full}"; then + if git clone ${_rpfug_git_args} -b "${_rpfug_git_branch:-main}" "${_rpfug_url_base}/${_rpfug_name}/${_rpfug_target_subdir}" "${_rpfug_dlcachedir_full}"; then _rpfug_clonefl=1; break; fi; done; @@ -52,23 +65,23 @@ rtlp_fetch_url_git() { if [ "${_rpfug_clonefl}" -eq 0 ]; then return 1; else if [ "${_rpfug_git_branch:+1}" = 1 ]; then - (rtl_fileop cd "${_rpfug_cache_dname_full}" &&\ + (rtl_fileop cd "${_rpfug_dlcachedir_full}" &&\ git checkout "${_rpfug_git_branch}") || return 1; fi; - (rtl_fileop cd "${_rpfug_cache_dname_full}" &&\ + (rtl_fileop cd "${_rpfug_dlcachedir_full}" &&\ git submodule update --init) || return 1; fi; fi; - if [ "${_rpfug_cache_dname}" != "${_rpfug_tgtdir}" ]; then - _rpfug_oldpwd="${PWD}"; rtl_fileop cd "${_rpfug_tgtdir}" || return 1; - rtl_fileop rm "${_rpfug_tgtdir}/${_rpfug_subdir}" || return 1; - _rpfug_dname="${_rpfug_tgtdir}/${_rpfug_subdir}"; rtl_dirname \$_rpfug_dname; + if [ "${_rpfug_dlcachedir}" != "${_rpfug_target_dname}" ]; then + _rpfug_oldpwd="${PWD}"; rtl_fileop cd "${_rpfug_target_dname}" || return 1; + rtl_fileop rm "${_rpfug_target_dname}/${_rpfug_target_subdir}" || return 1; + _rpfug_dname="${_rpfug_target_dname}/${_rpfug_target_subdir}"; rtl_dirname \$_rpfug_dname; if ! [ -e "${_rpfug_dname}" ]; then rtl_fileop mkdir "${_rpfug_dname}"; fi; - rtl_fileop cp "${_rpfug_cache_dname_full}" "${_rpfug_tgtdir}/${_rpfug_subdir}" || return 1; + rtl_fileop cp "${_rpfug_dlcachedir_full}" "${_rpfug_target_dname}/${_rpfug_target_subdir}" || return 1; rtl_fileop cd "${_rpfug_oldpwd}" || return 1; - fi) 4<>"${_rpfug_cache_dname_full%%[/]}.fetching"; + fi) 4<>"${_rpfug_dlcachedir_full%%[/]}.fetching"; if [ "${?}" -eq 0 ]; then cd "$(pwd)"; @@ -77,26 +90,34 @@ rtlp_fetch_url_git() { fi; }; +# +# rtlp_fetch_mirror_urls_git() - setup mirror for Git URL(s) +# @_git_args: optional argument string to pass to git(1) +# @_target_dname: target directory name +# @...: list of Git URLs +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_fetch_mirror_urls_git() { - local _rfmug_git_args="${1}" _rfmug_tgtdir="${2}" \ - _rfmug_dname="" _rfmug_rc=0 _rfmug_repo_dname="" _rfmug_subdir="" \ + local _rfmug_git_args="${1}" _rfmug_target_dname="${2}" \ + _rfmug_dname="" _rfmug_rc=0 _rfmug_repo_dname="" _rfmug_target_subdir="" \ _rfmug_url="" _rfmug_url_spec=""; shift 2; for _rfmug_url_spec in "${@}"; do - _rfmug_subdir="${_rfmug_url_spec%=*}"; _rfmug_subdir="${_rfmug_subdir##*/}"; _rfmug_url="${_rfmug_url_spec#*=}"; _rfmug_url="${_rfmug_url%@*}"; - _rfmug_repo_dname="${_rfmug_subdir}"; [ "${_rfmug_repo_dname%.git}" = "${_rfmug_repo_dname}" ] && _rfmug_repo_dname="${_rfmug_repo_dname}.git"; + _rfmug_target_subdir="${_rfmug_url_spec%=*}"; _rfmug_target_subdir="${_rfmug_target_subdir##*/}"; _rfmug_url="${_rfmug_url_spec#*=}"; _rfmug_url="${_rfmug_url%@*}"; + _rfmug_repo_dname="${_rfmug_target_subdir}"; [ "${_rfmug_repo_dname%.git}" = "${_rfmug_repo_dname}" ] && _rfmug_repo_dname="${_rfmug_repo_dname}.git"; - _rfmug_dname="${_rfmug_tgtdir}"; rtl_dirname \$_rfmug_dname; + _rfmug_dname="${_rfmug_target_dname}"; rtl_dirname \$_rfmug_dname; if ! [ -e "${_rfmug_dname}" ]; then rtl_fileop mkdir "${_rfmug_dname}"; fi; (set -o errexit -o noglob -o nounset; rtl_flock_acquire 4 || exit "${?}"; - trap "rm -f \"${_rfmug_tgtdir}/.fetching\"" EXIT; - if [ -e "${_rfmug_tgtdir}/${_rfmug_repo_dname}" ]; then - (rtl_fileop cd "${_rfmug_tgtdir}/${_rfmug_repo_dname}" && git fetch ${_rfmug_git_args} --all) || return 1; - else (rtl_fileop cd "${_rfmug_tgtdir}" && git clone ${_rfmug_git_args} --mirror "${_rfmug_url}" "${_rfmug_repo_dname}") || return 1; - fi) 4<>"${_rfmug_tgtdir}/.fetching"; + trap "rm -f \"${_rfmug_target_dname}/.fetching\"" EXIT; + if [ -e "${_rfmug_target_dname}/${_rfmug_repo_dname}" ]; then + (rtl_fileop cd "${_rfmug_target_dname}/${_rfmug_repo_dname}" && git fetch ${_rfmug_git_args} --all) || return 1; + else (rtl_fileop cd "${_rfmug_target_dname}" && git clone ${_rfmug_git_args} --mirror "${_rfmug_url}" "${_rfmug_repo_dname}") || return 1; + fi) 4<>"${_rfmug_target_dname}/.fetching"; if [ "${?}" -ne 0 ]; then _rfmug_rc=1; fi; @@ -105,23 +126,35 @@ rtl_fetch_mirror_urls_git() { return "${_rfmug_rc}"; }; +# +# rtl_fetch_url_git() - fetch Git URL(s) for item +# @_dlcachedir: absolute pathname to download cache directory +# @_git_args: optional argument string to pass to git(1) +# @_target_dname: target directory name +# @_name: single item name +# @_mirrors: optional list of mirror base URLs +# @...: list of Git URLs +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_fetch_urls_git() { - local _rfug_cache_dname="${1}" _rfug_git_args="${2}" _rfug_tgtdir="${3}" \ - _rfug_pkg_name="${4}" _rfug_mirrors="${5}" \ - _rfug_git_branch="" _rfug_subdir="" _rfug_url="" _rfug_url_spec=""; shift 5; + local _rfug_dlcachedir="${1}" _rfug_git_args="${2}" _rfug_target_dname="${3}" \ + _rfug_name="${4}" _rfug_mirrors="${5}" \ + _rfug_git_branch="" _rfug_target_subdir="" _rfug_url="" _rfug_url_spec=""; + shift 5; for _rfug_url_spec in "${@}"; do - _rfug_subdir="${_rfug_url_spec%=*}"; + _rfug_target_subdir="${_rfug_url_spec%=*}"; _rfug_url="${_rfug_url_spec#*=}"; _rfug_url="${_rfug_url%@*}"; if [ "${_rfug_url_spec#*@}" != "${_rfug_url_spec}" ]; then _rfug_git_branch=${_rfug_url_spec#*@}; fi; if ! rtlp_fetch_url_git \ - "${_rfug_cache_dname}" "${_rfug_git_args}" \ + "${_rfug_dlcachedir}" "${_rfug_git_args}" \ "${_rfug_git_branch}" "${_rfug_mirrors}" \ - "${_rfug_pkg_name}" "${_rfug_subdir}" \ - "${_rfug_tgtdir}" "${_rfug_url}"; + "${_rfug_name}" "${_rfug_target_subdir}" \ + "${_rfug_target_dname}" "${_rfug_url}"; then return 1; fi; diff --git a/subr.rtl/rtl_fetch_wget.subr b/subr.rtl/rtl_fetch_wget.subr index 1b5946c..13bc347 100644 --- a/subr.rtl/rtl_fetch_wget.subr +++ b/subr.rtl/rtl_fetch_wget.subr @@ -3,7 +3,18 @@ # set +o errexit -o noglob -o nounset is assumed. # -# N.B. URLs ($1) may contain `?' or '&' characters. +# +# rtl_fetch_url_wget() - fetch archive file(s) for item +# @_urls: list of URLs +# @_sha256sum_src: SHA256SUM digest file to check authenticity of archive file(s) with +# @_target_dname: target directory namne +# @_target_fname: target filename +# @_target_name: target subdirectory name +# @_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. +# rtl_fetch_url_wget() { local _rfuw_urls="${1}" _rfuw_sha256sum_src="${2}" _rfuw_target_dname="${3}" \ _rfuw_target_fname="${4}" _rfuw_target_name="${5}" _rfuw_mirrors="${6:-}" \ diff --git a/subr.rtl/rtl_fileop.subr b/subr.rtl/rtl_fileop.subr index 9b910ca..b628ac0 100644 --- a/subr.rtl/rtl_fileop.subr +++ b/subr.rtl/rtl_fileop.subr @@ -20,6 +20,13 @@ rtlp_fileop_log() { # Public subroutines # +# +# rtl_fileop() - clean download cache for single package +# @_op: file operation +# @...: file operation arguments +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_fileop() { local _rf_op="${1}" \ _rf_dst="" _rf_group="" _rf_install_args="" \ diff --git a/subr.rtl/rtl_filepath.subr b/subr.rtl/rtl_filepath.subr index 7d4ec55..3e24057 100644 --- a/subr.rtl/rtl_filepath.subr +++ b/subr.rtl/rtl_filepath.subr @@ -3,10 +3,23 @@ # set +o errexit -o noglob -o nounset is assumed. # +# +# rtl_basename() - obtain base name from filename +# @_rfname: inout reference to filename +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_basename() { rtl_basename2 "${1}" "${1}"; }; +# +# rtl_basename2() - obtain base name from filename +# @_rfname: in reference to filename +# @_rfname_out: out reference to new filename +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_basename2() { local _rb2_rfname="${1#\$}" _rb2_rfname_out="${2#\$}" \ _rb2_fname=""; @@ -16,6 +29,14 @@ rtl_basename2() { return 0; }; +# +# rtl_check_digest() - check digest of single file +# @_rdigest: out reference to digest of file +# @_fname: name of file to check +# @_digest_check: digest to check against +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_check_digest() { local _rcd_rdigest="${1#\$}" _rcd_fname="${2}" _rcd_digest_check="${3}" \ _rcd_digest=""; @@ -33,6 +54,14 @@ rtl_check_digest() { fi; }; +# +# rtl_check_digest_file() - check digest of single file w/ digest file +# @_fname: name of file to check +# @_digest_check: digest to check against +# @_digest_fname: name of file containing digest +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_check_digest_file() { local _rcdf_fname="${1}" _rcdf_digest_check="${2}" _rcdf_digest_fname="${3}" \ _rcdf_digest="" _rcdf_digest_file=""; @@ -51,6 +80,13 @@ rtl_check_digest_file() { fi; }; +# +# rtl_check_path_vars() - check pathname variables for validity +# @_rstatus: out reference to status string +# @_vnames: list of variable names +# +# Returns: zero (0) on success, non-zero (>0) on empty or unset pathname variable or pathname variable containing whitespace characters +# rtl_check_path_vars() { local _rcpv_rstatus="${1#\$}" _rcpv_vnames="${2}" \ _rcpv_rc=0 _rcpv_vname="" _rcpv_vname_val=""; @@ -70,15 +106,28 @@ rtl_check_path_vars() { return "${_rcpv_rc}"; }; +# +# rtl_dirname() - obtain directory name from filename +# @_rfname: inout reference to {file,directory} name +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_dirname() { rtl_dirname2 "${1}" "${1}"; }; +# +# rtl_dirname2() - obtain directory name from filename +# @_rfname: in reference to filename +# @_rfname_out: out reference to directory name +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_dirname2() { - local _rdname="${1#\$}" _rdname_out="${2#\$}" \ + local _rfname="${1#\$}" _rdname_out="${2#\$}" \ _rd2_dname=""; - eval _rd2_dname="\${${_rdname}}"; + eval _rd2_dname="\${${_rfname}}"; _rd2_dname="${_rd2_dname%/*}"; case "${_rd2_dname}" in @@ -92,6 +141,13 @@ rtl_dirname2() { return 0; }; +# +# rtl_exists_any() - check for existence of pathnames beneath directory +# @_subdir: single directory name +# @...: list of pathnames to check +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_exists_any() { local _rea_subdir="${1}"; shift; @@ -105,6 +161,14 @@ rtl_exists_any() { return 1; }; +# +# rtl_flock_acquire() - acquire file lock +# @_fd: single file descriptor +# @_conflict_exit_code: exit code on conflict +# @_wait: wait period in seconds +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_flock_acquire() { local _rfa_fd="${1}" _rfa_conflict_exit_code="${2:-253}" _rfa_wait="${3:-3600}"; @@ -123,6 +187,13 @@ rtl_flock_acquire() { done; }; +# +# rtl_is_newer() - check if single file is newer than other single file +# @_new_fname: single name of newer file +# @_old_fname: single name of older file +# +# Returns: zero (0) if @_new_fname is newer, non-zero (>0) if @_old_fname is newer +# rtl_is_newer() { local _ris_new_fname="${1}" _ris_old_fname="${2}" \ _ris_new_ts="" _ris_old_ts=""; @@ -141,6 +212,15 @@ rtl_is_newer() { fi; }; +# +# rtl_patch_files() - +# @_patch_cwd: patch(1) -d directory +# @_strip_count: patch(1) strip count +# @_fn: name of function that produces patch filenames and takes the arguments @_rpatch_fname @_patch_idx @... +# @... optional arguments to pass to @_fn +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_patch_files() { local _rpf_patch_cwd="${1}" _rpf_strip_count="${2}" _rpf_fn="${3}" \ _rpf_patch_fname="" _rpf_patch_idx=0; diff --git a/subr.rtl/rtl_string.subr b/subr.rtl/rtl_string.subr index 4f0910a..107771f 100644 --- a/subr.rtl/rtl_string.subr +++ b/subr.rtl/rtl_string.subr @@ -3,6 +3,12 @@ # set +o errexit -o noglob -o nounset is assumed. # +# +# rtl_isnumber() - check if string is number +# @_s: string to check +# +# Returns: zero (0) if string is number, non-zero (>0) if string is not number +# rtl_isnumber() { local _ri_s="${1}" \ _ri_rc=0; @@ -16,6 +22,13 @@ rtl_isnumber() { return "${_ri_rc}"; }; +# +# rtl_match() - match pattern against string +# @_s: input string +# @_find: pattern to match against string +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_match() { local _rm_s="${1}" _rm_find="${2}"; @@ -26,6 +39,13 @@ rtl_match() { fi; }; +# +# rtl_matchr() - match pattern against string from right-hand side +# @_s: input string +# @_find: pattern to match against string +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_matchr() { local _rmr_s="${1}" _rmr_find="${2}"; @@ -36,16 +56,63 @@ rtl_matchr() { fi; }; +# +# rtl_remove_postfix() - remove longest postfix from string w/ pattern +# @_pattern: pattern to match against input string +# @_s: input string +# @_rs_out: out reference to output string +# +# Returns: zero (0) on success, non-zero (>0) on failure +# +rtl_remove_postfix() { + local _rh_pattern="${1}" _rh_s="${2}" _rh_rs_out="${3#\$}"; + + while true; do + if [ "${_rh_s%%${_rh_pattern}}" = "${_rh_s}" ]; then + break; + else + _rh_s="${_rh_s%%${_rh_pattern}}"; + fi; + done; + + eval ${_rh_rs_out}='${_rh_s}'; + return 0; +}; + +# +# rtl_setrstatus() - set status string +# @_rstatus: out reference to status string +# @_status: new status string +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_setrstatus() { local _rsrs_rstatus="${1#\$}" _rsrs_status="${2}"; eval ${_rsrs_rstatus}=\"${_rsrs_status}\"; return 0; }; +# +# rtl_subst() - substitute in string +# @_rs: inout reference to string +# @_find: pattern to match against input string +# @_replace: replacement string +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_subst() { rtl_subst2 "${1}" "${1}" "${2}" "${3}"; }; +# +# rtl_subst2() - substitute in string +# @_rs: in reference to string +# @_rs_out: out reference to new string +# @_find: pattern to match against input string +# @_replace: replacement string +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_subst2() { local _rs2_rs="${1#\$}" _rs2_rs_out="${2#\$}" _rs2_find="${3}" _rs2_replace="${4}" \ _rs2_prefix="" _rs2_s="" _rs2_s_new=""; @@ -61,10 +128,23 @@ rtl_subst2() { return 0; }; +# +# rtl_tolower() - convert string to lower case +# @_rs: in reference to string +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_tolower() { rtl_tolower2 "${1}" "${1}"; }; +# +# rtl_tolower2() - convert string to lower case +# @_rs: in reference to string +# @_rs_out: out reference to new string +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_tolower2() { local _rtl2_rs="${1#\$}" _rtl2_rs_out="${2#\$}" \ _rtl2_s="" _rtl2_s_new=""; @@ -110,12 +190,27 @@ rtl_tolower2() { return 0; }; +# +# rtl_toupper() - convert string to upper case +# @_rs: in reference to string +# @_rs_out: out reference to new string +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_toupper() { rtl_toupper2 "${1}" "${1}"; }; +# +# rtl_toupper2() - convert string to upper case +# @_rs: in reference to string +# @_rs_out: out reference to new string +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_toupper2() { - local _rtu2_rs="${1#\$}" _rtu2_rs_out="${2#\$}" _rtu2_s="" _rtu2_s_new=""; + local _rtu2_rs="${1#\$}" _rtu2_rs_out="${2#\$}" \ + _rtu2_s="" _rtu2_s_new=""; eval _rtu2_s="\${${_rtu2_rs}}";