commit:     3b0150e488972b02c45c71192507300d823a361f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri May 30 11:02:11 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jun  3 20:49:52 2025 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=3b0150e4

Use contains_word() almost everywhere that it is applicable

As was mentioned by the commit introducing the contains_word() function,
it addresses a use case for which the has() function is rampantly
misappropriated. To briefly recap here, has() compares its first operand
to the following operands in a stringwise fashion. However, it is
commonly employed in the following fashion.

  # Here, wordlist contains zero or more whitespace-separated words.
  has some-word ${wordlist}

Thus, the shell is tasked with splitting the expansion of the variable -
a process which is sensitive to the prevailing value of IFS. Further, it
is exceedingly rare for such expansions to be guarded by the "noglob"
shell option, meaning that unintentional pathname expansion remains an
attendant risk.

The contains_word() function safely and efficiently addresses this
particular use case.

  # Unaffected by IFS. Immune to pathname expansion. Fast.
  contains_word some-word "${wordlist}"

This commit replaces the use of has() with contains_word() in almost
every case where it is applicable, though I elected to defer in several
instances that require further investigation. I would add that this
commit touches 18 files which previously accounted for no fewer than 175
SC2086 warnings. This number is thus reduced to 97 in one fell swoop.

See-also: 4a4631eef7186c29668a8c049d988b61469940fd
Link: https://github.com/gentoo/portage/pull/458
Link: https://www.shellcheck.net/wiki/SC2086
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 bin/bashrc-functions.sh                    |  4 +--
 bin/ebuild-helpers/doins                   |  2 +-
 bin/ebuild.sh                              | 12 +++++----
 bin/emerge-webrsync                        | 13 +++++----
 bin/install-qa-check.d/05prefix            |  5 ++--
 bin/install-qa-check.d/10executable-issues | 10 +++----
 bin/install-qa-check.d/10ignored-flags     |  7 ++---
 bin/install-qa-check.d/60pkgconfig         |  2 +-
 bin/install-qa-check.d/80libraries         |  2 +-
 bin/install-qa-check.d/80multilib-strict   |  6 ++---
 bin/install-qa-check.d/90cython-dep        |  2 +-
 bin/install-qa-check.d/90gcc-warnings      |  2 +-
 bin/isolated-functions.sh                  |  5 ++--
 bin/misc-functions.sh                      | 39 +++++++++++++++------------
 bin/phase-functions.sh                     | 43 +++++++++++++++++-------------
 bin/phase-helpers.sh                       |  7 +++--
 bin/postinst-qa-check.d/50xdg-utils        |  6 ++---
 misc/emerge-delta-webrsync                 | 11 +++++---
 18 files changed, 101 insertions(+), 77 deletions(-)

diff --git a/bin/bashrc-functions.sh b/bin/bashrc-functions.sh
index 7859663fdb..9b8b74dc7e 100644
--- a/bin/bashrc-functions.sh
+++ b/bin/bashrc-functions.sh
@@ -6,7 +6,7 @@ register_die_hook() {
        local hook
 
        for hook; do
-               if ! has "${hook}" ${EBUILD_DEATH_HOOKS}; then
+               if ! contains_word "${hook}" "${EBUILD_DEATH_HOOKS}"; then
                        export EBUILD_DEATH_HOOKS+=" ${hook}"
                fi
        done
@@ -16,7 +16,7 @@ register_success_hook() {
        local hook
 
        for hook; do
-               if ! has "${hook}" ${EBUILD_SUCCESS_HOOKS}; then
+               if ! contains_word "${hook}" "${EBUILD_SUCCESS_HOOKS}"; then
                        export EBUILD_SUCCESS_HOOKS+=" ${hook}"
                fi
        done

diff --git a/bin/ebuild-helpers/doins b/bin/ebuild-helpers/doins
index 8e5b45f2c1..ff5e88f3a5 100755
--- a/bin/ebuild-helpers/doins
+++ b/bin/ebuild-helpers/doins
@@ -85,7 +85,7 @@ if [[ "${DOINSSTRICTOPTION}" == 1 ]]; then
        DOINS_ARGS+=( --strict_option )
 fi
 
-if has xattr ${FEATURES}; then
+if contains_word xattr "${FEATURES}"; then
        DOINS_ARGS+=(
                --enable_copy_xattr
                "--xattr_exclude=${PORTAGE_XATTR_EXCLUDE}"

diff --git a/bin/ebuild.sh b/bin/ebuild.sh
index 832a85affa..9b90522e25 100755
--- a/bin/ebuild.sh
+++ b/bin/ebuild.sh
@@ -258,7 +258,7 @@ inherit() {
                        # disabled for nofetch, since that can be called by 
repoman and
                        # that triggers bug #407449 due to repoman not exporting
                        # non-essential variables such as INHERITED.
-                       if ! has ${ECLASS} ${INHERITED} ${__INHERITED_QA_CACHE} 
; then
+                       if ! contains_word "${ECLASS}" "${INHERITED} 
${__INHERITED_QA_CACHE}"; then
                                eqawarn "QA Notice: Eclass '${ECLASS}' 
inherited illegally in ${CATEGORY}/${PF} ${EBUILD_PHASE}"
                        fi
                fi
@@ -374,7 +374,9 @@ inherit() {
                        fi
                        unset $__export_funcs_var
 
-                       has $1 ${INHERITED} || export INHERITED="${INHERITED} 
$1"
+                       if ! contains_word "$1" "${INHERITED}"; then
+                               export INHERITED="${INHERITED} $1"
+                       fi
                        if [[ ${ECLASS_DEPTH} -eq 1 ]]; then
                                export 
PORTAGE_EXPLICIT_INHERIT="${PORTAGE_EXPLICIT_INHERIT} $1"
                        fi
@@ -707,11 +709,11 @@ if [[ ${EBUILD_PHASE} != clean?(rm) ]]; then
 
                if [[ ${EBUILD_PHASE} != depend ]] ; then
 
-                       if has distcc ${FEATURES} ; then
+                       if contains_word distcc "${FEATURES}"; then
                                [[ -n ${DISTCC_LOG} ]] && addwrite 
"${DISTCC_LOG%/*}"
                        fi
 
-                       if has ccache ${FEATURES} ; then
+                       if contains_word ccache "${FEATURES}"; then
                                if [[ -n ${CCACHE_DIR} ]] ; then
                                        addread "${CCACHE_DIR}"
                                        addwrite "${CCACHE_DIR}"
@@ -723,7 +725,7 @@ if [[ ${EBUILD_PHASE} != clean?(rm) ]]; then
        fi
 fi
 
-if has nostrip ${FEATURES} ${PORTAGE_RESTRICT} || has strip 
${PORTAGE_RESTRICT} ; then
+if contains_word nostrip "${FEATURES} ${PORTAGE_RESTRICT}" || contains_word 
strip "${PORTAGE_RESTRICT}"; then
        export DEBUGBUILD=1
 fi
 

diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync
index 3a9ee03984..f23c285624 100755
--- a/bin/emerge-webrsync
+++ b/bin/emerge-webrsync
@@ -111,7 +111,8 @@ handle_pgp_setup() {
        # WEBRSYNC_VERIFY_SIGNATURE=2: use legacy FEATURES="webrsync-gpg"
        WEBRSYNC_VERIFY_SIGNATURE=1
 
-       has webrsync-gpg ${FEATURES} && webrsync_gpg=1 || webrsync_gpg=0
+       contains_word webrsync-gpg "${FEATURES}"
+       webrsync_gpg=$(( $? == 0 ))
 
        repo_has_webrsync_verify=$(
                has $(__repo_attr "${repo_name}" sync-webrsync-verify-signature 
| LC_ALL=C tr '[:upper:]' '[:lower:]') true yes
@@ -412,7 +413,7 @@ sync_local() {
        [[ ${PORTAGE_QUIET} -eq 1 ]] || einfo "Syncing local repository ..."
 
        local ownership="${PORTAGE_USERNAME}:${PORTAGE_GRPNAME}"
-       if has usersync ${FEATURES} ; then
+       if contains_word usersync "${FEATURES}"; then
                case "${USERLAND}" in
                        BSD)
                                ownership=$(stat -f '%Su:%Sg' 
"${repo_location}")
@@ -457,7 +458,7 @@ sync_local() {
                [[ ${PORTAGE_QUIET} == 1 ]] || einfo "Cleaning up ..."
        fi
 
-       if has metadata-transfer ${FEATURES} ; then
+       if contains_word metadata-transfer "${FEATURES}"; then
                einfo "Updating cache ..."
                "${emerge}" --metadata
        fi
@@ -466,7 +467,9 @@ sync_local() {
        [[ -x "${post_sync}" ]] && "${post_sync}"
 
        # --quiet suppresses output if there are no relevant news items
-       has news ${FEATURES} && "${emerge}" --check-news --quiet
+       if contains_word news "${FEATURES}"; then
+               "${emerge}" --check-news --quiet
+       fi
        return 0
 }
 
@@ -700,7 +703,7 @@ main() {
        if [[ ! -d ${repo_location} ]]; then
                mkdir -p "${repo_location}" || die
 
-               if has usersync ${FEATURES} ; then
+               if contains_word usersync "${FEATURES}"; then
                        chown "${PORTAGE_USERNAME}":"${PORTAGE_GRPNAME}" 
"${repo_location}" || die
                fi
        fi

diff --git a/bin/install-qa-check.d/05prefix b/bin/install-qa-check.d/05prefix
index 9217113200..dc201b53df 100644
--- a/bin/install-qa-check.d/05prefix
+++ b/bin/install-qa-check.d/05prefix
@@ -96,11 +96,10 @@ install_qa_check_prefix() {
                                echo "${fn#${D}}:${line[0]} (script ${fn##*/} 
installed in PATH but interpreter ${line[0]} not found)" \
                                        >> "${T}"/non-prefix-shebangs-errs
                        fi
-               else
+               elif contains_word stricter "${FEATURES}"; then
                        # unprefixed/invalid shebang, but outside ${PATH}, this 
may be
                        # intended (e.g. config.guess) so remain silent by 
default
-                       has stricter ${FEATURES} && \
-                               eqawarn "QA Notice: invalid shebang in 
${fn#${D}}: ${line[0]}"
+                       eqawarn "QA Notice: invalid shebang in ${fn#${D}}: 
${line[0]}"
                fi
        done
        if [[ -e "${T}"/non-prefix-shebangs-errs ]] ; then

diff --git a/bin/install-qa-check.d/10executable-issues 
b/bin/install-qa-check.d/10executable-issues
index 5dc7cec950..164f062a21 100644
--- a/bin/install-qa-check.d/10executable-issues
+++ b/bin/install-qa-check.d/10executable-issues
@@ -4,7 +4,7 @@
 # text relocations, executable stacks
 
 elf_check() {
-       if ! type -P scanelf >/dev/null || has binchecks ${PORTAGE_RESTRICT}; 
then
+       if ! type -P scanelf >/dev/null || contains_word binchecks 
"${PORTAGE_RESTRICT}"; then
                return
        fi
 
@@ -12,7 +12,7 @@ elf_check() {
        local f x
 
        # display warnings when using stricter because we die afterwards
-       if has stricter ${FEATURES} ; then
+       if contains_word stricter "${FEATURES}"; then
                local PORTAGE_QUIET
        fi
 
@@ -33,7 +33,7 @@ elf_check() {
        for dir in "${forbidden_dirs[@]}"; do
                while read l; do
                        f+="  ${l/:/\n    RPATH: }\n"
-                       if ! has stricter ${FEATURES}; then
+                       if ! contains_word stricter "${FEATURES}"; then
                                __vecho "Auto fixing rpaths for ${l%%:*}"
                                TMPDIR="${dir}" scanelf -BXr "${l%%:*}" -o 
/dev/null
                        fi
@@ -54,7 +54,7 @@ elf_check() {
                eqawarn " with the maintainer of the package."
                eqawarn "${f}${f:+${x:+\n}}${x}"
                __vecho -ne '\n'
-               if [[ -n ${x} ]] || has stricter ${FEATURES} ; then
+               if [[ -n ${x} ]] || contains_word stricter "${FEATURES}"; then
                        insecure_rpath=1
                fi
        fi
@@ -139,7 +139,7 @@ elf_check() {
 
        if [[ ${insecure_rpath} -eq 1 ]] ; then
                die "Aborting due to serious QA concerns with RUNPATH/RPATH"
-       elif [[ -n ${die_msg} ]] && has stricter ${FEATURES} ; then
+       elif [[ -n ${die_msg} ]] && contains_word stricter "${FEATURES}"; then
                die "Aborting due to QA concerns: ${die_msg}"
        fi
 }

diff --git a/bin/install-qa-check.d/10ignored-flags 
b/bin/install-qa-check.d/10ignored-flags
index 5642ff7436..7a92be502b 100644
--- a/bin/install-qa-check.d/10ignored-flags
+++ b/bin/install-qa-check.d/10ignored-flags
@@ -3,7 +3,7 @@
 # QA checks for ignored *FLAGS.
 
 ignored_flag_check() {
-       if ! type -P scanelf >/dev/null || has binchecks ${PORTAGE_RESTRICT}; 
then
+       if ! type -P scanelf >/dev/null || contains_word binchecks 
"${PORTAGE_RESTRICT}"; then
                return
        fi
 
@@ -67,8 +67,9 @@ ignored_flag_check() {
        fi
 
        # Check for files built without respecting LDFLAGS
-       if [[ "${LDFLAGS}" == *,--defsym=__gentoo_check_ldflags__* ]] && \
-               ! has binchecks ${PORTAGE_RESTRICT} ; then
+       if [[ "${LDFLAGS}" == *,--defsym=__gentoo_check_ldflags__* ]] \
+               && ! contains_word binchecks "${PORTAGE_RESTRICT}"
+       then
                f=$(LC_ALL=C comm -2 -3 <(scanelf -qyRF '#k%p' -k .dynsym 
"${ED%/}/" | LC_ALL=C sort) \
                        <(scanelf -qyRF '#s%p' -s __gentoo_check_ldflags__ 
"${ED%/}/" | LC_ALL=C sort))
                if [[ -n ${f} ]] ; then

diff --git a/bin/install-qa-check.d/60pkgconfig 
b/bin/install-qa-check.d/60pkgconfig
index f26ae5dffb..1e8a18ed9e 100644
--- a/bin/install-qa-check.d/60pkgconfig
+++ b/bin/install-qa-check.d/60pkgconfig
@@ -136,7 +136,7 @@ pkgconfig_check() {
                # Skip result reporting if *_p* because for both _pN and _preN, 
we
                # don't generally expect the versions to be exactly accurate, 
and
                # we want to avoid false positives.
-               if [[ ${#bad_files[@]} -gt 0 && ${PV} != *_p* ]] && ! has live 
${PROPERTIES} ; then
+               if [[ ${#bad_files[@]} -gt 0 && ${PV} != *_p* ]] && ! 
contains_word live "${PROPERTIES}"; then
                        eqawarn "QA Notice: pkg-config files with mismatched 
Version found!"
                        eqawarn "The Version field of the following files does 
not match ${QA_PKGCONFIG_VERSION}"
                        local bad_file

diff --git a/bin/install-qa-check.d/80libraries 
b/bin/install-qa-check.d/80libraries
index 4e55db8b52..4dd392255a 100644
--- a/bin/install-qa-check.d/80libraries
+++ b/bin/install-qa-check.d/80libraries
@@ -94,7 +94,7 @@ scanelf_lib_check() {
 lib_check() {
        local f x i j
 
-       if type -P scanelf >/dev/null && ! has binchecks ${PORTAGE_RESTRICT}; 
then
+       if type -P scanelf >/dev/null && ! contains_word binchecks 
"${PORTAGE_RESTRICT}"; then
                scanelf_lib_check
        fi
 

diff --git a/bin/install-qa-check.d/80multilib-strict 
b/bin/install-qa-check.d/80multilib-strict
index 715e39452f..b3803a980a 100644
--- a/bin/install-qa-check.d/80multilib-strict
+++ b/bin/install-qa-check.d/80multilib-strict
@@ -5,9 +5,9 @@
 multilib_strict_check() {
        local IFS abort dir file
 
-       if has multilib-strict ${FEATURES} && \
-          type find &>/dev/null && type file &>/dev/null && \
-          [[ -n ${MULTILIB_STRICT_DIRS} && -n ${MULTILIB_STRICT_DENY} ]]
+       if contains_word multilib-strict "${FEATURES}" \
+               && type find file &>/dev/null \
+               && [[ ${MULTILIB_STRICT_DIRS} && ${MULTILIB_STRICT_DENY} ]]
        then
                rm -f "${T}/multilib-strict.log"
                for dir in ${MULTILIB_STRICT_DIRS} ; do

diff --git a/bin/install-qa-check.d/90cython-dep 
b/bin/install-qa-check.d/90cython-dep
index d9d40d9f8c..759f65cedb 100644
--- a/bin/install-qa-check.d/90cython-dep
+++ b/bin/install-qa-check.d/90cython-dep
@@ -7,7 +7,7 @@ cython_dep_check() {
        [[ ${CATEGORY}/${PN} == dev-python/cython ]] && return
        # grepping log files is expensive, so do it only for ebuilds using
        # distutils-r1
-       has distutils-r1 ${INHERITED} || return
+       contains_word distutils-r1 "${INHERITED}" || return
        [[ ${BDEPEND} == *dev-python/cython* ]] && return
 
        # Evaluate misc gcc warnings

diff --git a/bin/install-qa-check.d/90gcc-warnings 
b/bin/install-qa-check.d/90gcc-warnings
index 0b98dd5c5c..691a97f93f 100644
--- a/bin/install-qa-check.d/90gcc-warnings
+++ b/bin/install-qa-check.d/90gcc-warnings
@@ -185,7 +185,7 @@ gcc_warn_check() {
                to the upstream developers of this software.
                Homepage: ${HOMEPAGE}
                EOF
-               if has stricter ${FEATURES}; then
+               if contains_word stricter "${FEATURES}"; then
                        die "install aborted due to severe warnings shown above"
                fi
        fi

diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh
index ae28125de4..2cec30edfe 100644
--- a/bin/isolated-functions.sh
+++ b/bin/isolated-functions.sh
@@ -215,8 +215,9 @@ die() {
 
        if [[ -n ${PORTAGE_LOG_FILE} ]] ; then
                eerror "The complete build log is located at 
'${PORTAGE_LOG_FILE}'."
-               if [[ ${PORTAGE_LOG_FILE} != ${T}/* ]] && \
-                       ! has fail-clean ${FEATURES} ; then
+               if [[ ${PORTAGE_LOG_FILE} != ${T}/* ]] \
+                       && ! contains_word fail-clean "${FEATURES}"
+               then
                        # Display path to symlink in ${T}, as requested in bug 
#412865.
                        local log_ext=log
                        [[ ${PORTAGE_LOG_FILE} != *.log ]] && 
log_ext+=.${PORTAGE_LOG_FILE##*.}

diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
index 9510116c3c..47e7ae72e4 100755
--- a/bin/misc-functions.sh
+++ b/bin/misc-functions.sh
@@ -137,7 +137,7 @@ install_qa_check() {
                )
        done < <(printf "%s\0" "${qa_checks[@]}" | LC_ALL=C sort -u -z)
 
-       if has chflags ${FEATURES} ; then
+       if contains_word chflags "${FEATURES}"; then
                # Save all the file flags for restoration afterwards.
                mtree -c -p "${ED}" -k flags > "${T}/bsdflags.mtree"
                # Remove all the file flags so that we can do anything 
necessary.
@@ -153,13 +153,13 @@ install_qa_check() {
 
        # If binpkg-docompress is enabled, apply compression before creating
        # the binary package.
-       if has binpkg-docompress ${FEATURES}; then
+       if contains_word binpkg-docompress "${FEATURES}"; then
                "${PORTAGE_BIN_PATH}"/ecompress --queue 
"${PORTAGE_DOCOMPRESS[@]}"
                "${PORTAGE_BIN_PATH}"/ecompress --ignore 
"${PORTAGE_DOCOMPRESS_SKIP[@]}"
                "${PORTAGE_BIN_PATH}"/ecompress --dequeue
        fi
 
-       if has chflags ${FEATURES} ; then
+       if contains_word chflags "${FEATURES}"; then
                # Restore all the file flags that were saved earlier on.
                mtree -U -e -p "${ED}" -k flags < "${T}/bsdflags.mtree" &> 
/dev/null
        fi
@@ -236,7 +236,7 @@ install_qa_check() {
                                eqawarn "QA Notice: <stabilize-allarches/> 
found on package installing ELF files"
                        fi
 
-                       if has binchecks ${PORTAGE_RESTRICT}; then
+                       if contains_word binchecks "${PORTAGE_RESTRICT}"; then
                                eqawarn "QA Notice: RESTRICT=binchecks 
prevented checks on these ELF files:"
                                eqawarn "$(while read -r x; do x=${x#*;} ; 
x=${x%%;*} ; echo "${x#${EPREFIX}}" ; done < 
"${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2)"
                        fi
@@ -247,7 +247,7 @@ install_qa_check() {
        # the binary package.
        # Note: disabling it won't help with packages calling prepstrip 
directly.
        # We do this after the scanelf bits so that we can reuse the data. bug 
#749624.
-       if has binpkg-dostrip ${FEATURES}; then
+       if contains_word binpkg-dostrip "${FEATURES}"; then
                export STRIP_MASK
                if ___eapi_has_dostrip; then
                        "${PORTAGE_BIN_PATH}"/estrip --queue 
"${PORTAGE_DOSTRIP[@]}"
@@ -261,9 +261,10 @@ install_qa_check() {
        # Prematurely delete WORKDIR in case merge-wait is enabled to
        # decrease the space used by portage build directories until the
        # packages are merged and cleaned.
-       if has merge-wait ${FEATURES} &&
-               ! has keepwork ${FEATURES} &&
-               ! has noclean ${FEATURES} ; then
+       if contains_word merge-wait "${FEATURES}" \
+               && ! contains_word keepwork "${FEATURES}" \
+               && ! contains_word noclean "${FEATURES}"
+       then
                rm -rf "${WORKDIR}"
        fi
 }
@@ -275,7 +276,7 @@ __dyn_instprep() {
                return 0
        fi
 
-       if has chflags ${FEATURES}; then
+       if contains_word chflags "${FEATURES}"; then
                # Save all the file flags for restoration afterwards.
                mtree -c -p "${ED}" -k flags > "${T}/bsdflags.mtree"
                # Remove all the file flags so that we can do anything 
necessary.
@@ -285,7 +286,7 @@ __dyn_instprep() {
 
        # If binpkg-docompress is disabled, we need to apply compression
        # before installing.
-       if ! has binpkg-docompress ${FEATURES}; then
+       if ! contains_word binpkg-docompress "${FEATURES}"; then
                "${PORTAGE_BIN_PATH}"/ecompress --queue 
"${PORTAGE_DOCOMPRESS[@]}"
                "${PORTAGE_BIN_PATH}"/ecompress --ignore 
"${PORTAGE_DOCOMPRESS_SKIP[@]}"
                "${PORTAGE_BIN_PATH}"/ecompress --dequeue
@@ -293,7 +294,7 @@ __dyn_instprep() {
 
        # If binpkg-dostrip is disabled, apply stripping before creating
        # the binary package.
-       if ! has binpkg-dostrip ${FEATURES}; then
+       if ! contains_word binpkg-dostrip "${FEATURES}"; then
                export STRIP_MASK
                if ___eapi_has_dostrip; then
                        "${PORTAGE_BIN_PATH}"/estrip --queue 
"${PORTAGE_DOSTRIP[@]}"
@@ -304,7 +305,7 @@ __dyn_instprep() {
                fi
        fi
 
-       if has chflags ${FEATURES}; then
+       if contains_word chflags "${FEATURES}"; then
                # Restore all the file flags that were saved earlier on.
                mtree -U -e -p "${ED}" -k flags < "${T}/bsdflags.mtree" &> 
/dev/null
        fi
@@ -380,7 +381,7 @@ preinst_mask() {
        # from bashrc.
        local f x
        for f in man info doc; do
-               if has no${f} ${FEATURES}; then
+               if contains_word "no${f}" "${FEATURES}"; then
                        INSTALL_MASK+=" ${EPREFIX}/usr/share/${f}"
                fi
        done
@@ -408,7 +409,7 @@ preinst_sfperms() {
        fi
 
        # Smart FileSystem Permissions
-       if has sfperms ${FEATURES}; then
+       if contains_word sfperms "${FEATURES}"; then
                local i
                find "${ED}" -type f -perm -4000 -print0 | \
                while read -r -d $'\0' i ; do
@@ -448,7 +449,7 @@ preinst_suid_scan() {
        fi
 
        # Total suid control
-       if has suidctl ${FEATURES}; then
+       if contains_word suidctl "${FEATURES}"; then
                local i sfconf x
                sfconf=${PORTAGE_CONFIGROOT}etc/portage/suidctl.conf
                # sandbox prevents us from writing directly
@@ -486,7 +487,7 @@ preinst_selinux_labels() {
                 eerror "${FUNCNAME}: D is unset"
                 return 1
        fi
-       if has selinux ${FEATURES}; then
+       if contains_word selinux "${FEATURES}"; then
                # SELinux file labeling (needs to execute after preinst)
                # only attempt to label if setfiles is executable
                # and 'context' is available on selinuxfs.
@@ -536,7 +537,11 @@ __dyn_package() {
                local tar_options=""
 
                [[ ${PORTAGE_VERBOSE} = 1 ]] && tar_options+=" -v"
-               has xattr ${FEATURES} && [[ $(tar --help 2> /dev/null) == 
*--xattrs* ]] && tar_options+=" --xattrs"
+               if contains_word xattr "${FEATURES}" \
+                       && [[ $(tar --help 2>/dev/null) == *--xattrs* ]]
+               then
+                       tar_options+=" --xattrs"
+               fi
 
                [[ -z "${PORTAGE_COMPRESSION_COMMAND}" ]] && die 
"PORTAGE_COMPRESSION_COMMAND is unset"
 

diff --git a/bin/phase-functions.sh b/bin/phase-functions.sh
index 9749f65f60..19b643d9d5 100644
--- a/bin/phase-functions.sh
+++ b/bin/phase-functions.sh
@@ -287,7 +287,7 @@ __dyn_clean() {
                return 0
        fi
 
-       if has chflags ${FEATURES} ; then
+       if contains_word chflags "${FEATURES}"; then
                chflags -R noschg,nouchg,nosappnd,nouappnd "${PORTAGE_BUILDDIR}"
                chflags -R nosunlnk,nouunlnk "${PORTAGE_BUILDDIR}" 2>/dev/null
        fi
@@ -301,12 +301,14 @@ __dyn_clean() {
                "${PORTAGE_BUILDDIR}/empty"
        rm -f "${PORTAGE_BUILDDIR}/.installed"
 
-       if [[ ${EMERGE_FROM} = binary ]] || \
-               ! has keeptemp ${FEATURES} && ! has keepwork ${FEATURES} ; then
+       if [[ ${EMERGE_FROM} = binary ]] \
+               || ! contains_word keeptemp "${FEATURES}" \
+               && ! contains_word keepwork "${FEATURES}"
+       then
                rm -rf "${T}"
        fi
 
-       if [[ ${EMERGE_FROM} = binary ]] || ! has keepwork ${FEATURES} ; then
+       if [[ ${EMERGE_FROM} = binary ]] || ! contains_word keepwork 
"${FEATURES}"; then
                rm -f 
"${PORTAGE_BUILDDIR}"/.{ebuild_changed,logid,pretended,setuped,unpacked,prepared}
 \
                        
"${PORTAGE_BUILDDIR}"/.{configured,compiled,tested,packaged,instprepped} \
                        "${PORTAGE_BUILDDIR}"/.die_hooks \
@@ -380,7 +382,7 @@ __abort_install() {
 __has_phase_defined_up_to() {
        local phase
        for phase in unpack prepare configure compile test install; do
-               has ${phase} ${DEFINED_PHASES} && return 0
+               contains_word "${phase}" "${DEFINED_PHASES}" && return 0
                [[ ${phase} == $1 ]] && return 1
        done
        # We shouldn't actually get here
@@ -507,16 +509,17 @@ __dyn_test() {
                die "The source directory '${S}' doesn't exist"
        fi
 
-       if has test ${PORTAGE_RESTRICT} && ! has all ${ALLOW_TEST} &&
-                       ! { has test_network ${PORTAGE_PROPERTIES} && has 
network ${ALLOW_TEST}; } &&
-                       ! { has test_privileged ${PORTAGE_PROPERTIES} && has 
privileged ${ALLOW_TEST}; }
+       if contains_word test "${PORTAGE_RESTRICT}" \
+               && ! contains_word all "${ALLOW_TEST}" \
+               && ! { contains_word test_network "${PORTAGE_PROPERTIES}" && 
contains_word network "${ALLOW_TEST}"; } \
+               && ! { contains_word test_privileged "${PORTAGE_PROPERTIES}" && 
contains_word privileged "${ALLOW_TEST}"; }
        then
                einfo "Skipping make test/check due to ebuild restriction."
                __vecho ">>> Test phase [disabled because of RESTRICT=test]: 
${CATEGORY}/${PF}"
 
        # If ${EBUILD_FORCE_TEST} == 1 and FEATURES came from ${T}/environment
        # then it might not have FEATURES=test like it's supposed to here.
-       elif [[ ${EBUILD_FORCE_TEST} != 1 ]] && ! has test ${FEATURES} ; then
+       elif [[ ${EBUILD_FORCE_TEST} != 1 ]] && ! contains_word test 
"${FEATURES}"; then
                __vecho ">>> Test phase [not enabled]: ${CATEGORY}/${PF}"
        else
                local save_sp=${SANDBOX_PREDICT}
@@ -539,7 +542,7 @@ __dyn_test() {
 __dyn_install() {
        [[ -z "${PORTAGE_BUILDDIR}" ]] && die "${FUNCNAME}: PORTAGE_BUILDDIR is 
unset"
 
-       if has noauto ${FEATURES} ; then
+       if contains_word noauto "${FEATURES}"; then
                rm -f "${PORTAGE_BUILDDIR}/.installed"
        elif [[ -e ${PORTAGE_BUILDDIR}/.installed ]] ; then
                __vecho ">>> It appears that '${PF}' is already installed; 
skipping."
@@ -726,7 +729,7 @@ __dyn_install() {
        cp "${EBUILD}" "${PF}.ebuild"
        [[ -n "${PORTAGE_REPO_NAME}" ]]  && echo "${PORTAGE_REPO_NAME}" > 
repository
        [[ -n ${PORTAGE_REPO_REVISIONS} ]] && echo "${PORTAGE_REPO_REVISIONS}" 
> REPO_REVISIONS
-       if has nostrip ${FEATURES} ${PORTAGE_RESTRICT} || has strip 
${PORTAGE_RESTRICT}; then
+       if contains_word nostrip "${FEATURES} ${PORTAGE_RESTRICT}" || 
contains_word strip "${PORTAGE_RESTRICT}"; then
                >> DEBUGBUILD
        fi
        trap - SIGINT SIGQUIT
@@ -780,7 +783,7 @@ __dyn_help() {
        echo "  C++ flags   : ${CXXFLAGS}"
        echo "  make flags  : ${MAKEOPTS}"
        echo -n "  build mode  : "
-       if has nostrip ${FEATURES} ${PORTAGE_RESTRICT} || has strip 
${PORTAGE_RESTRICT}; then
+       if contains_word nostrip "${FEATURES} ${PORTAGE_RESTRICT}" || 
contains_word strip "${PORTAGE_RESTRICT}"; then
                echo "debug (large)"
        else
                echo "production (stripped)"
@@ -1003,7 +1006,9 @@ __ebuild_main() {
 
        # Force configure scripts that automatically detect ccache to
        # respect FEATURES="-ccache".
-       has ccache ${FEATURES} || export CCACHE_DISABLE=1
+       if ! contains_word ccache "${FEATURES}"; then
+               export CCACHE_DISABLE=1
+       fi
 
        local ___phase_func=$(__ebuild_arg_to_phase "${EBUILD_PHASE}")
        [[ -n ${___phase_func} ]] && __ebuild_phase_funcs "${EAPI}" 
"${___phase_func}"
@@ -1055,12 +1060,14 @@ __ebuild_main() {
                        done
                        unset x
 
-                       has distcc ${FEATURES} && [[ -n ${DISTCC_DIR} ]] && \
-                               [[ ${SANDBOX_WRITE/${DISTCC_DIR}} = 
${SANDBOX_WRITE} ]] && \
-                               addwrite "${DISTCC_DIR}"
+                       contains_word distcc "${FEATURES}" \
+                       && [[ ${DISTCC_DIR} ]] \
+                       && [[ ${SANDBOX_WRITE/${DISTCC_DIR}} == 
${SANDBOX_WRITE} ]] \
+                       && addwrite "${DISTCC_DIR}"
 
-                       if has noauto ${FEATURES} && \
-                               [[ ! -f ${PORTAGE_BUILDDIR}/.unpacked ]] ; then
+                       if contains_word noauto "${FEATURES}" \
+                               && [[ ! -f ${PORTAGE_BUILDDIR}/.unpacked ]]
+                       then
                                echo
                                echo "!!! We apparently haven't unpacked..." \
                                        "This is probably not what you"

diff --git a/bin/phase-helpers.sh b/bin/phase-helpers.sh
index fe7a554f93..cc1a3b9565 100644
--- a/bin/phase-helpers.sh
+++ b/bin/phase-helpers.sh
@@ -21,10 +21,13 @@ export MOPREFIX=${PN}
 export PORTAGE_DOCOMPRESS_SIZE_LIMIT="128"
 declare -a PORTAGE_DOCOMPRESS=( /usr/share/{doc,info,man} )
 declare -a PORTAGE_DOCOMPRESS_SKIP=( "/usr/share/doc/${PF}/html" )
-declare -a PORTAGE_DOSTRIP=( / )
-has strip ${PORTAGE_RESTRICT} && PORTAGE_DOSTRIP=()
+declare -a PORTAGE_DOSTRIP=()
 declare -a PORTAGE_DOSTRIP_SKIP=()
 
+if ! contains_word strip "${PORTAGE_RESTRICT}"; then
+        PORTAGE_DOSTRIP+=( / )
+fi
+
 into() {
        if [[ "$1" == "/" ]]; then
                export __E_DESTTREE=""

diff --git a/bin/postinst-qa-check.d/50xdg-utils 
b/bin/postinst-qa-check.d/50xdg-utils
index 089e664448..59baa197c7 100644
--- a/bin/postinst-qa-check.d/50xdg-utils
+++ b/bin/postinst-qa-check.d/50xdg-utils
@@ -35,7 +35,7 @@ xdg_desktop_database_check() {
        [[ ${PORTAGE_QA_PHASE} == preinst ]] && return
 
        # Parallel-install makes it impossible to blame a specific package
-       has parallel-install ${FEATURES} && return
+       contains_word parallel-install "${FEATURES}" && return
 
        # The eqatag call is prohibitively expensive if the cache is
        # missing and there are a large number of files.
@@ -86,7 +86,7 @@ xdg_icon_cache_check() {
        [[ ${PORTAGE_QA_PHASE} == preinst ]] && return
 
        # parallel-install makes it impossible to blame a specific package
-       has parallel-install ${FEATURES} && return
+       contains_word parallel-install "${FEATURES}" && return
 
        # Avoid false-positives on first install (bug #649464)
        [[ ${PN} == gtk-update-icon-cache ]] && return
@@ -132,7 +132,7 @@ xdg_mimeinfo_database_check() {
        [[ ${PORTAGE_QA_PHASE} == preinst ]] && return
 
        # parallel-install makes it impossible to blame a specific package
-       has parallel-install ${FEATURES} && return
+       contains_word parallel-install "${FEATURES}" && return
 
        # The eqatag call is prohibitively expensive if the cache is
        # missing and there are a large number of files.

diff --git a/misc/emerge-delta-webrsync b/misc/emerge-delta-webrsync
index a788cdb0eb..773f198a0b 100755
--- a/misc/emerge-delta-webrsync
+++ b/misc/emerge-delta-webrsync
@@ -170,7 +170,8 @@ handle_pgp_setup() {
        # WEBRSYNC_VERIFY_SIGNATURE=2: use legacy FEATURES="webrsync-gpg"
        WEBRSYNC_VERIFY_SIGNATURE=1
 
-       has webrsync-gpg ${FEATURES} && webrsync_gpg=1 || webrsync_gpg=0
+       contains_word webrsync-gpg "${FEATURES}"
+       webrsync_gpg=$(( $? == 0 ))
 
        repo_has_webrsync_verify=$(
                has $(__repo_attr "${repo_name}" sync-webrsync-verify-signature 
| LC_ALL=C tr '[:upper:]' '[:lower:]') true yes
@@ -522,7 +523,7 @@ sync_local() {
        __vecho "Syncing local tree ..."
 
        local ownership="portage:portage"
-       if has usersync ${FEATURES} ; then
+       if contains_word usersync "${FEATURES}"; then
                case "${USERLAND}" in
                        BSD)
                                ownership=$(stat -f '%Su:%Sg' 
"${repo_location}")
@@ -562,14 +563,16 @@ sync_local() {
                rm -fr "${TMPDIR}"
        fi
 
-       if has metadata-transfer ${FEATURES} ; then
+       if contains_word metadata-transfer "${FEATURES}"; then
                __vecho "Updating cache ..."
                emerge --metadata
        fi
        local post_sync=${PORTAGE_CONFIGROOT}etc/portage/bin/post_sync
        [ -x "${post_sync}" ] && "${post_sync}"
        # --quiet suppresses output if there are no relevant news items
-       has news ${FEATURES} && emerge --check-news --quiet
+       if contains_word news "${FEATURES}"; then
+               emerge --check-news --quiet
+       fi
        return 0
 }
 

Reply via email to