mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-10-31 18:10:56 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			673 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			673 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| ------------------------------
 | |
| GUIDELINES FOR ZSH DEVELOPMENT
 | |
| ------------------------------
 | |
| 
 | |
| Zsh is currently developed and maintained by the Zsh Development Group.
 | |
| This development takes place by mailing list.  Check the META-FAQ for the
 | |
| various zsh mailing lists and how to subscribe to them.  The development
 | |
| is very open and anyone is welcomed and encouraged to join and contribute.
 | |
| Because zsh is a very large package whose development can sometimes
 | |
| be very rapid, I kindly ask that people observe a few guidelines when
 | |
| contributing patches and feedback to the mailing list.  These guidelines
 | |
| are very simple and hopefully should make for a more orderly development
 | |
| of zsh.
 | |
| 
 | |
| Patches
 | |
| -------
 | |
| 
 | |
| * Send all patches to the mailing list rather than directly to me.
 | |
| 
 | |
| * Send only context diffs "diff -c oldfile newfile" or unified diffs
 | |
|   "diff -u oldfile newfile".  They are much easier to read and
 | |
|   understand while also allowing the patch program to patch more
 | |
|   intelligently.  Please make sure the filenames in the diff header
 | |
|   are relative to the top-level directory of the zsh distribution; for
 | |
|   example, it should say "Src/init.c" rather than "init.c" or
 | |
|   "zsh/Src/init.c".
 | |
| 
 | |
| * Please put only one bug fix or feature enhancement in a single patch and
 | |
|   only one patch per mail message.  This helps me to multiplex the many
 | |
|   (possibly conflicting) patches that I receive for zsh.  You shouldn't
 | |
|   needlessly split patches, but send them in the smallest LOGICAL unit.
 | |
| 
 | |
| * If a patch depends on other patches, then please say so.  Also please
 | |
|   mention what version of zsh this patch is for.
 | |
| 
 | |
| * Please test your patch and make sure it applies cleanly. It takes
 | |
|   considerably more time to manually merge a patch into the baseline code.
 | |
| 
 | |
| * There is now a zsh patch archive.  To have your patches appear in the
 | |
|   archive, send them to the mailing list with a Subject: line starting
 | |
|   with "PATCH:".
 | |
| 
 | |
| C coding style
 | |
| --------------
 | |
| 
 | |
| * The primary language is ANSI C as defined by the 1989 standard, but the
 | |
|   code should always be compatible with late K&R era compilers ("The C
 | |
|   Programming Language" 1st edition, plus "void" and "enum").  There are
 | |
|   many hacks to avoid the need to actually restrict the code to K&R C --
 | |
|   check out the configure tests -- but always bear the compatibility
 | |
|   requirements in mind.  In particular, preprocessing directives must
 | |
|   have the "#" unindented, and string pasting is not available.
 | |
| 
 | |
| * Conversely, there are preprocessor macros to provide safe access to some
 | |
|   language features not present in pure ANSI C, such as variable-length
 | |
|   arrays.  Always use the macros if you want to use these facilities.
 | |
| 
 | |
| * Avoid writing code that generates warnings under gcc with the default
 | |
|   options set by the configure script.  For example, write
 | |
|   "if ((foo = bar))" rather than "if (foo = bar)".
 | |
| 
 | |
| * Please try not using lines longer than 79 characters.
 | |
| 
 | |
| * The indent/brace style is Kernighan and Ritchie with 4 characters
 | |
|   indentations (with leading tab characters replacing sequences of
 | |
|   8 spaces).  This means that the opening brace is the last character
 | |
|   in the line of the if/while/for/do statement and the closing brace
 | |
|   has its own line:
 | |
| 
 | |
|       if (foo) {
 | |
| 	  do that
 | |
|       }
 | |
| 
 | |
| * Put only one simple statement on a line.  The body of an if/while/for/do
 | |
|   statement has its own line with 4 characters indentation even if there
 | |
|   are no braces.
 | |
| 
 | |
| * Do not use space between the function name and the opening parenthesis.
 | |
|   Use space after if/for/while.  Use space after type casts.
 | |
| 
 | |
| * Do not use (unsigned char) casts since some compilers do not handle
 | |
|   them properly.  Use the provided STOUC(X) macro instead.
 | |
| 
 | |
| * If you use emacs 19.30 or newer you can put the following line to your
 | |
|   ~/.emacs file to make these formatting rules the default:
 | |
| 
 | |
|     (add-hook 'c-mode-common-hook (function (lambda () (c-set-style "BSD"))))
 | |
| 
 | |
| * Function declarations must look like this:
 | |
| 
 | |
|   /**/
 | |
|   int
 | |
|   foo(char *s, char **p)
 | |
|   {
 | |
|       function body
 | |
|   }
 | |
| 
 | |
|   There must be an empty line, a line with "/**/", a line with the
 | |
|   type of the function, and finally the name of the function with typed
 | |
|   arguments.  These lines must not be indented.  The script generating
 | |
|   function prototypes and the ansi2knr program depend on this format.
 | |
|   If the function is not used outside the file it is defined in, it
 | |
|   should be declared "static"; this keyword goes on the type line,
 | |
|   before the return type.
 | |
| 
 | |
| * Global variable declarations must similarly be preceded by a
 | |
|   line containing only "/**/", for the prototype generation script.
 | |
|   The declaration itself should be all on one line (except for multi-line
 | |
|   initialisers).
 | |
| 
 | |
| * Leave a blank line between the declarations and statements in a compound
 | |
|   statement, if both are present.  Use blank lines elsewhere to separate
 | |
|   groups of statements in the interests of clarity.  There should never
 | |
|   be two consecutive blank lines.
 | |
| 
 | |
| Modules
 | |
| -------
 | |
| 
 | |
| Modules are described by a file named `foo.mdd' for a module
 | |
| `foo'. This file is actually a shell script that will sourced when zsh 
 | |
| is build. To describe the module it can/should set the following shell 
 | |
| variables:
 | |
| 
 | |
|   - moddeps         modules on which this module depends (default none)
 | |
|   - nozshdep        non-empty indicates no dependence on the `zsh' pseudo-module
 | |
|   - alwayslink      if non-empty, always link the module into the executable
 | |
|   - autobins        builtins defined by the module, for autoloading
 | |
|   - autoinfixconds  infix condition codes defined by the module, for
 | |
|                     autoloading (without the leading `-')
 | |
|   - autoprefixconds like autoinfixconds, but for prefix condition codes
 | |
|   - autoparams      parameters defined by the module, for autoloading
 | |
|   - objects         .o files making up this module (*must* be defined)
 | |
|   - proto           .pro files for this module (default generated from $objects)
 | |
|   - headers         extra headers for this module (default none)
 | |
|   - hdrdeps         extra headers on which the .mdh depends (default none)
 | |
|   - otherincs       extra headers that are included indirectly (default none)
 | |
| 
 | |
| Be sure to put the values in quotes. For further enlightenment have a
 | |
| look at the `mkmakemod.sh' script in the Src directory of the
 | |
| distribution.
 | |
| 
 | |
| Modules have to define four functions which will be called automatically
 | |
| by the zsh core. The first one, named `setup_foo' for a module named
 | |
| `foo', should set up any data needed in the module, at least any data
 | |
| other modules may be interested in. The second one, named `boot_foo',
 | |
| should register all builtins, conditional codes, and function wrappers
 | |
| (i.e. anything that will be visible to the user) and will be called
 | |
| after the `setup'-function. 
 | |
| The third one, named `cleanup_foo' for module `foo' is called when the
 | |
| user tries to unload a module and should de-register the builtins
 | |
| etc. The last function, `finish_foo' is called when the module is
 | |
| actually unloaded and should finalize all the data initialized in the 
 | |
| `setup'-function. Since the last two functions are only executed when
 | |
| the module is used as an dynamically loaded module you can surround
 | |
| it with `#ifdef MODULE' and `#endif'.
 | |
| In short, the `cleanup'-function should undo what the `boot'-function
 | |
| did, and the `finish'-function should undo what the `setup'-function
 | |
| did.
 | |
| All of these functions should return zero if they succeeded and
 | |
| non-zero otherwise.
 | |
| 
 | |
| Builtins are described in a table, for example:
 | |
| 
 | |
|   static struct builtin bintab[] = {
 | |
|     BUILTIN("example", 0, bin_example, 0, -1, 0, "flags", NULL),
 | |
|   };
 | |
| 
 | |
| Here `BUILTIN(...)' is a macro that simplifies the description. Its
 | |
| arguments are:
 | |
|   - the name of the builtin as a string
 | |
|   - optional flags (see BINF_* in zsh.h)
 | |
|   - the C-function implementing the builtin
 | |
|   - the minimum number of arguments the builtin needs
 | |
|   - the maximum number of arguments the builtin can handle or -1 if
 | |
|     the builtin can get any number of arguments
 | |
|   - an integer that is passed to the handler function and can be used
 | |
|     to distinguish builtins if the same C-function is used to
 | |
|     implement multiple builtins
 | |
|   - the options the builtin accepts, given as a string containing the
 | |
|     option characters (the above example makes the builtin accept the
 | |
|     options `f', `l', `a', `g', and `s')
 | |
|   - and finally a optional string containing option characters that
 | |
|     will always be reported as set when calling the C-function (this,
 | |
|     too, can be used when using one C-function to implement multiple
 | |
|     builtins)
 | |
| 
 | |
| The definition of the handler function looks like:
 | |
| 
 | |
|   /**/
 | |
|   static int
 | |
|   bin_example(char *nam, char **args, char *ops, int func)
 | |
|   {
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| The special comment /**/ is used by the zsh Makefile to generate the
 | |
| `*.pro' files. The arguments of the function are the number under
 | |
| which this function was invoked (the name of the builtin, but for
 | |
| functions that implement more than one builtin this information is
 | |
| needed). The second argument is the array of arguments *excluding* the 
 | |
| options that were defined in the struct and which are handled by the
 | |
| calling code. These options are given as the third argument. It is an
 | |
| array of 256 characters in which the n'th element is non-zero if the
 | |
| option with ASCII-value n was set (i.e. you can easily test if an
 | |
| option was used by `if (ops['f'])' etc.). The last argument is the
 | |
| integer value from the table (the sixth argument to `BUILTIN(...)').
 | |
| The integer return value by the function is the value returned by the
 | |
| builtin in shell level.
 | |
| 
 | |
| To register builtins in zsh and thereby making them visible to the
 | |
| user the function `addbuiltins()' is used:
 | |
| 
 | |
|   /**/
 | |
|   int
 | |
|   boot_example(Module m)
 | |
|   {
 | |
|     int ret;
 | |
| 
 | |
|     ret = addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| The arguments are the name of the module (taken from the argument in
 | |
| the example), the table of definitions and the number of entries in
 | |
| this table.
 | |
| The return value is 1 if everything went fine, 2 if at least one
 | |
| builtin couldn't be defined, and 0 if none of the builtin could be
 | |
| defined.
 | |
| 
 | |
| To de-register builtins use the function `deletebuiltins()':
 | |
| 
 | |
|   /**/
 | |
|   int
 | |
|   cleanup_example(Module m)
 | |
|   {
 | |
|     deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| The arguments and the return value are the same as for `addbuiltins()'
 | |
| 
 | |
| The definition of condition codes in modules is equally simple. First
 | |
| we need a table with the descriptions:
 | |
| 
 | |
|   static struct conddef cotab[] = {
 | |
|     CONDDEF("len", 0, cond_p_len, 1, 2, 0),
 | |
|     CONDDEF("ex", CONDF_INFIX, cond_i_ex, 0, 0, 0),
 | |
|   };
 | |
| 
 | |
| Again a macro is used, with the following arguments:
 | |
| 
 | |
|   - the name of the condition code without the leading hyphen
 | |
|     (i.e. the example makes the condition codes `-len' and `-ex'
 | |
|     usable in `[[...]]' constructs)
 | |
|   - an optional flag which for now can only be CONDF_INFIX; if this is 
 | |
|     given, an infix operator is created (i.e. the above makes
 | |
|     `[[ -len str ]]' and `[[ s1 -ex s2 ]]' available)
 | |
|   - the C-function implementing the conditional
 | |
|   - for non-infix condition codes the next two arguments give the
 | |
|     minimum and maximum number of string the conditional can handle
 | |
|     (i.e. `-len' can get one or two strings); as with builtins giving
 | |
|     -1 as the maximum number means that the conditional accepts any
 | |
|     number of strings
 | |
|   - finally as the last argument an integer that is passed to the
 | |
|     handler function that can be used to distinguish different
 | |
|     condition codes if the same C-function implements more than one of 
 | |
|     them
 | |
| 
 | |
| The definition for the function looks like:
 | |
| 
 | |
|   /**/
 | |
|   static int
 | |
|   cond_p_len(char **a, int id)
 | |
|   {
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| The first argument is an array containing the strings (NULL-terminated
 | |
| like the array of arguments for builtins), the second argument is the
 | |
| integer value stored in the table (the last argument to `CONDDEF(...)').
 | |
| The value returned by the function should be non-zero if the condition 
 | |
| is true and zero otherwise.
 | |
| 
 | |
| Note that no preprocessing is done on the strings. This means that
 | |
| no substitutions are performed on them and that they will be
 | |
| tokenized. There are three helper functions available:
 | |
| 
 | |
|   - char *cond_str(args, num, raw)
 | |
|     The first argument is the array of strings the handler function
 | |
|     got as an argument and the second one is an index into this array.
 | |
|     The return value is the num'th string from the array with
 | |
|     substitutions performed. If the last argument is zero, the string
 | |
|     will also be untokenized.
 | |
|   - long cond_val(args, num)
 | |
|     The arguments are the same as for cond_str(). The return value is
 | |
|     the result of the mathematical evaluation of the num'th string
 | |
|     form the array.
 | |
|   - int cond_match(args, num, str)
 | |
|     Again, the first two arguments are the same as for the other
 | |
|     functions. The third argument is any string. The result of the
 | |
|     function is non-zero if the the num'th string from the array taken 
 | |
|     as a glob pattern matches the given string.
 | |
| 
 | |
| Registering and de-resgitering condition codes with the shell is
 | |
| almost exactly the same as for builtins, using the functions
 | |
| `addconddefs()' and `deleteconddefs()' instead:
 | |
| 
 | |
|   /**/
 | |
|   int
 | |
|   boot_example(Module m)
 | |
|   {
 | |
|     int ret;
 | |
| 
 | |
|     ret = addconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab));
 | |
|     ...
 | |
|   }
 | |
| 
 | |
|   /**/
 | |
|   int
 | |
|   cleanup_example(Module m)
 | |
|   {
 | |
|     deleteconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab));
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| Arguments and return values are the same as for the functions for
 | |
| builtins.
 | |
| 
 | |
| For defining parameters, a module can call `createparam()' directly or 
 | |
| use a table to describe them, e.g.:
 | |
| 
 | |
|   static struct paramdef patab[] = {
 | |
|     PARAMDEF("foo", PM_INTEGER, NULL, get_foo, set_foo, unset_foo),
 | |
|     INTPARAMDEF("exint", &intparam),
 | |
|     STRPARAMDEF("exstr", &strparam),
 | |
|     ARRPARAMDEF("exarr", &arrparam),
 | |
|   };
 | |
| 
 | |
| There are four macros used:
 | |
| 
 | |
|   - PARAMDEF() gets as arguments:
 | |
|     - the name of the parameter
 | |
|     - the parameter flags to set for it (from the PM_* flags defined
 | |
|       in zsh.h)
 | |
|     - optionally a pointer to a variable holding the value of the
 | |
|       parameter
 | |
|     - three functions that will be used to get the value of the
 | |
|       parameter, store a value in the parameter, and unset the
 | |
|       parameter
 | |
|   - the other macros provide simple ways to define the most common
 | |
|     types of parameters; they get the name of the parameter and a
 | |
|     pointer to a variable holding the value as arguments; they are
 | |
|     used to define integer-, scalar-, and array-parameters, so the
 | |
|     variables whose addresses are given should be of type `long',
 | |
|     `char *', and `char **', respectively
 | |
| 
 | |
| For a description of how to write functions for getting or setting the 
 | |
| value of parameters, or how to write a function to unset a parameter,
 | |
| see the description of the following functions in the `params.c' file:
 | |
| 
 | |
|   - `intvargetfn()' and `intvarsetfn()' for integer parameters
 | |
|   - `strvargetfn()' and `strvarsetfn()' for scalar parameters
 | |
|   - `arrvargetfn()' and `arrvarsetfn()' for array parameters
 | |
|   - `stdunsetfn()' for unsetting parameters
 | |
| 
 | |
| Note that if one defines parameters using the last two macros (for
 | |
| scalars and arrays), the variable holding the value should be
 | |
| initialized to either `NULL' or to a a piece of memory created with
 | |
| `zalloc()'. But this memory should *not* be freed in the
 | |
| finish-function of the module because that will be taken care of by
 | |
| the `deleteparamdefs()' function described below.
 | |
| 
 | |
| To register the parameters in the zsh core, the function
 | |
| `addparamdefs()' is called as in:
 | |
| 
 | |
|   /**/
 | |
|   int
 | |
|   boot_example(Module m)
 | |
|   {
 | |
|     int ret;
 | |
| 
 | |
|     ret = addparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab))
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| The arguments and the return value are as for the functions used to
 | |
| add builtins and condition codes and like these, it should be called
 | |
| in the boot-function of the module. To remove the parameters defined,
 | |
| the function `deleteparamdefs()' should be called, again with the same 
 | |
| arguments and the same return value as for the functions to remove
 | |
| builtins and condition codes:
 | |
| 
 | |
|   /**/
 | |
|   int
 | |
|   cleanup_example(Module m)
 | |
|   {
 | |
|     deleteparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab));
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| Modules can also define function hooks. Other modules can then add
 | |
| functions to these hooks to make the first module call these functions
 | |
| instead of the default.
 | |
| 
 | |
| Again, an array is used to define hooks:
 | |
| 
 | |
|   static struct hookdef foohooks[] = {
 | |
|     HOOKDEF("foo", foofunc, 0),
 | |
|   };
 | |
| 
 | |
| The first argument of the macro is the name of the hook. This name
 | |
| is used whenever the hook is used. The second argument is the default
 | |
| function for the hook or NULL if no default function exists. The
 | |
| last argument is used to define flags for the hook. Currently only one
 | |
| such flag is defined: `HOOKF_ALL'. If this flag is given and more than
 | |
| one function was added to the hook, all functions will be called
 | |
| (including the default function). Otherwise only the last function
 | |
| added will be called.
 | |
| 
 | |
| The functions that can be used as default functions or that can be
 | |
| added to a hook have to be defined like:
 | |
| 
 | |
|   /**/
 | |
|   static int
 | |
|   foofunc(Hookdef h, void *data)
 | |
|   {
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| The first argument is a pointer to the struct defining the hook. The
 | |
| second argument is an arbitrary pointer that is given to the function
 | |
| used to invoke hooks (see below).
 | |
| 
 | |
| The functions to register and de-register hooks look like those for
 | |
| the other things that can be defined by modules:
 | |
| 
 | |
|   /**/
 | |
|   int
 | |
|   boot_foo(Module m)
 | |
|   {
 | |
|     int ret;
 | |
| 
 | |
|     ret = addhookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks))
 | |
|     ...
 | |
|   }
 | |
|   ...
 | |
|   /**/
 | |
|   int
 | |
|   cleanup_foo(Module m)
 | |
|   {
 | |
|     deletehookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks));
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| Modules that define hooks can invoke the function(s) registered for
 | |
| them by calling the function `runhook(name, data)'. The first argument 
 | |
| is the name of the hook and the second one is the pointer given to the 
 | |
| hook functions as their second argument. Hooks that have the `HOOKF_ALL' 
 | |
| flag call all function defined for them until one returns non-zero.
 | |
| The return value of `runhook()' is the return value of the last hook
 | |
| function called or zero if none was called.
 | |
| 
 | |
| To add a function to a hook, the function `addhookfunc(name, func)' is 
 | |
| called with the name of the hook and a hook function as arguments.
 | |
| Deleting them is done by calling `deletehookfunc(name, func)' with the 
 | |
| same arguments as for the corresponding call to `addhookfunc()'.
 | |
| 
 | |
| Alternative forms of the last three function are provided for hooks
 | |
| that are changed or called very often. These functions,
 | |
| `runhookdef(def, data)', `addhookdeffunc(def, func)', and
 | |
| `deletehookdeffunc(def, func)' get a pointer to the `hookdef'
 | |
| structure defining the hook instead of the name and otherwise behave
 | |
| like their counterparts.
 | |
| 
 | |
| Modules can also define function hooks. Other modules can then add
 | |
| functions to these hooks to make the first module call these functions
 | |
| instead of the default.
 | |
| 
 | |
| Again, an array is used to define hooks:
 | |
| 
 | |
|   static struct hookdef foohooks[] = {
 | |
|     HOOKDEF("foo", foofunc, 0),
 | |
|   };
 | |
| 
 | |
| The first argument of the macro is the name of the hook. This name
 | |
| is used whenever the hook is used. The second argument is the default
 | |
| function for the hook or NULL if no default function exists. The
 | |
| last argument is used to define flags for the hook. Currently only one
 | |
| such flag is defined: `HOOKF_ALL'. If this flag is given and more than
 | |
| one function was added to the hook, all functions will be called
 | |
| (including the default function). Otherwise only the last function
 | |
| added will be called.
 | |
| 
 | |
| The functions that can be used as default functions or that can be
 | |
| added to a hook have to be defined like:
 | |
| 
 | |
|   /**/
 | |
|   static int
 | |
|   foofunc(Hookdef h, void *data)
 | |
|   {
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| The first argument is a pointer to the struct defining the hook. The
 | |
| second argument is an arbitrary pointer that is given to the function
 | |
| used to invoke hooks (see below).
 | |
| 
 | |
| The functions to register and de-register hooks look like those for
 | |
| the other things that can be defined by modules:
 | |
| 
 | |
|   /**/
 | |
|   int
 | |
|   boot_foo(Module m)
 | |
|   {
 | |
|     int ret;
 | |
| 
 | |
|     ret = addhookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks))
 | |
|     ...
 | |
|   }
 | |
|   ...
 | |
|   /**/
 | |
|   int
 | |
|   cleanup_foo(Module m)
 | |
|   {
 | |
|     deletehookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks));
 | |
|     ...
 | |
|   }
 | |
| 
 | |
| Modules that define hooks can invoke the function(s) registered for
 | |
| them by calling the function `runhook(name, data)'. The first argument 
 | |
| is the name of the hook and the second one is the pointer given to the 
 | |
| hook functions as their second argument. Hooks that have the `HOOKF_ALL' 
 | |
| flag call all function defined for them until one returns non-zero.
 | |
| The return value of `runhook()' is the return value of the last hook
 | |
| function called or zero if none was called.
 | |
| 
 | |
| To add a function to a hook, the function `addhookfunc(name, func)' is 
 | |
| called with the name of the hook and a hook function as arguments.
 | |
| Deleting them is done by calling `deletehookfunc(name, func)' with the 
 | |
| same arguments as for the corresponding call to `addhookfunc()'.
 | |
| 
 | |
| Alternative forms of the last three function are provided for hooks
 | |
| that are changed or called very often. These functions,
 | |
| `runhookdef(def, data)', `addhookdeffunc(def, func)', and
 | |
| `deletehookdeffunc(def, func)' get a pointer to the `hookdef'
 | |
| structure defining the hook instead of the name and otherwise behave
 | |
| like their counterparts.
 | |
| 
 | |
| Finally, modules can define wrapper functions. These functions are
 | |
| called whenever a shell function is to be executed.
 | |
| 
 | |
| The definition is simple:
 | |
| 
 | |
|   static struct funcwrap wrapper[] = {
 | |
|     WRAPDEF(ex_wrapper),
 | |
|   };
 | |
| 
 | |
| The macro `WRAPDEF(...)' gets the C-function as its only argument.
 | |
| This function should be defined like:
 | |
| 
 | |
|   /**/
 | |
|   static int
 | |
|   ex_wrapper(List list, FuncWrap w, char *name)
 | |
|   {
 | |
|     ...
 | |
|     runshfunc(list, w, name);
 | |
|     ...
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
| The first two arguments should only be used to pass them to
 | |
| `runshfunc()' which will execute the shell function. The last argument 
 | |
| is the name of the function to be executed. The arguments passed to
 | |
| the function can be accessed vie the global variable `pparams' (a
 | |
| NULL-terminated array of strings).
 | |
| The return value of the wrapper function should be zero if it calls
 | |
| `runshfunc()' itself and non-zero otherwise. This can be used for
 | |
| wrapper functions that only need to run under certain conditions or
 | |
| that don't need to clean anything up after the shell function has
 | |
| finished:
 | |
| 
 | |
|   /**/
 | |
|   static int
 | |
|   ex_wrapper(List list, FuncWrap w, char *name)
 | |
|   {
 | |
|     if (wrapper_need_to_run) {
 | |
|       ...
 | |
|       runshfunc(list, w, name);
 | |
|       ...
 | |
|       return 0;
 | |
|     }
 | |
|     return 1;
 | |
|   }
 | |
| 
 | |
| Inside these wrapper functions the global variable `sfcontext' will be 
 | |
| set to a vlue indicating the circumstances under which the shell
 | |
| function was called. It can have any of the following values:
 | |
| 
 | |
|   - SFC_DIRECT:   the function was invoked directly by the user
 | |
|   - SFC_SIGNAL:   the function was invoked as a signal handler
 | |
|   - SFC_HOOK:     the function was automatically invoked as one of the
 | |
|                   special functions known by the shell (like `chpwd')
 | |
|   - SFC_WIDGET:   the function was called from the zsh line editor as a
 | |
|                   user-defined widget
 | |
|   - SFC_COMPLETE: the function was called from the completion code
 | |
|                   (e.g. with `compctl -K func')
 | |
| 
 | |
| If a module invokes a shell function (e.g. as a hook function), the
 | |
| value of this variable should only be changed temporarily and restored
 | |
| to its previous value after the shell function has finished.
 | |
| 
 | |
| There is a problem when the user tries to unload a module that has
 | |
| defined wrappers from a shell function. In this case the module can't
 | |
| be unloaded immediately since the wrapper function is still on the
 | |
| call stack. The zsh code delays unloading modules until all wrappers
 | |
| from them have finished. To hide this from the user, the module's
 | |
| cleanup function is run immediatly so that all builtins, condition
 | |
| codes, and wrapper function defined by the module are
 | |
| de-registered. But if there is some module-global state that has to be 
 | |
| finalized (e.g. some memory that has to be freed) and that is used by
 | |
| the wrapper functions finalizing this data in the cleanup function
 | |
| won't work.
 | |
| This is why ther are two functions each for the initialization and
 | |
| finalization of modules. The `boot'- and `cleanup'-functions are run
 | |
| whenever the user calls `zmodload' or `zmodload -u' and should only
 | |
| register or de-register the module's interface that is visible to the
 | |
| user. Anything else should be done in the `setup'- and
 | |
| `finish'-functions. Otherwise modules that other modules depend upon
 | |
| may destroy their state too early and wrapper functions in the latter
 | |
| modules may stop working since the state they use is already destroyed.
 | |
| 
 | |
| Documentation
 | |
| -------------
 | |
| 
 | |
| * Edit only the .yo files.  All other formats (man pages, TeXinfo, HTML,
 | |
|   etc.) are automatically generated from the yodl source.
 | |
| 
 | |
| * Always use the correct markup.  em() is used for emphasis, and bf()
 | |
|   for citations.  tt() marks text that is literal input to or output
 | |
|   from the shell.  var() marks metasyntactic variables.
 | |
| 
 | |
| * In addition to appropriate markup, always use quotes (`') where
 | |
|   appropriate.  Specifically, use quotes to mark text that is not a part
 | |
|   of the actual text of the documentation (i.e., that it is being quoted).
 | |
|   In principle, all combinations of quotes and markup are possible,
 | |
|   because the purposes of the two devices are completely orthogonal.
 | |
|   For example,
 | |
| 
 | |
|       Type `tt(xyzzy)' to let zsh know you have played tt(advent).
 | |
|       Saying `plugh' aloud doesn't have much effect, however.
 | |
| 
 | |
|   In this case, "zsh" is normal text (a name), "advent" is a command name
 | |
|   ocurring in the main text, "plugh" is a normal word that is being quoted
 | |
|   (it's the user that says `plugh', not the documentation), and "xyzzy"
 | |
|   is some text to be typed literally that is being quoted.
 | |
| 
 | |
| * For multiple-line pieces of text that should not be filled, there are
 | |
|   various models.
 | |
|   - If the text is pure example, i.e. with no metasyntactic variables etc.,
 | |
|     it should be included within `example(...)'.  The text will be
 | |
|     indented, will not be filled and will be put into a fixed width font.
 | |
|   - If the text includes mixed fonts, it should be included within
 | |
|     `indent(...)'.  The text is now filled unless `nofill(...)' is also
 | |
|     used, and explicit font-changing commands are required inside.
 | |
|   - If the text appears inside some other format, such as for example the
 | |
|     `item()' list structure, then the instruction `nofill(...)', which
 | |
|     simply turns off filling should be used; as with `indent(...)',
 | |
|     explicit font changing commands are required.  This can be used
 | |
|     without `indent()' when no identation is required, e.g. if the
 | |
|     accumulated indentation would otherwise be too long.
 | |
|   All the above should appear on their own, separated by newlines from the
 | |
|   surrounding text.  No extra newlines after the opening or before the
 | |
|   closing parenthesis are required.
 |