Gentoo Archives: gentoo-dev

From: Mike Frysinger <vapier@g.o>
To: gentoo-dev@l.g.o
Subject: Re: [gentoo-dev] estack_{push,pop}: cool new helpers or over engineering?
Date: Wed, 14 Dec 2011 23:50:27
Message-Id: 201112141849.50101.vapier@gentoo.org
In Reply to: [gentoo-dev] estack_{push,pop}: cool new helpers or over engineering? by Mike Frysinger
1 some people pointed out typos/bugs, so here's v2
2 -mike
3
4 --- eutils.eclass 14 Dec 2011 17:36:18 -0000 1.372
5 +++ eutils.eclass 14 Dec 2011 23:46:37 -0000
6 @@ -100,6 +100,54 @@ esvn_clean() {
7 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf
8 }
9
10 +# @FUNCTION: estack_push
11 +# @USAGE: <stack> [items to push]
12 +# @DESCRIPTION:
13 +# Push any number of items onto the specified stack. Pick a name that
14 +# is a valid variable (i.e. stick to alphanumerics), and push as many
15 +# items as you like onto the stack at once.
16 +#
17 +# The following code snippet will echo 5, then 4, then 3, then ...
18 +# @CODE
19 +# estack_push mystack 1 2 3 4 5
20 +# while estack_pop mystack i ; do
21 +# echo ${i}
22 +# done
23 +# @CODE
24 +estack_push() {
25 + [[ $# -eq 0 ]] && die "estack_push: incorrect # of arguments"
26 + local stack_name="__ESTACK_$1__" ; shift
27 + eval ${stack_name}+=\( \"\$@\" \)
28 +}
29 +
30 +# @FUNCTION: estack_pop
31 +# @USAGE: <stack> [variable]
32 +# @DESCRIPTION:
33 +# Pop a single item off the specified stack. If a variable is specified,
34 +# the popped item is stored there. If no more items are available, return
35 +# 1, else return 0. See estack_push for more info.
36 +estack_pop() {
37 + ( [[ $# -eq 0 ]] || [[ $# -gt 2 ]] ) && die "estack_pop: incorrect # of arguments"
38 +
39 + # We use the fugly __estack_xxx var names to avoid collision with
40 + # passing back the return value. If we used "local i" and the
41 + # caller ran `estack_pop ... i`, we'd end up setting the local
42 + # copy of "i" rather than the caller's copy. The __estack_xxx
43 + # garbage is preferable to using $1/$2 everywhere as that is a
44 + # bit harder to read.
45 + local __estack_name="__ESTACK_$1__" ; shift
46 + local __estack_retvar=$1 ; shift
47 + eval local __estack_i=\${#${__estack_name}[@]}
48 + # Don't warn -- let the caller interpret this as a failure
49 + # or as normal behavior (akin to `shift`)
50 + [[ $(( --__estack_i )) -eq -1 ]] && return 1
51 +
52 + if [[ -n ${__estack_retvar} ]] ; then
53 + eval ${__estack_retvar}=\"\${${__estack_name}[${__estack_i}]}\"
54 + fi
55 + eval unset ${__estack_name}[${__estack_i}]
56 +}
57 +
58 # @FUNCTION: eshopts_push
59 # @USAGE: [options to `set` or `shopt`]
60 # @DESCRIPTION:
61 @@ -126,15 +174,14 @@ esvn_clean() {
62 eshopts_push() {
63 # have to assume __ESHOPTS_SAVE__ isn't screwed with
64 # as a `declare -a` here will reset its value
65 - local i=${#__ESHOPTS_SAVE__[@]}
66 if [[ $1 == -[su] ]] ; then
67 - __ESHOPTS_SAVE__[$i]=$(shopt -p)
68 + estack_push eshopts "$(shopt -p)"
69 [[ $# -eq 0 ]] && return 0
70 shopt "$@" || die "eshopts_push: bad options to shopt: $*"
71 else
72 - __ESHOPTS_SAVE__[$i]=$-
73 + estack_push eshopts $-
74 [[ $# -eq 0 ]] && return 0
75 set "$@" || die "eshopts_push: bad options to set: $*"
76 fi
77 }
78
79 @@ -144,19 +191,36 @@ eshopts_push() {
80 # Restore the shell options to the state saved with the corresponding
81 # eshopts_push call. See that function for more details.
82 eshopts_pop() {
83 - [[ $# -ne 0 ]] && die "eshopts_pop takes no arguments"
84 - local i=$(( ${#__ESHOPTS_SAVE__[@]} - 1 ))
85 - [[ ${i} -eq -1 ]] && die "eshopts_{push,pop}: unbalanced pair"
86 - local s=${__ESHOPTS_SAVE__[$i]}
87 - unset __ESHOPTS_SAVE__[$i]
88 + local s
89 + estack_pop eshopts s || die "${FUNCNAME}: unbalanced push"
90 if [[ ${s} == "shopt -"* ]] ; then
91 eval "${s}" || die "eshopts_pop: sanity: invalid shopt options: ${s}"
92 else
93 set +$- || die "eshopts_pop: sanity: invalid shell settings: $-"
94 set -${s} || die "eshopts_pop: sanity: unable to restore saved shell settings: ${s}"
95 fi
96 }
97
98 +# @FUNCTION: eumask_push
99 +# @USAGE: <new umask>
100 +# @DESCRIPTION:
101 +# Set the umask to the new value specified while saving the previous
102 +# value onto a stack. Useful for temporarily changing the umask.
103 +eumask_push() {
104 + estack_push eumask "$(umask)"
105 + umask "$@" || die "${FUNCNAME}: bad options to umask: $*"
106 +}
107 +
108 +# @FUNCTION: eumask_pop
109 +# @USAGE:
110 +# @DESCRIPTION:
111 +# Restore the previous umask state.
112 +eumask_pop() {
113 + local s
114 + estack_pop eumask s || die "${FUNCNAME}: unbalanced push"
115 + umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}"
116 +}
117 +
118 # @VARIABLE: EPATCH_SOURCE
119 # @DESCRIPTION:
120 # Default directory to search for patches.

Attachments

File name MIME type
signature.asc application/pgp-signature

Replies

Subject Author
[gentoo-dev] Re: estack_{push,pop}: cool new helpers or over engineering? Steven J Long <slong@××××××××××××××××××.uk>