zsh-workers
 help / color / mirror / code / Atom feed
* RE: PATCH: new parameter expansion type?
@ 1999-08-30 10:38 Sven Wischnowsky
  1999-08-31 13:18 ` Andrej Borsenkow
  0 siblings, 1 reply; 9+ messages in thread
From: Sven Wischnowsky @ 1999-08-30 10:38 UTC (permalink / raw)
  To: zsh-workers


Andrej Borsenkow wrote:

> > Ok, the `.' thingy is just because I couldn't think of a better
> > character/syntax (suggestions?) and this isn't as powerful as I would
> > like it because `then' and `else' can't expand to arrays. Maybe we
> > could make `${(A)foo^?^$arr1^$arr2}' do that (and maybe we could do
> > the same for `${(A)foo:-$arr}'.
> >
> 
> Remember discussion of backreference in new regexp implementation? I think, we
> should unify it with ${.../...} & Co code. There are two possibilities:

Sure I remember that, but it's a different thing -- or how would you
do an if-then-else with `${.../...}'? Or are you suggesting
`${.../pat/repl-then/repl-else}'? Hm.

> And about arrays and scalars - well, I'm afraid, this needs revising once more.
> Else we simply create one more ad hoc case. What is needed, is clear notion,
> when we have "array context" and "scalar context". Then it is possible to
> define, when result of substitution is an array and scalar. Currently, there is
> only really vague definition of "list of words". I just wish, result of
> substitution be better typed.

It isn't that vaguely defined -- ${..:-..} produces just a string. For 
${foo^..} we would have to say what happens if the then/else produces
more than one string and foo is an array (all strings inserted instead 
of the original element, I would say).

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: PATCH: new parameter expansion type?
  1999-08-30 10:38 PATCH: new parameter expansion type? Sven Wischnowsky
@ 1999-08-31 13:18 ` Andrej Borsenkow
  0 siblings, 0 replies; 9+ messages in thread
From: Andrej Borsenkow @ 1999-08-31 13:18 UTC (permalink / raw)
  To: Sven Wischnowsky, zsh-workers

> >
> > Remember discussion of backreference in new regexp implementation?
> I think, we
> > should unify it with ${.../...} & Co code. There are two possibilities:
>
> Sure I remember that, but it's a different thing -- or how would you
> do an if-then-else with `${.../...}'? Or are you suggesting
> `${.../pat/repl-then/repl-else}'? Hm.
>

No. What I suggest is

1. enable use of subpatterns
2. save the results of last pattern match in defined variables, e.g. $MATCH
(scalar) for a whole match  and $match (array) for subpatterns. Yes, it has som
eimpact, but e.g. in case of $foo == bar MATCH is reduntant (we match the whole
string anyway) and we can use option to turn it off.
3. now these variables can be used in ${.../...} and in ${...^...} in
replacement part. So, you can write
	${foo^$~bar^$baz^$MATCH}.
Or
	${foo/\([[:alpha:]]##\)\([[:letter:]]\)/$match[1]:$match[2]}

4. And these variables can be also used outside of expansion:

case $foo in
  any_pattern)
     print $match[3]


/andrej


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: new parameter expansion type?
  1999-08-31  8:50 Sven Wischnowsky
@ 1999-08-31 17:47 ` Bart Schaefer
  0 siblings, 0 replies; 9+ messages in thread
From: Bart Schaefer @ 1999-08-31 17:47 UTC (permalink / raw)
  To: zsh-workers

On Aug 31, 10:50am, Sven Wischnowsky wrote:
} Subject: Re: PATCH: new parameter expansion type?
}
} > This is essentially the same problem as ${(A)foo:=string} where it would
} > be nice to be able to have "string" be interpreted as an array.  I pointed
} > out the parsing problem with this back at that time.  It would be nice to
} > have a solution; Andrej suggested ${(A)foo:=(val1 val2 ...)} but it will
} > require a change to the parser to make that work.
} 
} Or we could add a flag that says that the string is to be split into
} different words and change `dquote_parse()' to allow us to say that
} the `endchar' is any white-space (or any seperator character).

I don't think that will work ... you have to split the string into words
long before you get into paramsubst() or you can't be guaranteed to get
it right.  It has to be a top-level syntax thing, not a parameter flag.

But maybe "a flag" isn't really what you meant ...

} I would have suggested using the forms with a double character (as in
} `${(A)arr:==a b c}') if that weren't too incompatible.

That means to assign the full path of the command named "a b c" to the
array.  You can't get away with overloading `=' any more than it already
is, I'm afraid.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: new parameter expansion type?
@ 1999-08-31  8:50 Sven Wischnowsky
  1999-08-31 17:47 ` Bart Schaefer
  0 siblings, 1 reply; 9+ messages in thread
From: Sven Wischnowsky @ 1999-08-31  8:50 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> On Aug 30, 11:49am, Sven Wischnowsky wrote:
> } Subject: PATCH: new parameter expansion type?
> }
> }   ${name^pattern^then^else}
> } 
> } Gives you the (substituted) `then' string if the expansion of `name'
> } matches the `pattern' and otherwise it gives you the `else' string.
> 
> Isn't this just the same as
> 
> 	${${${(M)name#pattern}:+then}:-else}
> 
> except of course that you have to be a little selective about whether
> you use # or % to delimit the pattern?

Nice, hadn't thought about that.

> I'm not particularly excited by the ^test^true^false syntax nor by the
> trick of making "." magic in the true/false strings.  I vote against this
> patch, in its current form at least.  Sorry, Sven.

Especially with the thing above I have absolutely no problems with
that.

> } Ok, the `.' thingy is just because I couldn't think of a better
> } character/syntax (suggestions?) and this isn't as powerful as I would
> } like it because `then' and `else' can't expand to arrays. Maybe we
> } could make `${(A)foo^?^$arr1^$arr2}' do that (and maybe we could do
> } the same for `${(A)foo:-$arr}'.
> 
> This is essentially the same problem as ${(A)foo:=string} where it would
> be nice to be able to have "string" be interpreted as an array.  I pointed
> out the parsing problem with this back at that time.  It would be nice to
> have a solution; Andrej suggested ${(A)foo:=(val1 val2 ...)} but it will
> require a change to the parser to make that work.

Or we could add a flag that says that the string is to be split into
different words and change `dquote_parse()' to allow us to say that
the `endchar' is any white-space (or any seperator character). I would 
have suggested using the forms with a double character (as in
`${(A)arr:==a b c}') if that weren't too incompatible.

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: new parameter expansion type?
  1999-08-30 16:05 ` Bart Schaefer
@ 1999-08-30 16:10   ` Peter Stephenson
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Stephenson @ 1999-08-30 16:10 UTC (permalink / raw)
  To: zsh-workers

"Bart Schaefer" wrote:
> On Aug 30, 11:49am, Sven Wischnowsky wrote:
> } Subject: PATCH: new parameter expansion type?
> }
> }   ${name^pattern^then^else}
> } 
> } Gives you the (substituted) `then' string if the expansion of `name'
> } matches the `pattern' and otherwise it gives you the `else' string.
> 
> Isn't this just the same as
> 
> 	${${${(M)name#pattern}:+then}:-else}
> 
> except of course that you have to be a little selective about whether
> you use # or % to delimit the pattern?

This seems to be the case; I've included it in 6-pws-2, but I'll probably
back it off in 6-pws-3, unless there's a good reason otherwise.

I was thinking about a more general ternary expression syntax, which would
require doing some work to pre-expansion argument lists.  Something like

${[[ <test> ]] <true1> <true2> ... | <false1> <false2> ... }

i.e. the true/false bits are treated like part of an ordinary argument list
(but can't have redirections).  I suspect it's going to be too clumsy,
however.  You can get the same effect with if's and arrays, obviously.

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: new parameter expansion type?
  1999-08-30  9:49 Sven Wischnowsky
  1999-08-30 10:06 ` Andrej Borsenkow
  1999-08-30 10:58 ` Tanaka Akira
@ 1999-08-30 16:05 ` Bart Schaefer
  1999-08-30 16:10   ` Peter Stephenson
  2 siblings, 1 reply; 9+ messages in thread
From: Bart Schaefer @ 1999-08-30 16:05 UTC (permalink / raw)
  To: zsh-workers

On Aug 30, 11:49am, Sven Wischnowsky wrote:
} Subject: PATCH: new parameter expansion type?
}
}   ${name^pattern^then^else}
} 
} Gives you the (substituted) `then' string if the expansion of `name'
} matches the `pattern' and otherwise it gives you the `else' string.

Isn't this just the same as

	${${${(M)name#pattern}:+then}:-else}

except of course that you have to be a little selective about whether
you use # or % to delimit the pattern?

I'm not particularly excited by the ^test^true^false syntax nor by the
trick of making "." magic in the true/false strings.  I vote against this
patch, in its current form at least.  Sorry, Sven.

} Ok, the `.' thingy is just because I couldn't think of a better
} character/syntax (suggestions?) and this isn't as powerful as I would
} like it because `then' and `else' can't expand to arrays. Maybe we
} could make `${(A)foo^?^$arr1^$arr2}' do that (and maybe we could do
} the same for `${(A)foo:-$arr}'.

This is essentially the same problem as ${(A)foo:=string} where it would
be nice to be able to have "string" be interpreted as an array.  I pointed
out the parsing problem with this back at that time.  It would be nice to
have a solution; Andrej suggested ${(A)foo:=(val1 val2 ...)} but it will
require a change to the parser to make that work.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: new parameter expansion type?
  1999-08-30  9:49 Sven Wischnowsky
  1999-08-30 10:06 ` Andrej Borsenkow
@ 1999-08-30 10:58 ` Tanaka Akira
  1999-08-30 16:05 ` Bart Schaefer
  2 siblings, 0 replies; 9+ messages in thread
From: Tanaka Akira @ 1999-08-30 10:58 UTC (permalink / raw)
  To: zsh-workers

In article <199908300949.LAA20865@beta.informatik.hu-berlin.de>,
  Sven Wischnowsky <wischnow@informatik.hu-berlin.de> writes:

> --- od/Zsh/expn.yo	Sun Aug 29 20:02:39 1999
> +++ Doc/Zsh/expn.yo	Sun Aug 29 22:00:54 1999
> @@ -447,6 +447,21 @@
>  while in the second case, the shortest matches are taken and the
>  result is `tt(spy spy lispy star)'.
>  )
> +xitem(tt(${)var(name)tt(^)var(pattern)tt(^)var(then)tt(^)var(else)tt(}))
> +item(tt(${)var(name)tt(^^)var(pattern)tt(^)var(then)tt(^)var(else)tt(}))(
> +If the expansion of var(name) matches the var(pattern), the var(then)
> +string is substituted, otherwise the var(else) string is
> +substituted. In the second form the var(pattern) is taken to be
> +negated (even if the tt(EXTENDED_GLOB) option is not set. The
> +var(else) string with the preceding `tt(^)' may be omitted in which
> +case the expansion behaves as if var(name) were unset (or, if
> +var(name) is an array, as if the element compared did not exist). In
> +the var(pattern) and the var(then) string a `tt(^)' may be included by 
> +preceding it with two backslashes. Finally, the var(then) and
> +var(else) string may consist of only a dot to make it expand to the
> +original string. To make them expand to only a dot, the string
> +`tt(\.)' has to be used.
> +)
>  item(tt(${#)var(spec)tt(}))(
>  If var(spec) is one of the above substitutions, substitute
>  the length in characters of the result instead of

Hm. Parentheses doesn't match.

Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /projects/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.1.1.25
diff -u -F^( -r1.1.1.25 expn.yo
--- expn.yo	1999/08/30 10:17:30	1.1.1.25
+++ expn.yo	1999/08/30 10:35:44
@@ -452,7 +452,7 @@ (This and the following
 If the expansion of var(name) matches the var(pattern), the var(then)
 string is substituted, otherwise the var(else) string is
 substituted. In the second form the var(pattern) is taken to be
-negated (even if the tt(EXTENDED_GLOB) option is not set. The
+negated (even if the tt(EXTENDED_GLOB) option is not set). The
 var(else) string with the preceding `tt(^)' may be omitted in which
 case the expansion behaves as if var(name) were unset (or, if
 var(name) is an array, as if the element compared did not exist). In
-- 
Tanaka Akira


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: PATCH: new parameter expansion type?
  1999-08-30  9:49 Sven Wischnowsky
@ 1999-08-30 10:06 ` Andrej Borsenkow
  1999-08-30 10:58 ` Tanaka Akira
  1999-08-30 16:05 ` Bart Schaefer
  2 siblings, 0 replies; 9+ messages in thread
From: Andrej Borsenkow @ 1999-08-30 10:06 UTC (permalink / raw)
  To: Sven Wischnowsky, zsh-workers

> Ok, the `.' thingy is just because I couldn't think of a better
> character/syntax (suggestions?) and this isn't as powerful as I would
> like it because `then' and `else' can't expand to arrays. Maybe we
> could make `${(A)foo^?^$arr1^$arr2}' do that (and maybe we could do
> the same for `${(A)foo:-$arr}'.
>

Remember discussion of backreference in new regexp implementation? I think, we
should unify it with ${.../...} & Co code. There are two possibilities:

 - use "standard" way and let \& refer to the whole match and \n, ... to n-th
subpattern

 - use $match/$MATCH (or anything you like) to refer to the last matched
(sub)patterns where $match[n] refers to n-th match and $MATCH to the whole
match.

The latter is better as it does not introduce new metacharacters and can be used
outside of parameter expansion ... but it implies, that in ${.../...},
${...^...} the substitution is expanded after the matching is done.

And about arrays and scalars - well, I'm afraid, this needs revising once more.
Else we simply create one more ad hoc case. What is needed, is clear notion,
when we have "array context" and "scalar context". Then it is possible to
define, when result of substitution is an array and scalar. Currently, there is
only really vague definition of "list of words". I just wish, result of
substitution be better typed.

/andrej


^ permalink raw reply	[flat|nested] 9+ messages in thread

* PATCH: new parameter expansion type?
@ 1999-08-30  9:49 Sven Wischnowsky
  1999-08-30 10:06 ` Andrej Borsenkow
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Sven Wischnowsky @ 1999-08-30  9:49 UTC (permalink / raw)
  To: zsh-workers


This is from `_arguments':

  if [[ "$def" = :* ]]; then
    opt=yes
  else
    opt=''
  fi

... the completion functions are full of these -- always making me
wish that we had some kind of ternary operator in parameter
expansions. The patch below implements this:

  ${name^pattern^then^else}

Gives you the (substituted) `then' string if the expansion of `name'
matches the `pattern' and otherwise it gives you the `else'
string. The first `^' may be doubled to negate the test. `^'s in the
`pattern' and the `then' may be quoted with two bacslashes (as in
`${../..}'). The `^else' may be omitted in which case it expands to
nothing (not even the empty string if you are using this on an array)
if the `pattern' doesn't match. Finally, the `then' and the `else' may 
be only a `.' to make them expand to the original string (needed if
used on arrays).
Ok, the `.' thingy is just because I couldn't think of a better
character/syntax (suggestions?) and this isn't as powerful as I would
like it because `then' and `else' can't expand to arrays. Maybe we
could make `${(A)foo^?^$arr1^$arr2}' do that (and maybe we could do
the same for `${(A)foo:-$arr}'.

But then, maybe you don't like this at all...

Bye
 Sven

--- os/subst.c	Sun Aug 29 20:02:43 1999
+++ Src/subst.c	Sun Aug 29 21:38:14 1999
@@ -725,6 +725,8 @@
     char *sep = NULL, *spsep = NULL;
     char *premul = NULL, *postmul = NULL, *preone = NULL, *postone = NULL;
     char *replstr = NULL;	/* replacement string for /orig/repl */
+    char *thenstr, *elsestr;    /* then and else for ${..^..^..^..} */
+    int negpat = 0;
     zlong prenum = 0, postnum = 0;
     int copied = 0;
     int arrasg = 0;
@@ -1227,7 +1229,8 @@
 		    *s == '%' ||
 		    *s == '#' || *s == Pound ||
 		    *s == '?' || *s == Quest ||
-		    *s == '/')) {
+		    *s == '/' ||
+		    *s == '^' || *s == Hat)) {
 
 	if (!flnum)
 	    flnum++;
@@ -1282,7 +1285,47 @@
 	    untokenize(replstr);
 	    *ptr = '\0';
 	}
+	if (s[-1] == '^' || s[-1] == Hat) {
+	    char *ptr = s;
 
+	    if (*s == s[-1]) {
+		s++;
+		negpat = 1;
+	    }
+	    for (ptr = s; *ptr && *ptr != '^' && *ptr != Hat; ptr++)
+		if (*ptr == '\\' && (ptr[1] == '^' || ptr[1] == Hat))
+		    chuck(ptr);
+	    if (!*ptr || !ptr[1]) {
+		zerr("missing `then' string", NULL, 0);
+		return NULL;
+	    }
+	    *ptr++ = '\0';
+	    thenstr = ptr;
+	    for (; *ptr && *ptr != '^' && *ptr != Hat; ptr++)
+		if (*ptr == '\\' && (ptr[1] == '^' || ptr[1] == Hat))
+		    chuck(ptr);
+	    if (*ptr) {
+		elsestr = ptr + 1;
+		if (elsestr[0] == '\\' && elsestr[1] == '.')
+		    elsestr++;
+		if (elsestr[0] == '.' && !elsestr[1])
+		    elsestr = (char *) 1;
+		else {
+		    singsub(&elsestr);
+		    untokenize(elsestr);
+		}
+		*ptr = '\0';
+	    } else
+		elsestr = NULL;
+	    if (thenstr[0] == '\\' && thenstr[1] == '.')
+		thenstr++;
+	    if (thenstr[0] == '.' && !thenstr[1])
+		thenstr = (char *) 1;
+	    else {
+		singsub(&thenstr);
+		untokenize(thenstr);
+	    }
+	}
 	if (colf)
 	    flags |= SUB_ALL;
 	/*
@@ -1396,6 +1439,8 @@
 	case '#':
 	case Pound:
 	case '/':
+	case '^':
+	case Hat:
 	    if (qt) {
 		int one = noerrs, oef = errflag, haserr;
 
@@ -1417,26 +1462,65 @@
 		char t = s[-1];
 
 		singsub(&s);
-		if (t == '/' && (flags & SUB_SUBSTR)) {
-		    if (*s == '#' || *s == '%') {
-			flags &= ~SUB_SUBSTR;
-			if (*s == '%')
-			    flags |= SUB_END;
-			s++;
-		    } else if (*s == '\\') {
-			s++;
+		if (t == '^' || t == Hat) {
+		    if (!vunset && isarr) {
+			char **ap, **pp;
+			Patprog pprg;
+
+			if (!(pprg = patcompile(s, PAT_STATIC, NULL))) {
+			    zerr("bad pattern: %s", s, 0);
+			    return NULL;
+			}
+			if (!copied)
+			    aval = arrdup(aval), copied = 1;
+			for (ap = pp = aval; *ap; ap++) {
+			    if ((!!pattry(pprg, *ap)) ^ negpat)
+				*pp++ = dupstring(thenstr == ((char *) 1) ?
+						  *ap : thenstr);
+			    else if (elsestr)
+				*pp++ = dupstring(elsestr == ((char *) 1) ?
+						  *ap : elsestr);
+			}
+			*pp = NULL;
+		    } else {
+			Patprog pprg;
+
+			if (vunset)
+			    val = dupstring("");
+			if ((pprg = patcompile(s, PAT_STATIC, NULL)) &&
+			    ((!!pattry(pprg, val)) ^ negpat))
+			    val = dupstring(thenstr == ((char *) 1) ?
+					    val : thenstr);
+			else if (elsestr)
+			    val = dupstring(elsestr == ((char *) 1) ?
+					    val : elsestr);
+			else {
+			    vunset = 1;
+			    val = dupstring("");
+			}
+			copied = 1;
+		    }
+		} else {
+		    if (t == '/' && (flags & SUB_SUBSTR)) {
+			if (*s == '#' || *s == '%') {
+			    flags &= ~SUB_SUBSTR;
+			    if (*s == '%')
+				flags |= SUB_END;
+			    s++;
+			} else if (*s == '\\') {
+			    s++;
+			}
+		    }
+		    if (!vunset && isarr) {
+			getmatcharr(&aval, s, flags, flnum, replstr);
+			copied = 1;
+		    } else {
+			if (vunset)
+			    val = dupstring("");
+			getmatch(&val, s, flags, flnum, replstr);
+			copied = 1;
 		    }
 		}
-	    }
-
-	    if (!vunset && isarr) {
-		getmatcharr(&aval, s, flags, flnum, replstr);
-		copied = 1;
-	    } else {
-		if (vunset)
-		    val = dupstring("");
-		getmatch(&val, s, flags, flnum, replstr);
-		copied = 1;
 	    }
 	    break;
 	}
--- od/Zsh/expn.yo	Sun Aug 29 20:02:39 1999
+++ Doc/Zsh/expn.yo	Sun Aug 29 22:00:54 1999
@@ -447,6 +447,21 @@
 while in the second case, the shortest matches are taken and the
 result is `tt(spy spy lispy star)'.
 )
+xitem(tt(${)var(name)tt(^)var(pattern)tt(^)var(then)tt(^)var(else)tt(}))
+item(tt(${)var(name)tt(^^)var(pattern)tt(^)var(then)tt(^)var(else)tt(}))(
+If the expansion of var(name) matches the var(pattern), the var(then)
+string is substituted, otherwise the var(else) string is
+substituted. In the second form the var(pattern) is taken to be
+negated (even if the tt(EXTENDED_GLOB) option is not set. The
+var(else) string with the preceding `tt(^)' may be omitted in which
+case the expansion behaves as if var(name) were unset (or, if
+var(name) is an array, as if the element compared did not exist). In
+the var(pattern) and the var(then) string a `tt(^)' may be included by 
+preceding it with two backslashes. Finally, the var(then) and
+var(else) string may consist of only a dot to make it expand to the
+original string. To make them expand to only a dot, the string
+`tt(\.)' has to be used.
+)
 item(tt(${#)var(spec)tt(}))(
 If var(spec) is one of the above substitutions, substitute
 the length in characters of the result instead of

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~1999-08-31 17:49 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-08-30 10:38 PATCH: new parameter expansion type? Sven Wischnowsky
1999-08-31 13:18 ` Andrej Borsenkow
  -- strict thread matches above, loose matches on Subject: below --
1999-08-31  8:50 Sven Wischnowsky
1999-08-31 17:47 ` Bart Schaefer
1999-08-30  9:49 Sven Wischnowsky
1999-08-30 10:06 ` Andrej Borsenkow
1999-08-30 10:58 ` Tanaka Akira
1999-08-30 16:05 ` Bart Schaefer
1999-08-30 16:10   ` Peter Stephenson

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).