/[gentoo-x86]/eclass/eutils.eclass
Gentoo

Contents of /eclass/eutils.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.373 - (hide annotations) (download)
Fri Dec 16 23:38:41 2011 UTC (2 years, 9 months ago) by vapier
Branch: MAIN
Changes since 1.372: +78 -14 lines
add new generic stack helpers estack_{push,pop}, rebase eshopts_{push,pop} on top of those, and then add new helpers for messing with the umask sanely

1 vapier 1.356 # Copyright 1999-2011 Gentoo Foundation
2 azarah 1.1 # Distributed under the terms of the GNU General Public License v2
3 vapier 1.373 # $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.372 2011/12/14 17:36:18 vapier Exp $
4 vapier 1.283
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 swegener 1.286 #
15 vapier 1.283 # Due to the nature of this eclass, some functions may have maintainers
16     # different from the overall eclass!
17 azarah 1.1
18 vapier 1.371 if [[ ${___ECLASS_ONCE_EUTILS} != "recur -_+^+_- spank" ]] ; then
19     ___ECLASS_ONCE_EUTILS="recur -_+^+_- spank"
20    
21 vapier 1.368 inherit multilib portability user
22 azarah 1.1
23 vapier 1.22 DESCRIPTION="Based on the ${ECLASS} eclass"
24 azarah 1.1
25 betelgeuse 1.329 if has "${EAPI:-0}" 0 1 2; then
26    
27 vapier 1.283 # @FUNCTION: epause
28     # @USAGE: [seconds]
29     # @DESCRIPTION:
30     # Sleep for the specified number of seconds (default of 5 seconds). Useful when
31     # printing a message the user should probably be reading and often used in
32     # conjunction with the ebeep function. If the EPAUSE_IGNORE env var is set,
33 betelgeuse 1.329 # don't wait at all. Defined in EAPIs 0 1 and 2.
34 ciaranm 1.98 epause() {
35 vapier 1.245 [[ -z ${EPAUSE_IGNORE} ]] && sleep ${1:-5}
36 ciaranm 1.98 }
37    
38 vapier 1.283 # @FUNCTION: ebeep
39     # @USAGE: [number of beeps]
40     # @DESCRIPTION:
41     # Issue the specified number of beeps (default of 5 beeps). Useful when
42     # printing a message the user should probably be reading and often used in
43     # conjunction with the epause function. If the EBEEP_IGNORE env var is set,
44 betelgeuse 1.329 # don't beep at all. Defined in EAPIs 0 1 and 2.
45 ciaranm 1.98 ebeep() {
46     local n
47 vapier 1.245 if [[ -z ${EBEEP_IGNORE} ]] ; then
48 ciaranm 1.98 for ((n=1 ; n <= ${1:-5} ; n++)) ; do
49     echo -ne "\a"
50     sleep 0.1 &>/dev/null ; sleep 0,1 &>/dev/null
51     echo -ne "\a"
52     sleep 1
53     done
54     fi
55     }
56    
57 reavertm 1.331 else
58    
59 reavertm 1.332 ebeep() {
60 reavertm 1.337 ewarn "QA Notice: ebeep is not defined in EAPI=${EAPI}, please file a bug at http://bugs.gentoo.org"
61 reavertm 1.332 }
62 reavertm 1.331
63 reavertm 1.332 epause() {
64 reavertm 1.337 ewarn "QA Notice: epause is not defined in EAPI=${EAPI}, please file a bug at http://bugs.gentoo.org"
65 reavertm 1.332 }
66 reavertm 1.331
67 betelgeuse 1.329 fi
68    
69 betelgeuse 1.348 # @FUNCTION: eqawarn
70     # @USAGE: [message]
71     # @DESCRIPTION:
72 mgorny 1.363 # Proxy to ewarn for package managers that don't provide eqawarn and use the PM
73     # implementation if available. Reuses PORTAGE_ELOG_CLASSES as set by the dev
74     # profile.
75 betelgeuse 1.348 if ! declare -F eqawarn >/dev/null ; then
76     eqawarn() {
77 mgorny 1.363 has qa ${PORTAGE_ELOG_CLASSES} && ewarn "$@"
78 ferringb 1.370 :
79 betelgeuse 1.348 }
80     fi
81    
82 hollow 1.298 # @FUNCTION: ecvs_clean
83 vapier 1.299 # @USAGE: [list of dirs]
84 hollow 1.298 # @DESCRIPTION:
85 vapier 1.299 # Remove CVS directories recursiveley. Useful when a source tarball contains
86     # internal CVS directories. Defaults to $PWD.
87 hollow 1.298 ecvs_clean() {
88 vapier 1.299 [[ -z $* ]] && set -- .
89 hollow 1.298 find "$@" -type d -name 'CVS' -prune -print0 | xargs -0 rm -rf
90     find "$@" -type f -name '.cvs*' -print0 | xargs -0 rm -rf
91     }
92    
93     # @FUNCTION: esvn_clean
94 vapier 1.299 # @USAGE: [list of dirs]
95 hollow 1.298 # @DESCRIPTION:
96 vapier 1.299 # Remove .svn directories recursiveley. Useful when a source tarball contains
97     # internal Subversion directories. Defaults to $PWD.
98 hollow 1.298 esvn_clean() {
99 vapier 1.299 [[ -z $* ]] && set -- .
100 hollow 1.298 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf
101     }
102    
103 vapier 1.373 # @FUNCTION: estack_push
104     # @USAGE: <stack> [items to push]
105     # @DESCRIPTION:
106     # Push any number of items onto the specified stack. Pick a name that
107     # is a valid variable (i.e. stick to alphanumerics), and push as many
108     # items as you like onto the stack at once.
109     #
110     # The following code snippet will echo 5, then 4, then 3, then ...
111     # @CODE
112     # estack_push mystack 1 2 3 4 5
113     # while estack_pop mystack i ; do
114     # echo "${i}"
115     # done
116     # @CODE
117     estack_push() {
118     [[ $# -eq 0 ]] && die "estack_push: incorrect # of arguments"
119     local stack_name="__ESTACK_$1__" ; shift
120     eval ${stack_name}+=\( \"\$@\" \)
121     }
122    
123     # @FUNCTION: estack_pop
124     # @USAGE: <stack> [variable]
125     # @DESCRIPTION:
126     # Pop a single item off the specified stack. If a variable is specified,
127     # the popped item is stored there. If no more items are available, return
128     # 1, else return 0. See estack_push for more info.
129     estack_pop() {
130     [[ $# -eq 0 || $# -gt 2 ]] && die "estack_pop: incorrect # of arguments"
131    
132     # We use the fugly __estack_xxx var names to avoid collision with
133     # passing back the return value. If we used "local i" and the
134     # caller ran `estack_pop ... i`, we'd end up setting the local
135     # copy of "i" rather than the caller's copy. The __estack_xxx
136     # garbage is preferable to using $1/$2 everywhere as that is a
137     # bit harder to read.
138     local __estack_name="__ESTACK_$1__" ; shift
139     local __estack_retvar=$1 ; shift
140     eval local __estack_i=\${#${__estack_name}[@]}
141     # Don't warn -- let the caller interpret this as a failure
142     # or as normal behavior (akin to `shift`)
143     [[ $(( --__estack_i )) -eq -1 ]] && return 1
144    
145     if [[ -n ${__estack_retvar} ]] ; then
146     eval ${__estack_retvar}=\"\${${__estack_name}[${__estack_i}]}\"
147     fi
148     eval unset ${__estack_name}[${__estack_i}]
149     }
150    
151 vapier 1.322 # @FUNCTION: eshopts_push
152 vapier 1.330 # @USAGE: [options to `set` or `shopt`]
153 vapier 1.322 # @DESCRIPTION:
154     # Often times code will want to enable a shell option to change code behavior.
155     # Since changing shell options can easily break other pieces of code (which
156     # assume the default state), eshopts_push is used to (1) push the current shell
157     # options onto a stack and (2) pass the specified arguments to set.
158     #
159 vapier 1.330 # If the first argument is '-s' or '-u', we assume you want to call `shopt`
160     # rather than `set` as there are some options only available via that.
161     #
162 vapier 1.322 # A common example is to disable shell globbing so that special meaning/care
163     # may be used with variables/arguments to custom functions. That would be:
164     # @CODE
165     # eshopts_push -o noglob
166     # for x in ${foo} ; do
167     # if ...some check... ; then
168     # eshopts_pop
169     # return 0
170     # fi
171     # done
172     # eshopts_pop
173     # @CODE
174     eshopts_push() {
175     # have to assume __ESHOPTS_SAVE__ isn't screwed with
176     # as a `declare -a` here will reset its value
177 vapier 1.330 if [[ $1 == -[su] ]] ; then
178 vapier 1.373 estack_push eshopts "$(shopt -p)"
179 vapier 1.330 [[ $# -eq 0 ]] && return 0
180 vapier 1.373 shopt "$@" || die "${FUNCNAME}: bad options to shopt: $*"
181 vapier 1.330 else
182 vapier 1.373 estack_push eshopts $-
183 vapier 1.330 [[ $# -eq 0 ]] && return 0
184 vapier 1.373 set "$@" || die "${FUNCNAME}: bad options to set: $*"
185 vapier 1.330 fi
186 vapier 1.322 }
187    
188     # @FUNCTION: eshopts_pop
189     # @USAGE:
190     # @DESCRIPTION:
191     # Restore the shell options to the state saved with the corresponding
192     # eshopts_push call. See that function for more details.
193     eshopts_pop() {
194 vapier 1.373 local s
195     estack_pop eshopts s || die "${FUNCNAME}: unbalanced push"
196 vapier 1.330 if [[ ${s} == "shopt -"* ]] ; then
197 vapier 1.373 eval "${s}" || die "${FUNCNAME}: sanity: invalid shopt options: ${s}"
198 vapier 1.330 else
199 vapier 1.373 set +$- || die "${FUNCNAME}: sanity: invalid shell settings: $-"
200     set -${s} || die "${FUNCNAME}: sanity: unable to restore saved shell settings: ${s}"
201 vapier 1.330 fi
202 vapier 1.322 }
203    
204 vapier 1.373 # @FUNCTION: eumask_push
205     # @USAGE: <new umask>
206     # @DESCRIPTION:
207     # Set the umask to the new value specified while saving the previous
208     # value onto a stack. Useful for temporarily changing the umask.
209     eumask_push() {
210     estack_push eumask "$(umask)"
211     umask "$@" || die "${FUNCNAME}: bad options to umask: $*"
212     }
213    
214     # @FUNCTION: eumask_pop
215     # @USAGE:
216     # @DESCRIPTION:
217     # Restore the previous umask state.
218     eumask_pop() {
219     local s
220     estack_pop eumask s || die "${FUNCNAME}: unbalanced push"
221     umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}"
222     }
223    
224 vapier 1.325 # @VARIABLE: EPATCH_SOURCE
225     # @DESCRIPTION:
226     # Default directory to search for patches.
227 azarah 1.2 EPATCH_SOURCE="${WORKDIR}/patch"
228 vapier 1.325 # @VARIABLE: EPATCH_SUFFIX
229     # @DESCRIPTION:
230     # Default extension for patches (do not prefix the period yourself).
231 azarah 1.2 EPATCH_SUFFIX="patch.bz2"
232 vapier 1.325 # @VARIABLE: EPATCH_OPTS
233     # @DESCRIPTION:
234     # Default options for patch:
235     # @CODE
236     # -g0 - keep RCS, ClearCase, Perforce and SCCS happy #24571
237     # --no-backup-if-mismatch - do not leave .orig files behind
238     # -E - automatically remove empty files
239     # @CODE
240 vapier 1.230 EPATCH_OPTS="-g0 -E --no-backup-if-mismatch"
241 vapier 1.325 # @VARIABLE: EPATCH_EXCLUDE
242     # @DESCRIPTION:
243 mr_bones_ 1.308 # List of patches not to apply. Note this is only file names,
244 vapier 1.325 # and not the full path. Globs accepted.
245 azarah 1.6 EPATCH_EXCLUDE=""
246 vapier 1.325 # @VARIABLE: EPATCH_SINGLE_MSG
247     # @DESCRIPTION:
248 azarah 1.9 # Change the printed message for a single patch.
249     EPATCH_SINGLE_MSG=""
250 vapier 1.325 # @VARIABLE: EPATCH_MULTI_MSG
251     # @DESCRIPTION:
252 vapier 1.173 # Change the printed message for multiple patches.
253     EPATCH_MULTI_MSG="Applying various patches (bugfixes/updates) ..."
254 vapier 1.325 # @VARIABLE: EPATCH_FORCE
255     # @DESCRIPTION:
256     # Only require patches to match EPATCH_SUFFIX rather than the extended
257     # arch naming style.
258 azarah 1.29 EPATCH_FORCE="no"
259 azarah 1.2
260 vapier 1.325 # @FUNCTION: epatch
261     # @USAGE: [patches] [dirs of patches]
262     # @DESCRIPTION:
263     # epatch is designed to greatly simplify the application of patches. It can
264     # process patch files directly, or directories of patches. The patches may be
265     # compressed (bzip/gzip/etc...) or plain text. You generally need not specify
266     # the -p option as epatch will automatically attempt -p0 to -p5 until things
267     # apply successfully.
268 azarah 1.2 #
269 vapier 1.325 # If you do not specify any options, then epatch will default to the directory
270     # specified by EPATCH_SOURCE.
271 azarah 1.2 #
272 vapier 1.325 # When processing directories, epatch will apply all patches that match:
273     # @CODE
274 vapier 1.350 # if ${EPATCH_FORCE} != "yes"
275 vapier 1.325 # ??_${ARCH}_foo.${EPATCH_SUFFIX}
276     # else
277     # *.${EPATCH_SUFFIX}
278     # @CODE
279     # The leading ?? are typically numbers used to force consistent patch ordering.
280     # The arch field is used to apply patches only for the host architecture with
281     # the special value of "all" means apply for everyone. Note that using values
282     # other than "all" is highly discouraged -- you should apply patches all the
283     # time and let architecture details be detected at configure/compile time.
284 azarah 1.2 #
285 vapier 1.325 # If EPATCH_SUFFIX is empty, then no period before it is implied when searching
286     # for patches to apply.
287 azarah 1.2 #
288 vapier 1.325 # Refer to the other EPATCH_xxx variables for more customization of behavior.
289 azarah 1.2 epatch() {
290 swegener 1.231 _epatch_draw_line() {
291 vapier 1.325 # create a line of same length as input string
292 agriffis 1.229 [[ -z $1 ]] && set "$(printf "%65s" '')"
293     echo "${1//?/=}"
294 vapier 1.219 }
295 azarah 1.3
296 vapier 1.195 unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402
297    
298 vapier 1.325 # Let the rest of the code process one user arg at a time --
299     # each arg may expand into multiple patches, and each arg may
300     # need to start off with the default global EPATCH_xxx values
301     if [[ $# -gt 1 ]] ; then
302     local m
303 vapier 1.94 for m in "$@" ; do
304     epatch "${m}"
305     done
306     return 0
307 azarah 1.3 fi
308    
309 vapier 1.325 local SINGLE_PATCH="no"
310     # no args means process ${EPATCH_SOURCE}
311     [[ $# -eq 0 ]] && set -- "${EPATCH_SOURCE}"
312    
313     if [[ -f $1 ]] ; then
314 azarah 1.3 SINGLE_PATCH="yes"
315 vapier 1.325 set -- "$1"
316     # Use the suffix from the single patch (localize it); the code
317     # below will find the suffix for us
318     local EPATCH_SUFFIX=$1
319    
320     elif [[ -d $1 ]] ; then
321     # Some people like to make dirs of patches w/out suffixes (vim)
322     set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"}
323 danarmak 1.32
324 vapier 1.359 elif [[ -f ${EPATCH_SOURCE}/$1 ]] ; then
325     # Re-use EPATCH_SOURCE as a search dir
326     epatch "${EPATCH_SOURCE}/$1"
327     return $?
328    
329 azarah 1.3 else
330 vapier 1.325 # sanity check ... if it isn't a dir or file, wtf man ?
331     [[ $# -ne 0 ]] && EPATCH_SOURCE=$1
332     echo
333     eerror "Cannot find \$EPATCH_SOURCE! Value for \$EPATCH_SOURCE is:"
334     eerror
335     eerror " ${EPATCH_SOURCE}"
336     eerror " ( ${EPATCH_SOURCE##*/} )"
337     echo
338     die "Cannot find \$EPATCH_SOURCE!"
339 azarah 1.3 fi
340 azarah 1.2
341 vapier 1.325 local PIPE_CMD
342 azarah 1.2 case ${EPATCH_SUFFIX##*\.} in
343 vapier 1.325 xz) PIPE_CMD="xz -dc" ;;
344     lzma) PIPE_CMD="lzma -dc" ;;
345     bz2) PIPE_CMD="bzip2 -dc" ;;
346     gz|Z|z) PIPE_CMD="gzip -dc" ;;
347     ZIP|zip) PIPE_CMD="unzip -p" ;;
348     *) ;;
349 azarah 1.2 esac
350    
351 vapier 1.325 [[ ${SINGLE_PATCH} == "no" ]] && einfo "${EPATCH_MULTI_MSG}"
352    
353     local x
354     for x in "$@" ; do
355     # If the patch dir given contains subdirs, or our EPATCH_SUFFIX
356     # didn't match anything, ignore continue on
357     [[ ! -f ${x} ]] && continue
358    
359     local patchname=${x##*/}
360    
361     # Apply single patches, or forced sets of patches, or
362     # patches with ARCH dependant names.
363 flameeyes 1.266 # ???_arch_foo.patch
364 vapier 1.325 # Else, skip this input altogether
365     local a=${patchname#*_} # strip the ???_
366     a=${a%%_*} # strip the _foo.patch
367     if ! [[ ${SINGLE_PATCH} == "yes" || \
368 ulm 1.354 ${EPATCH_FORCE} == "yes" || \
369     ${a} == all || \
370     ${a} == ${ARCH} ]]
371 azarah 1.2 then
372 vapier 1.325 continue
373     fi
374 azarah 1.6
375 vapier 1.325 # Let people filter things dynamically
376     if [[ -n ${EPATCH_EXCLUDE} ]] ; then
377     # let people use globs in the exclude
378     eshopts_push -o noglob
379    
380 scarabeus 1.328 local ex
381 vapier 1.325 for ex in ${EPATCH_EXCLUDE} ; do
382 scarabeus 1.328 if [[ ${patchname} == ${ex} ]] ; then
383     eshopts_pop
384     continue 2
385     fi
386 vapier 1.325 done
387 vapier 1.326
388 vapier 1.325 eshopts_pop
389     fi
390 danarmak 1.32
391 vapier 1.325 if [[ ${SINGLE_PATCH} == "yes" ]] ; then
392     if [[ -n ${EPATCH_SINGLE_MSG} ]] ; then
393     einfo "${EPATCH_SINGLE_MSG}"
394 azarah 1.3 else
395 vapier 1.325 einfo "Applying ${patchname} ..."
396 azarah 1.3 fi
397 vapier 1.325 else
398     einfo " ${patchname} ..."
399     fi
400 azarah 1.2
401 vapier 1.325 # most of the time, there will only be one run per unique name,
402     # but if there are more, make sure we get unique log filenames
403     local STDERR_TARGET="${T}/${patchname}.out"
404     if [[ -e ${STDERR_TARGET} ]] ; then
405     STDERR_TARGET="${T}/${patchname}-$$.out"
406     fi
407 azarah 1.2
408 vapier 1.369 printf "***** %s *****\nPWD: %s\n\n" "${patchname}" "${PWD}" > "${STDERR_TARGET}"
409 vapier 1.304
410 vapier 1.325 # Decompress the patch if need be
411     local count=0
412     local PATCH_TARGET
413     if [[ -n ${PIPE_CMD} ]] ; then
414     PATCH_TARGET="${T}/$$.patch"
415     echo "PIPE_COMMAND: ${PIPE_CMD} ${x} > ${PATCH_TARGET}" >> "${STDERR_TARGET}"
416 vapier 1.304
417 vapier 1.325 if ! (${PIPE_CMD} "${x}" > "${PATCH_TARGET}") >> "${STDERR_TARGET}" 2>&1 ; then
418     echo
419     eerror "Could not extract patch!"
420     #die "Could not extract patch!"
421     count=5
422     break
423 vapier 1.305 fi
424 vapier 1.325 else
425     PATCH_TARGET=${x}
426     fi
427 vapier 1.305
428 vapier 1.325 # Check for absolute paths in patches. If sandbox is disabled,
429     # people could (accidently) patch files in the root filesystem.
430     # Or trigger other unpleasantries #237667. So disallow -p0 on
431     # such patches.
432     local abs_paths=$(egrep -n '^[-+]{3} /' "${PATCH_TARGET}" | awk '$2 != "/dev/null" { print }')
433     if [[ -n ${abs_paths} ]] ; then
434     count=1
435     printf "NOTE: skipping -p0 due to absolute paths in patch:\n%s\n" "${abs_paths}" >> "${STDERR_TARGET}"
436     fi
437 vapier 1.353 # Similar reason, but with relative paths.
438     local rel_paths=$(egrep -n '^[-+]{3} [^ ]*[.][.]/' "${PATCH_TARGET}")
439     if [[ -n ${rel_paths} ]] ; then
440     eqawarn "QA Notice: Your patch uses relative paths '../'."
441     eqawarn " In the future this will cause a failure."
442     eqawarn "${rel_paths}"
443     fi
444 vapier 1.325
445     # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/
446     while [[ ${count} -lt 5 ]] ; do
447     # Generate some useful debug info ...
448     (
449     _epatch_draw_line "***** ${patchname} *****"
450     echo
451     echo "PATCH COMMAND: patch -p${count} ${EPATCH_OPTS} < '${PATCH_TARGET}'"
452     echo
453     _epatch_draw_line "***** ${patchname} *****"
454 vapier 1.360 patch -p${count} ${EPATCH_OPTS} --dry-run -f < "${PATCH_TARGET}" 2>&1
455     ret=$?
456     echo
457     echo "patch program exited with status ${ret}"
458     exit ${ret}
459 vapier 1.325 ) >> "${STDERR_TARGET}"
460 azarah 1.8
461 vapier 1.360 if [ $? -eq 0 ] ; then
462 vapier 1.325 (
463     _epatch_draw_line "***** ${patchname} *****"
464     echo
465     echo "ACTUALLY APPLYING ${patchname} ..."
466     echo
467     _epatch_draw_line "***** ${patchname} *****"
468     patch -p${count} ${EPATCH_OPTS} < "${PATCH_TARGET}" 2>&1
469 vapier 1.360 ret=$?
470     echo
471     echo "patch program exited with status ${ret}"
472     exit ${ret}
473 vapier 1.325 ) >> "${STDERR_TARGET}"
474 danarmak 1.32
475 vapier 1.325 if [ $? -ne 0 ] ; then
476     echo
477     eerror "A dry-run of patch command succeeded, but actually"
478     eerror "applying the patch failed!"
479     #die "Real world sux compared to the dreamworld!"
480     count=5
481 azarah 1.2 fi
482 vapier 1.325 break
483 azarah 1.8 fi
484    
485 vapier 1.325 : $(( count++ ))
486     done
487 azarah 1.8
488 vapier 1.325 # if we had to decompress the patch, delete the temp one
489     if [[ -n ${PIPE_CMD} ]] ; then
490     rm -f "${PATCH_TARGET}"
491     fi
492 azarah 1.3
493 vapier 1.325 if [[ ${count} -ge 5 ]] ; then
494     echo
495     eerror "Failed Patch: ${patchname} !"
496     eerror " ( ${PATCH_TARGET} )"
497     eerror
498     eerror "Include in your bugreport the contents of:"
499     eerror
500     eerror " ${STDERR_TARGET}"
501     echo
502     die "Failed Patch: ${patchname}!"
503 azarah 1.2 fi
504 vapier 1.325
505     # if everything worked, delete the patch log
506     rm -f "${STDERR_TARGET}"
507     eend 0
508 azarah 1.2 done
509 vapier 1.325
510     [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
511     : # everything worked
512 azarah 1.26 }
513 vapier 1.361
514     # @FUNCTION: epatch_user
515     # @USAGE:
516     # @DESCRIPTION:
517     # Applies user-provided patches to the source tree. The patches are
518     # taken from /etc/portage/patches/<CATEGORY>/<PF|P|PN>/, where the first
519     # of these three directories to exist will be the one to use, ignoring
520     # any more general directories which might exist as well.
521     #
522     # User patches are intended for quick testing of patches without ebuild
523     # modifications, as well as for permanent customizations a user might
524     # desire. Obviously, there can be no official support for arbitrarily
525     # patched ebuilds. So whenever a build log in a bug report mentions that
526     # user patches were applied, the user should be asked to reproduce the
527     # problem without these.
528     #
529     # Not all ebuilds do call this function, so placing patches in the
530     # stated directory might or might not work, depending on the package and
531     # the eclasses it inherits and uses. It is safe to call the function
532     # repeatedly, so it is always possible to add a call at the ebuild
533     # level. The first call is the time when the patches will be
534     # applied.
535     #
536     # Ideally, this function should be called after gentoo-specific patches
537     # have been applied, so that their code can be modified as well, but
538     # before calls to e.g. eautoreconf, as the user patches might affect
539     # autotool input files as well.
540 vapier 1.318 epatch_user() {
541     [[ $# -ne 0 ]] && die "epatch_user takes no options"
542    
543 vapier 1.361 # Allow multiple calls to this function; ignore all but the first
544 vapier 1.362 local applied="${T}/epatch_user.applied"
545 vapier 1.361 [[ -e ${applied} ]] && return 2
546    
547 vapier 1.318 # don't clobber any EPATCH vars that the parent might want
548 zmedico 1.323 local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches
549 vapier 1.318 for check in {${CATEGORY}/${PF},${CATEGORY}/${P},${CATEGORY}/${PN}}; do
550     EPATCH_SOURCE=${base}/${CTARGET}/${check}
551     [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check}
552     [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check}
553     if [[ -d ${EPATCH_SOURCE} ]] ; then
554     EPATCH_SOURCE=${EPATCH_SOURCE} \
555     EPATCH_SUFFIX="patch" \
556     EPATCH_FORCE="yes" \
557     EPATCH_MULTI_MSG="Applying user patches from ${EPATCH_SOURCE} ..." \
558     epatch
559 vapier 1.361 echo "${EPATCH_SOURCE}" > "${applied}"
560 vapier 1.349 return 0
561 vapier 1.318 fi
562     done
563 vapier 1.361 echo "none" > "${applied}"
564 vapier 1.349 return 1
565 vapier 1.318 }
566 azarah 1.26
567 vapier 1.283 # @FUNCTION: emktemp
568     # @USAGE: [temp dir]
569     # @DESCRIPTION:
570 vapier 1.52 # Cheap replacement for when debianutils (and thus mktemp)
571 vapier 1.283 # does not exist on the users system.
572 vapier 1.117 emktemp() {
573 vapier 1.119 local exe="touch"
574 vapier 1.194 [[ $1 == -d ]] && exe="mkdir" && shift
575     local topdir=$1
576 mr_bones_ 1.100
577 vapier 1.194 if [[ -z ${topdir} ]] ; then
578     [[ -z ${T} ]] \
579 vapier 1.117 && topdir="/tmp" \
580 vapier 1.194 || topdir=${T}
581 vapier 1.117 fi
582    
583 vapier 1.280 if ! type -P mktemp > /dev/null ; then
584     # system lacks `mktemp` so we have to fake it
585 vapier 1.117 local tmp=/
586 vapier 1.194 while [[ -e ${tmp} ]] ; do
587     tmp=${topdir}/tmp.${RANDOM}.${RANDOM}.${RANDOM}
588 vapier 1.117 done
589 vapier 1.194 ${exe} "${tmp}" || ${exe} -p "${tmp}"
590 vapier 1.117 echo "${tmp}"
591 vapier 1.52 else
592 vapier 1.280 # the args here will give slightly wierd names on BSD,
593     # but should produce a usable file on all userlands
594 flameeyes 1.223 if [[ ${exe} == "touch" ]] ; then
595 vapier 1.280 TMPDIR="${topdir}" mktemp -t tmp.XXXXXXXXXX
596 flameeyes 1.223 else
597 vapier 1.280 TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX
598 flameeyes 1.223 fi
599 vapier 1.52 fi
600     }
601    
602 vapier 1.283 # @FUNCTION: edos2unix
603     # @USAGE: <file> [more files ...]
604     # @DESCRIPTION:
605     # A handy replacement for dos2unix, recode, fixdos, etc... This allows you
606     # to remove all of these text utilities from DEPEND variables because this
607     # is a script based solution. Just give it a list of files to convert and
608     # they will all be changed from the DOS CRLF format to the UNIX LF format.
609 vapier 1.24 edos2unix() {
610 vapier 1.366 [[ $# -eq 0 ]] && return 0
611     sed -i 's/\r$//' -- "$@" || die
612 vapier 1.39 }
613    
614     # Make a desktop file !
615     # Great for making those icons in kde/gnome startmenu !
616 flameeyes 1.266 # Amaze your friends ! Get the women ! Join today !
617 vapier 1.39 #
618 vapier 1.341 # make_desktop_entry(<command>, [name], [icon], [type], [fields])
619 vapier 1.39 #
620 tupone 1.238 # binary: what command does the app run with ?
621 vapier 1.39 # name: the name that will show up in the menu
622     # icon: give your little like a pretty little icon ...
623 vapier 1.118 # this can be relative (to /usr/share/pixmaps) or
624     # a full path to an icon
625 flameeyes 1.266 # type: what kind of application is this ? for categories:
626 vapier 1.284 # http://standards.freedesktop.org/menu-spec/latest/apa.html
627 vapier 1.341 # fields: extra fields to append to the desktop file; a printf string
628 vapier 1.39 make_desktop_entry() {
629 vapier 1.341 [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
630 vapier 1.39
631 vapier 1.158 local exec=${1}
632     local name=${2:-${PN}}
633 wolf31o2 1.293 local icon=${3:-${PN}}
634 vapier 1.158 local type=${4}
635 vapier 1.341 local fields=${5}
636 vapier 1.158
637     if [[ -z ${type} ]] ; then
638     local catmaj=${CATEGORY%%-*}
639     local catmin=${CATEGORY##*-}
640     case ${catmaj} in
641     app)
642     case ${catmin} in
643 vapier 1.284 accessibility) type=Accessibility;;
644 vapier 1.338 admin) type=System;;
645     antivirus) type=System;;
646     arch) type=Archiving;;
647     backup) type=Archiving;;
648     cdr) type=DiscBurning;;
649     dicts) type=Dictionary;;
650     doc) type=Documentation;;
651     editors) type=TextEditor;;
652     emacs) type=TextEditor;;
653     emulation) type=Emulator;;
654     laptop) type=HardwareSettings;;
655     office) type=Office;;
656     pda) type=PDA;;
657     vim) type=TextEditor;;
658     xemacs) type=TextEditor;;
659 vapier 1.158 esac
660 azarah 1.59 ;;
661 vapier 1.158
662     dev)
663 vapier 1.159 type="Development"
664 vapier 1.158 ;;
665    
666     games)
667     case ${catmin} in
668 wolf31o2 1.265 action|fps) type=ActionGame;;
669 vapier 1.338 arcade) type=ArcadeGame;;
670     board) type=BoardGame;;
671     emulation) type=Emulator;;
672     kids) type=KidsGame;;
673     puzzle) type=LogicGame;;
674     roguelike) type=RolePlaying;;
675     rpg) type=RolePlaying;;
676 vapier 1.158 simulation) type=Simulation;;
677 vapier 1.338 sports) type=SportsGame;;
678     strategy) type=StrategyGame;;
679 vapier 1.158 esac
680 vapier 1.159 type="Game;${type}"
681 vapier 1.158 ;;
682    
683 vapier 1.284 gnome)
684     type="Gnome;GTK"
685     ;;
686    
687     kde)
688     type="KDE;Qt"
689     ;;
690    
691 vapier 1.158 mail)
692 vapier 1.159 type="Network;Email"
693 vapier 1.158 ;;
694    
695     media)
696     case ${catmin} in
697 vapier 1.339 gfx)
698     type=Graphics
699     ;;
700     *)
701     case ${catmin} in
702     radio) type=Tuner;;
703     sound) type=Audio;;
704     tv) type=TV;;
705     video) type=Video;;
706     esac
707     type="AudioVideo;${type}"
708     ;;
709 vapier 1.158 esac
710 wolf31o2 1.65 ;;
711 vapier 1.158
712     net)
713     case ${catmin} in
714     dialup) type=Dialup;;
715 vapier 1.338 ftp) type=FileTransfer;;
716     im) type=InstantMessaging;;
717     irc) type=IRCClient;;
718     mail) type=Email;;
719     news) type=News;;
720     nntp) type=News;;
721     p2p) type=FileTransfer;;
722     voip) type=Telephony;;
723 vapier 1.158 esac
724 vapier 1.159 type="Network;${type}"
725 vapier 1.158 ;;
726    
727     sci)
728     case ${catmin} in
729 vapier 1.284 astro*) type=Astronomy;;
730 vapier 1.338 bio*) type=Biology;;
731     calc*) type=Calculator;;
732     chem*) type=Chemistry;;
733 vapier 1.284 elec*) type=Electronics;;
734 vapier 1.338 geo*) type=Geology;;
735     math*) type=Math;;
736 vapier 1.284 physics) type=Physics;;
737     visual*) type=DataVisualization;;
738 vapier 1.159 esac
739 abcd 1.336 type="Education;Science;${type}"
740 vapier 1.158 ;;
741    
742 vapier 1.284 sys)
743     type="System"
744     ;;
745    
746 vapier 1.158 www)
747     case ${catmin} in
748     client) type=WebBrowser;;
749     esac
750 abcd 1.336 type="Network;${type}"
751 azarah 1.59 ;;
752 vapier 1.158
753 azarah 1.59 *)
754     type=
755     ;;
756 vapier 1.39 esac
757     fi
758 carlo 1.177 if [ "${SLOT}" == "0" ] ; then
759     local desktop_name="${PN}"
760     else
761     local desktop_name="${PN}-${SLOT}"
762     fi
763 vapier 1.272 local desktop="${T}/$(echo ${exec} | sed 's:[[:space:]/:]:_:g')-${desktop_name}.desktop"
764 vapier 1.271 #local desktop=${T}/${exec%% *:-${desktop_name}}.desktop
765 vapier 1.39
766 abcd 1.336 # Don't append another ";" when a valid category value is provided.
767     type=${type%;}${type:+;}
768    
769     eshopts_push -s extglob
770     if [[ -n ${icon} && ${icon} != /* ]] && [[ ${icon} == *.xpm || ${icon} == *.png || ${icon} == *.svg ]]; then
771     ewarn "As described in the Icon Theme Specification, icon file extensions are not"
772     ewarn "allowed in .desktop files if the value is not an absolute path."
773     icon=${icon%.@(xpm|png|svg)}
774     fi
775     eshopts_pop
776    
777 vapier 1.271 cat <<-EOF > "${desktop}"
778     [Desktop Entry]
779     Name=${name}
780     Type=Application
781     Comment=${DESCRIPTION}
782     Exec=${exec}
783     TryExec=${exec%% *}
784     Icon=${icon}
785 abcd 1.336 Categories=${type}
786 vapier 1.271 EOF
787 vapier 1.39
788 vapier 1.341 if [[ ${fields:-=} != *=* ]] ; then
789     # 5th arg used to be value to Path=
790     ewarn "make_desktop_entry: update your 5th arg to read Path=${fields}"
791     fields="Path=${fields}"
792     fi
793 vapier 1.342 [[ -n ${fields} ]] && printf '%b\n' "${fields}" >> "${desktop}"
794 wolf31o2 1.293
795 vapier 1.204 (
796     # wrap the env here so that the 'insinto' call
797     # doesn't corrupt the env of the caller
798     insinto /usr/share/applications
799     doins "${desktop}"
800 vapier 1.340 ) || die "installing desktop file failed"
801 danarmak 1.32 }
802    
803 vapier 1.283 # @FUNCTION: validate_desktop_entries
804     # @USAGE: [directories]
805     # @MAINTAINER:
806     # Carsten Lohrke <carlo@gentoo.org>
807     # @DESCRIPTION:
808 carlo 1.278 # Validate desktop entries using desktop-file-utils
809 carlo 1.277 validate_desktop_entries() {
810     if [[ -x /usr/bin/desktop-file-validate ]] ; then
811     einfo "Checking desktop entry validity"
812     local directories=""
813 carlo 1.279 for d in /usr/share/applications $@ ; do
814     [[ -d ${D}${d} ]] && directories="${directories} ${D}${d}"
815 carlo 1.277 done
816 carlo 1.279 if [[ -n ${directories} ]] ; then
817     for FILE in $(find ${directories} -name "*\.desktop" \
818     -not -path '*.hidden*' | sort -u 2>/dev/null)
819     do
820     local temp=$(desktop-file-validate ${FILE} | grep -v "warning:" | \
821     sed -e "s|error: ||" -e "s|${FILE}:|--|g" )
822     [[ -n $temp ]] && elog ${temp/--/${FILE/${D}/}:}
823     done
824     fi
825 carlo 1.277 echo ""
826     else
827     einfo "Passing desktop entry validity check. Install dev-util/desktop-file-utils, if you want to help to improve Gentoo."
828     fi
829     }
830    
831 vapier 1.283 # @FUNCTION: make_session_desktop
832 vapier 1.314 # @USAGE: <title> <command> [command args...]
833 vapier 1.283 # @DESCRIPTION:
834     # Make a GDM/KDM Session file. The title is the file to execute to start the
835     # Window Manager. The command is the name of the Window Manager.
836 vapier 1.314 #
837     # You can set the name of the file via the ${wm} variable.
838 lanius 1.133 make_session_desktop() {
839 vapier 1.314 [[ -z $1 ]] && eerror "$0: You must specify the title" && return 1
840     [[ -z $2 ]] && eerror "$0: You must specify the command" && return 1
841 lanius 1.133
842 vapier 1.167 local title=$1
843     local command=$2
844 vapier 1.314 local desktop=${T}/${wm:-${PN}}.desktop
845     shift 2
846 lanius 1.133
847 vapier 1.271 cat <<-EOF > "${desktop}"
848     [Desktop Entry]
849     Name=${title}
850     Comment=This session logs you into ${title}
851 vapier 1.314 Exec=${command} $*
852 vapier 1.271 TryExec=${command}
853 vapier 1.314 Type=XSession
854 vapier 1.271 EOF
855 lanius 1.133
856 vapier 1.271 (
857     # wrap the env here so that the 'insinto' call
858     # doesn't corrupt the env of the caller
859 lanius 1.133 insinto /usr/share/xsessions
860     doins "${desktop}"
861 vapier 1.271 )
862 lanius 1.133 }
863    
864 vapier 1.283 # @FUNCTION: domenu
865     # @USAGE: <menus>
866     # @DESCRIPTION:
867     # Install the list of .desktop menu files into the appropriate directory
868     # (/usr/share/applications).
869 lanius 1.133 domenu() {
870 vapier 1.271 (
871     # wrap the env here so that the 'insinto' call
872     # doesn't corrupt the env of the caller
873     local i j ret=0
874 lanius 1.133 insinto /usr/share/applications
875 vapier 1.167 for i in "$@" ; do
876     if [[ -f ${i} ]] ; then
877     doins "${i}"
878 vapier 1.271 ((ret+=$?))
879 vapier 1.167 elif [[ -d ${i} ]] ; then
880     for j in "${i}"/*.desktop ; do
881     doins "${j}"
882 vapier 1.271 ((ret+=$?))
883 lanius 1.133 done
884 vapier 1.285 else
885     ((++ret))
886 swegener 1.190 fi
887 lanius 1.133 done
888 vapier 1.271 exit ${ret}
889     )
890 lanius 1.133 }
891 vapier 1.283
892     # @FUNCTION: newmenu
893     # @USAGE: <menu> <newname>
894     # @DESCRIPTION:
895     # Like all other new* functions, install the specified menu as newname.
896 vapier 1.167 newmenu() {
897 vapier 1.271 (
898     # wrap the env here so that the 'insinto' call
899     # doesn't corrupt the env of the caller
900 vapier 1.167 insinto /usr/share/applications
901 vapier 1.271 newins "$@"
902     )
903 vapier 1.167 }
904 lanius 1.133
905 vapier 1.283 # @FUNCTION: doicon
906     # @USAGE: <list of icons>
907     # @DESCRIPTION:
908     # Install the list of icons into the icon directory (/usr/share/pixmaps).
909     # This is useful in conjunction with creating desktop/menu files.
910 lanius 1.133 doicon() {
911 vapier 1.271 (
912     # wrap the env here so that the 'insinto' call
913     # doesn't corrupt the env of the caller
914     local i j ret
915 lanius 1.133 insinto /usr/share/pixmaps
916 vapier 1.167 for i in "$@" ; do
917     if [[ -f ${i} ]] ; then
918     doins "${i}"
919 vapier 1.271 ((ret+=$?))
920 vapier 1.167 elif [[ -d ${i} ]] ; then
921     for j in "${i}"/*.png ; do
922     doins "${j}"
923 vapier 1.271 ((ret+=$?))
924 lanius 1.133 done
925 vapier 1.285 else
926     ((++ret))
927 swegener 1.190 fi
928 lanius 1.133 done
929 vapier 1.271 exit ${ret}
930     )
931 lanius 1.133 }
932 vapier 1.283
933     # @FUNCTION: newicon
934     # @USAGE: <icon> <newname>
935     # @DESCRIPTION:
936     # Like all other new* functions, install the specified icon as newname.
937 vapier 1.167 newicon() {
938 vapier 1.271 (
939     # wrap the env here so that the 'insinto' call
940     # doesn't corrupt the env of the caller
941 vapier 1.167 insinto /usr/share/pixmaps
942 vapier 1.271 newins "$@"
943     )
944 vapier 1.167 }
945 lanius 1.133
946 vapier 1.70 # for internal use only (unpack_pdv and unpack_makeself)
947     find_unpackable_file() {
948 vapier 1.196 local src=$1
949     if [[ -z ${src} ]] ; then
950     src=${DISTDIR}/${A}
951 vapier 1.50 else
952 vapier 1.196 if [[ -e ${DISTDIR}/${src} ]] ; then
953     src=${DISTDIR}/${src}
954     elif [[ -e ${PWD}/${src} ]] ; then
955     src=${PWD}/${src}
956     elif [[ -e ${src} ]] ; then
957     src=${src}
958 vapier 1.50 fi
959     fi
960 vapier 1.196 [[ ! -e ${src} ]] && return 1
961 vapier 1.70 echo "${src}"
962     }
963    
964 vapier 1.283 # @FUNCTION: unpack_pdv
965     # @USAGE: <file to unpack> <size of off_t>
966     # @DESCRIPTION:
967 vapier 1.70 # Unpack those pesky pdv generated files ...
968     # They're self-unpacking programs with the binary package stuffed in
969     # the middle of the archive. Valve seems to use it a lot ... too bad
970     # it seems to like to segfault a lot :(. So lets take it apart ourselves.
971 swegener 1.286 #
972 vapier 1.283 # You have to specify the off_t size ... I have no idea how to extract that
973     # information out of the binary executable myself. Basically you pass in
974     # the size of the off_t type (in bytes) on the machine that built the pdv
975     # archive.
976 vapier 1.70 #
977 vapier 1.283 # One way to determine this is by running the following commands:
978 ulm 1.288 #
979     # @CODE
980     # strings <pdv archive> | grep lseek
981     # strace -elseek <pdv archive>
982     # @CODE
983     #
984 vapier 1.283 # Basically look for the first lseek command (we do the strings/grep because
985     # sometimes the function call is _llseek or something) and steal the 2nd
986     # parameter. Here is an example:
987 ulm 1.288 #
988     # @CODE
989     # vapier@vapier 0 pdv_unpack # strings hldsupdatetool.bin | grep lseek
990     # lseek
991     # vapier@vapier 0 pdv_unpack # strace -elseek ./hldsupdatetool.bin
992     # lseek(3, -4, SEEK_END) = 2981250
993     # @CODE
994     #
995 vapier 1.283 # Thus we would pass in the value of '4' as the second parameter.
996 vapier 1.70 unpack_pdv() {
997 vapier 1.271 local src=$(find_unpackable_file "$1")
998 vapier 1.196 local sizeoff_t=$2
999 vapier 1.70
1000 vapier 1.196 [[ -z ${src} ]] && die "Could not locate source for '$1'"
1001     [[ -z ${sizeoff_t} ]] && die "No idea what off_t size was used for this pdv :("
1002 vapier 1.70
1003 vapier 1.212 local shrtsrc=$(basename "${src}")
1004 vapier 1.70 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1005 vapier 1.271 local metaskip=$(tail -c ${sizeoff_t} "${src}" | hexdump -e \"%i\")
1006     local tailskip=$(tail -c $((${sizeoff_t}*2)) "${src}" | head -c ${sizeoff_t} | hexdump -e \"%i\")
1007 vapier 1.70
1008     # grab metadata for debug reasons
1009 vapier 1.271 local metafile=$(emktemp)
1010     tail -c +$((${metaskip}+1)) "${src}" > "${metafile}"
1011 vapier 1.70
1012     # rip out the final file name from the metadata
1013 vapier 1.271 local datafile=$(tail -c +$((${metaskip}+1)) "${src}" | strings | head -n 1)
1014     datafile=$(basename "${datafile}")
1015 vapier 1.70
1016 vapier 1.71 # now lets uncompress/untar the file if need be
1017 vapier 1.271 local tmpfile=$(emktemp)
1018 vapier 1.70 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null | head -c 512 > ${tmpfile}
1019 vapier 1.71
1020 vapier 1.271 local iscompressed=$(file -b "${tmpfile}")
1021     if [[ ${iscompressed:0:8} == "compress" ]] ; then
1022 vapier 1.71 iscompressed=1
1023     mv ${tmpfile}{,.Z}
1024     gunzip ${tmpfile}
1025     else
1026     iscompressed=0
1027     fi
1028 vapier 1.271 local istar=$(file -b "${tmpfile}")
1029     if [[ ${istar:0:9} == "POSIX tar" ]] ; then
1030 vapier 1.71 istar=1
1031     else
1032     istar=0
1033     fi
1034    
1035     #for some reason gzip dies with this ... dd cant provide buffer fast enough ?
1036     #dd if=${src} ibs=${metaskip} count=1 \
1037     # | dd ibs=${tailskip} skip=1 \
1038     # | gzip -dc \
1039     # > ${datafile}
1040     if [ ${iscompressed} -eq 1 ] ; then
1041     if [ ${istar} -eq 1 ] ; then
1042     tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1043     | head -c $((${metaskip}-${tailskip})) \
1044     | tar -xzf -
1045     else
1046 vapier 1.70 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1047     | head -c $((${metaskip}-${tailskip})) \
1048     | gzip -dc \
1049     > ${datafile}
1050 vapier 1.71 fi
1051     else
1052     if [ ${istar} -eq 1 ] ; then
1053     tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1054     | head -c $((${metaskip}-${tailskip})) \
1055 vapier 1.73 | tar --no-same-owner -xf -
1056 vapier 1.71 else
1057 vapier 1.70 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1058     | head -c $((${metaskip}-${tailskip})) \
1059     > ${datafile}
1060 vapier 1.71 fi
1061     fi
1062     true
1063     #[ -s "${datafile}" ] || die "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1064 vapier 1.70 #assert "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1065     }
1066    
1067 vapier 1.283 # @FUNCTION: unpack_makeself
1068     # @USAGE: [file to unpack] [offset] [tail|dd]
1069     # @DESCRIPTION:
1070 vapier 1.70 # Unpack those pesky makeself generated files ...
1071     # They're shell scripts with the binary package tagged onto
1072     # the end of the archive. Loki utilized the format as does
1073     # many other game companies.
1074 swegener 1.286 #
1075 vapier 1.283 # If the file is not specified, then ${A} is used. If the
1076     # offset is not specified then we will attempt to extract
1077     # the proper offset from the script itself.
1078 vapier 1.70 unpack_makeself() {
1079 vapier 1.217 local src_input=${1:-${A}}
1080     local src=$(find_unpackable_file "${src_input}")
1081 vapier 1.196 local skip=$2
1082     local exe=$3
1083    
1084 vapier 1.217 [[ -z ${src} ]] && die "Could not locate source for '${src_input}'"
1085 vapier 1.50
1086 vapier 1.196 local shrtsrc=$(basename "${src}")
1087 vapier 1.41 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1088 vapier 1.212 if [[ -z ${skip} ]] ; then
1089 mr_bones_ 1.343 local ver=$(grep -m1 -a '#.*Makeself' "${src}" | awk '{print $NF}')
1090 vapier 1.41 local skip=0
1091 vapier 1.112 exe=tail
1092 vapier 1.41 case ${ver} in
1093 wolf31o2 1.240 1.5.*|1.6.0-nv) # tested 1.5.{3,4,5} ... guessing 1.5.x series is same
1094 vapier 1.112 skip=$(grep -a ^skip= "${src}" | cut -d= -f2)
1095 vapier 1.41 ;;
1096     2.0|2.0.1)
1097 vapier 1.112 skip=$(grep -a ^$'\t'tail "${src}" | awk '{print $2}' | cut -b2-)
1098 vapier 1.41 ;;
1099 wolf31o2 1.48 2.1.1)
1100 vapier 1.112 skip=$(grep -a ^offset= "${src}" | awk '{print $2}' | cut -b2-)
1101 vapier 1.344 (( skip++ ))
1102 wolf31o2 1.48 ;;
1103 vapier 1.49 2.1.2)
1104 vapier 1.112 skip=$(grep -a ^offset= "${src}" | awk '{print $3}' | head -n 1)
1105 vapier 1.344 (( skip++ ))
1106 vapier 1.49 ;;
1107 wolf31o2 1.48 2.1.3)
1108 vapier 1.112 skip=`grep -a ^offset= "${src}" | awk '{print $3}'`
1109 vapier 1.344 (( skip++ ))
1110 vapier 1.41 ;;
1111 wolf31o2 1.211 2.1.4|2.1.5)
1112 vapier 1.112 skip=$(grep -a offset=.*head.*wc "${src}" | awk '{print $3}' | head -n 1)
1113     skip=$(head -n ${skip} "${src}" | wc -c)
1114     exe="dd"
1115     ;;
1116 vapier 1.41 *)
1117     eerror "I'm sorry, but I was unable to support the Makeself file."
1118     eerror "The version I detected was '${ver}'."
1119     eerror "Please file a bug about the file ${shrtsrc} at"
1120     eerror "http://bugs.gentoo.org/ so that support can be added."
1121     die "makeself version '${ver}' not supported"
1122     ;;
1123     esac
1124     debug-print "Detected Makeself version ${ver} ... using ${skip} as offset"
1125     fi
1126 vapier 1.112 case ${exe} in
1127     tail) exe="tail -n +${skip} '${src}'";;
1128 vapier 1.344 dd) exe="dd ibs=${skip} skip=1 if='${src}'";;
1129 vapier 1.112 *) die "makeself cant handle exe '${exe}'"
1130     esac
1131 vapier 1.41
1132 vapier 1.68 # lets grab the first few bytes of the file to figure out what kind of archive it is
1133 vapier 1.356 local filetype tmpfile=$(emktemp)
1134 vapier 1.112 eval ${exe} 2>/dev/null | head -c 512 > "${tmpfile}"
1135 vapier 1.356 filetype=$(file -b "${tmpfile}") || die
1136 vapier 1.68 case ${filetype} in
1137 vapier 1.257 *tar\ archive*)
1138 vapier 1.112 eval ${exe} | tar --no-same-owner -xf -
1139 vapier 1.68 ;;
1140     bzip2*)
1141 vapier 1.112 eval ${exe} | bzip2 -dc | tar --no-same-owner -xf -
1142 mr_bones_ 1.69 ;;
1143 vapier 1.68 gzip*)
1144 vapier 1.112 eval ${exe} | tar --no-same-owner -xzf -
1145 vapier 1.68 ;;
1146 vapier 1.93 compress*)
1147 vapier 1.112 eval ${exe} | gunzip | tar --no-same-owner -xf -
1148 vapier 1.93 ;;
1149 vapier 1.68 *)
1150 vapier 1.93 eerror "Unknown filetype \"${filetype}\" ?"
1151 vapier 1.68 false
1152     ;;
1153     esac
1154     assert "failure unpacking (${filetype}) makeself ${shrtsrc} ('${ver}' +${skip})"
1155 wolf31o2 1.56 }
1156    
1157 vapier 1.283 # @FUNCTION: cdrom_get_cds
1158     # @USAGE: <file on cd1> [file on cd2] [file on cd3] [...]
1159     # @DESCRIPTION:
1160 vapier 1.75 # Aquire cd(s) for those lovely cd-based emerges. Yes, this violates
1161     # the whole 'non-interactive' policy, but damnit I want CD support !
1162 swegener 1.286 #
1163 vapier 1.283 # With these cdrom functions we handle all the user interaction and
1164     # standardize everything. All you have to do is call cdrom_get_cds()
1165 vapier 1.75 # and when the function returns, you can assume that the cd has been
1166     # found at CDROM_ROOT.
1167 swegener 1.286 #
1168 vapier 1.283 # The function will attempt to locate a cd based upon a file that is on
1169     # the cd. The more files you give this function, the more cds
1170     # the cdrom functions will handle.
1171 swegener 1.286 #
1172 vapier 1.283 # Normally the cdrom functions will refer to the cds as 'cd #1', 'cd #2',
1173     # etc... If you want to give the cds better names, then just export
1174 vapier 1.243 # the appropriate CDROM_NAME variable before calling cdrom_get_cds().
1175 vapier 1.283 # Use CDROM_NAME for one cd, or CDROM_NAME_# for multiple cds. You can
1176     # also use the CDROM_NAME_SET bash array.
1177 swegener 1.286 #
1178 vapier 1.283 # For those multi cd ebuilds, see the cdrom_load_next_cd() function.
1179 vapier 1.75 cdrom_get_cds() {
1180     # first we figure out how many cds we're dealing with by
1181     # the # of files they gave us
1182     local cdcnt=0
1183     local f=
1184     for f in "$@" ; do
1185 vapier 1.214 ((++cdcnt))
1186 vapier 1.75 export CDROM_CHECK_${cdcnt}="$f"
1187     done
1188     export CDROM_TOTAL_CDS=${cdcnt}
1189     export CDROM_CURRENT_CD=1
1190    
1191     # now we see if the user gave use CD_ROOT ...
1192     # if they did, let's just believe them that it's correct
1193 vapier 1.215 if [[ -n ${CD_ROOT}${CD_ROOT_1} ]] ; then
1194 vapier 1.75 local var=
1195     cdcnt=0
1196 vapier 1.131 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1197 vapier 1.214 ((++cdcnt))
1198 vapier 1.75 var="CD_ROOT_${cdcnt}"
1199 vapier 1.215 [[ -z ${!var} ]] && var="CD_ROOT"
1200 vapier 1.131 if [[ -z ${!var} ]] ; then
1201 vapier 1.75 eerror "You must either use just the CD_ROOT"
1202     eerror "or specify ALL the CD_ROOT_X variables."
1203     eerror "In this case, you will need ${CDROM_TOTAL_CDS} CD_ROOT_X variables."
1204     die "could not locate CD_ROOT_${cdcnt}"
1205     fi
1206     done
1207 vapier 1.215 export CDROM_ROOT=${CD_ROOT_1:-${CD_ROOT}}
1208 vapier 1.75 einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1209 vapier 1.215 export CDROM_SET=-1
1210     for f in ${CDROM_CHECK_1//:/ } ; do
1211     ((++CDROM_SET))
1212 cardoe 1.346 [[ -e ${CDROM_ROOT}/${f} ]] && break
1213 vapier 1.215 done
1214     export CDROM_MATCH=${f}
1215 vapier 1.75 return
1216     fi
1217    
1218 vapier 1.215 # User didn't help us out so lets make sure they know they can
1219     # simplify the whole process ...
1220 vapier 1.131 if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1221 vapier 1.215 einfo "This ebuild will need the ${CDROM_NAME:-cdrom for ${PN}}"
1222 vapier 1.75 echo
1223     einfo "If you do not have the CD, but have the data files"
1224     einfo "mounted somewhere on your filesystem, just export"
1225     einfo "the variable CD_ROOT so that it points to the"
1226     einfo "directory containing the files."
1227     echo
1228 vapier 1.132 einfo "For example:"
1229     einfo "export CD_ROOT=/mnt/cdrom"
1230     echo
1231 vapier 1.75 else
1232 vapier 1.243 if [[ -n ${CDROM_NAME_SET} ]] ; then
1233     # Translate the CDROM_NAME_SET array into CDROM_NAME_#
1234     cdcnt=0
1235     while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1236     ((++cdcnt))
1237     export CDROM_NAME_${cdcnt}="${CDROM_NAME_SET[$((${cdcnt}-1))]}"
1238     done
1239     fi
1240    
1241 vapier 1.75 einfo "This package will need access to ${CDROM_TOTAL_CDS} cds."
1242     cdcnt=0
1243 vapier 1.131 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1244 vapier 1.214 ((++cdcnt))
1245 vapier 1.75 var="CDROM_NAME_${cdcnt}"
1246 vapier 1.131 [[ ! -z ${!var} ]] && einfo " CD ${cdcnt}: ${!var}"
1247 vapier 1.75 done
1248     echo
1249     einfo "If you do not have the CDs, but have the data files"
1250     einfo "mounted somewhere on your filesystem, just export"
1251     einfo "the following variables so they point to the right place:"
1252 nyhm 1.347 einfon ""
1253 vapier 1.75 cdcnt=0
1254 vapier 1.131 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1255 vapier 1.214 ((++cdcnt))
1256 vapier 1.75 echo -n " CD_ROOT_${cdcnt}"
1257     done
1258     echo
1259     einfo "Or, if you have all the files in the same place, or"
1260     einfo "you only have one cdrom, you can export CD_ROOT"
1261     einfo "and that place will be used as the same data source"
1262     einfo "for all the CDs."
1263     echo
1264 vapier 1.132 einfo "For example:"
1265     einfo "export CD_ROOT_1=/mnt/cdrom"
1266     echo
1267 vapier 1.75 fi
1268 vapier 1.215
1269 vapier 1.214 export CDROM_SET=""
1270 vapier 1.75 export CDROM_CURRENT_CD=0
1271     cdrom_load_next_cd
1272     }
1273    
1274 vapier 1.283 # @FUNCTION: cdrom_load_next_cd
1275     # @DESCRIPTION:
1276     # Some packages are so big they come on multiple CDs. When you're done reading
1277     # files off a CD and want access to the next one, just call this function.
1278     # Again, all the messy details of user interaction are taken care of for you.
1279     # Once this returns, just read the variable CDROM_ROOT for the location of the
1280     # mounted CD. Note that you can only go forward in the CD list, so make sure
1281     # you only call this function when you're done using the current CD.
1282 vapier 1.75 cdrom_load_next_cd() {
1283 vapier 1.215 local var
1284     ((++CDROM_CURRENT_CD))
1285 vapier 1.79
1286 vapier 1.75 unset CDROM_ROOT
1287 vapier 1.215 var=CD_ROOT_${CDROM_CURRENT_CD}
1288     [[ -z ${!var} ]] && var="CD_ROOT"
1289 vapier 1.131 if [[ -z ${!var} ]] ; then
1290 vapier 1.75 var="CDROM_CHECK_${CDROM_CURRENT_CD}"
1291 vapier 1.215 _cdrom_locate_file_on_cd ${!var}
1292 vapier 1.75 else
1293 vapier 1.131 export CDROM_ROOT=${!var}
1294 vapier 1.75 fi
1295    
1296     einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1297     }
1298    
1299     # this is used internally by the cdrom_get_cds() and cdrom_load_next_cd()
1300     # functions. this should *never* be called from an ebuild.
1301     # all it does is try to locate a give file on a cd ... if the cd isn't
1302     # found, then a message asking for the user to insert the cdrom will be
1303     # displayed and we'll hang out here until:
1304     # (1) the file is found on a mounted cdrom
1305     # (2) the user hits CTRL+C
1306 vapier 1.215 _cdrom_locate_file_on_cd() {
1307 vapier 1.214 local mline=""
1308 wolf31o2 1.296 local showedmsg=0 showjolietmsg=0
1309 vapier 1.214
1310 vapier 1.131 while [[ -z ${CDROM_ROOT} ]] ; do
1311 vapier 1.214 local i=0
1312     local -a cdset=(${*//:/ })
1313     if [[ -n ${CDROM_SET} ]] ; then
1314     cdset=(${cdset[${CDROM_SET}]})
1315     fi
1316    
1317     while [[ -n ${cdset[${i}]} ]] ; do
1318     local dir=$(dirname ${cdset[${i}]})
1319     local file=$(basename ${cdset[${i}]})
1320    
1321 uberlord 1.259 local point= node= fs= foo=
1322     while read point node fs foo ; do
1323 nyhm 1.281 [[ " cd9660 iso9660 udf " != *" ${fs} "* ]] && \
1324 uberlord 1.264 ! [[ ${fs} == "subfs" && ",${opts}," == *",fs=cdfss,"* ]] \
1325     && continue
1326 uberlord 1.259 point=${point//\040/ }
1327 vapier 1.292 [[ ! -d ${point}/${dir} ]] && continue
1328 uberlord 1.259 [[ -z $(find "${point}/${dir}" -maxdepth 1 -iname "${file}") ]] && continue
1329     export CDROM_ROOT=${point}
1330     export CDROM_SET=${i}
1331     export CDROM_MATCH=${cdset[${i}]}
1332     return
1333 kanaka 1.262 done <<< "$(get_mounts)"
1334 vapier 1.214
1335     ((++i))
1336 vapier 1.75 done
1337    
1338 vapier 1.214 echo
1339     if [[ ${showedmsg} -eq 0 ]] ; then
1340     if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1341     if [[ -z ${CDROM_NAME} ]] ; then
1342     einfo "Please insert+mount the cdrom for ${PN} now !"
1343     else
1344     einfo "Please insert+mount the ${CDROM_NAME} cdrom now !"
1345     fi
1346     else
1347     if [[ -z ${CDROM_NAME_1} ]] ; then
1348     einfo "Please insert+mount cd #${CDROM_CURRENT_CD} for ${PN} now !"
1349 vapier 1.75 else
1350 vapier 1.214 local var="CDROM_NAME_${CDROM_CURRENT_CD}"
1351     einfo "Please insert+mount the ${!var} cdrom now !"
1352 vapier 1.75 fi
1353     fi
1354 vapier 1.214 showedmsg=1
1355 vapier 1.75 fi
1356 vapier 1.214 einfo "Press return to scan for the cd again"
1357     einfo "or hit CTRL+C to abort the emerge."
1358     echo
1359 wolf31o2 1.296 if [[ ${showjolietmsg} -eq 0 ]] ; then
1360     showjolietmsg=1
1361     else
1362     ewarn "If you are having trouble with the detection"
1363     ewarn "of your CD, it is possible that you do not have"
1364     ewarn "Joliet support enabled in your kernel. Please"
1365     ewarn "check that CONFIG_JOLIET is enabled in your kernel."
1366     ebeep 5
1367     fi
1368 vapier 1.222 read || die "something is screwed with your system"
1369 vapier 1.75 done
1370     }
1371 vapier 1.92
1372 vapier 1.287 # @FUNCTION: strip-linguas
1373     # @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>]
1374     # @DESCRIPTION:
1375 mr_bones_ 1.100 # Make sure that LINGUAS only contains languages that
1376 vapier 1.287 # a package can support. The first form allows you to
1377     # specify a list of LINGUAS. The -i builds a list of po
1378     # files found in all the directories and uses the
1379     # intersection of the lists. The -u builds a list of po
1380     # files found in all the directories and uses the union
1381     # of the lists.
1382 vapier 1.92 strip-linguas() {
1383 vapier 1.242 local ls newls nols
1384 vapier 1.154 if [[ $1 == "-i" ]] || [[ $1 == "-u" ]] ; then
1385     local op=$1; shift
1386 vapier 1.315 ls=$(find "$1" -name '*.po' -exec basename {} .po ';'); shift
1387 vapier 1.92 local d f
1388     for d in "$@" ; do
1389 vapier 1.154 if [[ ${op} == "-u" ]] ; then
1390     newls=${ls}
1391 vapier 1.92 else
1392     newls=""
1393     fi
1394 vapier 1.315 for f in $(find "$d" -name '*.po' -exec basename {} .po ';') ; do
1395 vapier 1.154 if [[ ${op} == "-i" ]] ; then
1396 ssuominen 1.358 has ${f} ${ls} && newls="${newls} ${f}"
1397 vapier 1.92 else
1398 ssuominen 1.358 has ${f} ${ls} || newls="${newls} ${f}"
1399 vapier 1.92 fi
1400     done
1401 vapier 1.154 ls=${newls}
1402 vapier 1.92 done
1403     else
1404 vapier 1.236 ls="$@"
1405 vapier 1.92 fi
1406    
1407 vapier 1.242 nols=""
1408 vapier 1.92 newls=""
1409     for f in ${LINGUAS} ; do
1410 ssuominen 1.358 if has ${f} ${ls} ; then
1411 vapier 1.120 newls="${newls} ${f}"
1412 vapier 1.92 else
1413 vapier 1.242 nols="${nols} ${f}"
1414 vapier 1.92 fi
1415     done
1416 vapier 1.244 [[ -n ${nols} ]] \
1417 vapier 1.316 && ewarn "Sorry, but ${PN} does not support the LINGUAS:" ${nols}
1418 vapier 1.237 export LINGUAS=${newls:1}
1419 vapier 1.92 }
1420 iggy 1.110
1421 vapier 1.283 # @FUNCTION: preserve_old_lib
1422     # @USAGE: <libs to preserve> [more libs]
1423     # @DESCRIPTION:
1424     # These functions are useful when a lib in your package changes ABI SONAME.
1425     # An example might be from libogg.so.0 to libogg.so.1. Removing libogg.so.0
1426 eradicator 1.111 # would break packages that link against it. Most people get around this
1427     # by using the portage SLOT mechanism, but that is not always a relevant
1428 vapier 1.283 # solution, so instead you can call this from pkg_preinst. See also the
1429     # preserve_old_lib_notify function.
1430 eradicator 1.111 preserve_old_lib() {
1431 vapier 1.268 if [[ ${EBUILD_PHASE} != "preinst" ]] ; then
1432 vapier 1.267 eerror "preserve_old_lib() must be called from pkg_preinst() only"
1433 vapier 1.276 die "Invalid preserve_old_lib() usage"
1434 vapier 1.267 fi
1435     [[ -z $1 ]] && die "Usage: preserve_old_lib <library to preserve> [more libraries to preserve]"
1436    
1437 vapier 1.297 # let portage worry about it
1438     has preserve-libs ${FEATURES} && return 0
1439    
1440 vapier 1.267 local lib dir
1441     for lib in "$@" ; do
1442     [[ -e ${ROOT}/${lib} ]] || continue
1443     dir=${lib%/*}
1444     dodir ${dir} || die "dodir ${dir} failed"
1445     cp "${ROOT}"/${lib} "${D}"/${lib} || die "cp ${lib} failed"
1446     touch "${D}"/${lib}
1447     done
1448 eradicator 1.111 }
1449    
1450 vapier 1.283 # @FUNCTION: preserve_old_lib_notify
1451     # @USAGE: <libs to notify> [more libs]
1452     # @DESCRIPTION:
1453     # Spit helpful messages about the libraries preserved by preserve_old_lib.
1454 eradicator 1.111 preserve_old_lib_notify() {
1455 vapier 1.268 if [[ ${EBUILD_PHASE} != "postinst" ]] ; then
1456 vapier 1.267 eerror "preserve_old_lib_notify() must be called from pkg_postinst() only"
1457 vapier 1.276 die "Invalid preserve_old_lib_notify() usage"
1458 vapier 1.267 fi
1459    
1460 vapier 1.297 # let portage worry about it
1461     has preserve-libs ${FEATURES} && return 0
1462    
1463 vapier 1.267 local lib notice=0
1464     for lib in "$@" ; do
1465     [[ -e ${ROOT}/${lib} ]] || continue
1466     if [[ ${notice} -eq 0 ]] ; then
1467     notice=1
1468     ewarn "Old versions of installed libraries were detected on your system."
1469     ewarn "In order to avoid breaking packages that depend on these old libs,"
1470     ewarn "the libraries are not being removed. You need to run revdep-rebuild"
1471     ewarn "in order to remove these old dependencies. If you do not have this"
1472     ewarn "helper program, simply emerge the 'gentoolkit' package."
1473     ewarn
1474     fi
1475 vapier 1.355 # temp hack for #348634 #357225
1476     [[ ${PN} == "mpfr" ]] && lib=${lib##*/}
1477 vapier 1.352 ewarn " # revdep-rebuild --library '${lib}'"
1478 vapier 1.267 done
1479 vapier 1.291 if [[ ${notice} -eq 1 ]] ; then
1480     ewarn
1481     ewarn "Once you've finished running revdep-rebuild, it should be safe to"
1482 vapier 1.300 ewarn "delete the old libraries. Here is a copy & paste for the lazy:"
1483     for lib in "$@" ; do
1484     ewarn " # rm '${lib}'"
1485     done
1486 vapier 1.291 fi
1487 eradicator 1.111 }
1488 vapier 1.125
1489 vapier 1.283 # @FUNCTION: built_with_use
1490     # @USAGE: [--hidden] [--missing <action>] [-a|-o] <DEPEND ATOM> <List of USE flags>
1491     # @DESCRIPTION:
1492 betelgeuse 1.329 #
1493     # Deprecated: Use EAPI 2 use deps in DEPEND|RDEPEND and with has_version calls.
1494     #
1495 vapier 1.283 # A temporary hack until portage properly supports DEPENDing on USE
1496     # flags being enabled in packages. This will check to see if the specified
1497     # DEPEND atom was built with the specified list of USE flags. The
1498     # --missing option controls the behavior if called on a package that does
1499     # not actually support the defined USE flags (aka listed in IUSE).
1500     # The default is to abort (call die). The -a and -o flags control
1501     # the requirements of the USE flags. They correspond to "and" and "or"
1502     # logic. So the -a flag means all listed USE flags must be enabled
1503 opfer 1.302 # while the -o flag means at least one of the listed IUSE flags must be
1504 vapier 1.283 # enabled. The --hidden option is really for internal use only as it
1505     # means the USE flag we're checking is hidden expanded, so it won't be found
1506     # in IUSE like normal USE flags.
1507 swegener 1.286 #
1508 vapier 1.283 # Remember that this function isn't terribly intelligent so order of optional
1509     # flags matter.
1510 vapier 1.125 built_with_use() {
1511 vapier 1.275 local hidden="no"
1512     if [[ $1 == "--hidden" ]] ; then
1513     hidden="yes"
1514     shift
1515     fi
1516    
1517 vapier 1.269 local missing_action="die"
1518     if [[ $1 == "--missing" ]] ; then
1519     missing_action=$2
1520     shift ; shift
1521     case ${missing_action} in
1522     true|false|die) ;;
1523     *) die "unknown action '${missing_action}'";;
1524     esac
1525     fi
1526    
1527 vapier 1.130 local opt=$1
1528     [[ ${opt:0:1} = "-" ]] && shift || opt="-a"
1529    
1530     local PKG=$(best_version $1)
1531 vapier 1.247 [[ -z ${PKG} ]] && die "Unable to resolve $1 to an installed package"
1532 vapier 1.130 shift
1533    
1534 vapier 1.213 local USEFILE=${ROOT}/var/db/pkg/${PKG}/USE
1535 vapier 1.249 local IUSEFILE=${ROOT}/var/db/pkg/${PKG}/IUSE
1536 vapier 1.213
1537 cardoe 1.273 # if the IUSE file doesn't exist, the read will error out, we need to handle
1538     # this gracefully
1539 vapier 1.275 if [[ ! -e ${USEFILE} ]] || [[ ! -e ${IUSEFILE} && ${hidden} == "no" ]] ; then
1540 cardoe 1.273 case ${missing_action} in
1541     true) return 0;;
1542     false) return 1;;
1543     die) die "Unable to determine what USE flags $PKG was built with";;
1544     esac
1545     fi
1546    
1547 vapier 1.275 if [[ ${hidden} == "no" ]] ; then
1548 zmedico 1.301 local IUSE_BUILT=( $(<"${IUSEFILE}") )
1549 vapier 1.275 # Don't check USE_EXPAND #147237
1550     local expand
1551     for expand in $(echo ${USE_EXPAND} | tr '[:upper:]' '[:lower:]') ; do
1552     if [[ $1 == ${expand}_* ]] ; then
1553     expand=""
1554     break
1555     fi
1556     done
1557     if [[ -n ${expand} ]] ; then
1558 zmedico 1.301 if ! has $1 ${IUSE_BUILT[@]#[-+]} ; then
1559 vapier 1.275 case ${missing_action} in
1560     true) return 0;;
1561     false) return 1;;
1562     die) die "$PKG does not actually support the $1 USE flag!";;
1563     esac
1564     fi
1565 vapier 1.269 fi
1566 vapier 1.250 fi
1567 vapier 1.249
1568 vapier 1.125 local USE_BUILT=$(<${USEFILE})
1569 vapier 1.130 while [[ $# -gt 0 ]] ; do
1570     if [[ ${opt} = "-o" ]] ; then
1571     has $1 ${USE_BUILT} && return 0
1572     else
1573     has $1 ${USE_BUILT} || return 1
1574     fi
1575 vapier 1.125 shift
1576     done
1577 vapier 1.130 [[ ${opt} = "-a" ]]
1578 vapier 1.125 }
1579 vapier 1.126
1580 vapier 1.289 # @FUNCTION: epunt_cxx
1581 vapier 1.283 # @USAGE: [dir to scan]
1582     # @DESCRIPTION:
1583     # Many configure scripts wrongly bail when a C++ compiler could not be
1584     # detected. If dir is not specified, then it defaults to ${S}.
1585     #
1586     # http://bugs.gentoo.org/73450
1587 vapier 1.126 epunt_cxx() {
1588 vapier 1.127 local dir=$1
1589     [[ -z ${dir} ]] && dir=${S}
1590     ebegin "Removing useless C++ checks"
1591     local f
1592 vapier 1.294 find "${dir}" -name configure | while read f ; do
1593     patch --no-backup-if-mismatch -p0 "${f}" "${PORTDIR}/eclass/ELT-patches/nocxx/nocxx.patch" > /dev/null
1594 vapier 1.127 done
1595     eend 0
1596 vapier 1.126 }
1597 ka0ttic 1.143
1598 vapier 1.283 # @FUNCTION: make_wrapper
1599 wolf31o2 1.295 # @USAGE: <wrapper> <target> [chdir] [libpaths] [installpath]
1600 vapier 1.283 # @DESCRIPTION:
1601     # Create a shell wrapper script named wrapper in installpath
1602     # (defaults to the bindir) to execute target (default of wrapper) by
1603     # first optionally setting LD_LIBRARY_PATH to the colon-delimited
1604     # libpaths followed by optionally changing directory to chdir.
1605 wolf31o2 1.160 make_wrapper() {
1606 wolf31o2 1.164 local wrapper=$1 bin=$2 chdir=$3 libdir=$4 path=$5
1607 wolf31o2 1.160 local tmpwrapper=$(emktemp)
1608 vapier 1.202 # We don't want to quote ${bin} so that people can pass complex
1609     # things as $bin ... "./someprog --args"
1610 wolf31o2 1.160 cat << EOF > "${tmpwrapper}"
1611     #!/bin/sh
1612 vapier 1.201 cd "${chdir:-.}"
1613 vapier 1.210 if [ -n "${libdir}" ] ; then
1614     if [ "\${LD_LIBRARY_PATH+set}" = "set" ] ; then
1615     export LD_LIBRARY_PATH="\${LD_LIBRARY_PATH}:${libdir}"
1616     else
1617     export LD_LIBRARY_PATH="${libdir}"
1618     fi
1619 vapier 1.201 fi
1620 vapier 1.202 exec ${bin} "\$@"
1621 wolf31o2 1.160 EOF
1622     chmod go+rx "${tmpwrapper}"
1623 vapier 1.201 if [[ -n ${path} ]] ; then
1624 vapier 1.283 (
1625 vapier 1.201 exeinto "${path}"
1626 wolf31o2 1.164 newexe "${tmpwrapper}" "${wrapper}"
1627 vapier 1.283 ) || die
1628 wolf31o2 1.164 else
1629 vapier 1.283 newbin "${tmpwrapper}" "${wrapper}" || die
1630 wolf31o2 1.164 fi
1631 wolf31o2 1.160 }
1632 mr_bones_ 1.311
1633 vapier 1.351 # @FUNCTION: path_exists
1634     # @USAGE: [-a|-o] <paths>
1635     # @DESCRIPTION:
1636     # Check if the specified paths exist. Works for all types of paths
1637     # (files/dirs/etc...). The -a and -o flags control the requirements
1638     # of the paths. They correspond to "and" and "or" logic. So the -a
1639     # flag means all the paths must exist while the -o flag means at least
1640     # one of the paths must exist. The default behavior is "and". If no
1641     # paths are specified, then the return value is "false".
1642     path_exists() {
1643     local opt=$1
1644     [[ ${opt} == -[ao] ]] && shift || opt="-a"
1645    
1646     # no paths -> return false
1647     # same behavior as: [[ -e "" ]]
1648     [[ $# -eq 0 ]] && return 1
1649    
1650     local p r=0
1651     for p in "$@" ; do
1652     [[ -e ${p} ]]
1653     : $(( r += $? ))
1654     done
1655    
1656     case ${opt} in
1657     -a) return $(( r != 0 )) ;;
1658     -o) return $(( r == $# )) ;;
1659     esac
1660     }
1661 mgorny 1.364
1662     # @FUNCTION: in_iuse
1663     # @USAGE: <flag>
1664     # @DESCRIPTION:
1665     # Determines whether the given flag is in IUSE. Strips IUSE default prefixes
1666     # as necessary.
1667     #
1668     # Note that this function should not be used in the global scope.
1669     in_iuse() {
1670     debug-print-function ${FUNCNAME} "${@}"
1671     [[ ${#} -eq 1 ]] || die "Invalid args to ${FUNCNAME}()"
1672    
1673     local flag=${1}
1674     local liuse=( ${IUSE} )
1675    
1676     has "${flag}" "${liuse[@]#[+-]}"
1677     }
1678 vapier 1.365
1679 vapier 1.367 # @FUNCTION: use_if_iuse
1680     # @USAGE: <flag>
1681     # @DESCRIPTION:
1682     # Return true if the given flag is in USE and IUSE.
1683     #
1684     # Note that this function should not be used in the global scope.
1685     use_if_iuse() {
1686     in_iuse $1 || return 1
1687     use $1
1688     }
1689    
1690 vapier 1.365 # @FUNCTION: usex
1691     # @USAGE: <USE flag> [true output] [false output] [true suffix] [false suffix]
1692     # @DESCRIPTION:
1693     # If USE flag is set, echo [true output][true suffix] (defaults to "yes"),
1694     # otherwise echo [false output][false suffix] (defaults to "no").
1695     usex() { use "$1" && echo "${2-yes}$4" || echo "${3-no}$5" ; } #382963
1696 vapier 1.371
1697 vapier 1.372 check_license() { die "you no longer need this as portage supports ACCEPT_LICENSE itself"; }
1698    
1699 vapier 1.371 fi

  ViewVC Help
Powered by ViewVC 1.1.20