zsh-workers
 help / color / mirror / code / Atom feed
* RE: PATCH: 3.1.5-pws-4: typeset fix
@ 1999-01-14 17:53 Amol Deshpande
  1999-01-15 12:35 ` PATCH: 3.0.5: " Peter Stephenson
  0 siblings, 1 reply; 6+ messages in thread
From: Amol Deshpande @ 1999-01-14 17:53 UTC (permalink / raw)
  To: zsh-workers, 'Peter Stephenson'

is there a simple fix that will work for 3.0.5 ?
thanks,
-amol

> ----------
> From: 	Peter Stephenson[SMTP:pws@ibmth.df.unipi.it]
> Sent: 	Thursday, January 14, 1999 7:25 AM
> To: 	zsh-workers@math.gatech.edu
> Subject: 	PATCH: 3.1.5-pws-4: typeset fix
> 
> "Bart Schaefer" wrote:
> > Haven't looked into it any farther yet, but run zsh -f and then (where
> the
> > name "variable" can be any parameter that is not already set):
> > 
> > zsh% typeset -i variable
> > zsh% typeset -m +i variable
> > zsh% echo $variable
> > 
> > and kablooey.
> 
> Right, that's it.  I know how attached everyone is to the old typeset
> code, but I've finally decided to rewrite it so that it's *gasp*
> almost readable.  So far, I haven't done much else to it, though there
> are probably other rationalisations which could now be added.
> 
> Known changes include:
> 
> - typeset -m behaviour is now identical to the behaviour without the
> m, with the exception that restricted variables are silently ignored
> if necessary (this is what happened before).  There was an additional
> bug hidden here, in that the sequences of commands above, changing
> `variable' from integer to non-integer, could alter the parameter
> table, so it now makes a list of parameters while scanning the table,
> and runs through it later.
> 
> - I removed the restriction on creating array variables (with -a).
> You get an error message if you try to set the array as well.  I
> can't see any problem apart from that.
> 
> - I also de-dangled some else's.
> 
> *** Doc/Zsh/builtins.yo.typeset	Thu Dec 17 17:10:13 1998
> --- Doc/Zsh/builtins.yo	Thu Jan 14 16:19:39 1999
> ***************
> *** 947,955 ****
>   first assignment.
>   )
>   item(tt(-a))(
> ! The names refer to array parameters.  For historical reasons, scalar
> ! parameters are created even when this flag is specified, but the
> ! output is restricted to arrays (including associative arrays).
>   )
>   item(tt(-f))(
>   The names refer to functions rather than parameters.  No assignments
> --- 947,956 ----
>   first assignment.
>   )
>   item(tt(-a))(
> ! The names refer to array parameters.  An array parameter may be
> ! created this way, but it may not be assigned to in the tt(typeset)
> ! statement.  When displaying, both normal and associative arrays are
> ! shown.
>   )
>   item(tt(-f))(
>   The names refer to functions rather than parameters.  No assignments
> *** Src/builtin.c.typeset	Thu Dec 17 12:17:04 1998
> --- Src/builtin.c	Thu Jan 14 15:55:34 1999
> ***************
> *** 1224,1236 ****
>   		if (!editor)
>   		    editor = DEFAULT_FCEDIT;
>   
> ! 		if (fcedit(editor, fil))
>   		    if (stuff(fil))
>   			zwarnnam("fc", "%e: %s", s, errno);
>   		    else {
>   			loop(0,1);
>   			retval = lastval;
>   		    }
>   	    }
>   	}
>   	unlink(fil);
> --- 1224,1237 ----
>   		if (!editor)
>   		    editor = DEFAULT_FCEDIT;
>   
> ! 		if (fcedit(editor, fil)) {
>   		    if (stuff(fil))
>   			zwarnnam("fc", "%e: %s", s, errno);
>   		    else {
>   			loop(0,1);
>   			retval = lastval;
>   		    }
> + 		}
>   	    }
>   	}
>   	unlink(fil);
> ***************
> *** 1464,1469 ****
> --- 1465,1581 ----
>       return &asg;
>   }
>   
> + /* function to set a single parameter */
> + 
> + /**/
> + int
> + typeset_single(char *cname, char *pname, Param pm, int func,
> + 	       int on, int off, int roff, char *value)
> + {
> +     int usepm, tc;
> + 
> +     /* use the existing pm? */
> +     usepm = pm && !(pm->flags & PM_UNSET);
> + 
> +     /* Always use an existing pm if special at current locallevel */
> +     if (pm && (pm->flags & PM_SPECIAL) && pm->level == locallevel)
> + 	usepm = 1;
> + 
> +     /*
> +      * Don't use a non-special existing param if
> +      *   - the local level has changed, and
> +      *   - the function is not `export'.
> +      */
> +     if (usepm && !(pm->flags & PM_SPECIAL) &&
> + 	locallevel != pm->level && func != BIN_EXPORT)
> + 	usepm = 0;
> + 
> +     /* attempting a type conversion? */
> +     if ((tc = usepm && (((off & pm->flags) | (on & ~pm->flags)) &
> + 			(PM_INTEGER|PM_HASHED|PM_ARRAY))))
> + 	usepm = 0;
> +     if (tc && (pm->flags & PM_SPECIAL)) {
> + 	zerrnam(cname, "%s: can't change type of a special parameter",
> + 		pname, 0);
> + 	return 1;
> +     }
> + 
> +     if (usepm) {
> + 	if (!on && !roff && !value) {
> + 	    paramtab->printnode((HashNode)pm, 0);
> + 	    return 0;
> + 	}
> + 	if ((pm->flags & PM_RESTRICTED && isset(RESTRICTED))) {
> + 	    zerrnam(cname, "%s: restricted", pname, 0);
> + 	    return 1;
> + 	}
> + 	if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
> + 	    !(pm->flags & PM_READONLY & ~off))
> + 	    uniqarray((*pm->gets.afn) (pm));
> + 	pm->flags = (pm->flags | on) & ~off;
> + 	/* This auxlen/pm->ct stuff is a nasty hack. */
> + 	if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) &&
> + 	    auxlen)
> + 	    pm->ct = auxlen;
> + 	if (!(pm->flags & (PM_ARRAY|PM_HASHED))) {
> + 	    if (pm->flags & PM_EXPORTED) {
> + 		if (!(pm->flags & PM_UNSET) && !pm->env && !value)
> + 		    pm->env = addenv(pname, getsparam(pname));
> + 	    } else if (pm->env) {
> + 		delenv(pm->env);
> + 		zsfree(pm->env);
> + 		pm->env = NULL;
> + 	    }
> + 	    if (value)
> + 		setsparam(pname, ztrdup(value));
> + 	} else if (value) {
> + 	    zwarnnam(cname, "can't assign new value for array %s", pname,
> 0);
> + 	    return 1;
> + 	}
> + 	return 0;
> +     }
> + 
> +     /*
> +      * We're here either because we're creating a new parameter,
> +      * or we're adding a parameter at a different local level,
> +      * or we're converting the type of a parameter.  In the
> +      * last case only, we need to delete the old parameter.
> +      */
> +     if (tc) {
> + 	if (pm->flags & PM_READONLY) {
> + 	    on |= ~off & PM_READONLY;
> + 	    pm->flags &= ~PM_READONLY;
> + 	}
> + 	/*
> + 	 * Try to carry over a value, but not when changing from,
> + 	 * to, or between non-scalar types.
> + 	 */
> + 	if (!value && !((pm->flags|on) & (PM_ARRAY|PM_HASHED)))
> + 	    value = dupstring(getsparam(pname));
> + 	/* pname may point to pm->nam which is about to disappear */
> + 	pname = dupstring(pname);
> + 	unsetparam_pm(pm, 0, 1);
> +     }
> +     /*
> +      * Create a new node for a parameter with the flags in `on' minus
> the
> +      * readonly flag
> +      */
> +     pm = createparam(ztrdup(pname), on & ~PM_READONLY);
> +     DPUTS(!pm, "BUG: parameter not created");
> +     pm->ct = auxlen;
> +     if (func != BIN_EXPORT)
> + 	pm->level = locallevel;
> +     if (value && !(pm->flags & (PM_ARRAY|PM_HASHED)))
> + 	setsparam(pname, ztrdup(value));
> +     pm->flags |= (on & PM_READONLY);
> +     if (value && (pm->flags & (PM_ARRAY|PM_HASHED))) {
> + 	zerrnam(cname, "%s: can't assign initial value for array", pname,
> 0);
> + 	return 1;
> +     }
> + 
> +     return 0;
> + }
> + 
>   /* declare, export, integer, local, readonly, typeset */
>   
>   /**/
> ***************
> *** 1475,1481 ****
>       Comp com;
>       char *optstr = "aiALRZlurtxU";
>       int on = 0, off = 0, roff, bit = PM_ARRAY;
> !     int initon, initoff, of, i;
>       int returnval = 0, printflags = 0;
>   
>       /* hash -f is really the builtin `functions' */
> --- 1587,1593 ----
>       Comp com;
>       char *optstr = "aiALRZlurtxU";
>       int on = 0, off = 0, roff, bit = PM_ARRAY;
> !     int i;
>       int returnval = 0, printflags = 0;
>   
>       /* hash -f is really the builtin `functions' */
> ***************
> *** 1521,1527 ****
> --- 1633,1643 ----
>   
>       /* With the -m option, treat arguments as glob patterns */
>       if (ops['m']) {
> + 	MUSTUSEHEAP("typeset -m");
>   	while ((asg = getasg(*argv++))) {
> + 	    LinkList pmlist = newlinklist();
> + 	    LinkNode pmnode;
> + 
>   	    tokenize(asg->name);   /* expand argument */
>   	    if (!(com = parsereg(asg->name))) {
>   		untokenize(asg->name);
> ***************
> *** 1529,1671 ****
>   		returnval = 1;
>   		continue;
>   	    }
> ! 	    /* If no options or values are given, display all *
> ! 	     * parameters matching the glob pattern.          */
> ! 	    if (!(on || roff || asg->value)) {
> ! 		scanmatchtable(paramtab, com, 0, 0, paramtab->printnode, 0);
> ! 		continue;
> ! 	    }
> ! 	    /* Since either options or values are given, we search   *
> ! 	     * through the parameter table and change all parameters *
> ! 	     * matching the glob pattern to have these flags and/or  *
> ! 	     * value.                                                */
>   	    for (i = 0; i < paramtab->hsize; i++) {
> ! 		for (pm = (Param) paramtab->nodes[i]; pm; pm = (Param)
> pm->next) {
>   		    if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED))
>   			continue;
> ! 		    if (domatch(pm->nam, com, 0)) {
> ! 			/* set up flags if we have any */
> ! 			if (on || roff) {
> ! 			    if (PM_TYPE(pm->flags) == PM_ARRAY && (on &
> PM_UNIQUE) &&
> ! 				!(pm->flags & PM_READONLY & ~off))
> ! 				uniqarray((*pm->gets.afn) (pm));
> ! 			    if ((on & ~pm->flags) & PM_HASHED) {
> ! 				char *nam = ztrdup(pm->nam);
> ! 				unsetparam(nam);
> ! 				pm = createparam(nam, on & ~PM_READONLY);
> ! 				DPUTS(!pm, "BUG: parameter not created");
> ! 			    }
> ! 			    pm->flags = (pm->flags | on) & ~off;
> ! 			    if (PM_TYPE(pm->flags) != PM_ARRAY &&
> ! 				PM_TYPE(pm->flags) != PM_HASHED) {
> ! 				if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z
> | PM_INTEGER)) && auxlen)
> ! 				    pm->ct = auxlen;
> ! 				/* did we just export this? */
> ! 				if ((pm->flags & PM_EXPORTED) && !pm->env) {
> ! 				    pm->env = addenv(pm->nam, (asg->value) ?
> asg->value : getsparam(pm->nam));
> ! 				} else if (!(pm->flags & PM_EXPORTED) &&
> pm->env) {
> ! 				/* did we just unexport this? */
> ! 				    delenv(pm->env);
> ! 				    zsfree(pm->env);
> ! 				    pm->env = NULL;
> ! 				}
> ! 			    }
> ! 			}
> ! 			/* set up a new value if given */
> ! 			if (asg->value) {
> ! 			    setsparam(pm->nam, ztrdup(asg->value));
> ! 			}
> ! 		    }
>   		}
>   	    }
>   	}
>   	return returnval;
>       }
>   
> -     /* Save the values of on, off, and func */
> -     initon = on;
> -     initoff = off;
> -     of = func;
> - 
>       /* Take arguments literally.  Don't glob */
>       while ((asg = getasg(*argv++))) {
> - 	/* restore the original values of on, off, and func */
> - 	on = initon;
> - 	off = initoff;
> - 	func = of;
> - 	on &= ~PM_ARRAY;
> - 
>   	/* check if argument is a valid identifier */
>   	if (!isident(asg->name)) {
>   	    zerr("not an identifier: %s", asg->name, 0);
>   	    returnval = 1;
>   	    continue;
>   	}
> ! 	bit = 0;    /* flag for switching int<->not-int */
> ! 	if ((pm = (Param)paramtab->getnode(paramtab, asg->name)) &&
> ! 	    (((pm->flags & PM_SPECIAL) && pm->level == locallevel) ||
> ! 	     (!(pm->flags & PM_UNSET) &&
> ! 	      ((locallevel == pm->level) || func == BIN_EXPORT) &&
> ! 	      !(bit = (((off & pm->flags) | (on & ~pm->flags)) &
> ! 		       (PM_INTEGER|PM_HASHED)))))) {
> ! 	    /* if no flags or values are given, just print this parameter */
> ! 	    if (!on && !roff && !asg->value) {
> ! 		paramtab->printnode((HashNode) pm, 0);
> ! 		continue;
> ! 	    }
> ! 	    if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED)) {
> ! 		zerrnam(name, "%s: restricted", pm->nam, 0);
> ! 		returnval = 1;
> ! 		continue;
> ! 	    }
> ! 	    if((pm->flags & PM_SPECIAL) &&
> ! 	       PM_TYPE((pm->flags | on) & ~off) != PM_TYPE(pm->flags)) {
> ! 		zerrnam(name, "%s: cannot change type of a special
> parameter",
> ! 		    pm->nam, 0);
> ! 		returnval = 1;
> ! 		continue;
> ! 	    }
> ! 	    if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
> ! 		!(pm->flags & PM_READONLY & ~off))
> ! 		uniqarray((*pm->gets.afn) (pm));
> ! 	    pm->flags = (pm->flags | on) & ~off;
> ! 	    if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) &&
> ! 		auxlen)
> ! 		pm->ct = auxlen;
> ! 	    if (PM_TYPE(pm->flags) != PM_ARRAY &&
> ! 		PM_TYPE(pm->flags) != PM_HASHED) {
> ! 		if (pm->flags & PM_EXPORTED) {
> ! 		    if (!(pm->flags & PM_UNSET) && !pm->env && !asg->value)
> ! 			pm->env = addenv(asg->name, getsparam(asg->name));
> ! 		} else if (pm->env) {
> ! 		    delenv(pm->env);
> ! 		    zsfree(pm->env);
> ! 		    pm->env = NULL;
> ! 		}
> ! 		if (asg->value)
> ! 		    setsparam(asg->name, ztrdup(asg->value));
> ! 	    }
> ! 	} else {
> ! 	    if (bit) {
> ! 		if (pm->flags & PM_READONLY) {
> ! 		    on |= ~off & PM_READONLY;
> ! 		    pm->flags &= ~PM_READONLY;
> ! 		}
> ! 		if (!asg->value)
> ! 		    asg->value = dupstring(getsparam(asg->name));
> ! 		unsetparam(asg->name);
> ! 	    }
> ! 	    /* create a new node for a parameter with the *
> ! 	     * flags in `on' minus the readonly flag      */
> ! 	    pm = createparam(ztrdup(asg->name), on & ~PM_READONLY);
> ! 	    DPUTS(!pm, "BUG: parameter not created");
> ! 	    pm->ct = auxlen;
> ! 	    if (func != BIN_EXPORT)
> ! 		pm->level = locallevel;
> ! 	    if (asg->value)
> ! 		setsparam(asg->name, ztrdup(asg->value));
> ! 	    pm->flags |= (on & PM_READONLY);
> ! 	}
>       }
>       return returnval;
>   }
> --- 1645,1689 ----
>   		returnval = 1;
>   		continue;
>   	    }
> ! 	    /*
> ! 	     * Search through the parameter table and change all parameters
> ! 	     * matching the glob pattern to have these flags and/or value.
> ! 	     * Bad news:  if the parameter gets altered, e.g. by
> ! 	     * a type conversion, then paramtab can be shifted around,
> ! 	     * so we need to store the parameters to alter on a separate
> ! 	     * list for later use.	     
> ! 	     */
>   	    for (i = 0; i < paramtab->hsize; i++) {
> ! 		for (pm = (Param) paramtab->nodes[i]; pm;
> ! 		     pm = (Param) pm->next) {
>   		    if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED))
>   			continue;
> ! 		    if (domatch(pm->nam, com, 0))
> ! 			addlinknode(pmlist, pm);
>   		}
>   	    }
> + 	    for (pmnode = firstnode(pmlist); pmnode; incnode(pmnode)) {
> + 		pm = (Param) getdata(pmnode);
> + 		if (typeset_single(name, pm->nam, pm, func, on, off, roff,
> + 				   asg->value))
> + 		    returnval = 1;
> + 	    }
>   	}
>   	return returnval;
>       }
>   
>       /* Take arguments literally.  Don't glob */
>       while ((asg = getasg(*argv++))) {
>   	/* check if argument is a valid identifier */
>   	if (!isident(asg->name)) {
>   	    zerr("not an identifier: %s", asg->name, 0);
>   	    returnval = 1;
>   	    continue;
>   	}
> ! 	if (typeset_single(name, asg->name,
> ! 			   (Param)paramtab->getnode(paramtab, asg->name),
> ! 			   func, on, off, roff, asg->value))
> ! 	    returnval = 1;
>       }
>       return returnval;
>   }
> ***************
> *** 2778,2785 ****
>   		LASTALLOC_RETURN;
>   	    }
>   	}
> ! 	if (in_exit++ && from_signal)
>   	    LASTALLOC_RETURN;
>   	if (isset(MONITOR))
>   	    /* send SIGHUP to any jobs left running  */
>   	    killrunjobs(from_signal);
> --- 2796,2804 ----
>   		LASTALLOC_RETURN;
>   	    }
>   	}
> ! 	if (in_exit++ && from_signal) {
>   	    LASTALLOC_RETURN;
> + 	}
>   	if (isset(MONITOR))
>   	    /* send SIGHUP to any jobs left running  */
>   	    killrunjobs(from_signal);
> ***************
> *** 3181,3193 ****
>   	    }
>   	    if (c == EOF || (c == '\n' && !zbuf))
>   		break;
> ! 	    if (!bslash && isep(c) && bptr == buf)
>   		if (iwsep(c))
>   		    continue;
>   		else if (!first) {
>   		    first = 1;
>   		    continue;
>   		}
>   	    bslash = c == '\\' && !bslash && !ops['r'];
>   	    if (bslash)
>   		continue;
> --- 3200,3213 ----
>   	    }
>   	    if (c == EOF || (c == '\n' && !zbuf))
>   		break;
> ! 	    if (!bslash && isep(c) && bptr == buf) {
>   		if (iwsep(c))
>   		    continue;
>   		else if (!first) {
>   		    first = 1;
>   		    continue;
>   		}
> + 	    }
>   	    bslash = c == '\\' && !bslash && !ops['r'];
>   	    if (bslash)
>   		continue;
> ***************
> *** 3240,3246 ****
>       char cc, retry = 0;
>   
>       /* use zbuf if possible */
> !     if (zbuf)
>   	/* If zbuf points to anything, it points to the next character in
> the
>   	buffer.  This may be a null byte to indicate EOF.  If reading from
> the
>   	buffer, move on the buffer pointer. */
> --- 3260,3266 ----
>       char cc, retry = 0;
>   
>       /* use zbuf if possible */
> !     if (zbuf) {
>   	/* If zbuf points to anything, it points to the next character in
> the
>   	buffer.  This may be a null byte to indicate EOF.  If reading from
> the
>   	buffer, move on the buffer pointer. */
> ***************
> *** 3248,3253 ****
> --- 3268,3274 ----
>   	    return zbuf++, STOUC(*zbuf++ ^ 32);
>   	else
>   	    return (*zbuf) ? STOUC(*zbuf++) : EOF;
> +     }
>       for (;;) {
>   	/* read a character from readfd */
>   	switch (read(readfd, &cc, 1)) {
> 
> -- 
> 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] 6+ messages in thread

* PATCH: 3.0.5: typeset fix
  1999-01-14 17:53 PATCH: 3.1.5-pws-4: typeset fix Amol Deshpande
@ 1999-01-15 12:35 ` Peter Stephenson
  1999-01-15 16:35   ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Stephenson @ 1999-01-15 12:35 UTC (permalink / raw)
  To: zsh-workers

Amol Deshpande wrote:
> is there a simple fix that will work for 3.0.5 ?

I don't think so, because using the same code with and without -m
requires something of a rewrite.  This patch does that.  The logic is
different in 3.0.5 but I haven't changed it except expanding out the
long test like I did before.  For some reason 3.1.5 looks more like
the pre-3 code I remember.  There are no changes in the features this
time.

*** Src/builtin.c.typeset	Fri Sep 26 03:42:15 1997
--- Src/builtin.c	Fri Jan 15 13:26:58 1999
***************
*** 2788,2793 ****
--- 2788,2900 ----
  
  /**** parameter builtins ****/
  
+ /* function to set a single parameter */
+ 
+ /**/
+ int
+ typeset_single(char *cname, char *pname, Param pm, int func, int on, int off, int roff, char *value)
+ {
+     int usepm, tc;
+ 
+     on &= ~PM_ARRAY;
+ 
+     /* use the existing pm? */
+     usepm = pm && !(pm->flags & PM_UNSET);
+ 
+     /* Always use an existing pm if special at current locallevel */
+     if (pm && (pm->flags & PM_SPECIAL) && pm->level == locallevel)
+ 	usepm = 1;
+ 
+     /*
+      * Don't use a non-special existing param if
+      *   - the local level has changed, and
+      *   - the function is not `export'.
+      */
+     if (usepm && !(pm->flags & PM_SPECIAL) &&
+ 	locallevel != pm->level && func != BIN_EXPORT)
+ 	usepm = 0;
+ 
+     /* attempting a type conversion? */
+     if ((tc = usepm && (((off & pm->flags) | (on & ~pm->flags)) & PM_INTEGER)
+ 	 && !(pm->flags & PM_SPECIAL)))
+ 	usepm = 0;
+ 
+     if (usepm) {
+ 	if (pm->flags & PM_SPECIAL) {
+ 	    func = 0;
+ 	    on = (PM_TYPE(pm->flags) == PM_INTEGER) ?
+ 		(on &= ~(PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_UPPER)) :
+ 		(on & ~PM_INTEGER);
+ 	    off &= ~PM_INTEGER;
+ 	}
+ 	if (pm->level) {
+ 	    if ((on & PM_EXPORTED) && !(on &= ~PM_EXPORTED) && !off)
+ 		return 1;
+ 	}
+ 	if (!on && !roff && !value) {
+ 	    paramtab->printnode((HashNode)pm, 0);
+ 	    return 0;
+ 	}
+ 	if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
+ 	    !(pm->flags & PM_READONLY & ~off))
+ 	    uniqarray((*pm->gets.afn) (pm));
+ 	pm->flags = (pm->flags | on) & ~off;
+ 	/* This auxlen/pm->ct stuff is a nasty hack. */
+ 	if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) &&
+ 	    auxlen)
+ 	    pm->ct = auxlen;
+ 	if (PM_TYPE(pm->flags) != PM_ARRAY) {
+ 	    if (pm->flags & PM_EXPORTED) {
+ 		if (!pm->env)
+ 		    pm->env = addenv(pname, value ? value : getsparam(pname));
+ 	    } else if (pm->env) {
+ 		delenv(pm->env);
+ 		zsfree(pm->env);
+ 		pm->env = NULL;
+ 	    }
+ 	    if (value)
+ 		setsparam(pname, ztrdup(value));
+ 	}
+ 	return 0;
+     }
+ 
+     /*
+      * We're here either because we're creating a new parameter,
+      * or we're adding a parameter at a different local level,
+      * or we're converting the type of a parameter.  In the
+      * last case only, we need to delete the old parameter.
+      */
+     if (tc) {
+ 	if (pm->flags & PM_READONLY) {
+ 	    on |= ~off & PM_READONLY;
+ 	    pm->flags &= ~PM_READONLY;
+ 	}
+ 	if (!value)
+ 	    value = dupstring(getsparam(pname));
+ 	/* pname may point to pm->nam which is about to disappear */
+ 	pname = dupstring(pname);
+ 	unsetparam_pm(pm, 0);
+     } else if (locallist && func != BIN_EXPORT) {
+ 	PERMALLOC {
+ 	    addlinknode(locallist, ztrdup(pname));
+ 	} LASTALLOC;
+     }
+     /*
+      * Create a new node for a parameter with the flags in `on' minus the
+      * readonly flag
+      */
+     pm = createparam(ztrdup(pname), on & ~PM_READONLY);
+     DPUTS(!pm, "BUG: parameter not created");
+     pm->ct = auxlen;
+     if (func != BIN_EXPORT)
+ 	pm->level = locallevel;
+     if (value)
+ 	setsparam(pname, ztrdup(value));
+     pm->flags |= (on & PM_READONLY);
+ 
+     return 0;
+ }
+ 
  /* declare, export, integer, local, readonly, typeset */
  
  /**/
***************
*** 2799,2805 ****
      Comp com;
      char *optstr = "iLRZlurtxU";
      int on = 0, off = 0, roff, bit = PM_INTEGER;
!     int initon, initoff, of, i;
      int returnval = 0, printflags = 0;
  
      /* hash -f is really the builtin `functions' */
--- 2906,2912 ----
      Comp com;
      char *optstr = "iLRZlurtxU";
      int on = 0, off = 0, roff, bit = PM_INTEGER;
!     int i;
      int returnval = 0, printflags = 0;
  
      /* hash -f is really the builtin `functions' */
***************
*** 2845,2851 ****
--- 2952,2962 ----
  
      /* With the -m option, treat arguments as glob patterns */
      if (ops['m']) {
+ 	MUSTUSEHEAP("typeset -m");
  	while ((asg = getasg(*argv++))) {
+ 	    LinkList pmlist = newlinklist();
+ 	    LinkNode pmnode;
+ 
  	    tokenize(asg->name);   /* expand argument */
  	    if (!(com = parsereg(asg->name))) {
  		untokenize(asg->name);
***************
*** 2853,2985 ****
  		returnval = 1;
  		continue;
  	    }
! 	    /* If no options or values are given, display all *
! 	     * parameters matching the glob pattern.          */
! 	    if (!(on || roff || asg->value)) {
! 		scanmatchtable(paramtab, com, 0, 0, paramtab->printnode, 0);
! 		continue;
! 	    }
! 	    /* Since either options or values are given, we search   *
! 	     * through the parameter table and change all parameters *
! 	     * matching the glob pattern to have these flags and/or  *
! 	     * value.                                                */
  	    for (i = 0; i < paramtab->hsize; i++) {
! 		for (pm = (Param) paramtab->nodes[i]; pm; pm = (Param) pm->next) {
! 		    if (domatch(pm->nam, com, 0)) {
! 			/* set up flags if we have any */
! 			if (on || roff) {
! 			    if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
! 				!(pm->flags & PM_READONLY & ~off))
! 				uniqarray((*pm->gets.afn) (pm));
! 			    pm->flags = (pm->flags | on) & ~off;
! 			    if (PM_TYPE(pm->flags) != PM_ARRAY) {
! 				if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) && auxlen)
! 				    pm->ct = auxlen;
! 				/* did we just export this? */
! 				if ((pm->flags & PM_EXPORTED) && !pm->env) {
! 				    pm->env = addenv(pm->nam, (asg->value) ? asg->value : getsparam(pm->nam));
! 				} else if (!(pm->flags & PM_EXPORTED) && pm->env) {
! 				/* did we just unexport this? */
! 				    delenv(pm->env);
! 				    zsfree(pm->env);
! 				    pm->env = NULL;
! 				}
! 			    }
! 			}
! 			/* set up a new value if given */
! 			if (asg->value) {
! 			    setsparam(pm->nam, ztrdup(asg->value));
! 			}
! 		    }
  		}
  	    }
  	}
  	return returnval;
      }
  
-     /* Save the values of on, off, and func */
-     initon = on;
-     initoff = off;
-     of = func;
- 
      /* Take arguments literally.  Don't glob */
      while ((asg = getasg(*argv++))) {
- 	/* restore the original values of on, off, and func */
- 	on = initon;
- 	off = initoff;
- 	func = of;
- 	on &= ~PM_ARRAY;
- 
  	/* check if argument is a valid identifier */
  	if (!isident(asg->name)) {
  	    zerr("not an identifier: %s", asg->name, 0);
  	    returnval = 1;
  	    continue;
  	}
! 	if ((pm = (Param) paramtab->getnode(paramtab, asg->name))) {
! 	    if (pm->flags & PM_SPECIAL) {
! 		func = 0;
! 		on = (PM_TYPE(pm->flags) == PM_INTEGER) ?
! 		    (on &= ~(PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_UPPER)) :
! 		    (on & ~PM_INTEGER);
! 		off &= ~PM_INTEGER;
! 	    }
! 	    if (pm->level) {
! 		if ((on & PM_EXPORTED) && !(on &= ~PM_EXPORTED) && !off)
! 		    return 1;
! 	    }
! 	}
! 	bit = 0;    /* flag for switching int<->not-int */
! 	if (pm && !(pm->flags & PM_UNSET) && ((((locallevel == pm->level) || func == BIN_EXPORT)
! 		&& !(bit = ((off & pm->flags) | (on & ~pm->flags)) & PM_INTEGER)) || (pm->flags & PM_SPECIAL))) {
! 	    /* if no flags or values are given, just print this parameter */
! 	    if (!on && !roff && !asg->value) {
! 		paramtab->printnode((HashNode) pm, 0);
! 		continue;
! 	    }
! 	    if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
! 		!(pm->flags & PM_READONLY & ~off))
! 		uniqarray((*pm->gets.afn) (pm));
! 	    pm->flags = (pm->flags | on) & ~off;
! 	    if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) && auxlen)
! 		pm->ct = auxlen;
! 	    if (PM_TYPE(pm->flags) != PM_ARRAY) {
! 		if (pm->flags & PM_EXPORTED) {
! 		    if (!pm->env)
! 			pm->env = addenv(asg->name, (asg->value) ? asg->value : getsparam(asg->name));
! 		} else if (pm->env) {
! 		    delenv(pm->env);
! 		    zsfree(pm->env);
! 		    pm->env = NULL;
! 		}
! 		if (asg->value)
! 		    setsparam(asg->name, ztrdup(asg->value));
! 	    }
! 	} else {
! 	    if (bit) {
! 		if (pm->flags & PM_READONLY) {
! 		    on |= ~off & PM_READONLY;
! 		    pm->flags &= ~PM_READONLY;
! 		}
! 		if (!asg->value)
! 		    asg->value = dupstring(getsparam(asg->name));
! 		unsetparam(asg->name);
! 	    } else if (locallist && func != BIN_EXPORT) {
! 		PERMALLOC {
! 		    addlinknode(locallist, ztrdup(asg->name));
! 		} LASTALLOC;
! 	    }
! 	    /* create a new node for a parameter with the *
! 	     * flags in `on' minus the readonly flag      */
! 	    pm = createparam(ztrdup(asg->name), on & ~PM_READONLY);
! 	    DPUTS(!pm, "BUG: parameter not created");
! 	    pm->ct = auxlen;
! 	    if (func != BIN_EXPORT)
! 		pm->level = locallevel;
! 	    if (asg->value)
! 		setsparam(asg->name, ztrdup(asg->value));
! 	    pm->flags |= (on & PM_READONLY);
! 	}
      }
      return returnval;
  }
--- 2964,3005 ----
  		returnval = 1;
  		continue;
  	    }
! 	    /*
! 	     * Search through the parameter table and change all parameters
! 	     * matching the glob pattern to have these flags and/or value.
! 	     * Bad news:  if the parameter gets altered, e.g. by
! 	     * a type conversion, then paramtab can be shifted around,
! 	     * so we need to store the parameters to alter on a separate
! 	     * list for later use.	     
! 	     */
  	    for (i = 0; i < paramtab->hsize; i++) {
! 		for (pm = (Param) paramtab->nodes[i]; pm;
! 		     pm = (Param) pm->next) {
! 		    if (domatch(pm->nam, com, 0))
! 			addlinknode(pmlist, pm);
  		}
  	    }
+ 	    for (pmnode = firstnode(pmlist); pmnode; incnode(pmnode)) {
+ 		pm = (Param) getdata(pmnode);
+ 		if (typeset_single(name, pm->nam, pm, func, on, off, roff,
+ 				   asg->value))
+ 		    returnval = 1;
+ 	    }
  	}
  	return returnval;
      }
  
      /* Take arguments literally.  Don't glob */
      while ((asg = getasg(*argv++))) {
  	/* check if argument is a valid identifier */
  	if (!isident(asg->name)) {
  	    zerr("not an identifier: %s", asg->name, 0);
  	    returnval = 1;
  	    continue;
  	}
! 	typeset_single(name, asg->name,
! 		       (Param) paramtab->getnode(paramtab, asg->name),
! 		       func, on, off, roff, asg->value);
      }
      return returnval;
  }

-- 
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] 6+ messages in thread

* Re: PATCH: 3.0.5: typeset fix
  1999-01-15 12:35 ` PATCH: 3.0.5: " Peter Stephenson
@ 1999-01-15 16:35   ` Bart Schaefer
  0 siblings, 0 replies; 6+ messages in thread
From: Bart Schaefer @ 1999-01-15 16:35 UTC (permalink / raw)
  To: Peter Stephenson, zsh-workers

On Jan 15,  1:35pm, Peter Stephenson wrote:
} Subject: PATCH: 3.0.5: typeset fix
}
} This patch does that. The logic is different in 3.0.5 but I haven't
} changed it except expanding out the long test like I did before. For
} some reason 3.1.5 looks more like the pre-3 code I remember.

This does not surprise me.  There seem to have been a number of patches
made between approximately 3.0.3 and 3.0.5 that were never propagated to
3.1.2 and later.  Handling of SIGWINCH is another that comes to mind.

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


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

* RE: PATCH: 3.1.5-pws-4: typeset fix
  1999-01-14 15:25 ` PATCH: 3.1.5-pws-4: typeset fix Peter Stephenson
@ 1999-01-14 16:06   ` Andrej Borsenkow
  1999-01-14 15:55     ` Peter Stephenson
  0 siblings, 1 reply; 6+ messages in thread
From: Andrej Borsenkow @ 1999-01-14 16:06 UTC (permalink / raw)
  To: Peter Stephenson, zsh-workers

> 
> - I removed the restriction on creating array variables (with -a).
> You get an error message if you try to set the array as well.  I
> can't see any problem apart from that.
> 

Do you mean, that

local -a arr

is now valid?

/andrej


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

* Re: PATCH: 3.1.5-pws-4: typeset fix
  1999-01-14 16:06   ` Andrej Borsenkow
@ 1999-01-14 15:55     ` Peter Stephenson
  0 siblings, 0 replies; 6+ messages in thread
From: Peter Stephenson @ 1999-01-14 15:55 UTC (permalink / raw)
  To: zsh-workers

"Andrej Borsenkow" wrote:
> Do you mean, that
> 
> local -a arr
> 
> is now valid?

It's not only valid, it works, too.

-- 
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] 6+ messages in thread

* PATCH: 3.1.5-pws-4: typeset fix
  1999-01-13 16:08 Repeatable zsh crash in 3.0.5 and 3.1.5-pws-4 Bart Schaefer
@ 1999-01-14 15:25 ` Peter Stephenson
  1999-01-14 16:06   ` Andrej Borsenkow
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Stephenson @ 1999-01-14 15:25 UTC (permalink / raw)
  To: zsh-workers

"Bart Schaefer" wrote:
> Haven't looked into it any farther yet, but run zsh -f and then (where the
> name "variable" can be any parameter that is not already set):
> 
> zsh% typeset -i variable
> zsh% typeset -m +i variable
> zsh% echo $variable
> 
> and kablooey.

Right, that's it.  I know how attached everyone is to the old typeset
code, but I've finally decided to rewrite it so that it's *gasp*
almost readable.  So far, I haven't done much else to it, though there
are probably other rationalisations which could now be added.

Known changes include:

- typeset -m behaviour is now identical to the behaviour without the
m, with the exception that restricted variables are silently ignored
if necessary (this is what happened before).  There was an additional
bug hidden here, in that the sequences of commands above, changing
`variable' from integer to non-integer, could alter the parameter
table, so it now makes a list of parameters while scanning the table,
and runs through it later.

- I removed the restriction on creating array variables (with -a).
You get an error message if you try to set the array as well.  I
can't see any problem apart from that.

- I also de-dangled some else's.

*** Doc/Zsh/builtins.yo.typeset	Thu Dec 17 17:10:13 1998
--- Doc/Zsh/builtins.yo	Thu Jan 14 16:19:39 1999
***************
*** 947,955 ****
  first assignment.
  )
  item(tt(-a))(
! The names refer to array parameters.  For historical reasons, scalar
! parameters are created even when this flag is specified, but the
! output is restricted to arrays (including associative arrays).
  )
  item(tt(-f))(
  The names refer to functions rather than parameters.  No assignments
--- 947,956 ----
  first assignment.
  )
  item(tt(-a))(
! The names refer to array parameters.  An array parameter may be
! created this way, but it may not be assigned to in the tt(typeset)
! statement.  When displaying, both normal and associative arrays are
! shown.
  )
  item(tt(-f))(
  The names refer to functions rather than parameters.  No assignments
*** Src/builtin.c.typeset	Thu Dec 17 12:17:04 1998
--- Src/builtin.c	Thu Jan 14 15:55:34 1999
***************
*** 1224,1236 ****
  		if (!editor)
  		    editor = DEFAULT_FCEDIT;
  
! 		if (fcedit(editor, fil))
  		    if (stuff(fil))
  			zwarnnam("fc", "%e: %s", s, errno);
  		    else {
  			loop(0,1);
  			retval = lastval;
  		    }
  	    }
  	}
  	unlink(fil);
--- 1224,1237 ----
  		if (!editor)
  		    editor = DEFAULT_FCEDIT;
  
! 		if (fcedit(editor, fil)) {
  		    if (stuff(fil))
  			zwarnnam("fc", "%e: %s", s, errno);
  		    else {
  			loop(0,1);
  			retval = lastval;
  		    }
+ 		}
  	    }
  	}
  	unlink(fil);
***************
*** 1464,1469 ****
--- 1465,1581 ----
      return &asg;
  }
  
+ /* function to set a single parameter */
+ 
+ /**/
+ int
+ typeset_single(char *cname, char *pname, Param pm, int func,
+ 	       int on, int off, int roff, char *value)
+ {
+     int usepm, tc;
+ 
+     /* use the existing pm? */
+     usepm = pm && !(pm->flags & PM_UNSET);
+ 
+     /* Always use an existing pm if special at current locallevel */
+     if (pm && (pm->flags & PM_SPECIAL) && pm->level == locallevel)
+ 	usepm = 1;
+ 
+     /*
+      * Don't use a non-special existing param if
+      *   - the local level has changed, and
+      *   - the function is not `export'.
+      */
+     if (usepm && !(pm->flags & PM_SPECIAL) &&
+ 	locallevel != pm->level && func != BIN_EXPORT)
+ 	usepm = 0;
+ 
+     /* attempting a type conversion? */
+     if ((tc = usepm && (((off & pm->flags) | (on & ~pm->flags)) &
+ 			(PM_INTEGER|PM_HASHED|PM_ARRAY))))
+ 	usepm = 0;
+     if (tc && (pm->flags & PM_SPECIAL)) {
+ 	zerrnam(cname, "%s: can't change type of a special parameter",
+ 		pname, 0);
+ 	return 1;
+     }
+ 
+     if (usepm) {
+ 	if (!on && !roff && !value) {
+ 	    paramtab->printnode((HashNode)pm, 0);
+ 	    return 0;
+ 	}
+ 	if ((pm->flags & PM_RESTRICTED && isset(RESTRICTED))) {
+ 	    zerrnam(cname, "%s: restricted", pname, 0);
+ 	    return 1;
+ 	}
+ 	if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
+ 	    !(pm->flags & PM_READONLY & ~off))
+ 	    uniqarray((*pm->gets.afn) (pm));
+ 	pm->flags = (pm->flags | on) & ~off;
+ 	/* This auxlen/pm->ct stuff is a nasty hack. */
+ 	if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) &&
+ 	    auxlen)
+ 	    pm->ct = auxlen;
+ 	if (!(pm->flags & (PM_ARRAY|PM_HASHED))) {
+ 	    if (pm->flags & PM_EXPORTED) {
+ 		if (!(pm->flags & PM_UNSET) && !pm->env && !value)
+ 		    pm->env = addenv(pname, getsparam(pname));
+ 	    } else if (pm->env) {
+ 		delenv(pm->env);
+ 		zsfree(pm->env);
+ 		pm->env = NULL;
+ 	    }
+ 	    if (value)
+ 		setsparam(pname, ztrdup(value));
+ 	} else if (value) {
+ 	    zwarnnam(cname, "can't assign new value for array %s", pname, 0);
+ 	    return 1;
+ 	}
+ 	return 0;
+     }
+ 
+     /*
+      * We're here either because we're creating a new parameter,
+      * or we're adding a parameter at a different local level,
+      * or we're converting the type of a parameter.  In the
+      * last case only, we need to delete the old parameter.
+      */
+     if (tc) {
+ 	if (pm->flags & PM_READONLY) {
+ 	    on |= ~off & PM_READONLY;
+ 	    pm->flags &= ~PM_READONLY;
+ 	}
+ 	/*
+ 	 * Try to carry over a value, but not when changing from,
+ 	 * to, or between non-scalar types.
+ 	 */
+ 	if (!value && !((pm->flags|on) & (PM_ARRAY|PM_HASHED)))
+ 	    value = dupstring(getsparam(pname));
+ 	/* pname may point to pm->nam which is about to disappear */
+ 	pname = dupstring(pname);
+ 	unsetparam_pm(pm, 0, 1);
+     }
+     /*
+      * Create a new node for a parameter with the flags in `on' minus the
+      * readonly flag
+      */
+     pm = createparam(ztrdup(pname), on & ~PM_READONLY);
+     DPUTS(!pm, "BUG: parameter not created");
+     pm->ct = auxlen;
+     if (func != BIN_EXPORT)
+ 	pm->level = locallevel;
+     if (value && !(pm->flags & (PM_ARRAY|PM_HASHED)))
+ 	setsparam(pname, ztrdup(value));
+     pm->flags |= (on & PM_READONLY);
+     if (value && (pm->flags & (PM_ARRAY|PM_HASHED))) {
+ 	zerrnam(cname, "%s: can't assign initial value for array", pname, 0);
+ 	return 1;
+     }
+ 
+     return 0;
+ }
+ 
  /* declare, export, integer, local, readonly, typeset */
  
  /**/
***************
*** 1475,1481 ****
      Comp com;
      char *optstr = "aiALRZlurtxU";
      int on = 0, off = 0, roff, bit = PM_ARRAY;
!     int initon, initoff, of, i;
      int returnval = 0, printflags = 0;
  
      /* hash -f is really the builtin `functions' */
--- 1587,1593 ----
      Comp com;
      char *optstr = "aiALRZlurtxU";
      int on = 0, off = 0, roff, bit = PM_ARRAY;
!     int i;
      int returnval = 0, printflags = 0;
  
      /* hash -f is really the builtin `functions' */
***************
*** 1521,1527 ****
--- 1633,1643 ----
  
      /* With the -m option, treat arguments as glob patterns */
      if (ops['m']) {
+ 	MUSTUSEHEAP("typeset -m");
  	while ((asg = getasg(*argv++))) {
+ 	    LinkList pmlist = newlinklist();
+ 	    LinkNode pmnode;
+ 
  	    tokenize(asg->name);   /* expand argument */
  	    if (!(com = parsereg(asg->name))) {
  		untokenize(asg->name);
***************
*** 1529,1671 ****
  		returnval = 1;
  		continue;
  	    }
! 	    /* If no options or values are given, display all *
! 	     * parameters matching the glob pattern.          */
! 	    if (!(on || roff || asg->value)) {
! 		scanmatchtable(paramtab, com, 0, 0, paramtab->printnode, 0);
! 		continue;
! 	    }
! 	    /* Since either options or values are given, we search   *
! 	     * through the parameter table and change all parameters *
! 	     * matching the glob pattern to have these flags and/or  *
! 	     * value.                                                */
  	    for (i = 0; i < paramtab->hsize; i++) {
! 		for (pm = (Param) paramtab->nodes[i]; pm; pm = (Param) pm->next) {
  		    if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED))
  			continue;
! 		    if (domatch(pm->nam, com, 0)) {
! 			/* set up flags if we have any */
! 			if (on || roff) {
! 			    if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
! 				!(pm->flags & PM_READONLY & ~off))
! 				uniqarray((*pm->gets.afn) (pm));
! 			    if ((on & ~pm->flags) & PM_HASHED) {
! 				char *nam = ztrdup(pm->nam);
! 				unsetparam(nam);
! 				pm = createparam(nam, on & ~PM_READONLY);
! 				DPUTS(!pm, "BUG: parameter not created");
! 			    }
! 			    pm->flags = (pm->flags | on) & ~off;
! 			    if (PM_TYPE(pm->flags) != PM_ARRAY &&
! 				PM_TYPE(pm->flags) != PM_HASHED) {
! 				if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) && auxlen)
! 				    pm->ct = auxlen;
! 				/* did we just export this? */
! 				if ((pm->flags & PM_EXPORTED) && !pm->env) {
! 				    pm->env = addenv(pm->nam, (asg->value) ? asg->value : getsparam(pm->nam));
! 				} else if (!(pm->flags & PM_EXPORTED) && pm->env) {
! 				/* did we just unexport this? */
! 				    delenv(pm->env);
! 				    zsfree(pm->env);
! 				    pm->env = NULL;
! 				}
! 			    }
! 			}
! 			/* set up a new value if given */
! 			if (asg->value) {
! 			    setsparam(pm->nam, ztrdup(asg->value));
! 			}
! 		    }
  		}
  	    }
  	}
  	return returnval;
      }
  
-     /* Save the values of on, off, and func */
-     initon = on;
-     initoff = off;
-     of = func;
- 
      /* Take arguments literally.  Don't glob */
      while ((asg = getasg(*argv++))) {
- 	/* restore the original values of on, off, and func */
- 	on = initon;
- 	off = initoff;
- 	func = of;
- 	on &= ~PM_ARRAY;
- 
  	/* check if argument is a valid identifier */
  	if (!isident(asg->name)) {
  	    zerr("not an identifier: %s", asg->name, 0);
  	    returnval = 1;
  	    continue;
  	}
! 	bit = 0;    /* flag for switching int<->not-int */
! 	if ((pm = (Param)paramtab->getnode(paramtab, asg->name)) &&
! 	    (((pm->flags & PM_SPECIAL) && pm->level == locallevel) ||
! 	     (!(pm->flags & PM_UNSET) &&
! 	      ((locallevel == pm->level) || func == BIN_EXPORT) &&
! 	      !(bit = (((off & pm->flags) | (on & ~pm->flags)) &
! 		       (PM_INTEGER|PM_HASHED)))))) {
! 	    /* if no flags or values are given, just print this parameter */
! 	    if (!on && !roff && !asg->value) {
! 		paramtab->printnode((HashNode) pm, 0);
! 		continue;
! 	    }
! 	    if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED)) {
! 		zerrnam(name, "%s: restricted", pm->nam, 0);
! 		returnval = 1;
! 		continue;
! 	    }
! 	    if((pm->flags & PM_SPECIAL) &&
! 	       PM_TYPE((pm->flags | on) & ~off) != PM_TYPE(pm->flags)) {
! 		zerrnam(name, "%s: cannot change type of a special parameter",
! 		    pm->nam, 0);
! 		returnval = 1;
! 		continue;
! 	    }
! 	    if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
! 		!(pm->flags & PM_READONLY & ~off))
! 		uniqarray((*pm->gets.afn) (pm));
! 	    pm->flags = (pm->flags | on) & ~off;
! 	    if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) &&
! 		auxlen)
! 		pm->ct = auxlen;
! 	    if (PM_TYPE(pm->flags) != PM_ARRAY &&
! 		PM_TYPE(pm->flags) != PM_HASHED) {
! 		if (pm->flags & PM_EXPORTED) {
! 		    if (!(pm->flags & PM_UNSET) && !pm->env && !asg->value)
! 			pm->env = addenv(asg->name, getsparam(asg->name));
! 		} else if (pm->env) {
! 		    delenv(pm->env);
! 		    zsfree(pm->env);
! 		    pm->env = NULL;
! 		}
! 		if (asg->value)
! 		    setsparam(asg->name, ztrdup(asg->value));
! 	    }
! 	} else {
! 	    if (bit) {
! 		if (pm->flags & PM_READONLY) {
! 		    on |= ~off & PM_READONLY;
! 		    pm->flags &= ~PM_READONLY;
! 		}
! 		if (!asg->value)
! 		    asg->value = dupstring(getsparam(asg->name));
! 		unsetparam(asg->name);
! 	    }
! 	    /* create a new node for a parameter with the *
! 	     * flags in `on' minus the readonly flag      */
! 	    pm = createparam(ztrdup(asg->name), on & ~PM_READONLY);
! 	    DPUTS(!pm, "BUG: parameter not created");
! 	    pm->ct = auxlen;
! 	    if (func != BIN_EXPORT)
! 		pm->level = locallevel;
! 	    if (asg->value)
! 		setsparam(asg->name, ztrdup(asg->value));
! 	    pm->flags |= (on & PM_READONLY);
! 	}
      }
      return returnval;
  }
--- 1645,1689 ----
  		returnval = 1;
  		continue;
  	    }
! 	    /*
! 	     * Search through the parameter table and change all parameters
! 	     * matching the glob pattern to have these flags and/or value.
! 	     * Bad news:  if the parameter gets altered, e.g. by
! 	     * a type conversion, then paramtab can be shifted around,
! 	     * so we need to store the parameters to alter on a separate
! 	     * list for later use.	     
! 	     */
  	    for (i = 0; i < paramtab->hsize; i++) {
! 		for (pm = (Param) paramtab->nodes[i]; pm;
! 		     pm = (Param) pm->next) {
  		    if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED))
  			continue;
! 		    if (domatch(pm->nam, com, 0))
! 			addlinknode(pmlist, pm);
  		}
  	    }
+ 	    for (pmnode = firstnode(pmlist); pmnode; incnode(pmnode)) {
+ 		pm = (Param) getdata(pmnode);
+ 		if (typeset_single(name, pm->nam, pm, func, on, off, roff,
+ 				   asg->value))
+ 		    returnval = 1;
+ 	    }
  	}
  	return returnval;
      }
  
      /* Take arguments literally.  Don't glob */
      while ((asg = getasg(*argv++))) {
  	/* check if argument is a valid identifier */
  	if (!isident(asg->name)) {
  	    zerr("not an identifier: %s", asg->name, 0);
  	    returnval = 1;
  	    continue;
  	}
! 	if (typeset_single(name, asg->name,
! 			   (Param)paramtab->getnode(paramtab, asg->name),
! 			   func, on, off, roff, asg->value))
! 	    returnval = 1;
      }
      return returnval;
  }
***************
*** 2778,2785 ****
  		LASTALLOC_RETURN;
  	    }
  	}
! 	if (in_exit++ && from_signal)
  	    LASTALLOC_RETURN;
  	if (isset(MONITOR))
  	    /* send SIGHUP to any jobs left running  */
  	    killrunjobs(from_signal);
--- 2796,2804 ----
  		LASTALLOC_RETURN;
  	    }
  	}
! 	if (in_exit++ && from_signal) {
  	    LASTALLOC_RETURN;
+ 	}
  	if (isset(MONITOR))
  	    /* send SIGHUP to any jobs left running  */
  	    killrunjobs(from_signal);
***************
*** 3181,3193 ****
  	    }
  	    if (c == EOF || (c == '\n' && !zbuf))
  		break;
! 	    if (!bslash && isep(c) && bptr == buf)
  		if (iwsep(c))
  		    continue;
  		else if (!first) {
  		    first = 1;
  		    continue;
  		}
  	    bslash = c == '\\' && !bslash && !ops['r'];
  	    if (bslash)
  		continue;
--- 3200,3213 ----
  	    }
  	    if (c == EOF || (c == '\n' && !zbuf))
  		break;
! 	    if (!bslash && isep(c) && bptr == buf) {
  		if (iwsep(c))
  		    continue;
  		else if (!first) {
  		    first = 1;
  		    continue;
  		}
+ 	    }
  	    bslash = c == '\\' && !bslash && !ops['r'];
  	    if (bslash)
  		continue;
***************
*** 3240,3246 ****
      char cc, retry = 0;
  
      /* use zbuf if possible */
!     if (zbuf)
  	/* If zbuf points to anything, it points to the next character in the
  	buffer.  This may be a null byte to indicate EOF.  If reading from the
  	buffer, move on the buffer pointer. */
--- 3260,3266 ----
      char cc, retry = 0;
  
      /* use zbuf if possible */
!     if (zbuf) {
  	/* If zbuf points to anything, it points to the next character in the
  	buffer.  This may be a null byte to indicate EOF.  If reading from the
  	buffer, move on the buffer pointer. */
***************
*** 3248,3253 ****
--- 3268,3274 ----
  	    return zbuf++, STOUC(*zbuf++ ^ 32);
  	else
  	    return (*zbuf) ? STOUC(*zbuf++) : EOF;
+     }
      for (;;) {
  	/* read a character from readfd */
  	switch (read(readfd, &cc, 1)) {

-- 
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] 6+ messages in thread

end of thread, other threads:[~1999-01-15 16:38 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-01-14 17:53 PATCH: 3.1.5-pws-4: typeset fix Amol Deshpande
1999-01-15 12:35 ` PATCH: 3.0.5: " Peter Stephenson
1999-01-15 16:35   ` Bart Schaefer
  -- strict thread matches above, loose matches on Subject: below --
1999-01-13 16:08 Repeatable zsh crash in 3.0.5 and 3.1.5-pws-4 Bart Schaefer
1999-01-14 15:25 ` PATCH: 3.1.5-pws-4: typeset fix Peter Stephenson
1999-01-14 16:06   ` Andrej Borsenkow
1999-01-14 15:55     ` 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).