diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/local.mk | 1 | ||||
-rw-r--r-- | lib/substvars.sh | 103 |
2 files changed, 104 insertions, 0 deletions
diff --git a/lib/local.mk b/lib/local.mk index 1a4ac0e..d593289 100644 --- a/lib/local.mk +++ b/lib/local.mk @@ -5,6 +5,7 @@ pkgdata_sources = \ lib/fd.sh \ lib/archplat.sh \ lib/deps.sh \ + lib/substvars.sh \ lib/control.sh \ lib/feed.sh \ lib/pkg.sh \ diff --git a/lib/substvars.sh b/lib/substvars.sh new file mode 100644 index 0000000..40d908b --- /dev/null +++ b/lib/substvars.sh @@ -0,0 +1,103 @@ +# Functions for setting and substituting variables +# +# Copyright (C) 2012, 2014 Patrick "P. J." McDermott +# +# This file is part of the ProteanOS Development Kit. +# +# The ProteanOS Development Kit is free software: you can redistribute +# it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# The ProteanOS Development Kit is distributed in the hope that it +# will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the ProteanOS Development Kit. If not, see +# <http://www.gnu.org/licenses/>. + +[ "x${_SUBSTVARS_SM+set}" = 'xset' ] && return 0 +_SUBSTVARS_SM=1 + +set_substvar() +{ + local name="${1}" + local value="${2}" + + # Convert variable name to lower case and validate. + name="$(echo "${name}" | tr 'A-Z-' 'a-z_')" + case "${name:- }" in + *[!a-z0-9_]*) + error 2 "$(get_msg 'substvar_invalid')" + ;; + esac + + # Trim leading and trailing newline characters from value. + value="$(printf '%s\n' "${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/^[\n]*//; # Remove leading newline characters. + s/[\n]*$//; # Remove trailing newline characters. + p; # Print the results. + }; + ')" + + # Escape single quotes in value. + value="$(printf '%s\n' "${value}" | sed "s/'/'\\\\''/g")" + + eval "substvar_${name}='${value}'" + + return 0 +} + +substvars() +{ + local string="${1}" + local depth= + local lhs= + local name= + local rhs= + local old_rhs= + local value= + + # Logic inspired by that of dpkg's Dpkg::Substvars::substvars() + # subroutine. + + depth=0 + + while :; do + lhs="${string%%\$\{*}" + if [ ${#lhs} -eq ${#string} ]; then + # No "${" was found. + break + fi + string="${string#*\$\{}" + name="${string%%\}*}" + rhs="${string#*\}}" + + if [ ${#rhs} -lt ${#old_rhs} ]; then + # Reset the nesting counter if we've advanced the right + # side of the matched space. + depth=0 + fi + if [ ${depth} -ge ${_OB_SUBSTVARS_MAX_DEPTH} ]; then + # Warn of possible recursion. + ob_warn "$(ob_get_msg 'substvar_deep_nesting')" + return 1 + fi + old_rhs="${rhs}" + + # Perform the substitution. + name="$(echo "${name}" | tr 'A-Z-' 'a-z_')" + value="$(eval printf '%s\n' "\"\$\{substvar_${name}\}\"")" + string="${lhs}${value}${rhs}" + depth=$(($depth + 1)) + done + + printf '%s\n' "${string}" + + return 0 +} |