summaryrefslogtreecommitdiffstats
path: root/bin/isolated-functions.sh
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2007-11-21 04:44:20 +0000
committerZac Medico <zmedico@gentoo.org>2007-11-21 04:44:20 +0000
commita50a1bda0e6fa8dcc1626a4fcb714755765169f0 (patch)
treedc692c47a5ea9fe998a592dd10638a8992f1aaf1 /bin/isolated-functions.sh
parentfa5253f154551345ec901c2b4144ad5f1becf3b2 (diff)
downloadportage-a50a1bda0e6fa8dcc1626a4fcb714755765169f0.tar.gz
portage-a50a1bda0e6fa8dcc1626a4fcb714755765169f0.tar.bz2
portage-a50a1bda0e6fa8dcc1626a4fcb714755765169f0.zip
Sync with ebuild.sh and isolated-functions.sh as of trunk r8569. This
includes all the environment filtering enhancements that solve bugs #46223 and #190128. svn path=/main/branches/2.1.2/; revision=8570
Diffstat (limited to 'bin/isolated-functions.sh')
-rw-r--r--bin/isolated-functions.sh121
1 files changed, 118 insertions, 3 deletions
diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh
index bb119b98e..b46f50a4d 100644
--- a/bin/isolated-functions.sh
+++ b/bin/isolated-functions.sh
@@ -1,6 +1,120 @@
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header$
+# $Id$
+
+# We need this next line for "die" and "assert". It expands
+# It _must_ preceed all the calls to die and assert.
+shopt -s expand_aliases
+alias die='diefunc "$FUNCNAME" "$LINENO" "$?"'
+alias assert='_pipestatus="${PIPESTATUS[*]}"; [[ "${_pipestatus// /}" -eq 0 ]] || diefunc "$FUNCNAME" "$LINENO" "$_pipestatus"'
+alias save_IFS='[ "${IFS:-unset}" != "unset" ] && old_IFS="${IFS}"'
+alias restore_IFS='if [ "${old_IFS:-unset}" != "unset" ]; then IFS="${old_IFS}"; unset old_IFS; else unset IFS; fi'
+
+shopt -s extdebug
+
+# dump_trace([number of funcs on stack to skip],
+# [whitespacing for filenames],
+# [whitespacing for line numbers])
+dump_trace() {
+ local funcname="" sourcefile="" lineno="" n e s="yes"
+ declare -i strip=${1:-1}
+ local filespacing=$2 linespacing=$3
+
+ eerror "Call stack:"
+ for (( n = ${#FUNCNAME[@]} - 1, p = ${#BASH_ARGV[@]} ; n > ${strip} ; n-- )) ; do
+ funcname=${FUNCNAME[${n} - 1]}
+ sourcefile=$(basename ${BASH_SOURCE[${n}]})
+ lineno=${BASH_LINENO[${n} - 1]}
+ # Display function arguments
+ args=
+ if [[ -n "${BASH_ARGV[@]}" ]]; then
+ for (( j = 1 ; j <= ${BASH_ARGC[${n} - 1]} ; ++j )); do
+ newarg=${BASH_ARGV[$(( p - j - 1 ))]}
+ args="${args:+${args} }'${newarg}'"
+ done
+ (( p -= ${BASH_ARGC[${n} - 1]} ))
+ fi
+ eerror " $(printf "%${filespacing}s" "${sourcefile}"), line $(printf "%${linespacing}s" "${lineno}"): Called ${funcname}${args:+ ${args}}"
+ done
+}
+
+diefunc() {
+ local funcname="$1" lineno="$2" exitcode="$3"
+ shift 3
+ if [ -n "${QA_INTERCEPTORS}" ] ; then
+ # die was called from inside inherit. We need to clean up
+ # QA_INTERCEPTORS since sed is called below.
+ unset -f ${QA_INTERCEPTORS}
+ unset QA_INTERCEPTORS
+ fi
+ local n filespacing=0 linespacing=0
+ # setup spacing to make output easier to read
+ for ((n = ${#FUNCNAME[@]} - 1; n >= 0; --n)); do
+ sourcefile=${BASH_SOURCE[${n}]} sourcefile=${sourcefile##*/}
+ lineno=${BASH_LINENO[${n}]}
+ ((filespacing < ${#sourcefile})) && filespacing=${#sourcefile}
+ ((linespacing < ${#lineno})) && linespacing=${#lineno}
+ done
+
+ eerror
+ eerror "ERROR: $CATEGORY/$PF failed."
+ dump_trace 2 ${filespacing} ${linespacing}
+ eerror " $(printf "%${filespacing}s" "${BASH_SOURCE[1]##*/}"), line $(printf "%${linespacing}s" "${BASH_LINENO[0]}"): Called die"
+ eerror "The specific snippet of code:"
+ # This scans the file that called die and prints out the logic that
+ # ended in the call to die. This really only handles lines that end
+ # with '|| die' and any preceding lines with line continuations (\).
+ # This tends to be the most common usage though, so let's do it.
+ # Due to the usage of appending to the hold space (even when empty),
+ # we always end up with the first line being a blank (thus the 2nd sed).
+ sed -n \
+ -e "# When we get to the line that failed, append it to the
+ # hold space, move the hold space to the pattern space,
+ # then print out the pattern space and quit immediately
+ ${BASH_LINENO[0]}{H;g;p;q}" \
+ -e '# If this line ends with a line continuation, append it
+ # to the hold space
+ /\\$/H' \
+ -e '# If this line does not end with a line continuation,
+ # erase the line and set the hold buffer to it (thus
+ # erasing the hold buffer in the process)
+ /[^\]$/{s:^.*$::;h}' \
+ ${BASH_SOURCE[1]} \
+ | sed -e '1d' -e 's:^:RETAIN-LEADING-SPACE:' \
+ | while read -r n ; do eerror " ${n#RETAIN-LEADING-SPACE}" ; done
+ eerror " The die message:"
+ eerror " ${*:-(no error message)}"
+ eerror
+ eerror "If you need support, post the topmost build error, and the call stack if relevant."
+ [[ -n ${PORTAGE_LOG_FILE} ]] \
+ && eerror "A complete build log is located at '${PORTAGE_LOG_FILE}'."
+ if [[ -n ${EBUILD_OVERLAY_ECLASSES} ]] ; then
+ eerror "This ebuild used the following eclasses from overlays:"
+ local x
+ for x in ${EBUILD_OVERLAY_ECLASSES} ; do
+ eerror " ${x}"
+ done
+ fi
+ if [ "${EMERGE_FROM}" != "binary" ] && \
+ [ "${EBUILD#${PORTDIR}/}" == "${EBUILD}" ] ; then
+ local overlay=${EBUILD%/*}
+ overlay=${overlay%/*}
+ overlay=${overlay%/*}
+ eerror "This ebuild is from an overlay: '${overlay}/'"
+ fi
+ eerror
+
+ if [[ "${EBUILD_PHASE/depend}" == "${EBUILD_PHASE}" ]] ; then
+ local x
+ for x in $EBUILD_DEATH_HOOKS; do
+ ${x} "$@" >&2 1>&2
+ done
+ fi
+
+ # subshell die support
+ kill -s SIGTERM ${EBUILD_MASTER_PID}
+ exit 1
+}
quiet_mode() {
[[ ${PORTAGE_QUIET} -eq 1 ]]
@@ -209,8 +323,9 @@ set_colors() {
# Adjust COLS so that eend works properly on a standard BSD console.
[ "${TERM}" = "cons25" ] && COLS=$((${COLS} - 1))
- ENDCOL=$'\e[A\e['${COLS}'C' # Now, ${ENDCOL} will move us to the end of the
- # column; irregardless of character width
+ # Now, ${ENDCOL} will move us to the end of the
+ # column; irregardless of character width
+ ENDCOL=$'\e[A\e['${COLS}'C'
if [ -n "${PORTAGE_COLORMAP}" ] ; then
eval ${PORTAGE_COLORMAP}
else