From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1RbS7i-0007ZX-Ac for garchives@archives.gentoo.org; Fri, 16 Dec 2011 07:22:30 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 164EC21C078; Fri, 16 Dec 2011 07:22:17 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id A4C9A21C063 for ; Fri, 16 Dec 2011 07:21:41 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp.gentoo.org (Postfix) with ESMTP id 3A1A81B408B for ; Fri, 16 Dec 2011 07:21:41 +0000 (UTC) X-Virus-Scanned: by amavisd-new using ClamAV at gentoo.org X-Spam-Flag: NO X-Spam-Score: -3.327 X-Spam-Level: X-Spam-Status: No, score=-3.327 tagged_above=-999 required=5.5 tests=[AWL=-0.279, BAYES_00=-1.9, RCVD_NUMERIC_HELO=1.164, RP_MATCHES_RCVD=-2.31, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001] autolearn=ham Received: from smtp.gentoo.org ([127.0.0.1]) by localhost (smtp.gentoo.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OJTHaR3yhk-3 for ; Fri, 16 Dec 2011 07:21:32 +0000 (UTC) Received: from lo.gmane.org (lo.gmane.org [80.91.229.12]) by smtp.gentoo.org (Postfix) with ESMTP id 516E51B4092 for ; Fri, 16 Dec 2011 07:21:32 +0000 (UTC) Received: from list by lo.gmane.org with local (Exim 4.69) (envelope-from ) id 1RbS6k-00076X-Nd for gentoo-dev@gentoo.org; Fri, 16 Dec 2011 08:21:30 +0100 Received: from 109.176.247.130 ([109.176.247.130]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Fri, 16 Dec 2011 08:21:30 +0100 Received: from slong by 109.176.247.130 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Fri, 16 Dec 2011 08:21:30 +0100 X-Injected-Via-Gmane: http://gmane.org/ To: gentoo-dev@lists.gentoo.org From: Steven J Long Subject: [gentoo-dev] Re: estack_{push,pop}: cool new helpers or over engineering? Followup-To: gmane.linux.gentoo.devel Date: Fri, 16 Dec 2011 07:29:25 +0000 Organization: Friendly-Coders Message-ID: References: <201112141725.22148.vapier@gentoo.org> <201112141849.50101.vapier@gentoo.org> Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@lists.gentoo.org Reply-to: gentoo-dev@lists.gentoo.org Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7Bit X-Complaints-To: usenet@dough.gmane.org X-Gmane-NNTP-Posting-Host: 109.176.247.130 X-Archives-Salt: cfe3125a-933c-4b83-a9a1-d610fc2501db X-Archives-Hash: 422ffa16da7b5bf277c0dcdc76704508 Just to point out that arithmetic context can be more efficient; no bugs, except for a /minor/ possibility (second last comment.) Mike Frysinger wrote: > --- eutils.eclass 14 Dec 2011 17:36:18 -0000 1.372 > +++ eutils.eclass 14 Dec 2011 23:46:37 -0000 > @@ -100,6 +100,54 @@ esvn_clean() { > find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf > } > > +# @FUNCTION: estack_push > +# @USAGE: [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 > +# estack_push mystack 1 2 3 4 5 > +# while estack_pop mystack i ; do > +# echo ${i} A minor #bash point in passing: although these values of i are safe, for tutorial code, I really would recommend quoting: echo "$i" (or "${i}"). It's better to get people used to quoting by default, and only not quoting iff they need field-splitting on parameter expansions (eg for a variable used for command options.) > +# done > +# @CODE > +estack_push() { > + [[ $# -eq 0 ]] && die "estack_push: incorrect # of arguments" > + local stack_name="__ESTACK_$1__" ; shift > + eval ${stack_name}+=\( \"\$@\" \) > +} ((..)) is quicker than [[ .. ]] for arithmetic stuff, and usually easier to grok swiftly. (($#)) || die .. is how this would normally be done. > + > +# @FUNCTION: estack_pop > +# @USAGE: [variable] > +# @DESCRIPTION: > +# Pop a single item off the specified stack. If a variable is specified, > +# the popped item is stored there. If no more items are available, > return > +# 1, else return 0. See estack_push for more info. > +estack_pop() { > + ( [[ $# -eq 0 ]] || [[ $# -gt 2 ]] ) && die "estack_pop: incorrect # of arguments" (($# == 0 || $# > 2)) && die.. # does it in one command, with no subshell. [[ $# -eq 0 || $# -gt 2 ]] && die .. would work too, but more slowly. In general if you want to do complex chains without a subshell, you would use: { } && .. instead of: ( ) && .. TBH I would type (($#==0||$#>2)) in bash, though I space in C, where it doesn't affect execution time. But it's not as clear, especially if you're not in a highlighting editor. > + # We use the fugly __estack_xxx var names to avoid collision with > + # passing back the return value. If we used "local i" and the > + # caller ran `estack_pop ... i`, we'd end up setting the local > + # copy of "i" rather than the caller's copy. The __estack_xxx > + # garbage is preferable to using $1/$2 everywhere as that is a > + # bit harder to read. > + local __estack_name="__ESTACK_$1__" ; shift > + local __estack_retvar=$1 ; shift > + eval local __estack_i=\${#${__estack_name}[@]} > + # Don't warn -- let the caller interpret this as a failure > + # or as normal behavior (akin to `shift`) > + [[ $(( --__estack_i )) -eq -1 ]] && return 1 ((--__estack_i == -1)) && .. > + > + if [[ -n ${__estack_retvar} ]] ; then > + eval ${__estack_retvar}=\"\${${__estack_name} [${__estack_i}]}\" > + fi > + eval unset ${__estack_name}[${__estack_i}] > +} > + > # @FUNCTION: eshopts_push > # @USAGE: [options to `set` or `shopt`] > # @DESCRIPTION: > @@ -126,15 +174,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 I'm not sure how this will ever match, given that $1 has been checked above? (($#==1)) && return 0 # if that applies (might be a 'bug'.) > shopt "$@" || die "eshopts_push: bad options to shopt: $*" > else > - __ESHOPTS_SAVE__[$i]=$- > + estack_push eshopts $- > [[ $# -eq 0 ]] && return 0 (($#)) || return 0 > set "$@" || die "eshopts_push: bad options to set: $*" > fi > } > HTH, Steve. -- #friendly-coders -- We're friendly, but we're not /that/ friendly ;-)