Gentoo Archives: gentoo-dev

From: Mike Frysinger <vapier@g.o>
To: gentoo-dev@l.g.o
Subject: [gentoo-dev] estack_{push,pop}: cool new helpers or over engineering?
Date: Wed, 14 Dec 2011 22:26:20
Message-Id: 201112141725.22148.vapier@gentoo.org
1 i needed to temporarily modify the umask in some vcs eclasses. rather than
2 open coding the umask saving/restoring, i decided to re-use the
3 eshopts_{push,pop} logic so the umask can be pushed/popped easily.
4
5 the resulting code was mostly copy & paste the same, and the stack maintenance
6 ends up drowning out the meat of the stuff i care about -- screwing with the
7 umask. so to that end, i added a set of generic stack helpers:
8 estack_{push,pop}. then i rewrote eshopts_{push,pop} and based
9 eumask_{push,pop} on top of that.
10
11 what do people think ? good stuff, or am i trying too hard ?
12 -mike
13
14 --- eutils.eclass 14 Dec 2011 17:36:18 -0000 1.372
15 +++ eutils.eclass 14 Dec 2011 22:23:02 -0000
16 @@ -100,6 +100,51 @@ esvn_clean() {
17 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf
18 }
19
20 +# @FUNCTION: estack_push
21 +# @USAGE: <stack> [items to push]
22 +# @DESCRIPTION:
23 +# Push any number of items onto the specified stack. Pick a name that
24 +# is a valid variable (i.e. stick to alphanumerics), and push as many
25 +# items as you like onto the stack at once.
26 +#
27 +# The following code snippet will echo 5, then 4, then 3, then ...
28 +# @CODE
29 +# estask_push mystack 1 2 3 4 5
30 +# while i=$(estack_pop mystack) ; do
31 +# echo ${i}
32 +# done
33 +# @CODE
34 +estack_push() {
35 + [[ $# -eq 0 ]] && die "estack_push: incorrect # of arguments"
36 + local stack_name="__ESTACK_$1__" ; shift
37 + eval ${stack_name}+=\( \"\$@\" \)
38 +}
39 +
40 +# @FUNCTION: estack_pop
41 +# @USAGE: <stack>
42 +# @DESCRIPTION:
43 +# Pop a single item off the specified stack and return 0. If no more
44 +# items are available, return 1. See estack_push for more info.
45 +estack_pop() {
46 + if [[ $# -ne 1 ]] ; then
47 + # Would like to call `die` here, but people will usually
48 + # be calling this in a subshell; e.g.
49 + # val=$(estack_pop foo)
50 + eerror "estack_pop: incorrect # of arguments"
51 + return 1
52 + fi
53 +
54 + local stack_name="__ESTACK_$1__" ; shift
55 + eval local i=\${#${stack_name}[@]}
56 + # Don't warn -- let the caller interpret this as a failure
57 + # or as normal behavior (akin to `shift`)
58 + [[ $(( --i )) -eq -1 ]] && return 1
59 +
60 + eval local s=\"\${${stack_name}[${i}]}\"
61 + eval unset ${stack_name}[${i}]
62 + echo "${s}"
63 +}
64 +
65 # @FUNCTION: eshopts_push
66 # @USAGE: [options to `set` or `shopt`]
67 # @DESCRIPTION:
68 @@ -126,15 +171,14 @@ esvn_clean() {
69 eshopts_push() {
70 # have to assume __ESHOPTS_SAVE__ isn't screwed with
71 # as a `declare -a` here will reset its value
72 - local i=${#__ESHOPTS_SAVE__[@]}
73 if [[ $1 == -[su] ]] ; then
74 - __ESHOPTS_SAVE__[$i]=$(shopt -p)
75 + estack_push eshopts "$(shopt -p)"
76 [[ $# -eq 0 ]] && return 0
77 shopt "$@" || die "eshopts_push: bad options to shopt: $*"
78 else
79 - __ESHOPTS_SAVE__[$i]=$-
80 + estack_push eshopts $-
81 [[ $# -eq 0 ]] && return 0
82 set "$@" || die "eshopts_push: bad options to set: $*"
83 fi
84 @@ -144,19 +188,36 @@ eshopts_push() {
85 # Restore the shell options to the state saved with the corresponding
86 # eshopts_push call. See that function for more details.
87 eshopts_pop() {
88 - [[ $# -ne 0 ]] && die "eshopts_pop takes no arguments"
89 - local i=$(( ${#__ESHOPTS_SAVE__[@]} - 1 ))
90 - [[ ${i} -eq -1 ]] && die "eshopts_{push,pop}: unbalanced pair"
91 - local s=${__ESHOPTS_SAVE__[$i]}
92 - unset __ESHOPTS_SAVE__[$i]
93 + local s
94 + s=$(estack_pop eshopts) || die # do not merge with `local` above
95 if [[ ${s} == "shopt -"* ]] ; then
96 eval "${s}" || die "eshopts_pop: sanity: invalid shopt options: ${s}"
97 else
98 set +$- || die "eshopts_pop: sanity: invalid shell settings: $-"
99 set -${s} || die "eshopts_pop: sanity: unable to restore saved shell settings: ${s}"
100 fi
101 }
102
103 +# @FUNCTION: eumask_push
104 +# @USAGE: <new umask>
105 +# @DESCRIPTION:
106 +# Set the umask to the new value specified while saving the previous
107 +# value onto a stack. Useful for temporarily changing the umask.
108 +eumask_push() {
109 + estack_push eumask "$(umask)"
110 + umask "$@" || die "${FUNCNAME}: bad options to umask: $*"
111 +}
112 +
113 +# @FUNCTION: eumask_pop
114 +# @USAGE:
115 +# @DESCRIPTION:
116 +# Restore the previous umask state.
117 +eumask_pop() {
118 + local s
119 + s=$(estack_pop eumask) || die # do not merge with `local` above
120 + umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}"
121 +}
122 +
123 # @VARIABLE: EPATCH_SOURCE
124 # @DESCRIPTION:
125 # Default directory to search for patches.

Attachments

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

Replies