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

Misc. module stuff

It has been a while since I worked on a module and the last one had
only one autoloaded builtin.  This is stuff I've noticed while working
on a more complicated case.

The .mdd file provides two ways to declare autoloads:


The former are loaded in zsh native mode, but the latter are loaded in
every other emulation mode. This means jumping through some
complicated hoops to, for example, autoload something only in "ksh"
emulation and not in "sh" emulation.

Further, it's implied by zsh-development-guide that it's not possible
to have a .mdd where autofeatures is empty but autofeatures_emu is not
empty.  Is this intentional?  It seems necessary to duplicate
autofeatures in autofeatures_emu if there are any items that should be
autoloaded in both cases.

Speaking of zsh-development-guide, it says:
  - PARAMDEF() gets as arguments:
    - optionally a pointer to a variable holding the value of the
   - a GSU pointer to the three functions that will be used to get
      the value of the parameter, store a value in the parameter,
      and unset the parameter
The part about a pointer to a variable holding the value is only
correct if the GSU pointer is NULL or the setfn is explicitly
expecting a pointer-to-object (which the default one does).  This can
be fixed by editing the document.

In zsh.h there is a comment
 * ... Parameters used in a module that don't
 * have special behaviour shouldn't be declared in a table but
 * should just be added with the standard parameter functions.
This can also be added to zsh-development-guide.  However, parameters
mentioned in autofeatures must be declared in the tables, or an error
message results at module load time:
   zsh: module `zsh/example' has no such feature: `p:exref': autoload cancelled
Is there no correct way to declare a feature that is enabled only via
the setup_ function?

Curiously even after that "cancelled" message, referencing a different
autoloaded feature might reload the module again, successfully.

Quoting dev guide again:
  The function named `boot_' should register function wrappers, hooks and
  anything that will be visible to the user that is not handled by features_
  and enables_ (so features should not be turned on here).  It will be called
  after the `setup_'-function, and also after the initial set of features
  have been set by calls to `features_' and `enables_'.
As far as I can tell this is false: boot_ is not called after setup_,
only once after the initial call to features_ and enables_, and is not
called if features_ "fails".   The admonition that features_ and
enables_ might be called multiple times is correct.

One of the things I think it is useful for a function wrapper to do,
is to create local parameters in the function scope.  It took me quite
a bit of experimentation to figure out how to do this, because
startparamscope() is not called until after control has passed out of
the wrapper.  The trick is:
* Increment locallevel
* Call pm = createparam(name, PM_LOCAL) to get a Param pointer
* Assign pm->level = locallevel (this, I was not expecting to need)
* Set the value of the parameter
* Decrement locallevel again.
This is all best done inside queue_signals/unqueue_signals.  Don't
forget to decrement before calling either runshfunc(...) or return 1;

A drawback to doing the above is that if the user writes a function
containing "local foo" for some wrapper-created local "foo", typeset
will print out the value of that variable.

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