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