diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/control.sh | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/control.sh b/lib/control.sh index 15093a0..5190155 100644 --- a/lib/control.sh +++ b/lib/control.sh @@ -23,6 +23,8 @@ _OB_CONTROL_SM='true' ob_use messages ob_use locale +_OB_SUBSTVARS_MAX_DEPTH=50 + OB_CONTROL_NAME= OB_CONTROL_VALUE= @@ -169,6 +171,58 @@ ob_set_substvar() return ${?} } +ob_substvars() +{ + _ob_local _obsv_string _obsv_depth \ + _obsv_lhs _obsv_name _obsv_rhs _obsv_old_rhs _obsv_value + + if [ ${#} -eq 1 ]; then + _obsv_string="${1}" + else + _ob_return 125 + return ${?} + fi + + # Logic inspired by that of dpkg's Dpkg::Substvars::substvars() subroutine. + + _obsv_depth=0 + + while true; do + _obsv_lhs="${_obsv_string%%\$\{*}" + if [ ${#_obsv_lhs} -eq ${#_obsv_string} ]; then + # No "${" was found. + break + fi + _obsv_string="${_obsv_string#*\$\{}" + _obsv_name="${_obsv_string%%\}*}" + _obsv_rhs="${_obsv_string#*\}}" + + if [ ${#_obsv_rhs} -lt ${#_obsv_old_rhs} ]; then + # Reset the nesting counter if we've advanced the right side of the + # matched space. + _obsv_depth=0 + fi + if [ ${_obsv_depth} -ge ${_OB_SUBSTVARS_MAX_DEPTH} ]; then + # Warn of possible recursion. + ob_warn "$(ob_get_msg 'substvar_deep_nesting')" + _ob_return 1 + return ${?} + fi + _obsv_old_rhs="${_obsv_rhs}" + + # Perform the substitution. + _obsv_name="$(echo "${_obsv_name}" | tr 'a-z-' 'A-Z_')" + _obsv_value="$(eval echo \"\$\{"_OB_SUBSTVAR_${_obsv_name}"\}\")" + _obsv_string="${_obsv_lhs}${_obsv_value}${_obsv_rhs}" + _obsv_depth=$(($_obsv_depth + 1)) + done + + printf '%s\n' "${_obsv_string}" + + _ob_return 0 + return ${?} +} + _ob_parse_control_error() { _ob_local _obpcoe_file _obpcoe_line_nr _obpcoe_msg_id \ |