From f330bdf21e67f45ada205022c66fe0a84eefdcbe Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Wed, 28 Apr 1999 22:08:46 +0000 Subject: zsh-workers:6133 --- Doc/Zsh/builtins.yo | 10 ++- Src/Modules/example.c | 39 +++++++++++- Src/Modules/example.mdd | 1 + Src/builtin.c | 10 +-- Src/mkbltnmlst.sh | 5 +- Src/mkmakemod.sh | 3 +- Src/module.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++- Src/params.c | 25 ++++++-- Src/zsh.h | 24 ++++++++ 9 files changed, 260 insertions(+), 17 deletions(-) diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index ffc9f3cfe..e9bc2ab16 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1175,9 +1175,12 @@ xitem(tt(zmodload) tt(-d) [ tt(-L) ] [ var(name) [ var(dep) ... ] ]) xitem(tt(zmodload) tt(-du) var(name) [ var(dep) ... ]) xitem(tt(zmodload) tt(-a) [ tt(-iL) ] [ var(name) [ var(builtin) ... ] ]) xitem(tt(zmodload) tt(-au) [ tt(-i) ] var(builtin) ...) -xitem(tt(zmodload) tt(-c) [ tt(-iI) ] [ var(name) [ var(cond) ... ] ]) +xitem(tt(zmodload) tt(-c) [ tt(-iI) ] var(name) [ var(cond) ... ]) xitem(tt(zmodload) tt(-cu) [ tt(-iI) ] var(cond) ...) -item(tt(zmodload) tt(-c) [ tt(-IL) ])( +xitem(tt(zmodload) tt(-c) [ tt(-IL) ]) +xitem(tt(zmodload) tt(-p) [ tt(-i) ] var(name) [ var(parameter) ... ]) +xitem(tt(zmodload) tt(-pu) [ tt(-i) ] var(parameter) ... ]) +item(tt(zmodload) tt(-p) [ tt(-L) ])( tt(zmodload) performs operations relating to zsh's loadable modules. This feature is not available on all operating systems, or on all installations on a particular operating system. @@ -1253,5 +1256,8 @@ names. Without this option prefix condition names are defined. Together with the tt(-u) option definitions for autoloaded conditions are removed. If given no condition names all defined names are listed (as a series of tt(zmodload) commands if the tt(-L) option is given). + +The tt(-p) option is like the tt(-c) option, but makes tt(zmodload) +work on autoloaded parameters instead of condition codes. ) enditem() diff --git a/Src/Modules/example.c b/Src/Modules/example.c index 95545172f..50b8c1626 100644 --- a/Src/Modules/example.c +++ b/Src/Modules/example.c @@ -30,22 +30,45 @@ #include "example.mdh" #include "example.pro" +/* parameters */ + +static long intparam; +static char *strparam; +static char **arrparam; + + /**/ static int bin_example(char *nam, char **args, char *ops, int func) { unsigned char c; + char **oargs = args, **p = arrparam; + long i = 0; printf("Options: "); for (c = 32; ++c < 128;) if (ops[c]) putchar(c); printf("\nArguments:"); - for (; *args; args++) { + for (; *args; i++, args++) { putchar(' '); fputs(*args, stdout); } printf("\nName: %s\n", nam); + printf("\nInteger Parameter: %ld\n", intparam); + printf("String Parameter: %s\n", strparam ? strparam : ""); + printf("Array Parameter:"); + if (p) + while (*p) printf(" %s", *p++); + printf("\n"); + + intparam = i; + zsfree(strparam); + strparam = ztrdup(*oargs ? *oargs : ""); + freearray(arrparam); + PERMALLOC { + arrparam = arrdup(oargs); + } LASTALLOC; return 0; } @@ -103,6 +126,12 @@ static struct conddef cotab[] = { CONDDEF("ex", CONDF_INFIX, cond_i_ex, 0, 0, 0), }; +static struct paramdef patab[] = { + INTPARAMDEF("exint", &intparam), + STRPARAMDEF("exstr", &strparam), + ARRPARAMDEF("exarr", &arrparam), +}; + static struct funcwrap wrapper[] = { WRAPDEF(ex_wrapper), }; @@ -120,8 +149,15 @@ setup_example(Module m) int boot_example(Module m) { + intparam = 42; + strparam = ztrdup("example"); + arrparam = (char **) zalloc(3 * sizeof(char *)); + arrparam[0] = ztrdup("example"); + arrparam[1] = ztrdup("array"); + arrparam[2] = NULL; return !(addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) | addconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab)) | + addparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab)) | !addwrapper(m, wrapper)); } @@ -133,6 +169,7 @@ cleanup_example(Module m) { deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); deleteconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab)); + deleteparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab)); deletewrapper(m, wrapper); return 0; } diff --git a/Src/Modules/example.mdd b/Src/Modules/example.mdd index f2cd50693..5ed55e6f1 100644 --- a/Src/Modules/example.mdd +++ b/Src/Modules/example.mdd @@ -2,5 +2,6 @@ autobins="example" autoinfixconds="ex" autoprefixconds="len" +autoparams="exint exstr exarr" objects="example.o" diff --git a/Src/builtin.c b/Src/builtin.c index c042537f4..03beb13d9 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -120,7 +120,7 @@ static struct builtin builtins[] = BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"), #ifdef DYNAMIC - BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "LaudicI", NULL), + BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "LaudicIp", NULL), #endif }; @@ -1485,7 +1485,7 @@ typeset_single(char *cname, char *pname, Param pm, int func, int usepm, tc, keeplocal = 0; /* use the existing pm? */ - usepm = pm && !(pm->flags & PM_UNSET); + usepm = pm && !(pm->flags & (PM_UNSET | PM_AUTOLOAD)); /* Always use an existing pm if special at current locallevel */ if (pm && (pm->flags & PM_SPECIAL) && pm->level == locallevel) @@ -1793,7 +1793,7 @@ bin_typeset(char *name, char **argv, char *ops, int func) continue; } if (!typeset_single(name, asg->name, - (Param)paramtab->getnode(paramtab, asg->name), + (Param)gethashnode2(paramtab, asg->name), func, on, off, roff, asg->value, NULL)) returnval = 1; } @@ -1945,7 +1945,7 @@ bin_unset(char *name, char **argv, char *ops, int func) next = (Param) pm->next; if ((!(pm->flags & PM_RESTRICTED) || unset(RESTRICTED)) && domatch(pm->nam, com, 0)) { - unsetparam(pm->nam); + unsetparam_pm(pm, 0, 1); match++; } } @@ -1974,7 +1974,7 @@ bin_unset(char *name, char **argv, char *ops, int func) } *ss = 0; } - pm = (Param) paramtab->getnode(paramtab, s); + pm = (Param) gethashnode2(paramtab, s); if (!pm) returnval = 1; else if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED)) { diff --git a/Src/mkbltnmlst.sh b/Src/mkbltnmlst.sh index b58d1e1dd..c174cbac6 100644 --- a/Src/mkbltnmlst.sh +++ b/Src/mkbltnmlst.sh @@ -24,7 +24,7 @@ for x_mod in $x_mods; do *" $x_mod "*) ;; *) echo "/* non-linked-in known module \`$x_mod' */" eval "loc=\$loc_$x_mod" - unset moddeps autobins autoinfixconds autoprefixconds + unset moddeps autobins autoinfixconds autoprefixconds autoparams . $srcdir/../$loc/${x_mod}.mdd for bin in $autobins; do echo " add_autobin(\"$bin\", \"$x_mod\");" @@ -35,6 +35,9 @@ for x_mod in $x_mods; do for cond in $autoprefixconds; do echo " add_autocond(\"$cond\", 0, \"$x_mod\");" done + for param in $autoparams; do + echo " add_autoparam(\"$param\", \"$x_mod\");" + done for dep in $moddeps; do case $bin_mods in *" $dep "*) diff --git a/Src/mkmakemod.sh b/Src/mkmakemod.sh index 2f79acbc3..cd92c7f07 100644 --- a/Src/mkmakemod.sh +++ b/Src/mkmakemod.sh @@ -24,6 +24,7 @@ # autoinfixconds infix condition codes defined by the module, for # autoloading (without the leading `-') # autoprefixconds like autoinfixconds, but for prefix condition codes +# autoparams parameters defined by the module, for autoloading # objects .o files making up this module (*must* be defined) # proto .pro files for this module (default generated from $objects) # headers extra headers for this module (default none) @@ -170,7 +171,7 @@ if $first_stage; then for module in $here_modules; do unset moddeps nozshdep alwayslink hasexport - unset autobins autoinfixconds autoprefixconds + unset autobins autoinfixconds autoprefixconds autoparams unset objects proto headers hdrdeps otherincs . $top_srcdir/$the_subdir/${module}.mdd test -n "${moddeps+set}" || moddeps= diff --git a/Src/module.c b/Src/module.c index ff386c630..09f1fd5db 100644 --- a/Src/module.c +++ b/Src/module.c @@ -539,18 +539,24 @@ load_module(char const *name) m = zcalloc(sizeof(*m)); m->nam = ztrdup(name); m->handle = handle; + m->flags |= MOD_SETUP; + PERMALLOC { + node = addlinknode(modules, m); + } LASTALLOC; if (setup_module(m) || init_module(m)) { finish_module(m); + remnode(modules, node); zsfree(m->nam); zfree(m, sizeof(*m)); + m->flags &= ~MOD_SETUP; return NULL; } - PERMALLOC { - addlinknode(modules, m); - } LASTALLOC; + m->flags &= ~MOD_SETUP; return m; } m = (Module) getdata(node); + if (m->flags & MOD_SETUP) + return m; if (m->flags & MOD_UNLOAD) m->flags &= ~MOD_UNLOAD; else if (m->handle) @@ -570,17 +576,22 @@ load_module(char const *name) if (!m->handle) { if (!(m->handle = do_load_module(name))) return NULL; + m->flags |= MOD_SETUP; if (setup_module(m)) { finish_module(m->handle); m->handle = NULL; + m->flags &= ~MOD_SETUP; return NULL; } } + m->flags |= MOD_SETUP; if (init_module(m)) { finish_module(m->handle); m->handle = NULL; + m->flags &= ~MOD_SETUP; return NULL; } + m->flags &= ~MOD_SETUP; return m; } @@ -690,6 +701,8 @@ bin_zmodload(char *nam, char **args, char *ops, int func) return bin_zmodload_auto(nam, args, ops); else if (ops['c'] || ops['C']) return bin_zmodload_cond(nam, args, ops); + else if (ops['p']) + return bin_zmodload_param(nam, args, ops); else return bin_zmodload_load(nam, args, ops); } @@ -888,6 +901,66 @@ bin_zmodload_cond(char *nam, char **args, char *ops) } } +static void +printautoparams(HashNode hn, int lon) +{ + Param pm = (Param) hn; + + if (pm->flags & PM_AUTOLOAD) { + if (lon) + printf("zmodload -p %s %s\n", pm->u.str, pm->nam); + else + printf("%s (%s)\n", pm->nam, pm->u.str); + } +} + +/**/ +static int +bin_zmodload_param(char *nam, char **args, char *ops) +{ + int ret = 0; + + if (ops['u']) { + /* remove autoloaded parameters */ + for (; *args; args++) { + Param pm = (Param) gethashnode2(paramtab, *args); + + if (!pm) { + if (!ops['i']) { + zwarnnam(nam, "%s: no such parameter", *args, 0); + ret = 1; + } + } else if (!(pm->flags & PM_AUTOLOAD)) { + zwarnnam(nam, "%s: parameter is already defined", *args, 0); + ret = 1; + } else + unsetparam_pm(pm, 0, 1); + } + return ret; + } else if (!*args) { + scanhashtable(paramtab, 1, 0, 0, printautoparams, ops['L']); + return 0; + } else { + /* add autoloaded parameters */ + char *modnam; + + modnam = *args++; + if(isset(RESTRICTED) && strchr(modnam, '/')) { + zwarnnam(nam, "%s: restricted", modnam, 0); + return 1; + } + do { + char *pnam = *args ? *args++ : modnam; + if (strchr(pnam, '/')) { + zwarnnam(nam, "%s: `/' is illegal in a parameter", pnam, 0); + ret = 1; + } else + add_autoparam(pnam, modnam); + } while(*args); + return ret; + } +} + /**/ int unload_module(Module m, LinkNode node) @@ -1114,6 +1187,71 @@ addconddefs(char const *nam, Conddef c, int size) return hadf ? hads : 1; } +/* This adds the given parameter definition. The return value is zero on * + * success and 1 on failure. */ + +/**/ +int +addparamdef(Paramdef d) +{ + Param pm; + + if ((pm = (Param) gethashnode2(paramtab, d->name))) + unsetparam_pm(pm, 0, 1); + + if (!(pm = createparam(d->name, d->flags)) && + !(pm = (Param) paramtab->getnode(paramtab, d->name))) + return 1; + + pm->level = 0; + pm->u.data = d->var; + pm->sets.ifn = (void (*)(Param, long)) d->set; + pm->gets.ifn = (long (*)(Param)) d->get; + pm->unsetfn = (void (*)(Param, int)) d->unset; + + return 0; +} + +/* This adds multiple parameter definitions. This is like addbuiltins(). */ + +/**/ +int +addparamdefs(char const *nam, Paramdef d, int size) +{ + int hads = 0, hadf = 0; + + while (size--) { + if (addparamdef(d)) { + zwarnnam(nam, "error when adding parameter `%s'", d->name, 0); + hadf = 1; + } else + hads = 2; + d++; + } + return hadf ? hads : 1; +} + +/* Delete parameters defined. No error checking yet. */ + +/**/ +int +deleteparamdef(Paramdef d) +{ + unsetparam(d->name); + return 0; +} + +/**/ +int +deleteparamdefs(char const *nam, Paramdef d, int size) +{ + while (size--) { + deleteparamdef(d); + d++; + } + return 1; +} + #ifdef DYNAMIC /* This adds a definition for autoloading a module for a condition. */ @@ -1188,4 +1326,20 @@ deleteconddefs(char const *nam, Conddef c, int size) return hadf ? hads : 1; } +/* This adds a definition for autoloading a module for a parameter. */ + +/**/ +void +add_autoparam(char *nam, char *module) +{ + Param pm; + + if ((pm = (Param) gethashnode2(paramtab, nam))) + unsetparam_pm(pm, 0, 1); + + pm = setsparam(ztrdup(nam), ztrdup(module)); + + pm->flags |= PM_AUTOLOAD; +} + #endif diff --git a/Src/params.c b/Src/params.c index dbc6ce8d8..079b89cf6 100644 --- a/Src/params.c +++ b/Src/params.c @@ -267,8 +267,8 @@ newparamtable(int size, char const *name) ht->emptytable = emptyhashtable; ht->filltable = NULL; ht->addnode = addhashnode; - ht->getnode = gethashnode2; - ht->getnode2 = gethashnode2; + ht->getnode = getparamnode; + ht->getnode2 = getparamnode; ht->removenode = removehashnode; ht->disablenode = NULL; ht->enablenode = NULL; @@ -278,6 +278,23 @@ newparamtable(int size, char const *name) return ht; } +/**/ +static HashNode +getparamnode(HashTable ht, char *nam) +{ + HashNode hn = gethashnode2(ht, nam); + Param pm = (Param) hn; + + if (pm && pm->u.str && (pm->flags & PM_AUTOLOAD)) { + char *mn = dupstring(pm->u.str); + + if (!load_module(mn)) + return NULL; + hn = gethashnode2(ht, nam); + } + return hn; +} + /* Copy a parameter hash table */ static HashTable outtable; @@ -542,7 +559,7 @@ createparam(char *name, int flags) Param pm, oldpm; if (name != nulstring) { - oldpm = (Param) paramtab->getnode(paramtab, name); + oldpm = (Param) gethashnode2(paramtab, name); if (oldpm && oldpm->level == locallevel) { if (!(oldpm->flags & PM_UNSET) || (oldpm->flags & PM_SPECIAL)) { @@ -2698,7 +2715,7 @@ printparamnode(HashNode hn, int printflags) Param p = (Param) hn; char *t, **u; - if (p->flags & PM_UNSET) + if (p->flags & (PM_UNSET | PM_AUTOLOAD)) return; /* Print the attributes of the parameter */ diff --git a/Src/zsh.h b/Src/zsh.h index c3c853dfd..1eefc51c1 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -231,6 +231,7 @@ typedef struct hashtable *HashTable; typedef struct reswd *Reswd; typedef struct alias *Alias; typedef struct param *Param; +typedef struct paramdef *Paramdef; typedef struct cmdnam *Cmdnam; typedef struct shfunc *Shfunc; typedef struct funcwrap *FuncWrap; @@ -850,6 +851,7 @@ struct module { #define MOD_BUSY (1<<0) #define MOD_UNLOAD (1<<1) +#define MOD_SETUP (1<<2) /* node used in parameter hash table (paramtab) */ @@ -923,6 +925,7 @@ struct param { #define PM_RESTRICTED (1<<15) /* cannot be changed in restricted mode */ #define PM_UNSET (1<<16) /* has null value */ #define PM_REMOVABLE (1<<17) /* special can be removed from paramtab */ +#define PM_AUTOLOAD (1<<18) /* autoloaded from module */ /* Flags for extracting elements of arrays and associative arrays */ #define SCANPM_WANTVALS (1<<0) @@ -955,6 +958,27 @@ struct param { #define PF_ASSIGN 0x02 /* argument handled like the RHS of foo=bar */ #define PF_SINGLE 0x04 /* single word substitution */ +struct paramdef { + char *name; + int flags; + void *var; + void *set; + void *get; + void *unset; +}; + +#define PARAMDEF(name, flags, var, set, get, unset) \ + { name, flags, (void *) var, (void *) set, (void *) get, (void *) unset } +#define INTPARAMDEF(name, var) \ + { name, PM_INTEGER, (void *) var, (void *) intvarsetfn, \ + (void *) intvargetfn, (void *) stdunsetfn } +#define STRPARAMDEF(name, var) \ + { name, PM_SCALAR, (void *) var, (void *) strvarsetfn, \ + (void *) strvargetfn, (void *) stdunsetfn } +#define ARRPARAMDEF(name, var) \ + { name, PM_ARRAY, (void *) var, (void *) arrvarsetfn, \ + (void *) arrvargetfn, (void *) stdunsetfn } + /* node for named directory hash table (nameddirtab) */ struct nameddir { -- cgit 1.4.1