26763: fix problem on failed cd -s to relative path
[zsh.git] / Src / module.c
blob8e5586e6d4826bf1d923812c0e8a05ac15a52074
1 /*
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
7 * All rights reserved.
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.
29 #include "zsh.mdh"
30 #include "module.pro"
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.
38 /**/
39 LinkList linkedmodules;
41 /* $module_path ($MODULE_PATH) */
43 /**/
44 char **module_path;
46 /* Hash of modules */
48 /**/
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().
56 enum {
58 * `-i' option: ignore errors pertaining to redefinitions,
59 * or indicate to do_module_features() that it should be
60 * silent.
62 FEAT_IGNORE = 0x0001,
63 /* If a condition, condition is infix rather than prefix */
64 FEAT_INFIX = 0x0002,
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
69 * autoloading.
71 FEAT_AUTOALL = 0x0004,
73 * Remove feature: alternative to "-X:NAME" used if
74 * X is passed separately from NAME.
76 FEAT_REMOVE = 0x0008,
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,
103 int flags);
105 /* Bits in the second argument to find_module. */
106 enum {
108 * Resolve any aliases to the underlying module.
110 FINDMOD_ALIASP = 0x0001,
112 * Create an element for the module in the list if
113 * it is not found.
115 FINDMOD_CREATE = 0x0002,
118 static void
119 freemodulenode(HashNode hn)
121 Module m = (Module) hn;
123 if (m->node.flags & MOD_ALIAS)
124 zsfree(m->u.alias);
125 zsfree(m->node.nam);
126 if (m->autoloads)
127 freelinklist(m->autoloads, freestr);
128 if (m->deps)
129 freelinklist(m->deps, freestr);
130 zfree(m, sizeof(*m));
133 /* flags argument to printmodulenode */
134 enum {
135 /* -L flag, output zmodload commands */
136 PRINTMOD_LIST = 0x0001,
137 /* -e flag */
138 PRINTMOD_EXIST = 0x0002,
139 /* -A flag */
140 PRINTMOD_ALIAS = 0x0004,
141 /* -d flag */
142 PRINTMOD_DEPS = 0x0008,
143 /* -F flag */
144 PRINTMOD_FEATURES = 0x0010,
145 /* -l flag in combination with -L flag */
146 PRINTMOD_LISTALL = 0x0020,
147 /* -a flag */
148 PRINTMOD_AUTO = 0x0040
151 /* Scan function for printing module details */
153 static void
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
160 * cases, too.
162 const char *modname = m->node.nam;
164 if (flags & PRINTMOD_DEPS) {
166 * Print the module's dependencies.
168 LinkNode n;
170 if (!m->deps)
171 return;
173 if (flags & PRINTMOD_LIST) {
174 printf("zmodload -d ");
175 if (modname[0] == '-')
176 fputs("-- ", stdout);
177 quotedzputs(modname, stdout);
178 } else {
179 nicezputs(modname, stdout);
180 putchar(':');
182 for (n = firstnode(m->deps); n; incnode(n)) {
183 putchar(' ');
184 if (flags & PRINTMOD_LIST)
185 quotedzputs((char *) getdata(n), stdout);
186 else
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)))
197 return;
199 if (!m->u.handle || (m->node.flags & MOD_UNLOAD))
200 return;
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);
211 putchar('=');
212 quotedzputs(m->u.alias, stdout);
213 } else {
214 nicezputs(modname, stdout);
215 fputs(" -> ", stdout);
216 nicezputs(m->u.alias, stdout);
218 } else if (m->u.handle || (flags & PRINTMOD_AUTO)) {
220 * Loaded module.
222 if (flags & PRINTMOD_LIST) {
224 * List with -L format. Possibly we are printing
225 * features, either enables or autoloads.
227 char **features = NULL;
228 int *enables = NULL;
229 if (flags & PRINTMOD_AUTO) {
230 if (!m->autoloads || !firstnode(m->autoloads))
231 return;
232 } else if (flags & PRINTMOD_FEATURES) {
233 if (features_module(m, &features) ||
234 enables_module(m, &enables) ||
235 !*features)
236 return;
238 printf("zmodload ");
239 if (flags & PRINTMOD_AUTO) {
240 fputs("-Fa ", stdout);
241 } else if (features)
242 fputs("-F ", stdout);
243 if(modname[0] == '-')
244 fputs("-- ", stdout);
245 quotedzputs(modname, stdout);
246 if (flags & PRINTMOD_AUTO) {
247 LinkNode an;
248 for (an = firstnode(m->autoloads); an; incnode(an)) {
249 putchar(' ');
250 quotedzputs((char *)getdata(an), stdout);
252 } else if (features) {
253 const char *f;
254 while ((f = *features++)) {
255 int on = *enables++;
256 if (flags & PRINTMOD_LISTALL)
257 printf(" %s", on ? "+" : "-");
258 else if (!on)
259 continue;
260 else
261 putchar(' ');
262 quotedzputs(f, stdout);
265 } else /* -l */
266 nicezputs(modname, stdout);
267 } else
268 return;
269 putchar('\n');
272 /**/
273 HashTable
274 newmoduletable(int size, char const *name)
276 HashTable ht;
277 ht = newhashtable(size, name, NULL);
279 ht->hash = hasher;
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;
293 return ht;
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. */
304 /**/
306 setup_(UNUSED(Module m))
308 return 0;
311 /**/
313 features_(UNUSED(Module m), UNUSED(char ***features))
316 * There are lots and lots of features, but they're not
317 * handled here.
319 return 1;
322 /**/
324 enables_(UNUSED(Module m), UNUSED(int **enables))
326 return 1;
329 /**/
331 boot_(UNUSED(Module m))
333 return 0;
336 /**/
338 cleanup_(UNUSED(Module m))
340 return 0;
343 /**/
345 finish_(UNUSED(Module m))
347 return 0;
351 /************************************************************************
352 * Module utility functions
353 ************************************************************************/
355 /* This registers a builtin module. */
357 /**/
358 void
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)
366 Linkedmod m;
368 m = (Linkedmod) zalloc(sizeof(*m));
370 m->name = ztrdup(n);
371 m->setup = setup;
372 m->features = features;
373 m->enables = enables;
374 m->boot = boot;
375 m->cleanup = cleanup;
376 m->finish = finish;
378 zaddlinknode(linkedmodules, m);
381 /* Check if a module is linked in. */
383 /**/
384 Linkedmod
385 module_linked(char const *name)
387 LinkNode node;
389 for (node = firstnode(linkedmodules); node; incnode(node))
390 if (!strcmp(((Linkedmod) getdata(node))->name, name))
391 return (Linkedmod) getdata(node);
393 return NULL;
397 /************************************************************************
398 * Support for the various feature types.
399 * First, builtins.
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. */
407 /**/
408 static int
409 addbuiltin(Builtin b)
411 Builtin bn = (Builtin) builtintab->getnode2(builtintab, b->node.nam);
412 if (bn && (bn->node.flags & BINF_ADDED))
413 return 1;
414 if (bn)
415 builtintab->freenode(builtintab->removenode(builtintab, b->node.nam));
416 builtintab->addnode(builtintab, b->node.nam, b);
417 return 0;
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. */
424 /**/
425 static int
426 add_autobin(const char *module, const char *bnam, int flags)
428 Builtin bn;
429 int ret;
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))
439 return 1;
441 return 0;
444 /* Remove the builtin added previously by addbuiltin(). Returns *
445 * zero on succes and -1 if there is no builtin with that name. */
447 /**/
449 deletebuiltin(const char *nam)
451 Builtin bn;
453 bn = (Builtin) builtintab->removenode(builtintab, nam);
454 if (!bn)
455 return -1;
456 builtintab->freenode(&bn->node);
457 return 0;
460 /* Remove an autoloaded added by add_autobin */
462 /**/
463 static int
464 del_autobin(UNUSED(const char *module), const char *bnam, int flags)
466 Builtin bn = (Builtin) builtintab->getnode2(builtintab, bnam);
467 if (!bn) {
468 if(!(flags & FEAT_IGNORE))
469 return 2;
470 } else if (bn->node.flags & BINF_ADDED) {
471 if (!(flags & FEAT_IGNORE))
472 return 3;
473 } else
474 deletebuiltin(bnam);
476 return 0;
480 * Manipulate a set of builtins. This should be called
481 * via setfeatureenables() (or, usually, via the next level up,
482 * handlefeatures()).
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.
499 /**/
500 static int
501 setbuiltins(char const *nam, Builtin binl, int size, int *e)
503 int ret = 0, n;
505 for(n = 0; n < size; n++) {
506 Builtin b = &binl[n];
507 if (e && *e++) {
508 if (b->node.flags & BINF_ADDED)
509 continue;
510 if (addbuiltin(b)) {
511 zwarnnam(nam,
512 "name clash when adding builtin `%s'", b->node.nam);
513 ret = 1;
514 } else {
515 b->node.flags |= BINF_ADDED;
517 } else {
518 if (!(b->node.flags & BINF_ADDED))
519 continue;
520 if (deletebuiltin(b->node.nam)) {
521 zwarnnam(nam, "builtin `%s' already deleted", b->node.nam);
522 ret = 1;
523 } else {
524 b->node.flags &= ~BINF_ADDED;
528 return ret;
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().
542 /**/
543 mod_export int
544 addbuiltins(char const *nam, Builtin binl, int size)
546 int ret = 0, n;
548 for(n = 0; n < size; n++) {
549 Builtin b = &binl[n];
550 if(b->node.flags & BINF_ADDED)
551 continue;
552 if(addbuiltin(b)) {
553 zwarnnam(nam, "name clash when adding builtin `%s'", b->node.nam);
554 ret = 1;
555 } else {
556 b->node.flags |= BINF_ADDED;
559 return ret;
563 /************************************************************************
564 * Function wrappers.
565 ************************************************************************/
567 /* The list of function wrappers defined. */
569 /**/
570 FuncWrap wrappers;
572 /* This adds a definition for a wrapper. Return value is one in case of *
573 * error and zero if all went fine. */
575 /**/
576 mod_export int
577 addwrapper(Module m, FuncWrap w)
579 FuncWrap p, q;
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
585 * loaded.
587 if (m->node.flags & MOD_ALIAS)
588 return 1;
590 if (w->flags & WRAPF_ADDED)
591 return 1;
592 for (p = wrappers, q = NULL; p; q = p, p = p->next);
593 if (q)
594 q->next = w;
595 else
596 wrappers = w;
597 w->next = NULL;
598 w->flags |= WRAPF_ADDED;
599 w->module = m;
601 return 0;
604 /* This removes the given wrapper definition from the list. Returned is *
605 * one in case of error and zero otherwise. */
607 /**/
608 mod_export int
609 deletewrapper(Module m, FuncWrap w)
611 FuncWrap p, q;
613 if (m->node.flags & MOD_ALIAS)
614 return 1;
616 if (w->flags & WRAPF_ADDED) {
617 for (p = wrappers, q = NULL; p && p != w; q = p, p = p->next);
619 if (p) {
620 if (q)
621 q->next = p->next;
622 else
623 wrappers = p->next;
624 p->flags &= ~WRAPF_ADDED;
626 return 0;
629 return 1;
633 /************************************************************************
634 * Conditions.
635 ************************************************************************/
637 /* The list of module-defined conditions. */
639 /**/
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. */
646 /**/
647 Conddef
648 getconddef(int inf, const char *name, int autol)
650 Conddef p;
651 int f = 1;
653 do {
654 for (p = condtab; p; p = p->next) {
655 if ((!!inf == !!(p->flags & CONDF_INFIX)) &&
656 !strcmp(name, p->name))
657 break;
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.
664 if (f) {
665 (void)ensurefeature(p->module,
666 (p->flags & CONDF_INFIX) ? "C:" : "c:",
667 (p->flags & CONDF_AUTOALL) ? NULL : name);
668 f = 0;
669 p = NULL;
670 } else {
671 deleteconddef(p);
672 return NULL;
674 } else
675 break;
676 } while (!p);
677 return p;
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.
690 /**/
691 static int
692 addconddef(Conddef c)
694 Conddef p = getconddef((c->flags & CONDF_INFIX), c->name, 0);
696 if (p) {
697 if (!p->module || (p->flags & CONDF_ADDED))
698 return 1;
699 /* There is an autoload definition. */
701 deleteconddef(p);
703 c->next = condtab;
704 condtab = c;
705 return 0;
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. */
711 /**/
713 deleteconddef(Conddef c)
715 Conddef p, q;
717 for (p = condtab, q = NULL; p && p != c; q = p, p = p->next);
719 if (p) {
720 if (q)
721 q->next = p->next;
722 else
723 condtab = p->next;
725 if (p->module) {
726 /* autoloaded, free it */
727 zsfree(p->name);
728 zsfree(p->module);
729 zfree(p, sizeof(*p));
731 return 0;
733 return -1;
737 * Add or remove sets of conditions. The interface is
738 * identical to setbuiltins().
741 /**/
742 static int
743 setconddefs(char const *nam, Conddef c, int size, int *e)
745 int ret = 0;
747 while (size--) {
748 if (e && *e++) {
749 if (c->flags & CONDF_ADDED) {
750 c++;
751 continue;
753 if (addconddef(c)) {
754 zwarnnam(nam, "name clash when adding condition `%s'",
755 c->name);
756 ret = 1;
757 } else {
758 c->flags |= CONDF_ADDED;
760 } else {
761 if (!(c->flags & CONDF_ADDED)) {
762 c++;
763 continue;
765 if (deleteconddef(c)) {
766 zwarnnam(nam, "condition `%s' already deleted", c->name);
767 ret = 1;
768 } else {
769 c->flags &= ~CONDF_ADDED;
772 c++;
774 return ret;
777 /* This adds a definition for autoloading a module for a condition. */
779 /**/
780 static int
781 add_autocond(const char *module, const char *cnam, int flags)
783 Conddef c;
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);
793 if (addconddef(c)) {
794 zsfree(c->name);
795 zsfree(c->module);
796 zfree(c, sizeof(*c));
798 if (!(flags & FEAT_IGNORE))
799 return 1;
801 return 0;
804 /* Remove a condition added with add_autocond */
806 /**/
807 static int
808 del_autocond(UNUSED(const char *modnam), const char *cnam, int flags)
810 Conddef cd = getconddef((flags & FEAT_INFIX) ? 1 : 0, cnam, 0);
812 if (!cd) {
813 if (!(flags & FEAT_IGNORE)) {
814 return 2;
816 } else if (cd->flags & CONDF_ADDED) {
817 if (!(flags & FEAT_IGNORE))
818 return 3;
819 } else
820 deleteconddef(cd);
822 return 0;
825 /************************************************************************
826 * Hook functions.
827 ************************************************************************/
829 /* This list of hook functions defined. */
831 /**/
832 Hookdef hooktab;
834 /* Find a hook definition given the name. */
836 /**/
837 Hookdef
838 gethookdef(char *n)
840 Hookdef p;
842 for (p = hooktab; p; p = p->next)
843 if (!strcmp(n, p->name))
844 return p;
845 return NULL;
848 /* This adds the given hook definition. The return value is zero on *
849 * success and 1 on failure. */
851 /**/
853 addhookdef(Hookdef h)
855 if (gethookdef(h->name))
856 return 1;
858 h->next = hooktab;
859 hooktab = h;
860 h->funcs = znewlinklist();
862 return 0;
866 * This adds multiple hook definitions. This is like addbuiltins().
867 * This allows a NULL module because we call it from init.c.
870 /**/
871 mod_export int
872 addhookdefs(Module m, Hookdef h, int size)
874 int ret = 0;
876 while (size--) {
877 if (addhookdef(h)) {
878 zwarnnam(m ? m->node.nam : NULL,
879 "name clash when adding hook `%s'", h->name);
880 ret = 1;
882 h++;
884 return ret;
887 /* Delete hook definitions. */
889 /**/
891 deletehookdef(Hookdef h)
893 Hookdef p, q;
895 for (p = hooktab, q = NULL; p && p != h; q = p, p = p->next);
897 if (!p)
898 return 1;
900 if (q)
901 q->next = p->next;
902 else
903 hooktab = p->next;
904 freelinklist(p->funcs, NULL);
905 return 0;
908 /* Remove multiple hook definitions. */
910 /**/
911 mod_export int
912 deletehookdefs(UNUSED(Module m), Hookdef h, int size)
914 int ret = 0;
916 while (size--) {
917 if (deletehookdef(h))
918 ret = 1;
919 h++;
921 return ret;
924 /* Add a function to a hook. */
926 /**/
928 addhookdeffunc(Hookdef h, Hookfn f)
930 zaddlinknode(h->funcs, (void *) f);
932 return 0;
935 /**/
936 mod_export int
937 addhookfunc(char *n, Hookfn f)
939 Hookdef h = gethookdef(n);
941 if (h)
942 return addhookdeffunc(h, f);
943 return 1;
946 /* Delete a function from a hook. */
948 /**/
950 deletehookdeffunc(Hookdef h, Hookfn f)
952 LinkNode p;
954 for (p = firstnode(h->funcs); p; incnode(p))
955 if (f == (Hookfn) getdata(p)) {
956 remnode(h->funcs, p);
957 return 0;
959 return 1;
962 /* Delete a hook. */
964 /**/
965 mod_export int
966 deletehookfunc(char *n, Hookfn f)
968 Hookdef h = gethookdef(n);
970 if (h)
971 return deletehookdeffunc(h, f);
972 return 1;
975 /* Run the function(s) for a hook. */
977 /**/
978 mod_export int
979 runhookdef(Hookdef h, void *d)
981 if (empty(h->funcs)) {
982 if (h->def)
983 return h->def(h, d);
984 return 0;
985 } else if (h->flags & HOOKF_ALL) {
986 LinkNode p;
987 int r;
989 for (p = firstnode(h->funcs); p; incnode(p))
990 if ((r = ((Hookfn) getdata(p))(h, d)))
991 return r;
992 if (h->def)
993 return h->def(h, d);
994 return 0;
995 } else
996 return ((Hookfn) getdata(lastnode(h->funcs)))(h, d);
1001 /************************************************************************
1002 * Shell parameters.
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.
1014 static int
1015 checkaddparam(const char *nam, int opt_i)
1017 Param pm;
1019 if (!(pm = (Param) gethashnode2(paramtab, nam)))
1020 return 0;
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",
1033 nam, pm->level ?
1034 "local parameter exists" :
1035 "parameter already exists");
1036 return 1;
1038 return 2;
1041 unsetparam_pm(pm, 0, 1);
1042 return 0;
1045 /* This adds the given parameter definition. The return value is zero on *
1046 * success and 1 on failure. */
1048 /**/
1050 addparamdef(Paramdef d)
1052 Param pm;
1054 if (checkaddparam(d->name, 0))
1055 return 1;
1057 if (d->getnfn) {
1058 if (!(pm = createspecialhash(d->name, d->getnfn,
1059 d->scantfn, d->flags)))
1060 return 1;
1062 else if (!(pm = createparam(d->name, d->flags)) &&
1063 !(pm = (Param) paramtab->getnode(paramtab, d->name)))
1064 return 1;
1066 d->pm = pm;
1067 pm->level = 0;
1068 if (d->var)
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)) {
1076 case PM_SCALAR:
1077 pm->gsu.s = d->gsu ? (GsuScalar)d->gsu : &varscalar_gsu;
1078 break;
1080 case PM_INTEGER:
1081 pm->gsu.i = d->gsu ? (GsuInteger)d->gsu : &varinteger_gsu;
1082 break;
1084 case PM_ARRAY:
1085 pm->gsu.a = d->gsu ? (GsuArray)d->gsu : &vararray_gsu;
1086 break;
1088 case PM_HASHED:
1089 /* hashes may behave like standard hashes */
1090 if (d->gsu)
1091 pm->gsu.h = (GsuHash)d->gsu;
1092 break;
1094 default:
1095 unsetparam_pm(pm, 0, 1);
1096 return 1;
1100 return 0;
1103 /* Delete parameters defined. No error checking yet. */
1105 /**/
1107 deleteparamdef(Paramdef d)
1109 Param pm = (Param) paramtab->getnode(paramtab, d->name);
1111 if (!pm)
1112 return 1;
1113 if (pm != d->pm) {
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;
1120 searchpm;
1121 prevpm = searchpm, searchpm = searchpm->old)
1122 if (searchpm == d->pm)
1123 break;
1125 if (!searchpm)
1126 return 1;
1128 paramtab->removenode(paramtab, pm->node.nam);
1129 prevpm->old = searchpm->old;
1130 searchpm->old = pm;
1131 paramtab->addnode(paramtab, searchpm->node.nam, searchpm);
1133 pm = searchpm;
1135 pm->node.flags = (pm->node.flags & ~PM_READONLY) | PM_REMOVABLE;
1136 unsetparam_pm(pm, 0, 1);
1137 d->pm = NULL;
1138 return 0;
1142 * Add or remove sets of parameters. The interface is
1143 * identical to setbuiltins().
1146 /**/
1147 static int
1148 setparamdefs(char const *nam, Paramdef d, int size, int *e)
1150 int ret = 0;
1152 while (size--) {
1153 if (e && *e++) {
1154 if (d->pm) {
1155 d++;
1156 continue;
1158 if (addparamdef(d)) {
1159 zwarnnam(nam, "error when adding parameter `%s'", d->name);
1160 ret = 1;
1162 } else {
1163 if (!d->pm) {
1164 d++;
1165 continue;
1167 if (deleteparamdef(d)) {
1168 zwarnnam(nam, "parameter `%s' already deleted", d->name);
1169 ret = 1;
1172 d++;
1174 return ret;
1177 /* This adds a definition for autoloading a module for a parameter. */
1179 /**/
1180 static int
1181 add_autoparam(const char *module, const char *pnam, int flags)
1183 Param pm;
1184 int ret;
1186 queue_signals();
1187 if ((ret = checkaddparam(pnam, (flags & FEAT_IGNORE)))) {
1188 unqueue_signals();
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;
1204 unqueue_signals();
1206 return 0;
1209 /* Remove a parameter added with add_autoparam() */
1211 /**/
1212 static int
1213 del_autoparam(UNUSED(const char *modnam), const char *pnam, int flags)
1215 Param pm = (Param) gethashnode2(paramtab, pnam);
1217 if (!pm) {
1218 if (!(flags & FEAT_IGNORE))
1219 return 2;
1220 } else if (!(pm->node.flags & PM_AUTOLOAD)) {
1221 if (!(flags & FEAT_IGNORE))
1222 return 3;
1223 } else
1224 unsetparam_pm(pm, 0, 1);
1226 return 0;
1229 /************************************************************************
1230 * Math functions.
1231 ************************************************************************/
1233 /* List of math functions. */
1235 /**/
1236 MathFunc mathfuncs;
1239 * Remove a single math function form the list (utility function).
1240 * This does not delete a module math function, that's deletemathfunc().
1243 /**/
1244 void
1245 removemathfunc(MathFunc previous, MathFunc current)
1247 if (previous)
1248 previous->next = current->next;
1249 else
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. */
1259 /**/
1260 MathFunc
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 :
1274 name);
1276 return getmathfunc(name, 0);
1278 return p;
1281 return NULL;
1284 /* Add a single math function */
1286 /**/
1287 static int
1288 addmathfunc(MathFunc f)
1290 MathFunc p, q = NULL;
1292 if (f->flags & MFF_ADDED)
1293 return 1;
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);
1302 break;
1304 return 1;
1307 f->next = mathfuncs;
1308 mathfuncs = f;
1310 return 0;
1313 /* Delete a single math function */
1315 /**/
1316 mod_export int
1317 deletemathfunc(MathFunc f)
1319 MathFunc p, q;
1321 for (p = mathfuncs, q = NULL; p && p != f; q = p, p = p->next);
1323 if (p) {
1324 if (q)
1325 q->next = f->next;
1326 else
1327 mathfuncs = f->next;
1329 /* the following applies to both unloaded and user-defined functions */
1330 if (f->module) {
1331 zsfree(f->name);
1332 zsfree(f->module);
1333 zfree(f, sizeof(*f));
1334 } else
1335 f->flags &= ~MFF_ADDED;
1337 return 0;
1339 return -1;
1343 * Add or remove sets of math functions. The interface is
1344 * identical to setbuiltins().
1347 /**/
1348 static int
1349 setmathfuncs(char const *nam, MathFunc f, int size, int *e)
1351 int ret = 0;
1353 while (size--) {
1354 if (e && *e++) {
1355 if (f->flags & MFF_ADDED) {
1356 f++;
1357 continue;
1359 if (addmathfunc(f)) {
1360 zwarnnam(nam, "name clash when adding math function `%s'",
1361 f->name);
1362 ret = 1;
1363 } else {
1364 f->flags |= MFF_ADDED;
1366 } else {
1367 if (!(f->flags & MFF_ADDED)) {
1368 f++;
1369 continue;
1371 if (deletemathfunc(f)) {
1372 zwarnnam(nam, "math function `%s' already deleted", f->name);
1373 ret = 1;
1374 } else {
1375 f->flags &= ~MFF_ADDED;
1378 f++;
1380 return ret;
1383 /* Add an autoload definition for a math function. */
1385 /**/
1386 static int
1387 add_automathfunc(const char *module, const char *fnam, int flags)
1389 MathFunc f;
1391 f = (MathFunc) zalloc(sizeof(*f));
1393 f->name = ztrdup(fnam);
1394 f->module = ztrdup(module);
1395 f->flags = 0;
1397 if (addmathfunc(f)) {
1398 zsfree(f->name);
1399 zsfree(f->module);
1400 zfree(f, sizeof(*f));
1402 if (!(flags & FEAT_IGNORE))
1403 return 1;
1406 return 0;
1409 /* Remove a math function added with add_automathfunc() */
1411 /**/
1412 static int
1413 del_automathfunc(UNUSED(const char *modnam), const char *fnam, int flags)
1415 MathFunc f = getmathfunc(fnam, 0);
1417 if (!f) {
1418 if (!(flags & FEAT_IGNORE))
1419 return 2;
1420 } else if (f->flags & MFF_ADDED) {
1421 if (!(flags & FEAT_IGNORE))
1422 return 3;
1423 } else
1424 deletemathfunc(f);
1426 return 0;
1429 /************************************************************************
1430 * Now support for dynamical loading and the fallback functions
1431 * we use for loading if dynamical loading is not available.
1432 ************************************************************************/
1434 /**/
1435 #ifdef DYNAMIC
1437 /**/
1438 #ifdef AIXDYNAMIC
1440 #include <sys/ldr.h>
1442 static char *dlerrstr[256];
1444 static void *
1445 load_and_bind(const char *fn)
1447 void *ret = (void *) load((char *) fn, L_NOAUTODEFER, NULL);
1449 if (ret) {
1450 Module m;
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);
1461 if (err) {
1462 loadquery(L_GETMESSAGES, dlerrstr, sizeof(dlerrstr));
1463 unload(ret);
1464 ret = NULL;
1466 } else
1467 loadquery(L_GETMESSAGES, dlerrstr, sizeof(dlerrstr));
1469 return ret;
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
1477 #endif
1479 /**/
1480 #else
1482 #ifdef HAVE_DLFCN_H
1483 # if defined(HAVE_DL_H) && defined(HPUXDYNAMIC)
1484 # include <dl.h>
1485 # else
1486 # include <dlfcn.h>
1487 # endif
1488 #else
1489 # ifdef HAVE_DL_H
1490 # include <dl.h>
1491 # define RTLD_LAZY BIND_DEFERRED
1492 # define RTLD_GLOBAL DYNAMIC_PATH
1493 # else
1494 # include <sys/types.h>
1495 # include <nlist.h>
1496 # include <link.h>
1497 # endif
1498 #endif
1500 /**/
1501 #ifdef HPUXDYNAMIC
1502 # define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0)
1503 # define dlclose(handle) shl_unload((shl_t)(handle))
1505 static
1506 void *
1507 hpux_dlsym(void *handle, char *name)
1509 void *sym_addr;
1510 if (!shl_findsym((shl_t *)&handle, name, TYPE_UNDEFINED, &sym_addr))
1511 return sym_addr;
1512 return NULL;
1515 # define dlsym(handle,name) hpux_dlsym(handle,name)
1516 # ifdef HAVE_DLERROR /* paranoia */
1517 # undef HAVE_DLERROR
1518 # endif
1519 #else
1520 # ifndef HAVE_DLCLOSE
1521 # define dlclose(X) ((X), 0)
1522 # endif
1523 /**/
1524 #endif
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 */
1542 /**/
1543 #endif /* !AIXDYNAMIC */
1545 #ifndef RTLD_LAZY
1546 # define RTLD_LAZY 1
1547 #endif
1548 #ifndef RTLD_GLOBAL
1549 # define RTLD_GLOBAL 0
1550 #endif
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.
1558 /**/
1559 static void *
1560 try_load_module(char const *name)
1562 char buf[PATH_MAX + 1];
1563 char **pp;
1564 void *ret = NULL;
1565 int l;
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)
1570 continue;
1571 sprintf(buf, "%s/%s.%s", **pp ? *pp : ".", name, DL_EXT);
1572 ret = dlopen(unmeta(buf), RTLD_LAZY | RTLD_GLOBAL);
1575 return ret;
1579 * Load a module, with option to complain or not.
1580 * Returns the handle from the dynamic loader.
1583 /**/
1584 static void *
1585 do_load_module(char const *name, int silent)
1587 void *ret;
1589 ret = try_load_module(name);
1590 if (!ret && !silent) {
1591 #ifdef HAVE_DLERROR
1592 zwarn("failed to load module `%s': %s", name, dlerror());
1593 #else
1594 zwarn("failed to load module: %s", name);
1595 #endif
1597 return ret;
1600 /**/
1601 #else /* !DYNAMIC */
1604 * Dummy loader when no dynamic loading available; always fails.
1607 /**/
1608 static void *
1609 do_load_module(char const *name, int silent)
1611 if (!silent)
1612 zwarn("failed to load module: %s", name);
1614 return NULL;
1617 /**/
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
1628 * structure.
1630 /**/
1631 static Module
1632 find_module(const char *name, int flags, const char **namep)
1634 Module m;
1636 m = (Module)modulestab->getnode2(modulestab, name);
1637 if (m) {
1638 if ((flags & FINDMOD_ALIASP) && (m->node.flags & MOD_ALIAS)) {
1639 if (namep)
1640 *namep = m->u.alias;
1641 return find_module(m->u.alias, flags, namep);
1643 if (namep)
1644 *namep = m->node.nam;
1645 return m;
1647 if (!(flags & FINDMOD_CREATE))
1648 return NULL;
1649 m = zshcalloc(sizeof(*m));
1650 modulestab->addnode(modulestab, ztrdup(name), m);
1651 return m;
1655 * Unlink and free a module node from the linked list.
1658 /**/
1659 static void
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.
1674 /**/
1675 mod_export int
1676 module_loaded(const char *name)
1678 Module m;
1680 return ((m = find_module(name, FINDMOD_ALIASP, NULL)) &&
1681 m->u.handle &&
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
1688 * the module.
1691 /**/
1692 #ifdef DYNAMIC
1694 /**/
1695 #ifdef AIXDYNAMIC
1697 /**/
1698 static int
1699 dyn_setup_module(Module m)
1701 return ((int (*)_((int,Module, void*))) m->u.handle)(0, m, NULL);
1704 /**/
1705 static int
1706 dyn_features_module(Module m, char ***features)
1708 return ((int (*)_((int,Module, void*))) m->u.handle)(4, m, features);
1711 /**/
1712 static int
1713 dyn_enables_module(Module m, int **enables)
1715 return ((int (*)_((int,Module, void*))) m->u.handle)(5, m, enables);
1718 /**/
1719 static int
1720 dyn_boot_module(Module m)
1722 return ((int (*)_((int,Module, void*))) m->u.handle)(1, m, NULL);
1725 /**/
1726 static int
1727 dyn_cleanup_module(Module m)
1729 return ((int (*)_((int,Module, void*))) m->u.handle)(2, m, NULL);
1732 /**/
1733 static int
1734 dyn_finish_module(Module m)
1736 return ((int (*)_((int,Module,void *))) m->u.handle)(3, m, NULL);
1739 /**/
1740 #else
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);
1749 char const *p;
1750 char *q;
1751 strcpy(buf, name);
1752 q = strchr(buf, 0);
1753 for(p = m->node.nam; *p; p++) {
1754 if(*p == '/') {
1755 *q++ = 'Q';
1756 *q++ = 's';
1757 } else if(*p == '_') {
1758 *q++ = 'Q';
1759 *q++ = 'u';
1760 } else if(*p == 'Q') {
1761 *q++ = 'Q';
1762 *q++ = 'q';
1763 } else
1764 *q++ = *p;
1766 *q = 0;
1767 return (Module_generic_func) dlsym(m->u.handle, buf);
1768 #endif /* !DYNAMIC_NAME_CLASH_OK */
1771 /**/
1772 static int
1773 dyn_setup_module(Module m)
1775 Module_void_func fn = (Module_void_func)module_func(m, STR_SETUP);
1777 if (fn)
1778 return fn(m);
1779 zwarnnam(m->node.nam, "no setup function");
1780 return 1;
1783 /**/
1784 static int
1785 dyn_features_module(Module m, char ***features)
1787 Module_features_func fn =
1788 (Module_features_func)module_func(m, STR_FEATURES);
1790 if (fn)
1791 return fn(m, features);
1792 /* not a user-visible error if no features function */
1793 return 1;
1796 /**/
1797 static int
1798 dyn_enables_module(Module m, int **enables)
1800 Module_enables_func fn = (Module_enables_func)module_func(m, STR_ENABLES);
1802 if (fn)
1803 return fn(m, enables);
1804 /* not a user-visible error if no enables function */
1805 return 1;
1808 /**/
1809 static int
1810 dyn_boot_module(Module m)
1812 Module_void_func fn = (Module_void_func)module_func(m, STR_BOOT);
1814 if(fn)
1815 return fn(m);
1816 zwarnnam(m->node.nam, "no boot function");
1817 return 1;
1820 /**/
1821 static int
1822 dyn_cleanup_module(Module m)
1824 Module_void_func fn = (Module_void_func)module_func(m, STR_CLEANUP);
1826 if(fn)
1827 return fn(m);
1828 zwarnnam(m->node.nam, "no cleanup function");
1829 return 1;
1832 /* Note that this function does more than just calling finish_foo(), *
1833 * it really unloads the module. */
1835 /**/
1836 static int
1837 dyn_finish_module(Module m)
1839 Module_void_func fn = (Module_void_func)module_func(m, STR_FINISH);
1840 int r;
1842 if (fn)
1843 r = fn(m);
1844 else {
1845 zwarnnam(m->node.nam, "no finish function");
1846 r = 1;
1848 dlclose(m->u.handle);
1849 return r;
1852 /**/
1853 #endif /* !AIXDYNAMIC */
1855 /**/
1856 static int
1857 setup_module(Module m)
1859 return ((m->node.flags & MOD_LINKED) ?
1860 (m->u.linked->setup)(m) : dyn_setup_module(m));
1863 /**/
1864 static int
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));
1872 /**/
1873 static int
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));
1881 /**/
1882 static int
1883 boot_module(Module m)
1885 return ((m->node.flags & MOD_LINKED) ?
1886 (m->u.linked->boot)(m) : dyn_boot_module(m));
1889 /**/
1890 static int
1891 cleanup_module(Module m)
1893 return ((m->node.flags & MOD_LINKED) ?
1894 (m->u.linked->cleanup)(m) : dyn_cleanup_module(m));
1897 /**/
1898 static int
1899 finish_module(Module m)
1901 return ((m->node.flags & MOD_LINKED) ?
1902 (m->u.linked->finish)(m) : dyn_finish_module(m));
1905 /**/
1906 #else /* !DYNAMIC */
1908 /**/
1909 static int
1910 setup_module(Module m)
1912 return ((m->node.flags & MOD_LINKED) ? (m->u.linked->setup)(m) : 1);
1915 /**/
1916 static int
1917 features_module(Module m, char ***features)
1919 return ((m->node.flags & MOD_LINKED) ? (m->u.linked->features)(m, features)
1920 : 1);
1923 /**/
1924 static int
1925 enables_module(Module m, int **enables)
1927 return ((m->node.flags & MOD_LINKED) ? (m->u.linked->enables)(m, enables)
1928 : 1);
1931 /**/
1932 static int
1933 boot_module(Module m)
1935 return ((m->node.flags & MOD_LINKED) ? (m->u.linked->boot)(m) : 1);
1938 /**/
1939 static int
1940 cleanup_module(Module m)
1942 return ((m->node.flags & MOD_LINKED) ? (m->u.linked->cleanup)(m) : 1);
1945 /**/
1946 static int
1947 finish_module(Module m)
1949 return ((m->node.flags & MOD_LINKED) ? (m->u.linked->finish)(m) : 1);
1952 /**/
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).
1969 /**/
1970 static int
1971 do_module_features(Module m, Feature_enables enablesarr, int flags)
1973 char **features;
1974 int ret = 0;
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'",
1989 m->node.nam);
1990 return 1;
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.
2000 LinkNode an, nextn;
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))
2007 break;
2008 if (!*ptr) {
2009 char *arg[2];
2010 if (!(flags & FEAT_IGNORE))
2011 zwarn(
2012 "module `%s' has no such feature: `%s': autoload cancelled",
2013 m->node.nam, al);
2015 * This shouldn't happen, so it's not worth optimising
2016 * the call to autofeatures...
2018 arg[0] = al = dupstring(al);
2019 arg[1] = NULL;
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.
2026 if (enablesarr) {
2027 Feature_enables fep;
2028 for (fep = enablesarr; fep->str; fep++) {
2029 char *str = fep->str;
2030 if (*str == '+' || *str == '-')
2031 str++;
2032 if (fep->pat ? pattry(fep->pat, al) :
2033 !strcmp(al, str)) {
2034 /* can't enable it after all, so return 1 */
2035 ret = 1;
2036 while (fep->str) {
2037 fep->str = fep[1].str;
2038 fep->pat = fep[1].pat;
2039 fep++;
2041 if (!fep->pat)
2042 break;
2050 if (enablesarr) {
2051 Feature_enables fep;
2052 for (fep = enablesarr; fep->str; fep++) {
2053 char **fp, *esp = fep->str;
2054 int on = 1, found = 0;
2055 if (*esp == '+')
2056 esp++;
2057 else if (*esp == '-') {
2058 on = 0;
2059 esp++;
2061 for (fp = features; *fp; fp++)
2062 if (fep->pat ? pattry(fep->pat, *fp) : !strcmp(*fp, esp)) {
2063 enables[fp - features] = on;
2064 found++;
2065 if (!fep->pat)
2066 break;
2068 if (!found) {
2069 if (!(flags & FEAT_IGNORE))
2070 zwarn(fep->pat ?
2071 "module `%s' has no feature matching: `%s'" :
2072 "module `%s' has no such feature: `%s'",
2073 m->node.nam, esp);
2074 return 1;
2077 } else {
2079 * Enable all features. This is used when loading
2080 * without using zmodload -F.
2082 int n_features = arrlen(features);
2083 int *ep;
2084 for (ep = enables; n_features--; ep++)
2085 *ep = 1;
2088 if (enables_module(m, &enables))
2089 return 2;
2090 } else if (enablesarr) {
2091 if (!(flags & FEAT_IGNORE))
2092 zwarn("module `%s' does not support features", m->node.nam);
2093 return 1;
2095 /* Else it doesn't support features but we don't care. */
2097 return ret;
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
2104 * as a string.
2106 * Returns 0 if OK, 1 if completely failed, 2 if some features
2107 * couldn't be set up.
2110 /**/
2111 static int
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 :
2116 FEAT_CHECKAUTO);
2118 if (ret == 1)
2119 return 1;
2121 if (boot_module(m))
2122 return 1;
2123 return ret;
2127 * Cleanup the module.
2130 /**/
2131 static int
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.
2144 /**/
2145 static int
2146 modname_ok(char const *p)
2148 do {
2149 p = itype_end(p, IIDENT, 0);
2150 if (!*p)
2151 return 1;
2152 } while(*p++ == '/');
2153 return 0;
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.
2172 /**/
2173 mod_export int
2174 load_module(char const *name, Feature_enables enablesarr, int silent)
2176 Module m;
2177 void *handle = NULL;
2178 Linkedmod linked;
2179 int set, bootret;
2181 if (!modname_ok(name)) {
2182 if (!silent)
2183 zerr("invalid module name `%s'", name);
2184 return 1;
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
2189 * is the right one.
2191 queue_signals();
2192 if (!(m = find_module(name, FINDMOD_ALIASP, &name))) {
2193 if (!(linked = module_linked(name)) &&
2194 !(handle = do_load_module(name, silent))) {
2195 unqueue_signals();
2196 return 1;
2198 m = zshcalloc(sizeof(*m));
2199 if (handle) {
2200 m->u.handle = handle;
2201 m->node.flags |= MOD_SETUP;
2202 } else {
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) {
2210 if (!set)
2211 do_cleanup_module(m);
2212 finish_module(m);
2213 delete_module(m);
2214 unqueue_signals();
2215 return 1;
2217 m->node.flags |= MOD_INIT_S | MOD_INIT_B;
2218 m->node.flags &= ~MOD_SETUP;
2219 unqueue_signals();
2220 return bootret;
2222 if (m->node.flags & MOD_SETUP) {
2223 unqueue_signals();
2224 return 0;
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) {
2229 unqueue_signals();
2230 return 0;
2232 if (m->node.flags & MOD_BUSY) {
2233 zerr("circular dependencies for module ;%s", name);
2234 return 1;
2236 m->node.flags |= MOD_BUSY;
2238 * TODO: shouldn't we unload the module if one of
2239 * its dependencies fails?
2241 if (m->deps) {
2242 LinkNode n;
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;
2246 unqueue_signals();
2247 return 1;
2250 m->node.flags &= ~MOD_BUSY;
2251 if (!m->u.handle) {
2252 handle = NULL;
2253 if (!(linked = module_linked(name)) &&
2254 !(handle = do_load_module(name, silent))) {
2255 unqueue_signals();
2256 return 1;
2258 if (handle) {
2259 m->u.handle = handle;
2260 m->node.flags |= MOD_SETUP;
2261 } else {
2262 m->u.linked = linked;
2263 m->node.flags |= MOD_SETUP | MOD_LINKED;
2265 if (setup_module(m)) {
2266 finish_module(m);
2267 if (handle)
2268 m->u.handle = NULL;
2269 else
2270 m->u.linked = NULL;
2271 m->node.flags &= ~MOD_SETUP;
2272 unqueue_signals();
2273 return 1;
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);
2280 finish_module(m);
2281 if (m->node.flags & MOD_LINKED)
2282 m->u.linked = NULL;
2283 else
2284 m->u.handle = NULL;
2285 m->node.flags &= ~MOD_SETUP;
2286 unqueue_signals();
2287 return 1;
2289 m->node.flags |= MOD_INIT_B;
2290 m->node.flags &= ~MOD_SETUP;
2291 unqueue_signals();
2292 return bootret;
2295 /* This ensures that the module with the name given as the first argument
2296 * is loaded.
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
2304 * at all.
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.
2314 /**/
2315 mod_export int
2316 require_module(const char *module, Feature_enables features)
2318 Module m = NULL;
2319 int ret = 0;
2321 /* Resolve aliases and actual loadable module as for load_module */
2322 queue_signals();
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);
2327 else
2328 ret = do_module_features(m, features, 0);
2329 unqueue_signals();
2331 return ret;
2335 * Indicate that the module named "name" depends on the module
2336 * named "from".
2339 /**/
2340 void
2341 add_dep(const char *name, char *from)
2343 LinkNode node;
2344 Module m;
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);
2359 if (!m->deps)
2360 m->deps = znewlinklist();
2361 for (node = firstnode(m->deps);
2362 node && strcmp((char *) getdata(node), from);
2363 incnode(node));
2364 if (!node)
2365 zaddlinknode(m->deps, ztrdup(from));
2369 * Function to be used when scanning the builtins table to
2370 * find and print autoloadable builtins.
2373 /**/
2374 static void
2375 autoloadscan(HashNode hn, int printflags)
2377 Builtin bn = (Builtin) hn;
2379 if(bn->node.flags & BINF_ADDED)
2380 return;
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)) {
2387 putchar(' ');
2388 quotedzputs(bn->node.nam, stdout);
2390 } else {
2391 nicezputs(bn->node.nam, stdout);
2392 if(strcmp(bn->node.nam, bn->optstr)) {
2393 fputs(" (", stdout);
2394 nicezputs(bn->optstr, stdout);
2395 putchar(')');
2398 putchar('\n');
2402 /************************************************************************
2403 * Handling for the zmodload builtin and its various options.
2404 ************************************************************************/
2407 * Main builtin entry point for zmodload.
2410 /**/
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");
2423 return 1;
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");
2427 return 1;
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");
2433 return 1;
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");
2440 return 1;
2442 if (OPT_ISSET(ops,'u') && !*args) {
2443 zwarnnam(nam, "what do you want to unload?");
2444 return 1;
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");
2451 /* except -F ... */
2452 return 1;
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);
2457 return 1;
2460 queue_signals();
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')) {
2471 if (autoopts > 1) {
2472 zwarnnam(nam, "use only one of -b, -c, or -p");
2473 ret = 1;
2474 } else
2475 ret = bin_zmodload_auto(nam, args, ops);
2476 } else
2477 ret = bin_zmodload_load(nam, args, ops);
2478 unqueue_signals();
2480 return ret;
2483 /* zmodload -A */
2485 /**/
2486 static int
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.
2502 Module m;
2504 if (!*args) {
2505 if (OPT_ISSET(ops,'R')) {
2506 zwarnnam(nam, "no module alias to remove");
2507 return 1;
2509 scanhashtable(modulestab, 1, MOD_ALIAS, 0,
2510 modulestab->printnode,
2511 OPT_ISSET(ops,'L') ? PRINTMOD_LIST : 0);
2512 return 0;
2515 for (; *args; args++) {
2516 char *eqpos = strchr(*args, '=');
2517 char *aliasname = eqpos ? eqpos+1 : NULL;
2518 if (eqpos)
2519 *eqpos = '\0';
2520 if (!modname_ok(*args)) {
2521 zwarnnam(nam, "invalid module name `%s'", *args);
2522 return 1;
2524 if (OPT_ISSET(ops,'R')) {
2525 if (aliasname) {
2526 zwarnnam(nam, "bad syntax for removing module alias: %s",
2527 *args);
2528 return 1;
2530 m = find_module(*args, 0, NULL);
2531 if (m) {
2532 if (!(m->node.flags & MOD_ALIAS)) {
2533 zwarnnam(nam, "module is not an alias: %s", *args);
2534 return 1;
2536 delete_module(m);
2537 } else {
2538 zwarnnam(nam, "no such module alias: %s", *args);
2539 return 1;
2541 } else {
2542 if (aliasname) {
2543 const char *mname = aliasname;
2544 if (!modname_ok(aliasname)) {
2545 zwarnnam(nam, "invalid module name `%s'", aliasname);
2546 return 1;
2548 do {
2549 if (!strcmp(mname, *args)) {
2550 zwarnnam(nam, "module alias would refer to itself: %s",
2551 *args);
2552 return 1;
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);
2558 if (m) {
2559 if (!(m->node.flags & MOD_ALIAS)) {
2560 zwarnnam(nam, "module is not an alias: %s", *args);
2561 return 1;
2563 zsfree(m->u.alias);
2564 } else {
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);
2570 } else {
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') ?
2575 PRINTMOD_LIST : 0);
2576 else {
2577 zwarnnam(nam, "module is not an alias: %s", *args);
2578 return 1;
2580 } else {
2581 zwarnnam(nam, "no such module alias: %s", *args);
2582 return 1;
2588 return 0;
2591 /* zmodload -e (without -F) */
2593 /**/
2594 static int
2595 bin_zmodload_exist(UNUSED(char *nam), char **args, Options ops)
2597 Module m;
2599 if (!*args) {
2600 scanhashtable(modulestab, 1, 0, 0, modulestab->printnode,
2601 OPT_ISSET(ops,'A') ? PRINTMOD_EXIST|PRINTMOD_ALIAS :
2602 PRINTMOD_EXIST);
2603 return 0;
2604 } else {
2605 int ret = 0;
2607 for (; !ret && *args; args++) {
2608 if (!(m = find_module(*args, FINDMOD_ALIASP, NULL))
2609 || !m->u.handle
2610 || (m->node.flags & MOD_UNLOAD))
2611 ret = 1;
2613 return ret;
2617 /* zmodload -d */
2619 /**/
2620 static int
2621 bin_zmodload_dep(UNUSED(char *nam), char **args, Options ops)
2623 Module m;
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);
2628 if (!m)
2629 return 0;
2630 if (*args && m->deps) {
2631 do {
2632 LinkNode dnode;
2633 for (dnode = firstnode(m->deps); dnode; incnode(dnode))
2634 if (!strcmp(*args, getdata(dnode))) {
2635 zsfree(getdata(dnode));
2636 remnode(m->deps, dnode);
2637 break;
2639 } while(*++args);
2640 if (empty(m->deps)) {
2641 freelinklist(m->deps, freestr);
2642 m->deps = NULL;
2644 } else {
2645 if (m->deps) {
2646 freelinklist(m->deps, freestr);
2647 m->deps = NULL;
2650 if (!m->deps && !m->u.handle)
2651 delete_module(m);
2652 return 0;
2653 } else if (!args[0] || !args[1]) {
2654 /* list dependencies */
2655 int depflags = OPT_ISSET(ops,'L') ?
2656 PRINTMOD_DEPS|PRINTMOD_LIST : PRINTMOD_DEPS;
2657 if (args[0]) {
2658 if ((m = (Module)modulestab->getnode2(modulestab, args[0])))
2659 modulestab->printnode(&m->node, depflags);
2660 } else {
2661 scanhashtable(modulestab, 1, 0, 0, modulestab->printnode,
2662 depflags);
2664 return 0;
2665 } else {
2666 /* add dependencies */
2667 int ret = 0;
2668 char *tnam = *args++;
2670 for (; *args; args++)
2671 add_dep(tnam, *args);
2672 return ret;
2677 * Function for scanning the parameter table to find and print
2678 * out autoloadable parameters.
2681 static void
2682 printautoparams(HashNode hn, int lon)
2684 Param pm = (Param) hn;
2686 if (pm->node.flags & PM_AUTOLOAD) {
2687 if (lon)
2688 printf("zmodload -ap %s %s\n", pm->u.str, pm->node.nam);
2689 else
2690 printf("%s (%s)\n", pm->node.nam, pm->u.str);
2694 /* zmodload -a/u [bcpf] */
2696 /**/
2697 static int
2698 bin_zmodload_auto(char *nam, char **args, Options ops)
2700 int fchar, flags;
2701 char *modnam;
2703 if (OPT_ISSET(ops,'c')) {
2704 if (!*args) {
2705 /* list autoloaded conditions */
2706 Conddef p;
2708 for (p = condtab; p; p = p->next) {
2709 if (p->module) {
2710 if (OPT_ISSET(ops,'L')) {
2711 fputs("zmodload -ac", stdout);
2712 if (p->flags & CONDF_INFIX)
2713 putchar('I');
2714 printf(" %s %s\n", p->module, p->name);
2715 } else {
2716 if (p->flags & CONDF_INFIX)
2717 fputs("infix ", stdout);
2718 else
2719 fputs("post ", stdout);
2720 printf("%s (%s)\n",p->name, p->module);
2724 return 0;
2726 fchar = OPT_ISSET(ops,'I') ? 'C' : 'c';
2727 } else if (OPT_ISSET(ops,'p')) {
2728 if (!*args) {
2729 /* list autoloaded parameters */
2730 scanhashtable(paramtab, 1, 0, 0, printautoparams,
2731 OPT_ISSET(ops,'L'));
2732 return 0;
2734 fchar = 'p';
2735 } else if (OPT_ISSET(ops,'f')) {
2736 if (!*args) {
2737 /* list autoloaded math functions */
2738 MathFunc p;
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);
2745 } else
2746 printf("%s (%s)\n",p->name, p->module);
2749 return 0;
2751 fchar = 'f';
2752 } else {
2753 /* builtins are the default; zmodload -ab or just zmodload -a */
2754 if (!*args) {
2755 /* list autoloaded builtins */
2756 scanhashtable(builtintab, 1, 0, 0,
2757 autoloadscan, OPT_ISSET(ops,'L') ? PRINT_LIST : 0);
2758 return 0;
2760 fchar = 'b';
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;
2769 modnam = NULL;
2770 } else {
2771 /* add autoload */
2772 modnam = *args;
2774 if (args[1])
2775 args++;
2777 return autofeatures(nam, modnam, args, fchar, flags);
2780 /* Backend handler for zmodload -u */
2782 /**/
2784 unload_module(Module m)
2786 int del;
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);
2793 if (!m)
2794 return 1;
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))
2806 return 1;
2807 m->node.flags &= ~(MOD_INIT_B|MOD_INIT_S);
2809 del = (m->node.flags & MOD_UNLOAD);
2811 if (m->wrapper) {
2812 m->node.flags |= MOD_UNLOAD;
2813 return 0;
2815 m->node.flags &= ~MOD_UNLOAD;
2818 * We always need to finish the module (and unload it)
2819 * if it is present.
2821 if (m->node.flags & MOD_LINKED) {
2822 if (m->u.linked) {
2823 m->u.linked->finish(m);
2824 m->u.linked = NULL;
2826 } else {
2827 if (m->u.handle) {
2828 finish_module(m);
2829 m->u.handle = NULL;
2833 if (del && m->deps) {
2834 /* The module was unloaded delayed, unload all modules *
2835 * on which it depended. */
2836 LinkNode n;
2838 for (n = firstnode(m->deps); n; incnode(n)) {
2839 Module dm = find_module((char *) getdata(n),
2840 FINDMOD_ALIASP, NULL);
2842 if (dm &&
2843 (dm->node.flags & MOD_UNLOAD)) {
2844 /* See if this is the only module depending on it. */
2845 Module am;
2846 int du = 1, i;
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) {
2851 LinkNode sn;
2853 * Don't scan the module we're unloading;
2854 * ignore if no dependencies.
2856 if (am == m || !am->deps)
2857 continue;
2858 /* Don't scan if not loaded nor linked */
2859 if ((am->node.flags & MOD_LINKED) ?
2860 !am->u.linked : !am->u.handle)
2861 continue;
2862 for (sn = firstnode(am->deps); du && sn;
2863 incnode(sn)) {
2864 if (!strcmp((char *) getdata(sn),
2865 dm->node.nam))
2866 du = 0;
2870 if (du)
2871 unload_module(dm);
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) {
2883 delete_module(m);
2885 return 0;
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).
2894 /**/
2896 unload_named_module(char *modname, char *nam, int silent)
2898 const char *mname;
2899 Module m;
2900 int ret = 0;
2902 m = find_module(modname, FINDMOD_ALIASP, &mname);
2903 if (m) {
2904 int i, del = 0;
2905 Module dm;
2907 for (i = 0; i < modulestab->hsize; i++) {
2908 for (dm = (Module)modulestab->nodes[i]; dm;
2909 dm = (Module)dm->node.next) {
2910 LinkNode dn;
2911 if (!dm->deps || !dm->u.handle)
2912 continue;
2913 for (dn = firstnode(dm->deps); dn; incnode(dn)) {
2914 if (!strcmp((char *) getdata(dn), mname)) {
2915 if (dm->node.flags & MOD_UNLOAD)
2916 del = 1;
2917 else {
2918 zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", mname);
2919 return 1;
2925 if (del)
2926 m->wrapper++;
2927 if (unload_module(m))
2928 ret = 1;
2929 if (del)
2930 m->wrapper--;
2931 } else if (!silent) {
2932 zwarnnam(nam, "no such module %s", modname);
2933 ret = 1;
2936 return ret;
2939 /* zmodload -u without -d */
2941 /**/
2942 static int
2943 bin_zmodload_load(char *nam, char **args, Options ops)
2945 int ret = 0;
2946 if(OPT_ISSET(ops,'u')) {
2947 /* unload modules */
2948 for(; *args; args++) {
2949 if (unload_named_module(*args, nam, OPT_ISSET(ops,'i')))
2950 ret = 1;
2952 return ret;
2953 } else if(!*args) {
2954 /* list modules */
2955 scanhashtable(modulestab, 1, 0, MOD_UNLOAD|MOD_ALIAS,
2956 modulestab->printnode,
2957 OPT_ISSET(ops,'L') ? PRINTMOD_LIST : 0);
2958 return 0;
2959 } else {
2960 /* load modules */
2961 for (; *args; args++) {
2962 int tmpret = require_module(*args, NULL);
2963 if (tmpret && ret != 1)
2964 ret = tmpret;
2967 return ret;
2971 /* zmodload -F */
2973 /**/
2974 static int
2975 bin_zmodload_features(const char *nam, char **args, Options ops)
2977 int iarg;
2978 char *modname = *args;
2979 Patprog *patprogs;
2980 Feature_enables features, fep;
2982 if (modname)
2983 args++;
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");
2988 return 1;
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);
2996 return 0;
2999 if (!modname) {
3000 zwarnnam(nam, "-F requires a module name");
3001 return 1;
3004 if (OPT_ISSET(ops,'m')) {
3005 char **argp;
3006 Patprog *patprogp;
3008 /* not NULL terminated */
3009 patprogp = patprogs =
3010 (Patprog *)zhalloc(arrlen(args)*sizeof(Patprog));
3011 for (argp = args; *argp; argp++, patprogp++) {
3012 char *arg = *argp;
3013 if (*arg == '+' || *arg == '-')
3014 arg++;
3015 tokenize(arg);
3016 *patprogp = patcompile(arg, 0, 0);
3018 } else
3019 patprogs = NULL;
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.
3029 Module m;
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')) {
3036 LinkNode ln;
3038 * If there are no autoloads defined, return status 1.
3040 if (!m || !m->autoloads)
3041 return 1;
3042 if (OPT_ISSET(ops,'e')) {
3043 for (fp = args; *fp; fp++) {
3044 char *fstr = *fp;
3045 int sense = 1;
3046 if (*fstr == '+')
3047 fstr++;
3048 else if (*fstr == '-') {
3049 fstr++;
3050 sense = 0;
3052 if ((linknodebystring(m->autoloads, fstr) != NULL) !=
3053 sense)
3054 return 1;
3056 return 0;
3058 if (param) {
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');
3064 arrp = NULL;
3066 for (ln = firstnode(m->autoloads); ln; incnode(ln)) {
3067 char *al = (char *)getdata(ln);
3068 if (param)
3069 *arrp++ = ztrdup(al);
3070 else
3071 printf("%s%c", al,
3072 OPT_ISSET(ops,'L') && nextnode(ln) ? ' ' : '\n');
3074 if (param) {
3075 *arrp = NULL;
3076 if (!setaparam(param, arrset))
3077 return 1;
3079 return 0;
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);
3084 return 1;
3086 if (features_module(m, &features)) {
3087 if (!OPT_ISSET(ops,'e'))
3088 zwarnnam(nam, "module `%s' does not support features",
3089 m->node.nam);
3090 return 1;
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'",
3095 m->node.nam);
3096 return 1;
3098 for (arrp = args, iarg = 0; *arrp; arrp++, iarg++) {
3099 char *arg = *arrp;
3100 int on, found = 0;
3101 if (*arg == '-') {
3102 on = 0;
3103 arg++;
3104 } else if (*arg == '+') {
3105 on = 1;
3106 arg++;
3107 } else
3108 on = -1;
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 &&
3114 on != (*ep & 1))
3115 return 1;
3116 found++;
3117 if (!patprogs)
3118 break;
3121 if (!found) {
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'",
3126 modname, *arrp);
3127 return 1;
3130 if (OPT_ISSET(ops,'e')) /* yep, everything we want exists */
3131 return 0;
3132 if (param) {
3133 int arrlen = 0;
3134 for (fp = features, ep = enables; *fp; fp++, ep++) {
3135 if (OPT_ISSET(ops, 'L') && !OPT_ISSET(ops, 'l') &&
3136 !*ep)
3137 continue;
3138 if (*args) {
3139 char **argp;
3140 for (argp = args, iarg = 0; *argp; argp++, iarg++) {
3141 char *arg = *argp;
3142 /* ignore +/- for consistency */
3143 if (*arg == '+' || *arg == '-')
3144 arg++;
3145 if (patprogs ? pattry(patprogs[iarg], *fp) :
3146 !strcmp(*fp, arg))
3147 break;
3149 if (!*argp)
3150 continue;
3152 arrlen++;
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++) {
3158 char *onoff;
3159 int term;
3160 if (*args) {
3161 char **argp;
3162 for (argp = args, iarg = 0; *argp; argp++, iarg++) {
3163 char *arg = *argp;
3164 if (*arg == '+' || *arg == '-')
3165 arg++;
3166 if (patprogs ? pattry(patprogs[iarg], *fp) :
3167 !strcmp(*fp, *argp))
3168 break;
3170 if (!*argp)
3171 continue;
3173 if (OPT_ISSET(ops, 'L') && !OPT_ISSET(ops, 'l')) {
3174 if (!*ep)
3175 continue;
3176 onoff = "";
3177 } else if (*ep) {
3178 onoff = "+";
3179 } else {
3180 onoff = "-";
3182 if (param) {
3183 *arrp++ = bicat(onoff, *fp);
3184 } else {
3185 if (OPT_ISSET(ops, 'L') && fp[1]) {
3186 term = ' ';
3187 } else {
3188 term = '\n';
3190 printf("%s%s%c", onoff, *fp, term);
3193 if (param) {
3194 *arrp = NULL;
3195 if (!setaparam(param, arrset))
3196 return 1;
3198 return 0;
3199 } else if (OPT_ISSET(ops,'P')) {
3200 zwarnnam(nam, "-P can only be used with -l or -L");
3201 return 1;
3202 } else if (OPT_ISSET(ops,'a')) {
3203 if (OPT_ISSET(ops,'m')) {
3204 zwarnnam(nam, "-m cannot be used with -a");
3205 return 1;
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);
3221 fep = features =
3222 (Feature_enables)zhalloc((arrlen(args)+1)*sizeof(*fep));
3224 while (*args) {
3225 fep->str = *args++;
3226 fep->pat = patprogs ? *patprogs++ : NULL;
3227 fep++;
3229 fep->str = NULL;
3230 fep->pat = 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.
3249 /**/
3250 mod_export char **
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;
3263 while (bn_size--)
3264 *featurep++ = dyncat("b:", (bnp++)->node.nam);
3265 while (cd_size--) {
3266 *featurep++ = dyncat((cdp->flags & CONDF_INFIX) ? "C:" : "c:",
3267 cdp->name);
3268 cdp++;
3270 while (mf_size--)
3271 *featurep++ = dyncat("f:", (mfp++)->name);
3272 while (pd_size--)
3273 *featurep++ = dyncat("p:", (pdp++)->name);
3275 features[features_size] = NULL;
3276 return features;
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.
3284 /**/
3285 mod_export int *
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;
3298 while (bn_size--)
3299 *enablep++ = ((bnp++)->node.flags & BINF_ADDED) ? 1 : 0;
3300 while (cd_size--)
3301 *enablep++ = ((cdp++)->flags & CONDF_ADDED) ? 1 : 0;
3302 while (mf_size--)
3303 *enablep++ = ((mfp++)->flags & MFF_ADDED) ? 1 : 0;
3304 while (pd_size--)
3305 *enablep++ = (pdp++)->pm ? 1 : 0;
3307 return enables;
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
3317 * error.
3320 /**/
3321 mod_export int
3322 setfeatureenables(Module m, Features f, int *e)
3324 int ret = 0;
3326 if (f->bn_size) {
3327 if (setbuiltins(m->node.nam, f->bn_list, f->bn_size, e))
3328 ret = 1;
3329 if (e)
3330 e += f->bn_size;
3332 if (f->cd_size) {
3333 if (setconddefs(m->node.nam, f->cd_list, f->cd_size, e))
3334 ret = 1;
3335 if (e)
3336 e += f->cd_size;
3338 if (f->mf_size) {
3339 if (setmathfuncs(m->node.nam, f->mf_list, f->mf_size, e))
3340 ret = 1;
3342 if (f->pd_size) {
3343 if (setparamdefs(m->node.nam, f->pd_list, f->pd_size, e))
3344 ret = 1;
3345 if (e)
3346 e += f->pd_size;
3348 return ret;
3352 * Convenient front-end to get or set features which
3353 * can be used in a module enables_() function.
3356 /**/
3357 mod_export int
3358 handlefeatures(Module m, Features f, int **enables)
3360 if (!enables || *enables)
3361 return setfeatureenables(m, f, *enables);
3362 *enables = getfeatureenables(m, f);
3363 return 0;
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.
3383 /**/
3384 mod_export int
3385 ensurefeature(const char *modname, const char *prefix, const char *feature)
3387 char *f;
3388 struct feature_enables features[2];
3390 if (!feature)
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.
3405 /**/
3407 autofeatures(const char *cmdnam, const char *module, char **features,
3408 int prefchar, int defflags)
3410 int ret = 0, subret;
3411 Module defm, m;
3412 char **modfeatures = NULL;
3413 if (module) {
3414 defm = (Module)find_module(module,
3415 FINDMOD_ALIASP|FINDMOD_CREATE, NULL);
3416 if ((defm->node.flags & MOD_LINKED) ? defm->u.linked :
3417 defm->u.handle)
3418 (void)features_module(defm, &modfeatures);
3419 } else
3420 defm = NULL;
3422 for (; *features; features++) {
3423 char *fnam, *typnam, *feature;
3424 int add, fchar, flags = defflags;
3425 autofeaturefn_t fn;
3427 if (prefchar) {
3429 * "features" is list of bare features with no
3430 * type prefix; prefchar gives type character.
3432 add = 1; /* unless overridden by flag */
3433 fchar = prefchar;
3434 fnam = *features;
3435 feature = zhalloc(strlen(fnam) + 3);
3436 sprintf(feature, "%c:%s", fchar, fnam);
3437 } else {
3438 feature = *features;
3439 if (*feature == '-') {
3440 add = 0;
3441 feature++;
3442 } else {
3443 add = 1;
3444 if (*feature == '+')
3445 feature++;
3448 if (!*feature || feature[1] != ':') {
3449 zwarnnam(cmdnam, "bad format for autoloadable feature: `%s'",
3450 feature);
3451 ret = 1;
3452 continue;
3454 fnam = feature + 2;
3455 fchar = feature[0];
3457 if (flags & FEAT_REMOVE)
3458 add = 0;
3460 switch (fchar) {
3461 case 'b':
3462 fn = add ? add_autobin : del_autobin;
3463 typnam = "builtin";
3464 break;
3466 case 'C':
3467 flags |= FEAT_INFIX;
3468 /* FALLTHROUGH */
3469 case 'c':
3470 fn = add ? add_autocond : del_autocond;
3471 typnam = "condition";
3472 break;
3474 case 'f':
3475 fn = add ? add_automathfunc : del_automathfunc;
3476 typnam = "math function";
3477 break;
3479 case 'p':
3480 fn = add ? add_autoparam : del_autoparam;
3481 typnam = "parameter";
3482 break;
3484 default:
3485 zwarnnam(cmdnam, "bad autoloadable feature type: `%c'",
3486 fchar);
3487 ret = 1;
3488 continue;
3491 if (strchr(fnam, '/')) {
3492 zwarnnam(cmdnam, "%s: `/' is illegal in a %s", fnam, typnam);
3493 ret = 1;
3494 continue;
3497 if (!module) {
3499 * Traditional un-autoload syntax doesn't tell us
3500 * which module this came from.
3502 int i;
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) {
3506 if (m->autoloads &&
3507 linknodebystring(m->autoloads, feature))
3508 break;
3511 if (!m) {
3512 if (!(flags & FEAT_IGNORE)) {
3513 ret = 1;
3514 zwarnnam(cmdnam, "%s: no such %s", fnam, typnam);
3516 continue;
3518 } else
3519 m = defm;
3521 subret = 0;
3522 if (add) {
3523 char **ptr;
3524 if (modfeatures) {
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))
3531 break;
3532 if (!*ptr) {
3533 zwarnnam(cmdnam, "module `%s' has no such feature: `%s'",
3534 m->node.nam, feature);
3535 ret = 1;
3536 continue;
3539 if (!m->autoloads) {
3540 m->autoloads = znewlinklist();
3541 zaddlinknode(m->autoloads, ztrdup(feature));
3542 } else {
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));
3547 if (cmp == 0) {
3548 /* Already there. Never an error. */
3549 break;
3551 if (cmp < 0) {
3552 zinsertlinknode(m->autoloads, prev,
3553 ztrdup(feature));
3554 break;
3556 prev = ln;
3558 if (!ln)
3559 zaddlinknode(m->autoloads, ztrdup(feature));
3561 } else if (m->autoloads) {
3562 LinkNode ln;
3563 if ((ln = linknodebystring(m->autoloads, feature)))
3564 zsfree((char *)remnode(m->autoloads, ln));
3565 else {
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;
3574 if (subret == 0)
3575 subret = fn(module, fnam, flags);
3577 if (subret != 0) {
3578 /* -2 indicates not an error, just skip running fn() */
3579 if (subret != -2)
3580 ret = 1;
3581 switch (subret) {
3582 case 1:
3583 zwarnnam(cmdnam, "failed to add %s `%s'", typnam, fnam);
3584 break;
3586 case 2:
3587 zwarnnam(cmdnam, "%s: no such %s", fnam, typnam);
3588 break;
3590 case 3:
3591 zwarnnam(cmdnam, "%s: %s is already defined", fnam, typnam);
3592 break;
3594 default:
3595 /* no (further) message needed */
3596 break;
3601 return ret;