zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: CHR$(foo) => ${(#)foo}
@ 2005-11-01 14:34 Peter Stephenson
  2005-11-01 14:53 ` Peter Stephenson
  2005-11-01 17:20 ` Bart Schaefer
  0 siblings, 2 replies; 5+ messages in thread
From: Peter Stephenson @ 2005-11-01 14:34 UTC (permalink / raw)
  To: Zsh hackers list

I've always been frustrated that zsh couldn't turn an integer into a
character without some horrible hack like

  eval chr=\$\'\\x${foo[-2,-1]}\'

which assumes $foo contains a hex number.

There are lots of ways of turning a number into a character, but few the
other way round, none that I'm aware of convenient for use in general
substitutions.  This adds the (#) expansion flag to do that.  I couldn't
think of a better syntax, certainly none I was likely to remember.

I deliberately haven't tried to anything more sophisticated than the
printf %c form here.  Handling of multibyte character sets in parameter
substitution will need a lot more thought to do consistently and it
seemed pointless to jump the gun.  (A first guess of how to do would be
that, if the parameter expansion is in multibyte mode, which we don't
have yet, we treat the expression as a Unicode character and output the
same effect as the \U........ print escape.)

Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.56
diff -u -r1.56 expn.yo
--- Doc/Zsh/expn.yo	23 Sep 2005 17:03:17 -0000	1.56
+++ Doc/Zsh/expn.yo	1 Nov 2005 14:25:34 -0000
@@ -632,6 +632,12 @@
 following flags are supported:
 
 startitem()
+item(tt(#))(
+Evaluate the parameter as a numeric expression, joining together array
+elements if necessary, and output the character corresponding to the
+resulting integer.  Note that this form is entirely distinct from
+use of the tt(#) without parentheses.
+)
 item(tt(%))(
 Expand all tt(%) escapes in the resulting words in the same way as in in
 prompts (see noderef(Prompt Expansion)). If this flag is given twice,
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.42
diff -u -r1.42 subst.c
--- Src/subst.c	13 Oct 2005 16:30:14 -0000	1.42
+++ Src/subst.c	1 Nov 2005 14:25:35 -0000
@@ -915,6 +915,10 @@
      */
     int globsubst = isset(GLOBSUBST);
     /*
+     * Indicates ${(#)...}.
+     */
+    int evalchar = 0;
+    /*
      * Indicates ${#pm}, massaged by whichlen which is set by
      * the (c), (w), and (W) flags to indicate how we take the length.
      */
@@ -1320,6 +1324,11 @@
 		    unique = 1;
 		    break;
 
+		case '#':
+		case Pound:
+		    evalchar = 1;
+		    break;
+
 		default:
 		  flagerr:
 		    zerr("error in flags", NULL, 0);
@@ -2233,6 +2242,27 @@
     }
     if (errflag)
 	return NULL;
+    if (evalchar) {
+	/*
+	 * Evaluate the value numerically and output the result as
+	 * a character.
+	 *
+	 * Note this doesn't yet handle Unicode or multibyte characters:
+	 * that will need handling more generally probably by
+	 * an additional flag of some sort.
+	 */
+	zlong ires;
+
+	if (isarr) {
+	    val = sepjoin(aval, sep, 1);
+	    isarr = 0;
+	}
+	ires = mathevali(val);
+	if (errflag)
+	    return NULL;
+	val = zhalloc(2);
+	sprintf(val, "%c", (int)ires);
+    }
     /*
      * This handles taking a length with ${#foo} and variations.
      * TODO: again. one might naively have thought this had the

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


This message has been scanned for viruses by BlackSpider MailControl - www.blackspider.com


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

* Re: PATCH: CHR$(foo) => ${(#)foo}
  2005-11-01 14:34 PATCH: CHR$(foo) => ${(#)foo} Peter Stephenson
@ 2005-11-01 14:53 ` Peter Stephenson
  2005-11-01 17:20 ` Bart Schaefer
  1 sibling, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2005-11-01 14:53 UTC (permalink / raw)
  To: zsh-workers

Peter Stephenson <pws@csr.com> wrote:
> There are lots of ways of turning a number into a character, but few the
> other way round, none that I'm aware of convenient for use in general
> substitutions.  This adds the (#) expansion flag to do that.  I couldn't
> think of a better syntax, certainly none I was likely to remember.

After posting this, I realised that handling arrays element by element was
much more natural (consistent enough with other forms of array processing
that it doesn't need specially documenting).  You can do things like

  % foo=(0x41 0x42 0x43)
  % print ${(#j..)foo}
  ABC

which was what I was trying to do in the first place.

Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.56
diff -u -r1.56 expn.yo
--- Doc/Zsh/expn.yo	23 Sep 2005 17:03:17 -0000	1.56
+++ Doc/Zsh/expn.yo	1 Nov 2005 14:49:12 -0000
@@ -632,6 +632,11 @@
 following flags are supported:
 
 startitem()
+item(tt(#))(
+Evaluate the parameter as a numeric expression and output the character
+corresponding to the resulting integer.  Note that this form is entirely
+distinct from use of the tt(#) without parentheses.
+)
 item(tt(%))(
 Expand all tt(%) escapes in the resulting words in the same way as in in
 prompts (see noderef(Prompt Expansion)). If this flag is given twice,
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.42
diff -u -r1.42 subst.c
--- Src/subst.c	13 Oct 2005 16:30:14 -0000	1.42
+++ Src/subst.c	1 Nov 2005 14:49:15 -0000
@@ -915,6 +915,10 @@
      */
     int globsubst = isset(GLOBSUBST);
     /*
+     * Indicates ${(#)...}.
+     */
+    int evalchar = 0;
+    /*
      * Indicates ${#pm}, massaged by whichlen which is set by
      * the (c), (w), and (W) flags to indicate how we take the length.
      */
@@ -1320,6 +1324,11 @@
 		    unique = 1;
 		    break;
 
+		case '#':
+		case Pound:
+		    evalchar = 1;
+		    break;
+
 		default:
 		  flagerr:
 		    zerr("error in flags", NULL, 0);
@@ -2233,6 +2242,40 @@
     }
     if (errflag)
 	return NULL;
+    if (evalchar) {
+	/*
+	 * Evaluate the value numerically and output the result as
+	 * a character.
+	 *
+	 * Note this doesn't yet handle Unicode or multibyte characters:
+	 * that will need handling more generally probably by
+	 * an additional flag of some sort.
+	 */
+	zlong ires;
+
+	if (isarr) {
+	    char **aval2, **avptr, **av2ptr;
+
+	    aval2 = (char **)zhalloc((arrlen(aval)+1)*sizeof(char *));
+
+	    for (avptr = aval, av2ptr = aval2; *avptr; avptr++, av2ptr++)
+	    {
+		ires = mathevali(*avptr);
+		if (errflag)
+		    return NULL;
+		*av2ptr = zhalloc(2);
+		sprintf(*av2ptr, "%c", (int)ires);
+	    }
+	    *av2ptr = NULL;
+	    aval = aval2;
+	} else {
+	    ires = mathevali(val);
+	    if (errflag)
+		return NULL;
+	    val = zhalloc(2);
+	    sprintf(val, "%c", (int)ires);
+	}
+    }
     /*
      * This handles taking a length with ${#foo} and variations.
      * TODO: again. one might naively have thought this had the


-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


This message has been scanned for viruses by BlackSpider MailControl - www.blackspider.com


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

* Re: PATCH: CHR$(foo) => ${(#)foo}
  2005-11-01 14:34 PATCH: CHR$(foo) => ${(#)foo} Peter Stephenson
  2005-11-01 14:53 ` Peter Stephenson
@ 2005-11-01 17:20 ` Bart Schaefer
  2005-11-01 17:46   ` Peter Stephenson
  1 sibling, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2005-11-01 17:20 UTC (permalink / raw)
  To: Zsh hackers list

On Nov 1,  2:34pm, Peter Stephenson wrote:
}
} There are lots of ways of turning a number into a character, but few the
} other way round

Don't you mean "lots of ways of turning a character into a number"?  What
you added is a way to turn a number into a character.

} This adds the (#) expansion flag to do that.

So we now have

        ${#x}           Number of characters in x
        $((#x))         Number of the first character in x
        ${(#)x}         Character of the number in x

and the oddball

        $((##x))        Number of the character 'x'

I suppose that means that

        ${(#)#x}        Number of characters in the
                        character of the number in x     (i.e., 1)
    $((##${(#)${#x}}))  Number of the character of
                        the number of characters in x

There doesn't seem to be a way to get the number of characters in the
number of the character of the number in x.  Hmm.


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

* Re: PATCH: CHR$(foo) => ${(#)foo}
  2005-11-01 17:20 ` Bart Schaefer
@ 2005-11-01 17:46   ` Peter Stephenson
  2005-11-01 18:17     ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2005-11-01 17:46 UTC (permalink / raw)
  To: Zsh hackers list

Bart Schaefer wrote:
> On Nov 1,  2:34pm, Peter Stephenson wrote:
> }
> } There are lots of ways of turning a number into a character, but few the
> } other way round
> 
> Don't you mean "lots of ways of turning a character into a number"?  What
> you added is a way to turn a number into a character.

Probably, yes.

> So we now have

Er, there wasn't anything here I was supposed to take account of, was
there?

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


This message has been scanned for viruses by BlackSpider MailControl - www.blackspider.com


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

* Re: PATCH: CHR$(foo) => ${(#)foo}
  2005-11-01 17:46   ` Peter Stephenson
@ 2005-11-01 18:17     ` Bart Schaefer
  0 siblings, 0 replies; 5+ messages in thread
From: Bart Schaefer @ 2005-11-01 18:17 UTC (permalink / raw)
  To: Zsh hackers list

On Nov 1,  5:46pm, Peter Stephenson wrote:
}
} Er, there wasn't anything here I was supposed to take account of, was
} there?

No ... I was just streaming my consciousness.

Unless maybe you feel like writing a FAQ entry.


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

end of thread, other threads:[~2005-11-01 18:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-01 14:34 PATCH: CHR$(foo) => ${(#)foo} Peter Stephenson
2005-11-01 14:53 ` Peter Stephenson
2005-11-01 17:20 ` Bart Schaefer
2005-11-01 17:46   ` Peter Stephenson
2005-11-01 18:17     ` Bart Schaefer

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