summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/control.sh54
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 \