zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <pws@ibmth.df.unipi.it>
To: zsh-workers@sunsite.auc.dk (Zsh hackers list)
Subject: PATH: zsh-3.1.5-pws-6: more typeset -T stuff
Date: Thu, 04 Feb 1999 18:16:41 +0100	[thread overview]
Message-ID: <9902041716.AA19313@ibmth.df.unipi.it> (raw)

This is what happens just when you've finished a paper and can't bring
yourself to start anything new...

I noticed some problems with typeset -T:

1. `typeset -T FOO foo' wasn't idempotent, because the second time
round, foo was unset first which destroyed the value of FOO so it
couldn't be copied when that was recreated.  Likewise, you need to
pass on whether it was currently exported.  And you need to make sure
it's really the right parameter from the right level of localness.
Sob.  (It still recreates the whole thing from scratch, but that's
what the user ordered.)

I noticed this because I have TEXINPUTS exported when logging in, then
tied in each individual shell without assigning the value again: this
sort of thing is supposed to work, even when you do another
`. ~/.zshenv'.  It's still not quite idempotent, because of the
right/left/zero flags, but there's such a thing as being fed up.

2. `typeset -T foo foo' wasn't tested for, and could have done such
awful things I felt too frighened even to test what.

3. Exporting at the same time always worked, but now the array doesn't
get marked for export (which didn't have an effect anyway).  I've
documented this.

4. A small memory leak (name1 on an error) has vanished as a side
effect.

--- Doc/Zsh/builtins.yo.T	Tue Feb  2 12:11:29 1999
+++ Doc/Zsh/builtins.yo	Thu Feb  4 17:50:30 1999
@@ -913,7 +913,9 @@
 of untying the variables without unsetting them, or converting the
 type of one them with another tt(typeset) command; tt(+T) does not work,
 assigning an array to var(SCALAR) is an error, and assigning a scalar
-to var(array) sets it to be a single-element array.
+to var(array) sets it to be a single-element array.  Note that
+both tt(typeset -xT ...) and tt(export -T ...) work, but only the
+scalar will be marked for export.
 
 If no var(name) is present, the names and values of all parameters are
 printed.  In this case the attribute flags restrict the the display to
--- Src/builtin.c.T	Tue Feb  2 12:11:29 1999
+++ Src/builtin.c	Thu Feb  4 18:12:17 1999
@@ -1665,7 +1665,8 @@
 
     if (on & PM_TIED) {
 	Param apm;
-	char *name1;
+	struct asgment asg0;
+	char *oldval = NULL;
 
 	if (ops['m']) {
 	    zwarnnam(name, "incompatible options for -T", NULL, 0);
@@ -1677,36 +1678,61 @@
 	    return 1;
 	}
 
+	if (!(asg = getasg(argv[0])))
+	    return 1;
+	asg0 = *asg;
+	if (!(asg = getasg(argv[1])))
+	    return 1;
+	if (!strcmp(asg0.name, asg->name)) {
+	    zerrnam(name, "can't tie a variable to itself", NULL, 0);
+	    return 1;
+	}
+	/*
+	 * Keep the old value of the scalar.  We need to do this
+	 * here as if it is already tied to the same array it
+	 * will be unset when we retie the array.  This is all
+	 * so that typeset -T is idempotent.
+	 *
+	 * We also need to remember here whether the damn thing is
+	 * exported and pass that along.  Isn't the world complicated?
+	 */
+	if ((pm = (Param) paramtab->getnode(paramtab, asg0.name))
+	    && !(pm->flags & PM_UNSET)
+	    && (locallevel == pm->level || func == BIN_EXPORT)) {
+	    if (!asg0.value && !(PM_TYPE(pm->flags) & (PM_ARRAY|PM_HASHED)))
+		oldval = ztrdup(getsparam(asg0.name));
+	    on |= (pm->flags & PM_EXPORTED);
+	}
 	/*
 	 * Create the tied array; this is normal except that
 	 * it has the PM_TIED flag set.  Do it first because
 	 * we need the address.
 	 */
-	if (!(asg = getasg(argv[1])))
-	    return 1;
-	name1 = ztrdup(asg->name);
 	if (!(apm=typeset_single(name, asg->name,
 				 (Param)paramtab->getnode(paramtab,
 							  asg->name),
-				 func, on | PM_ARRAY, off, roff,
-				 asg->value, NULL)))
+				 func, (on | PM_ARRAY) & ~PM_EXPORTED,
+				 off, roff, asg->value, NULL)))
 	    return 1;
 
 	/*
 	 * Create the tied colonarray.  We make it as a normal scalar
 	 * and fix up the oddities later.
 	 */
-	if (!(asg = getasg(argv[0])) ||
-	    !(pm=typeset_single(name, asg->name,
+	if (!(pm=typeset_single(name, asg0.name,
 				(Param)paramtab->getnode(paramtab,
-							 asg->name),
-				func, on, off, roff, asg->value, apm))) {
+							 asg0.name),
+				func, on, off, roff, asg0.value, apm))) {
+	    if (oldval)
+		zsfree(oldval);
 	    unsetparam_pm(apm, 1, 1);
 	    return 1;
 	}
 
-	pm->ename = name1;
-	apm->ename = ztrdup(asg->name);
+	pm->ename = ztrdup(asg->name);
+	apm->ename = ztrdup(asg0.name);
+	if (oldval)
+	    setsparam(asg0.name, oldval);
 
 	return 0;
     }

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


                 reply	other threads:[~1999-02-04 17:16 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9902041716.AA19313@ibmth.df.unipi.it \
    --to=pws@ibmth.df.unipi.it \
    --cc=zsh-workers@sunsite.auc.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).