From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17792 invoked from network); 27 Dec 1996 11:26:04 -0000 Received: from euclid.skiles.gatech.edu (list@130.207.146.50) by coral.primenet.com.au with SMTP; 27 Dec 1996 11:26:04 -0000 Received: (from list@localhost) by euclid.skiles.gatech.edu (8.7.3/8.7.3) id GAA24712; Fri, 27 Dec 1996 06:18:54 -0500 (EST) Resent-Date: Fri, 27 Dec 1996 06:18:54 -0500 (EST) From: Zefram Message-Id: <6676.199612271120@stone.dcs.warwick.ac.uk> Subject: improvement in builtin addition/deletion To: zsh-workers@math.gatech.edu (Z Shell workers mailing list) Date: Fri, 27 Dec 1996 11:19:59 +0000 (GMT) X-Patch: 164 X-Loop: zefram@dcs.warwick.ac.uk X-Stardate: [-31]8637.36 X-US-Congress: Moronic fuckers Content-Type: text Resent-Message-ID: <"bNuyI.0.326.T2xmo"@euclid> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/2646 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu -----BEGIN PGP SIGNED MESSAGE----- This patch adds two new functions, addbuiltins() and deletebuiltins(). They add and delete several builtins at once, in the manner of the code I produced for the files module. They are actually helpful even when adding only one builtin: they ensure that error messages are correctly generated in all cases. It also makes adding a second builtin to the module as easy as possible. When used by linked-in modules, this necessitates a change to init_bltinmods(), so that the modules have a name. This requires that the form of bltinmods.list change; you should delete that file when applying this patch. This patch depends on my recent patch to make addbuiltin() more comprehensive. -zefram *** Src/Makefile.in 1996/12/24 05:31:03 1.23 --- Src/Makefile.in 1996/12/24 16:51:25 *************** *** 212,218 **** bltinmods.list: $(MODBINS) ( for mod in `cat $(MODBINS)`; do \ ! echo "DOMOD(boot_$$mod)"; \ done ) > $@ zshxmods.h: $(MODBINS) --- 212,218 ---- bltinmods.list: $(MODBINS) ( for mod in `cat $(MODBINS)`; do \ ! echo "DOMOD(\"$$mod\", boot_$$mod)"; \ done ) > $@ zshxmods.h: $(MODBINS) *** Src/init.c 1996/12/24 15:48:32 1.32 --- Src/init.c 1996/12/24 16:50:53 *************** *** 768,774 **** source(buf); } ! #define DOMOD(boot) int boot(Module); #include "bltinmods.list" #undef DOMOD --- 768,774 ---- source(buf); } ! #define DOMOD(name, boot) int boot(Module); #include "bltinmods.list" #undef DOMOD *************** *** 776,782 **** void init_bltinmods(void) { ! #define DOMOD(boot) boot(NULL); #include "bltinmods.list" #undef DOMOD } --- 776,783 ---- void init_bltinmods(void) { ! static struct module mod = { NULL, 0, NULL, NULL }; ! #define DOMOD(name, boot) mod.nam = name; boot(&mod); #include "bltinmods.list" #undef DOMOD } *** Src/module.c 1996/12/24 15:48:33 1.19 --- Src/module.c 1996/12/24 16:37:47 *************** *** 71,76 **** --- 71,105 ---- return 0; } + /* Add multiple builtins. binl points to a table of `size' binlist * + * structures. Those for which (.flags & BINL_ADDED) is false are to be * + * added; that flag is set if they succeed. If any fail, an error * + * message is printed, using nam as the leading name. Returns 1 if all * + * additions succeed, 2 if some succeed and some fail, and 0 if all (and * + * at least 1) fail. The usual usage in a boot_*() function would be * + * return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); */ + + /**/ + int + addbuiltins(char const *nam, BinList binl, int size) + { + int hads = 0, hadf = 0, n; + + for(n = 0; n < size; n++) { + BinList b = &binl[n]; + if(b->flags & BINL_ADDED) + continue; + if(addbuiltin(b->nam, b->binf, b->func, + b->minargs, b->maxargs, b->funcid, b->optstr, b->defopts)) { + zwarnnam(nam, "name clash when adding builtin `%s'", b->nam, 0); + b->flags |= BINL_ADDED; + hadf = 1; + } else + hads = 2; + } + return hadf ? hads : 1; + } + #ifdef DYNAMIC /* Define an autoloadable builtin. It returns 0 on success, or 1 on * *************** *** 102,107 **** --- 131,165 ---- zsfree(bn->optstr); zfree(bn, sizeof(struct builtin)); return 0; + } + + /* Delete multiple builtins. binl points to a table of `size' binlist * + * structures. Those for which (.flags & BINL_ADDED) is true are to be * + * deleted; that flag is cleared. If any fail, an error message is * + * printed, using nam as the leading name. Returns 1 if all deletions * + * succeed, 2 if some succeed and some fail, and 0 if all (and at least * + * 1) fail. In normal use, from a cleanup_*() function, this return * + * value would be ignored -- the only cause of failure would be that a * + * wayward module had deleted our builtin without telling us. */ + + /**/ + int + deletebuiltins(char const *nam, BinList binl, int size) + { + int hads = 0, hadf = 0, n; + + for(n = 0; n < size; n++) { + BinList b = &binl[n]; + if(!(b->flags & BINL_ADDED)) + continue; + if(deletebuiltin(b->nam)) { + zwarnnam(nam, "builtin `%s' already deleted", b->nam, 0); + hadf = 1; + } else + hads = 2; + b->flags &= ~BINL_ADDED; + } + return hadf ? hads : 1; } #ifdef HAVE_DLFCN_H *** Src/zsh.h 1996/12/24 03:45:31 1.37 --- Src/zsh.h 1996/12/24 16:05:55 *************** *** 1255,1260 **** --- 1255,1277 ---- #define ZSIG_IGNORED (1<<1) #define ZSIG_FUNC (1<<2) + /*********************************/ + /* Dynamic builtin table munging */ + /*********************************/ + + typedef struct binlist *BinList; + + #define BINL_ADDED (1<<0) + + struct binlist { + char *nam; + int binf; + HandlerFunc func; + int minargs, maxargs, funcid; + char *optstr, *defopts; + int flags; + }; + /***********************/ /* Shared header files */ /***********************/ *** Src/Modules/example.c 1996/12/24 15:48:37 1.4 --- Src/Modules/example.c 1996/12/24 16:39:13 *************** *** 59,73 **** * boot_example is executed when the module is loaded. */ /**/ int boot_example(Module m) { ! if (addbuiltin("example", 0, bin_example, 0, -1, 0, "flags", NULL)) { ! zwarnnam(m->nam, "name clash when adding builtin `example'", NULL, 0); ! return -1; ! } ! return 0; } #ifdef MODULE --- 59,73 ---- * boot_example is executed when the module is loaded. */ + static struct binlist bintab[] = { + { "example", 0, bin_example, 0, -1, 0, "flags", NULL, 0 }, + }; + /**/ int boot_example(Module m) { ! return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); } #ifdef MODULE *************** *** 76,81 **** int cleanup_example(Module m) { ! return deletebuiltin("example"); } #endif --- 76,82 ---- int cleanup_example(Module m) { ! deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); ! return 0; } #endif *** Src/Modules/files.c 1996/12/24 15:53:45 1.5 --- Src/Modules/files.c 1996/12/24 16:39:27 *************** *** 400,413 **** /* module paraphernalia */ ! static struct bin { ! char *name; ! int binf; ! HandlerFunc func; ! int min, max, funcid; ! char *optstr, *defopts; ! int added; ! } bins[] = { #ifdef HAVE_LSTAT { "ln", 0, bin_ln, 1, -1, BIN_LN, "dfis", NULL, 0 }, #else --- 400,406 ---- /* module paraphernalia */ ! static struct binlist bintab[] = { #ifdef HAVE_LSTAT { "ln", 0, bin_ln, 1, -1, BIN_LN, "dfis", NULL, 0 }, #else *************** *** 418,442 **** { "rm", 0, bin_rm, 1, -1, 0, "dfir", NULL, 0 }, { "rmdir", 0, bin_rmdir, 1, -1, 0, NULL, NULL, 0 }, { "sync", 0, bin_sync, 0, 0, 0, NULL, NULL, 0 }, - { NULL, 0, NULL, 0, 0, 0, NULL, NULL, 0 } }; /**/ int boot_files(Module m) { ! int added = 0; ! struct bin *bin; ! ! for(bin = bins; bin->name; bin++) { ! if (!bin->added && addbuiltin(bin->name, bin->binf, bin->func, ! bin->min, bin->max, bin->funcid, bin->optstr, bin->defopts)) ! zwarnnam(m->nam, "name clash when adding builtin `%s'", ! bin->name, 0); ! else ! added = bin->added = 1; ! } ! return !added; } #ifdef MODULE --- 411,423 ---- { "rm", 0, bin_rm, 1, -1, 0, "dfir", NULL, 0 }, { "rmdir", 0, bin_rmdir, 1, -1, 0, NULL, NULL, 0 }, { "sync", 0, bin_sync, 0, 0, 0, NULL, NULL, 0 }, }; /**/ int boot_files(Module m) { ! return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); } #ifdef MODULE *************** *** 445,458 **** int cleanup_files(Module m) { ! int fail = 0; ! struct bin *bin; ! ! for(bin = bins; bin->name; bin++) ! if (bin->added && deletebuiltin(bin->name)) ! fail = 1; ! else ! bin->added = 0; ! return fail; } #endif --- 426,432 ---- int cleanup_files(Module m) { ! deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); ! return 0; } #endif *** Src/Zle/compctl.c 1996/12/24 15:48:38 1.3 --- Src/Zle/compctl.c 1996/12/24 16:41:16 *************** *** 1020,1033 **** return ret; } /**/ int boot_compctl(Module m) { ! if (addbuiltin("compctl", 0, bin_compctl, 0, -1, 0, NULL, NULL)) { ! zwarnnam(m->nam, "name clash when adding builtin `compctl'", NULL, 0); ! return -1; ! } compctltab->printnode = printcompctlp; return 0; } --- 1020,1035 ---- return ret; } + static struct binlist bintab[] = { + { "compctl", 0, bin_compctl, 0, -1, 0, NULL, NULL, 0 }, + }; + /**/ int boot_compctl(Module m) { ! if(!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab))) ! return 1; compctltab->printnode = printcompctlp; return 0; } *************** *** 1039,1044 **** cleanup_compctl(Module m) { compctltab->printnode = NULL; ! return deletebuiltin("compctl"); } #endif --- 1041,1047 ---- cleanup_compctl(Module m) { compctltab->printnode = NULL; ! deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); ! return 0; } #endif *** Src/Zle/zle_main.c 1996/12/24 15:48:39 1.7 --- Src/Zle/zle_main.c 1996/12/24 16:42:43 *************** *** 1546,1551 **** --- 1546,1556 ---- cc_first.mask = 0; } + static struct binlist bintab[] = { + { "bindkey", 0, bin_bindkey, 0, -1, 0, "asvemdruU", NULL, 0 }, + { "vared", 0, bin_vared, 1, 7, 0, NULL, NULL, 0 }, + }; + /**/ int boot_zle(Module m) *************** *** 1566,1572 **** initkeybindings(); /* initialize key bindings */ compctlsetup(); ! addbuiltin("bindkey", 0, bin_bindkey, 0, -1, 0, "asvemdruU", NULL); ! addbuiltin("vared", 0, bin_vared, 1, 7, 0, NULL, NULL); return 0; } --- 1571,1576 ---- initkeybindings(); /* initialize key bindings */ compctlsetup(); ! addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); return 0; } -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQCVAwUBMsANp3D/+HJTpU/hAQH1RwQAvVZEwqnJswiqL3lboqbW7s8Ii7GHLm5C 7l/dA75yp1avKMlNKR1sSD+IYy+XhVgJByIwLU13A5V+gizU9h2UxuUjkEM/jq5W DkkiLoF3aLGDvKbf1H6kN619ewhx8kERxNhePfckV34oHSaikRzCx8sAHXrZBnT4 n/lujwBGEeU= =/c2v -----END PGP SIGNATURE-----