zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: parameter module
@ 1999-09-16 12:15 Sven Wischnowsky
  0 siblings, 0 replies; 3+ messages in thread
From: Sven Wischnowsky @ 1999-09-16 12:15 UTC (permalink / raw)
  To: zsh-workers


This adds the `dirstack' and `modules' special parameters. The first
one is a normal array containing the directory stack entries. The
latter is more interesting. It's an assoc array with the names of
modules as keys. The values are `builtin', `loaded', and
`autoloaded'. So we could use tests like `if (( $+modules[stat] )) ...'
to find out if a module is in some way usable (even if it still needs
to be loaded). I could easily change the value from the simple
`autoloaded' to a string containing descriptions of the things on
which the module would be autoloaded. I'd like to hear if you think
this is useful enough to implement (and suggestions for the syntax if
you have any).

Also I wanted to ask (before 3.1.6 was released, actually) if the
special parameters from the `parameter' module should be renamed to
`z*'. Or is it too late now?

Ok, if anyone has other ideas for what could be made accessible in the 
module, let me know (the only other thing I could think of are the
limits, but I'm not sure if that's worth it).

Oh, and none of this is used in the completion functions, yet.

Bye
 Sven

diff -u od/Zsh/mod_parameter.yo Doc/Zsh/mod_parameter.yo
--- od/Zsh/mod_parameter.yo	Thu Sep 16 07:31:12 1999
+++ Doc/Zsh/mod_parameter.yo	Thu Sep 16 10:40:15 1999
@@ -46,4 +46,19 @@
 .
 Setting or unsetting keys in this array is not possible.
 )
+vindex(modules)
+item(tt(modules))(
+An association giving information about module. The keys are the names
+of the modules builtin, loaded, or registered to be autoloaded. The
+value says which state the named module is in and is one of the
+strings tt(builtin), tt(loaded), or tt(autoloaded).
+
+Setting or unsetting keys in this array is not possible.
+)
+vindex(dirstack)
+item(tt(dirstack))(
+A normal array holding the elements of the directory stack. Note that
+the output of the tt(dirs) builtin command includes one more
+directory, the current working directory.
+)
 enditem()
diff -u -r os/Modules/parameter.c Src/Modules/parameter.c
--- os/Modules/parameter.c	Thu Sep 16 10:46:37 1999
+++ Src/Modules/parameter.c	Thu Sep 16 10:27:56 1999
@@ -596,14 +596,216 @@
 	}
 }
 
+/* Functions for the modules special parameter. */
+
+static char *modpmname;
+static int modpmfound;
+
+/**/
+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;
+
+    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;
+
+	for (node = firstnode(bltinmodules); node; incnode(node))
+	    if (!strcmp(name, (char *) getdata(node))) {
+		type = "builtin";
+		break;
+	    }
+#ifdef DYNAMIC
+	if (!type) {
+	    Module m;
+
+	    for (node = firstnode(modules); node; incnode(node)) {
+		m = (Module) getdata(node);
+		if (m->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";
+	}
+#endif
+	if (type)
+	    pm->u.str = type;
+	else {
+	    pm->u.str = "";
+	    pm->flags |= PM_UNSET;
+	}
+    } LASTALLOC;
+
+    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;
+
+    for (node = firstnode(bltinmodules); node; incnode(node)) {
+	pm.nam = (char *) getdata(node);
+	addlinknode(done, pm.nam);
+	pm.u.str = "builtin";
+	func((HashNode) &pm, flags);
+    }
+#ifdef DYNAMIC
+    for (node = firstnode(modules); node; incnode(node)) {
+	m = (Module) getdata(node);
+	if (m->handle && !(m->flags & MOD_UNLOAD)) {
+	    pm.nam = m->nam;
+	    addlinknode(done, pm.nam);
+	    pm.u.str = "loaded";
+	    func((HashNode) &pm, flags);
+	}
+    }
+    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);
+		pm.u.str = "autoloaded";
+		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);
+	    pm.u.str = "autoloaded";
+	    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);
+		pm.u.str = "autoloaded";
+		func((HashNode) &pm, flags);
+	    }
+	}
+#endif
+}
+
+/* Functions for the dirstack special parameter. */
+
+static void
+dirssetfn(Param pm, char **x)
+{
+    PERMALLOC {
+	freelinklist(dirstack, freestr);
+	dirstack = newlinklist();
+	while (*x)
+	    addlinknode(dirstack, ztrdup(*x++));
+    } LASTALLOC;
+}
+
+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;
+}
+
 /* Names and Params for the special parameters. */
 
 #define PAR_NAM "parameters"
 #define CMD_NAM "commands"
 #define FUN_NAM "functions"
 #define OPT_NAM "options"
+#define MOD_NAM "modules"
+#define DIR_NAM "dirstack"
 
-static Param parpm, cmdpm, funpm, optpm;
+static Param parpm, cmdpm, funpm, optpm, modpm, dirpm;
 
 /**/
 int
@@ -618,7 +820,7 @@
 {
     /* 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);
@@ -641,6 +843,18 @@
 				    scanpmoptions)))
 	return 1;
     optpm->sets.hfn = setpmoptions;
+    unsetparam(MOD_NAM);
+    if (!(modpm = createspecialhash(MOD_NAM, getpmmodule,
+				    scanpmmodules)))
+	return 1;
+    modpm->flags |= PM_READONLY;
+    unsetparam(DIR_NAM);
+    if (!(dirpm = createparam(DIR_NAM,
+			      PM_ARRAY|PM_HIDE|PM_SPECIAL|PM_REMOVABLE)))
+	return 1;
+    dirpm->sets.afn = dirssetfn;
+    dirpm->gets.afn = dirsgetfn;
+    dirpm->unsetfn = stdunsetfn;
 
     return 0;
 }
@@ -664,6 +878,12 @@
     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);
+    if ((pm = (Param) paramtab->getnode(paramtab, MOD_NAM)) && pm == modpm) {
+	pm->flags &= ~PM_READONLY;
+	unsetparam_pm(pm, 0, 1);
+    }
+    if ((pm = (Param) paramtab->getnode(paramtab, DIR_NAM)) && pm == dirpm)
 	unsetparam_pm(pm, 0, 1);
     return 0;
 }
diff -u -r os/Modules/parameter.mdd Src/Modules/parameter.mdd
--- os/Modules/parameter.mdd	Thu Sep 16 10:46:42 1999
+++ Src/Modules/parameter.mdd	Thu Sep 16 10:47:02 1999
@@ -1,3 +1,3 @@
-autoparams="parameters commands functions options"
+autoparams="parameters commands functions options modules dirstack"
 
 objects="parameter.o"

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 3+ messages in thread

* PATCH: parameter module
@ 1999-05-15 14:40 Peter Stephenson
  0 siblings, 0 replies; 3+ messages in thread
From: Peter Stephenson @ 1999-05-15 14:40 UTC (permalink / raw)
  To: Zsh hackers list

I spotted some problems with the parameter module.

1. If you call zmodload from a function, the parameters got loaded into
local scope.  Since I use a function load() which calls zmodload, this
confused me.  As the scope of the zmodload is not local, and there is no
typeset to make them appear in local scope, I presume this was not the
intention, but maybe I was wrong.  It might be possible to do some typeset
trickery so that `typeset parameters' gets the parameters special variable
loaded into local scope.  At the moment, I shudder to think what effect
this has(*), but I put a debugging test in createparam() for parameters
that didn't get deleted properly from a local scope.

(*) I thought createparam() was supposed to fail if you did this, and hence
createspecialparam() also, but that doesn't seem to happen.  I don't dare
look at this in case it's a bug.

2. When unloading, $parameters was readonly and complained about it.

3. Trivial fix for a compiler warning about unitialized variables.  I also
added a debugging check for unhandled parameter types:  you never know when
someone's going to change the shell and forget the parameter module.

--- Src/Modules/parameter.c.pm	Thu May 13 17:45:44 1999
+++ Src/Modules/parameter.c	Sat May 15 16:19:37 1999
@@ -50,7 +50,7 @@
     if (!(pm = createparam(name, PM_SPECIAL|PM_REMOVABLE|PM_HASHED)))
 	return NULL;
 
-    pm->level = locallevel;
+    pm->level = pm->old ? locallevel : 0;
     pm->gets.hfn = hashgetfn;
     pm->sets.hfn = hashsetfn;
     pm->unsetfn = stdunsetfn;
@@ -79,7 +79,7 @@
 static char *
 paramtypestr(Param pm)
 {
-    char *val;
+    char *val = NULL;
     int f = pm->flags;
 
     if (!(f & PM_UNSET)) {
@@ -89,6 +89,7 @@
 	case PM_INTEGER: val = "integer"; break;
 	case PM_HASHED:  val = "association"; break;
 	}
+	DPUTS(!val, "BUG: type not handled in parameter");
 	val = dupstring(val);
 	if (f & PM_LEFT)
 	    val = dyncat(val, "-left");
@@ -638,8 +639,10 @@
 
     /* Remove the special parameters if they are still the same. */
 
-    if ((pm = (Param) paramtab->getnode(paramtab, PAR_NAM)) && pm == parpm)
+    if ((pm = (Param) paramtab->getnode(paramtab, PAR_NAM)) && pm == parpm) {
+	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)
--- Src/params.c.pm	Thu May 13 17:45:43 1999
+++ Src/params.c	Sat May 15 16:27:47 1999
@@ -572,6 +572,8 @@
 			 gethashnode2(paramtab, name) :
 			 paramtab->getnode(paramtab, name));
 
+	DPUTS(oldpm && oldpm->level > locallevel,
+	      "BUG:  old local parameter not deleteed");
 	if (oldpm && oldpm->level == locallevel) {
 	    if (!(oldpm->flags & PM_UNSET) || (oldpm->flags & PM_SPECIAL)) {
 		oldpm->flags &= ~PM_UNSET;

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


^ permalink raw reply	[flat|nested] 3+ messages in thread

* PATCH: parameter module
@ 1999-05-12  8:51 Sven Wischnowsky
  0 siblings, 0 replies; 3+ messages in thread
From: Sven Wischnowsky @ 1999-05-12  8:51 UTC (permalink / raw)
  To: zsh-workers


The stuff from 6198 as a module named `parameter', otherwise there's
nothing new (apart from the docs). I tried to change as little as
possible in the core, but some changes were needed. Most notably, the
possibility to define a scanning function in the hashtable structure.

I haven't modified xmods.conf, so this is not automatically autoloaded.

Bye
 Sven

diff -u os/hashtable.c Src/hashtable.c
--- os/hashtable.c	Tue May 11 11:20:53 1999
+++ Src/hashtable.c	Wed May 12 10:33:55 1999
@@ -112,6 +112,7 @@
     ht->hsize = size;
     ht->ct = 0;
     ht->scan = NULL;
+    ht->scantab = NULL;
     return ht;
 }
 
@@ -361,6 +362,10 @@
 {
     struct scanstatus st;
 
+    if (ht->scantab) {
+	ht->scantab(ht, scanfunc, scanflags);
+	return;
+    }
     if (sorted) {
 	int i, ct = ht->ct;
 	VARARR(HashNode, hnsorttab, ct);
diff -u os/options.c Src/options.c
--- os/options.c	Sat May  8 16:37:10 1999
+++ Src/options.c	Wed May 12 09:13:48 1999
@@ -45,15 +45,6 @@
 /**/
 HashTable optiontab;
  
-typedef struct optname *Optname;
-
-struct optname {
-    HashNode next;		/* next in hash chain */
-    char *nam;			/* hash data */
-    int flags;
-    int optno;			/* option number */
-};
-
 /* The canonical option name table */
 
 #define OPT_CSH		EMULATE_CSH
diff -u os/params.c Src/params.c
--- os/params.c	Sat May  8 15:06:04 1999
+++ Src/params.c	Wed May 12 09:23:24 1999
@@ -334,7 +334,7 @@
 static unsigned numparamvals;
 
 /**/
-static void
+void
 scancountparams(HashNode hn, int flags)
 {
     ++numparamvals;
@@ -346,7 +346,7 @@
 static char **paramvals;
 
 /**/
-static void
+void
 scanparamvals(HashNode hn, int flags)
 {
     struct value v;
@@ -1859,7 +1859,7 @@
 /* Function to get value of an association parameter */
 
 /**/
-static HashTable
+HashTable
 hashgetfn(Param pm)
 {
     return pm->u.hash;
@@ -1872,7 +1872,7 @@
 /* Function to set value of an association parameter */
 
 /**/
-static void
+void
 hashsetfn(Param pm, HashTable x)
 {
     if (pm->u.hash && pm->u.hash != x) {
diff -u os/zsh.h Src/zsh.h
--- os/zsh.h	Tue May 11 14:54:58 1999
+++ Src/zsh.h	Wed May 12 09:13:53 1999
@@ -228,6 +228,7 @@
 typedef struct hashnode  *HashNode;
 typedef struct hashtable *HashTable;
 
+typedef struct optname   *Optname;
 typedef struct reswd     *Reswd;
 typedef struct alias     *Alias;
 typedef struct param     *Param;
@@ -685,6 +686,7 @@
 /* type of function that is passed to *
  * scanhashtable or scanmatchtable    */
 typedef void     (*ScanFunc)       _((HashNode, int));
+typedef void     (*ScanTabFunc)    _((HashTable, ScanFunc, int));
 
 typedef void (*PrintTableStats) _((HashTable));
 
@@ -710,6 +712,7 @@
     ScanFunc enablenode;	/* pointer to function to enable a node       */
     FreeNodeFunc freenode;	/* pointer to function to free a node         */
     ScanFunc printnode;		/* pointer to function to print a node        */
+    ScanTabFunc scantab;	/* pointer to function to scan table          */
 
 #ifdef HASHTABLE_INTERNAL_MEMBERS
     HASHTABLE_INTERNAL_MEMBERS	/* internal use in hashtable.c                */
@@ -728,6 +731,15 @@
  * you can disable builtins, shell functions, aliases and *
  * reserved words.                                        */
 #define DISABLED	(1<<0)
+
+/* node in shell option table */
+
+struct optname {
+    HashNode next;		/* next in hash chain */
+    char *nam;			/* hash data */
+    int flags;
+    int optno;			/* option number */
+};
 
 /* node in shell reserved word hash table (reswdtab) */
 
diff -u os/Modules/parameter.c Src/Modules/parameter.c
--- os/Modules/parameter.c	Wed May 12 10:32:53 1999
+++ Src/Modules/parameter.c	Wed May 12 10:03:46 1999
@@ -0,0 +1,659 @@
+/*
+ * parameter.c - parameter interface to zsh internals
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 1999 Sven Wischnowsky
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Sven Wischnowsky or the Zsh Development Group be liable
+ * to any party for direct, indirect, special, incidental, or consequential
+ * damages arising out of the use of this software and its documentation,
+ * even if Sven Wischnowsky and the Zsh Development Group have been advised of
+ * the possibility of such damage.
+ *
+ * Sven Wischnowsky and the Zsh Development Group specifically disclaim any
+ * warranties, including, but not limited to, the implied warranties of
+ * merchantability and fitness for a particular purpose.  The software
+ * provided hereunder is on an "as is" basis, and Sven Wischnowsky and the
+ * Zsh Development Group have no obligation to provide maintenance,
+ * support, updates, enhancements, or modifications.
+ *
+ */
+
+#include "parameter.mdh"
+#include "parameter.pro"
+
+/* Empty dummy function for special hash parameters. */
+
+/**/
+static void
+shempty(void)
+{
+}
+
+/* Create a simple special hash parameter. */
+
+/**/
+static Param
+createspecialhash(char *name, GetNodeFunc get, ScanTabFunc scan)
+{
+    Param pm;
+    HashTable ht;
+
+    if (!(pm = createparam(name, PM_SPECIAL|PM_REMOVABLE|PM_HASHED)))
+	return NULL;
+
+    pm->level = locallevel;
+    pm->gets.hfn = hashgetfn;
+    pm->sets.hfn = hashsetfn;
+    pm->unsetfn = stdunsetfn;
+    pm->u.hash = ht = newhashtable(7, name, NULL);
+
+    ht->hash        = hasher;
+    ht->emptytable  = (TableFunc) shempty;
+    ht->filltable   = NULL;
+    ht->addnode     = (AddNodeFunc) shempty;
+    ht->getnode     = ht->getnode2 = get;
+    ht->removenode  = (RemoveNodeFunc) shempty;
+    ht->disablenode = NULL;
+    ht->enablenode  = NULL;
+    ht->freenode    = (FreeNodeFunc) shempty;
+    ht->printnode   = printparamnode;
+    ht->scantab     = scan;
+
+    return pm;
+}
+
+/* Functions for the parameters special parameter. */
+
+/* Return a string describing the type of a parameter. */
+
+/**/
+static char *
+paramtypestr(Param pm)
+{
+    char *val;
+    int f = pm->flags;
+
+    if (!(f & PM_UNSET)) {
+	switch (PM_TYPE(f)) {
+	case PM_SCALAR:  val = "scalar"; break;
+	case PM_ARRAY:   val = "array"; break;
+	case PM_INTEGER: val = "integer"; break;
+	case PM_HASHED:  val = "association"; break;
+	}
+	val = dupstring(val);
+	if (f & PM_LEFT)
+	    val = dyncat(val, "-left");
+	if (f & PM_RIGHT_B)
+	    val = dyncat(val, "-right_blanks");
+	if (f & PM_RIGHT_Z)
+	    val = dyncat(val, "-right_zeros");
+	if (f & PM_LOWER)
+	    val = dyncat(val, "-lower");
+	if (f & PM_UPPER)
+	    val = dyncat(val, "-upper");
+	if (f & PM_READONLY)
+	    val = dyncat(val, "-readonly");
+	if (f & PM_TAGGED)
+	    val = dyncat(val, "-tag");
+	if (f & PM_EXPORTED)
+	    val = dyncat(val, "-export");
+	if (f & PM_UNIQUE)
+	    val = dyncat(val, "-unique");
+    } else
+	val = dupstring("");
+
+    return val;
+}
+
+/**/
+static HashNode
+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;
+
+    return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmparameters(HashTable ht, ScanFunc func, int flags)
+{
+    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 < realparamtab->hsize; i++)
+	for (hn = realparamtab->nodes[i]; hn; hn = hn->next) {
+	    pm.nam = hn->nam;
+	    if (func != scancountparams)
+		pm.u.str = paramtypestr((Param) hn);
+	    func((HashNode) &pm, flags);
+	}
+}
+
+/* Functions for the commands special parameter. */
+
+/**/
+static void
+setpmcommand(Param pm, char *value)
+{
+    if (isset(RESTRICTED))
+	zwarnnam(NULL, "restricted: %s", value, 0);
+    else {
+	Cmdnam cn = zcalloc(sizeof(*cn));
+
+	cn->flags = HASHED;
+	cn->u.cmd = ztrdup(value);
+
+	cmdnamtab->addnode(cmdnamtab, ztrdup(pm->nam), (HashNode) cn);
+    }
+}
+
+/**/
+static void
+unsetpmcommand(Param pm, int exp)
+{
+    HashNode hn = cmdnamtab->removenode(cmdnamtab, pm->nam);
+
+    if (hn)
+	cmdnamtab->freenode(hn);
+}
+
+/**/
+static void
+setpmcommands(Param pm, HashTable ht)
+{
+    int i;
+    HashNode hn;
+
+    for (i = 0; i < ht->hsize; i++)
+	for (hn = ht->nodes[i]; hn; hn = hn->next) {
+	    Cmdnam cn = zcalloc(sizeof(*cn));
+	    struct value v;
+
+	    v.isarr = v.inv = v.a = 0;
+	    v.b = -1;
+	    v.arr = NULL;
+	    v.pm = (Param) hn;
+
+	    cn->flags = HASHED;
+	    cn->u.cmd = ztrdup(getstrvalue(&v));
+
+	    cmdnamtab->addnode(cmdnamtab, ztrdup(hn->nam), (HashNode) cn);
+	}
+}
+
+/**/
+static HashNode
+getpmcommand(HashTable ht, char *name)
+{
+    Cmdnam cmd;
+    Param pm = NULL;
+
+    if (!(cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name)) &&
+	isset(HASHLISTALL)) {
+	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;
+	}
+    } LASTALLOC;
+
+    return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmcommands(HashTable ht, ScanFunc func, int flags)
+{
+    struct param pm;
+    int i;
+    HashNode hn;
+    Cmdnam cmd;
+
+    if (isset(HASHLISTALL))
+	cmdnamtab->filltable(cmdnamtab);
+
+    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;
+
+    for (i = 0; i < cmdnamtab->hsize; i++)
+	for (hn = cmdnamtab->nodes[i]; hn; hn = hn->next) {
+	    pm.nam = hn->nam;
+	    cmd = (Cmdnam) hn;
+	    if (func != scancountparams) {
+		if (cmd->flags & HASHED)
+		    pm.u.str = cmd->u.cmd;
+		else {
+		    pm.u.str = zhalloc(strlen(*(cmd->u.name)) +
+				       strlen(cmd->nam) + 2);
+		    strcpy(pm.u.str, *(cmd->u.name));
+		    strcat(pm.u.str, "/");
+		    strcat(pm.u.str, cmd->nam);
+		}
+	    }
+	    func((HashNode) &pm, flags);
+	}
+}
+
+/* Functions for the functions special parameter. */
+
+/**/
+static void
+setfunction(char *name, char *value)
+{
+    char *val;
+    Shfunc shf;
+    List list;
+    int sn;
+
+    val = ztrdup(value);
+    val = metafy(val, strlen(val), META_REALLOC);
+
+    HEAPALLOC {
+	list = parse_string(val);
+    } LASTALLOC;
+
+    if (!list || list == &dummy_list) {
+	zwarnnam(NULL, "invalid function definition", val, 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;
+	}
+	shfunctab->addnode(shfunctab, ztrdup(name), shf);
+    } LASTALLOC;
+
+    zsfree(val);
+}
+
+/**/
+static void
+setpmfunction(Param pm, char *value)
+{
+    setfunction(pm->nam, value);
+}
+
+/**/
+static void
+unsetpmfunction(Param pm, int exp)
+{
+    HashNode hn = shfunctab->removenode(shfunctab, pm->nam);
+
+    if (hn)
+	shfunctab->freenode(hn);
+}
+
+/**/
+static void
+setpmfunctions(Param pm, HashTable ht)
+{
+    int i;
+    HashNode hn;
+
+    for (i = 0; i < ht->hsize; i++)
+	for (hn = ht->nodes[i]; hn; hn = hn->next) {
+	    struct value v;
+
+	    v.isarr = v.inv = v.a = 0;
+	    v.b = -1;
+	    v.arr = NULL;
+	    v.pm = (Param) hn;
+
+	    setfunction(hn->nam, getstrvalue(&v));
+	}
+}
+
+/**/
+static HashNode
+getpmfunction(HashTable ht, char *name)
+{
+    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;
+	    }
+	} else {
+	    pm->u.str = "";
+	    pm->flags |= PM_UNSET;
+	}
+    } LASTALLOC;
+
+    return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmfunctions(HashTable ht, ScanFunc func, int flags)
+{
+    struct param pm;
+    int i;
+    HashNode hn;
+
+    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;
+
+    for (i = 0; i < shfunctab->hsize; i++)
+	for (hn = shfunctab->nodes[i]; hn; hn = hn->next) {
+	    if (!(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);
+			zsfree(t);
+		    }
+		}
+		func((HashNode) &pm, flags);
+	    }
+	}
+}
+
+/* Functions for the options special parameter. */
+
+/**/
+static void
+setpmoption(Param pm, char *value)
+{
+    int n;
+
+    if (!value || (strcmp(value, "on") && strcmp(value, "off")))
+	zwarnnam(NULL, "invalid value: %s", value, 0);
+    else if (!(n = optlookup(pm->nam)))
+	zwarnnam(NULL, "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);
+}
+
+/**/
+static void
+unsetpmoption(Param pm, int exp)
+{
+    int n;
+
+    if (!(n = optlookup(pm->nam)))
+	zwarnnam(NULL, "no such option: %s", pm->nam, 0);
+    else if (dosetopt(n, 0, 0))
+	zwarnnam(NULL, "can't change option: %s", pm->nam, 0);
+}
+
+/**/
+static void
+setpmoptions(Param pm, HashTable ht)
+{
+    int i;
+    HashNode hn;
+
+    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;
+
+	    val = getstrvalue(&v);
+	    if (!val || (strcmp(val, "on") && strcmp(val, "off")))
+		zwarnnam(NULL, "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);
+	}
+}
+
+/**/
+static HashNode
+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;
+
+    return (HashNode) pm;
+}
+
+/**/
+static void
+scanpmoptions(HashTable ht, ScanFunc func, int flags)
+{
+    struct param pm;
+    int i;
+    HashNode hn;
+
+    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;
+
+    for (i = 0; i < optiontab->hsize; i++)
+	for (hn = optiontab->nodes[i]; hn; hn = hn->next) {
+	    pm.nam = hn->nam;
+	    pm.u.str = opts[((Optname) hn)->optno] ? "on" : "off";
+	    func((HashNode) &pm, flags);
+	}
+}
+
+/* Names and Params for the special parameters. */
+
+#define PAR_NAM "parameters"
+#define CMD_NAM "commands"
+#define FUN_NAM "functions"
+#define OPT_NAM "options"
+
+static Param parpm, cmdpm, funpm, optpm;
+
+/**/
+int
+setup_parameter(Module m)
+{
+    return 0;
+}
+
+/**/
+int
+boot_parameter(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
+     * 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;
+
+    return 0;
+}
+
+#ifdef MODULE
+
+/**/
+int
+cleanup_parameter(Module m)
+{
+    Param pm;
+
+    /* Remove the special parameters if they are still the same. */
+
+    if ((pm = (Param) paramtab->getnode(paramtab, PAR_NAM)) && pm == parpm)
+	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)
+{
+    return 0;
+}
+
+#endif
diff -u os/Modules/parameter.mdd Src/Modules/parameter.mdd
--- os/Modules/parameter.mdd	Wed May 12 10:32:53 1999
+++ Src/Modules/parameter.mdd	Wed May 12 09:09:50 1999
@@ -0,0 +1,3 @@
+autoparams="parameters commands functions options"
+
+objects="parameter.o"
diff -u od/Zsh/mod_files.yo Doc/Zsh/mod_files.yo
--- od/Zsh/mod_files.yo	Sat Oct 17 20:56:48 1998
+++ Doc/Zsh/mod_files.yo	Wed May 12 10:10:38 1999
@@ -1,4 +1,4 @@
-texinode(The files Module)(The sched Module)(The example Module)(Zsh Modules)
+texinode(The files Module)(The parameter Module)(The example Module)(Zsh Modules)
 sect(The files Module)
 cindex(files, manipulating)
 The tt(files) module makes some standard commands available as builtins:
diff -u od/Zsh/mod_parameter.yo Doc/Zsh/mod_parameter.yo
--- od/Zsh/mod_parameter.yo	Wed May 12 10:33:07 1999
+++ Doc/Zsh/mod_parameter.yo	Wed May 12 10:44:50 1999
@@ -0,0 +1,49 @@
+texinode(The parameter Module)(The sched Module)(The files Module)(Zsh Modules)
+sect(The parameter Module)
+cindex(parameters, special)
+The tt(parameter) module gives access to some of the internal hash
+tables used by the shell, by defining four special associative arrays.
+
+startitem()
+vindex(options)
+item(tt(options))(
+The keys for this associative array are the names of the options that
+can be set and unset using the tt(setopt) and tt(unsetopt)
+builtins. The value of each key is either the string tt(on) if the
+option is currently set, or the string tt(off) if the option is unset.
+Setting a key to one of these strings is like setting or unsetting
+the option, respectively. Unsetting a key in this array is like
+setting it to the value tt(off).
+)
+vindex(commands)
+item(tt(command))(
+This array gives access to the command hash table. The keys are the
+names of external commands, the values are the pathnames of the files
+that would be executed when the command would be invoked. Setting a
+key in this array defines a new entry in this table in the same way as
+with the tt(hash) builtin. Unsetting a key as in `tt(unset
+"commands[foo]")' removes the entry for the given key from the command 
+hash table.
+)
+vindex(functions)
+item(tt(functions))(
+This association maps function names to their definitions. Setting a
+key in it is like defining a function with the name given by the key
+and the body given by the value. Unsetting a key removes the
+definition for the function named by the key.
+)
+vindex(parameters)
+item(tt(parameters))(
+The keys in this associative array are the names of the parameters
+currently defined. The values are strings describing the type of the
+parameter, in the same format used by the tt(t) parameter flag, see
+ifzman(\
+zmanref(zshexpn)
+)\
+ifnzman(\
+noderef(Parameter Expansion)
+)\
+.
+Setting or unsetting keys in this array is not possible.
+)
+enditem()
diff -u od/Zsh/mod_sched.yo Doc/Zsh/mod_sched.yo
--- od/Zsh/mod_sched.yo	Thu Jun 12 14:34:16 1997
+++ Doc/Zsh/mod_sched.yo	Wed May 12 10:10:48 1999
@@ -1,4 +1,4 @@
-texinode(The sched Module)(The stat Module)(The files Module)(Zsh Modules)
+texinode(The sched Module)(The stat Module)(The parameter Module)(Zsh Modules)
 sect(The sched Module)
 The tt(sched) module makes available one builtin command:
 
diff -u od/Zsh/modules.yo Doc/Zsh/modules.yo
--- od/Zsh/modules.yo	Tue Apr 13 09:59:04 1999
+++ Doc/Zsh/modules.yo	Wed May 12 10:08:59 1999
@@ -31,6 +31,9 @@
 item(tt(files))(
 Some basic file manipulation commands as builtins.
 )
+item(tt(parameter))(
+Access to internal hash tables via special associative arrays.
+)
 item(tt(sched))(
 A builtin that provides a timed execution facility within the shell.
 )
@@ -52,6 +55,7 @@
 menu(The deltochar Module)
 menu(The example Module)
 menu(The files Module)
+menu(The parameter Module)
 menu(The sched Module)
 menu(The stat Module)
 menu(The zftp Module)
@@ -64,6 +68,7 @@
 includefile(Zsh/mod_deltochar.yo)\x01
 includefile(Zsh/mod_example.yo)\x01
 includefile(Zsh/mod_files.yo)\x01
+includefile(Zsh/mod_parameter.yo)\x01
 includefile(Zsh/mod_sched.yo)\x01
 includefile(Zsh/mod_stat.yo)\x01
 includefile(Zsh/mod_zftp.yo)\x01

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~1999-09-16 12:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-09-16 12:15 PATCH: parameter module Sven Wischnowsky
  -- strict thread matches above, loose matches on Subject: below --
1999-05-15 14:40 Peter Stephenson
1999-05-12  8:51 Sven Wischnowsky

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).