zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: zsh-3.1.5-pws-5 + recent: typeset -T MYPATH mypath (finally!)
@ 1999-01-28 17:25 Peter Stephenson
  1999-01-28 17:53 ` Bruce Stephens
  1999-01-29 16:56 ` Bart Schaefer
  0 siblings, 2 replies; 3+ messages in thread
From: Peter Stephenson @ 1999-01-28 17:25 UTC (permalink / raw)
  To: Zsh hackers list

Now I've tidied up bin_typeset() a bit, it's finally possible to make
user-tiable path-like variables without the onset of suicidal
feelings.  This has been requested for several years.  Maybe there's not
even anyone left who wants it --- word splitting and joining has
improved quite a lot since then.  The syntax is
  typeset -T TEXINPUTS texinputs
where the scalar has to come first, but there is no restriction on the
names.

As usual, the pair will be local to any function in which you use
typeset.  You can avoid this by using export directly:
  export -T TEXINPUTS=... texinputs
is the canonical way to set something like this the first time, since
there's not a lot of point of having the colon array unless you export
it.  `typeset -T' on its own works as expected, but I haven't made any
special arrangement for ${(t)...}, which would have to cover $PATH
etc. too.  Also, typeset +T doesn't work.

There are all sorts of potential problems with null arrays and memory
leaks etc., but I haven't run across any yet.  I fixed a couple of
documentation bugs for typeset and a minor (recent) bracketing problem
at the top of getarg() (that will be rejected if you're not patched up
to date).  The problem I was trying to tackle with the new `keeplocal'
variable in typeset_single() may or may not be real, but it makes me
feel happier.  Also, `export -i foo; typeset +i foo' used to forget
$foo was exported, now it remembers, likewise `export FOO; typeset -T
FOO foo', which is how I discovered it.

Feel free to destruction test this.

--- Doc/Zsh/builtins.yo.tied	Thu Jan 14 16:19:39 1999
+++ Doc/Zsh/builtins.yo	Thu Jan 28 18:04:21 1999
@@ -878,7 +878,10 @@
 findex(typeset)
 cindex(parameters, setting)
 cindex(parameters, declaring)
-item(tt(typeset) [ {tt(PLUS())|tt(-)}tt(ALRUZafilrtuxm) [var(n)]] [ var(name)[tt(=)var(value)] ... ])(
+xitem(tt(typeset) [ {tt(PLUS())|tt(-)}tt(ALRUZafilrtuxm) [var(n)]] [ \
+var(name)[tt(=)var(value)] ... ])
+item(tt(typeset) -T [ {tt(PLUS()|tt(-))}tt(LRUZrux) ] \
+  var(SCALAR)[tt(=)var(value)] var(array))(
 Set or display attributes and values for shell parameters.
 
 A parameter is created for each var(name) that does not already refer
@@ -891,13 +894,23 @@
 which case the parameter is exported em(only) when var(name) does not
 already appear in the environment.
 
-For each nofill(var(name)tt(=)var(value)) assignment, the parameter
+For each var(name)tt(=)var(value) assignment, the parameter
 var(name) set to var(value).  Note that arrays currently cannot be
 assigned in tt(typeset) expressions; scalars and integers only.
 
 For each remaining var(name) that refers to a parameter that is set,
 the name and value of the parameter are printed in the form of an
 assignment.  Nothing is printed for newly-created parameters.
+
+If the tt(-T) option is given, exactly two (or zero) var(name)
+arguments must be present.  They represent a scalar and an array (in
+that order) that will be tied together in the manner of tt($PATH) and
+tt($path).  In other words, an array present in the latter variable
+appears as a scalar with the elements of the array joined by colons in
+the former.  Only the scalar may have an initial value.  Both the
+scalar and the array may otherwise be manipulated as normal.  If one
+is unset, the other will automatically be unset too.  There is no way
+of untying the variables without unsetting them; tt(+T) does not work.
 
 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.tied	Fri Jan 22 13:28:35 1999
+++ Src/builtin.c	Thu Jan 28 18:04:06 1999
@@ -50,7 +50,7 @@
     BUILTIN("cd", 0, bin_cd, 0, 2, BIN_CD, NULL, NULL),
     BUILTIN("chdir", 0, bin_cd, 0, 2, BIN_CD, NULL, NULL),
     BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL),
-    BUILTIN("declare", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRUZafilrtux", NULL),
+    BUILTIN("declare", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRTUZafilrtux", NULL),
     BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "v", NULL),
     BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmr", NULL),
     BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL),
@@ -60,7 +60,7 @@
     BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmr", NULL),
     BUILTIN("eval", BINF_PSPECIAL, bin_eval, 0, -1, BIN_EVAL, NULL, NULL),
     BUILTIN("exit", BINF_PSPECIAL, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
-    BUILTIN("export", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, BIN_EXPORT, "LRUZafilrtu", "x"),
+    BUILTIN("export", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, BIN_EXPORT, "LRTUZafilrtu", "x"),
     BUILTIN("false", 0, bin_false, 0, -1, 0, NULL, NULL),
     BUILTIN("fc", BINF_FCOPTS, bin_fc, 0, -1, BIN_FC, "nlreIRWAdDfEim", NULL),
     BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
@@ -78,7 +78,7 @@
     BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL),
     BUILTIN("kill", 0, bin_kill, 0, -1, 0, NULL, NULL),
     BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL),
-    BUILTIN("local", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRUZailrtu", NULL),
+    BUILTIN("local", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRTUZailrtu", NULL),
     BUILTIN("log", 0, bin_log, 0, 0, 0, NULL, NULL),
     BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL),
 
@@ -93,7 +93,7 @@
     BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
     BUILTIN("r", BINF_R, bin_fc, 0, -1, BIN_FC, "nrl", NULL),
     BUILTIN("read", 0, bin_read, 0, -1, 0, "rzu0123456789pkqecnAlE", NULL),
-    BUILTIN("readonly", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRUZafiltux", "r"),
+    BUILTIN("readonly", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRTUZafiltux", "r"),
     BUILTIN("rehash", 0, bin_hash, 0, 0, 0, "dfv", "r"),
     BUILTIN("return", BINF_PSPECIAL, bin_break, 0, 1, BIN_RETURN, NULL, NULL),
     BUILTIN("set", BINF_PSPECIAL, bin_set, 0, -1, 0, NULL, NULL),
@@ -107,7 +107,7 @@
     BUILTIN("trap", BINF_PSPECIAL, bin_trap, 0, -1, 0, NULL, NULL),
     BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL),
     BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsw", "v"),
-    BUILTIN("typeset", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRUZafilrtuxm", NULL),
+    BUILTIN("typeset", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "ALRTUZafilrtuxm", NULL),
     BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL),
     BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "m", "a"),
     BUILTIN("unfunction", 0, bin_unhash, 1, -1, 0, "m", "f"),
@@ -1468,11 +1468,11 @@
 /* function to set a single parameter */
 
 /**/
-int
+Param
 typeset_single(char *cname, char *pname, Param pm, int func,
-	       int on, int off, int roff, char *value)
+	       int on, int off, int roff, char *value, Param altpm)
 {
-    int usepm, tc;
+    int usepm, tc, keeplocal = 0;
 
     /* use the existing pm? */
     usepm = pm && !(pm->flags & PM_UNSET);
@@ -1490,24 +1490,24 @@
 	locallevel != pm->level && func != BIN_EXPORT)
 	usepm = 0;
 
-    /* attempting a type conversion? */
+    /* attempting a type conversion, or making a tied colonarray? */
     if ((tc = usepm && (((off & pm->flags) | (on & ~pm->flags)) &
-			(PM_INTEGER|PM_HASHED|PM_ARRAY))))
+			(PM_INTEGER|PM_HASHED|PM_ARRAY|PM_TIED))))
 	usepm = 0;
     if (tc && (pm->flags & PM_SPECIAL)) {
 	zerrnam(cname, "%s: can't change type of a special parameter",
 		pname, 0);
-	return 1;
+	return NULL;
     }
 
     if (usepm) {
 	if (!on && !roff && !value) {
 	    paramtab->printnode((HashNode)pm, 0);
-	    return 0;
+	    return pm;
 	}
 	if ((pm->flags & PM_RESTRICTED && isset(RESTRICTED))) {
 	    zerrnam(cname, "%s: restricted", pname, 0);
-	    return 1;
+	    return pm;
 	}
 	if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
 	    !(pm->flags & PM_READONLY & ~off))
@@ -1530,9 +1530,9 @@
 		setsparam(pname, ztrdup(value));
 	} else if (value) {
 	    zwarnnam(cname, "can't assign new value for array %s", pname, 0);
-	    return 1;
+	    return NULL;
 	}
-	return 0;
+	return pm;
     }
 
     /*
@@ -1542,10 +1542,15 @@
      * 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;
-	}
+	/* Maintain existing readonly/exported status... */
+	on |= ~off & (PM_READONLY|PM_EXPORTED) & pm->flags;
+	/* ...but turn off existing readonly so we can delete it */
+	pm->flags &= ~PM_READONLY;
+	/*
+	 * If we're just changing the type, we should keep the
+	 * variable at the current level of localness.
+	 */
+	keeplocal = pm->level;
 	/*
 	 * Try to carry over a value, but not when changing from,
 	 * to, or between non-scalar types.
@@ -1563,17 +1568,33 @@
     pm = createparam(pname, on & ~PM_READONLY);
     DPUTS(!pm, "BUG: parameter not created");
     pm->ct = auxlen;
-    if (func != BIN_EXPORT)
+
+    if (altpm && PM_TYPE(pm->flags) == PM_SCALAR) {
+	/*
+	 * It seems safer to set this here than in createparam(),
+	 * to make sure we only ever use the colonarr functions
+	 * when u.data is correctly set.
+	 */
+	pm->sets.cfn = colonarrsetfn;
+	pm->gets.cfn = colonarrgetfn;
+	pm->u.data = &altpm->u.arr;
+    }
+
+    if (keeplocal)
+	pm->level = keeplocal;
+    else 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;
+	/* the only safe thing to do here seems to be unset the param */
+	unsetparam_pm(pm, 0, 1);
+	return NULL;
     }
 
-    return 0;
+    return pm;
 }
 
 /* declare, export, integer, local, readonly, typeset */
@@ -1585,7 +1606,7 @@
     Param pm;
     Asgment asg;
     Comp com;
-    char *optstr = "aiALRZlurtxU";
+    char *optstr = "aiALRZlurtxUT";
     int on = 0, off = 0, roff, bit = PM_ARRAY;
     int i;
     int returnval = 0, printflags = 0;
@@ -1619,6 +1640,9 @@
 	off |= PM_UPPER;
     if (on & PM_HASHED)
 	off |= PM_ARRAY;
+    if (on & PM_TIED)
+	off |= PM_INTEGER | PM_ARRAY | PM_HASHED;
+
     on &= ~off;
 
     /* Given no arguments, list whatever the options specify. */
@@ -1631,6 +1655,58 @@
 	return 0;
     }
 
+    if (on & PM_TIED) {
+	Param apm;
+	char *name1;
+
+	if (ops['m']) {
+	    zwarnnam(name, "incompatible options for -T", NULL, 0);
+	    return 1;
+	}
+	on &= ~off;
+	if (!argv[1] || argv[2]) {
+	    zwarnnam(name, "-T requires names of scalar and array", NULL, 0);
+	    return 1;
+	}
+
+	/*
+	 * 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)))
+	    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,
+				(Param)paramtab->getnode(paramtab,
+							 asg->name),
+				func, on, off, roff, asg->value, apm))) {
+	    unsetparam_pm(apm, 1, 1);
+	    return 1;
+	}
+
+	pm->ename = name1;
+	apm->ename = ztrdup(asg->name);
+
+	return 0;
+    }
+    if (off & PM_TIED) {
+	zerrnam(name, "use unset to remove tied variables", NULL, 0);
+	return 1;
+    }
+
     /* With the -m option, treat arguments as glob patterns */
     if (ops['m']) {
 	MUSTUSEHEAP("typeset -m");
@@ -1664,8 +1740,8 @@
 	    }
 	    for (pmnode = firstnode(pmlist); pmnode; incnode(pmnode)) {
 		pm = (Param) getdata(pmnode);
-		if (typeset_single(name, pm->nam, pm, func, on, off, roff,
-				   asg->value))
+		if (!typeset_single(name, pm->nam, pm, func, on, off, roff,
+				    asg->value, NULL))
 		    returnval = 1;
 	    }
 	}
@@ -1680,9 +1756,9 @@
 	    returnval = 1;
 	    continue;
 	}
-	if (typeset_single(name, asg->name,
-			   (Param)paramtab->getnode(paramtab, asg->name),
-			   func, on, off, roff, asg->value))
+	if (!typeset_single(name, asg->name,
+			    (Param)paramtab->getnode(paramtab, asg->name),
+			    func, on, off, roff, asg->value, NULL))
 	    returnval = 1;
     }
     return returnval;
--- Src/params.c.tied	Mon Jan 25 13:28:56 1999
+++ Src/params.c	Thu Jan 28 18:21:13 1999
@@ -679,7 +679,7 @@
     Comp c;
 
     /* first parse any subscription flags */
-    if (v->pm && *s == '(' || *s == Inpar) {
+    if (v->pm && (*s == '(' || *s == Inpar)) {
 	int escapes = 0;
 	int waste;
 	for (s++; *s != ')' && *s != Outpar && s != *str; s++) {
@@ -1759,6 +1759,9 @@
     if (pm->flags & PM_UNIQUE)
 	uniqarray(x);
     pm->u.arr = x;
+    /* Arrays tied to colon-arrays may need to fix the environment */
+    if (pm->ename && x)
+	arrfixenv(pm->ename, x);
 }
 
 /* Function to get value of an association parameter */
@@ -1950,7 +1953,8 @@
 char *
 colonarrgetfn(Param pm)
 {
-    return zjoin(*(char ***)pm->u.data, ':');
+    char ***dptr = (char ***)pm->u.data;
+    return *dptr ? zjoin(*dptr, ':') : "";
 }
 
 /**/
@@ -1959,8 +1963,15 @@
 {
     char ***dptr = (char ***)pm->u.data;
 
-    freearray(*dptr);
-    *dptr = x ? colonsplit(x, pm->flags & PM_UNIQUE) : mkarray(NULL);
+    /*
+     * If this is tied to a parameter (rather than internal) array,
+     * the array itself may be NULL.  Otherwise, we have to make
+     * sure it doesn't ever get null.
+     */
+    if (*dptr)
+	freearray(*dptr);
+    *dptr = x ? colonsplit(x, pm->flags & PM_UNIQUE) :
+	(pm->flags & PM_TIED) ? NULL : mkarray(NULL);
     if (pm->ename)
 	arrfixenv(pm->nam, *dptr);
     zsfree(x);
@@ -2399,7 +2410,7 @@
     MUSTUSEHEAP("arrfixenv");
     if (t == path)
 	cmdnamtab->emptytable(cmdnamtab);
-    u = zjoin(t, ':');
+    u = t ? zjoin(t, ':') : "";
     len_s = strlen(s);
     pm = (Param) paramtab->getnode(paramtab, s);
     for (ep = environ; *ep; ep++)
@@ -2602,6 +2613,9 @@
     if (delunset)
 	pm->unsetfn(pm, 1);
     zsfree(pm->nam);
+    /* If this variable was tied by the user, ename was ztrdup'd */
+    if (pm->flags & PM_TIED)
+	zsfree(pm->ename);
     zfree(pm, sizeof(struct param));
 }
 
--- Src/zsh.h.tied	Thu Jan 28 14:59:50 1999
+++ Src/zsh.h	Thu Jan 28 17:58:23 1999
@@ -916,10 +917,11 @@
 #define PM_TAGGED	(1<<9)	/* tagged                                     */
 #define PM_EXPORTED	(1<<10)	/* exported                                   */
 #define PM_UNIQUE	(1<<11)	/* remove duplicates                          */
-#define PM_SPECIAL	(1<<12) /* special builtin parameter                  */
-#define PM_DONTIMPORT	(1<<13)	/* do not import this variable                */
-#define PM_RESTRICTED	(1<<14) /* cannot be changed in restricted mode       */
-#define PM_UNSET	(1<<15)	/* has null value                             */
+#define PM_TIED 	(1<<12)	/* array tied to colon-path or v.v. */
+#define PM_SPECIAL	(1<<13) /* special builtin parameter                  */
+#define PM_DONTIMPORT	(1<<14)	/* do not import this variable                */
+#define PM_RESTRICTED	(1<<15) /* cannot be changed in restricted mode       */
+#define PM_UNSET	(1<<16)	/* has null value                             */
 
 /* Flags for extracting elements of arrays and associative arrays */
 #define SCANPM_WANTVALS   (1<<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


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

* Re: PATCH: zsh-3.1.5-pws-5 + recent: typeset -T MYPATH mypath  (finally!)
  1999-01-28 17:25 PATCH: zsh-3.1.5-pws-5 + recent: typeset -T MYPATH mypath (finally!) Peter Stephenson
@ 1999-01-28 17:53 ` Bruce Stephens
  1999-01-29 16:56 ` Bart Schaefer
  1 sibling, 0 replies; 3+ messages in thread
From: Bruce Stephens @ 1999-01-28 17:53 UTC (permalink / raw)
  To: Zsh hackers list

Peter Stephenson <pws@ibmth.df.unipi.it> writes:

> Now I've tidied up bin_typeset() a bit, it's finally possible to make
> user-tiable path-like variables without the onset of suicidal
> feelings.  This has been requested for several years.  Maybe there's not
> even anyone left who wants it --- word splitting and joining has
> improved quite a lot since then.  The syntax is
>   typeset -T TEXINPUTS texinputs
> where the scalar has to come first, but there is no restriction on the
> names.

I think the issue was mostly with typeset -U.  Looking at the
description of -U, it suggests that it ought to work for
colon-separated things like PATH anyway.  Hmm...  No, it doesn't work
for random variables, only for special ones.

So, this patch *is* still worthwhile.  It ought to allow me to create
new colon-separated variables, and have the shell eliminate
duplicates.  Of course, what we really want is programmable setting
and reading of variables, like ksh93 has.


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

* Re: PATCH: zsh-3.1.5-pws-5 + recent: typeset -T MYPATH mypath (finally!)
  1999-01-28 17:25 PATCH: zsh-3.1.5-pws-5 + recent: typeset -T MYPATH mypath (finally!) Peter Stephenson
  1999-01-28 17:53 ` Bruce Stephens
@ 1999-01-29 16:56 ` Bart Schaefer
  1 sibling, 0 replies; 3+ messages in thread
From: Bart Schaefer @ 1999-01-29 16:56 UTC (permalink / raw)
  To: Peter Stephenson, Zsh hackers list

On Jan 28,  6:25pm, Peter Stephenson wrote:
} Subject: PATCH: zsh-3.1.5-pws-5 + recent: typeset -T MYPATH mypath (finall
}
} Now I've tidied up bin_typeset() a bit, it's finally possible to make
} user-tiable path-like variables without the onset of suicidal
} feelings.

Cool.

} Also, typeset +T doesn't work.
} 
} Feel free to destruction test this.

There seem to be some differences between "special" tied variables and user
defined ones.  Not a big deal, but it should perhaps be documented (lest
anyone get the idea that the special variables could cease to be special).
The stuff at <17> through <19> below might even be considered a bug, though
it behaves the same way as it did before this patch.

zagzig<1> typeset -T BAR bar
zagzig<2> bar=(x y z)
zagzig<3> typeset -U bar
zagzig<4> echo $BAR
x:y:z
zagzig<5> BAR=a:b:c:d:a
zagzig<6> echo $bar
a b c d a
zagzig<7> bar=($bar)
zagzig<8> echo $BAR
a:b:c:d
zagzig<9> bar="oops"
zagzig<10> echo $BAR

zagzig<11> bar=(a b c d)
zagzig<12> echo $BAR

zagzig<13> path="oops"
zagzig<14> echo $PATH
oops
zagzig<15> unset path
zagzig<16> echo $PATH

zagzig<17> path=(/usr/local/bin /bin /usr/bin /usr/sbin)
zagzig<18> echo $PATH

zagzig<19> printenv PATH
/usr/local/bin:/bin:/usr/bin:/usr/sbin

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


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

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

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-01-28 17:25 PATCH: zsh-3.1.5-pws-5 + recent: typeset -T MYPATH mypath (finally!) Peter Stephenson
1999-01-28 17:53 ` Bruce Stephens
1999-01-29 16:56 ` 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).