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. |