Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [zsh 4.0.1-pre-2 bug] named directories disappear

On Apr 3, 10:16am, Sven Wischnowsky wrote:
} That's caused by adduserdir() in utils.c.  The test in utils.c:533
} succeeds when the local variable is set and then the namedir-entry is
} removed.
} I'm not sure how we should solve this.  Maybe just make `hash -d x=...'
} set the parameter `x', too?  Once one has done the above, one can't
} set $x anymore anyway.

True, but that changes the sense of ${x:-...} tests.  Maybe that's not a
very significant concern ...

An even more radical suggestion:  remove the getnode2() test from the
condition at line 530, so that one must both set the parameter AND use
it in a ~param expression before the nameddirtab entry gets clobbered?

But, sigh, that would mean always looking up the parameter to see if
it had changed, which sort of spoils the purpose of the nameddir hash.

} Or maybe the other way round?  Use a flag in nameddirtab entries that
} says that the entry was added with `hash -d ...' and don't change or
} remove such entries when the corresponding parameter is modified?

How about this:

Insted of a flag, we store (pm->level + 1) in the nameddirtab entry.
`hash -d' sets this field to zero (as if locallevel == -1).

When a parameter is set or unset, the corresponding nameddirtab entry:
may be changed only if (nd->level > 0 || pm->level == 0), and
may be deleted only if (nd->level > pm->level).

This implies that entries created with "hash -d" can be removed either
with "hash -r" or by assigning to a global, but not by assigning to a
local; it also implies that if a nameddirtab entry is changed, then
either (1) the global parameter changed, or (2) there must be another
parameter (in a surrounding scope) from which the entry can be restored
when the current scope ends, or (3) there was no entry in a surrounding

It might be possible to do the equivalent with a couple of bits in the
existing nd->flags, because I think "deleted only if ((nd->level > 0 &&
pm->level > 0) || pm->level == 0)" is sufficient; so you need one bit
for "this was set with hash -d" and one bit for "this was set from a
local parameter", and then you can work it out.

My concern with any plan that locks nameddir entries is that a function
might set a local and then use it as a namedir, only to have that fail
because of a previous "hash -d".

I'm not sure there's any right way out of this, only a least wrong ...

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

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   

Messages sorted by: Reverse Date, Date, Thread, Author