Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- GMT_EPATCH_SOURCE="${WORKDIR}/patch"
- GMT_EPATCH_SUFFIX="patch.bz2"
- GMT_EPATCH_OPTS=""
- GMT_EPATCH_COMMON_OPTS="-g0 -E --no-backup-if-mismatch"
- GMT_EPATCH_EXCLUDE=""
- GMT_EPATCH_SINGLE_MSG="(gmt_epatch)"
- GMT_EPATCH_MULTI_MSG="Applying various patches (bugfixes/updates: (gmt_epatch) ..."
- GMT_EPATCH_FORCE="no"
- post_src_prepare() {
- if [[ ${GMT_EPATCH_USER_FORCE} == yes ]]; then
- [[ ${GMT_EPATCH_USER_POST_SRC_PREPARE} == yes ]] || return 0
- gmt_epatch_user || \
- { ewarn "SHIT!"; ewarn "gmt_epatch_user failed for =${CATEGORY}/${P}" ; /bin/true ; }
- fi
- unset GMT_EPATCH_USER_FORCE
- if [[ ${GMT_CPP11_POST_SRC_PREPARE} == yes ]]; then
- CXXFLAGS="${CXXFLAGS} --std=c++11"
- fi
- # no unset here because in theory every src_prepare requires reapplication of flags
- }
- gmt_epatch_user() {
- [[ $# -ne 0 ]] && die "gmt_epatch_user takes no options"
- # Allow multiple calls to this function; ignore all but the first
- local applied="${T}/gmt_epatch_user.log"
- [[ -e ${applied} ]] && return 2
- # don't clobber any EPATCH vars that the parent might want
- local GMT_EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches
- for check in ${CATEGORY}/{${P}-${PR},${P},${PN}}{,:${SLOT}}; do
- GMT_EPATCH_SOURCE=${base}/${CTARGET}/${check}
- [[ -r ${GMT_EPATCH_SOURCE} ]] || GMT_EPATCH_SOURCE=${base}/${CHOST}/${check}
- [[ -r ${GMT_EPATCH_SOURCE} ]] || GMT_EPATCH_SOURCE=${base}/${check}
- if [[ -d ${GMT_EPATCH_SOURCE} ]] ; then
- GMT_EPATCH_SOURCE=${GMT_EPATCH_SOURCE} \
- GMT_EPATCH_SUFFIX="patch" \
- GMT_EPATCH_FORCE="yes" \
- GMT_EPATCH_MULTI_MSG="Applying user patches from ${GMT_EPATCH_SOURCE} (gmt_epatch)" \
- gmt_epatch
- echo "${GMT_EPATCH_SOURCE}" > "${applied}"
- has "${gmt_epatch_user_death_notice}" ${EBUILD_DEATH_HOOKS} || EBUILD_DEATH_HOOKS+=" gmt_epatch_user_death_notice"
- return 0
- fi
- done
- echo "none" > "${applied}"
- return 1
- }
- gmt_epatch_user_death_notice() {
- ewarn "!!! User patches were wedged into this build gmt style!"
- }
- gmt_epatch() {
- _gmt_epatch_draw_line() {
- # create a line of same length as input string
- [[ -z $1 ]] && set "$(printf "%65s" '')"
- echo "${1//?/=}"
- }
- unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402
- # First process options. We localize the GMT_EPATCH_OPTS setting
- # from above so that we can pass it on in the loop below with
- # any additional values the user has specified.
- local GMT_EPATCH_OPTS=( ${GMT_EPATCH_OPTS[*]} )
- while [[ $# -gt 0 ]] ; do
- case $1 in
- -*) GMT_EPATCH_OPTS+=( "$1" ) ;;
- *) break ;;
- esac
- shift
- done
- # Let the rest of the code process one user arg at a time --
- # each arg may expand into multiple patches, and each arg may
- # need to start off with the default global EPATCH_xxx values
- if [[ $# -gt 1 ]] ; then
- local m
- for m in "$@" ; do
- gmt_epatch "${m}"
- done
- return 0
- fi
- local GMT_SINGLE_PATCH="no"
- # no args means process ${GMT_EPATCH_SOURCE}
- [[ $# -eq 0 ]] && set -- "${GMT_EPATCH_SOURCE}"
- if [[ -f $1 ]] ; then
- GMT_SINGLE_PATCH="yes"
- set -- "$1"
- # Use the suffix from the single patch (localize it); the code
- # below will find the suffix for us
- local GMT_EPATCH_SUFFIX=$1
- elif [[ -d $1 ]] ; then
- # We have to force sorting to C so that the wildcard expansion is consistent #471666.
- gmt_evar_push_set LC_COLLATE C
- # Some people like to make dirs of patches w/out suffixes (vim).
- set -- "$1"/*${GMT_EPATCH_SUFFIX:+."${GMT_EPATCH_SUFFIX}"}
- gmt_evar_pop
- elif [[ -f ${GMT_EPATCH_SOURCE}/$1 ]] ; then
- # Re-use GMT_EPATCH_SOURCE as a search dir
- gmt_epatch "${GMT_EPATCH_SOURCE}/$1"
- return $?
- else
- # sanity check ... if it isn't a dir or file, wtf man ?
- [[ $# -ne 0 ]] && GMT_EPATCH_SOURCE=$1
- echo
- eerror "Cannot find \$GMT_EPATCH_SOURCE! Value for \$GMT_EPATCH_SOURCE is:"
- eerror
- eerror " ${GMT_EPATCH_SOURCE}"
- eerror " ( ${GMT_EPATCH_SOURCE##*/} )"
- echo
- die "Cannot find \$GMT_EPATCH_SOURCE!"
- fi
- # Now that we know we're actually going to apply something, merge
- # all of the patch options back in to a single variable for below.
- GMT_EPATCH_OPTS="${EPATCH_COMMON_OPTS} ${GMT_EPATCH_OPTS[*]}"
- local PIPE_CMD
- case ${GMT_EPATCH_SUFFIX##*\.} in
- xz) PIPE_CMD="xz -dc" ;;
- lzma) PIPE_CMD="lzma -dc" ;;
- bz2) PIPE_CMD="bzip2 -dc" ;;
- gz|Z|z) PIPE_CMD="gzip -dc" ;;
- ZIP|zip) PIPE_CMD="unzip -p" ;;
- *) ;;
- esac
- [[ ${GMT_SINGLE_PATCH} == "no" ]] && einfo "${GMT_EPATCH_MULTI_MSG}"
- local x
- for x in "$@" ; do
- # If the patch dir given contains subdirs, or our GMT_EPATCH_SUFFIX
- # didn't match anything, ignore continue on
- [[ ! -f ${x} ]] && continue
- local patchname=${x##*/}
- # Apply single patches, or forced sets of patches, or
- # patches with ARCH dependant names.
- # ???_arch_foo.patch
- # Else, skip this input altogether
- local a=${patchname#*_} # strip the ???_
- a=${a%%_*} # strip the _foo.patch
- if ! [[ ${GMT_SINGLE_PATCH} == "yes" || \
- ${GMT_EPATCH_FORCE} == "yes" || \
- ${a} == all || \
- ${a} == ${ARCH} ]]
- then
- continue
- fi
- # Let people filter things dynamically
- if [[ -n ${GMT_EPATCH_EXCLUDE}${GMT_EPATCH_USER_EXCLUDE} ]] ; then
- # let people use globs in the exclude
- gmt_eshopts_push -o noglob
- local ex
- for ex in ${GMT_EPATCH_EXCLUDE} ; do
- if [[ ${patchname} == ${ex} ]] ; then
- einfo " Skipping ${patchname} due to GMT_EPATCH_EXCLUDE ..."
- gmt_eshopts_pop
- continue 2
- fi
- done
- for ex in ${GMT_EPATCH_USER_EXCLUDE} ; do
- if [[ ${patchname} == ${ex} ]] ; then
- einfo " Skipping ${patchname} due to GMT_EPATCH_USER_EXCLUDE ..."
- gmt_eshopts_pop
- continue 2
- fi
- done
- gmt_eshopts_pop
- fi
- if [[ ${GMT_SINGLE_PATCH} == "yes" ]] ; then
- if [[ -n ${GMT_EPATCH_SINGLE_MSG} ]] ; then
- einfo "${GMT_EPATCH_SINGLE_MSG}"
- else
- einfo "Applying ${patchname} ... (gmt)"
- fi
- else
- einfo " ${patchname} ..."
- fi
- # Handle aliased patch command #404447 #461568
- local patch="patch"
- eval $(alias patch 2>/dev/null | sed 's:^alias ::')
- # most of the time, there will only be one run per unique name,
- # but if there are more, make sure we get unique log filenames
- local STDERR_TARGET="${T}/${patchname}.out"
- if [[ -e ${STDERR_TARGET} ]] ; then
- STDERR_TARGET="${T}/${patchname}-$$.out"
- fi
- printf "***** %s *****\nPWD: %s\nPATCH TOOL: %s -> %s\nVERSION INFO:\n%s\n\n" \
- "${patchname}" \
- "${PWD}" \
- "${patch}" \
- "$(type -P "${patch}")" \
- "$(${patch} --version)" \
- > "${STDERR_TARGET}"
- # Decompress the patch if need be
- local count=0
- local PATCH_TARGET
- if [[ -n ${PIPE_CMD} ]] ; then
- PATCH_TARGET="${T}/$$.patch"
- echo "PIPE_COMMAND: ${PIPE_CMD} ${x} > ${PATCH_TARGET}" >> "${STDERR_TARGET}"
- if ! (${PIPE_CMD} "${x}" > "${PATCH_TARGET}") >> "${STDERR_TARGET}" 2>&1 ; then
- echo
- eerror "Could not extract patch!"
- #die "Could not extract patch!"
- count=5
- break
- fi
- else
- PATCH_TARGET=${x}
- fi
- # Check for absolute paths in patches. If sandbox is disabled,
- # people could (accidently) patch files in the root filesystem.
- # Or trigger other unpleasantries #237667. So disallow -p0 on
- # such patches.
- local abs_paths=$(egrep -n '^[-+]{3} /' "${PATCH_TARGET}" | awk '$2 != "/dev/null" { print }')
- if [[ -n ${abs_paths} ]] ; then
- count=1
- printf "NOTE: skipping -p0 due to absolute paths in patch:\n%s\n" "${abs_paths}" >> "${STDERR_TARGET}"
- fi
- # Similar reason, but with relative paths.
- local rel_paths=$(egrep -n '^[-+]{3} [^ ]*[.][.]/' "${PATCH_TARGET}")
- if [[ -n ${rel_paths} ]] ; then
- echo
- eerror "Rejected Patch: ${patchname} !"
- eerror " ( ${PATCH_TARGET} )"
- eerror
- eerror "Your patch uses relative paths '../':"
- eerror "${rel_paths}"
- echo
- die "you need to fix the relative paths in patch"
- fi
- # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/
- local patch_cmd
- while [[ ${count} -lt 5 ]] ; do
- patch_cmd="${patch} -p${count} ${GMT_EPATCH_OPTS}"
- # Generate some useful debug info ...
- (
- _gmt_epatch_draw_line "***** ${patchname} *****"
- echo
- echo "PATCH COMMAND: ${patch_cmd} < '${PATCH_TARGET}'"
- echo
- _gmt_epatch_draw_line "***** ${patchname} *****"
- ${patch_cmd} --dry-run -f < "${PATCH_TARGET}" 2>&1
- ret=$?
- echo
- echo "patch program exited with status ${ret}"
- exit ${ret}
- ) >> "${STDERR_TARGET}"
- if [ $? -eq 0 ] ; then
- (
- _gmt_epatch_draw_line "***** ${patchname} *****"
- echo
- echo "ACTUALLY APPLYING ${patchname} ..."
- echo
- _gmt_epatch_draw_line "***** ${patchname} *****"
- ${patch_cmd} < "${PATCH_TARGET}" 2>&1
- ret=$?
- echo
- echo "patch program exited with status ${ret}"
- exit ${ret}
- ) >> "${STDERR_TARGET}"
- if [ $? -ne 0 ] ; then
- echo
- eerror "A dry-run of patch command succeeded, but actually"
- eerror "applying the patch failed!"
- #die "Real world sux compared to the dreamworld!"
- count=5
- fi
- break
- fi
- : $(( count++ ))
- done
- # if we had to decompress the patch, delete the temp one
- if [[ -n ${PIPE_CMD} ]] ; then
- rm -f "${PATCH_TARGET}"
- fi
- if [[ ${count} -ge 5 ]] ; then
- echo
- eerror "Failed Patch: ${patchname} ! (gmt_epatch)"
- eerror " ( ${PATCH_TARGET} )"
- eerror
- eerror "Clues might be in:"
- eerror
- eerror " ${STDERR_TARGET}"
- echo
- die "Failed Patch: ${patchname}! (gmt_epatch)"
- fi
- # if everything worked, delete the full debug patch log
- rm -f "${STDERR_TARGET}"
- # then log away the exact stuff for people to review later
- cat <<-EOF >> "${T}/gmt_epatch.log"
- PATCH: ${x}
- CMD: ${patch_cmd}
- PWD: ${PWD}
- EOF
- eend 0
- done
- [[ ${GMT_SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
- : # everything worked
- }
- gmt_isdigit() {
- local d
- for d ; do
- [[ ${d:-bad} == *[!0-9]* ]] && return 1
- done
- return 0
- }
- gmt_estack_push() {
- [[ $# -eq 0 ]] && die "gmt_estack_push: incorrect # of arguments"
- local stack_name="_GMT_ESTACK_$1_" ; shift
- eval ${stack_name}+=\( \"\$@\" \)
- }
- gmt_estack_pop() {
- [[ $# -eq 0 || $# -gt 2 ]] && die "gmt_estack_pop: incorrect # of arguments"
- local _estack_name="_GMT_ESTACK_$1_" ; shift
- local _estack_retvar=$1 ; shift
- eval local _estack_i=\${#${_estack_name}\[@\]}
- # Don't warn -- let the caller interpret this as a failure
- # or as normal behavior (akin to `shift`)
- [[ $(( --_estack_i )) -eq -1 ]] && return 1
- if [[ -n ${_estack_retvar} ]] ; then
- eval ${_estack_retvar}=\"\${${_estack_name}\[${_estack_i}\]}\"
- fi
- eval unset ${_estack_name}\[${_estack_i}\]
- }
- gmt_evar_push() {
- local var val
- for var ; do
- [[ ${!var+set} == "set" ]] \
- && val=${!var} \
- || val="unset_76xc3x46x065xb4cax59f9x9e6793f94"
- gmt_estack_push evar "${var}" "${val}"
- done
- }
- gmt_evar_push_set() {
- local var=$1
- gmt_evar_push ${var}
- case $# in
- 1) unset ${var} ;;
- 2) printf -v "${var}" '%s' "$2" ;;
- *) die "${FUNCNAME}: incorrect # of args: $*" ;;
- esac
- }
- gmt_evar_pop() {
- local cnt=${1:-bad}
- case $# in
- 0) cnt=1 ;;
- 1) gmt_isdigit "${cnt}" || die "${FUNCNAME}: first arg must be a number: $*" ;;
- *) die "${FUNCNAME}: only accepts one arg: $*" ;;
- esac
- local var val
- while (( cnt-- )) ; do
- gmt_estack_pop evar val || die "${FUNCNAME}: unbalanced push"
- gmt_estack_pop evar var || die "${FUNCNAME}: unbalanced push"
- [[ ${val} == "unset_76xc3x46x065xb4cax59f9x9e6793f94" ]] \
- && unset ${var} \
- || printf -v "${var}" '%s' "${val}"
- done
- }
- gmt_eshopts_push() {
- if [[ $1 == -[su] ]] ; then
- gmt_estack_push eshopts "$(shopt -p)"
- [[ $# -eq 0 ]] && return 0
- shopt "$@" || die "${FUNCNAME}: bad options to shopt: $*"
- else
- gmt_estack_push eshopts $-
- [[ $# -eq 0 ]] && return 0
- set "$@" || die "${FUNCNAME}: bad options to set: $*"
- fi
- }
- # @FUNCTION: gmt_eshopts_pop
- # @USAGE:
- # @DESCRIPTION:
- # Restore the shell options to the state saved with the corresponding
- # gmt_eshopts_push call. See that function for more details.
- gmt_eshopts_pop() {
- local s
- gmt_estack_pop eshopts s || die "${FUNCNAME}: unbalanced push"
- if [[ ${s} == "shopt -"* ]] ; then
- eval "${s}" || die "${FUNCNAME}: sanity: invalid shopt options: ${s}"
- else
- set +$- || die "${FUNCNAME}: sanity: invalid shell settings: $-"
- set -${s} || die "${FUNCNAME}: sanity: unable to restore saved shell settings: ${s}"
- fi
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement