zsh-workers
 help / color / mirror / code / Atom feed
* Re: uppercase inheritance
       [not found] <894F73B43295D211B7B20000F807EA88ED80D0@sbe0461.swissptt.ch>
@ 1999-12-10 21:36 ` Peter Stephenson
  1999-12-11 21:20   ` Bart Schaefer
  0 siblings, 1 reply; 2+ messages in thread
From: Peter Stephenson @ 1999-12-10 21:36 UTC (permalink / raw)
  To: zsh-workers

Norman.Azadian@swisscom.com wrote:
> I've tried this under version 3.1.6 (on HP-UX version 11.0):
> 
> 	= typeset -u -x aaa=bbb
> 	= echo $aaa
> 	BBB
> 	= zsh
> 	= echo $aaa
> 	bbb
> 	=
> 
> Am I missing something, or has ZSH neglected to pass on the uppercase
> property to the subshell?

The problem is that the version in the environment isn't uppercased;
actually, I'm not completely convinced that this is wrong, since the
typeset specifiers are quiet specifically for output formatting, not for
transformations on the variable itself.  The following will make that
happen, but notice that what's in the environment continues to reflect the
status when the variable was last assigned, not the state of the uppercase
flag.  I wouldn't like to alter that without major changes to the structure
of the code (which could happen if we were to introduce get/set functions
for variables).

Index: Src/builtin.c
===================================================================
RCS file: /home/pws/CVSROOT/projects/zsh/Src/builtin.c,v
retrieving revision 1.6
diff -u -r1.6 builtin.c
--- Src/builtin.c	1999/12/06 23:18:02	1.6
+++ Src/builtin.c	1999/12/10 20:03:05
@@ -645,13 +645,13 @@
     if (!(pm->flags & PM_EXPORTED) &&
 	(!pm->level || (isset(ALLEXPORT) && !pm->old))) {
 	pm->flags |= PM_EXPORTED;
-	pm->env = addenv("PWD", pwd);
+	pm->env = addenv("PWD", pwd, pm->flags);
     }
     pm = (Param) paramtab->getnode(paramtab, "OLDPWD");
     if (!(pm->flags & PM_EXPORTED) &&
 	(!pm->level || (isset(ALLEXPORT) && !pm->old))) {
 	pm->flags |= PM_EXPORTED;
-	pm->env = addenv("OLDPWD", oldpwd);
+	pm->env = addenv("OLDPWD", oldpwd, pm->flags);
     }
 }
 
@@ -1621,7 +1621,7 @@
 	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));
+		    pm->env = addenv(pname, getsparam(pname), pm->flags);
 	    } else if (pm->env &&
 		       (!pm->level || (isset(ALLEXPORT) && !pm->old))) {
 		delenv(pm->env);
Index: Src/exec.c
===================================================================
RCS file: /home/pws/CVSROOT/projects/zsh/Src/exec.c,v
retrieving revision 1.3
diff -u -r1.3 exec.c
--- Src/exec.c	1999/12/06 23:18:02	1.3
+++ Src/exec.c	1999/12/10 20:03:04
@@ -2217,7 +2217,7 @@
 	    } else
 		paramtab->addnode(paramtab, pm->nam, pm);
 	    if ((pm->flags & PM_EXPORTED) && ((s = getsparam(pm->nam))))
-		pm->env = addenv(pm->nam, s);
+		pm->env = addenv(pm->nam, s, pm->flags);
 	}
     }
 }
Index: Src/params.c
===================================================================
RCS file: /home/pws/CVSROOT/projects/zsh/Src/params.c,v
retrieving revision 1.2
diff -u -r1.2 params.c
--- Src/params.c	1999/12/03 19:12:10	1.2
+++ Src/params.c	1999/12/10 20:10:48
@@ -510,7 +510,8 @@
 			pm->env = *envp++ = ztrdup(*envp2);
 			*envp = NULL;
 			if (pm->flags & PM_SPECIAL)
-			    pm->env = replenv(pm->env, getsparam(pm->nam));
+			    pm->env = replenv(pm->env, getsparam(pm->nam),
+					      pm->flags);
 		    }
 		}
 		*str = '=';
@@ -522,18 +523,18 @@
 	pm = (Param) paramtab->getnode(paramtab, "HOME");
 	if (!(pm->flags & PM_EXPORTED)) {
 	    pm->flags |= PM_EXPORTED;
-	    pm->env = addenv("HOME", home);
+	    pm->env = addenv("HOME", home, pm->flags);
 	}
 	pm = (Param) paramtab->getnode(paramtab, "LOGNAME");
 	if (!(pm->flags & PM_EXPORTED)) {
 	    pm->flags |= PM_EXPORTED;
-	    pm->env = addenv("LOGNAME", pm->u.str);
+	    pm->env = addenv("LOGNAME", pm->u.str, pm->flags);
 	}
 	pm = (Param) paramtab->getnode(paramtab, "SHLVL");
 	if (!(pm->flags & PM_EXPORTED))
 	    pm->flags |= PM_EXPORTED;
 	sprintf(buf, "%d", (int)++shlvl);
-	pm->env = addenv("SHLVL", buf);
+	pm->env = addenv("SHLVL", buf, pm->flags);
 
 	/* Add the standard non-special parameters */
 	set_pwd_env();
@@ -1506,10 +1507,10 @@
     else
 	val = v->pm->gets.cfn(v->pm);
     if (v->pm->env)
-	v->pm->env = replenv(v->pm->env, val);
+	v->pm->env = replenv(v->pm->env, val, v->pm->flags);
     else {
 	v->pm->flags |= PM_EXPORTED;
-	v->pm->env = addenv(v->pm->nam, val);
+	v->pm->env = addenv(v->pm->nam, val, v->pm->flags);
     }
 }
 
@@ -2683,13 +2684,13 @@
     len_s = strlen(s);
     for (ep = environ; *ep; ep++)
 	if (!strncmp(*ep, s, len_s) && (*ep)[len_s] == '=') {
-	    pm->env = replenv(*ep, u);
+	    pm->env = replenv(*ep, u, pm->flags);
 	    return;
 	}
     if (isset(ALLEXPORT))
 	pm->flags |= PM_EXPORTED;
     if (pm->flags & PM_EXPORTED)
-	pm->env = addenv(s, u);
+	pm->env = addenv(s, u, pm->flags);
 }
 
 /* Given *name = "foo", it searchs the environment for string *
@@ -2709,11 +2710,25 @@
     return NULL;
 }
 
+/**/
+static void
+copyenvstr(char *s, char *value, int flags)
+{
+    while (*s++) {
+	if ((*s = *value++) == Meta)
+	    *s = *value++ ^ 32;
+	if (flags & PM_LOWER)
+	    *s = tulower(*s);
+	else if (flags & PM_UPPER)
+	    *s = tuupper(*s);
+    }
+}
+
 /* Change the value of an existing environment variable */
 
 /**/
 char *
-replenv(char *e, char *value)
+replenv(char *e, char *value, int flags)
 {
     char **ep, *s;
     int len_value;
@@ -2726,9 +2741,7 @@
 	    while (*s++ != '=');
 	    *ep = (char *) zrealloc(e, s - e + len_value + 1);
 	    s = s - e + *ep - 1;
-	    while (*s++)
-		if ((*s = *value++) == Meta)
-		    *s = *value++ ^ 32;
+	    copyenvstr(s, value, flags);
 	    return *ep;
 	}
     return NULL;
@@ -2739,7 +2752,7 @@
 
 /**/
 static char *
-mkenvstr(char *name, char *value)
+mkenvstr(char *name, char *value, int flags)
 {
     char *str, *s;
     int len_name, len_value;
@@ -2751,9 +2764,7 @@
     strcpy(s, name);
     s += len_name;
     *s = '=';
-    while (*s++)
-	if ((*s = *value++) == Meta)
-	    *s = *value++ ^ 32;
+    copyenvstr(s, value, flags);
     return str;
 }
 
@@ -2764,7 +2775,7 @@
 
 /**/
 char *
-addenv(char *name, char *value)
+addenv(char *name, char *value, int flags)
 {
     char **ep, *s, *t;
     int num_env;
@@ -2775,7 +2786,7 @@
 	for (s = *ep, t = name; *s && *s == *t; s++, t++);
 	if (*s == '=' && !*t) {
 	    zsfree(*ep);
-	    return *ep = mkenvstr(name, value);
+	    return *ep = mkenvstr(name, value, flags);
 	}
     }
 
@@ -2785,7 +2796,7 @@
 
     /* Now add it at the end */
     ep = environ + num_env;
-    *ep = mkenvstr(name, value);
+    *ep = mkenvstr(name, value, flags);
     *(ep + 1) = NULL;
     return *ep;
 }

-- 
Peter Stephenson <pws@pwstephenson.fsnet.co.uk>


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

* Re: uppercase inheritance
  1999-12-10 21:36 ` uppercase inheritance Peter Stephenson
@ 1999-12-11 21:20   ` Bart Schaefer
  0 siblings, 0 replies; 2+ messages in thread
From: Bart Schaefer @ 1999-12-11 21:20 UTC (permalink / raw)
  To: Peter Stephenson, zsh-workers

On Dec 10,  9:36pm, Peter Stephenson wrote:
} Subject: Re: uppercase inheritance
}
} The problem is that the version in the environment isn't uppercased;
} actually, I'm not completely convinced that this is wrong, since the
} typeset specifiers are quiet specifically for output formatting

When are they noisy?  (Sorry.)

} not for transformations on the variable itself.

I've always wondered about that.  What's the point?  There's no way to
refer to the value except to "output" it.  Doing a split or substitute
only on lower-case letters and then outputting the result in upper case
seems like a rather obscure usage (not to mention potentially confusing)
and one that could equally well be accomplished by using a modifier.

It makes more sense for justification, so maybe the point is to have it
work consistently.  However, look at this (3.1.6-pws-11 *before* 8997):

zagzig% typeset -u up
zagzig% up=case
zagzig% typeset +u
up
zagzig% echo $up
CASE
zagzig% typeset +u up
zagzig% typeset +u
zagzig% echo $up
CASE
zagzig%

Note that, although the upcased property has been removed from "up", its
value is now *stored* all upper case.  This does NOT happen with justify:

g% typeset -R 10 just
zagzig% just=right
zagzig% typeset +R
just
zagzig% echo "$just"
     right
zagzig% typeset +R just
zagzig% typeset +R
zagzig% echo "$just"
right

This makes me believe that case conversion was intended to *appear* as
though it happened on assignment, not just on output, but that Paul was
too lazy to actually implement it that way.

It gets stranger:

zagzig% typeset -l down=CASE
zagzig% export down
zagzig% printenv down
CASE
zagzig% echo $down
case
zagzig% typeset +l down
zagzig% echo $down
case
zagzig% printenv down
CASE

Now watch what happens if we play with "typeset +x":

zagzig% unset up down
zagzig% typeset -u up
zagzig% export up
zagzig% up=case
zagzig% printenv up
case
zagzig% echo $up
CASE
zagzig% typeset +x up
zagzig% export up
zagzig% printenv up
CASE

Note that un-exporting and then re-exporting causes the converted value
to go into the environment.  (Again, this does not happen with justify.)

Finally:

zagzig% typeset -l down
zagzig% down=CASE
zagzig% typeset +l down
zagzig% echo $down
CASE

If the value of the variable is never referenced before removing the
conversion flag, the stored value remains in the original assigned case
rather than being converted.  Gaaah.

Now if I look at 3.1.6-pws-11 *after* 8997, only these two results have
changed:

zagzig% typeset -l down=CASE
zagzig% export down
zagzig% printenv down
case
zagzig% echo $down
case
zagzig% typeset +l down
zagzig% echo $down
case
zagzig% printenv down
case

zagzig% typeset -u up
zagzig% export up
zagzig% up=case
zagzig% printenv up
CASE
zagzig% echo $up
CASE
zagzig% typeset +x up
zagzig% export up
zagzig% printenv up
CASE

If you decide to fix this, Peter, do you think you could also take care of
ksh export semantics (locals *can* be exported in ksh, and the old environ
gets restored when they go out of scope) under emulation?

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


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

end of thread, other threads:[~1999-12-11 21:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <894F73B43295D211B7B20000F807EA88ED80D0@sbe0461.swissptt.ch>
1999-12-10 21:36 ` uppercase inheritance Peter Stephenson
1999-12-11 21:20   ` 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).