summaryrefslogtreecommitdiffstats
path: root/lib/control.sh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/control.sh')
-rw-r--r--lib/control.sh142
1 files changed, 119 insertions, 23 deletions
diff --git a/lib/control.sh b/lib/control.sh
index 0e9a1f6..abbb2f2 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=
@@ -32,17 +34,22 @@ ob_parse_control()
_obpco_all_fields _obpco_got_fields \
_obpco_line_nr _obpco_line _obpco_name _obpco_value
- if [ ${#} -eq 4 ]; then
+ if [ ${#} -eq 2 ]; then
+ _obpco_file="${1}"
+ _obpco_field_cb="${2}"
+ _obpco_check_fields='false'
+ elif [ ${#} -eq 4 ]; then
_obpco_file="${1}"
_obpco_field_cb="${2}"
_obpco_req_fields="${3}"
_obpco_opt_fields="${4}"
+ _obpco_check_fields='true'
+ _obpco_all_fields=" ${_obpco_req_fields} ${_obpco_opt_fields} "
else
_ob_return 125
return ${?}
fi
- _obpco_all_fields=" ${_obpco_req_fields} ${_obpco_opt_fields} "
_obpco_got_fields=' '
_obpco_line_nr=0
@@ -64,23 +71,27 @@ ob_parse_control()
fi
fi
_obpco_name="${_obpco_line%%:*}"
- _obpco_value="${_obpco_line#*: }"
- if [ -z "${_obpco_name}" -o "${_obpco_name}" = "${_obpco_line}" \
- -o -z "${_obpco_value}" ]; then
+ _obpco_value="${_obpco_line#*:}"
+ _obpco_value="${_obpco_value# }"
+ if [ -z "${_obpco_name}" \
+ -o "${_obpco_name}" = "${_obpco_line}" ]; then
# Badly formatted control field.
_ob_parse_control_error "${_obpco_file}" "${_obpco_line_nr}" \
'control_bad_nv'
continue
fi
- if [ "${_obpco_all_fields% ${_obpco_name} *}" = \
- "${_obpco_all_fields}" ]; then
- # Unknown field.
- _ob_parse_control_error "${_obpco_file}" "${_obpco_line_nr}" \
- 'control_unknown_field' "${_obpco_name}"
- else
- # Remove field from list of required fields.
- _obpco_req_fields="$(echo "${_obpco_req_fields}" | \
- sed "s/${_obpco_name}//")"
+ if ${_obpco_check_fields}; then
+ if [ "${_obpco_all_fields% ${_obpco_name} *}" = \
+ "${_obpco_all_fields}" ]; then
+ # Unknown field.
+ _ob_parse_control_error \
+ "${_obpco_file}" "${_obpco_line_nr}" \
+ 'control_unknown_field' "${_obpco_name}"
+ else
+ # Remove field from list of required fields.
+ _obpco_req_fields="$(echo "${_obpco_req_fields}" | \
+ sed "s/${_obpco_name}//")"
+ fi
fi
if [ "${_obpco_got_fields% ${_obpco_name} *}" != \
"${_obpco_got_fields}" ]; then
@@ -113,21 +124,106 @@ ${_obpco_line# }"
fi
fi
- _obpco_req_fields="${_obpco_req_fields## }"
- _obpco_req_fields="${_obpco_req_fields%% }"
- if [ -n "${_obpco_req_fields}" ]; then
- # Missing required control fields.
- _obpco_req_fields="$(echo "${_obpco_req_fields}" | sed 's/ / /g' | \
- sed "s/ /$(ob_get_msg 'list_item_separator')/g")"
- _ob_parse_control_error "${_obpco_file}" '0' \
- 'control_missing_fields' \
- "${_obpco_req_fields}"
+ if ${_obpco_check_fields}; then
+ _obpco_req_fields="${_obpco_req_fields## }"
+ _obpco_req_fields="${_obpco_req_fields%% }"
+ if [ -n "${_obpco_req_fields}" ]; then
+ # Missing required control fields.
+ _obpco_req_fields="$(echo "${_obpco_req_fields}" | \
+ sed 's/ / /g' | \
+ sed "s/ /$(ob_get_msg 'list_item_separator')/g")"
+ _ob_parse_control_error "${_obpco_file}" '0' \
+ 'control_missing_fields' \
+ "${_obpco_req_fields}"
+ fi
fi
_ob_return 0
return ${?}
}
+ob_set_substvar()
+{
+ _ob_local _obssv_name _obssv_value
+
+ if [ ${#} -eq 2 ]; then
+ _obssv_name="${1}"
+ _obssv_value="${2}"
+ else
+ _ob_return 125
+ return ${?}
+ fi
+
+ # Trim leading and trailing whitespace from value.
+ _obssv_value="$(echo "${_obssv_value}" | sed -n '
+ H; # Store each input line in the hold space.
+ ${ # At the last line of input, …
+ g; # … restore the hold space into the pattern space, …
+ s/^[ \t\n]*//; # … remove leading whitespace, …
+ s/[ \t\n]*$//; # … remove trailing whitespace, and …
+ p; # … print the results.
+ };
+ ')"
+
+ _obssv_name="$(echo "${_obssv_name}" | tr 'a-z-' 'A-Z_')"
+ eval "_OB_SUBSTVAR_${_obssv_name}='${_obssv_value}'"
+
+ _ob_return 125
+ 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 \