summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/local.mk1
-rw-r--r--lib/substvars.sh103
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
+}