From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20 invoked from network); 10 May 2008 21:02:28 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.4 (2008-01-01) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.4 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 10 May 2008 21:02:28 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 87753 invoked from network); 10 May 2008 21:02:19 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 10 May 2008 21:02:19 -0000 Received: (qmail 14302 invoked by alias); 10 May 2008 21:02:16 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 24990 Received: (qmail 14287 invoked from network); 10 May 2008 21:02:15 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 10 May 2008 21:02:15 -0000 Received: from mail.o2.co.uk (vader.london.02.net [82.132.130.150]) by bifrost.dotsrc.org (Postfix) with ESMTP id 5A85A80ED172 for ; Sat, 10 May 2008 23:02:07 +0200 (CEST) Received: from sc.homeunix.net (78.105.216.138) by mail.o2.co.uk (8.0.013.3) (authenticated as stephane.chazelas) id 480CEB82041E793A for zsh-workers@sunsite.dk; Sat, 10 May 2008 22:02:06 +0100 Received: from chazelas by sc.homeunix.net with local (Exim 4.69) (envelope-from ) id 1JuwCk-00030U-Gf for zsh-workers@sunsite.dk; Sat, 10 May 2008 22:02:06 +0100 Date: Sat, 10 May 2008 22:02:06 +0100 From: Stephane Chazelas To: Zsh hackers list Subject: [PATCH] zmv (Was: b='${a//"/}' and ${(e)b}) Message-ID: <20080510210206.GC5560@sc.homeunix.net> Mail-Followup-To: Zsh hackers list References: <20080510123843.GA5560@sc.homeunix.net> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="GvXjxJ+pjyke8COw" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20080510123843.GA5560@sc.homeunix.net> User-Agent: Mutt/1.5.16 (2007-09-19) X-Virus-Scanned: ClamAV 0.91.2/7083/Sat May 10 17:55:11 2008 on bifrost X-Virus-Status: Clean --GvXjxJ+pjyke8COw Content-Type: text/plain; charset=iso-8859-15 Content-Disposition: inline Content-Transfer-Encoding: 8bit While I was looking at zmv: I read: if [[ -z $action ]]; then # We can't necessarily get the name of the function directly, because # of no_function_argzero stupidity. tmpf=${TMPPREFIX}zmv$$ print -P %N >$tmpf myname=$(<$tmpf) rm -f $tmpf action=$myname[-2,-1] if [[ $action != (cp|mv|ln) ]]; then print "Action $action not recognised: must be cp, mv or ln." >&2 return 1 fi fi We could use: action=${(%):-%N} (which looks like a very complicated smiley) Also, for tempfiles, there's tmpf==(print -P %N) Also, I read: print -P "%N: unrecognized option: -$OPTARG" >&2 If $OPTARG is "%", that fails Maybe it would make sense to have a %P as a printf format for prompt expansions: printf '%P: unrecognized option: -%s\n' %N "$OPTARG" Of course, the above can be written: print -nP %N >&2 print -r ": unrecognized option: -$OPTARG" >&2 or print -r "${(%):-%N}: unrecognized option: -$OPTARG" >&2 though Also, I've seen some problems with the: $find variable: $ zmv -wn '[a\\]' '$f' zmv: warning: no wildcards were found in search pattern $ zmv -wn 'a#' '$f' zmv: warning: no wildcards were found in search pattern Please find a patch attached. Please test as I'm not really confident that I didn't introduce a few pairs of half-dozens bugs ;) -- Stéphane --GvXjxJ+pjyke8COw Content-Type: text/plain; charset=iso-8859-15 Content-Disposition: attachment; filename=diff Index: zmv =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/Misc/zmv,v retrieving revision 1.13 diff -u -r1.13 zmv --- zmv 13 Apr 2008 16:11:54 -0000 1.13 +++ zmv 10 May 2008 20:59:45 -0000 @@ -128,12 +128,14 @@ typeset -A from to integer stat +myname=${(%):-%N} + while getopts ":o:p:MCLfinqQsvwW" opt; do if [[ $opt = "?" ]]; then - print -P "%N: unrecognized option: -$OPTARG" >&2 + print -r -- "$myname: unrecognized option: -$OPTARG" >&2 return 1 fi - eval "opt_$opt=${(q)OPTARG:--$opt}" + eval "opt_$opt=\${OPTARG:--\$opt}" done (( OPTIND > 1 )) && shift $(( OPTIND - 1 )) @@ -143,6 +145,15 @@ [[ -n $opt_L ]] && action=ln [[ -n $opt_p ]] && action=$opt_p +if [[ -z $action ]]; then + action=$myname[-2,-1] + + if [[ $action != (cp|mv|ln) ]]; then + print -r "$myname: action $action not recognised: must be cp, mv or ln." >&2 + return 1 + fi +fi + if (( $# != 2 )); then print -P "Usage: %N [OPTIONS] oldpattern newpattern @@ -164,25 +175,8 @@ repl=$2 shift 2 -if [[ -z $action ]]; then - # We can't necessarily get the name of the function directly, because - # of no_function_argzero stupidity. - tmpf=${TMPPREFIX}zmv$$ - print -P %N >$tmpf - myname=$(<$tmpf) - rm -f $tmpf - - action=$myname[-2,-1] - - if [[ $action != (cp|mv|ln) ]]; then - print "Action $action not recognised: must be cp, mv or ln." >&2 - return 1 - fi -fi - - if [[ -n $opt_s && $action != ln ]]; then - print -P "%N: invalid option: -s" >&2 + print -r -- "$myname: invalid option: -s" >&2 return 1 fi @@ -193,10 +187,10 @@ # Well, this seems to work. # The tricky bit is getting all forms of [...] correct, but as long # as we require inactive bits to be backslashed its not so bad. - find='(#m)(\*\*#[/]|[*?]|\<[0-9]#-[0-9]#\>|\[(\[:[a-z]##:\]|\\\[|\\\]|[^\[\]]##)##\])\##' + find='(#m)((\*\*#/|[*?]|<[0-9]#-[0-9]#>|\[(^|)(\]|)(\[:[a-z]##:\]|\\?|[^\]])##\])\##|?\###)' tmp="${pat//${~find}/$[++cnt]}" if [[ $cnt = 0 ]]; then - print -P "%N: warning: no wildcards were found in search pattern" >&2 + print -r -- "$myname: warning: no wildcards were found in search pattern" >&2 else pat="${pat//${~find}/($MATCH)}" fi @@ -252,26 +246,33 @@ fi [[ -e $f && $f = (#b)${~pat} ]] || continue set -- "$match[@]" - g=${(e)repl} + { { + g=${(Xe)repl} + } 2> /dev/null } always { + if (( TRY_BLOCK_ERROR )); then + print -r -- "$myname: syntax error in replacement" >&2 + return 1 + fi + } if [[ -z $g ]]; then - errs=($errs "\`$f' expanded to an empty string") + errs+=("\`$f' expanded to an empty string") elif [[ $f = $g ]]; then # don't cause error: more useful just to skip # errs=($errs "$f not altered by substitution") - [[ -n $opt_v ]] && print "$f not altered, ignored" + [[ -n $opt_v ]] && print -r -- "$f not altered, ignored" continue elif [[ -n $from[$g] && ! -d $g ]]; then - errs=($errs "$f and $from[$g] both map to $g") + errs+=("$f and $from[$g] both map to $g") elif [[ -f $g && -z $opt_f && ! ($f -ef $g && $action = mv) ]]; then - errs=($errs "file exists: $g") + errs+=("file exists: $g") fi from[$g]=$f to[$f]=$g done if (( $#errs )); then - print -P "%N: error(s) in substitution:" >&2 - print -l $errs >&2 + print -r -- "$myname: error(s) in substitution:" >&2 + print -lr -- $errs >&2 return 1 fi --GvXjxJ+pjyke8COw--