From: Mike Frysinger <vapier@gentoo.org>
To: gentoo-dev@lists.gentoo.org
Subject: [gentoo-dev] estack_{push,pop}: cool new helpers or over engineering?
Date: Wed, 14 Dec 2011 17:25:21 -0500 [thread overview]
Message-ID: <201112141725.22148.vapier@gentoo.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 4371 bytes --]
i needed to temporarily modify the umask in some vcs eclasses. rather than
open coding the umask saving/restoring, i decided to re-use the
eshopts_{push,pop} logic so the umask can be pushed/popped easily.
the resulting code was mostly copy & paste the same, and the stack maintenance
ends up drowning out the meat of the stuff i care about -- screwing with the
umask. so to that end, i added a set of generic stack helpers:
estack_{push,pop}. then i rewrote eshopts_{push,pop} and based
eumask_{push,pop} on top of that.
what do people think ? good stuff, or am i trying too hard ?
-mike
--- eutils.eclass 14 Dec 2011 17:36:18 -0000 1.372
+++ eutils.eclass 14 Dec 2011 22:23:02 -0000
@@ -100,6 +100,51 @@ esvn_clean() {
find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf
}
+# @FUNCTION: estack_push
+# @USAGE: <stack> [items to push]
+# @DESCRIPTION:
+# Push any number of items onto the specified stack. Pick a name that
+# is a valid variable (i.e. stick to alphanumerics), and push as many
+# items as you like onto the stack at once.
+#
+# The following code snippet will echo 5, then 4, then 3, then ...
+# @CODE
+# estask_push mystack 1 2 3 4 5
+# while i=$(estack_pop mystack) ; do
+# echo ${i}
+# done
+# @CODE
+estack_push() {
+ [[ $# -eq 0 ]] && die "estack_push: incorrect # of arguments"
+ local stack_name="__ESTACK_$1__" ; shift
+ eval ${stack_name}+=\( \"\$@\" \)
+}
+
+# @FUNCTION: estack_pop
+# @USAGE: <stack>
+# @DESCRIPTION:
+# Pop a single item off the specified stack and return 0. If no more
+# items are available, return 1. See estack_push for more info.
+estack_pop() {
+ if [[ $# -ne 1 ]] ; then
+ # Would like to call `die` here, but people will usually
+ # be calling this in a subshell; e.g.
+ # val=$(estack_pop foo)
+ eerror "estack_pop: incorrect # of arguments"
+ return 1
+ fi
+
+ local stack_name="__ESTACK_$1__" ; shift
+ eval local i=\${#${stack_name}[@]}
+ # Don't warn -- let the caller interpret this as a failure
+ # or as normal behavior (akin to `shift`)
+ [[ $(( --i )) -eq -1 ]] && return 1
+
+ eval local s=\"\${${stack_name}[${i}]}\"
+ eval unset ${stack_name}[${i}]
+ echo "${s}"
+}
+
# @FUNCTION: eshopts_push
# @USAGE: [options to `set` or `shopt`]
# @DESCRIPTION:
@@ -126,15 +171,14 @@ esvn_clean() {
eshopts_push() {
# have to assume __ESHOPTS_SAVE__ isn't screwed with
# as a `declare -a` here will reset its value
- local i=${#__ESHOPTS_SAVE__[@]}
if [[ $1 == -[su] ]] ; then
- __ESHOPTS_SAVE__[$i]=$(shopt -p)
+ estack_push eshopts "$(shopt -p)"
[[ $# -eq 0 ]] && return 0
shopt "$@" || die "eshopts_push: bad options to shopt: $*"
else
- __ESHOPTS_SAVE__[$i]=$-
+ estack_push eshopts $-
[[ $# -eq 0 ]] && return 0
set "$@" || die "eshopts_push: bad options to set: $*"
fi
@@ -144,19 +188,36 @@ eshopts_push() {
# Restore the shell options to the state saved with the corresponding
# eshopts_push call. See that function for more details.
eshopts_pop() {
- [[ $# -ne 0 ]] && die "eshopts_pop takes no arguments"
- local i=$(( ${#__ESHOPTS_SAVE__[@]} - 1 ))
- [[ ${i} -eq -1 ]] && die "eshopts_{push,pop}: unbalanced pair"
- local s=${__ESHOPTS_SAVE__[$i]}
- unset __ESHOPTS_SAVE__[$i]
+ local s
+ s=$(estack_pop eshopts) || die # do not merge with `local` above
if [[ ${s} == "shopt -"* ]] ; then
eval "${s}" || die "eshopts_pop: sanity: invalid shopt options: ${s}"
else
set +$- || die "eshopts_pop: sanity: invalid shell settings: $-"
set -${s} || die "eshopts_pop: sanity: unable to restore saved shell settings: ${s}"
fi
}
+# @FUNCTION: eumask_push
+# @USAGE: <new umask>
+# @DESCRIPTION:
+# Set the umask to the new value specified while saving the previous
+# value onto a stack. Useful for temporarily changing the umask.
+eumask_push() {
+ estack_push eumask "$(umask)"
+ umask "$@" || die "${FUNCNAME}: bad options to umask: $*"
+}
+
+# @FUNCTION: eumask_pop
+# @USAGE:
+# @DESCRIPTION:
+# Restore the previous umask state.
+eumask_pop() {
+ local s
+ s=$(estack_pop eumask) || die # do not merge with `local` above
+ umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}"
+}
+
# @VARIABLE: EPATCH_SOURCE
# @DESCRIPTION:
# Default directory to search for patches.
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
next reply other threads:[~2011-12-14 22:26 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-14 22:25 Mike Frysinger [this message]
2011-12-14 23:49 ` [gentoo-dev] estack_{push,pop}: cool new helpers or over engineering? Mike Frysinger
2011-12-16 7:29 ` [gentoo-dev] " Steven J Long
2011-12-16 23:20 ` Mike Frysinger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201112141725.22148.vapier@gentoo.org \
--to=vapier@gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox