Gentoo Archives: gentoo-dev

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

Replies