summaryrefslogtreecommitdiff
path: root/Src/Modules/parameter.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Modules/parameter.c')
-rw-r--r--Src/Modules/parameter.c1699
1 files changed, 1500 insertions, 199 deletions
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 2257933f5..e8e387a59 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -30,6 +30,10 @@
#include "parameter.mdh"
#include "parameter.pro"
+/* This says if we are cleaning up when the module is unloaded. */
+
+static int incleanup;
+
/* Empty dummy function for special hash parameters. */
/**/
@@ -47,14 +51,14 @@ createspecialhash(char *name, GetNodeFunc get, ScanTabFunc scan)
Param pm;
HashTable ht;
- if (!(pm = createparam(name, PM_SPECIAL|PM_REMOVABLE|PM_HASHED)))
+ if (!(pm = createparam(name, PM_SPECIAL|PM_HIDE|PM_REMOVABLE|PM_HASHED)))
return NULL;
pm->level = pm->old ? locallevel : 0;
pm->gets.hfn = hashgetfn;
pm->sets.hfn = hashsetfn;
pm->unsetfn = stdunsetfn;
- pm->u.hash = ht = newhashtable(7, name, NULL);
+ pm->u.hash = ht = newhashtable(0, name, NULL);
ht->hash = hasher;
ht->emptytable = (TableFunc) shempty;
@@ -83,14 +87,21 @@ paramtypestr(Param pm)
int f = pm->flags;
if (!(f & PM_UNSET)) {
+ if (pm->flags & PM_AUTOLOAD)
+ return dupstring("undefined");
+
switch (PM_TYPE(f)) {
case PM_SCALAR: val = "scalar"; break;
case PM_ARRAY: val = "array"; break;
case PM_INTEGER: val = "integer"; break;
+ case PM_EFLOAT:
+ case PM_FFLOAT: val = "float"; break;
case PM_HASHED: val = "association"; break;
}
DPUTS(!val, "BUG: type not handled in parameter");
val = dupstring(val);
+ if (pm->level)
+ val = dyncat(val, "-local");
if (f & PM_LEFT)
val = dyncat(val, "-left");
if (f & PM_RIGHT_B)
@@ -109,6 +120,10 @@ paramtypestr(Param pm)
val = dyncat(val, "-export");
if (f & PM_UNIQUE)
val = dyncat(val, "-unique");
+ if (f & PM_HIDE)
+ val = dyncat(val, "-hide");
+ if (f & PM_SPECIAL)
+ val = dyncat(val, "-special");
} else
val = dupstring("");
@@ -121,27 +136,24 @@ getpmparameter(HashTable ht, char *name)
{
Param rpm, pm = NULL;
- HEAPALLOC {
- pm = (Param) zhalloc(sizeof(struct param));
- pm->nam = dupstring(name);
- pm->flags = PM_SCALAR | PM_READONLY;
- pm->sets.cfn = NULL;
- pm->gets.cfn = strgetfn;
- pm->unsetfn = NULL;
- pm->ct = 0;
- pm->env = NULL;
- pm->ename = NULL;
- pm->old = NULL;
- pm->level = 0;
- if ((rpm = (Param) realparamtab->getnode(realparamtab, name)) &&
- !(rpm->flags & PM_UNSET))
- pm->u.str = paramtypestr(rpm);
- else {
- pm->u.str = "";
- pm->flags |= PM_UNSET;
- }
- } LASTALLOC;
-
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR | PM_READONLY;
+ pm->sets.cfn = NULL;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = NULL;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+ if ((rpm = (Param) realparamtab->getnode(realparamtab, name)) &&
+ !(rpm->flags & PM_UNSET))
+ pm->u.str = paramtypestr(rpm);
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
return (HashNode) pm;
}
@@ -166,7 +178,9 @@ scanpmparameters(HashTable ht, ScanFunc func, int flags)
for (i = 0; i < realparamtab->hsize; i++)
for (hn = realparamtab->nodes[i]; hn; hn = hn->next) {
pm.nam = hn->nam;
- if (func != scancountparams)
+ if (func != scancountparams &&
+ ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS)))
pm.u.str = paramtypestr((Param) hn);
func((HashNode) &pm, flags);
}
@@ -179,12 +193,12 @@ static void
setpmcommand(Param pm, char *value)
{
if (isset(RESTRICTED))
- zwarnnam(NULL, "restricted: %s", value, 0);
+ zwarn("restricted: %s", value, 0);
else {
Cmdnam cn = zcalloc(sizeof(*cn));
cn->flags = HASHED;
- cn->u.cmd = ztrdup(value);
+ cn->u.cmd = value;
cmdnamtab->addnode(cmdnamtab, ztrdup(pm->nam), (HashNode) cn);
}
@@ -207,6 +221,9 @@ setpmcommands(Param pm, HashTable ht)
int i;
HashNode hn;
+ if (!ht)
+ return;
+
for (i = 0; i < ht->hsize; i++)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
Cmdnam cn = zcalloc(sizeof(*cn));
@@ -222,6 +239,7 @@ setpmcommands(Param pm, HashTable ht)
cmdnamtab->addnode(cmdnamtab, ztrdup(hn->nam), (HashNode) cn);
}
+ deleteparamtable(ht);
}
/**/
@@ -236,34 +254,30 @@ getpmcommand(HashTable ht, char *name)
cmdnamtab->filltable(cmdnamtab);
cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name);
}
- HEAPALLOC {
- pm = (Param) zhalloc(sizeof(struct param));
- pm->nam = dupstring(name);
- pm->flags = PM_SCALAR;
- pm->sets.cfn = setpmcommand;
- pm->gets.cfn = strgetfn;
- pm->unsetfn = unsetpmcommand;
- pm->ct = 0;
- pm->env = NULL;
- pm->ename = NULL;
- pm->old = NULL;
- pm->level = 0;
- if (cmd) {
- if (cmd->flags & HASHED)
- pm->u.str = cmd->u.cmd;
- else {
- pm->u.str = zhalloc(strlen(*(cmd->u.name)) +
- strlen(name) + 2);
- strcpy(pm->u.str, *(cmd->u.name));
- strcat(pm->u.str, "/");
- strcat(pm->u.str, name);
- }
- } else {
- pm->u.str = "";
- pm->flags |= PM_UNSET;
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR;
+ pm->sets.cfn = setpmcommand;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = unsetpmcommand;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+ if (cmd) {
+ if (cmd->flags & HASHED)
+ pm->u.str = cmd->u.cmd;
+ else {
+ pm->u.str = zhalloc(strlen(*(cmd->u.name)) + strlen(name) + 2);
+ strcpy(pm->u.str, *(cmd->u.name));
+ strcat(pm->u.str, "/");
+ strcat(pm->u.str, name);
}
- } LASTALLOC;
-
+ } else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
return (HashNode) pm;
}
@@ -293,7 +307,9 @@ scanpmcommands(HashTable ht, ScanFunc func, int flags)
for (hn = cmdnamtab->nodes[i]; hn; hn = hn->next) {
pm.nam = hn->nam;
cmd = (Cmdnam) hn;
- if (func != scancountparams) {
+ if (func != scancountparams &&
+ ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS))) {
if (cmd->flags & HASHED)
pm.u.str = cmd->u.cmd;
else {
@@ -312,43 +328,37 @@ scanpmcommands(HashTable ht, ScanFunc func, int flags)
/**/
static void
-setfunction(char *name, char *value)
+setfunction(char *name, char *val, int dis)
{
- char *val;
+ char *value = dupstring(val);
Shfunc shf;
- List list;
+ Eprog prog;
int sn;
- val = ztrdup(value);
val = metafy(val, strlen(val), META_REALLOC);
- HEAPALLOC {
- list = parse_string(val);
- } LASTALLOC;
+ prog = parse_string(val, 1);
- if (!list || list == &dummy_list) {
- zwarnnam(NULL, "invalid function definition", val, 0);
+ if (!prog || prog == &dummy_eprog) {
+ zwarn("invalid function definition", value, 0);
zsfree(val);
return;
}
- PERMALLOC {
- shf = (Shfunc) zalloc(sizeof(*shf));
- shf->funcdef = (List) dupstruct(list);
- shf->flags = 0;
-
- if (!strncmp(name, "TRAP", 4) &&
- (sn = getsignum(name + 4)) != -1) {
- if (settrap(sn, shf->funcdef)) {
- freestruct(shf->funcdef);
- zfree(shf, sizeof(*shf));
- zsfree(val);
- LASTALLOC_RETURN;
- }
- sigtrapped[sn] |= ZSIG_FUNC;
+ shf = (Shfunc) zalloc(sizeof(*shf));
+ shf->funcdef = dupeprog(prog, 0);
+ shf->flags = dis;
+
+ if (!strncmp(name, "TRAP", 4) &&
+ (sn = getsignum(name + 4)) != -1) {
+ if (settrap(sn, shf->funcdef)) {
+ freeeprog(shf->funcdef);
+ zfree(shf, sizeof(*shf));
+ zsfree(val);
+ return;
}
- shfunctab->addnode(shfunctab, ztrdup(name), shf);
- } LASTALLOC;
-
+ sigtrapped[sn] |= ZSIG_FUNC;
+ }
+ shfunctab->addnode(shfunctab, ztrdup(name), shf);
zsfree(val);
}
@@ -356,7 +366,14 @@ setfunction(char *name, char *value)
static void
setpmfunction(Param pm, char *value)
{
- setfunction(pm->nam, value);
+ setfunction(pm->nam, value, 0);
+}
+
+/**/
+static void
+setpmdisfunction(Param pm, char *value)
+{
+ setfunction(pm->nam, value, DISABLED);
}
/**/
@@ -371,11 +388,14 @@ unsetpmfunction(Param pm, int exp)
/**/
static void
-setpmfunctions(Param pm, HashTable ht)
+setfunctions(Param pm, HashTable ht, int dis)
{
int i;
HashNode hn;
+ if (!ht)
+ return;
+
for (i = 0; i < ht->hsize; i++)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
@@ -385,62 +405,100 @@ setpmfunctions(Param pm, HashTable ht)
v.arr = NULL;
v.pm = (Param) hn;
- setfunction(hn->nam, getstrvalue(&v));
+ setfunction(hn->nam, ztrdup(getstrvalue(&v)), dis);
}
+ deleteparamtable(ht);
+}
+
+/**/
+static void
+setpmfunctions(Param pm, HashTable ht)
+{
+ setfunctions(pm, ht, 0);
+}
+
+/**/
+static void
+setpmdisfunctions(Param pm, HashTable ht)
+{
+ setfunctions(pm, ht, DISABLED);
}
/**/
static HashNode
-getpmfunction(HashTable ht, char *name)
+getfunction(HashTable ht, char *name, int dis)
{
Shfunc shf;
Param pm = NULL;
- HEAPALLOC {
- pm = (Param) zhalloc(sizeof(struct param));
- pm->nam = dupstring(name);
- pm->flags = PM_SCALAR;
- pm->sets.cfn = setpmfunction;
- pm->gets.cfn = strgetfn;
- pm->unsetfn = unsetpmfunction;
- pm->ct = 0;
- pm->env = NULL;
- pm->ename = NULL;
- pm->old = NULL;
- pm->level = 0;
-
- if ((shf = (Shfunc) shfunctab->getnode(shfunctab, name))) {
- if (shf->flags & PM_UNDEFINED)
- pm->u.str = "undefined";
- else {
- char *t = getpermtext((void *) dupstruct((void *)
- shf->funcdef)), *h;
-
- h = dupstring(t);
- zsfree(t);
- unmetafy(h, NULL);
-
- pm->u.str = h;
- }
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR;
+ pm->sets.cfn = (dis ? setpmdisfunction : setpmfunction);
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = unsetpmfunction;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+
+ if ((shf = (Shfunc) shfunctab->getnode2(shfunctab, name)) &&
+ (dis ? (shf->flags & DISABLED) : !(shf->flags & DISABLED))) {
+ if (shf->flags & PM_UNDEFINED) {
+ pm->u.str = dyncat("builtin autoload -X",
+ ((shf->flags & PM_UNALIASED) ?
+ ((shf->flags & PM_TAGGED) ? "Ut" : "U") :
+ ((shf->flags & PM_TAGGED) ? "t" : "")));
} else {
- pm->u.str = "";
- pm->flags |= PM_UNSET;
+ char *t = getpermtext(shf->funcdef, NULL), *n, *h;
+
+ if (shf->funcdef->flags & EF_RUN) {
+ n = nicedupstring(name);
+ h = (char *) zhalloc(strlen(t) + strlen(n) + 9);
+ h[0] = '\t';
+ strcpy(h + 1, t);
+ strcat(h, "\n\t");
+ strcat(h, n);
+ strcat(h, " \"$@\"");
+ } else
+ h = dyncat("\t", t);
+ zsfree(t);
+ unmetafy(h, NULL);
+
+ pm->u.str = h;
}
- } LASTALLOC;
-
+ } else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
return (HashNode) pm;
}
/**/
+static HashNode
+getpmfunction(HashTable ht, char *name)
+{
+ return getfunction(ht, name, 0);
+}
+
+/**/
+static HashNode
+getpmdisfunction(HashTable ht, char *name)
+{
+ return getfunction(ht, name, DISABLED);
+}
+
+/**/
static void
-scanpmfunctions(HashTable ht, ScanFunc func, int flags)
+scanfunctions(HashTable ht, ScanFunc func, int flags, int dis)
{
struct param pm;
int i;
HashNode hn;
pm.flags = PM_SCALAR;
- pm.sets.cfn = setpmcommand;
+ pm.sets.cfn = (dis ? setpmdisfunction : setpmfunction);
pm.gets.cfn = strgetfn;
pm.unsetfn = unsetpmcommand;
pm.ct = 0;
@@ -451,16 +509,32 @@ scanpmfunctions(HashTable ht, ScanFunc func, int flags)
for (i = 0; i < shfunctab->hsize; i++)
for (hn = shfunctab->nodes[i]; hn; hn = hn->next) {
- if (!(hn->flags & DISABLED)) {
+ if (dis ? (hn->flags & DISABLED) : !(hn->flags & DISABLED)) {
pm.nam = hn->nam;
- if (func != scancountparams) {
- if (((Shfunc) hn)->flags & PM_UNDEFINED)
- pm.u.str = "undefined";
- else {
- char *t = getpermtext((void *)
- dupstruct((void *) ((Shfunc) hn)->funcdef));
-
- unmetafy((pm.u.str = dupstring(t)), NULL);
+ if (func != scancountparams &&
+ ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS))) {
+ if (((Shfunc) hn)->flags & PM_UNDEFINED) {
+ Shfunc shf = (Shfunc) hn;
+ pm.u.str =
+ dyncat("builtin autoload -X",
+ ((shf->flags & PM_UNALIASED) ?
+ ((shf->flags & PM_TAGGED) ? "Ut" : "U") :
+ ((shf->flags & PM_TAGGED) ? "t" : "")));
+ } else {
+ char *t = getpermtext(((Shfunc) hn)->funcdef, NULL), *n;
+
+ if (((Shfunc) hn)->funcdef->flags & EF_RUN) {
+ n = nicedupstring(hn->nam);
+ pm.u.str = (char *) zhalloc(strlen(t) + strlen(n) + 9);
+ pm.u.str[0] = '\t';
+ strcpy(pm.u.str + 1, t);
+ strcat(pm.u.str, "\n\t");
+ strcat(pm.u.str, n);
+ strcat(pm.u.str, " \"$@\"");
+ } else
+ pm.u.str = dyncat("\t", t);
+ unmetafy(pm.u.str, NULL);
zsfree(t);
}
}
@@ -469,6 +543,173 @@ scanpmfunctions(HashTable ht, ScanFunc func, int flags)
}
}
+/**/
+static void
+scanpmfunctions(HashTable ht, ScanFunc func, int flags)
+{
+ scanfunctions(ht, func, flags, 0);
+}
+
+/**/
+static void
+scanpmdisfunctions(HashTable ht, ScanFunc func, int flags)
+{
+ scanfunctions(ht, func, flags, DISABLED);
+}
+
+/* Functions for the funcstack special parameter. */
+
+/**/
+static char **
+funcstackgetfn(Param pm)
+{
+ Funcstack f;
+ int num;
+ char **ret, **p;
+
+ for (f = funcstack, num = 0; f; f = f->prev, num++);
+
+ ret = (char **) zhalloc((num + 1) * sizeof(char *));
+
+ for (f = funcstack, p = ret; f; f = f->prev, p++)
+ *p = f->name;
+ *p = NULL;
+
+ return ret;
+}
+
+/* Functions for the builtins special parameter. */
+
+/**/
+static HashNode
+getbuiltin(HashTable ht, char *name, int dis)
+{
+ Param pm = NULL;
+ Builtin bn;
+
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR | PM_READONLY;
+ pm->sets.cfn = NULL;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = NULL;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+ if ((bn = (Builtin) builtintab->getnode2(builtintab, name)) &&
+ (dis ? (bn->flags & DISABLED) : !(bn->flags & DISABLED))) {
+ char *t = ((bn->handlerfunc || (bn->flags & BINF_PREFIX)) ?
+ "defined" : "undefined");
+
+ pm->u.str = dupstring(t);
+ } else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
+ return (HashNode) pm;
+}
+
+/**/
+static HashNode
+getpmbuiltin(HashTable ht, char *name)
+{
+ return getbuiltin(ht, name, 0);
+}
+
+/**/
+static HashNode
+getpmdisbuiltin(HashTable ht, char *name)
+{
+ return getbuiltin(ht, name, DISABLED);
+}
+
+/**/
+static void
+scanbuiltins(HashTable ht, ScanFunc func, int flags, int dis)
+{
+ struct param pm;
+ int i;
+ HashNode hn;
+
+ pm.flags = PM_SCALAR | PM_READONLY;
+ pm.sets.cfn = NULL;
+ pm.gets.cfn = strgetfn;
+ pm.unsetfn = NULL;
+ pm.ct = 0;
+ pm.env = NULL;
+ pm.ename = NULL;
+ pm.old = NULL;
+ pm.level = 0;
+
+ for (i = 0; i < builtintab->hsize; i++)
+ for (hn = builtintab->nodes[i]; hn; hn = hn->next) {
+ if (dis ? (hn->flags & DISABLED) : !(hn->flags & DISABLED)) {
+ pm.nam = hn->nam;
+ if (func != scancountparams &&
+ ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS))) {
+ char *t = ((((Builtin) hn)->handlerfunc ||
+ (hn->flags & BINF_PREFIX)) ?
+ "defined" : "undefined");
+
+ pm.u.str = dupstring(t);
+ }
+ func((HashNode) &pm, flags);
+ }
+ }
+}
+
+/**/
+static void
+scanpmbuiltins(HashTable ht, ScanFunc func, int flags)
+{
+ scanbuiltins(ht, func, flags, 0);
+}
+
+/**/
+static void
+scanpmdisbuiltins(HashTable ht, ScanFunc func, int flags)
+{
+ scanbuiltins(ht, func, flags, DISABLED);
+}
+
+/* Functions for the reswords special parameter. */
+
+/**/
+static char **
+getreswords(int dis)
+{
+ int i;
+ HashNode hn;
+ char **ret, **p;
+
+ p = ret = (char **) zhalloc((reswdtab->ct + 1) * sizeof(char *));
+
+ for (i = 0; i < reswdtab->hsize; i++)
+ for (hn = reswdtab->nodes[i]; hn; hn = hn->next)
+ if (dis ? (hn->flags & DISABLED) : !(hn->flags & DISABLED))
+ *p++ = dupstring(hn->nam);
+ *p = NULL;
+
+ return ret;
+}
+
+/**/
+static char **
+reswordsgetfn(Param pm)
+{
+ return getreswords(0);
+}
+
+/**/
+static char **
+disreswordsgetfn(Param pm)
+{
+ return getreswords(DISABLED);
+}
+
/* Functions for the options special parameter. */
/**/
@@ -478,11 +719,12 @@ setpmoption(Param pm, char *value)
int n;
if (!value || (strcmp(value, "on") && strcmp(value, "off")))
- zwarnnam(NULL, "invalid value: %s", value, 0);
+ zwarn("invalid value: %s", value, 0);
else if (!(n = optlookup(pm->nam)))
- zwarnnam(NULL, "no such option: %s", pm->nam, 0);
+ zwarn("no such option: %s", pm->nam, 0);
else if (dosetopt(n, (value && strcmp(value, "off")), 0))
- zwarnnam(NULL, "can't change option: %s", pm->nam, 0);
+ zwarn("can't change option: %s", pm->nam, 0);
+ zsfree(value);
}
/**/
@@ -492,9 +734,9 @@ unsetpmoption(Param pm, int exp)
int n;
if (!(n = optlookup(pm->nam)))
- zwarnnam(NULL, "no such option: %s", pm->nam, 0);
+ zwarn("no such option: %s", pm->nam, 0);
else if (dosetopt(n, 0, 0))
- zwarnnam(NULL, "can't change option: %s", pm->nam, 0);
+ zwarn("can't change option: %s", pm->nam, 0);
}
/**/
@@ -504,6 +746,9 @@ setpmoptions(Param pm, HashTable ht)
int i;
HashNode hn;
+ if (!ht)
+ return;
+
for (i = 0; i < ht->hsize; i++)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
@@ -516,11 +761,12 @@ setpmoptions(Param pm, HashTable ht)
val = getstrvalue(&v);
if (!val || (strcmp(val, "on") && strcmp(val, "off")))
- zwarnnam(NULL, "invalid value: %s", val, 0);
+ zwarn("invalid value: %s", val, 0);
else if (dosetopt(optlookup(hn->nam),
(val && strcmp(val, "off")), 0))
- zwarnnam(NULL, "can't change option: %s", hn->nam, 0);
+ zwarn("can't change option: %s", hn->nam, 0);
}
+ deleteparamtable(ht);
}
/**/
@@ -530,27 +776,24 @@ getpmoption(HashTable ht, char *name)
Param pm = NULL;
int n;
- HEAPALLOC {
- pm = (Param) zhalloc(sizeof(struct param));
- pm->nam = dupstring(name);
- pm->flags = PM_SCALAR;
- pm->sets.cfn = setpmoption;
- pm->gets.cfn = strgetfn;
- pm->unsetfn = unsetpmoption;
- pm->ct = 0;
- pm->env = NULL;
- pm->ename = NULL;
- pm->old = NULL;
- pm->level = 0;
-
- if ((n = optlookup(name)))
- pm->u.str = dupstring(opts[n] ? "on" : "off");
- else {
- pm->u.str = "";
- pm->flags |= PM_UNSET;
- }
- } LASTALLOC;
-
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR;
+ pm->sets.cfn = setpmoption;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = unsetpmoption;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+
+ if ((n = optlookup(name)))
+ pm->u.str = dupstring(opts[n] ? "on" : "off");
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
return (HashNode) pm;
}
@@ -574,89 +817,1147 @@ scanpmoptions(HashTable ht, ScanFunc func, int flags)
for (i = 0; i < optiontab->hsize; i++)
for (hn = optiontab->nodes[i]; hn; hn = hn->next) {
+ int optno = ((Optname) hn)->optno, ison;
pm.nam = hn->nam;
- pm.u.str = opts[((Optname) hn)->optno] ? "on" : "off";
+ ison = optno < 0 ? !opts[-optno] : opts[optno];
+ pm.u.str = dupstring(ison ? "on" : "off");
func((HashNode) &pm, flags);
}
}
-/* Names and Params for the special parameters. */
+/* Functions for the modules special parameter. */
-#define PAR_NAM "parameters"
-#define CMD_NAM "commands"
-#define FUN_NAM "functions"
-#define OPT_NAM "options"
+static char *modpmname;
+static int modpmfound;
-static Param parpm, cmdpm, funpm, optpm;
+/**/
+static void
+modpmbuiltinscan(HashNode hn, int dummy)
+{
+ if (!(((Builtin) hn)->flags & BINF_ADDED) &&
+ !strcmp(((Builtin) hn)->optstr, modpmname))
+ modpmfound = 1;
+}
+
+/**/
+static void
+modpmparamscan(HashNode hn, int dummy)
+{
+ if ((((Param) hn)->flags & PM_AUTOLOAD) &&
+ !strcmp(((Param) hn)->u.str, modpmname))
+ modpmfound = 1;
+}
+
+/**/
+static int
+findmodnode(LinkList l, char *nam)
+{
+ LinkNode node;
+
+ for (node = firstnode(l); node; incnode(node))
+ if (!strcmp(nam, (char *) getdata(node)))
+ return 1;
+
+ return 0;
+}
+
+/**/
+static HashNode
+getpmmodule(HashTable ht, char *name)
+{
+ Param pm = NULL;
+ char *type = NULL;
+ LinkNode node;
+
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR | PM_READONLY;
+ pm->sets.cfn = NULL;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = NULL;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+
+ if (!type) {
+ Module m;
+
+ for (node = firstnode(modules); node; incnode(node)) {
+ m = (Module) getdata(node);
+ if (m->u.handle && !(m->flags & MOD_UNLOAD) &&
+ !strcmp(name, m->nam)) {
+ type = "loaded";
+ break;
+ }
+ }
+ }
+ modpmname = name;
+ modpmfound = 0;
+ if (!type) {
+ scanhashtable(builtintab, 0, 0, 0, modpmbuiltinscan, 0);
+ if (!modpmfound) {
+ Conddef p;
+
+ for (p = condtab; p; p = p->next)
+ if (p->module && !strcmp(name, p->module)) {
+ modpmfound = 1;
+ break;
+ }
+ if (!modpmfound)
+ scanhashtable(realparamtab, 0, 0, 0, modpmparamscan, 0);
+ }
+ if (modpmfound)
+ type = "autoloaded";
+ }
+ if (type)
+ pm->u.str = dupstring(type);
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
+ return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmmodules(HashTable ht, ScanFunc func, int flags)
+{
+ struct param pm;
+ int i;
+ HashNode hn;
+ LinkList done = newlinklist();
+ LinkNode node;
+ Module m;
+ Conddef p;
+
+ pm.flags = PM_SCALAR | PM_READONLY;
+ pm.sets.cfn = NULL;
+ pm.gets.cfn = strgetfn;
+ pm.unsetfn = NULL;
+ pm.ct = 0;
+ pm.env = NULL;
+ pm.ename = NULL;
+ pm.old = NULL;
+ pm.level = 0;
+
+ pm.u.str = dupstring("builtin");
+ pm.u.str = dupstring("loaded");
+ for (node = firstnode(modules); node; incnode(node)) {
+ m = (Module) getdata(node);
+ if (m->u.handle && !(m->flags & MOD_UNLOAD)) {
+ pm.nam = m->nam;
+ addlinknode(done, pm.nam);
+ func((HashNode) &pm, flags);
+ }
+ }
+ pm.u.str = dupstring("autoloaded");
+ for (i = 0; i < builtintab->hsize; i++)
+ for (hn = builtintab->nodes[i]; hn; hn = hn->next) {
+ if (!(((Builtin) hn)->flags & BINF_ADDED) &&
+ !findmodnode(done, ((Builtin) hn)->optstr)) {
+ pm.nam = ((Builtin) hn)->optstr;
+ addlinknode(done, pm.nam);
+ func((HashNode) &pm, flags);
+ }
+ }
+ for (p = condtab; p; p = p->next)
+ if (p->module && !findmodnode(done, p->module)) {
+ pm.nam = p->module;
+ addlinknode(done, pm.nam);
+ func((HashNode) &pm, flags);
+ }
+ for (i = 0; i < realparamtab->hsize; i++)
+ for (hn = realparamtab->nodes[i]; hn; hn = hn->next) {
+ if ((((Param) hn)->flags & PM_AUTOLOAD) &&
+ !findmodnode(done, ((Param) hn)->u.str)) {
+ pm.nam = ((Param) hn)->u.str;
+ addlinknode(done, pm.nam);
+ func((HashNode) &pm, flags);
+ }
+ }
+}
+
+/* Functions for the dirstack special parameter. */
+
+/**/
+static void
+dirssetfn(Param pm, char **x)
+{
+ char **ox = x;
+
+ if (!incleanup) {
+ freelinklist(dirstack, freestr);
+ dirstack = znewlinklist();
+ while (x && *x)
+ zaddlinknode(dirstack, ztrdup(*x++));
+ }
+ if (ox)
+ freearray(ox);
+}
+
+/**/
+static char **
+dirsgetfn(Param pm)
+{
+ int l = countlinknodes(dirstack);
+ char **ret = (char **) zhalloc((l + 1) * sizeof(char *)), **p;
+ LinkNode n;
+
+ for (n = firstnode(dirstack), p = ret; n; incnode(n), p++)
+ *p = dupstring((char *) getdata(n));
+ *p = NULL;
+
+ return ret;
+}
+
+/* Functions for the history special parameter. */
+
+/**/
+static HashNode
+getpmhistory(HashTable ht, char *name)
+{
+ Param pm = NULL;
+ Histent he;
+
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR | PM_READONLY;
+ pm->sets.cfn = NULL;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = NULL;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+ if ((he = quietgethist(atoi(name))))
+ pm->u.str = dupstring(he->text);
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
+ return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmhistory(HashTable ht, ScanFunc func, int flags)
+{
+ struct param pm;
+ int i = addhistnum(curhist, -1, HIST_FOREIGN);
+ Histent he = quietgethistent(i, GETHIST_UPWARD);
+ char buf[40];
+
+ pm.flags = PM_SCALAR | PM_READONLY;
+ pm.sets.cfn = NULL;
+ pm.gets.cfn = strgetfn;
+ pm.unsetfn = NULL;
+ pm.ct = 0;
+ pm.env = NULL;
+ pm.ename = NULL;
+ pm.old = NULL;
+ pm.level = 0;
+
+ while (he) {
+ if (func != scancountparams) {
+ sprintf(buf, "%d", he->histnum);
+ pm.nam = dupstring(buf);
+ if ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS))
+ pm.u.str = dupstring(he->text);
+ }
+ func((HashNode) &pm, flags);
+
+ he = up_histent(he);
+ }
+}
+
+/* Function for the historywords special parameter. */
+
+/**/
+static char **
+histwgetfn(Param pm)
+{
+ char **ret, **p, *h, *e, sav;
+ LinkList l = newlinklist();
+ LinkNode n;
+ int i = addhistnum(curhist, -1, HIST_FOREIGN), iw;
+ Histent he = quietgethistent(i, GETHIST_UPWARD);
+
+ while (he) {
+ for (iw = he->nwords - 1; iw >= 0; iw--) {
+ h = he->text + he->words[iw * 2];
+ e = he->text + he->words[iw * 2 + 1];
+ sav = *e;
+ *e = '\0';
+ addlinknode(l, dupstring(h));
+ *e = sav;
+ }
+ he = up_histent(he);
+ }
+ ret = (char **) zhalloc((countlinknodes(l) + 1) * sizeof(char *));
+
+ for (p = ret, n = firstnode(l); n; incnode(n), p++)
+ *p = (char *) getdata(n);
+ *p = NULL;
+
+ return ret;
+}
+
+/* Functions for the jobtexts special parameter. */
+
+/**/
+static char *
+pmjobtext(int job)
+{
+ Process pn;
+ int len = 1;
+ char *ret;
+
+ for (pn = jobtab[job].procs; pn; pn = pn->next)
+ len += strlen(pn->text) + 3;
+
+ ret = (char *) zhalloc(len);
+ ret[0] = '\0';
+
+ for (pn = jobtab[job].procs; pn; pn = pn->next) {
+ strcat(ret, pn->text);
+ if (pn->next)
+ strcat(ret, " | ");
+ }
+ return ret;
+}
+
+/**/
+static HashNode
+getpmjobtext(HashTable ht, char *name)
+{
+ Param pm = NULL;
+ int job;
+
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR | PM_READONLY;
+ pm->sets.cfn = NULL;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = NULL;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+
+ if ((job = atoi(name)) >= 1 && job < MAXJOB &&
+ jobtab[job].stat && jobtab[job].procs &&
+ !(jobtab[job].stat & STAT_NOPRINT))
+ pm->u.str = pmjobtext(job);
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
+ return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmjobtexts(HashTable ht, ScanFunc func, int flags)
+{
+ struct param pm;
+ int job;
+ char buf[40];
+
+ pm.flags = PM_SCALAR | PM_READONLY;
+ pm.sets.cfn = NULL;
+ pm.gets.cfn = strgetfn;
+ pm.unsetfn = NULL;
+ pm.ct = 0;
+ pm.env = NULL;
+ pm.ename = NULL;
+ pm.old = NULL;
+ pm.level = 0;
+
+ for (job = 1; job < MAXJOB; job++) {
+ if (jobtab[job].stat && jobtab[job].procs &&
+ !(jobtab[job].stat & STAT_NOPRINT)) {
+ if (func != scancountparams) {
+ sprintf(buf, "%d", job);
+ pm.nam = dupstring(buf);
+ if ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS))
+ pm.u.str = pmjobtext(job);
+ }
+ func((HashNode) &pm, flags);
+ }
+ }
+}
+
+/* Functions for the jobstates special parameter. */
+
+/**/
+static char *
+pmjobstate(int job)
+{
+ Process pn;
+ char buf[256], buf2[128], *ret, *state;
+
+ if (jobtab[job].stat & STAT_DONE)
+ ret = dupstring("done");
+ else if (jobtab[job].stat & STAT_STOPPED)
+ ret = dupstring("suspended");
+ else
+ ret = dupstring("running");
+
+ for (pn = jobtab[job].procs; pn; pn = pn->next) {
+
+ if (pn->status == SP_RUNNING)
+ state = "running";
+ else if (WIFEXITED(pn->status)) {
+ if (WEXITSTATUS(pn->status))
+ sprintf((state = buf2), "exit %d", (pn->status));
+ else
+ state = "done";
+ } else if (WIFSTOPPED(pn->status))
+ state = sigmsg(WSTOPSIG(pn->status));
+ else if (WCOREDUMP(pn->status))
+ sprintf((state = buf2), "%s (core dumped)",
+ sigmsg(WTERMSIG(pn->status)));
+ else
+ state = sigmsg(WTERMSIG(pn->status));
+
+ sprintf(buf, ":%d=%s", pn->pid, state);
+
+ ret = dyncat(ret, buf);
+ }
+ return ret;
+}
+
+/**/
+static HashNode
+getpmjobstate(HashTable ht, char *name)
+{
+ Param pm = NULL;
+ int job;
+
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR | PM_READONLY;
+ pm->sets.cfn = NULL;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = NULL;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+
+ if ((job = atoi(name)) >= 1 && job < MAXJOB &&
+ jobtab[job].stat && jobtab[job].procs &&
+ !(jobtab[job].stat & STAT_NOPRINT))
+ pm->u.str = pmjobstate(job);
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
+ return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmjobstates(HashTable ht, ScanFunc func, int flags)
+{
+ struct param pm;
+ int job;
+ char buf[40];
+
+ pm.flags = PM_SCALAR | PM_READONLY;
+ pm.sets.cfn = NULL;
+ pm.gets.cfn = strgetfn;
+ pm.unsetfn = NULL;
+ pm.ct = 0;
+ pm.env = NULL;
+ pm.ename = NULL;
+ pm.old = NULL;
+ pm.level = 0;
+
+ for (job = 1; job < MAXJOB; job++) {
+ if (jobtab[job].stat && jobtab[job].procs &&
+ !(jobtab[job].stat & STAT_NOPRINT)) {
+ if (func != scancountparams) {
+ sprintf(buf, "%d", job);
+ pm.nam = dupstring(buf);
+ if ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS))
+ pm.u.str = pmjobstate(job);
+ }
+ func((HashNode) &pm, flags);
+ }
+ }
+}
+
+/* Functions for the jobdirs special parameter. */
+
+/**/
+static char *
+pmjobdir(int job)
+{
+ char *ret;
+
+ ret = dupstring(jobtab[job].pwd ? jobtab[job].pwd : pwd);
+ return ret;
+}
+
+/**/
+static HashNode
+getpmjobdir(HashTable ht, char *name)
+{
+ Param pm = NULL;
+ int job;
+
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR | PM_READONLY;
+ pm->sets.cfn = NULL;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = NULL;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+
+ if ((job = atoi(name)) >= 1 && job < MAXJOB &&
+ jobtab[job].stat && jobtab[job].procs &&
+ !(jobtab[job].stat & STAT_NOPRINT))
+ pm->u.str = pmjobdir(job);
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
+ return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmjobdirs(HashTable ht, ScanFunc func, int flags)
+{
+ struct param pm;
+ int job;
+ char buf[40];
+
+ pm.flags = PM_SCALAR | PM_READONLY;
+ pm.sets.cfn = NULL;
+ pm.gets.cfn = strgetfn;
+ pm.unsetfn = NULL;
+ pm.ct = 0;
+ pm.env = NULL;
+ pm.ename = NULL;
+ pm.old = NULL;
+ pm.level = 0;
+
+ for (job = 1; job < MAXJOB; job++) {
+ if (jobtab[job].stat && jobtab[job].procs &&
+ !(jobtab[job].stat & STAT_NOPRINT)) {
+ if (func != scancountparams) {
+ sprintf(buf, "%d", job);
+ pm.nam = dupstring(buf);
+ if ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS))
+ pm.u.str = pmjobdir(job);
+ }
+ func((HashNode) &pm, flags);
+ }
+ }
+}
+
+/* Functions for the nameddirs special parameter. */
+
+/**/
+static void
+setpmnameddir(Param pm, char *value)
+{
+ if (!value || *value != '/' || strlen(value) >= PATH_MAX)
+ zwarn("invalid value: %s", value, 0);
+ else
+ adduserdir(pm->nam, value, 0, 1);
+ zsfree(value);
+}
+
+/**/
+static void
+unsetpmnameddir(Param pm, int exp)
+{
+ HashNode hd = nameddirtab->removenode(nameddirtab, pm->nam);
+
+ if (hd)
+ nameddirtab->freenode(hd);
+}
+
+/**/
+static void
+setpmnameddirs(Param pm, HashTable ht)
+{
+ int i;
+ HashNode hn, next, hd;
+
+ if (!ht)
+ return;
+
+ for (i = 0; i < nameddirtab->hsize; i++)
+ for (hn = nameddirtab->nodes[i]; hn; hn = next) {
+ next = hn->next;
+ if (!(((Nameddir) hn)->flags & ND_USERNAME) &&
+ (hd = nameddirtab->removenode(nameddirtab, hn->nam)))
+ nameddirtab->freenode(hd);
+ }
+
+ for (i = 0; i < ht->hsize; i++)
+ for (hn = ht->nodes[i]; hn; hn = hn->next) {
+ struct value v;
+ char *val;
+
+ v.isarr = v.inv = v.a = 0;
+ v.b = -1;
+ v.arr = NULL;
+ v.pm = (Param) hn;
+
+ if (!(val = getstrvalue(&v)) || *val != '/' ||
+ strlen(val) >= PATH_MAX)
+ zwarn("invalid value: %s", val, 0);
+ else
+ adduserdir(hn->nam, val, 0, 1);
+ }
+
+ /* The INTERACTIVE stuff ensures that the dirs are not immediatly removed
+ * when the sub-pms are deleted. */
+
+ i = opts[INTERACTIVE];
+ opts[INTERACTIVE] = 0;
+ deleteparamtable(ht);
+ opts[INTERACTIVE] = i;
+}
+
+/**/
+static HashNode
+getpmnameddir(HashTable ht, char *name)
+{
+ Param pm = NULL;
+ Nameddir nd;
+
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR;
+ pm->sets.cfn = setpmnameddir;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = unsetpmnameddir;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+ if ((nd = (Nameddir) nameddirtab->getnode(nameddirtab, name)) &&
+ !(nd->flags & ND_USERNAME))
+ pm->u.str = dupstring(nd->dir);
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
+ return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmnameddirs(HashTable ht, ScanFunc func, int flags)
+{
+ struct param pm;
+ int i;
+ HashNode hn;
+ Nameddir nd;
+
+ pm.flags = PM_SCALAR;
+ pm.sets.cfn = setpmnameddir;
+ pm.gets.cfn = strgetfn;
+ pm.unsetfn = unsetpmnameddir;
+ pm.ct = 0;
+ pm.env = NULL;
+ pm.ename = NULL;
+ pm.old = NULL;
+ pm.level = 0;
+
+ for (i = 0; i < nameddirtab->hsize; i++)
+ for (hn = nameddirtab->nodes[i]; hn; hn = hn->next) {
+ if (!((nd = (Nameddir) hn)->flags & ND_USERNAME)) {
+ pm.nam = hn->nam;
+ if (func != scancountparams &&
+ ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS)))
+ pm.u.str = dupstring(nd->dir);
+ func((HashNode) &pm, flags);
+ }
+ }
+}
+
+/* Functions for the userdirs special parameter. */
+
+/**/
+static HashNode
+getpmuserdir(HashTable ht, char *name)
+{
+ Param pm = NULL;
+ Nameddir nd;
+
+ nameddirtab->filltable(nameddirtab);
+
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR | PM_READONLY;
+ pm->sets.cfn = NULL;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = NULL;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+ if ((nd = (Nameddir) nameddirtab->getnode(nameddirtab, name)) &&
+ (nd->flags & ND_USERNAME))
+ pm->u.str = dupstring(nd->dir);
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
+ return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmuserdirs(HashTable ht, ScanFunc func, int flags)
+{
+ struct param pm;
+ int i;
+ HashNode hn;
+ Nameddir nd;
+
+ nameddirtab->filltable(nameddirtab);
+
+ pm.flags = PM_SCALAR | PM_READONLY;
+ pm.sets.cfn = NULL;
+ pm.gets.cfn = strgetfn;
+ pm.unsetfn = NULL;
+ pm.ct = 0;
+ pm.env = NULL;
+ pm.ename = NULL;
+ pm.old = NULL;
+ pm.level = 0;
+
+ for (i = 0; i < nameddirtab->hsize; i++)
+ for (hn = nameddirtab->nodes[i]; hn; hn = hn->next) {
+ if ((nd = (Nameddir) hn)->flags & ND_USERNAME) {
+ pm.nam = hn->nam;
+ if (func != scancountparams &&
+ ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS)))
+ pm.u.str = dupstring(nd->dir);
+ func((HashNode) &pm, flags);
+ }
+ }
+}
+
+/* Functions for the regularaliases and globalaliases special parameters. */
+
+/**/
+static void
+setralias(Param pm, char *value, int dis)
+{
+ aliastab->addnode(aliastab, ztrdup(pm->nam), createaliasnode(value, dis));
+}
+
+/**/
+static void
+setpmralias(Param pm, char *value)
+{
+ setralias(pm, value, 0);
+}
+
+/**/
+static void
+setpmdisralias(Param pm, char *value)
+{
+ setralias(pm, value, DISABLED);
+}
+
+/**/
+static void
+setgalias(Param pm, char *value, int dis)
+{
+ aliastab->addnode(aliastab, ztrdup(pm->nam),
+ createaliasnode(value, dis | ALIAS_GLOBAL));
+}
+
+/**/
+static void
+setpmgalias(Param pm, char *value)
+{
+ setgalias(pm, value, 0);
+}
+
+/**/
+static void
+setpmdisgalias(Param pm, char *value)
+{
+ setgalias(pm, value, DISABLED);
+}
+
+/**/
+static void
+unsetpmalias(Param pm, int exp)
+{
+ HashNode hd = aliastab->removenode(aliastab, pm->nam);
+
+ if (hd)
+ aliastab->freenode(hd);
+}
+
+/**/
+static void
+setaliases(Param pm, HashTable ht, int global, int dis)
+{
+ int i;
+ HashNode hn, next, hd;
+
+ if (!ht)
+ return;
+
+ for (i = 0; i < aliastab->hsize; i++)
+ for (hn = aliastab->nodes[i]; hn; hn = next) {
+ next = hn->next;
+ if (((global && (((Alias) hn)->flags & ALIAS_GLOBAL)) ||
+ (!global && !(((Alias) hn)->flags & ALIAS_GLOBAL))) &&
+ (hd = aliastab->removenode(aliastab, hn->nam)))
+ aliastab->freenode(hd);
+ }
+
+ for (i = 0; i < ht->hsize; i++)
+ for (hn = ht->nodes[i]; hn; hn = hn->next) {
+ struct value v;
+ char *val;
+
+ v.isarr = v.inv = v.a = 0;
+ v.b = -1;
+ v.arr = NULL;
+ v.pm = (Param) hn;
+
+ if ((val = getstrvalue(&v)))
+ aliastab->addnode(aliastab, ztrdup(hn->nam),
+ createaliasnode(ztrdup(val),
+ (global ? ALIAS_GLOBAL : 0) |
+ (dis ? DISABLED : 0)));
+ }
+ deleteparamtable(ht);
+}
+
+/**/
+static void
+setpmraliases(Param pm, HashTable ht)
+{
+ setaliases(pm, ht, 0, 0);
+}
+
+/**/
+static void
+setpmdisraliases(Param pm, HashTable ht)
+{
+ setaliases(pm, ht, 0, DISABLED);
+}
+
+/**/
+static void
+setpmgaliases(Param pm, HashTable ht)
+{
+ setaliases(pm, ht, 1, 0);
+}
+
+/**/
+static void
+setpmdisgaliases(Param pm, HashTable ht)
+{
+ setaliases(pm, ht, 1, DISABLED);
+}
+
+/**/
+static HashNode
+getalias(HashTable ht, char *name, int global, int dis)
+{
+ Param pm = NULL;
+ Alias al;
+
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR;
+ pm->sets.cfn = (global ? (dis ? setpmdisgalias : setpmgalias) :
+ (dis ? setpmdisralias : setpmralias));
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = unsetpmalias;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+ if ((al = (Alias) aliastab->getnode2(aliastab, name)) &&
+ ((global && (al->flags & ALIAS_GLOBAL)) ||
+ (!global && !(al->flags & ALIAS_GLOBAL))) &&
+ (dis ? (al->flags & DISABLED) : !(al->flags & DISABLED)))
+ pm->u.str = dupstring(al->text);
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
+ return (HashNode) pm;
+}
+
+/**/
+static HashNode
+getpmralias(HashTable ht, char *name)
+{
+ return getalias(ht, name, 0, 0);
+}
+
+/**/
+static HashNode
+getpmdisralias(HashTable ht, char *name)
+{
+ return getalias(ht, name, 0, 0);
+}
+
+/**/
+static HashNode
+getpmgalias(HashTable ht, char *name)
+{
+ return getalias(ht, name, 1, 0);
+}
+
+/**/
+static HashNode
+getpmdisgalias(HashTable ht, char *name)
+{
+ return getalias(ht, name, 1, DISABLED);
+}
+
+/**/
+static void
+scanaliases(HashTable ht, ScanFunc func, int flags, int global, int dis)
+{
+ struct param pm;
+ int i;
+ HashNode hn;
+ Alias al;
+
+ pm.flags = PM_SCALAR;
+ pm.sets.cfn = (global ? (dis ? setpmdisgalias : setpmgalias) :
+ (dis ? setpmdisralias : setpmralias));
+ pm.gets.cfn = strgetfn;
+ pm.unsetfn = unsetpmalias;
+ pm.ct = 0;
+ pm.env = NULL;
+ pm.ename = NULL;
+ pm.old = NULL;
+ pm.level = 0;
+
+ for (i = 0; i < aliastab->hsize; i++)
+ for (hn = aliastab->nodes[i]; hn; hn = hn->next) {
+ if (((global && ((al = (Alias) hn)->flags & ALIAS_GLOBAL)) ||
+ (!global && !((al = (Alias) hn)->flags & ALIAS_GLOBAL))) &&
+ (dis ? (al->flags & DISABLED) : !(al->flags & DISABLED))) {
+ pm.nam = hn->nam;
+ if (func != scancountparams &&
+ ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS)))
+ pm.u.str = dupstring(al->text);
+ func((HashNode) &pm, flags);
+ }
+ }
+}
+
+/**/
+static void
+scanpmraliases(HashTable ht, ScanFunc func, int flags)
+{
+ scanaliases(ht, func, flags, 0, 0);
+}
+
+/**/
+static void
+scanpmdisraliases(HashTable ht, ScanFunc func, int flags)
+{
+ scanaliases(ht, func, flags, 0, DISABLED);
+}
+
+/**/
+static void
+scanpmgaliases(HashTable ht, ScanFunc func, int flags)
+{
+ scanaliases(ht, func, flags, 1, 0);
+}
+
+/**/
+static void
+scanpmdisgaliases(HashTable ht, ScanFunc func, int flags)
+{
+ scanaliases(ht, func, flags, 1, DISABLED);
+}
+
+/* Table for defined parameters. */
+
+struct pardef {
+ char *name;
+ int flags;
+ GetNodeFunc getnfn;
+ ScanTabFunc scantfn;
+ void (*hsetfn) _((Param, HashTable));
+ void (*setfn) _((Param, char **));
+ char **(*getfn) _((Param));
+ void (*unsetfn) _((Param, int));
+ Param pm;
+};
+
+static struct pardef partab[] = {
+ { "parameters", PM_READONLY,
+ getpmparameter, scanpmparameters, hashsetfn,
+ NULL, NULL, stdunsetfn, NULL },
+ { "commands", 0,
+ getpmcommand, scanpmcommands, setpmcommands,
+ NULL, NULL, stdunsetfn, NULL },
+ { "functions", 0,
+ getpmfunction, scanpmfunctions, setpmfunctions,
+ NULL, NULL, stdunsetfn, NULL },
+ { "dis_functions", 0,
+ getpmdisfunction, scanpmdisfunctions, setpmdisfunctions,
+ NULL, NULL, stdunsetfn, NULL },
+ { "funcstack", PM_ARRAY|PM_SPECIAL|PM_READONLY,
+ NULL, NULL, NULL,
+ arrsetfn, funcstackgetfn, stdunsetfn, NULL },
+ { "builtins", PM_READONLY,
+ getpmbuiltin, scanpmbuiltins, hashsetfn,
+ NULL, NULL, stdunsetfn, NULL },
+ { "dis_builtins", PM_READONLY,
+ getpmdisbuiltin, scanpmdisbuiltins, hashsetfn,
+ NULL, NULL, stdunsetfn, NULL },
+ { "reswords", PM_ARRAY|PM_SPECIAL|PM_READONLY,
+ NULL, NULL, NULL,
+ arrsetfn, reswordsgetfn, stdunsetfn, NULL },
+ { "dis_reswords", PM_ARRAY|PM_SPECIAL|PM_READONLY,
+ NULL, NULL, NULL,
+ arrsetfn, disreswordsgetfn, stdunsetfn, NULL },
+ { "options", 0,
+ getpmoption, scanpmoptions, setpmoptions,
+ NULL, NULL, stdunsetfn, NULL },
+ { "modules", PM_READONLY,
+ getpmmodule, scanpmmodules, hashsetfn,
+ NULL, NULL, stdunsetfn, NULL },
+ { "dirstack", PM_ARRAY|PM_SPECIAL|PM_REMOVABLE,
+ NULL, NULL, NULL,
+ dirssetfn, dirsgetfn, stdunsetfn, NULL },
+ { "history", PM_READONLY,
+ getpmhistory, scanpmhistory, hashsetfn,
+ NULL, NULL, stdunsetfn, NULL },
+ { "historywords", PM_ARRAY|PM_SPECIAL|PM_READONLY,
+ NULL, NULL, NULL,
+ arrsetfn, histwgetfn, stdunsetfn, NULL },
+ { "jobtexts", PM_READONLY,
+ getpmjobtext, scanpmjobtexts, hashsetfn,
+ NULL, NULL, stdunsetfn, NULL },
+ { "jobstates", PM_READONLY,
+ getpmjobstate, scanpmjobstates, hashsetfn,
+ NULL, NULL, stdunsetfn, NULL },
+ { "jobdirs", PM_READONLY,
+ getpmjobdir, scanpmjobdirs, hashsetfn,
+ NULL, NULL, stdunsetfn, NULL },
+ { "nameddirs", 0,
+ getpmnameddir, scanpmnameddirs, setpmnameddirs,
+ NULL, NULL, stdunsetfn, NULL },
+ { "userdirs", PM_READONLY,
+ getpmuserdir, scanpmuserdirs, hashsetfn,
+ NULL, NULL, stdunsetfn, NULL },
+ { "aliases", 0,
+ getpmralias, scanpmraliases, setpmraliases,
+ NULL, NULL, stdunsetfn, NULL },
+ { "galiases", 0,
+ getpmgalias, scanpmgaliases, setpmgaliases,
+ NULL, NULL, stdunsetfn, NULL },
+ { "dis_aliases", 0,
+ getpmdisralias, scanpmdisraliases, setpmdisraliases,
+ NULL, NULL, stdunsetfn, NULL },
+ { "dis_galiases", 0,
+ getpmdisgalias, scanpmdisgaliases, setpmdisgaliases,
+ NULL, NULL, stdunsetfn, NULL },
+ { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+};
/**/
int
-setup_parameter(Module m)
+setup_(Module m)
{
+ incleanup = 0;
+
return 0;
}
/**/
int
-boot_parameter(Module m)
+boot_(Module m)
{
/* Create the special associative arrays.
* As an example for autoloaded parameters, this is probably a bad
- * example, because we the zsh core doesn't support creation of
+ * example, because the zsh core doesn't support creation of
* special hashes, yet. */
- unsetparam(PAR_NAM);
- if (!(parpm = createspecialhash(PAR_NAM, getpmparameter,
- scanpmparameters)))
- return 1;
- parpm->flags |= PM_READONLY;
- unsetparam(CMD_NAM);
- if (!(cmdpm = createspecialhash(CMD_NAM, getpmcommand,
- scanpmcommands)))
- return 1;
- cmdpm->sets.hfn = setpmcommands;
- unsetparam(FUN_NAM);
- if (!(funpm = createspecialhash(FUN_NAM, getpmfunction,
- scanpmfunctions)))
- return 1;
- funpm->sets.hfn = setpmfunctions;
- unsetparam(OPT_NAM);
- if (!(optpm = createspecialhash(OPT_NAM, getpmoption,
- scanpmoptions)))
- return 1;
- optpm->sets.hfn = setpmoptions;
+ struct pardef *def;
+ for (def = partab; def->name; def++) {
+ unsetparam(def->name);
+
+ if (def->getnfn) {
+ if (!(def->pm = createspecialhash(def->name, def->getnfn,
+ def->scantfn)))
+ return 1;
+ def->pm->flags |= def->flags;
+ if (def->hsetfn)
+ def->pm->sets.hfn = def->hsetfn;
+ } else {
+ if (!(def->pm = createparam(def->name, def->flags | PM_HIDE |
+ PM_REMOVABLE)))
+ return 1;
+ def->pm->sets.afn = def->setfn;
+ def->pm->gets.afn = def->getfn;
+ def->pm->unsetfn = def->unsetfn;
+ }
+ }
return 0;
}
-#ifdef MODULE
-
/**/
int
-cleanup_parameter(Module m)
+cleanup_(Module m)
{
Param pm;
+ struct pardef *def;
- /* Remove the special parameters if they are still the same. */
+ incleanup = 1;
- if ((pm = (Param) paramtab->getnode(paramtab, PAR_NAM)) && pm == parpm) {
- pm->flags &= ~PM_READONLY;
- unsetparam_pm(pm, 0, 1);
+ for (def = partab; def->name; def++) {
+ if ((pm = (Param) paramtab->getnode(paramtab, def->name)) &&
+ pm == def->pm) {
+ pm->flags &= ~PM_READONLY;
+ unsetparam_pm(pm, 0, 1);
+ }
}
- if ((pm = (Param) paramtab->getnode(paramtab, CMD_NAM)) && pm == cmdpm)
- unsetparam_pm(pm, 0, 1);
- if ((pm = (Param) paramtab->getnode(paramtab, FUN_NAM)) && pm == funpm)
- unsetparam_pm(pm, 0, 1);
- if ((pm = (Param) paramtab->getnode(paramtab, OPT_NAM)) && pm == optpm)
- unsetparam_pm(pm, 0, 1);
return 0;
}
/**/
int
-finish_parameter(Module m)
+finish_(Module m)
{
return 0;
}
-
-#endif