* b='${a//"/}' and ${(e)b} @ 2008-05-10 12:38 Stephane Chazelas 2008-05-10 17:12 ` Bart Schaefer 2008-05-10 21:02 ` [PATCH] zmv (Was: b='${a//"/}' and ${(e)b}) Stephane Chazelas 0 siblings, 2 replies; 4+ messages in thread From: Stephane Chazelas @ 2008-05-10 12:38 UTC (permalink / raw) To: Zsh hackers list Hiya, $ a='a"b' $ b='${a//"/}' $ echo ${(e)b} $ b='${a//\"/}' $ echo ${(e)b} $ b='${a//\\"/}' $ echo ${(e)b} $ b='${a//\\\"/}' $ echo ${(e)b} $ b='${a//["]/}' $ echo ${(e)b} $ b='${a//[a]/}' $ echo ${(e)b} "b $ echo "${a//"/}" dquote braceparam> $ echo "${a//\"/}" ab $ b='${a//["]/}' $ echo ${(eq)b} $\{a//\[\"\]/\} $ echo ${(qe)b} $\{a//\[\"\]/\} How would I do? I came accross the problem when trying: zmv '*"*' '${f//"/}' [...] +zmv:42> pat='*"*' +zmv:43> repl='${f//"/}' +zmv:44> shift 2 +zmv:45> [[ -z '' ]] +zmv:47> tmpf=/tmp/zshzmv5557 +zmv:48> print -P %N +zmv:49> myname=zmv +zmv:50> rm -f /tmp/zshzmv5557 +zmv:51> action=mv +zmv:52> [[ mv != '(cp|mv|ln)' ]] +zmv:58> [[ -n '' ]] +zmv:63> [[ -n '' || -n '' ]] +zmv:91> [[ -n '' ]] +zmv:96> [[ '*"*' == '(#b)(*)((**##/))(*)' ]] +zmv:107> fpat='*"*' +zmv:109> files=( 'a"' ) +zmv:110> [[ -n '' ]] +zmv:111> errs=( ) +zmv:112> f=a" +zmv:114> [[ '*"*' == '(#b)(*)(**##/)(*)' ]] +zmv:118> [[ -e 'a"' && 'a"' == '(#b)*"*' ]] +zmv:119> set -- '' g=${(e)repl} +zmv:120> g='' +zmv:121> [[ -z '' ]] +zmv:123> errs=( '`a"'\'' expanded to an empty string' ) +zmv:135> from[$g]='a"' +zmv:136> to[$f]='' +zmv:138> (( 1 )) +zmv:140> print -P '%N: error(s) in substitution:' zmv: error(s) in substitution: +zmv:141> print -l '`a"'\'' expanded to an empty string' `a"' expanded to an empty string +zmv:142> return 1 BTW, shouldn't it be "print -rl -- $errs >&2"? And -r added to all those "print"s? It might be a good idea also to use some ${(V)var} when stdout/stderr is a tty. Best regards, Stéphane ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: b='${a//"/}' and ${(e)b} 2008-05-10 12:38 b='${a//"/}' and ${(e)b} Stephane Chazelas @ 2008-05-10 17:12 ` Bart Schaefer 2008-05-11 16:10 ` Stephane Chazelas 2008-05-10 21:02 ` [PATCH] zmv (Was: b='${a//"/}' and ${(e)b}) Stephane Chazelas 1 sibling, 1 reply; 4+ messages in thread From: Bart Schaefer @ 2008-05-10 17:12 UTC (permalink / raw) To: Zsh hackers list On May 10, 1:38pm, Stephane Chazelas wrote: } } $ a='a"b' } $ b='${a//"/}' } $ echo ${(e)b} (etc.) If you use $ echo ${(Xe)b} Then you'll see that zsh burps "parse error" on nearly every one of those expressions. Without the (X) flag the error is silently ignored and the expansion returns nothing. (Perhaps zmv should use (X).) Now, as to why it's hard to quote a double quote within a // replacement when using the (e) flag, I'm not sure what to say except that the parsing rules for all those nested levels of sometimes-implicit quoting get a bit arcane. } How would I do? $ c='"' $ b='${a//$c/}' $ print ${(Xe)b} Which does work for zmv: $ zmv -n '*"*' '${f//$c/}' mv -- a\"b ab Or you can do this: $ zmv -n '*"*' '$f:gs/"//' mv -- a\"b ab The parsing rules for :s are a lot simpler than those for ${...}. ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: b='${a//"/}' and ${(e)b} 2008-05-10 17:12 ` Bart Schaefer @ 2008-05-11 16:10 ` Stephane Chazelas 0 siblings, 0 replies; 4+ messages in thread From: Stephane Chazelas @ 2008-05-11 16:10 UTC (permalink / raw) To: Bart Schaefer; +Cc: Zsh hackers list On Sat, May 10, 2008 at 10:12:41AM -0700, Bart Schaefer wrote: [...] > } $ a='a"b' > } $ b='${a//"/}' > } $ echo ${(e)b} > > (etc.) > > If you use > > $ echo ${(Xe)b} > > Then you'll see that zsh burps "parse error" on nearly every one of those > expressions. Without the (X) flag the error is silently ignored and the > expansion returns nothing. (Perhaps zmv should use (X).) > > Now, as to why it's hard to quote a double quote within a // replacement > when using the (e) flag, I'm not sure what to say except that the parsing > rules for all those nested levels of sometimes-implicit quoting get a bit > arcane. > > } How would I do? > > $ c='"' > $ b='${a//$c/}' > $ print ${(Xe)b} > > Which does work for zmv: Hi Bart, yes, that's what I had eventually found out as well (here's the comp.unix.shell discussion that started it: http://groups.google.com/group/comp.unix.shell/msg/df86a6f26b8ed168) I now also find that b='${a//"\""/}' works. That doesn't sound quite right though. -- Stéphane ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH] zmv (Was: b='${a//"/}' and ${(e)b}) 2008-05-10 12:38 b='${a//"/}' and ${(e)b} Stephane Chazelas 2008-05-10 17:12 ` Bart Schaefer @ 2008-05-10 21:02 ` Stephane Chazelas 1 sibling, 0 replies; 4+ messages in thread From: Stephane Chazelas @ 2008-05-10 21:02 UTC (permalink / raw) To: Zsh hackers list [-- Attachment #1: Type: text/plain, Size: 1302 bytes --] 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 [-- Attachment #2: diff --] [-- Type: text/plain, Size: 3471 bytes --] 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 ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-05-11 16:10 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-05-10 12:38 b='${a//"/}' and ${(e)b} Stephane Chazelas 2008-05-10 17:12 ` Bart Schaefer 2008-05-11 16:10 ` Stephane Chazelas 2008-05-10 21:02 ` [PATCH] zmv (Was: b='${a//"/}' and ${(e)b}) Stephane Chazelas
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).