eutils.eclass: In EAPI conditionals, replace "has" by case statements.
[gentoo.git] / eclass / eutils.eclass
1 # Copyright 1999-2015 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Id$
4
5 # @ECLASS: eutils.eclass
6 # @MAINTAINER:
7 # base-system@gentoo.org
8 # @BLURB: many extra (but common) functions that are used in ebuilds
9 # @DESCRIPTION:
10 # The eutils eclass contains a suite of functions that complement
11 # the ones that ebuild.sh already contain.  The idea is that the functions
12 # are not required in all ebuilds but enough utilize them to have a common
13 # home rather than having multiple ebuilds implementing the same thing.
14 #
15 # Due to the nature of this eclass, some functions may have maintainers
16 # different from the overall eclass!
17
18 if [[ -z ${_EUTILS_ECLASS} ]]; then
19 _EUTILS_ECLASS=1
20
21 inherit multilib toolchain-funcs
22
23 # @FUNCTION: eqawarn
24 # @USAGE: [message]
25 # @DESCRIPTION:
26 # Proxy to ewarn for package managers that don't provide eqawarn and use the PM
27 # implementation if available. Reuses PORTAGE_ELOG_CLASSES as set by the dev
28 # profile.
29 if ! declare -F eqawarn >/dev/null ; then
30         eqawarn() {
31                 has qa ${PORTAGE_ELOG_CLASSES} && ewarn "$@"
32                 :
33         }
34 fi
35
36 # @FUNCTION: ecvs_clean
37 # @USAGE: [list of dirs]
38 # @DESCRIPTION:
39 # Remove CVS directories recursiveley.  Useful when a source tarball contains
40 # internal CVS directories.  Defaults to $PWD.
41 ecvs_clean() {
42         [[ -z $* ]] && set -- .
43         find "$@" -type d -name 'CVS' -prune -print0 | xargs -0 rm -rf
44         find "$@" -type f -name '.cvs*' -print0 | xargs -0 rm -rf
45 }
46
47 # @FUNCTION: esvn_clean
48 # @USAGE: [list of dirs]
49 # @DESCRIPTION:
50 # Remove .svn directories recursiveley.  Useful when a source tarball contains
51 # internal Subversion directories.  Defaults to $PWD.
52 esvn_clean() {
53         [[ -z $* ]] && set -- .
54         find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf
55 }
56
57 # @FUNCTION: estack_push
58 # @USAGE: <stack> [items to push]
59 # @DESCRIPTION:
60 # Push any number of items onto the specified stack.  Pick a name that
61 # is a valid variable (i.e. stick to alphanumerics), and push as many
62 # items as you like onto the stack at once.
63 #
64 # The following code snippet will echo 5, then 4, then 3, then ...
65 # @CODE
66 #               estack_push mystack 1 2 3 4 5
67 #               while estack_pop mystack i ; do
68 #                       echo "${i}"
69 #               done
70 # @CODE
71 estack_push() {
72         [[ $# -eq 0 ]] && die "estack_push: incorrect # of arguments"
73         local stack_name="_ESTACK_$1_" ; shift
74         eval ${stack_name}+=\( \"\$@\" \)
75 }
76
77 # @FUNCTION: estack_pop
78 # @USAGE: <stack> [variable]
79 # @DESCRIPTION:
80 # Pop a single item off the specified stack.  If a variable is specified,
81 # the popped item is stored there.  If no more items are available, return
82 # 1, else return 0.  See estack_push for more info.
83 estack_pop() {
84         [[ $# -eq 0 || $# -gt 2 ]] && die "estack_pop: incorrect # of arguments"
85
86         # We use the fugly _estack_xxx var names to avoid collision with
87         # passing back the return value.  If we used "local i" and the
88         # caller ran `estack_pop ... i`, we'd end up setting the local
89         # copy of "i" rather than the caller's copy.  The _estack_xxx
90         # garbage is preferable to using $1/$2 everywhere as that is a
91         # bit harder to read.
92         local _estack_name="_ESTACK_$1_" ; shift
93         local _estack_retvar=$1 ; shift
94         eval local _estack_i=\${#${_estack_name}\[@\]}
95         # Don't warn -- let the caller interpret this as a failure
96         # or as normal behavior (akin to `shift`)
97         [[ $(( --_estack_i )) -eq -1 ]] && return 1
98
99         if [[ -n ${_estack_retvar} ]] ; then
100                 eval ${_estack_retvar}=\"\${${_estack_name}\[${_estack_i}\]}\"
101         fi
102         eval unset ${_estack_name}\[${_estack_i}\]
103 }
104
105 # @FUNCTION: evar_push
106 # @USAGE: <variable to save> [more vars to save]
107 # @DESCRIPTION:
108 # This let's you temporarily modify a variable and then restore it (including
109 # set vs unset semantics).  Arrays are not supported at this time.
110 #
111 # This is meant for variables where using `local` does not work (such as
112 # exported variables, or only temporarily changing things in a func).
113 #
114 # For example:
115 # @CODE
116 #               evar_push LC_ALL
117 #               export LC_ALL=C
118 #               ... do some stuff that needs LC_ALL=C set ...
119 #               evar_pop
120 #
121 #               # You can also save/restore more than one var at a time
122 #               evar_push BUTTERFLY IN THE SKY
123 #               ... do stuff with the vars ...
124 #               evar_pop     # This restores just one var, SKY
125 #               ... do more stuff ...
126 #               evar_pop 3   # This pops the remaining 3 vars
127 # @CODE
128 evar_push() {
129         local var val
130         for var ; do
131                 [[ ${!var+set} == "set" ]] \
132                         && val=${!var} \
133                         || val="unset_76fc3c462065bb4ca959f939e6793f94"
134                 estack_push evar "${var}" "${val}"
135         done
136 }
137
138 # @FUNCTION: evar_push_set
139 # @USAGE: <variable to save> [new value to store]
140 # @DESCRIPTION:
141 # This is a handy shortcut to save and temporarily set a variable.  If a value
142 # is not specified, the var will be unset.
143 evar_push_set() {
144         local var=$1
145         evar_push ${var}
146         case $# in
147         1) unset ${var} ;;
148         2) printf -v "${var}" '%s' "$2" ;;
149         *) die "${FUNCNAME}: incorrect # of args: $*" ;;
150         esac
151 }
152
153 # @FUNCTION: evar_pop
154 # @USAGE: [number of vars to restore]
155 # @DESCRIPTION:
156 # Restore the variables to the state saved with the corresponding
157 # evar_push call.  See that function for more details.
158 evar_pop() {
159         local cnt=${1:-bad}
160         case $# in
161         0) cnt=1 ;;
162         1) isdigit "${cnt}" || die "${FUNCNAME}: first arg must be a number: $*" ;;
163         *) die "${FUNCNAME}: only accepts one arg: $*" ;;
164         esac
165
166         local var val
167         while (( cnt-- )) ; do
168                 estack_pop evar val || die "${FUNCNAME}: unbalanced push"
169                 estack_pop evar var || die "${FUNCNAME}: unbalanced push"
170                 [[ ${val} == "unset_76fc3c462065bb4ca959f939e6793f94" ]] \
171                         && unset ${var} \
172                         || printf -v "${var}" '%s' "${val}"
173         done
174 }
175
176 # @FUNCTION: eshopts_push
177 # @USAGE: [options to `set` or `shopt`]
178 # @DESCRIPTION:
179 # Often times code will want to enable a shell option to change code behavior.
180 # Since changing shell options can easily break other pieces of code (which
181 # assume the default state), eshopts_push is used to (1) push the current shell
182 # options onto a stack and (2) pass the specified arguments to set.
183 #
184 # If the first argument is '-s' or '-u', we assume you want to call `shopt`
185 # rather than `set` as there are some options only available via that.
186 #
187 # A common example is to disable shell globbing so that special meaning/care
188 # may be used with variables/arguments to custom functions.  That would be:
189 # @CODE
190 #               eshopts_push -o noglob
191 #               for x in ${foo} ; do
192 #                       if ...some check... ; then
193 #                               eshopts_pop
194 #                               return 0
195 #                       fi
196 #               done
197 #               eshopts_pop
198 # @CODE
199 eshopts_push() {
200         if [[ $1 == -[su] ]] ; then
201                 estack_push eshopts "$(shopt -p)"
202                 [[ $# -eq 0 ]] && return 0
203                 shopt "$@" || die "${FUNCNAME}: bad options to shopt: $*"
204         else
205                 estack_push eshopts $-
206                 [[ $# -eq 0 ]] && return 0
207                 set "$@" || die "${FUNCNAME}: bad options to set: $*"
208         fi
209 }
210
211 # @FUNCTION: eshopts_pop
212 # @USAGE:
213 # @DESCRIPTION:
214 # Restore the shell options to the state saved with the corresponding
215 # eshopts_push call.  See that function for more details.
216 eshopts_pop() {
217         local s
218         estack_pop eshopts s || die "${FUNCNAME}: unbalanced push"
219         if [[ ${s} == "shopt -"* ]] ; then
220                 eval "${s}" || die "${FUNCNAME}: sanity: invalid shopt options: ${s}"
221         else
222                 set +$-     || die "${FUNCNAME}: sanity: invalid shell settings: $-"
223                 set -${s}   || die "${FUNCNAME}: sanity: unable to restore saved shell settings: ${s}"
224         fi
225 }
226
227 # @FUNCTION: eumask_push
228 # @USAGE: <new umask>
229 # @DESCRIPTION:
230 # Set the umask to the new value specified while saving the previous
231 # value onto a stack.  Useful for temporarily changing the umask.
232 eumask_push() {
233         estack_push eumask "$(umask)"
234         umask "$@" || die "${FUNCNAME}: bad options to umask: $*"
235 }
236
237 # @FUNCTION: eumask_pop
238 # @USAGE:
239 # @DESCRIPTION:
240 # Restore the previous umask state.
241 eumask_pop() {
242         [[ $# -eq 0 ]] || die "${FUNCNAME}: we take no options"
243         local s
244         estack_pop eumask s || die "${FUNCNAME}: unbalanced push"
245         umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}"
246 }
247
248 # @FUNCTION: isdigit
249 # @USAGE: <number> [more numbers]
250 # @DESCRIPTION:
251 # Return true if all arguments are numbers.
252 isdigit() {
253         local d
254         for d ; do
255                 [[ ${d:-bad} == *[!0-9]* ]] && return 1
256         done
257         return 0
258 }
259
260 # @VARIABLE: EPATCH_SOURCE
261 # @DESCRIPTION:
262 # Default directory to search for patches.
263 EPATCH_SOURCE="${WORKDIR}/patch"
264 # @VARIABLE: EPATCH_SUFFIX
265 # @DESCRIPTION:
266 # Default extension for patches (do not prefix the period yourself).
267 EPATCH_SUFFIX="patch.bz2"
268 # @VARIABLE: EPATCH_OPTS
269 # @DESCRIPTION:
270 # Options to pass to patch.  Meant for ebuild/package-specific tweaking
271 # such as forcing the patch level (-p#) or fuzz (-F#) factor.  Note that
272 # for single patch tweaking, you can also pass flags directly to epatch.
273 EPATCH_OPTS=""
274 # @VARIABLE: EPATCH_COMMON_OPTS
275 # @DESCRIPTION:
276 # Common options to pass to `patch`.  You probably should never need to
277 # change these.  If you do, please discuss it with base-system first to
278 # be sure.
279 # @CODE
280 #       -g0 - keep RCS, ClearCase, Perforce and SCCS happy #24571
281 #       --no-backup-if-mismatch - do not leave .orig files behind
282 #       -E - automatically remove empty files
283 # @CODE
284 EPATCH_COMMON_OPTS="-g0 -E --no-backup-if-mismatch"
285 # @VARIABLE: EPATCH_EXCLUDE
286 # @DESCRIPTION:
287 # List of patches not to apply.  Note this is only file names,
288 # and not the full path.  Globs accepted.
289 EPATCH_EXCLUDE=""
290 # @VARIABLE: EPATCH_SINGLE_MSG
291 # @DESCRIPTION:
292 # Change the printed message for a single patch.
293 EPATCH_SINGLE_MSG=""
294 # @VARIABLE: EPATCH_MULTI_MSG
295 # @DESCRIPTION:
296 # Change the printed message for multiple patches.
297 EPATCH_MULTI_MSG="Applying various patches (bugfixes/updates) ..."
298 # @VARIABLE: EPATCH_FORCE
299 # @DESCRIPTION:
300 # Only require patches to match EPATCH_SUFFIX rather than the extended
301 # arch naming style.
302 EPATCH_FORCE="no"
303 # @VARIABLE: EPATCH_USER_EXCLUDE
304 # @DEFAULT_UNSET
305 # @DESCRIPTION:
306 # List of patches not to apply.  Note this is only file names,
307 # and not the full path.  Globs accepted.
308
309 # @FUNCTION: epatch
310 # @USAGE: [options] [patches] [dirs of patches]
311 # @DESCRIPTION:
312 # epatch is designed to greatly simplify the application of patches.  It can
313 # process patch files directly, or directories of patches.  The patches may be
314 # compressed (bzip/gzip/etc...) or plain text.  You generally need not specify
315 # the -p option as epatch will automatically attempt -p0 to -p4 until things
316 # apply successfully.
317 #
318 # If you do not specify any patches/dirs, then epatch will default to the
319 # directory specified by EPATCH_SOURCE.
320 #
321 # Any options specified that start with a dash will be passed down to patch
322 # for this specific invocation.  As soon as an arg w/out a dash is found, then
323 # arg processing stops.
324 #
325 # When processing directories, epatch will apply all patches that match:
326 # @CODE
327 #       if ${EPATCH_FORCE} != "yes"
328 #               ??_${ARCH}_foo.${EPATCH_SUFFIX}
329 #       else
330 #               *.${EPATCH_SUFFIX}
331 # @CODE
332 # The leading ?? are typically numbers used to force consistent patch ordering.
333 # The arch field is used to apply patches only for the host architecture with
334 # the special value of "all" means apply for everyone.  Note that using values
335 # other than "all" is highly discouraged -- you should apply patches all the
336 # time and let architecture details be detected at configure/compile time.
337 #
338 # If EPATCH_SUFFIX is empty, then no period before it is implied when searching
339 # for patches to apply.
340 #
341 # Refer to the other EPATCH_xxx variables for more customization of behavior.
342 epatch() {
343         _epatch_draw_line() {
344                 # create a line of same length as input string
345                 [[ -z $1 ]] && set "$(printf "%65s" '')"
346                 echo "${1//?/=}"
347         }
348
349         unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402
350
351         # First process options.  We localize the EPATCH_OPTS setting
352         # from above so that we can pass it on in the loop below with
353         # any additional values the user has specified.
354         local EPATCH_OPTS=( ${EPATCH_OPTS[*]} )
355         while [[ $# -gt 0 ]] ; do
356                 case $1 in
357                 -*) EPATCH_OPTS+=( "$1" ) ;;
358                 *) break ;;
359                 esac
360                 shift
361         done
362
363         # Let the rest of the code process one user arg at a time --
364         # each arg may expand into multiple patches, and each arg may
365         # need to start off with the default global EPATCH_xxx values
366         if [[ $# -gt 1 ]] ; then
367                 local m
368                 for m in "$@" ; do
369                         epatch "${m}"
370                 done
371                 return 0
372         fi
373
374         local SINGLE_PATCH="no"
375         # no args means process ${EPATCH_SOURCE}
376         [[ $# -eq 0 ]] && set -- "${EPATCH_SOURCE}"
377
378         if [[ -f $1 ]] ; then
379                 SINGLE_PATCH="yes"
380                 set -- "$1"
381                 # Use the suffix from the single patch (localize it); the code
382                 # below will find the suffix for us
383                 local EPATCH_SUFFIX=$1
384
385         elif [[ -d $1 ]] ; then
386                 # We have to force sorting to C so that the wildcard expansion is consistent #471666.
387                 evar_push_set LC_COLLATE C
388                 # Some people like to make dirs of patches w/out suffixes (vim).
389                 set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"}
390                 evar_pop
391
392         elif [[ -f ${EPATCH_SOURCE}/$1 ]] ; then
393                 # Re-use EPATCH_SOURCE as a search dir
394                 epatch "${EPATCH_SOURCE}/$1"
395                 return $?
396
397         else
398                 # sanity check ... if it isn't a dir or file, wtf man ?
399                 [[ $# -ne 0 ]] && EPATCH_SOURCE=$1
400                 echo
401                 eerror "Cannot find \$EPATCH_SOURCE!  Value for \$EPATCH_SOURCE is:"
402                 eerror
403                 eerror "  ${EPATCH_SOURCE}"
404                 eerror "  ( ${EPATCH_SOURCE##*/} )"
405                 echo
406                 die "Cannot find \$EPATCH_SOURCE!"
407         fi
408
409         # Now that we know we're actually going to apply something, merge
410         # all of the patch options back in to a single variable for below.
411         EPATCH_OPTS="${EPATCH_COMMON_OPTS} ${EPATCH_OPTS[*]}"
412
413         local PIPE_CMD
414         case ${EPATCH_SUFFIX##*\.} in
415                 xz)      PIPE_CMD="xz -dc"    ;;
416                 lzma)    PIPE_CMD="lzma -dc"  ;;
417                 bz2)     PIPE_CMD="bzip2 -dc" ;;
418                 gz|Z|z)  PIPE_CMD="gzip -dc"  ;;
419                 ZIP|zip) PIPE_CMD="unzip -p"  ;;
420                 *)       ;;
421         esac
422
423         [[ ${SINGLE_PATCH} == "no" ]] && einfo "${EPATCH_MULTI_MSG}"
424
425         local x
426         for x in "$@" ; do
427                 # If the patch dir given contains subdirs, or our EPATCH_SUFFIX
428                 # didn't match anything, ignore continue on
429                 [[ ! -f ${x} ]] && continue
430
431                 local patchname=${x##*/}
432
433                 # Apply single patches, or forced sets of patches, or
434                 # patches with ARCH dependant names.
435                 #       ???_arch_foo.patch
436                 # Else, skip this input altogether
437                 local a=${patchname#*_} # strip the ???_
438                 a=${a%%_*}              # strip the _foo.patch
439                 if ! [[ ${SINGLE_PATCH} == "yes" || \
440                                 ${EPATCH_FORCE} == "yes" || \
441                                 ${a} == all     || \
442                                 ${a} == ${ARCH} ]]
443                 then
444                         continue
445                 fi
446
447                 # Let people filter things dynamically
448                 if [[ -n ${EPATCH_EXCLUDE}${EPATCH_USER_EXCLUDE} ]] ; then
449                         # let people use globs in the exclude
450                         eshopts_push -o noglob
451
452                         local ex
453                         for ex in ${EPATCH_EXCLUDE} ; do
454                                 if [[ ${patchname} == ${ex} ]] ; then
455                                         einfo "  Skipping ${patchname} due to EPATCH_EXCLUDE ..."
456                                         eshopts_pop
457                                         continue 2
458                                 fi
459                         done
460
461                         for ex in ${EPATCH_USER_EXCLUDE} ; do
462                                 if [[ ${patchname} == ${ex} ]] ; then
463                                         einfo "  Skipping ${patchname} due to EPATCH_USER_EXCLUDE ..."
464                                         eshopts_pop
465                                         continue 2
466                                 fi
467                         done
468
469                         eshopts_pop
470                 fi
471
472                 if [[ ${SINGLE_PATCH} == "yes" ]] ; then
473                         if [[ -n ${EPATCH_SINGLE_MSG} ]] ; then
474                                 einfo "${EPATCH_SINGLE_MSG}"
475                         else
476                                 einfo "Applying ${patchname} ..."
477                         fi
478                 else
479                         einfo "  ${patchname} ..."
480                 fi
481
482                 # Handle aliased patch command #404447 #461568
483                 local patch="patch"
484                 eval $(alias patch 2>/dev/null | sed 's:^alias ::')
485
486                 # most of the time, there will only be one run per unique name,
487                 # but if there are more, make sure we get unique log filenames
488                 local STDERR_TARGET="${T}/${patchname}.out"
489                 if [[ -e ${STDERR_TARGET} ]] ; then
490                         STDERR_TARGET="${T}/${patchname}-$$.out"
491                 fi
492
493                 printf "***** %s *****\nPWD: %s\nPATCH TOOL: %s -> %s\nVERSION INFO:\n%s\n\n" \
494                         "${patchname}" \
495                         "${PWD}" \
496                         "${patch}" \
497                         "$(type -P "${patch}")" \
498                         "$(${patch} --version)" \
499                         > "${STDERR_TARGET}"
500
501                 # Decompress the patch if need be
502                 local count=0
503                 local PATCH_TARGET
504                 if [[ -n ${PIPE_CMD} ]] ; then
505                         PATCH_TARGET="${T}/$$.patch"
506                         echo "PIPE_COMMAND:  ${PIPE_CMD} ${x} > ${PATCH_TARGET}" >> "${STDERR_TARGET}"
507
508                         if ! (${PIPE_CMD} "${x}" > "${PATCH_TARGET}") >> "${STDERR_TARGET}" 2>&1 ; then
509                                 echo
510                                 eerror "Could not extract patch!"
511                                 #die "Could not extract patch!"
512                                 count=5
513                                 break
514                         fi
515                 else
516                         PATCH_TARGET=${x}
517                 fi
518
519                 # Check for absolute paths in patches.  If sandbox is disabled,
520                 # people could (accidently) patch files in the root filesystem.
521                 # Or trigger other unpleasantries #237667.  So disallow -p0 on
522                 # such patches.
523                 local abs_paths=$(egrep -n '^[-+]{3} /' "${PATCH_TARGET}" | awk '$2 != "/dev/null" { print }')
524                 if [[ -n ${abs_paths} ]] ; then
525                         count=1
526                         printf "NOTE: skipping -p0 due to absolute paths in patch:\n%s\n" "${abs_paths}" >> "${STDERR_TARGET}"
527                 fi
528                 # Similar reason, but with relative paths.
529                 local rel_paths=$(egrep -n '^[-+]{3} [^ ]*[.][.]/' "${PATCH_TARGET}")
530                 if [[ -n ${rel_paths} ]] ; then
531                         echo
532                         eerror "Rejected Patch: ${patchname} !"
533                         eerror " ( ${PATCH_TARGET} )"
534                         eerror
535                         eerror "Your patch uses relative paths '../':"
536                         eerror "${rel_paths}"
537                         echo
538                         die "you need to fix the relative paths in patch"
539                 fi
540
541                 # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/
542                 local patch_cmd
543                 while [[ ${count} -lt 5 ]] ; do
544                         patch_cmd="${patch} -p${count} ${EPATCH_OPTS}"
545
546                         # Generate some useful debug info ...
547                         (
548                         _epatch_draw_line "***** ${patchname} *****"
549                         echo
550                         echo "PATCH COMMAND:  ${patch_cmd} --dry-run -f < '${PATCH_TARGET}'"
551                         echo
552                         _epatch_draw_line "***** ${patchname} *****"
553                         ${patch_cmd} --dry-run -f < "${PATCH_TARGET}" 2>&1
554                         ret=$?
555                         echo
556                         echo "patch program exited with status ${ret}"
557                         exit ${ret}
558                         ) >> "${STDERR_TARGET}"
559
560                         if [ $? -eq 0 ] ; then
561                                 (
562                                 _epatch_draw_line "***** ${patchname} *****"
563                                 echo
564                                 echo "ACTUALLY APPLYING ${patchname} ..."
565                                 echo "PATCH COMMAND:  ${patch_cmd} < '${PATCH_TARGET}'"
566                                 echo
567                                 _epatch_draw_line "***** ${patchname} *****"
568                                 ${patch_cmd} < "${PATCH_TARGET}" 2>&1
569                                 ret=$?
570                                 echo
571                                 echo "patch program exited with status ${ret}"
572                                 exit ${ret}
573                                 ) >> "${STDERR_TARGET}"
574
575                                 if [ $? -ne 0 ] ; then
576                                         echo
577                                         eerror "A dry-run of patch command succeeded, but actually"
578                                         eerror "applying the patch failed!"
579                                         #die "Real world sux compared to the dreamworld!"
580                                         count=5
581                                 fi
582                                 break
583                         fi
584
585                         : $(( count++ ))
586                 done
587
588                 # if we had to decompress the patch, delete the temp one
589                 if [[ -n ${PIPE_CMD} ]] ; then
590                         rm -f "${PATCH_TARGET}"
591                 fi
592
593                 if [[ ${count} -ge 5 ]] ; then
594                         echo
595                         eerror "Failed Patch: ${patchname} !"
596                         eerror " ( ${PATCH_TARGET} )"
597                         eerror
598                         eerror "Include in your bugreport the contents of:"
599                         eerror
600                         eerror "  ${STDERR_TARGET}"
601                         echo
602                         die "Failed Patch: ${patchname}!"
603                 fi
604
605                 # if everything worked, delete the full debug patch log
606                 rm -f "${STDERR_TARGET}"
607
608                 # then log away the exact stuff for people to review later
609                 cat <<-EOF >> "${T}/epatch.log"
610                 PATCH: ${x}
611                 CMD: ${patch_cmd}
612                 PWD: ${PWD}
613
614                 EOF
615                 eend 0
616         done
617
618         [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
619         : # everything worked
620 }
621
622 # @FUNCTION: emktemp
623 # @USAGE: [temp dir]
624 # @DESCRIPTION:
625 # Cheap replacement for when debianutils (and thus mktemp)
626 # does not exist on the users system.
627 emktemp() {
628         local exe="touch"
629         [[ $1 == -d ]] && exe="mkdir" && shift
630         local topdir=$1
631
632         if [[ -z ${topdir} ]] ; then
633                 [[ -z ${T} ]] \
634                         && topdir="/tmp" \
635                         || topdir=${T}
636         fi
637
638         if ! type -P mktemp > /dev/null ; then
639                 # system lacks `mktemp` so we have to fake it
640                 local tmp=/
641                 while [[ -e ${tmp} ]] ; do
642                         tmp=${topdir}/tmp.${RANDOM}.${RANDOM}.${RANDOM}
643                 done
644                 ${exe} "${tmp}" || ${exe} -p "${tmp}"
645                 echo "${tmp}"
646         else
647                 # the args here will give slightly wierd names on BSD,
648                 # but should produce a usable file on all userlands
649                 if [[ ${exe} == "touch" ]] ; then
650                         TMPDIR="${topdir}" mktemp -t tmp.XXXXXXXXXX
651                 else
652                         TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX
653                 fi
654         fi
655 }
656
657 # @FUNCTION: edos2unix
658 # @USAGE: <file> [more files ...]
659 # @DESCRIPTION:
660 # A handy replacement for dos2unix, recode, fixdos, etc...  This allows you
661 # to remove all of these text utilities from DEPEND variables because this
662 # is a script based solution.  Just give it a list of files to convert and
663 # they will all be changed from the DOS CRLF format to the UNIX LF format.
664 edos2unix() {
665         [[ $# -eq 0 ]] && return 0
666         sed -i 's/\r$//' -- "$@" || die
667 }
668
669 # @FUNCTION: make_desktop_entry
670 # @USAGE: make_desktop_entry(<command>, [name], [icon], [type], [fields])
671 # @DESCRIPTION:
672 # Make a .desktop file.
673 #
674 # @CODE
675 # binary:   what command does the app run with ?
676 # name:     the name that will show up in the menu
677 # icon:     the icon to use in the menu entry
678 #           this can be relative (to /usr/share/pixmaps) or
679 #           a full path to an icon
680 # type:     what kind of application is this?
681 #           for categories:
682 #           http://standards.freedesktop.org/menu-spec/latest/apa.html
683 #           if unset, function tries to guess from package's category
684 # fields:       extra fields to append to the desktop file; a printf string
685 # @CODE
686 make_desktop_entry() {
687         [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
688
689         local exec=${1}
690         local name=${2:-${PN}}
691         local icon=${3:-${PN}}
692         local type=${4}
693         local fields=${5}
694
695         if [[ -z ${type} ]] ; then
696                 local catmaj=${CATEGORY%%-*}
697                 local catmin=${CATEGORY##*-}
698                 case ${catmaj} in
699                         app)
700                                 case ${catmin} in
701                                         accessibility) type="Utility;Accessibility";;
702                                         admin)         type=System;;
703                                         antivirus)     type=System;;
704                                         arch)          type="Utility;Archiving";;
705                                         backup)        type="Utility;Archiving";;
706                                         cdr)           type="AudioVideo;DiscBurning";;
707                                         dicts)         type="Office;Dictionary";;
708                                         doc)           type=Documentation;;
709                                         editors)       type="Utility;TextEditor";;
710                                         emacs)         type="Development;TextEditor";;
711                                         emulation)     type="System;Emulator";;
712                                         laptop)        type="Settings;HardwareSettings";;
713                                         office)        type=Office;;
714                                         pda)           type="Office;PDA";;
715                                         vim)           type="Development;TextEditor";;
716                                         xemacs)        type="Development;TextEditor";;
717                                 esac
718                                 ;;
719
720                         dev)
721                                 type="Development"
722                                 ;;
723
724                         games)
725                                 case ${catmin} in
726                                         action|fps) type=ActionGame;;
727                                         arcade)     type=ArcadeGame;;
728                                         board)      type=BoardGame;;
729                                         emulation)  type=Emulator;;
730                                         kids)       type=KidsGame;;
731                                         puzzle)     type=LogicGame;;
732                                         roguelike)  type=RolePlaying;;
733                                         rpg)        type=RolePlaying;;
734                                         simulation) type=Simulation;;
735                                         sports)     type=SportsGame;;
736                                         strategy)   type=StrategyGame;;
737                                 esac
738                                 type="Game;${type}"
739                                 ;;
740
741                         gnome)
742                                 type="Gnome;GTK"
743                                 ;;
744
745                         kde)
746                                 type="KDE;Qt"
747                                 ;;
748
749                         mail)
750                                 type="Network;Email"
751                                 ;;
752
753                         media)
754                                 case ${catmin} in
755                                         gfx)
756                                                 type=Graphics
757                                                 ;;
758                                         *)
759                                                 case ${catmin} in
760                                                         radio) type=Tuner;;
761                                                         sound) type=Audio;;
762                                                         tv)    type=TV;;
763                                                         video) type=Video;;
764                                                 esac
765                                                 type="AudioVideo;${type}"
766                                                 ;;
767                                 esac
768                                 ;;
769
770                         net)
771                                 case ${catmin} in
772                                         dialup) type=Dialup;;
773                                         ftp)    type=FileTransfer;;
774                                         im)     type=InstantMessaging;;
775                                         irc)    type=IRCClient;;
776                                         mail)   type=Email;;
777                                         news)   type=News;;
778                                         nntp)   type=News;;
779                                         p2p)    type=FileTransfer;;
780                                         voip)   type=Telephony;;
781                                 esac
782                                 type="Network;${type}"
783                                 ;;
784
785                         sci)
786                                 case ${catmin} in
787                                         astro*)  type=Astronomy;;
788                                         bio*)    type=Biology;;
789                                         calc*)   type=Calculator;;
790                                         chem*)   type=Chemistry;;
791                                         elec*)   type=Electronics;;
792                                         geo*)    type=Geology;;
793                                         math*)   type=Math;;
794                                         physics) type=Physics;;
795                                         visual*) type=DataVisualization;;
796                                 esac
797                                 type="Education;Science;${type}"
798                                 ;;
799
800                         sys)
801                                 type="System"
802                                 ;;
803
804                         www)
805                                 case ${catmin} in
806                                         client) type=WebBrowser;;
807                                 esac
808                                 type="Network;${type}"
809                                 ;;
810
811                         *)
812                                 type=
813                                 ;;
814                 esac
815         fi
816         local slot=${SLOT%/*}
817         if [[ ${slot} == "0" ]] ; then
818                 local desktop_name="${PN}"
819         else
820                 local desktop_name="${PN}-${slot}"
821         fi
822         local desktop="${T}/$(echo ${exec} | sed 's:[[:space:]/:]:_:g')-${desktop_name}.desktop"
823         #local desktop=${T}/${exec%% *:-${desktop_name}}.desktop
824
825         # Don't append another ";" when a valid category value is provided.
826         type=${type%;}${type:+;}
827
828         eshopts_push -s extglob
829         if [[ -n ${icon} && ${icon} != /* ]] && [[ ${icon} == *.xpm || ${icon} == *.png || ${icon} == *.svg ]]; then
830                 ewarn "As described in the Icon Theme Specification, icon file extensions are not"
831                 ewarn "allowed in .desktop files if the value is not an absolute path."
832                 icon=${icon%.@(xpm|png|svg)}
833         fi
834         eshopts_pop
835
836         cat <<-EOF > "${desktop}"
837         [Desktop Entry]
838         Name=${name}
839         Type=Application
840         Comment=${DESCRIPTION}
841         Exec=${exec}
842         TryExec=${exec%% *}
843         Icon=${icon}
844         Categories=${type}
845         EOF
846
847         if [[ ${fields:-=} != *=* ]] ; then
848                 # 5th arg used to be value to Path=
849                 ewarn "make_desktop_entry: update your 5th arg to read Path=${fields}"
850                 fields="Path=${fields}"
851         fi
852         [[ -n ${fields} ]] && printf '%b\n' "${fields}" >> "${desktop}"
853
854         (
855                 # wrap the env here so that the 'insinto' call
856                 # doesn't corrupt the env of the caller
857                 insinto /usr/share/applications
858                 doins "${desktop}"
859         ) || die "installing desktop file failed"
860 }
861
862 # @FUNCTION: _eutils_eprefix_init
863 # @INTERNAL
864 # @DESCRIPTION:
865 # Initialized prefix variables for EAPI<3.
866 _eutils_eprefix_init() {
867         has "${EAPI:-0}" 0 1 2 && : ${ED:=${D}} ${EPREFIX:=} ${EROOT:=${ROOT}}
868 }
869
870 # @FUNCTION: validate_desktop_entries
871 # @USAGE: [directories]
872 # @MAINTAINER:
873 # Carsten Lohrke <carlo@gentoo.org>
874 # @DESCRIPTION:
875 # Validate desktop entries using desktop-file-utils
876 validate_desktop_entries() {
877         _eutils_eprefix_init
878         if [[ -x "${EPREFIX}"/usr/bin/desktop-file-validate ]] ; then
879                 einfo "Checking desktop entry validity"
880                 local directories=""
881                 for d in /usr/share/applications $@ ; do
882                         [[ -d ${ED}${d} ]] && directories="${directories} ${ED}${d}"
883                 done
884                 if [[ -n ${directories} ]] ; then
885                         for FILE in $(find ${directories} -name "*\.desktop" \
886                                                         -not -path '*.hidden*' | sort -u 2>/dev/null)
887                         do
888                                 local temp=$(desktop-file-validate ${FILE} | grep -v "warning:" | \
889                                                                 sed -e "s|error: ||" -e "s|${FILE}:|--|g" )
890                                 [[ -n $temp ]] && elog ${temp/--/${FILE/${ED}/}:}
891                         done
892                 fi
893                 echo ""
894         else
895                 einfo "Passing desktop entry validity check. Install dev-util/desktop-file-utils, if you want to help to improve Gentoo."
896         fi
897 }
898
899 # @FUNCTION: make_session_desktop
900 # @USAGE: <title> <command> [command args...]
901 # @DESCRIPTION:
902 # Make a GDM/KDM Session file.  The title is the file to execute to start the
903 # Window Manager.  The command is the name of the Window Manager.
904 #
905 # You can set the name of the file via the ${wm} variable.
906 make_session_desktop() {
907         [[ -z $1 ]] && eerror "$0: You must specify the title" && return 1
908         [[ -z $2 ]] && eerror "$0: You must specify the command" && return 1
909
910         local title=$1
911         local command=$2
912         local desktop=${T}/${wm:-${PN}}.desktop
913         shift 2
914
915         cat <<-EOF > "${desktop}"
916         [Desktop Entry]
917         Name=${title}
918         Comment=This session logs you into ${title}
919         Exec=${command} $*
920         TryExec=${command}
921         Type=XSession
922         EOF
923
924         (
925         # wrap the env here so that the 'insinto' call
926         # doesn't corrupt the env of the caller
927         insinto /usr/share/xsessions
928         doins "${desktop}"
929         )
930 }
931
932 # @FUNCTION: domenu
933 # @USAGE: <menus>
934 # @DESCRIPTION:
935 # Install the list of .desktop menu files into the appropriate directory
936 # (/usr/share/applications).
937 domenu() {
938         (
939         # wrap the env here so that the 'insinto' call
940         # doesn't corrupt the env of the caller
941         local i j ret=0
942         insinto /usr/share/applications
943         for i in "$@" ; do
944                 if [[ -f ${i} ]] ; then
945                         doins "${i}"
946                         ((ret+=$?))
947                 elif [[ -d ${i} ]] ; then
948                         for j in "${i}"/*.desktop ; do
949                                 doins "${j}"
950                                 ((ret+=$?))
951                         done
952                 else
953                         ((++ret))
954                 fi
955         done
956         exit ${ret}
957         )
958 }
959
960 # @FUNCTION: newmenu
961 # @USAGE: <menu> <newname>
962 # @DESCRIPTION:
963 # Like all other new* functions, install the specified menu as newname.
964 newmenu() {
965         (
966         # wrap the env here so that the 'insinto' call
967         # doesn't corrupt the env of the caller
968         insinto /usr/share/applications
969         newins "$@"
970         )
971 }
972
973 # @FUNCTION: _iconins
974 # @INTERNAL
975 # @DESCRIPTION:
976 # function for use in doicon and newicon
977 _iconins() {
978         (
979         # wrap the env here so that the 'insinto' call
980         # doesn't corrupt the env of the caller
981         local funcname=$1; shift
982         local size dir
983         local context=apps
984         local theme=hicolor
985
986         while [[ $# -gt 0 ]] ; do
987                 case $1 in
988                 -s|--size)
989                         if [[ ${2%%x*}x${2%%x*} == "$2" ]] ; then
990                                 size=${2%%x*}
991                         else
992                                 size=${2}
993                         fi
994                         case ${size} in
995                         16|22|24|32|36|48|64|72|96|128|192|256|512)
996                                 size=${size}x${size};;
997                         scalable)
998                                 ;;
999                         *)
1000                                 eerror "${size} is an unsupported icon size!"
1001                                 exit 1;;
1002                         esac
1003                         shift 2;;
1004                 -t|--theme)
1005                         theme=${2}
1006                         shift 2;;
1007                 -c|--context)
1008                         context=${2}
1009                         shift 2;;
1010                 *)
1011                         if [[ -z ${size} ]] ; then
1012                                 insinto /usr/share/pixmaps
1013                         else
1014                                 insinto /usr/share/icons/${theme}/${size}/${context}
1015                         fi
1016
1017                         if [[ ${funcname} == doicon ]] ; then
1018                                 if [[ -f $1 ]] ; then
1019                                         doins "${1}"
1020                                 elif [[ -d $1 ]] ; then
1021                                         shopt -s nullglob
1022                                         doins "${1}"/*.{png,svg}
1023                                         shopt -u nullglob
1024                                 else
1025                                         eerror "${1} is not a valid file/directory!"
1026                                         exit 1
1027                                 fi
1028                         else
1029                                 break
1030                         fi
1031                         shift 1;;
1032                 esac
1033         done
1034         if [[ ${funcname} == newicon ]] ; then
1035                 newins "$@"
1036         fi
1037         ) || die
1038 }
1039
1040 # @FUNCTION: doicon
1041 # @USAGE: [options] <icons>
1042 # @DESCRIPTION:
1043 # Install icon into the icon directory /usr/share/icons or into
1044 # /usr/share/pixmaps if "--size" is not set.
1045 # This is useful in conjunction with creating desktop/menu files.
1046 #
1047 # @CODE
1048 #  options:
1049 #  -s, --size
1050 #    !!! must specify to install into /usr/share/icons/... !!!
1051 #    size of the icon, like 48 or 48x48
1052 #    supported icon sizes are:
1053 #    16 22 24 32 36 48 64 72 96 128 192 256 scalable
1054 #  -c, --context
1055 #    defaults to "apps"
1056 #  -t, --theme
1057 #    defaults to "hicolor"
1058 #
1059 # icons: list of icons
1060 #
1061 # example 1: doicon foobar.png fuqbar.svg suckbar.png
1062 # results in: insinto /usr/share/pixmaps
1063 #             doins foobar.png fuqbar.svg suckbar.png
1064 #
1065 # example 2: doicon -s 48 foobar.png fuqbar.png blobbar.png
1066 # results in: insinto /usr/share/icons/hicolor/48x48/apps
1067 #             doins foobar.png fuqbar.png blobbar.png
1068 # @CODE
1069 doicon() {
1070         _iconins ${FUNCNAME} "$@"
1071 }
1072
1073 # @FUNCTION: newicon
1074 # @USAGE: [options] <icon> <newname>
1075 # @DESCRIPTION:
1076 # Like doicon, install the specified icon as newname.
1077 #
1078 # @CODE
1079 # example 1: newicon foobar.png NEWNAME.png
1080 # results in: insinto /usr/share/pixmaps
1081 #             newins foobar.png NEWNAME.png
1082 #
1083 # example 2: newicon -s 48 foobar.png NEWNAME.png
1084 # results in: insinto /usr/share/icons/hicolor/48x48/apps
1085 #             newins foobar.png NEWNAME.png
1086 # @CODE
1087 newicon() {
1088         _iconins ${FUNCNAME} "$@"
1089 }
1090
1091 # @FUNCTION: strip-linguas
1092 # @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>]
1093 # @DESCRIPTION:
1094 # Make sure that LINGUAS only contains languages that
1095 # a package can support.  The first form allows you to
1096 # specify a list of LINGUAS.  The -i builds a list of po
1097 # files found in all the directories and uses the
1098 # intersection of the lists.  The -u builds a list of po
1099 # files found in all the directories and uses the union
1100 # of the lists.
1101 strip-linguas() {
1102         local ls newls nols
1103         if [[ $1 == "-i" ]] || [[ $1 == "-u" ]] ; then
1104                 local op=$1; shift
1105                 ls=$(find "$1" -name '*.po' -exec basename {} .po ';'); shift
1106                 local d f
1107                 for d in "$@" ; do
1108                         if [[ ${op} == "-u" ]] ; then
1109                                 newls=${ls}
1110                         else
1111                                 newls=""
1112                         fi
1113                         for f in $(find "$d" -name '*.po' -exec basename {} .po ';') ; do
1114                                 if [[ ${op} == "-i" ]] ; then
1115                                         has ${f} ${ls} && newls="${newls} ${f}"
1116                                 else
1117                                         has ${f} ${ls} || newls="${newls} ${f}"
1118                                 fi
1119                         done
1120                         ls=${newls}
1121                 done
1122         else
1123                 ls="$@"
1124         fi
1125
1126         nols=""
1127         newls=""
1128         for f in ${LINGUAS} ; do
1129                 if has ${f} ${ls} ; then
1130                         newls="${newls} ${f}"
1131                 else
1132                         nols="${nols} ${f}"
1133                 fi
1134         done
1135         [[ -n ${nols} ]] \
1136                 && einfo "Sorry, but ${PN} does not support the LINGUAS:" ${nols}
1137         export LINGUAS=${newls:1}
1138 }
1139
1140 # @FUNCTION: preserve_old_lib
1141 # @USAGE: <libs to preserve> [more libs]
1142 # @DESCRIPTION:
1143 # These functions are useful when a lib in your package changes ABI SONAME.
1144 # An example might be from libogg.so.0 to libogg.so.1.  Removing libogg.so.0
1145 # would break packages that link against it.  Most people get around this
1146 # by using the portage SLOT mechanism, but that is not always a relevant
1147 # solution, so instead you can call this from pkg_preinst.  See also the
1148 # preserve_old_lib_notify function.
1149 preserve_old_lib() {
1150         _eutils_eprefix_init
1151         if [[ ${EBUILD_PHASE} != "preinst" ]] ; then
1152                 eerror "preserve_old_lib() must be called from pkg_preinst() only"
1153                 die "Invalid preserve_old_lib() usage"
1154         fi
1155         [[ -z $1 ]] && die "Usage: preserve_old_lib <library to preserve> [more libraries to preserve]"
1156
1157         # let portage worry about it
1158         has preserve-libs ${FEATURES} && return 0
1159
1160         local lib dir
1161         for lib in "$@" ; do
1162                 [[ -e ${EROOT}/${lib} ]] || continue
1163                 dir=${lib%/*}
1164                 dodir ${dir} || die "dodir ${dir} failed"
1165                 cp "${EROOT}"/${lib} "${ED}"/${lib} || die "cp ${lib} failed"
1166                 touch "${ED}"/${lib}
1167         done
1168 }
1169
1170 # @FUNCTION: preserve_old_lib_notify
1171 # @USAGE: <libs to notify> [more libs]
1172 # @DESCRIPTION:
1173 # Spit helpful messages about the libraries preserved by preserve_old_lib.
1174 preserve_old_lib_notify() {
1175         if [[ ${EBUILD_PHASE} != "postinst" ]] ; then
1176                 eerror "preserve_old_lib_notify() must be called from pkg_postinst() only"
1177                 die "Invalid preserve_old_lib_notify() usage"
1178         fi
1179
1180         # let portage worry about it
1181         has preserve-libs ${FEATURES} && return 0
1182
1183         _eutils_eprefix_init
1184
1185         local lib notice=0
1186         for lib in "$@" ; do
1187                 [[ -e ${EROOT}/${lib} ]] || continue
1188                 if [[ ${notice} -eq 0 ]] ; then
1189                         notice=1
1190                         ewarn "Old versions of installed libraries were detected on your system."
1191                         ewarn "In order to avoid breaking packages that depend on these old libs,"
1192                         ewarn "the libraries are not being removed.  You need to run revdep-rebuild"
1193                         ewarn "in order to remove these old dependencies.  If you do not have this"
1194                         ewarn "helper program, simply emerge the 'gentoolkit' package."
1195                         ewarn
1196                 fi
1197                 ewarn "  # revdep-rebuild --library '${lib}' && rm '${lib}'"
1198         done
1199 }
1200
1201 # @FUNCTION: built_with_use
1202 # @USAGE: [--hidden] [--missing <action>] [-a|-o] <DEPEND ATOM> <List of USE flags>
1203 # @DESCRIPTION:
1204 #
1205 # Deprecated: Use EAPI 2 use deps in DEPEND|RDEPEND and with has_version calls.
1206 #
1207 # A temporary hack until portage properly supports DEPENDing on USE
1208 # flags being enabled in packages.  This will check to see if the specified
1209 # DEPEND atom was built with the specified list of USE flags.  The
1210 # --missing option controls the behavior if called on a package that does
1211 # not actually support the defined USE flags (aka listed in IUSE).
1212 # The default is to abort (call die).  The -a and -o flags control
1213 # the requirements of the USE flags.  They correspond to "and" and "or"
1214 # logic.  So the -a flag means all listed USE flags must be enabled
1215 # while the -o flag means at least one of the listed IUSE flags must be
1216 # enabled.  The --hidden option is really for internal use only as it
1217 # means the USE flag we're checking is hidden expanded, so it won't be found
1218 # in IUSE like normal USE flags.
1219 #
1220 # Remember that this function isn't terribly intelligent so order of optional
1221 # flags matter.
1222 built_with_use() {
1223         _eutils_eprefix_init
1224         local hidden="no"
1225         if [[ $1 == "--hidden" ]] ; then
1226                 hidden="yes"
1227                 shift
1228         fi
1229
1230         local missing_action="die"
1231         if [[ $1 == "--missing" ]] ; then
1232                 missing_action=$2
1233                 shift ; shift
1234                 case ${missing_action} in
1235                         true|false|die) ;;
1236                         *) die "unknown action '${missing_action}'";;
1237                 esac
1238         fi
1239
1240         local opt=$1
1241         [[ ${opt:0:1} = "-" ]] && shift || opt="-a"
1242
1243         local PKG=$(best_version $1)
1244         [[ -z ${PKG} ]] && die "Unable to resolve $1 to an installed package"
1245         shift
1246
1247         local USEFILE=${EROOT}/var/db/pkg/${PKG}/USE
1248         local IUSEFILE=${EROOT}/var/db/pkg/${PKG}/IUSE
1249
1250         # if the IUSE file doesn't exist, the read will error out, we need to handle
1251         # this gracefully
1252         if [[ ! -e ${USEFILE} ]] || [[ ! -e ${IUSEFILE} && ${hidden} == "no" ]] ; then
1253                 case ${missing_action} in
1254                         true)   return 0;;
1255                         false)  return 1;;
1256                         die)    die "Unable to determine what USE flags $PKG was built with";;
1257                 esac
1258         fi
1259
1260         if [[ ${hidden} == "no" ]] ; then
1261                 local IUSE_BUILT=( $(<"${IUSEFILE}") )
1262                 # Don't check USE_EXPAND #147237
1263                 local expand
1264                 for expand in $(echo ${USE_EXPAND} | tr '[:upper:]' '[:lower:]') ; do
1265                         if [[ $1 == ${expand}_* ]] ; then
1266                                 expand=""
1267                                 break
1268                         fi
1269                 done
1270                 if [[ -n ${expand} ]] ; then
1271                         if ! has $1 ${IUSE_BUILT[@]#[-+]} ; then
1272                                 case ${missing_action} in
1273                                         true)  return 0;;
1274                                         false) return 1;;
1275                                         die)   die "$PKG does not actually support the $1 USE flag!";;
1276                                 esac
1277                         fi
1278                 fi
1279         fi
1280
1281         local USE_BUILT=$(<${USEFILE})
1282         while [[ $# -gt 0 ]] ; do
1283                 if [[ ${opt} = "-o" ]] ; then
1284                         has $1 ${USE_BUILT} && return 0
1285                 else
1286                         has $1 ${USE_BUILT} || return 1
1287                 fi
1288                 shift
1289         done
1290         [[ ${opt} = "-a" ]]
1291 }
1292
1293 # If an overlay has eclass overrides, but doesn't actually override the
1294 # libtool.eclass, we'll have ECLASSDIR pointing to the active overlay's
1295 # eclass/ dir, but libtool.eclass is still in the main Gentoo tree.  So
1296 # add a check to locate the ELT-patches/ regardless of what's going on.
1297 # Note: Duplicated in libtool.eclass.
1298 _EUTILS_ECLASSDIR_LOCAL=${BASH_SOURCE[0]%/*}
1299 eutils_elt_patch_dir() {
1300         local d="${ECLASSDIR}/ELT-patches"
1301         if [[ ! -d ${d} ]] ; then
1302                 d="${_EUTILS_ECLASSDIR_LOCAL}/ELT-patches"
1303         fi
1304         echo "${d}"
1305 }
1306
1307 # @FUNCTION: epunt_cxx
1308 # @USAGE: [dir to scan]
1309 # @DESCRIPTION:
1310 # Many configure scripts wrongly bail when a C++ compiler could not be
1311 # detected.  If dir is not specified, then it defaults to ${S}.
1312 #
1313 # https://bugs.gentoo.org/73450
1314 epunt_cxx() {
1315         local dir=$1
1316         [[ -z ${dir} ]] && dir=${S}
1317         ebegin "Removing useless C++ checks"
1318         local f p any_found
1319         while IFS= read -r -d '' f; do
1320                 for p in "$(eutils_elt_patch_dir)"/nocxx/*.patch ; do
1321                         if patch --no-backup-if-mismatch -p1 "${f}" "${p}" >/dev/null ; then
1322                                 any_found=1
1323                                 break
1324                         fi
1325                 done
1326         done < <(find "${dir}" -name configure -print0)
1327
1328         if [[ -z ${any_found} ]]; then
1329                 eqawarn "epunt_cxx called unnecessarily (no C++ checks to punt)."
1330         fi
1331         eend 0
1332 }
1333
1334 # @FUNCTION: make_wrapper
1335 # @USAGE: <wrapper> <target> [chdir] [libpaths] [installpath]
1336 # @DESCRIPTION:
1337 # Create a shell wrapper script named wrapper in installpath
1338 # (defaults to the bindir) to execute target (default of wrapper) by
1339 # first optionally setting LD_LIBRARY_PATH to the colon-delimited
1340 # libpaths followed by optionally changing directory to chdir.
1341 make_wrapper() {
1342         _eutils_eprefix_init
1343         local wrapper=$1 bin=$2 chdir=$3 libdir=$4 path=$5
1344         local tmpwrapper=$(emktemp)
1345
1346         (
1347         echo '#!/bin/sh'
1348         [[ -n ${chdir} ]] && printf 'cd "%s"\n' "${EPREFIX}${chdir}"
1349         if [[ -n ${libdir} ]] ; then
1350                 local var
1351                 if [[ ${CHOST} == *-darwin* ]] ; then
1352                         var=DYLD_LIBRARY_PATH
1353                 else
1354                         var=LD_LIBRARY_PATH
1355                 fi
1356                 cat <<-EOF
1357                         if [ "\${${var}+set}" = "set" ] ; then
1358                                 export ${var}="\${${var}}:${EPREFIX}${libdir}"
1359                         else
1360                                 export ${var}="${EPREFIX}${libdir}"
1361                         fi
1362                 EOF
1363         fi
1364         # We don't want to quote ${bin} so that people can pass complex
1365         # things as ${bin} ... "./someprog --args"
1366         printf 'exec %s "$@"\n' "${bin/#\//${EPREFIX}/}"
1367         ) > "${tmpwrapper}"
1368         chmod go+rx "${tmpwrapper}"
1369
1370         if [[ -n ${path} ]] ; then
1371                 (
1372                 exeinto "${path}"
1373                 newexe "${tmpwrapper}" "${wrapper}"
1374                 ) || die
1375         else
1376                 newbin "${tmpwrapper}" "${wrapper}" || die
1377         fi
1378 }
1379
1380 # @FUNCTION: path_exists
1381 # @USAGE: [-a|-o] <paths>
1382 # @DESCRIPTION:
1383 # Check if the specified paths exist.  Works for all types of paths
1384 # (files/dirs/etc...).  The -a and -o flags control the requirements
1385 # of the paths.  They correspond to "and" and "or" logic.  So the -a
1386 # flag means all the paths must exist while the -o flag means at least
1387 # one of the paths must exist.  The default behavior is "and".  If no
1388 # paths are specified, then the return value is "false".
1389 path_exists() {
1390         local opt=$1
1391         [[ ${opt} == -[ao] ]] && shift || opt="-a"
1392
1393         # no paths -> return false
1394         # same behavior as: [[ -e "" ]]
1395         [[ $# -eq 0 ]] && return 1
1396
1397         local p r=0
1398         for p in "$@" ; do
1399                 [[ -e ${p} ]]
1400                 : $(( r += $? ))
1401         done
1402
1403         case ${opt} in
1404                 -a) return $(( r != 0 )) ;;
1405                 -o) return $(( r == $# )) ;;
1406         esac
1407 }
1408
1409 # @FUNCTION: use_if_iuse
1410 # @USAGE: <flag>
1411 # @DESCRIPTION:
1412 # Return true if the given flag is in USE and IUSE.
1413 #
1414 # Note that this function should not be used in the global scope.
1415 use_if_iuse() {
1416         in_iuse $1 || return 1
1417         use $1
1418 }
1419
1420 # @FUNCTION: prune_libtool_files
1421 # @USAGE: [--all|--modules]
1422 # @DESCRIPTION:
1423 # Locate unnecessary libtool files (.la) and libtool static archives
1424 # (.a) and remove them from installation image.
1425 #
1426 # By default, .la files are removed whenever the static linkage can
1427 # either be performed using pkg-config or doesn't introduce additional
1428 # flags.
1429 #
1430 # If '--modules' argument is passed, .la files for modules (plugins) are
1431 # removed as well. This is usually useful when the package installs
1432 # plugins and the plugin loader does not use .la files.
1433 #
1434 # If '--all' argument is passed, all .la files are removed without
1435 # performing any heuristic on them. You shouldn't ever use that,
1436 # and instead report a bug in the algorithm instead.
1437 #
1438 # The .a files are only removed whenever corresponding .la files state
1439 # that they should not be linked to, i.e. whenever these files
1440 # correspond to plugins.
1441 #
1442 # Note: if your package installs both static libraries and .pc files
1443 # which use variable substitution for -l flags, you need to add
1444 # pkg-config to your DEPEND.
1445 prune_libtool_files() {
1446         debug-print-function ${FUNCNAME} "$@"
1447
1448         local removing_all removing_modules opt
1449         _eutils_eprefix_init
1450         for opt; do
1451                 case "${opt}" in
1452                         --all)
1453                                 removing_all=1
1454                                 removing_modules=1
1455                                 ;;
1456                         --modules)
1457                                 removing_modules=1
1458                                 ;;
1459                         *)
1460                                 die "Invalid argument to ${FUNCNAME}(): ${opt}"
1461                 esac
1462         done
1463
1464         local f
1465         local queue=()
1466         while IFS= read -r -d '' f; do # for all .la files
1467                 local archivefile=${f/%.la/.a}
1468
1469                 # The following check is done by libtool itself.
1470                 # It helps us avoid removing random files which match '*.la',
1471                 # see bug #468380.
1472                 if ! sed -n -e '/^# Generated by .*libtool/q0;4q1' "${f}"; then
1473                         continue
1474                 fi
1475
1476                 [[ ${f} != ${archivefile} ]] || die 'regex sanity check failed'
1477                 local reason= pkgconfig_scanned=
1478                 local snotlink=$(sed -n -e 's:^shouldnotlink=::p' "${f}")
1479
1480                 if [[ ${snotlink} == yes ]]; then
1481
1482                         # Remove static libs we're not supposed to link against.
1483                         if [[ -f ${archivefile} ]]; then
1484                                 einfo "Removing unnecessary ${archivefile#${D%/}} (static plugin)"
1485                                 queue+=( "${archivefile}" )
1486                         fi
1487
1488                         # The .la file may be used by a module loader, so avoid removing it
1489                         # unless explicitly requested.
1490                         if [[ ${removing_modules} ]]; then
1491                                 reason='module'
1492                         fi
1493
1494                 else
1495
1496                         # Remove .la files when:
1497                         # - user explicitly wants us to remove all .la files,
1498                         # - respective static archive doesn't exist,
1499                         # - they are covered by a .pc file already,
1500                         # - they don't provide any new information (no libs & no flags).
1501
1502                         if [[ ${removing_all} ]]; then
1503                                 reason='requested'
1504                         elif [[ ! -f ${archivefile} ]]; then
1505                                 reason='no static archive'
1506                         elif [[ ! $(sed -nre \
1507                                         "s/^(dependency_libs|inherited_linker_flags)='(.*)'$/\2/p" \
1508                                         "${f}") ]]; then
1509                                 reason='no libs & flags'
1510                         else
1511                                 if [[ ! ${pkgconfig_scanned} ]]; then
1512                                         # Create a list of all .pc-covered libs.
1513                                         local pc_libs=()
1514                                         if [[ ! ${removing_all} ]]; then
1515                                                 local pc
1516                                                 local tf=${T}/prune-lt-files.pc
1517                                                 local pkgconf=$(tc-getPKG_CONFIG)
1518
1519                                                 while IFS= read -r -d '' pc; do # for all .pc files
1520                                                         local arg libs
1521
1522                                                         # Use pkg-config if available (and works),
1523                                                         # fallback to sed.
1524                                                         if ${pkgconf} --exists "${pc}" &>/dev/null; then
1525                                                                 sed -e '/^Requires:/d' "${pc}" > "${tf}"
1526                                                                 libs=$(${pkgconf} --libs "${tf}")
1527                                                         else
1528                                                                 libs=$(sed -ne 's/^Libs://p' "${pc}")
1529                                                         fi
1530
1531                                                         for arg in ${libs}; do
1532                                                                 if [[ ${arg} == -l* ]]; then
1533                                                                         if [[ ${arg} == '*$*' ]]; then
1534                                                                                 eqawarn "${FUNCNAME}: variable substitution likely failed in ${pc}"
1535                                                                                 eqawarn "(arg: ${arg})"
1536                                                                                 eqawarn "Most likely, you need to add virtual/pkgconfig to DEPEND."
1537                                                                         fi
1538
1539                                                                         pc_libs+=( lib${arg#-l}.la )
1540                                                                 fi
1541                                                         done
1542                                                 done < <(find "${D}" -type f -name '*.pc' -print0)
1543
1544                                                 rm -f "${tf}"
1545                                         fi
1546
1547                                         pkgconfig_scanned=1
1548                                 fi # pkgconfig_scanned
1549
1550                                 has "${f##*/}" "${pc_libs[@]}" && reason='covered by .pc'
1551                         fi # removal due to .pc
1552
1553                 fi # shouldnotlink==no
1554
1555                 if [[ ${reason} ]]; then
1556                         einfo "Removing unnecessary ${f#${D%/}} (${reason})"
1557                         queue+=( "${f}" )
1558                 fi
1559         done < <(find "${ED}" -xtype f -name '*.la' -print0)
1560
1561         if [[ ${queue[@]} ]]; then
1562                 rm -f "${queue[@]}"
1563         fi
1564 }
1565
1566 # @FUNCTION: optfeature
1567 # @USAGE: <short description> <package atom to match> [other atoms]
1568 # @DESCRIPTION:
1569 # Print out a message suggesting an optional package (or packages) which
1570 # provide the described functionality
1571 #
1572 # The following snippet would suggest app-misc/foo for optional foo support,
1573 # app-misc/bar or app-misc/baz[bar] for optional bar support
1574 # and either both app-misc/a and app-misc/b or app-misc/c for alphabet support.
1575 # @CODE
1576 #       optfeature "foo support" app-misc/foo
1577 #       optfeature "bar support" app-misc/bar app-misc/baz[bar]
1578 #       optfeature "alphabet support" "app-misc/a app-misc/b" app-misc/c
1579 # @CODE
1580 optfeature() {
1581         debug-print-function ${FUNCNAME} "$@"
1582         local i j msg
1583         local desc=$1
1584         local flag=0
1585         shift
1586         for i; do
1587                 for j in ${i}; do
1588                         if has_version "${j}"; then
1589                                 flag=1
1590                         else
1591                                 flag=0
1592                                 break
1593                         fi
1594                 done
1595                 if [[ ${flag} -eq 1 ]]; then
1596                         break
1597                 fi
1598         done
1599         if [[ ${flag} -eq 0 ]]; then
1600                 for i; do
1601                         msg=" "
1602                         for j in ${i}; do
1603                                 msg+=" ${j} and"
1604                         done
1605                         msg="${msg:0: -4} for ${desc}"
1606                         elog "${msg}"
1607                 done
1608         fi
1609 }
1610
1611 fi
1612
1613 check_license() {
1614         die "you no longer need this as portage supports ACCEPT_LICENSE itself"
1615 }
1616
1617 case ${EAPI:-0} in
1618 0|1|2)
1619
1620 # @FUNCTION: epause
1621 # @USAGE: [seconds]
1622 # @DESCRIPTION:
1623 # Sleep for the specified number of seconds (default of 5 seconds).  Useful when
1624 # printing a message the user should probably be reading and often used in
1625 # conjunction with the ebeep function.  If the EPAUSE_IGNORE env var is set,
1626 # don't wait at all. Defined in EAPIs 0 1 and 2.
1627 epause() {
1628         [[ -z ${EPAUSE_IGNORE} ]] && sleep ${1:-5}
1629 }
1630
1631 # @FUNCTION: ebeep
1632 # @USAGE: [number of beeps]
1633 # @DESCRIPTION:
1634 # Issue the specified number of beeps (default of 5 beeps).  Useful when
1635 # printing a message the user should probably be reading and often used in
1636 # conjunction with the epause function.  If the EBEEP_IGNORE env var is set,
1637 # don't beep at all. Defined in EAPIs 0 1 and 2.
1638 ebeep() {
1639         local n
1640         if [[ -z ${EBEEP_IGNORE} ]] ; then
1641                 for ((n=1 ; n <= ${1:-5} ; n++)) ; do
1642                         echo -ne "\a"
1643                         sleep 0.1 &>/dev/null ; sleep 0,1 &>/dev/null
1644                         echo -ne "\a"
1645                         sleep 1
1646                 done
1647         fi
1648 }
1649
1650 ;;
1651 *)
1652
1653 ebeep() {
1654         ewarn "QA Notice: ebeep is not defined in EAPI=${EAPI}, please file a bug at https://bugs.gentoo.org"
1655 }
1656
1657 epause() {
1658         ewarn "QA Notice: epause is not defined in EAPI=${EAPI}, please file a bug at https://bugs.gentoo.org"
1659 }
1660
1661 ;;
1662 esac
1663
1664 case ${EAPI:-0} in
1665 0|1|2|3|4)
1666
1667 # @FUNCTION: usex
1668 # @USAGE: <USE flag> [true output] [false output] [true suffix] [false suffix]
1669 # @DESCRIPTION:
1670 # Proxy to declare usex for package managers or EAPIs that do not provide it
1671 # and use the package manager implementation when available (i.e. EAPI >= 5).
1672 # If USE flag is set, echo [true output][true suffix] (defaults to "yes"),
1673 # otherwise echo [false output][false suffix] (defaults to "no").
1674 usex() { use "$1" && echo "${2-yes}$4" || echo "${3-no}$5" ; } #382963
1675
1676 ;;
1677 esac
1678
1679 case ${EAPI:-0} in
1680 0|1|2|3|4|5)
1681
1682 # @VARIABLE: EPATCH_USER_SOURCE
1683 # @DESCRIPTION:
1684 # Location for user patches, see the epatch_user function.
1685 # Should be set by the user. Don't set this in ebuilds.
1686 : ${EPATCH_USER_SOURCE:=${PORTAGE_CONFIGROOT%/}/etc/portage/patches}
1687
1688 # @FUNCTION: epatch_user
1689 # @USAGE:
1690 # @DESCRIPTION:
1691 # Applies user-provided patches to the source tree. The patches are
1692 # taken from /etc/portage/patches/<CATEGORY>/<P-PR|P|PN>[:SLOT]/, where the first
1693 # of these three directories to exist will be the one to use, ignoring
1694 # any more general directories which might exist as well. They must end
1695 # in ".patch" to be applied.
1696 #
1697 # User patches are intended for quick testing of patches without ebuild
1698 # modifications, as well as for permanent customizations a user might
1699 # desire. Obviously, there can be no official support for arbitrarily
1700 # patched ebuilds. So whenever a build log in a bug report mentions that
1701 # user patches were applied, the user should be asked to reproduce the
1702 # problem without these.
1703 #
1704 # Not all ebuilds do call this function, so placing patches in the
1705 # stated directory might or might not work, depending on the package and
1706 # the eclasses it inherits and uses. It is safe to call the function
1707 # repeatedly, so it is always possible to add a call at the ebuild
1708 # level. The first call is the time when the patches will be
1709 # applied.
1710 #
1711 # Ideally, this function should be called after gentoo-specific patches
1712 # have been applied, so that their code can be modified as well, but
1713 # before calls to e.g. eautoreconf, as the user patches might affect
1714 # autotool input files as well.
1715 epatch_user() {
1716         [[ $# -ne 0 ]] && die "epatch_user takes no options"
1717
1718         # Allow multiple calls to this function; ignore all but the first
1719         local applied="${T}/epatch_user.log"
1720         [[ -e ${applied} ]] && return 2
1721
1722         # don't clobber any EPATCH vars that the parent might want
1723         local EPATCH_SOURCE check
1724         for check in ${CATEGORY}/{${P}-${PR},${P},${PN}}{,:${SLOT}}; do
1725                 EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${CTARGET}/${check}
1726                 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${CHOST}/${check}
1727                 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${check}
1728                 if [[ -d ${EPATCH_SOURCE} ]] ; then
1729                         EPATCH_SOURCE=${EPATCH_SOURCE} \
1730                         EPATCH_SUFFIX="patch" \
1731                         EPATCH_FORCE="yes" \
1732                         EPATCH_MULTI_MSG="Applying user patches from ${EPATCH_SOURCE} ..." \
1733                         epatch
1734                         echo "${EPATCH_SOURCE}" > "${applied}"
1735                         has epatch_user_death_notice ${EBUILD_DEATH_HOOKS} || EBUILD_DEATH_HOOKS+=" epatch_user_death_notice"
1736                         return 0
1737                 fi
1738         done
1739         echo "none" > "${applied}"
1740         return 1
1741 }
1742
1743 # @FUNCTION: epatch_user_death_notice
1744 # @INTERNAL
1745 # @DESCRIPTION:
1746 # Include an explicit notice in the die message itself that user patches were
1747 # applied to this build.
1748 epatch_user_death_notice() {
1749         ewarn "!!! User patches were applied to this build!"
1750 }
1751
1752 # @FUNCTION: einstalldocs
1753 # @DESCRIPTION:
1754 # Install documentation using DOCS and HTML_DOCS.
1755 #
1756 # If DOCS is declared and non-empty, all files listed in it are
1757 # installed. The files must exist, otherwise the function will fail.
1758 # In EAPI 4 and subsequent EAPIs DOCS may specify directories as well,
1759 # in other EAPIs using directories is unsupported.
1760 #
1761 # If DOCS is not declared, the files matching patterns given
1762 # in the default EAPI implementation of src_install will be installed.
1763 # If this is undesired, DOCS can be set to empty value to prevent any
1764 # documentation from being installed.
1765 #
1766 # If HTML_DOCS is declared and non-empty, all files and/or directories
1767 # listed in it are installed as HTML docs (using dohtml).
1768 #
1769 # Both DOCS and HTML_DOCS can either be an array or a whitespace-
1770 # separated list. Whenever directories are allowed, '<directory>/.' may
1771 # be specified in order to install all files within the directory
1772 # without creating a sub-directory in docdir.
1773 #
1774 # Passing additional options to dodoc and dohtml is not supported.
1775 # If you needed such a thing, you need to call those helpers explicitly.
1776 einstalldocs() {
1777         debug-print-function ${FUNCNAME} "${@}"
1778
1779         local dodoc_opts=-r
1780         has ${EAPI} 0 1 2 3 && dodoc_opts=
1781
1782         if ! declare -p DOCS &>/dev/null ; then
1783                 local d
1784                 for d in README* ChangeLog AUTHORS NEWS TODO CHANGES \
1785                                 THANKS BUGS FAQ CREDITS CHANGELOG ; do
1786                         if [[ -s ${d} ]] ; then
1787                                 dodoc "${d}" || die
1788                         fi
1789                 done
1790         elif [[ $(declare -p DOCS) == "declare -a"* ]] ; then
1791                 if [[ ${DOCS[@]} ]] ; then
1792                         dodoc ${dodoc_opts} "${DOCS[@]}" || die
1793                 fi
1794         else
1795                 if [[ ${DOCS} ]] ; then
1796                         dodoc ${dodoc_opts} ${DOCS} || die
1797                 fi
1798         fi
1799
1800         if [[ $(declare -p HTML_DOCS 2>/dev/null) == "declare -a"* ]] ; then
1801                 if [[ ${HTML_DOCS[@]} ]] ; then
1802                         dohtml -r "${HTML_DOCS[@]}" || die
1803                 fi
1804         else
1805                 if [[ ${HTML_DOCS} ]] ; then
1806                         dohtml -r ${HTML_DOCS} || die
1807                 fi
1808         fi
1809
1810         return 0
1811 }
1812
1813 # @FUNCTION: in_iuse
1814 # @USAGE: <flag>
1815 # @DESCRIPTION:
1816 # Determines whether the given flag is in IUSE. Strips IUSE default prefixes
1817 # as necessary.
1818 #
1819 # Note that this function should not be used in the global scope.
1820 in_iuse() {
1821         debug-print-function ${FUNCNAME} "${@}"
1822         [[ ${#} -eq 1 ]] || die "Invalid args to ${FUNCNAME}()"
1823
1824         local flag=${1}
1825         local liuse=( ${IUSE} )
1826
1827         has "${flag}" "${liuse[@]#[+-]}"
1828 }
1829
1830 ;;
1831 esac