1 |
Split the estack_* and related functions from eutils into a dedicated |
2 |
estack.eclass. Those functions have significant complexity and are not |
3 |
used frequently, therefore they benefit from having a separate file |
4 |
and an explicit dedicated maintainer. |
5 |
|
6 |
The new eclass is implicitly inherited by eutils to preserve |
7 |
compatibility. However, the inherit will be removed in EAPI 7, |
8 |
and the ebuilds should switch to using estack directly. |
9 |
|
10 |
Thanks to Ulrich Müller for doing the research on this. |
11 |
--- |
12 |
eclass/estack.eclass | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++ |
13 |
eclass/eutils.eclass | 210 ++----------------------------------------------- |
14 |
2 files changed, 224 insertions(+), 203 deletions(-) |
15 |
create mode 100644 eclass/estack.eclass |
16 |
|
17 |
diff --git a/eclass/estack.eclass b/eclass/estack.eclass |
18 |
new file mode 100644 |
19 |
index 000000000000..19c388f3d8d2 |
20 |
--- /dev/null |
21 |
+++ b/eclass/estack.eclass |
22 |
@@ -0,0 +1,217 @@ |
23 |
+# Copyright 1999-2017 Gentoo Foundation |
24 |
+# Distributed under the terms of the GNU General Public License v2 |
25 |
+ |
26 |
+# @ECLASS: estack.eclass |
27 |
+# @MAINTAINER: |
28 |
+# base-system@g.o |
29 |
+# @BLURB: stack-like value storage support |
30 |
+# @DESCRIPTION: |
31 |
+# Support for storing values on stack-like variables. |
32 |
+ |
33 |
+if [[ -z ${_ESTACK_ECLASS} ]]; then |
34 |
+ |
35 |
+# @FUNCTION: estack_push |
36 |
+# @USAGE: <stack> [items to push] |
37 |
+# @DESCRIPTION: |
38 |
+# Push any number of items onto the specified stack. Pick a name that |
39 |
+# is a valid variable (i.e. stick to alphanumerics), and push as many |
40 |
+# items as you like onto the stack at once. |
41 |
+# |
42 |
+# The following code snippet will echo 5, then 4, then 3, then ... |
43 |
+# @CODE |
44 |
+# estack_push mystack 1 2 3 4 5 |
45 |
+# while estack_pop mystack i ; do |
46 |
+# echo "${i}" |
47 |
+# done |
48 |
+# @CODE |
49 |
+estack_push() { |
50 |
+ [[ $# -eq 0 ]] && die "estack_push: incorrect # of arguments" |
51 |
+ local stack_name="_ESTACK_$1_" ; shift |
52 |
+ eval ${stack_name}+=\( \"\$@\" \) |
53 |
+} |
54 |
+ |
55 |
+# @FUNCTION: estack_pop |
56 |
+# @USAGE: <stack> [variable] |
57 |
+# @DESCRIPTION: |
58 |
+# Pop a single item off the specified stack. If a variable is specified, |
59 |
+# the popped item is stored there. If no more items are available, return |
60 |
+# 1, else return 0. See estack_push for more info. |
61 |
+estack_pop() { |
62 |
+ [[ $# -eq 0 || $# -gt 2 ]] && die "estack_pop: incorrect # of arguments" |
63 |
+ |
64 |
+ # We use the fugly _estack_xxx var names to avoid collision with |
65 |
+ # passing back the return value. If we used "local i" and the |
66 |
+ # caller ran `estack_pop ... i`, we'd end up setting the local |
67 |
+ # copy of "i" rather than the caller's copy. The _estack_xxx |
68 |
+ # garbage is preferable to using $1/$2 everywhere as that is a |
69 |
+ # bit harder to read. |
70 |
+ local _estack_name="_ESTACK_$1_" ; shift |
71 |
+ local _estack_retvar=$1 ; shift |
72 |
+ eval local _estack_i=\${#${_estack_name}\[@\]} |
73 |
+ # Don't warn -- let the caller interpret this as a failure |
74 |
+ # or as normal behavior (akin to `shift`) |
75 |
+ [[ $(( --_estack_i )) -eq -1 ]] && return 1 |
76 |
+ |
77 |
+ if [[ -n ${_estack_retvar} ]] ; then |
78 |
+ eval ${_estack_retvar}=\"\${${_estack_name}\[${_estack_i}\]}\" |
79 |
+ fi |
80 |
+ eval unset \"${_estack_name}\[${_estack_i}\]\" |
81 |
+} |
82 |
+ |
83 |
+# @FUNCTION: evar_push |
84 |
+# @USAGE: <variable to save> [more vars to save] |
85 |
+# @DESCRIPTION: |
86 |
+# This let's you temporarily modify a variable and then restore it (including |
87 |
+# set vs unset semantics). Arrays are not supported at this time. |
88 |
+# |
89 |
+# This is meant for variables where using `local` does not work (such as |
90 |
+# exported variables, or only temporarily changing things in a func). |
91 |
+# |
92 |
+# For example: |
93 |
+# @CODE |
94 |
+# evar_push LC_ALL |
95 |
+# export LC_ALL=C |
96 |
+# ... do some stuff that needs LC_ALL=C set ... |
97 |
+# evar_pop |
98 |
+# |
99 |
+# # You can also save/restore more than one var at a time |
100 |
+# evar_push BUTTERFLY IN THE SKY |
101 |
+# ... do stuff with the vars ... |
102 |
+# evar_pop # This restores just one var, SKY |
103 |
+# ... do more stuff ... |
104 |
+# evar_pop 3 # This pops the remaining 3 vars |
105 |
+# @CODE |
106 |
+evar_push() { |
107 |
+ local var val |
108 |
+ for var ; do |
109 |
+ [[ ${!var+set} == "set" ]] \ |
110 |
+ && val=${!var} \ |
111 |
+ || val="unset_76fc3c462065bb4ca959f939e6793f94" |
112 |
+ estack_push evar "${var}" "${val}" |
113 |
+ done |
114 |
+} |
115 |
+ |
116 |
+# @FUNCTION: evar_push_set |
117 |
+# @USAGE: <variable to save> [new value to store] |
118 |
+# @DESCRIPTION: |
119 |
+# This is a handy shortcut to save and temporarily set a variable. If a value |
120 |
+# is not specified, the var will be unset. |
121 |
+evar_push_set() { |
122 |
+ local var=$1 |
123 |
+ evar_push ${var} |
124 |
+ case $# in |
125 |
+ 1) unset ${var} ;; |
126 |
+ 2) printf -v "${var}" '%s' "$2" ;; |
127 |
+ *) die "${FUNCNAME}: incorrect # of args: $*" ;; |
128 |
+ esac |
129 |
+} |
130 |
+ |
131 |
+# @FUNCTION: evar_pop |
132 |
+# @USAGE: [number of vars to restore] |
133 |
+# @DESCRIPTION: |
134 |
+# Restore the variables to the state saved with the corresponding |
135 |
+# evar_push call. See that function for more details. |
136 |
+evar_pop() { |
137 |
+ local cnt=${1:-bad} |
138 |
+ case $# in |
139 |
+ 0) cnt=1 ;; |
140 |
+ 1) isdigit "${cnt}" || die "${FUNCNAME}: first arg must be a number: $*" ;; |
141 |
+ *) die "${FUNCNAME}: only accepts one arg: $*" ;; |
142 |
+ esac |
143 |
+ |
144 |
+ local var val |
145 |
+ while (( cnt-- )) ; do |
146 |
+ estack_pop evar val || die "${FUNCNAME}: unbalanced push" |
147 |
+ estack_pop evar var || die "${FUNCNAME}: unbalanced push" |
148 |
+ [[ ${val} == "unset_76fc3c462065bb4ca959f939e6793f94" ]] \ |
149 |
+ && unset ${var} \ |
150 |
+ || printf -v "${var}" '%s' "${val}" |
151 |
+ done |
152 |
+} |
153 |
+ |
154 |
+# @FUNCTION: eshopts_push |
155 |
+# @USAGE: [options to `set` or `shopt`] |
156 |
+# @DESCRIPTION: |
157 |
+# Often times code will want to enable a shell option to change code behavior. |
158 |
+# Since changing shell options can easily break other pieces of code (which |
159 |
+# assume the default state), eshopts_push is used to (1) push the current shell |
160 |
+# options onto a stack and (2) pass the specified arguments to set. |
161 |
+# |
162 |
+# If the first argument is '-s' or '-u', we assume you want to call `shopt` |
163 |
+# rather than `set` as there are some options only available via that. |
164 |
+# |
165 |
+# A common example is to disable shell globbing so that special meaning/care |
166 |
+# may be used with variables/arguments to custom functions. That would be: |
167 |
+# @CODE |
168 |
+# eshopts_push -o noglob |
169 |
+# for x in ${foo} ; do |
170 |
+# if ...some check... ; then |
171 |
+# eshopts_pop |
172 |
+# return 0 |
173 |
+# fi |
174 |
+# done |
175 |
+# eshopts_pop |
176 |
+# @CODE |
177 |
+eshopts_push() { |
178 |
+ if [[ $1 == -[su] ]] ; then |
179 |
+ estack_push eshopts "$(shopt -p)" |
180 |
+ [[ $# -eq 0 ]] && return 0 |
181 |
+ shopt "$@" || die "${FUNCNAME}: bad options to shopt: $*" |
182 |
+ else |
183 |
+ estack_push eshopts $- |
184 |
+ [[ $# -eq 0 ]] && return 0 |
185 |
+ set "$@" || die "${FUNCNAME}: bad options to set: $*" |
186 |
+ fi |
187 |
+} |
188 |
+ |
189 |
+# @FUNCTION: eshopts_pop |
190 |
+# @USAGE: |
191 |
+# @DESCRIPTION: |
192 |
+# Restore the shell options to the state saved with the corresponding |
193 |
+# eshopts_push call. See that function for more details. |
194 |
+eshopts_pop() { |
195 |
+ local s |
196 |
+ estack_pop eshopts s || die "${FUNCNAME}: unbalanced push" |
197 |
+ if [[ ${s} == "shopt -"* ]] ; then |
198 |
+ eval "${s}" || die "${FUNCNAME}: sanity: invalid shopt options: ${s}" |
199 |
+ else |
200 |
+ set +$- || die "${FUNCNAME}: sanity: invalid shell settings: $-" |
201 |
+ set -${s} || die "${FUNCNAME}: sanity: unable to restore saved shell settings: ${s}" |
202 |
+ fi |
203 |
+} |
204 |
+ |
205 |
+# @FUNCTION: eumask_push |
206 |
+# @USAGE: <new umask> |
207 |
+# @DESCRIPTION: |
208 |
+# Set the umask to the new value specified while saving the previous |
209 |
+# value onto a stack. Useful for temporarily changing the umask. |
210 |
+eumask_push() { |
211 |
+ estack_push eumask "$(umask)" |
212 |
+ umask "$@" || die "${FUNCNAME}: bad options to umask: $*" |
213 |
+} |
214 |
+ |
215 |
+# @FUNCTION: eumask_pop |
216 |
+# @USAGE: |
217 |
+# @DESCRIPTION: |
218 |
+# Restore the previous umask state. |
219 |
+eumask_pop() { |
220 |
+ [[ $# -eq 0 ]] || die "${FUNCNAME}: we take no options" |
221 |
+ local s |
222 |
+ estack_pop eumask s || die "${FUNCNAME}: unbalanced push" |
223 |
+ umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}" |
224 |
+} |
225 |
+ |
226 |
+# @FUNCTION: isdigit |
227 |
+# @USAGE: <number> [more numbers] |
228 |
+# @DESCRIPTION: |
229 |
+# Return true if all arguments are numbers. |
230 |
+isdigit() { |
231 |
+ local d |
232 |
+ for d ; do |
233 |
+ [[ ${d:-bad} == *[!0-9]* ]] && return 1 |
234 |
+ done |
235 |
+ return 0 |
236 |
+} |
237 |
+ |
238 |
+_ESTACK_ECLASS=1 |
239 |
+fi #_ESTACK_ECLASS |
240 |
diff --git a/eclass/eutils.eclass b/eclass/eutils.eclass |
241 |
index ac6a4854d17b..79ec00042a3f 100644 |
242 |
--- a/eclass/eutils.eclass |
243 |
+++ b/eclass/eutils.eclass |
244 |
@@ -19,6 +19,13 @@ _EUTILS_ECLASS=1 |
245 |
|
246 |
inherit multilib toolchain-funcs |
247 |
|
248 |
+# implicitly inherited (now split) eclasses |
249 |
+case ${EAPI:-0} in |
250 |
+0|1|2|3|4|5|6) |
251 |
+ inherit estack |
252 |
+ ;; |
253 |
+esac |
254 |
+ |
255 |
# @FUNCTION: eqawarn |
256 |
# @USAGE: [message] |
257 |
# @DESCRIPTION: |
258 |
@@ -63,209 +70,6 @@ egit_clean() { |
259 |
find "$@" -type d -name '.git*' -prune -print0 | xargs -0 rm -rf |
260 |
} |
261 |
|
262 |
-# @FUNCTION: estack_push |
263 |
-# @USAGE: <stack> [items to push] |
264 |
-# @DESCRIPTION: |
265 |
-# Push any number of items onto the specified stack. Pick a name that |
266 |
-# is a valid variable (i.e. stick to alphanumerics), and push as many |
267 |
-# items as you like onto the stack at once. |
268 |
-# |
269 |
-# The following code snippet will echo 5, then 4, then 3, then ... |
270 |
-# @CODE |
271 |
-# estack_push mystack 1 2 3 4 5 |
272 |
-# while estack_pop mystack i ; do |
273 |
-# echo "${i}" |
274 |
-# done |
275 |
-# @CODE |
276 |
-estack_push() { |
277 |
- [[ $# -eq 0 ]] && die "estack_push: incorrect # of arguments" |
278 |
- local stack_name="_ESTACK_$1_" ; shift |
279 |
- eval ${stack_name}+=\( \"\$@\" \) |
280 |
-} |
281 |
- |
282 |
-# @FUNCTION: estack_pop |
283 |
-# @USAGE: <stack> [variable] |
284 |
-# @DESCRIPTION: |
285 |
-# Pop a single item off the specified stack. If a variable is specified, |
286 |
-# the popped item is stored there. If no more items are available, return |
287 |
-# 1, else return 0. See estack_push for more info. |
288 |
-estack_pop() { |
289 |
- [[ $# -eq 0 || $# -gt 2 ]] && die "estack_pop: incorrect # of arguments" |
290 |
- |
291 |
- # We use the fugly _estack_xxx var names to avoid collision with |
292 |
- # passing back the return value. If we used "local i" and the |
293 |
- # caller ran `estack_pop ... i`, we'd end up setting the local |
294 |
- # copy of "i" rather than the caller's copy. The _estack_xxx |
295 |
- # garbage is preferable to using $1/$2 everywhere as that is a |
296 |
- # bit harder to read. |
297 |
- local _estack_name="_ESTACK_$1_" ; shift |
298 |
- local _estack_retvar=$1 ; shift |
299 |
- eval local _estack_i=\${#${_estack_name}\[@\]} |
300 |
- # Don't warn -- let the caller interpret this as a failure |
301 |
- # or as normal behavior (akin to `shift`) |
302 |
- [[ $(( --_estack_i )) -eq -1 ]] && return 1 |
303 |
- |
304 |
- if [[ -n ${_estack_retvar} ]] ; then |
305 |
- eval ${_estack_retvar}=\"\${${_estack_name}\[${_estack_i}\]}\" |
306 |
- fi |
307 |
- eval unset \"${_estack_name}\[${_estack_i}\]\" |
308 |
-} |
309 |
- |
310 |
-# @FUNCTION: evar_push |
311 |
-# @USAGE: <variable to save> [more vars to save] |
312 |
-# @DESCRIPTION: |
313 |
-# This let's you temporarily modify a variable and then restore it (including |
314 |
-# set vs unset semantics). Arrays are not supported at this time. |
315 |
-# |
316 |
-# This is meant for variables where using `local` does not work (such as |
317 |
-# exported variables, or only temporarily changing things in a func). |
318 |
-# |
319 |
-# For example: |
320 |
-# @CODE |
321 |
-# evar_push LC_ALL |
322 |
-# export LC_ALL=C |
323 |
-# ... do some stuff that needs LC_ALL=C set ... |
324 |
-# evar_pop |
325 |
-# |
326 |
-# # You can also save/restore more than one var at a time |
327 |
-# evar_push BUTTERFLY IN THE SKY |
328 |
-# ... do stuff with the vars ... |
329 |
-# evar_pop # This restores just one var, SKY |
330 |
-# ... do more stuff ... |
331 |
-# evar_pop 3 # This pops the remaining 3 vars |
332 |
-# @CODE |
333 |
-evar_push() { |
334 |
- local var val |
335 |
- for var ; do |
336 |
- [[ ${!var+set} == "set" ]] \ |
337 |
- && val=${!var} \ |
338 |
- || val="unset_76fc3c462065bb4ca959f939e6793f94" |
339 |
- estack_push evar "${var}" "${val}" |
340 |
- done |
341 |
-} |
342 |
- |
343 |
-# @FUNCTION: evar_push_set |
344 |
-# @USAGE: <variable to save> [new value to store] |
345 |
-# @DESCRIPTION: |
346 |
-# This is a handy shortcut to save and temporarily set a variable. If a value |
347 |
-# is not specified, the var will be unset. |
348 |
-evar_push_set() { |
349 |
- local var=$1 |
350 |
- evar_push ${var} |
351 |
- case $# in |
352 |
- 1) unset ${var} ;; |
353 |
- 2) printf -v "${var}" '%s' "$2" ;; |
354 |
- *) die "${FUNCNAME}: incorrect # of args: $*" ;; |
355 |
- esac |
356 |
-} |
357 |
- |
358 |
-# @FUNCTION: evar_pop |
359 |
-# @USAGE: [number of vars to restore] |
360 |
-# @DESCRIPTION: |
361 |
-# Restore the variables to the state saved with the corresponding |
362 |
-# evar_push call. See that function for more details. |
363 |
-evar_pop() { |
364 |
- local cnt=${1:-bad} |
365 |
- case $# in |
366 |
- 0) cnt=1 ;; |
367 |
- 1) isdigit "${cnt}" || die "${FUNCNAME}: first arg must be a number: $*" ;; |
368 |
- *) die "${FUNCNAME}: only accepts one arg: $*" ;; |
369 |
- esac |
370 |
- |
371 |
- local var val |
372 |
- while (( cnt-- )) ; do |
373 |
- estack_pop evar val || die "${FUNCNAME}: unbalanced push" |
374 |
- estack_pop evar var || die "${FUNCNAME}: unbalanced push" |
375 |
- [[ ${val} == "unset_76fc3c462065bb4ca959f939e6793f94" ]] \ |
376 |
- && unset ${var} \ |
377 |
- || printf -v "${var}" '%s' "${val}" |
378 |
- done |
379 |
-} |
380 |
- |
381 |
-# @FUNCTION: eshopts_push |
382 |
-# @USAGE: [options to `set` or `shopt`] |
383 |
-# @DESCRIPTION: |
384 |
-# Often times code will want to enable a shell option to change code behavior. |
385 |
-# Since changing shell options can easily break other pieces of code (which |
386 |
-# assume the default state), eshopts_push is used to (1) push the current shell |
387 |
-# options onto a stack and (2) pass the specified arguments to set. |
388 |
-# |
389 |
-# If the first argument is '-s' or '-u', we assume you want to call `shopt` |
390 |
-# rather than `set` as there are some options only available via that. |
391 |
-# |
392 |
-# A common example is to disable shell globbing so that special meaning/care |
393 |
-# may be used with variables/arguments to custom functions. That would be: |
394 |
-# @CODE |
395 |
-# eshopts_push -o noglob |
396 |
-# for x in ${foo} ; do |
397 |
-# if ...some check... ; then |
398 |
-# eshopts_pop |
399 |
-# return 0 |
400 |
-# fi |
401 |
-# done |
402 |
-# eshopts_pop |
403 |
-# @CODE |
404 |
-eshopts_push() { |
405 |
- if [[ $1 == -[su] ]] ; then |
406 |
- estack_push eshopts "$(shopt -p)" |
407 |
- [[ $# -eq 0 ]] && return 0 |
408 |
- shopt "$@" || die "${FUNCNAME}: bad options to shopt: $*" |
409 |
- else |
410 |
- estack_push eshopts $- |
411 |
- [[ $# -eq 0 ]] && return 0 |
412 |
- set "$@" || die "${FUNCNAME}: bad options to set: $*" |
413 |
- fi |
414 |
-} |
415 |
- |
416 |
-# @FUNCTION: eshopts_pop |
417 |
-# @USAGE: |
418 |
-# @DESCRIPTION: |
419 |
-# Restore the shell options to the state saved with the corresponding |
420 |
-# eshopts_push call. See that function for more details. |
421 |
-eshopts_pop() { |
422 |
- local s |
423 |
- estack_pop eshopts s || die "${FUNCNAME}: unbalanced push" |
424 |
- if [[ ${s} == "shopt -"* ]] ; then |
425 |
- eval "${s}" || die "${FUNCNAME}: sanity: invalid shopt options: ${s}" |
426 |
- else |
427 |
- set +$- || die "${FUNCNAME}: sanity: invalid shell settings: $-" |
428 |
- set -${s} || die "${FUNCNAME}: sanity: unable to restore saved shell settings: ${s}" |
429 |
- fi |
430 |
-} |
431 |
- |
432 |
-# @FUNCTION: eumask_push |
433 |
-# @USAGE: <new umask> |
434 |
-# @DESCRIPTION: |
435 |
-# Set the umask to the new value specified while saving the previous |
436 |
-# value onto a stack. Useful for temporarily changing the umask. |
437 |
-eumask_push() { |
438 |
- estack_push eumask "$(umask)" |
439 |
- umask "$@" || die "${FUNCNAME}: bad options to umask: $*" |
440 |
-} |
441 |
- |
442 |
-# @FUNCTION: eumask_pop |
443 |
-# @USAGE: |
444 |
-# @DESCRIPTION: |
445 |
-# Restore the previous umask state. |
446 |
-eumask_pop() { |
447 |
- [[ $# -eq 0 ]] || die "${FUNCNAME}: we take no options" |
448 |
- local s |
449 |
- estack_pop eumask s || die "${FUNCNAME}: unbalanced push" |
450 |
- umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}" |
451 |
-} |
452 |
- |
453 |
-# @FUNCTION: isdigit |
454 |
-# @USAGE: <number> [more numbers] |
455 |
-# @DESCRIPTION: |
456 |
-# Return true if all arguments are numbers. |
457 |
-isdigit() { |
458 |
- local d |
459 |
- for d ; do |
460 |
- [[ ${d:-bad} == *[!0-9]* ]] && return 1 |
461 |
- done |
462 |
- return 0 |
463 |
-} |
464 |
- |
465 |
# @VARIABLE: EPATCH_SOURCE |
466 |
# @DESCRIPTION: |
467 |
# Default directory to search for patches. |
468 |
-- |
469 |
2.12.0 |