1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-01-01 05:16:05 +01:00

Initial revision

This commit is contained in:
Tanaka Akira 1999-05-19 13:10:53 +00:00
parent 5d0a0edcca
commit ba1bd66d5f
3 changed files with 714 additions and 0 deletions

49
Doc/Zsh/mod_parameter.yo Normal file
View file

@ -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()

662
Src/Modules/parameter.c Normal file
View file

@ -0,0 +1,662 @@
/*
* 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 = pm->old ? locallevel : 0;
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 = NULL;
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;
}
DPUTS(!val, "BUG: type not handled in parameter");
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) {
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)
{
return 0;
}
#endif

View file

@ -0,0 +1,3 @@
autoparams="parameters commands functions options"
objects="parameter.o"