2 * module.c - deal with dynamic modules
4 * This file is part of zsh, the Z shell.
6 * Copyright (c) 1996-1997 Zoltán Hidvégi
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
15 * In no event shall Zoltán Hidvégi or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Zoltán Hidvégi and the Zsh Development Group have been advised of
19 * the possibility of such damage.
21 * Zoltán Hidvégi and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose. The software
24 * provided hereunder is on an "as is" basis, and Zoltán Hidvégi and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
33 * List of linked-in modules.
34 * This is set up at boot and remains for the life of the shell;
35 * entries do not appear in "zmodload" listings.
39 LinkList linkedmodules
;
41 /* $module_path ($MODULE_PATH) */
49 mod_export HashTable modulestab
;
52 * Bit flags passed as the "flags" argument of a autofeaturefn_t.
53 * Used in other places, such as the final argument to
54 * do_module_features().
58 * `-i' option: ignore errors pertaining to redefinitions,
59 * or indicate to do_module_features() that it should be
63 /* If a condition, condition is infix rather than prefix */
66 * Enable all features in the module when autoloading.
67 * This is the traditional zmodload -a behaviour;
68 * zmodload -Fa only enables features explicitly marked for
71 FEAT_AUTOALL
= 0x0004,
73 * Remove feature: alternative to "-X:NAME" used if
74 * X is passed separately from NAME.
78 * For do_module_features(). Check that any autoloads
79 * for the module are actually provided.
81 FEAT_CHECKAUTO
= 0x0010
85 * All functions to add or remove autoloadable features fit
86 * the following prototype.
88 * "module" is the name of the module.
90 * "feature" is the name of the feature, minus any type prefix.
92 * "flags" is a set of the bits above.
94 * The return value is 0 for success, -1 for failure with no
95 * message needed, and one of the following to indicate the calling
96 * function should print a message:
98 * 1: failed to add [type] `[feature]'
99 * 2: [feature]: no such [type]
100 * 3: [feature]: [type] is already defined
102 typedef int (*autofeaturefn_t
)(const char *module
, const char *feature
,
105 /* Bits in the second argument to find_module. */
108 * Resolve any aliases to the underlying module.
110 FINDMOD_ALIASP
= 0x0001,
112 * Create an element for the module in the list if
115 FINDMOD_CREATE
= 0x0002,
119 freemodulenode(HashNode hn
)
121 Module m
= (Module
) hn
;
123 if (m
->node
.flags
& MOD_ALIAS
)
127 freelinklist(m
->autoloads
, freestr
);
129 freelinklist(m
->deps
, freestr
);
130 zfree(m
, sizeof(*m
));
133 /* flags argument to printmodulenode */
135 /* -L flag, output zmodload commands */
136 PRINTMOD_LIST
= 0x0001,
138 PRINTMOD_EXIST
= 0x0002,
140 PRINTMOD_ALIAS
= 0x0004,
142 PRINTMOD_DEPS
= 0x0008,
144 PRINTMOD_FEATURES
= 0x0010,
145 /* -l flag in combination with -L flag */
146 PRINTMOD_LISTALL
= 0x0020,
148 PRINTMOD_AUTO
= 0x0040
151 /* Scan function for printing module details */
154 printmodulenode(HashNode hn
, int flags
)
156 Module m
= (Module
)hn
;
158 * If we check for a module loaded under an alias, we
159 * need the name of the alias. We can use it in other
162 const char *modname
= m
->node
.nam
;
164 if (flags
& PRINTMOD_DEPS
) {
166 * Print the module's dependencies.
173 if (flags
& PRINTMOD_LIST
) {
174 printf("zmodload -d ");
175 if (modname
[0] == '-')
176 fputs("-- ", stdout
);
177 quotedzputs(modname
, stdout
);
179 nicezputs(modname
, stdout
);
182 for (n
= firstnode(m
->deps
); n
; incnode(n
)) {
184 if (flags
& PRINTMOD_LIST
)
185 quotedzputs((char *) getdata(n
), stdout
);
187 nicezputs((char *) getdata(n
), stdout
);
189 } else if (flags
& PRINTMOD_EXIST
) {
191 * Just print the module name, provided the module is
192 * present under an alias or otherwise.
194 if (m
->node
.flags
& MOD_ALIAS
) {
195 if (!(flags
& PRINTMOD_ALIAS
) ||
196 !(m
= find_module(m
->u
.alias
, FINDMOD_ALIASP
, NULL
)))
199 if (!m
->u
.handle
|| (m
->node
.flags
& MOD_UNLOAD
))
201 nicezputs(modname
, stdout
);
202 } else if (m
->node
.flags
& MOD_ALIAS
) {
204 * Normal listing, but for aliases.
206 if (flags
& PRINTMOD_LIST
) {
207 printf("zmodload -A ");
208 if (modname
[0] == '-')
209 fputs("-- ", stdout
);
210 quotedzputs(modname
, stdout
);
212 quotedzputs(m
->u
.alias
, stdout
);
214 nicezputs(modname
, stdout
);
215 fputs(" -> ", stdout
);
216 nicezputs(m
->u
.alias
, stdout
);
218 } else if (m
->u
.handle
|| (flags
& PRINTMOD_AUTO
)) {
222 if (flags
& PRINTMOD_LIST
) {
224 * List with -L format. Possibly we are printing
225 * features, either enables or autoloads.
227 char **features
= NULL
;
229 if (flags
& PRINTMOD_AUTO
) {
230 if (!m
->autoloads
|| !firstnode(m
->autoloads
))
232 } else if (flags
& PRINTMOD_FEATURES
) {
233 if (features_module(m
, &features
) ||
234 enables_module(m
, &enables
) ||
239 if (flags
& PRINTMOD_AUTO
) {
240 fputs("-Fa ", stdout
);
242 fputs("-F ", stdout
);
243 if(modname
[0] == '-')
244 fputs("-- ", stdout
);
245 quotedzputs(modname
, stdout
);
246 if (flags
& PRINTMOD_AUTO
) {
248 for (an
= firstnode(m
->autoloads
); an
; incnode(an
)) {
250 quotedzputs((char *)getdata(an
), stdout
);
252 } else if (features
) {
254 while ((f
= *features
++)) {
256 if (flags
& PRINTMOD_LISTALL
)
257 printf(" %s", on
? "+" : "-");
262 quotedzputs(f
, stdout
);
266 nicezputs(modname
, stdout
);
274 newmoduletable(int size
, char const *name
)
277 ht
= newhashtable(size
, name
, NULL
);
280 ht
->emptytable
= emptyhashtable
;
281 ht
->filltable
= NULL
;
282 ht
->cmpnodes
= strcmp
;
283 ht
->addnode
= addhashnode
;
284 /* DISABLED is not supported */
285 ht
->getnode
= gethashnode2
;
286 ht
->getnode2
= gethashnode2
;
287 ht
->removenode
= removehashnode
;
288 ht
->disablenode
= NULL
;
289 ht
->enablenode
= NULL
;
290 ht
->freenode
= freemodulenode
;
291 ht
->printnode
= printmodulenode
;
296 /************************************************************************
297 * zsh/main standard module functions
298 ************************************************************************/
300 /* The `zsh/main' module contains all the base code that can't actually be *
301 * built as a separate module. It is initialised by main(), so there's *
302 * nothing for the boot function to do. */
306 setup_(UNUSED(Module m
))
313 features_(UNUSED(Module m
), UNUSED(char ***features
))
316 * There are lots and lots of features, but they're not
324 enables_(UNUSED(Module m
), UNUSED(int **enables
))
331 boot_(UNUSED(Module m
))
338 cleanup_(UNUSED(Module m
))
345 finish_(UNUSED(Module m
))
351 /************************************************************************
352 * Module utility functions
353 ************************************************************************/
355 /* This registers a builtin module. */
359 register_module(char *n
, Module_void_func setup
,
360 Module_features_func features
,
361 Module_enables_func enables
,
362 Module_void_func boot
,
363 Module_void_func cleanup
,
364 Module_void_func finish
)
368 m
= (Linkedmod
) zalloc(sizeof(*m
));
372 m
->features
= features
;
373 m
->enables
= enables
;
375 m
->cleanup
= cleanup
;
378 zaddlinknode(linkedmodules
, m
);
381 /* Check if a module is linked in. */
385 module_linked(char const *name
)
389 for (node
= firstnode(linkedmodules
); node
; incnode(node
))
390 if (!strcmp(((Linkedmod
) getdata(node
))->name
, name
))
391 return (Linkedmod
) getdata(node
);
397 /************************************************************************
398 * Support for the various feature types.
400 ************************************************************************/
402 /* addbuiltin() can be used to add a new builtin. It returns zero on *
403 * success, 1 on failure. The only possible type of failure is that *
404 * a builtin with the specified name already exists. An autoloaded *
405 * builtin can be replaced using this function. */
409 addbuiltin(Builtin b
)
411 Builtin bn
= (Builtin
) builtintab
->getnode2(builtintab
, b
->node
.nam
);
412 if (bn
&& (bn
->node
.flags
& BINF_ADDED
))
415 builtintab
->freenode(builtintab
->removenode(builtintab
, b
->node
.nam
));
416 builtintab
->addnode(builtintab
, b
->node
.nam
, b
);
420 /* Define an autoloadable builtin. It returns 0 on success, or 1 on *
421 * failure. The only possible cause of failure is that a builtin *
422 * with the specified name already exists. */
426 add_autobin(const char *module
, const char *bnam
, int flags
)
431 bn
= zshcalloc(sizeof(*bn
));
432 bn
->node
.nam
= ztrdup(bnam
);
433 bn
->optstr
= ztrdup(module
);
434 if (flags
& FEAT_AUTOALL
)
435 bn
->node
.flags
|= BINF_AUTOALL
;
436 if ((ret
= addbuiltin(bn
))) {
437 builtintab
->freenode(&bn
->node
);
438 if (!(flags
& FEAT_IGNORE
))
444 /* Remove the builtin added previously by addbuiltin(). Returns *
445 * zero on succes and -1 if there is no builtin with that name. */
449 deletebuiltin(const char *nam
)
453 bn
= (Builtin
) builtintab
->removenode(builtintab
, nam
);
456 builtintab
->freenode(&bn
->node
);
460 /* Remove an autoloaded added by add_autobin */
464 del_autobin(UNUSED(const char *module
), const char *bnam
, int flags
)
466 Builtin bn
= (Builtin
) builtintab
->getnode2(builtintab
, bnam
);
468 if(!(flags
& FEAT_IGNORE
))
470 } else if (bn
->node
.flags
& BINF_ADDED
) {
471 if (!(flags
& FEAT_IGNORE
))
480 * Manipulate a set of builtins. This should be called
481 * via setfeatureenables() (or, usually, via the next level up,
484 * "nam" is the name of the calling code builtin, probably "zmodload".
486 * "binl" is the builtin table containing an array of "size" builtins.
488 * "e" is either NULL, in which case all builtins in the
489 * table are removed, or else an array corresponding to "binl"
490 * with a 1 for builtins that are to be added and a 0 for builtins
491 * that are to be removed. Any builtin already in the appropriate
492 * state is left alone.
494 * Returns 1 on any error, 0 for success. The recommended way
495 * of handling errors is to compare the enables passed down
496 * with the set retrieved after the error to find what failed.
501 setbuiltins(char const *nam
, Builtin binl
, int size
, int *e
)
505 for(n
= 0; n
< size
; n
++) {
506 Builtin b
= &binl
[n
];
508 if (b
->node
.flags
& BINF_ADDED
)
512 "name clash when adding builtin `%s'", b
->node
.nam
);
515 b
->node
.flags
|= BINF_ADDED
;
518 if (!(b
->node
.flags
& BINF_ADDED
))
520 if (deletebuiltin(b
->node
.nam
)) {
521 zwarnnam(nam
, "builtin `%s' already deleted", b
->node
.nam
);
524 b
->node
.flags
&= ~BINF_ADDED
;
532 * Add multiple builtins. binl points to a table of `size' builtin
533 * structures. Those for which (.flags & BINF_ADDED) is false are to be
534 * added; that flag is set if they succeed.
536 * If any fail, an error message is printed, using nam as the leading name.
537 * Returns 0 on success, 1 for any failure.
539 * This should not be used from a module; instead, use handlefeatures().
544 addbuiltins(char const *nam
, Builtin binl
, int size
)
548 for(n
= 0; n
< size
; n
++) {
549 Builtin b
= &binl
[n
];
550 if(b
->node
.flags
& BINF_ADDED
)
553 zwarnnam(nam
, "name clash when adding builtin `%s'", b
->node
.nam
);
556 b
->node
.flags
|= BINF_ADDED
;
563 /************************************************************************
565 ************************************************************************/
567 /* The list of function wrappers defined. */
572 /* This adds a definition for a wrapper. Return value is one in case of *
573 * error and zero if all went fine. */
577 addwrapper(Module m
, FuncWrap w
)
582 * We can't add a wrapper to an alias, since it's supposed
583 * to behave identically to the resolved module. This shouldn't
584 * happen since we usually add wrappers when a real module is
587 if (m
->node
.flags
& MOD_ALIAS
)
590 if (w
->flags
& WRAPF_ADDED
)
592 for (p
= wrappers
, q
= NULL
; p
; q
= p
, p
= p
->next
);
598 w
->flags
|= WRAPF_ADDED
;
604 /* This removes the given wrapper definition from the list. Returned is *
605 * one in case of error and zero otherwise. */
609 deletewrapper(Module m
, FuncWrap w
)
613 if (m
->node
.flags
& MOD_ALIAS
)
616 if (w
->flags
& WRAPF_ADDED
) {
617 for (p
= wrappers
, q
= NULL
; p
&& p
!= w
; q
= p
, p
= p
->next
);
624 p
->flags
&= ~WRAPF_ADDED
;
633 /************************************************************************
635 ************************************************************************/
637 /* The list of module-defined conditions. */
640 mod_export Conddef condtab
;
642 /* This gets a condition definition with the given name. The first *
643 * argument says if we have to look for an infix condition. The last *
644 * argument is non-zero if we should autoload modules if needed. */
648 getconddef(int inf
, const char *name
, int autol
)
654 for (p
= condtab
; p
; p
= p
->next
) {
655 if ((!!inf
== !!(p
->flags
& CONDF_INFIX
)) &&
656 !strcmp(name
, p
->name
))
659 if (autol
&& p
&& p
->module
) {
661 * This is a definition for an autoloaded condition; load the
662 * module if we haven't tried that already.
665 (void)ensurefeature(p
->module
,
666 (p
->flags
& CONDF_INFIX
) ? "C:" : "c:",
667 (p
->flags
& CONDF_AUTOALL
) ? NULL
: name
);
681 * This adds the given condition definition. The return value is zero on *
682 * success and 1 on failure. If there is a matching definition for an *
683 * autoloaded condition, it is removed.
685 * This is used for adding both an autoload definition or
686 * a real condition. In the latter case the caller is responsible
687 * for setting the CONDF_ADDED flag.
692 addconddef(Conddef c
)
694 Conddef p
= getconddef((c
->flags
& CONDF_INFIX
), c
->name
, 0);
697 if (!p
->module
|| (p
->flags
& CONDF_ADDED
))
699 /* There is an autoload definition. */
708 /* This removes the given condition definition from the list(s). If this *
709 * is a definition for a autoloaded condition, the memory is freed. */
713 deleteconddef(Conddef c
)
717 for (p
= condtab
, q
= NULL
; p
&& p
!= c
; q
= p
, p
= p
->next
);
726 /* autoloaded, free it */
729 zfree(p
, sizeof(*p
));
737 * Add or remove sets of conditions. The interface is
738 * identical to setbuiltins().
743 setconddefs(char const *nam
, Conddef c
, int size
, int *e
)
749 if (c
->flags
& CONDF_ADDED
) {
754 zwarnnam(nam
, "name clash when adding condition `%s'",
758 c
->flags
|= CONDF_ADDED
;
761 if (!(c
->flags
& CONDF_ADDED
)) {
765 if (deleteconddef(c
)) {
766 zwarnnam(nam
, "condition `%s' already deleted", c
->name
);
769 c
->flags
&= ~CONDF_ADDED
;
777 /* This adds a definition for autoloading a module for a condition. */
781 add_autocond(const char *module
, const char *cnam
, int flags
)
785 c
= (Conddef
) zalloc(sizeof(*c
));
787 c
->name
= ztrdup(cnam
);
788 c
->flags
= ((flags
& FEAT_INFIX
) ? CONDF_INFIX
: 0);
789 if (flags
& FEAT_AUTOALL
)
790 c
->flags
|= CONDF_AUTOALL
;
791 c
->module
= ztrdup(module
);
796 zfree(c
, sizeof(*c
));
798 if (!(flags
& FEAT_IGNORE
))
804 /* Remove a condition added with add_autocond */
808 del_autocond(UNUSED(const char *modnam
), const char *cnam
, int flags
)
810 Conddef cd
= getconddef((flags
& FEAT_INFIX
) ? 1 : 0, cnam
, 0);
813 if (!(flags
& FEAT_IGNORE
)) {
816 } else if (cd
->flags
& CONDF_ADDED
) {
817 if (!(flags
& FEAT_IGNORE
))
825 /************************************************************************
827 ************************************************************************/
829 /* This list of hook functions defined. */
834 /* Find a hook definition given the name. */
842 for (p
= hooktab
; p
; p
= p
->next
)
843 if (!strcmp(n
, p
->name
))
848 /* This adds the given hook definition. The return value is zero on *
849 * success and 1 on failure. */
853 addhookdef(Hookdef h
)
855 if (gethookdef(h
->name
))
860 h
->funcs
= znewlinklist();
866 * This adds multiple hook definitions. This is like addbuiltins().
867 * This allows a NULL module because we call it from init.c.
872 addhookdefs(Module m
, Hookdef h
, int size
)
878 zwarnnam(m
? m
->node
.nam
: NULL
,
879 "name clash when adding hook `%s'", h
->name
);
887 /* Delete hook definitions. */
891 deletehookdef(Hookdef h
)
895 for (p
= hooktab
, q
= NULL
; p
&& p
!= h
; q
= p
, p
= p
->next
);
904 freelinklist(p
->funcs
, NULL
);
908 /* Remove multiple hook definitions. */
912 deletehookdefs(UNUSED(Module m
), Hookdef h
, int size
)
917 if (deletehookdef(h
))
924 /* Add a function to a hook. */
928 addhookdeffunc(Hookdef h
, Hookfn f
)
930 zaddlinknode(h
->funcs
, (void *) f
);
937 addhookfunc(char *n
, Hookfn f
)
939 Hookdef h
= gethookdef(n
);
942 return addhookdeffunc(h
, f
);
946 /* Delete a function from a hook. */
950 deletehookdeffunc(Hookdef h
, Hookfn f
)
954 for (p
= firstnode(h
->funcs
); p
; incnode(p
))
955 if (f
== (Hookfn
) getdata(p
)) {
956 remnode(h
->funcs
, p
);
966 deletehookfunc(char *n
, Hookfn f
)
968 Hookdef h
= gethookdef(n
);
971 return deletehookdeffunc(h
, f
);
975 /* Run the function(s) for a hook. */
979 runhookdef(Hookdef h
, void *d
)
981 if (empty(h
->funcs
)) {
985 } else if (h
->flags
& HOOKF_ALL
) {
989 for (p
= firstnode(h
->funcs
); p
; incnode(p
))
990 if ((r
= ((Hookfn
) getdata(p
))(h
, d
)))
996 return ((Hookfn
) getdata(lastnode(h
->funcs
)))(h
, d
);
1001 /************************************************************************
1003 ************************************************************************/
1006 * Check that it's possible to add a parameter. This
1007 * requires that either there's no parameter already present,
1008 * or it's a global parameter marked for autoloading.
1010 * The special status 2 is to indicate it didn't work but
1011 * -i was in use so we didn't print a warning.
1015 checkaddparam(const char *nam
, int opt_i
)
1019 if (!(pm
= (Param
) gethashnode2(paramtab
, nam
)))
1022 if (pm
->level
|| !(pm
->node
.flags
& PM_AUTOLOAD
)) {
1024 * -i suppresses "it's already that way" warnings,
1025 * but not "this can't possibly work" warnings, so we print
1026 * the message anyway if there's a local parameter blocking
1027 * the parameter we want to add, not if there's a
1028 * non-autoloadable parameter already there. This
1029 * is consistent with the way add_auto* functions work.
1031 if (!opt_i
|| !pm
->level
) {
1032 zwarn("Can't add module parameter `%s': %s",
1034 "local parameter exists" :
1035 "parameter already exists");
1041 unsetparam_pm(pm
, 0, 1);
1045 /* This adds the given parameter definition. The return value is zero on *
1046 * success and 1 on failure. */
1050 addparamdef(Paramdef d
)
1054 if (checkaddparam(d
->name
, 0))
1058 if (!(pm
= createspecialhash(d
->name
, d
->getnfn
,
1059 d
->scantfn
, d
->flags
)))
1062 else if (!(pm
= createparam(d
->name
, d
->flags
)) &&
1063 !(pm
= (Param
) paramtab
->getnode(paramtab
, d
->name
)))
1069 pm
->u
.data
= d
->var
;
1070 if (d
->var
|| d
->gsu
) {
1072 * If no get/set/unset class, use the appropriate
1073 * variable type, else use the one supplied.
1075 switch (PM_TYPE(pm
->node
.flags
)) {
1077 pm
->gsu
.s
= d
->gsu
? (GsuScalar
)d
->gsu
: &varscalar_gsu
;
1081 pm
->gsu
.i
= d
->gsu
? (GsuInteger
)d
->gsu
: &varinteger_gsu
;
1085 pm
->gsu
.a
= d
->gsu
? (GsuArray
)d
->gsu
: &vararray_gsu
;
1089 /* hashes may behave like standard hashes */
1091 pm
->gsu
.h
= (GsuHash
)d
->gsu
;
1095 unsetparam_pm(pm
, 0, 1);
1103 /* Delete parameters defined. No error checking yet. */
1107 deleteparamdef(Paramdef d
)
1109 Param pm
= (Param
) paramtab
->getnode(paramtab
, d
->name
);
1115 * See if the parameter has been hidden. If so,
1116 * bring it to the front to unset it.
1118 Param prevpm
, searchpm
;
1119 for (prevpm
= pm
, searchpm
= pm
->old
;
1121 prevpm
= searchpm
, searchpm
= searchpm
->old
)
1122 if (searchpm
== d
->pm
)
1128 paramtab
->removenode(paramtab
, pm
->node
.nam
);
1129 prevpm
->old
= searchpm
->old
;
1131 paramtab
->addnode(paramtab
, searchpm
->node
.nam
, searchpm
);
1135 pm
->node
.flags
= (pm
->node
.flags
& ~PM_READONLY
) | PM_REMOVABLE
;
1136 unsetparam_pm(pm
, 0, 1);
1142 * Add or remove sets of parameters. The interface is
1143 * identical to setbuiltins().
1148 setparamdefs(char const *nam
, Paramdef d
, int size
, int *e
)
1158 if (addparamdef(d
)) {
1159 zwarnnam(nam
, "error when adding parameter `%s'", d
->name
);
1167 if (deleteparamdef(d
)) {
1168 zwarnnam(nam
, "parameter `%s' already deleted", d
->name
);
1177 /* This adds a definition for autoloading a module for a parameter. */
1181 add_autoparam(const char *module
, const char *pnam
, int flags
)
1187 if ((ret
= checkaddparam(pnam
, (flags
& FEAT_IGNORE
)))) {
1190 * checkaddparam() has already printed a message if one was
1191 * needed. If it wasn't owing to the presence of -i, ret is 2;
1192 * for consistency with other add_auto* functions we return
1193 * status 0 to indicate there's already such a parameter and
1194 * we've been told not to worry if so.
1196 return ret
== 2 ? 0 : -1;
1199 pm
= setsparam(dupstring(pnam
), ztrdup(module
));
1201 pm
->node
.flags
|= PM_AUTOLOAD
;
1202 if (flags
& FEAT_AUTOALL
)
1203 pm
->node
.flags
|= PM_AUTOALL
;
1209 /* Remove a parameter added with add_autoparam() */
1213 del_autoparam(UNUSED(const char *modnam
), const char *pnam
, int flags
)
1215 Param pm
= (Param
) gethashnode2(paramtab
, pnam
);
1218 if (!(flags
& FEAT_IGNORE
))
1220 } else if (!(pm
->node
.flags
& PM_AUTOLOAD
)) {
1221 if (!(flags
& FEAT_IGNORE
))
1224 unsetparam_pm(pm
, 0, 1);
1229 /************************************************************************
1231 ************************************************************************/
1233 /* List of math functions. */
1239 * Remove a single math function form the list (utility function).
1240 * This does not delete a module math function, that's deletemathfunc().
1245 removemathfunc(MathFunc previous
, MathFunc current
)
1248 previous
->next
= current
->next
;
1250 mathfuncs
= current
->next
;
1252 zsfree(current
->name
);
1253 zsfree(current
->module
);
1254 zfree(current
, sizeof(*current
));
1257 /* Find a math function in the list, handling autoload if necessary. */
1261 getmathfunc(const char *name
, int autol
)
1263 MathFunc p
, q
= NULL
;
1265 for (p
= mathfuncs
; p
; q
= p
, p
= p
->next
)
1266 if (!strcmp(name
, p
->name
)) {
1267 if (autol
&& p
->module
&& !(p
->flags
& MFF_USERFUNC
)) {
1268 char *n
= dupstring(p
->module
);
1269 int flags
= p
->flags
;
1271 removemathfunc(q
, p
);
1273 (void)ensurefeature(n
, "f:", (flags
& MFF_AUTOALL
) ? NULL
:
1276 return getmathfunc(name
, 0);
1284 /* Add a single math function */
1288 addmathfunc(MathFunc f
)
1290 MathFunc p
, q
= NULL
;
1292 if (f
->flags
& MFF_ADDED
)
1295 for (p
= mathfuncs
; p
; q
= p
, p
= p
->next
)
1296 if (!strcmp(f
->name
, p
->name
)) {
1297 if (p
->module
&& !(p
->flags
& MFF_USERFUNC
)) {
1299 * Autoloadable, replace.
1301 removemathfunc(q
, p
);
1307 f
->next
= mathfuncs
;
1313 /* Delete a single math function */
1317 deletemathfunc(MathFunc f
)
1321 for (p
= mathfuncs
, q
= NULL
; p
&& p
!= f
; q
= p
, p
= p
->next
);
1327 mathfuncs
= f
->next
;
1329 /* the following applies to both unloaded and user-defined functions */
1333 zfree(f
, sizeof(*f
));
1335 f
->flags
&= ~MFF_ADDED
;
1343 * Add or remove sets of math functions. The interface is
1344 * identical to setbuiltins().
1349 setmathfuncs(char const *nam
, MathFunc f
, int size
, int *e
)
1355 if (f
->flags
& MFF_ADDED
) {
1359 if (addmathfunc(f
)) {
1360 zwarnnam(nam
, "name clash when adding math function `%s'",
1364 f
->flags
|= MFF_ADDED
;
1367 if (!(f
->flags
& MFF_ADDED
)) {
1371 if (deletemathfunc(f
)) {
1372 zwarnnam(nam
, "math function `%s' already deleted", f
->name
);
1375 f
->flags
&= ~MFF_ADDED
;
1383 /* Add an autoload definition for a math function. */
1387 add_automathfunc(const char *module
, const char *fnam
, int flags
)
1391 f
= (MathFunc
) zalloc(sizeof(*f
));
1393 f
->name
= ztrdup(fnam
);
1394 f
->module
= ztrdup(module
);
1397 if (addmathfunc(f
)) {
1400 zfree(f
, sizeof(*f
));
1402 if (!(flags
& FEAT_IGNORE
))
1409 /* Remove a math function added with add_automathfunc() */
1413 del_automathfunc(UNUSED(const char *modnam
), const char *fnam
, int flags
)
1415 MathFunc f
= getmathfunc(fnam
, 0);
1418 if (!(flags
& FEAT_IGNORE
))
1420 } else if (f
->flags
& MFF_ADDED
) {
1421 if (!(flags
& FEAT_IGNORE
))
1429 /************************************************************************
1430 * Now support for dynamical loading and the fallback functions
1431 * we use for loading if dynamical loading is not available.
1432 ************************************************************************/
1440 #include <sys/ldr.h>
1442 static char *dlerrstr
[256];
1445 load_and_bind(const char *fn
)
1447 void *ret
= (void *) load((char *) fn
, L_NOAUTODEFER
, NULL
);
1451 int i
, err
= loadbind(0, (void *) addbuiltin
, ret
);
1452 for (i
= 0; i
< modulestab
->hsize
&& !err
; i
++) {
1453 for (m
= (Module
)modulestab
->nodes
[i
]; m
&& !err
;
1454 m
= (Module
)m
->node
.next
) {
1455 if (!(m
->node
.flags
& MOD_ALIAS
) &&
1456 m
->u
.handle
&& !(m
->node
.flags
& MOD_LINKED
))
1457 err
|= loadbind(0, m
->u
.handle
, ret
);
1462 loadquery(L_GETMESSAGES
, dlerrstr
, sizeof(dlerrstr
));
1467 loadquery(L_GETMESSAGES
, dlerrstr
, sizeof(dlerrstr
));
1472 #define dlopen(X,Y) load_and_bind(X)
1473 #define dlclose(X) unload(X)
1474 #define dlerror() (dlerrstr[0])
1475 #ifndef HAVE_DLERROR
1476 # define HAVE_DLERROR 1
1483 # if defined(HAVE_DL_H) && defined(HPUXDYNAMIC)
1491 # define RTLD_LAZY BIND_DEFERRED
1492 # define RTLD_GLOBAL DYNAMIC_PATH
1494 # include <sys/types.h>
1502 # define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0)
1503 # define dlclose(handle) shl_unload((shl_t)(handle))
1507 hpux_dlsym(void *handle
, char *name
)
1510 if (!shl_findsym((shl_t
*)&handle
, name
, TYPE_UNDEFINED
, &sym_addr
))
1515 # define dlsym(handle,name) hpux_dlsym(handle,name)
1516 # ifdef HAVE_DLERROR /* paranoia */
1517 # undef HAVE_DLERROR
1520 # ifndef HAVE_DLCLOSE
1521 # define dlclose(X) ((X), 0)
1526 #ifdef DLSYM_NEEDS_UNDERSCORE
1527 # define STR_SETUP "_setup_"
1528 # define STR_FEATURES "_features_"
1529 # define STR_ENABLES "_enables_"
1530 # define STR_BOOT "_boot_"
1531 # define STR_CLEANUP "_cleanup_"
1532 # define STR_FINISH "_finish_"
1533 #else /* !DLSYM_NEEDS_UNDERSCORE */
1534 # define STR_SETUP "setup_"
1535 # define STR_FEATURES "features_"
1536 # define STR_ENABLES "enables_"
1537 # define STR_BOOT "boot_"
1538 # define STR_CLEANUP "cleanup_"
1539 # define STR_FINISH "finish_"
1540 #endif /* !DLSYM_NEEDS_UNDERSCORE */
1543 #endif /* !AIXDYNAMIC */
1546 # define RTLD_LAZY 1
1549 # define RTLD_GLOBAL 0
1553 * Attempt to load a module. This is the lowest level of
1554 * zsh function for dynamical modules. Returns the handle
1555 * from the dynamic loader.
1560 try_load_module(char const *name
)
1562 char buf
[PATH_MAX
+ 1];
1567 l
= 1 + strlen(name
) + 1 + strlen(DL_EXT
);
1568 for (pp
= module_path
; !ret
&& *pp
; pp
++) {
1569 if (l
+ (**pp
? strlen(*pp
) : 1) > PATH_MAX
)
1571 sprintf(buf
, "%s/%s.%s", **pp
? *pp
: ".", name
, DL_EXT
);
1572 ret
= dlopen(unmeta(buf
), RTLD_LAZY
| RTLD_GLOBAL
);
1579 * Load a module, with option to complain or not.
1580 * Returns the handle from the dynamic loader.
1585 do_load_module(char const *name
, int silent
)
1589 ret
= try_load_module(name
);
1590 if (!ret
&& !silent
) {
1592 zwarn("failed to load module `%s': %s", name
, dlerror());
1594 zwarn("failed to load module: %s", name
);
1601 #else /* !DYNAMIC */
1604 * Dummy loader when no dynamic loading available; always fails.
1609 do_load_module(char const *name
, int silent
)
1612 zwarn("failed to load module: %s", name
);
1618 #endif /* !DYNAMIC */
1621 * Find a module in the list.
1622 * flags is a set of bits defined in the enum above.
1623 * If namep is set, this is set to point to the last alias value resolved,
1624 * even if that module was not loaded. or the module name if no aliases.
1625 * Hence this is always the physical module to load in a chain of aliases.
1626 * Return NULL if the module named is not stored as a structure, or if we were
1627 * resolving aliases and the final module named is not stored as a
1632 find_module(const char *name
, int flags
, const char **namep
)
1636 m
= (Module
)modulestab
->getnode2(modulestab
, name
);
1638 if ((flags
& FINDMOD_ALIASP
) && (m
->node
.flags
& MOD_ALIAS
)) {
1640 *namep
= m
->u
.alias
;
1641 return find_module(m
->u
.alias
, flags
, namep
);
1644 *namep
= m
->node
.nam
;
1647 if (!(flags
& FINDMOD_CREATE
))
1649 m
= zshcalloc(sizeof(*m
));
1650 modulestab
->addnode(modulestab
, ztrdup(name
), m
);
1655 * Unlink and free a module node from the linked list.
1660 delete_module(Module m
)
1662 modulestab
->removenode(modulestab
, m
->node
.nam
);
1664 modulestab
->freenode(&m
->node
);
1668 * Return 1 if a module is fully loaded else zero.
1669 * A linked module may be marked as unloaded even though
1670 * we can't fully unload it; this returns 0 to try to
1671 * make that state transparently like an unloaded module.
1676 module_loaded(const char *name
)
1680 return ((m
= find_module(name
, FINDMOD_ALIASP
, NULL
)) &&
1682 !(m
->node
.flags
& MOD_UNLOAD
));
1686 * Setup and cleanup functions: we don't search for aliases here,
1687 * since they should have been resolved before we try to load or unload
1699 dyn_setup_module(Module m
)
1701 return ((int (*)_((int,Module
, void*))) m
->u
.handle
)(0, m
, NULL
);
1706 dyn_features_module(Module m
, char ***features
)
1708 return ((int (*)_((int,Module
, void*))) m
->u
.handle
)(4, m
, features
);
1713 dyn_enables_module(Module m
, int **enables
)
1715 return ((int (*)_((int,Module
, void*))) m
->u
.handle
)(5, m
, enables
);
1720 dyn_boot_module(Module m
)
1722 return ((int (*)_((int,Module
, void*))) m
->u
.handle
)(1, m
, NULL
);
1727 dyn_cleanup_module(Module m
)
1729 return ((int (*)_((int,Module
, void*))) m
->u
.handle
)(2, m
, NULL
);
1734 dyn_finish_module(Module m
)
1736 return ((int (*)_((int,Module
,void *))) m
->u
.handle
)(3, m
, NULL
);
1742 static Module_generic_func
1743 module_func(Module m
, char *name
)
1745 #ifdef DYNAMIC_NAME_CLASH_OK
1746 return (Module_generic_func
) dlsym(m
->u
.handle
, name
);
1747 #else /* !DYNAMIC_NAME_CLASH_OK */
1748 VARARR(char, buf
, strlen(name
) + strlen(m
->node
.nam
)*2 + 1);
1753 for(p
= m
->node
.nam
; *p
; p
++) {
1757 } else if(*p
== '_') {
1760 } else if(*p
== 'Q') {
1767 return (Module_generic_func
) dlsym(m
->u
.handle
, buf
);
1768 #endif /* !DYNAMIC_NAME_CLASH_OK */
1773 dyn_setup_module(Module m
)
1775 Module_void_func fn
= (Module_void_func
)module_func(m
, STR_SETUP
);
1779 zwarnnam(m
->node
.nam
, "no setup function");
1785 dyn_features_module(Module m
, char ***features
)
1787 Module_features_func fn
=
1788 (Module_features_func
)module_func(m
, STR_FEATURES
);
1791 return fn(m
, features
);
1792 /* not a user-visible error if no features function */
1798 dyn_enables_module(Module m
, int **enables
)
1800 Module_enables_func fn
= (Module_enables_func
)module_func(m
, STR_ENABLES
);
1803 return fn(m
, enables
);
1804 /* not a user-visible error if no enables function */
1810 dyn_boot_module(Module m
)
1812 Module_void_func fn
= (Module_void_func
)module_func(m
, STR_BOOT
);
1816 zwarnnam(m
->node
.nam
, "no boot function");
1822 dyn_cleanup_module(Module m
)
1824 Module_void_func fn
= (Module_void_func
)module_func(m
, STR_CLEANUP
);
1828 zwarnnam(m
->node
.nam
, "no cleanup function");
1832 /* Note that this function does more than just calling finish_foo(), *
1833 * it really unloads the module. */
1837 dyn_finish_module(Module m
)
1839 Module_void_func fn
= (Module_void_func
)module_func(m
, STR_FINISH
);
1845 zwarnnam(m
->node
.nam
, "no finish function");
1848 dlclose(m
->u
.handle
);
1853 #endif /* !AIXDYNAMIC */
1857 setup_module(Module m
)
1859 return ((m
->node
.flags
& MOD_LINKED
) ?
1860 (m
->u
.linked
->setup
)(m
) : dyn_setup_module(m
));
1865 features_module(Module m
, char ***features
)
1867 return ((m
->node
.flags
& MOD_LINKED
) ?
1868 (m
->u
.linked
->features
)(m
, features
) :
1869 dyn_features_module(m
, features
));
1874 enables_module(Module m
, int **enables
)
1876 return ((m
->node
.flags
& MOD_LINKED
) ?
1877 (m
->u
.linked
->enables
)(m
, enables
) :
1878 dyn_enables_module(m
, enables
));
1883 boot_module(Module m
)
1885 return ((m
->node
.flags
& MOD_LINKED
) ?
1886 (m
->u
.linked
->boot
)(m
) : dyn_boot_module(m
));
1891 cleanup_module(Module m
)
1893 return ((m
->node
.flags
& MOD_LINKED
) ?
1894 (m
->u
.linked
->cleanup
)(m
) : dyn_cleanup_module(m
));
1899 finish_module(Module m
)
1901 return ((m
->node
.flags
& MOD_LINKED
) ?
1902 (m
->u
.linked
->finish
)(m
) : dyn_finish_module(m
));
1906 #else /* !DYNAMIC */
1910 setup_module(Module m
)
1912 return ((m
->node
.flags
& MOD_LINKED
) ? (m
->u
.linked
->setup
)(m
) : 1);
1917 features_module(Module m
, char ***features
)
1919 return ((m
->node
.flags
& MOD_LINKED
) ? (m
->u
.linked
->features
)(m
, features
)
1925 enables_module(Module m
, int **enables
)
1927 return ((m
->node
.flags
& MOD_LINKED
) ? (m
->u
.linked
->enables
)(m
, enables
)
1933 boot_module(Module m
)
1935 return ((m
->node
.flags
& MOD_LINKED
) ? (m
->u
.linked
->boot
)(m
) : 1);
1940 cleanup_module(Module m
)
1942 return ((m
->node
.flags
& MOD_LINKED
) ? (m
->u
.linked
->cleanup
)(m
) : 1);
1947 finish_module(Module m
)
1949 return ((m
->node
.flags
& MOD_LINKED
) ? (m
->u
.linked
->finish
)(m
) : 1);
1953 #endif /* !DYNAMIC */
1956 /************************************************************************
1957 * Functions called when manipulating modules
1958 ************************************************************************/
1961 * Set the features for the module, which must be loaded
1962 * by now (though may not be fully set up).
1964 * Return 0 for success, 1 for failure, 2 if some features
1965 * couldn't be set by the module itself (non-existent features
1966 * are tested here and cause 1 to be returned).
1971 do_module_features(Module m
, Feature_enables enablesarr
, int flags
)
1976 if (features_module(m
, &features
) == 0) {
1978 * Features are supported. If we were passed
1979 * a NULL array, enable all features, else
1980 * enable only the features listed.
1981 * (This may in principle be an empty array,
1982 * although that's not very pointful.)
1984 int *enables
= NULL
;
1985 if (enables_module(m
, &enables
)) {
1986 /* If features are supported, enables should be, too */
1987 if (!(flags
& FEAT_IGNORE
))
1988 zwarn("error getting enabled features for module `%s'",
1993 if ((flags
& FEAT_CHECKAUTO
) && m
->autoloads
) {
1995 * Check autoloads are available. Since these
1996 * have been requested at some other point, they
1997 * don't affect the return status unless something
1998 * in enablesstr doesn't work.
2001 for (an
= firstnode(m
->autoloads
); an
; an
= nextn
) {
2002 char *al
= (char *)getdata(an
), **ptr
;
2003 /* careful, we can delete the current node */
2004 nextn
= nextnode(an
);
2005 for (ptr
= features
; *ptr
; ptr
++)
2006 if (!strcmp(al
, *ptr
))
2010 if (!(flags
& FEAT_IGNORE
))
2012 "module `%s' has no such feature: `%s': autoload cancelled",
2015 * This shouldn't happen, so it's not worth optimising
2016 * the call to autofeatures...
2018 arg
[0] = al
= dupstring(al
);
2020 (void)autofeatures(NULL
, m
->node
.nam
, arg
, 0,
2021 FEAT_IGNORE
|FEAT_REMOVE
);
2023 * don't want to try to enable *that*...
2024 * expunge it from the enable string.
2027 Feature_enables fep
;
2028 for (fep
= enablesarr
; fep
->str
; fep
++) {
2029 char *str
= fep
->str
;
2030 if (*str
== '+' || *str
== '-')
2032 if (fep
->pat
? pattry(fep
->pat
, al
) :
2034 /* can't enable it after all, so return 1 */
2037 fep
->str
= fep
[1].str
;
2038 fep
->pat
= fep
[1].pat
;
2051 Feature_enables fep
;
2052 for (fep
= enablesarr
; fep
->str
; fep
++) {
2053 char **fp
, *esp
= fep
->str
;
2054 int on
= 1, found
= 0;
2057 else if (*esp
== '-') {
2061 for (fp
= features
; *fp
; fp
++)
2062 if (fep
->pat
? pattry(fep
->pat
, *fp
) : !strcmp(*fp
, esp
)) {
2063 enables
[fp
- features
] = on
;
2069 if (!(flags
& FEAT_IGNORE
))
2071 "module `%s' has no feature matching: `%s'" :
2072 "module `%s' has no such feature: `%s'",
2079 * Enable all features. This is used when loading
2080 * without using zmodload -F.
2082 int n_features
= arrlen(features
);
2084 for (ep
= enables
; n_features
--; ep
++)
2088 if (enables_module(m
, &enables
))
2090 } else if (enablesarr
) {
2091 if (!(flags
& FEAT_IGNORE
))
2092 zwarn("module `%s' does not support features", m
->node
.nam
);
2095 /* Else it doesn't support features but we don't care. */
2101 * Boot the module, including setting up features.
2102 * As we've only just loaded the module, we don't yet
2103 * know what features it supports, so we get them passed
2106 * Returns 0 if OK, 1 if completely failed, 2 if some features
2107 * couldn't be set up.
2112 do_boot_module(Module m
, Feature_enables enablesarr
, int silent
)
2114 int ret
= do_module_features(m
, enablesarr
,
2115 silent
? FEAT_IGNORE
|FEAT_CHECKAUTO
:
2127 * Cleanup the module.
2132 do_cleanup_module(Module m
)
2134 return (m
->node
.flags
& MOD_LINKED
) ?
2135 (m
->u
.linked
&& m
->u
.linked
->cleanup(m
)) :
2136 (m
->u
.handle
&& cleanup_module(m
));
2140 * Test a module name contains only valid characters: those
2141 * allowed in a shell identifier plus slash. Return 1 if so.
2146 modname_ok(char const *p
)
2149 p
= itype_end(p
, IIDENT
, 0);
2152 } while(*p
++ == '/');
2157 * High level function to load a module, encapsulating
2158 * all the handling of module functions.
2160 * "*enablesstr" is NULL if the caller is not feature-aware;
2161 * then the module should turn on all features. If it
2162 * is not NULL it points to an array of features to be
2163 * turned on. This function is responsible for testing whether
2164 * the module supports those features.
2166 * If "silent" is 1, don't issue warnings for errors.
2168 * Now returns 0 for success (changed post-4.3.4),
2169 * 1 for complete failure, 2 if some features couldn't be set.
2174 load_module(char const *name
, Feature_enables enablesarr
, int silent
)
2177 void *handle
= NULL
;
2181 if (!modname_ok(name
)) {
2183 zerr("invalid module name `%s'", name
);
2187 * The following function call may alter name to the final name in a
2188 * chain of aliases. This makes sure the actual module loaded
2192 if (!(m
= find_module(name
, FINDMOD_ALIASP
, &name
))) {
2193 if (!(linked
= module_linked(name
)) &&
2194 !(handle
= do_load_module(name
, silent
))) {
2198 m
= zshcalloc(sizeof(*m
));
2200 m
->u
.handle
= handle
;
2201 m
->node
.flags
|= MOD_SETUP
;
2203 m
->u
.linked
= linked
;
2204 m
->node
.flags
|= MOD_SETUP
| MOD_LINKED
;
2206 modulestab
->addnode(modulestab
, ztrdup(name
), m
);
2208 if ((set
= setup_module(m
)) ||
2209 (bootret
= do_boot_module(m
, enablesarr
, silent
)) == 1) {
2211 do_cleanup_module(m
);
2217 m
->node
.flags
|= MOD_INIT_S
| MOD_INIT_B
;
2218 m
->node
.flags
&= ~MOD_SETUP
;
2222 if (m
->node
.flags
& MOD_SETUP
) {
2226 if (m
->node
.flags
& MOD_UNLOAD
)
2227 m
->node
.flags
&= ~MOD_UNLOAD
;
2228 else if ((m
->node
.flags
& MOD_LINKED
) ? m
->u
.linked
: m
->u
.handle
) {
2232 if (m
->node
.flags
& MOD_BUSY
) {
2233 zerr("circular dependencies for module ;%s", name
);
2236 m
->node
.flags
|= MOD_BUSY
;
2238 * TODO: shouldn't we unload the module if one of
2239 * its dependencies fails?
2243 for (n
= firstnode(m
->deps
); n
; incnode(n
))
2244 if (load_module((char *) getdata(n
), NULL
, silent
) == 1) {
2245 m
->node
.flags
&= ~MOD_BUSY
;
2250 m
->node
.flags
&= ~MOD_BUSY
;
2253 if (!(linked
= module_linked(name
)) &&
2254 !(handle
= do_load_module(name
, silent
))) {
2259 m
->u
.handle
= handle
;
2260 m
->node
.flags
|= MOD_SETUP
;
2262 m
->u
.linked
= linked
;
2263 m
->node
.flags
|= MOD_SETUP
| MOD_LINKED
;
2265 if (setup_module(m
)) {
2271 m
->node
.flags
&= ~MOD_SETUP
;
2275 m
->node
.flags
|= MOD_INIT_S
;
2277 m
->node
.flags
|= MOD_SETUP
;
2278 if ((bootret
= do_boot_module(m
, enablesarr
, silent
)) == 1) {
2279 do_cleanup_module(m
);
2281 if (m
->node
.flags
& MOD_LINKED
)
2285 m
->node
.flags
&= ~MOD_SETUP
;
2289 m
->node
.flags
|= MOD_INIT_B
;
2290 m
->node
.flags
&= ~MOD_SETUP
;
2295 /* This ensures that the module with the name given as the first argument
2297 * The other argument is the array of features to set. If this is NULL
2298 * all features are enabled (even if the module was already loaded).
2300 * If this is non-NULL the module features are set accordingly
2301 * whether or not the module is loaded; it is an error if the
2302 * module does not support the features passed (even if the feature
2303 * is to be turned off) or if the module does not support features
2305 * The return value is 0 if the module was found or loaded
2306 * (this changed post-4.3.4, because I got so confused---pws),
2307 * 1 if loading failed completely, 2 if some features couldn't be set.
2309 * This function behaves like load_module() except that it
2310 * handles the case where the module was already loaded, and
2311 * sets features accordingly.
2316 require_module(const char *module
, Feature_enables features
)
2321 /* Resolve aliases and actual loadable module as for load_module */
2323 m
= find_module(module
, FINDMOD_ALIASP
, &module
);
2324 if (!m
|| !m
->u
.handle
||
2325 (m
->node
.flags
& MOD_UNLOAD
))
2326 ret
= load_module(module
, features
, 0);
2328 ret
= do_module_features(m
, features
, 0);
2335 * Indicate that the module named "name" depends on the module
2341 add_dep(const char *name
, char *from
)
2347 * If we were passed an alias, we must resolve it to a final
2348 * module name (and maybe add the corresponding struct), since otherwise
2349 * we would need to check all modules to see if they happen
2350 * to be aliased to the same thing to implement dependencies properly.
2352 * This should mean that an attempt to add an alias which would
2353 * have the same name as a module which has dependencies is correctly
2354 * rejected, because then the module named already exists as a non-alias.
2355 * Better make sure. (There's no problem making a an alias which
2356 * *points* to a module with dependencies, of course.)
2358 m
= find_module(name
, FINDMOD_ALIASP
|FINDMOD_CREATE
, &name
);
2360 m
->deps
= znewlinklist();
2361 for (node
= firstnode(m
->deps
);
2362 node
&& strcmp((char *) getdata(node
), from
);
2365 zaddlinknode(m
->deps
, ztrdup(from
));
2369 * Function to be used when scanning the builtins table to
2370 * find and print autoloadable builtins.
2375 autoloadscan(HashNode hn
, int printflags
)
2377 Builtin bn
= (Builtin
) hn
;
2379 if(bn
->node
.flags
& BINF_ADDED
)
2381 if(printflags
& PRINT_LIST
) {
2382 fputs("zmodload -ab ", stdout
);
2383 if(bn
->optstr
[0] == '-')
2384 fputs("-- ", stdout
);
2385 quotedzputs(bn
->optstr
, stdout
);
2386 if(strcmp(bn
->node
.nam
, bn
->optstr
)) {
2388 quotedzputs(bn
->node
.nam
, stdout
);
2391 nicezputs(bn
->node
.nam
, stdout
);
2392 if(strcmp(bn
->node
.nam
, bn
->optstr
)) {
2393 fputs(" (", stdout
);
2394 nicezputs(bn
->optstr
, stdout
);
2402 /************************************************************************
2403 * Handling for the zmodload builtin and its various options.
2404 ************************************************************************/
2407 * Main builtin entry point for zmodload.
2412 bin_zmodload(char *nam
, char **args
, Options ops
, UNUSED(int func
))
2414 int ops_bcpf
= OPT_ISSET(ops
,'b') || OPT_ISSET(ops
,'c') ||
2415 OPT_ISSET(ops
,'p') || OPT_ISSET(ops
,'f');
2416 int ops_au
= OPT_ISSET(ops
,'a') || OPT_ISSET(ops
,'u');
2417 int ret
= 1, autoopts
;
2418 /* options only allowed with -F */
2419 char *fonly
= "lP", *fp
;
2421 if (ops_bcpf
&& !ops_au
) {
2422 zwarnnam(nam
, "-b, -c, -f, and -p must be combined with -a or -u");
2425 if (OPT_ISSET(ops
,'F') && (ops_bcpf
|| OPT_ISSET(ops
,'u'))) {
2426 zwarnnam(nam
, "-b, -c, -f, -p and -u cannot be combined with -F");
2429 if (OPT_ISSET(ops
,'A') || OPT_ISSET(ops
,'R')) {
2430 if (ops_bcpf
|| ops_au
|| OPT_ISSET(ops
,'d') ||
2431 (OPT_ISSET(ops
,'R') && OPT_ISSET(ops
,'e'))) {
2432 zwarnnam(nam
, "illegal flags combined with -A or -R");
2435 if (!OPT_ISSET(ops
,'e'))
2436 return bin_zmodload_alias(nam
, args
, ops
);
2438 if (OPT_ISSET(ops
,'d') && OPT_ISSET(ops
,'a')) {
2439 zwarnnam(nam
, "-d cannot be combined with -a");
2442 if (OPT_ISSET(ops
,'u') && !*args
) {
2443 zwarnnam(nam
, "what do you want to unload?");
2446 if (OPT_ISSET(ops
,'e') && (OPT_ISSET(ops
,'I') || OPT_ISSET(ops
,'L') ||
2447 (OPT_ISSET(ops
,'a') && !OPT_ISSET(ops
,'F'))
2448 || OPT_ISSET(ops
,'d') ||
2449 OPT_ISSET(ops
,'i') || OPT_ISSET(ops
,'u'))) {
2450 zwarnnam(nam
, "-e cannot be combined with other options");
2454 for (fp
= fonly
; *fp
; fp
++) {
2455 if (OPT_ISSET(ops
,STOUC(*fp
)) && !OPT_ISSET(ops
,'F')) {
2456 zwarnnam(nam
, "-%c is only allowed with -F", *fp
);
2461 if (OPT_ISSET(ops
, 'F'))
2462 ret
= bin_zmodload_features(nam
, args
, ops
);
2463 else if (OPT_ISSET(ops
,'e'))
2464 ret
= bin_zmodload_exist(nam
, args
, ops
);
2465 else if (OPT_ISSET(ops
,'d'))
2466 ret
= bin_zmodload_dep(nam
, args
, ops
);
2467 else if ((autoopts
= OPT_ISSET(ops
, 'b') + OPT_ISSET(ops
, 'c') +
2468 OPT_ISSET(ops
, 'p') + OPT_ISSET(ops
, 'f')) ||
2469 /* zmodload -a is equivalent to zmodload -ab, annoyingly */
2470 OPT_ISSET(ops
, 'a')) {
2472 zwarnnam(nam
, "use only one of -b, -c, or -p");
2475 ret
= bin_zmodload_auto(nam
, args
, ops
);
2477 ret
= bin_zmodload_load(nam
, args
, ops
);
2487 bin_zmodload_alias(char *nam
, char **args
, Options ops
)
2490 * TODO: while it would be too nasty to have aliases, as opposed
2491 * to real loadable modules, with dependencies --- just what would
2492 * we need to load when, exactly? --- there is in principle no objection
2493 * to making it possible to force an alias onto an existing unloaded
2494 * module which has dependencies. This would simply transfer
2495 * the dependencies down the line to the aliased-to module name.
2496 * This is actually useful, since then you can alias zsh/zle=mytestzle
2497 * to load another version of zle. But then what happens when the
2498 * alias is removed? Do you transfer the dependencies back? And
2499 * suppose other names are aliased to the same file? It might be
2500 * kettle of fish best left unwormed.
2505 if (OPT_ISSET(ops
,'R')) {
2506 zwarnnam(nam
, "no module alias to remove");
2509 scanhashtable(modulestab
, 1, MOD_ALIAS
, 0,
2510 modulestab
->printnode
,
2511 OPT_ISSET(ops
,'L') ? PRINTMOD_LIST
: 0);
2515 for (; *args
; args
++) {
2516 char *eqpos
= strchr(*args
, '=');
2517 char *aliasname
= eqpos
? eqpos
+1 : NULL
;
2520 if (!modname_ok(*args
)) {
2521 zwarnnam(nam
, "invalid module name `%s'", *args
);
2524 if (OPT_ISSET(ops
,'R')) {
2526 zwarnnam(nam
, "bad syntax for removing module alias: %s",
2530 m
= find_module(*args
, 0, NULL
);
2532 if (!(m
->node
.flags
& MOD_ALIAS
)) {
2533 zwarnnam(nam
, "module is not an alias: %s", *args
);
2538 zwarnnam(nam
, "no such module alias: %s", *args
);
2543 const char *mname
= aliasname
;
2544 if (!modname_ok(aliasname
)) {
2545 zwarnnam(nam
, "invalid module name `%s'", aliasname
);
2549 if (!strcmp(mname
, *args
)) {
2550 zwarnnam(nam
, "module alias would refer to itself: %s",
2554 } while ((m
= find_module(mname
, 0, NULL
))
2555 && (m
->node
.flags
& MOD_ALIAS
)
2556 && (mname
= m
->u
.alias
));
2557 m
= find_module(*args
, 0, NULL
);
2559 if (!(m
->node
.flags
& MOD_ALIAS
)) {
2560 zwarnnam(nam
, "module is not an alias: %s", *args
);
2565 m
= (Module
) zshcalloc(sizeof(*m
));
2566 m
->node
.flags
= MOD_ALIAS
;
2567 modulestab
->addnode(modulestab
, ztrdup(*args
), m
);
2569 m
->u
.alias
= ztrdup(aliasname
);
2571 if ((m
= find_module(*args
, 0, NULL
))) {
2572 if (m
->node
.flags
& MOD_ALIAS
)
2573 modulestab
->printnode(&m
->node
,
2574 OPT_ISSET(ops
,'L') ?
2577 zwarnnam(nam
, "module is not an alias: %s", *args
);
2581 zwarnnam(nam
, "no such module alias: %s", *args
);
2591 /* zmodload -e (without -F) */
2595 bin_zmodload_exist(UNUSED(char *nam
), char **args
, Options ops
)
2600 scanhashtable(modulestab
, 1, 0, 0, modulestab
->printnode
,
2601 OPT_ISSET(ops
,'A') ? PRINTMOD_EXIST
|PRINTMOD_ALIAS
:
2607 for (; !ret
&& *args
; args
++) {
2608 if (!(m
= find_module(*args
, FINDMOD_ALIASP
, NULL
))
2610 || (m
->node
.flags
& MOD_UNLOAD
))
2621 bin_zmodload_dep(UNUSED(char *nam
), char **args
, Options ops
)
2624 if (OPT_ISSET(ops
,'u')) {
2625 /* remove dependencies, which can't pertain to aliases */
2626 const char *tnam
= *args
++;
2627 m
= find_module(tnam
, FINDMOD_ALIASP
, &tnam
);
2630 if (*args
&& m
->deps
) {
2633 for (dnode
= firstnode(m
->deps
); dnode
; incnode(dnode
))
2634 if (!strcmp(*args
, getdata(dnode
))) {
2635 zsfree(getdata(dnode
));
2636 remnode(m
->deps
, dnode
);
2640 if (empty(m
->deps
)) {
2641 freelinklist(m
->deps
, freestr
);
2646 freelinklist(m
->deps
, freestr
);
2650 if (!m
->deps
&& !m
->u
.handle
)
2653 } else if (!args
[0] || !args
[1]) {
2654 /* list dependencies */
2655 int depflags
= OPT_ISSET(ops
,'L') ?
2656 PRINTMOD_DEPS
|PRINTMOD_LIST
: PRINTMOD_DEPS
;
2658 if ((m
= (Module
)modulestab
->getnode2(modulestab
, args
[0])))
2659 modulestab
->printnode(&m
->node
, depflags
);
2661 scanhashtable(modulestab
, 1, 0, 0, modulestab
->printnode
,
2666 /* add dependencies */
2668 char *tnam
= *args
++;
2670 for (; *args
; args
++)
2671 add_dep(tnam
, *args
);
2677 * Function for scanning the parameter table to find and print
2678 * out autoloadable parameters.
2682 printautoparams(HashNode hn
, int lon
)
2684 Param pm
= (Param
) hn
;
2686 if (pm
->node
.flags
& PM_AUTOLOAD
) {
2688 printf("zmodload -ap %s %s\n", pm
->u
.str
, pm
->node
.nam
);
2690 printf("%s (%s)\n", pm
->node
.nam
, pm
->u
.str
);
2694 /* zmodload -a/u [bcpf] */
2698 bin_zmodload_auto(char *nam
, char **args
, Options ops
)
2703 if (OPT_ISSET(ops
,'c')) {
2705 /* list autoloaded conditions */
2708 for (p
= condtab
; p
; p
= p
->next
) {
2710 if (OPT_ISSET(ops
,'L')) {
2711 fputs("zmodload -ac", stdout
);
2712 if (p
->flags
& CONDF_INFIX
)
2714 printf(" %s %s\n", p
->module
, p
->name
);
2716 if (p
->flags
& CONDF_INFIX
)
2717 fputs("infix ", stdout
);
2719 fputs("post ", stdout
);
2720 printf("%s (%s)\n",p
->name
, p
->module
);
2726 fchar
= OPT_ISSET(ops
,'I') ? 'C' : 'c';
2727 } else if (OPT_ISSET(ops
,'p')) {
2729 /* list autoloaded parameters */
2730 scanhashtable(paramtab
, 1, 0, 0, printautoparams
,
2731 OPT_ISSET(ops
,'L'));
2735 } else if (OPT_ISSET(ops
,'f')) {
2737 /* list autoloaded math functions */
2740 for (p
= mathfuncs
; p
; p
= p
->next
) {
2741 if (!(p
->flags
& MFF_USERFUNC
) && p
->module
) {
2742 if (OPT_ISSET(ops
,'L')) {
2743 fputs("zmodload -af", stdout
);
2744 printf(" %s %s\n", p
->module
, p
->name
);
2746 printf("%s (%s)\n",p
->name
, p
->module
);
2753 /* builtins are the default; zmodload -ab or just zmodload -a */
2755 /* list autoloaded builtins */
2756 scanhashtable(builtintab
, 1, 0, 0,
2757 autoloadscan
, OPT_ISSET(ops
,'L') ? PRINT_LIST
: 0);
2763 flags
= FEAT_AUTOALL
;
2764 if (OPT_ISSET(ops
,'i'))
2765 flags
|= FEAT_IGNORE
;
2766 if (OPT_ISSET(ops
,'u')) {
2767 /* remove autoload */
2768 flags
|= FEAT_REMOVE
;
2777 return autofeatures(nam
, modnam
, args
, fchar
, flags
);
2780 /* Backend handler for zmodload -u */
2784 unload_module(Module m
)
2789 * Only unload the real module, so resolve aliases.
2791 if (m
->node
.flags
& MOD_ALIAS
) {
2792 m
= find_module(m
->u
.alias
, FINDMOD_ALIASP
, NULL
);
2797 * We may need to clean up the module any time setup_ has been
2798 * called. After cleanup_ is successful we are no longer in the
2799 * booted state (because features etc. are deregistered), so remove
2800 * MOD_INIT_B, and also MOD_INIT_S since we won't need to cleanup
2801 * again if this succeeded.
2803 if ((m
->node
.flags
& MOD_INIT_S
) &&
2804 !(m
->node
.flags
& MOD_UNLOAD
) &&
2805 do_cleanup_module(m
))
2807 m
->node
.flags
&= ~(MOD_INIT_B
|MOD_INIT_S
);
2809 del
= (m
->node
.flags
& MOD_UNLOAD
);
2812 m
->node
.flags
|= MOD_UNLOAD
;
2815 m
->node
.flags
&= ~MOD_UNLOAD
;
2818 * We always need to finish the module (and unload it)
2821 if (m
->node
.flags
& MOD_LINKED
) {
2823 m
->u
.linked
->finish(m
);
2833 if (del
&& m
->deps
) {
2834 /* The module was unloaded delayed, unload all modules *
2835 * on which it depended. */
2838 for (n
= firstnode(m
->deps
); n
; incnode(n
)) {
2839 Module dm
= find_module((char *) getdata(n
),
2840 FINDMOD_ALIASP
, NULL
);
2843 (dm
->node
.flags
& MOD_UNLOAD
)) {
2844 /* See if this is the only module depending on it. */
2847 /* Scan hash table the hard way */
2848 for (i
= 0; du
&& i
< modulestab
->hsize
; i
++) {
2849 for (am
= (Module
)modulestab
->nodes
[i
]; du
&& am
;
2850 am
= (Module
)am
->node
.next
) {
2853 * Don't scan the module we're unloading;
2854 * ignore if no dependencies.
2856 if (am
== m
|| !am
->deps
)
2858 /* Don't scan if not loaded nor linked */
2859 if ((am
->node
.flags
& MOD_LINKED
) ?
2860 !am
->u
.linked
: !am
->u
.handle
)
2862 for (sn
= firstnode(am
->deps
); du
&& sn
;
2864 if (!strcmp((char *) getdata(sn
),
2875 if (m
->autoloads
&& firstnode(m
->autoloads
)) {
2877 * Module has autoloadable features. Restore them
2878 * so that the module will be reloaded when needed.
2880 autofeatures("zsh", m
->node
.nam
,
2881 hlinklist2array(m
->autoloads
, 0), 0, FEAT_IGNORE
);
2882 } else if (!m
->deps
) {
2889 * Unload a module by name (modname); nam is the command name.
2890 * Optionally don't print some error messages (always print
2891 * dependency errors).
2896 unload_named_module(char *modname
, char *nam
, int silent
)
2902 m
= find_module(modname
, FINDMOD_ALIASP
, &mname
);
2907 for (i
= 0; i
< modulestab
->hsize
; i
++) {
2908 for (dm
= (Module
)modulestab
->nodes
[i
]; dm
;
2909 dm
= (Module
)dm
->node
.next
) {
2911 if (!dm
->deps
|| !dm
->u
.handle
)
2913 for (dn
= firstnode(dm
->deps
); dn
; incnode(dn
)) {
2914 if (!strcmp((char *) getdata(dn
), mname
)) {
2915 if (dm
->node
.flags
& MOD_UNLOAD
)
2918 zwarnnam(nam
, "module %s is in use by another module and cannot be unloaded", mname
);
2927 if (unload_module(m
))
2931 } else if (!silent
) {
2932 zwarnnam(nam
, "no such module %s", modname
);
2939 /* zmodload -u without -d */
2943 bin_zmodload_load(char *nam
, char **args
, Options ops
)
2946 if(OPT_ISSET(ops
,'u')) {
2947 /* unload modules */
2948 for(; *args
; args
++) {
2949 if (unload_named_module(*args
, nam
, OPT_ISSET(ops
,'i')))
2955 scanhashtable(modulestab
, 1, 0, MOD_UNLOAD
|MOD_ALIAS
,
2956 modulestab
->printnode
,
2957 OPT_ISSET(ops
,'L') ? PRINTMOD_LIST
: 0);
2961 for (; *args
; args
++) {
2962 int tmpret
= require_module(*args
, NULL
);
2963 if (tmpret
&& ret
!= 1)
2975 bin_zmodload_features(const char *nam
, char **args
, Options ops
)
2978 char *modname
= *args
;
2980 Feature_enables features
, fep
;
2984 else if (OPT_ISSET(ops
,'L')) {
2985 int printflags
= PRINTMOD_LIST
|PRINTMOD_FEATURES
;
2986 if (OPT_ISSET(ops
,'P')) {
2987 zwarnnam(nam
, "-P is only allowed with a module name");
2990 if (OPT_ISSET(ops
,'l'))
2991 printflags
|= PRINTMOD_LISTALL
;
2992 if (OPT_ISSET(ops
,'a'))
2993 printflags
|= PRINTMOD_AUTO
;
2994 scanhashtable(modulestab
, 1, 0, MOD_ALIAS
,
2995 modulestab
->printnode
, printflags
);
3000 zwarnnam(nam
, "-F requires a module name");
3004 if (OPT_ISSET(ops
,'m')) {
3008 /* not NULL terminated */
3009 patprogp
= patprogs
=
3010 (Patprog
*)zhalloc(arrlen(args
)*sizeof(Patprog
));
3011 for (argp
= args
; *argp
; argp
++, patprogp
++) {
3013 if (*arg
== '+' || *arg
== '-')
3016 *patprogp
= patcompile(arg
, 0, 0);
3021 if (OPT_ISSET(ops
,'l') || OPT_ISSET(ops
,'L') || OPT_ISSET(ops
,'e')) {
3023 * With option 'l', list all features one per line with + or -.
3024 * With option 'L', list as zmodload statement showing
3025 * only options turned on.
3026 * With both options, list as zmodload showing options
3027 * to be turned both on and off.
3030 char **features
, **fp
, **arrset
= NULL
, **arrp
= NULL
;
3031 int *enables
= NULL
, *ep
;
3032 char *param
= OPT_ARG_SAFE(ops
,'P');
3034 m
= find_module(modname
, FINDMOD_ALIASP
, NULL
);
3035 if (OPT_ISSET(ops
,'a')) {
3038 * If there are no autoloads defined, return status 1.
3040 if (!m
|| !m
->autoloads
)
3042 if (OPT_ISSET(ops
,'e')) {
3043 for (fp
= args
; *fp
; fp
++) {
3048 else if (*fstr
== '-') {
3052 if ((linknodebystring(m
->autoloads
, fstr
) != NULL
) !=
3059 arrp
= arrset
= (char **)zalloc(sizeof(char*) *
3060 (countlinknodes(m
->autoloads
)+1));
3061 } else if (OPT_ISSET(ops
,'L')) {
3062 printf("zmodload -aF %s%c", m
->node
.nam
,
3063 m
->autoloads
&& firstnode(m
->autoloads
) ? ' ' : '\n');
3066 for (ln
= firstnode(m
->autoloads
); ln
; incnode(ln
)) {
3067 char *al
= (char *)getdata(ln
);
3069 *arrp
++ = ztrdup(al
);
3072 OPT_ISSET(ops
,'L') && nextnode(ln
) ? ' ' : '\n');
3076 if (!setaparam(param
, arrset
))
3081 if (!m
|| !m
->u
.handle
|| (m
->node
.flags
& MOD_UNLOAD
)) {
3082 if (!OPT_ISSET(ops
,'e'))
3083 zwarnnam(nam
, "module `%s' is not yet loaded", modname
);
3086 if (features_module(m
, &features
)) {
3087 if (!OPT_ISSET(ops
,'e'))
3088 zwarnnam(nam
, "module `%s' does not support features",
3092 if (enables_module(m
, &enables
)) {
3093 /* this shouldn't ever happen, so don't silence this error */
3094 zwarnnam(nam
, "error getting enabled features for module `%s'",
3098 for (arrp
= args
, iarg
= 0; *arrp
; arrp
++, iarg
++) {
3104 } else if (*arg
== '+') {
3109 for (fp
= features
, ep
= enables
; *fp
; fp
++, ep
++) {
3110 if (patprogs
? pattry(patprogs
[iarg
], *fp
) :
3111 !strcmp(arg
, *fp
)) {
3112 /* for -e, check given state, if any */
3113 if (OPT_ISSET(ops
,'e') && on
!= -1 &&
3122 if (!OPT_ISSET(ops
,'e'))
3123 zwarnnam(nam
, patprogs
?
3124 "module `%s' has no feature matching: `%s'" :
3125 "module `%s' has no such feature: `%s'",
3130 if (OPT_ISSET(ops
,'e')) /* yep, everything we want exists */
3134 for (fp
= features
, ep
= enables
; *fp
; fp
++, ep
++) {
3135 if (OPT_ISSET(ops
, 'L') && !OPT_ISSET(ops
, 'l') &&
3140 for (argp
= args
, iarg
= 0; *argp
; argp
++, iarg
++) {
3142 /* ignore +/- for consistency */
3143 if (*arg
== '+' || *arg
== '-')
3145 if (patprogs
? pattry(patprogs
[iarg
], *fp
) :
3154 arrp
= arrset
= zalloc(sizeof(char *) * (arrlen
+1));
3155 } else if (OPT_ISSET(ops
, 'L'))
3156 printf("zmodload -F %s ", m
->node
.nam
);
3157 for (fp
= features
, ep
= enables
; *fp
; fp
++, ep
++) {
3162 for (argp
= args
, iarg
= 0; *argp
; argp
++, iarg
++) {
3164 if (*arg
== '+' || *arg
== '-')
3166 if (patprogs
? pattry(patprogs
[iarg
], *fp
) :
3167 !strcmp(*fp
, *argp
))
3173 if (OPT_ISSET(ops
, 'L') && !OPT_ISSET(ops
, 'l')) {
3183 *arrp
++ = bicat(onoff
, *fp
);
3185 if (OPT_ISSET(ops
, 'L') && fp
[1]) {
3190 printf("%s%s%c", onoff
, *fp
, term
);
3195 if (!setaparam(param
, arrset
))
3199 } else if (OPT_ISSET(ops
,'P')) {
3200 zwarnnam(nam
, "-P can only be used with -l or -L");
3202 } else if (OPT_ISSET(ops
,'a')) {
3203 if (OPT_ISSET(ops
,'m')) {
3204 zwarnnam(nam
, "-m cannot be used with -a");
3208 * With zmodload -aF, we always use the effect of -i.
3209 * The thinking is that marking a feature for
3210 * autoload is separate from enabling or disabling it.
3211 * Arguably we could do this with the zmodload -ab method
3212 * but I've kept it there for old time's sake.
3213 * The decoupling has meant FEAT_IGNORE/-i also
3214 * suppresses an error for attempting to remove an
3215 * autoload when the feature is enabled, which used
3216 * to be a hard error before.
3218 return autofeatures(nam
, modname
, args
, 0, FEAT_IGNORE
);
3222 (Feature_enables
)zhalloc((arrlen(args
)+1)*sizeof(*fep
));
3226 fep
->pat
= patprogs
? *patprogs
++ : NULL
;
3232 return require_module(modname
, features
);
3236 /************************************************************************
3237 * Generic feature support.
3238 * These functions are designed to be called by modules.
3239 ************************************************************************/
3242 * Construct a features array out of the list of concrete
3243 * features given, leaving space for any abstract features
3244 * to be added by the module itself.
3246 * Note the memory is from the heap.
3251 featuresarray(UNUSED(Module m
), Features f
)
3253 int bn_size
= f
->bn_size
, cd_size
= f
->cd_size
;
3254 int mf_size
= f
->mf_size
, pd_size
= f
->pd_size
;
3255 int features_size
= bn_size
+ cd_size
+ pd_size
+ mf_size
+ f
->n_abstract
;
3256 Builtin bnp
= f
->bn_list
;
3257 Conddef cdp
= f
->cd_list
;
3258 MathFunc mfp
= f
->mf_list
;
3259 Paramdef pdp
= f
->pd_list
;
3260 char **features
= (char **)zhalloc((features_size
+ 1) * sizeof(char *));
3261 char **featurep
= features
;
3264 *featurep
++ = dyncat("b:", (bnp
++)->node
.nam
);
3266 *featurep
++ = dyncat((cdp
->flags
& CONDF_INFIX
) ? "C:" : "c:",
3271 *featurep
++ = dyncat("f:", (mfp
++)->name
);
3273 *featurep
++ = dyncat("p:", (pdp
++)->name
);
3275 features
[features_size
] = NULL
;
3280 * Return the current set of enables for the features in a
3281 * module using heap memory. Leave space for abstract
3282 * features. The array is not zero terminated.
3286 getfeatureenables(UNUSED(Module m
), Features f
)
3288 int bn_size
= f
->bn_size
, cd_size
= f
->cd_size
;
3289 int mf_size
= f
->mf_size
, pd_size
= f
->pd_size
;
3290 int features_size
= bn_size
+ cd_size
+ mf_size
+ pd_size
+ f
->n_abstract
;
3291 Builtin bnp
= f
->bn_list
;
3292 Conddef cdp
= f
->cd_list
;
3293 MathFunc mfp
= f
->mf_list
;
3294 Paramdef pdp
= f
->pd_list
;
3295 int *enables
= zhalloc(sizeof(int) * features_size
);
3296 int *enablep
= enables
;
3299 *enablep
++ = ((bnp
++)->node
.flags
& BINF_ADDED
) ? 1 : 0;
3301 *enablep
++ = ((cdp
++)->flags
& CONDF_ADDED
) ? 1 : 0;
3303 *enablep
++ = ((mfp
++)->flags
& MFF_ADDED
) ? 1 : 0;
3305 *enablep
++ = (pdp
++)->pm
? 1 : 0;
3311 * Add or remove the concrete features passed in arguments,
3312 * depending on the corresponding element of the array e.
3313 * If e is NULL, disable everything.
3314 * Return 0 for success, 1 for failure; does not attempt
3315 * to imitate the return values of addbuiltins() etc.
3316 * Any failure in adding a requested feature is an
3322 setfeatureenables(Module m
, Features f
, int *e
)
3327 if (setbuiltins(m
->node
.nam
, f
->bn_list
, f
->bn_size
, e
))
3333 if (setconddefs(m
->node
.nam
, f
->cd_list
, f
->cd_size
, e
))
3339 if (setmathfuncs(m
->node
.nam
, f
->mf_list
, f
->mf_size
, e
))
3343 if (setparamdefs(m
->node
.nam
, f
->pd_list
, f
->pd_size
, e
))
3352 * Convenient front-end to get or set features which
3353 * can be used in a module enables_() function.
3358 handlefeatures(Module m
, Features f
, int **enables
)
3360 if (!enables
|| *enables
)
3361 return setfeatureenables(m
, f
, *enables
);
3362 *enables
= getfeatureenables(m
, f
);
3367 * Ensure module "modname" is providing feature with "prefix"
3368 * and "feature" (e.g. "b:", "limit"). If feature is NULL,
3369 * ensure all features are loaded (used for compatibility
3370 * with the pre-feature autoloading behaviour).
3372 * This will usually be called from the main shell to handle
3373 * loading of an autoloadable feature.
3375 * Returns 0 on success, 1 for error in module, 2 for error
3376 * setting the feature. However, this isn't actually all
3377 * that useful for testing immediately on an autoload since
3378 * it could be a failure to autoload a different feature
3379 * from the one we want. We could fix this but it's
3380 * possible to test other ways.
3385 ensurefeature(const char *modname
, const char *prefix
, const char *feature
)
3388 struct feature_enables features
[2];
3391 return require_module(modname
, NULL
);
3392 f
= dyncat(prefix
, feature
);
3394 features
[0].str
= f
;
3395 features
[0].pat
= NULL
;
3396 features
[1].str
= NULL
;
3397 features
[1].pat
= NULL
;
3398 return require_module(modname
, features
);
3402 * Add autoloadable features for a given module.
3407 autofeatures(const char *cmdnam
, const char *module
, char **features
,
3408 int prefchar
, int defflags
)
3410 int ret
= 0, subret
;
3412 char **modfeatures
= NULL
;
3414 defm
= (Module
)find_module(module
,
3415 FINDMOD_ALIASP
|FINDMOD_CREATE
, NULL
);
3416 if ((defm
->node
.flags
& MOD_LINKED
) ? defm
->u
.linked
:
3418 (void)features_module(defm
, &modfeatures
);
3422 for (; *features
; features
++) {
3423 char *fnam
, *typnam
, *feature
;
3424 int add
, fchar
, flags
= defflags
;
3429 * "features" is list of bare features with no
3430 * type prefix; prefchar gives type character.
3432 add
= 1; /* unless overridden by flag */
3435 feature
= zhalloc(strlen(fnam
) + 3);
3436 sprintf(feature
, "%c:%s", fchar
, fnam
);
3438 feature
= *features
;
3439 if (*feature
== '-') {
3444 if (*feature
== '+')
3448 if (!*feature
|| feature
[1] != ':') {
3449 zwarnnam(cmdnam
, "bad format for autoloadable feature: `%s'",
3457 if (flags
& FEAT_REMOVE
)
3462 fn
= add
? add_autobin
: del_autobin
;
3467 flags
|= FEAT_INFIX
;
3470 fn
= add
? add_autocond
: del_autocond
;
3471 typnam
= "condition";
3475 fn
= add
? add_automathfunc
: del_automathfunc
;
3476 typnam
= "math function";
3480 fn
= add
? add_autoparam
: del_autoparam
;
3481 typnam
= "parameter";
3485 zwarnnam(cmdnam
, "bad autoloadable feature type: `%c'",
3491 if (strchr(fnam
, '/')) {
3492 zwarnnam(cmdnam
, "%s: `/' is illegal in a %s", fnam
, typnam
);
3499 * Traditional un-autoload syntax doesn't tell us
3500 * which module this came from.
3503 for (i
= 0, m
= NULL
; !m
&& i
< modulestab
->hsize
; i
++) {
3504 for (m
= (Module
)modulestab
->nodes
[i
]; m
;
3505 m
= (Module
)m
->node
.next
) {
3507 linknodebystring(m
->autoloads
, feature
))
3512 if (!(flags
& FEAT_IGNORE
)) {
3514 zwarnnam(cmdnam
, "%s: no such %s", fnam
, typnam
);
3526 * If the module is already available, check that
3527 * it does in fact provide the necessary feature.
3529 for (ptr
= modfeatures
; *ptr
; ptr
++)
3530 if (!strcmp(*ptr
, feature
))
3533 zwarnnam(cmdnam
, "module `%s' has no such feature: `%s'",
3534 m
->node
.nam
, feature
);
3539 if (!m
->autoloads
) {
3540 m
->autoloads
= znewlinklist();
3541 zaddlinknode(m
->autoloads
, ztrdup(feature
));
3543 /* Insert in lexical order */
3544 LinkNode ln
, prev
= (LinkNode
)m
->autoloads
;
3545 while ((ln
= nextnode(prev
))) {
3546 int cmp
= strcmp(feature
, (char *)getdata(ln
));
3548 /* Already there. Never an error. */
3552 zinsertlinknode(m
->autoloads
, prev
,
3559 zaddlinknode(m
->autoloads
, ztrdup(feature
));
3561 } else if (m
->autoloads
) {
3563 if ((ln
= linknodebystring(m
->autoloads
, feature
)))
3564 zsfree((char *)remnode(m
->autoloads
, ln
));
3567 * With -i (or zmodload -Fa), removing an autoload
3568 * that's not there is not an error.
3570 subret
= (flags
& FEAT_IGNORE
) ? -2 : 2;
3575 subret
= fn(module
, fnam
, flags
);
3578 /* -2 indicates not an error, just skip running fn() */
3583 zwarnnam(cmdnam
, "failed to add %s `%s'", typnam
, fnam
);
3587 zwarnnam(cmdnam
, "%s: no such %s", fnam
, typnam
);
3591 zwarnnam(cmdnam
, "%s: %s is already defined", fnam
, typnam
);
3595 /* no (further) message needed */