zsh-workers
 help / color / mirror / code / Atom feed
* echoti and number of arguments
@ 2003-05-17  8:01 Stephane CHAZELAS
  2003-05-17  8:34 ` Stephane CHAZELAS
  2003-05-19 10:28 ` Peter Stephenson
  0 siblings, 2 replies; 5+ messages in thread
From: Stephane CHAZELAS @ 2003-05-17  8:01 UTC (permalink / raw)
  To: Zsh hackers list

I've noticed that the number of arguments was checked with
echoti. It's not a good idea.

Mainly because it's hard or even impossible to guess that number
from the terminfo string. For instance, "sgr" accepts 9
parameters, but terminals don't all support the 9 fields (for
instance, xterm-r5 has:
sgr=\E[%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p6%t;1%;m,
only fields 1 to 6 are supported, but it's valid to pass 9
parameters).

If you look at how ncurses' tput works: if no argument is
passed, the string is returned asis; if at least one argument is
provided, % escape sequences are handled, and 9 parameters are
used (if some are used but not provided, they default to 0 or ""
depending on their type).

Then, the way the argument count is checked in zsh is nonsense:

  /* count the number of arguments required */
  for (argct = 0, u = t; *u; u++)
      if (*u == '%') {
          if (u++, (*u == 'd' || *u == '2' || *u == '3' || *u == '.' ||
                    *u == '+'))
              argct++;
      }

Those flags have nothing to do with the argument count. %d may
be provided twice even when there's only one argument. For
instance, setf on xterm-16color has two %d but takes only one
argument, u6 (cursor position report) has two %d but doesn't
take any argument. sgr takes 9 arguments but argct above would
be zero.

>From terminfo(5):

   %%        outputs `%'
   %[[:]flags][width[.precision]][doxXs]
             as in printf, flags are [-+#] and space
   %c        print pop() like %c in printf()
   %s        print pop() like %s in printf()

   %p[1-9]   push i'th parm
   %P[a-z]   set dynamic variable [a-z] to pop()
   %g[a-z]   get dynamic variable [a-z] and push it
   %P[A-Z]   set static variable [a-z] to pop()
   %g[A-Z]   get static variable [a-z] and push it
   %'c'      char constant c
   %{nn}     integer constant nn
   %l        push strlen(pop)

   %+ %- %* %/ %m
             arithmetic (%m is mod): push(pop() op pop())
   %& %| %^  bit operations: push(pop() op pop())
   %= %> %<  logical operations: push(pop() op pop())
   %A, %O    logical and & or operations (for conditionals)
   %! %~     unary operations push(op pop())
   %i        add 1 to first two parameters (for ANSI terminals)

   %? expr %t thenpart %e elsepart %;
             if-then-else, %e elsepart is optional.
             else-if's are possible a la Algol 68:
             %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e %;
             ci are conditions, bi are bodies.

So, to my mind, echoti should only check that there are no more
than 9 parameters.

-- 
Stéphane


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

* Re: echoti and number of arguments
  2003-05-17  8:01 echoti and number of arguments Stephane CHAZELAS
@ 2003-05-17  8:34 ` Stephane CHAZELAS
  2003-05-19 10:28 ` Peter Stephenson
  1 sibling, 0 replies; 5+ messages in thread
From: Stephane CHAZELAS @ 2003-05-17  8:34 UTC (permalink / raw)
  To: Zsh hackers list

On Sat, May 17, 2003 at 10:01:16AM +0200, Stephane CHAZELAS wrote:
[...]
> Then, the way the argument count is checked in zsh is nonsense:
> 
>   /* count the number of arguments required */
>   for (argct = 0, u = t; *u; u++)
>       if (*u == '%') {
>           if (u++, (*u == 'd' || *u == '2' || *u == '3' || *u == '.' ||
>                     *u == '+'))
>               argct++;
>       }
[...]

I get it, it was copied from the termcap one. terminfo and
termcap escape handling are totally different.

-- 
Stéphane


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

* Re: echoti and number of arguments
  2003-05-17  8:01 echoti and number of arguments Stephane CHAZELAS
  2003-05-17  8:34 ` Stephane CHAZELAS
@ 2003-05-19 10:28 ` Peter Stephenson
  2003-05-19 14:51   ` Stephane CHAZELAS
  1 sibling, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2003-05-19 10:28 UTC (permalink / raw)
  To: Zsh hackers list

Stephane CHAZELAS wrote:
> I've noticed that the number of arguments was checked with
> echoti. It's not a good idea.

I think we need a configure test to make sure tparm() can take nine
arguments to make sure we don't get into compatibility problems.  That
will depend on various curses-style things, c.f terminfo.mdd.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR Ltd., Science Park, Milton Road,
Cambridge, CB4 0WH, UK                          Tel: +44 (0)1223 692070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************


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

* Re: echoti and number of arguments
  2003-05-19 10:28 ` Peter Stephenson
@ 2003-05-19 14:51   ` Stephane CHAZELAS
  2003-06-24 18:04     ` PATCH: " Oliver Kiddle
  0 siblings, 1 reply; 5+ messages in thread
From: Stephane CHAZELAS @ 2003-05-19 14:51 UTC (permalink / raw)
  To: Zsh hackers list

On Mon, May 19, 2003 at 11:28:05AM +0100, Peter Stephenson wrote:
> Stephane CHAZELAS wrote:
> > I've noticed that the number of arguments was checked with
> > echoti. It's not a good idea.
> 
> I think we need a configure test to make sure tparm() can take nine
> arguments to make sure we don't get into compatibility problems.  That
> will depend on various curses-style things, c.f terminfo.mdd.

More than that, tparm can take 0 to 9 parameters, which can be
of type "int" or "char*" and it's the responsability of the
caller to provide enough arguments and of the right type.

For instance

TERM=hpterm echoti pfx 1 "test"

Should call

tputs(tparm(tigetstr("pfx"), 1, "test"),1,putraw)

and to know that the second parameter is not a number, well, two
approaches:

1- parse tigetstr("pfx") => hard to do and redondant with
   what tparm() already does.

2- hard code the few existing capabilities that accept
   non-integers (that's what ncurses' tput(1) does using this
   table:
	TD(Num_Str,     "pkey_key",     "pfkey",        "pk"),
        TD(Num_Str,     "pkey_local",   "pfloc",        "pl"),
        TD(Num_Str,     "pkey_xmit",    "pfx",          "px"),
        TD(Num_Str,     "plab_norm",    "pln",          "pn"),
        TD(Num_Str_Str, "pkey_plab",    "pfxl",         "xl"),   
   The problem with that approach is the lack of extensibility.
   But, for the probably limited usage of echoti in zsh, that's
   probably far enough (and there already are hardcoded capnames
   in Modules/terminfo.c).
   
For other capabilities, tparm() should be called with 9 numeric
arguments (non-provided ones defaulting to 0).

Note that actually zsh's "bin_echoti" is quite bogus. I've spent
several minutes wondering how the 
"tputs(tparm(t, atoi(*argv)), num, putraw)" could work with
"cup" while we are actually passing only one parameter to
tparm(). It seems to be due to some side effect of the va_list
processing (I guess tparm() actually takes "num" as its second
parameter somewhere on some stack), if I change it to
z= tparm(t, atoi(*argv)); tputs(z, num, putraw), it doesn't work
anymore.

Note that there are problems with echotc too when libtermcap is
ncurses. For instance, when you do a tgetstr("AB"), you actually
get the terminfo entry for "setab", in terminfo format. So, the
routine used to count the number of expected arguments doesn't
work either (as you don't have a termcap format). Note that
tcsh's echotc is fooled on that one too.

$ echotc AB 1
echotc: not enough arguments

(my setab is \E[%?%p1%{8}%<%t%p1%'('%+%e%p1%{92}%+%;%dm, which
anyway cannot be mapped to termcap format).

-- 
Stéphane


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

* PATCH: Re: echoti and number of arguments
  2003-05-19 14:51   ` Stephane CHAZELAS
@ 2003-06-24 18:04     ` Oliver Kiddle
  0 siblings, 0 replies; 5+ messages in thread
From: Oliver Kiddle @ 2003-06-24 18:04 UTC (permalink / raw)
  To: Zsh hackers list; +Cc: Stephane CHAZELAS, Tomi.Vainio

This patch does basically as suggested in 18551, replacing the quick
fix I sent earlier. I've taken the second approach of hard coding the
list of five capabilities that accept non-integers as parameters. First
parameter is taken to be integer and any others a string.

I've also tried using putp() instead of tputs() to get rid of the
compiler warnings. We can always revert that if any problems crop up.
Anyway, this works on Solaris (32 and 64-bit) and Linux.

Oliver

Index: Src/Modules/terminfo.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/terminfo.c,v
retrieving revision 1.20
diff -u -r1.20 terminfo.c
--- Src/Modules/terminfo.c	25 Mar 2003 05:33:29 -0000	1.20
+++ Src/Modules/terminfo.c	24 Jun 2003 17:39:03 -0000
@@ -59,8 +59,10 @@
 static int
 bin_echoti(char *name, char **argv, Options ops, int func)
 {
-    char *s, *t, *u;
-    int num, argct;
+    char *s, *t, **u;
+    int arg, num, strarg = 0;
+    long pars[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+    char *strcap[] = { "pfkey", "pfloc", "pfx", "pln", "pfxl", NULL };
 
     s = *argv++;
     /* This depends on the termcap stuff in init.c */
@@ -92,28 +94,32 @@
 	zwarnnam(name, "no such terminfo capability: %s", s, 0);
 	return 1;
     }
-    /* count the number of arguments required */
-    for (argct = 0, u = t; *u; u++)
-        if (*u == '%') {
-            if (u++, (*u == 'd' || *u == '2' || *u == '3' || *u == '.' ||
-                      *u == '+'))
-                argct++;
-        }
-    /* check that the number of arguments provided is correct */
-    if (arrlen(argv) != argct) {
-        zwarnnam(name, (arrlen(argv) < argct) ? "not enough arguments" :
-                 "too many arguments", NULL, 0);
+    /* check that the number of arguments provided is not too high */
+    if (arrlen(argv) > 9) {
+        zwarnnam(name, "too many arguments", NULL, 0);
         return 1;
     }
+
+    /* check if we have a capability taking non-integers for parameters */
+    for (u = strcap; *u && !strarg; u++)
+      strarg = !strcmp(s, *u);
+
+    /* get the arguments */
+    for (arg=0; argv[arg]; arg++) {
+	if (strarg && arg > 0)
+            pars[arg] = (long) argv[arg];
+	else
+            pars[arg] = atoi(argv[arg]);
+    }
+
     /* output string, through the proper termcap functions */
-    if (!argct)
-        tputs(t, 1, putraw);
+    if (!arg)
+        putp(t);
     else {
-        num = (argv[1]) ? atoi(argv[1]) : atoi(*argv);
-        tputs(tparm(t, atoi(*argv)), num, putraw);
+        putp(tparm(t, pars[0], pars[1], pars[2], pars[3], pars[4],
+	              pars[5], pars[6], pars[7], pars[8]));
     }
     return 0;
-
 }
 
 /**/

________________________________________________________________________
This email has been scanned for all viruses by the MessageLabs Email
Security System. For more information on a proactive email security
service working around the clock, around the globe, visit
http://www.messagelabs.com
________________________________________________________________________


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

end of thread, other threads:[~2003-06-24 18:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-17  8:01 echoti and number of arguments Stephane CHAZELAS
2003-05-17  8:34 ` Stephane CHAZELAS
2003-05-19 10:28 ` Peter Stephenson
2003-05-19 14:51   ` Stephane CHAZELAS
2003-06-24 18:04     ` PATCH: " Oliver Kiddle

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