Gentoo Logo
Gentoo Spaceship




Note: Due to technical difficulties, the Archives are currently not up to date. GMANE provides an alternative service for most mailing lists.
c.f. bug 424647
List Archive: gentoo-dev
Navigation:
Lists: gentoo-dev: < Prev By Thread Next > < Prev By Date Next >
Headers:
To: gentoo-dev@g.o
From: Steven J Long <slong@...>
Subject: Re: estack_{push,pop}: cool new helpers or over engineering?
Date: Fri, 16 Dec 2011 07:29:25 +0000
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: <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
> +#		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: <stack> [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 ;-)




Replies:
Re: Re: estack_{push,pop}: cool new helpers or over engineering?
-- Mike Frysinger
References:
estack_{push,pop}: cool new helpers or over engineering?
-- Mike Frysinger
Re: estack_{push,pop}: cool new helpers or over engineering?
-- Mike Frysinger
Navigation:
Lists: gentoo-dev: < Prev By Thread Next > < Prev By Date Next >
Previous by thread:
Re: estack_{push,pop}: cool new helpers or over engineering?
Next by thread:
Re: Re: estack_{push,pop}: cool new helpers or over engineering?
Previous by date:
About removing utf8 herd
Next by date:
Re: making the stable tree more up-to-date


Updated Jun 29, 2012

Summary: Archive of the gentoo-dev mailing list.

Donate to support our development efforts.

Copyright 2001-2013 Gentoo Foundation, Inc. Questions, Comments? Contact us.