19014: add alias -s suf=handler

This commit is contained in:
Peter Stephenson 2003-09-03 10:15:32 +00:00
parent 716e925312
commit 3ffb3ad2f2
14 changed files with 388 additions and 151 deletions

View file

@ -1,3 +1,14 @@
2003-09-03 Peter Stephenson <pws@csr.com>
* 19014: Completion/Zsh/Command/_alias,
Completion/Zsh/Type/.distfiles, Completion/Zsh/Type/_aliases,
Completion/Zsh/Type/_command_names,
Completion/Zsh/Type/_suffix_alias_files, Doc/Zsh/builtins.yo,
Doc/Zsh/mod_parameter.yo, Src/builtin.c, Src/hashtable.c,
Src/init.c, Src/lex.c, Src/zsh.h, Src/Modules/parameter.c:
add `alias -s suf=cmd' capability to expand `anything.suf'
to `cmd anything.suf'.
2003-08-30 Peter Stephenson <pws@pwstephenson.fsnet.co.uk>
* c.f. somewhat terse reference in zsh-users/6493:

View file

@ -5,6 +5,7 @@ local curcontext="$curcontext" state line suf
_arguments -C -s -A "-*" -S \
'-+g[list or define global aliases]' \
'-+r[list or define regular aliases]' \
'-+s[list or define suffix aliases]' \
'-+m[print aliases matching specified pattern]' \
'-L[print each alias in the form of calls to alias]' \
'*::alias definition:->defn'
@ -18,4 +19,3 @@ if [[ -n "$state" ]]; then
_wanted alias expl 'alias definition' _aliases -S "$suf"
fi
fi

View file

@ -4,4 +4,5 @@ _aliases _file_descriptors _jobs_fg _options_unset
_arrays _functions _limits _parameters
_command_names _jobs _options _vars
_directory_stack _jobs_bg _options_set
_suffix_alias_files
'

View file

@ -4,14 +4,16 @@ local expl sel args opts
zparseopts -E -D s:=sel
[[ -z $sel ]] && sel=rg
[[ -z $sel ]] && sel=rgs
opts=( "$@" )
args=()
[[ $sel = *r* ]] && args=( $args 'aliases:regular alias:compadd -k aliases' )
[[ $sel = *g* ]] && args=( $args 'global-aliases:global alias:compadd -k galiases' )
[[ $sel = *s* ]] && args=( $args 'suffix-aliases:suffix alias:compadd -k saliases' )
[[ $sel = *R* ]] && args=( $args 'disabled-aliases:disabled regular alias:compadd -k dis_aliases' )
[[ $sel = *G* ]] && args=( $args 'disabled-global-aliases:disabled global alias:compadd -k dis_galiases' )
[[ $sel = *S* ]] && args=( $args 'disabled-suffix-aliases:disabled suffix alias:compadd -k dis_saliases' )
_alternative -O opts $args

View file

@ -24,6 +24,7 @@ else
'builtins:builtin command:compadd -k builtins'
'functions:shell function:compadd -k functions'
'aliases:alias:compadd -k aliases'
'suffix-aliases:suffix alias:_suffix_alias_files'
'reserved-words:reserved word:compadd -k reswords'
'jobs:: _jobs -t'
'parameters:: _parameters -g "^*readonly*" -qS= -r "\n\t\- =["'

View file

@ -0,0 +1,21 @@
#autoload
# Complete files for which a suffix alias exists.
local expl pat
(( ${#saliases} )) || return 1
if (( ${#saliases} == 1 )); then
pat="*.${(kq)saliases}"
else
local -a tmpa
# This is so we can quote the alias names against expansion
# without quoting the `|' which needs to be active in the pattern
# --- remember that an alias name can be pretty much anything.
tmpa=(${(kq)saliases})
pat="*.(${(kj.|.)tmpa})"
fi
# _wanted is called for us by _command_names
_path_files "$@" -g $pat

View file

@ -60,23 +60,40 @@ which may have effects on shell parameters. A zero exit code is returned.
findex(alias)
cindex(aliases, defining)
cindex(aliases, listing)
item(tt(alias) [ {tt(PLUS()|tt(-))}tt(gmrL) ] [ var(name)[tt(=)var(value)] ... ])(
item(tt(alias) [ {tt(PLUS()|tt(-))}tt(gmrsL) ] [ var(name)[tt(=)var(value)] ... ])(
For each var(name) with a corresponding var(value), define an alias
with that value. A trailing space in var(value) causes the next word
to be checked for alias expansion. If the tt(-g) flag is present,
define a global alias; global aliases are expanded even if they do not
occur in command position.
If the tt(-s) flags is present, define a suffix alias: if the command
word on a command line is in the form `var(text)tt(.)var(name)', where
var(text) is any non-empty string, it is replaced by the text
`var(value) var(text)tt(.)var(name)'. Note that var(name) is treated as
a literal string, not a pattern. A trailing space in var(value) is not
special in this case. For example,
example(alias -s ps=gv)
will cause the command `tt(*.ps)' to be expanded to `tt(gv *.ps)'. As
alias expansion is carried out earlier than globbing, the `tt(*.ps)' will
then be expanded. Suffix aliases constitute a different name space from
other aliases (so in the above example it is still possible
to create an alias for the command tt(ps)) and the two sets are never
listed together.
For each var(name) with no var(value),
print the value of var(name), if any. With no arguments, print all
currently defined aliases. If the tt(-m) flag is given the arguments
are taken as patterns (they should be quoted to preserve them from being
interpreted as glob patterns), and the aliases matching these patterns
are printed. When printing aliases and the tt(-g) or tt(-r) flags
are present, then restrict the printing to global or regular
aliases, respectively. Using `tt(PLUS())' instead of `tt(-)', or ending
the option list with a single `tt(PLUS())', prevents the values of the
aliases from being printed.
currently defined aliases other than suffix aliases. If the tt(-m) flag
is given the arguments are taken as patterns (they should be quoted to
preserve them from being interpreted as glob patterns), and the aliases
matching these patterns are printed. When printing aliases and one of
the tt(-g), tt(-r) or tt(-s) flags is present, restrict the printing to
global, regular or suffix aliases, respectively; a regular alias is one
which is neither a global nor a suffix alias. Using `tt(PLUS())'
instead of `tt(-)', or ending the option list with a single
`tt(PLUS())', prevents the values of the aliases from being printed.
If the tt(-L) flag is present, then print each
alias in a manner suitable for putting in a startup script. The exit
@ -228,11 +245,12 @@ enditem()
findex(disable)
cindex(disabling commands)
cindex(commands, disabling)
item(tt(disable) [ tt(-afmr) ] var(name) ...)(
item(tt(disable) [ tt(-afmrs) ] var(name) ...)(
Temporarily disable the var(name)d hash table elements. The default
is to disable builtin commands. This allows you to use an external
command with the same name as a builtin command. The tt(-a) option
causes tt(disable) to act on aliases. The tt(-f) option causes
causes tt(disable) to act on regular or global aliases. The tt(-s)
option causes tt(disable) to act on suffix aliases. The tt(-f) option causes
tt(disable) to act on shell functions. The tt(-r) options causes
tt(disable) to act on reserved words. Without arguments all disabled
hash table elements from the corresponding hash table are printed.
@ -323,11 +341,12 @@ modes except tt(ksh).
findex(enable)
cindex(enabling commands)
cindex(commands, enabling)
item(tt(enable) [ tt(-afmr) ] var(name) ...)(
item(tt(enable) [ tt(-afmrs) ] var(name) ...)(
Enable the var(name)d hash table elements, presumably disabled
earlier with tt(disable). The default is to enable builtin commands.
The tt(-a) option causes tt(enable) to act on aliases. The tt(-f)
option causes tt(enable) to act on shell functions. The tt(-r)
The tt(-a) option causes tt(enable) to act on regular or global aliases.
The tt(-s) option causes tt(enable) to act on suffix aliases.
The tt(-f) option causes tt(enable) to act on shell functions. The tt(-r)
option causes tt(enable) to act on reserved words. Without arguments
all enabled hash table elements from the corresponding hash table are
printed. With the tt(-m) flag the arguments are taken as patterns
@ -1380,10 +1399,12 @@ alias(unalias)(unhash -a)
cindex(functions, removing)
alias(unfunction)(unhash -f)
findex(unhash)
item(tt(unhash) [ tt(-adfm) ] var(name) ...)(
item(tt(unhash) [ tt(-adfms) ] var(name) ...)(
Remove the element named var(name) from an internal hash table. The
default is remove elements from the command hash table. The tt(-a)
option causes tt(unhash) to remove aliases. The tt(-f) option causes
option causes tt(unhash) to remove regular or global aliases.
The tt(-s) option causes tt(unhash) to remove suffix aliases.
The tt(-f) option causes
tt(unhash) to remove shell functions. The tt(-d) options causes
tt(unhash) to remove named directories. If the tt(-m) flag is given
the arguments are taken as patterns (should be quoted) and all elements

View file

@ -64,16 +64,24 @@ expansions.
)
vindex(dis_aliases)
item(tt(dis_aliases))(
Like tt(raliases) but for disabled regular aliases.
Like tt(aliases) but for disabled regular aliases.
)
vindex(galiases)
item(tt(galiases))(
Like tt(raliases), but for global aliases.
Like tt(aliases), but for global aliases.
)
vindex(dis_galiases)
item(tt(dis_galiases))(
Like tt(galiases) but for disabled global aliases.
)
vindex(saliases)
item(tt(saliases))(
Like tt(raliases), but for suffix aliases.
)
vindex(dis_saliases)
item(tt(dis_saliases))(
Like tt(saliases) but for disabled suffix aliases.
)
vindex(parameters)
item(tt(parameters))(
The keys in this associative array are the names of the parameters

View file

@ -1611,49 +1611,56 @@ scanpmuserdirs(HashTable ht, ScanFunc func, int flags)
}
}
/* Functions for the regularaliases and globalaliases special parameters. */
/* Functions for the raliases, galiases and saliases special parameters. */
/**/
static void
setralias(Param pm, char *value, int dis)
setalias(HashTable ht, Param pm, char *value, int flags)
{
aliastab->addnode(aliastab, ztrdup(pm->nam), createaliasnode(value, dis));
ht->addnode(aliastab, ztrdup(pm->nam),
createaliasnode(value, flags));
}
/**/
static void
setpmralias(Param pm, char *value)
{
setralias(pm, value, 0);
setalias(aliastab, 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));
setalias(aliastab, pm, value, DISABLED);
}
/**/
static void
setpmgalias(Param pm, char *value)
{
setgalias(pm, value, 0);
setalias(aliastab, pm, value, ALIAS_GLOBAL);
}
/**/
static void
setpmdisgalias(Param pm, char *value)
{
setgalias(pm, value, DISABLED);
setgalias(aliastab, pm, value, ALIAS_GLOBAL|DISABLED);
}
/**/
static void
setpmsalias(Param pm, char *value)
{
setgalias(sufaliastab, pm, value, 0);
}
/**/
static void
setpmdissalias(Param pm, char *value)
{
setgalias(sufaliastab, pm, value, DISABLED);
}
/**/
@ -1668,7 +1675,17 @@ unsetpmalias(Param pm, int exp)
/**/
static void
setaliases(Param pm, HashTable ht, int global, int dis)
unsetpmsalias(Param pm, int exp)
{
HashNode hd = sufaliastab->removenode(sufaliastab, pm->nam);
if (hd)
sufaliastab->freenode(hd);
}
/**/
static void
setaliases(HashTable alht, Param pm, HashTable ht, int flags)
{
int i;
HashNode hn, next, hd;
@ -1676,13 +1693,18 @@ setaliases(Param pm, HashTable ht, int global, int dis)
if (!ht)
return;
for (i = 0; i < aliastab->hsize; i++)
for (hn = aliastab->nodes[i]; hn; hn = next) {
for (i = 0; i < alht->hsize; i++)
for (hn = alht->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);
/*
* The following respects the DISABLED flag, e.g.
* we get a different behaviour for raliases and dis_raliases.
* The predecessor to this code didn't do that; presumably
* that was a bug.
*/
if (flags == ((Alias)hn)->flags &&
(hd = alht->removenode(alht, hn->nam)))
alht->freenode(hd);
}
for (i = 0; i < ht->hsize; i++)
@ -1696,10 +1718,8 @@ setaliases(Param pm, HashTable ht, int global, int dis)
v.pm = (Param) hn;
if ((val = getstrvalue(&v)))
aliastab->addnode(aliastab, ztrdup(hn->nam),
createaliasnode(ztrdup(val),
(global ? ALIAS_GLOBAL : 0) |
(dis ? DISABLED : 0)));
alht->addnode(alht, ztrdup(hn->nam),
createaliasnode(ztrdup(val), flags));
}
deleteparamtable(ht);
}
@ -1708,53 +1728,103 @@ setaliases(Param pm, HashTable ht, int global, int dis)
static void
setpmraliases(Param pm, HashTable ht)
{
setaliases(pm, ht, 0, 0);
setaliases(aliastab, pm, ht, 0);
}
/**/
static void
setpmdisraliases(Param pm, HashTable ht)
{
setaliases(pm, ht, 0, DISABLED);
setaliases(aliastab, pm, ht, DISABLED);
}
/**/
static void
setpmgaliases(Param pm, HashTable ht)
{
setaliases(pm, ht, 1, 0);
setaliases(aliastab, pm, ht, ALIAS_GLOBAL);
}
/**/
static void
setpmdisgaliases(Param pm, HashTable ht)
{
setaliases(pm, ht, 1, DISABLED);
setaliases(aliastab, pm, ht, ALIAS_GLOBAL|DISABLED);
}
/**/
static void
setpmsaliases(Param pm, HashTable ht)
{
setaliases(sufaliastab, pm, ht, ALIAS_SUFFIX);
}
/**/
static void
setpmdissaliases(Param pm, HashTable ht)
{
setaliases(sufaliastab, pm, ht, ALIAS_SUFFIX|DISABLED);
}
/**/
static void
assignaliasdefs(Param pm, int flags)
{
pm->flags = PM_SCALAR;
/* we really need to squirrel the flags away somewhere... */
switch (flags) {
case 0:
pm->sets.cfn = setpmralias;
break;
case ALIAS_GLOBAL:
pm->sets.cfn = setpmgalias;
break;
case ALIAS_SUFFIX:
pm->sets.cfn = setpmsalias;
break;
case DISABLED:
pm->sets.cfn = setpmdisralias;
break;
case ALIAS_GLOBAL|DISABLED:
pm->sets.cfn = setpmdisgalias;
break;
case ALIAS_SUFFIX|DISABLED:
pm->sets.cfn = setpmdissalias;
break;
}
pm->gets.cfn = strgetfn;
if (flags & ALIAS_SUFFIX)
pm->unsetfn = unsetpmsalias;
else
pm->unsetfn = unsetpmalias;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
}
/**/
static HashNode
getalias(HashTable ht, char *name, int global, int dis)
getalias(HashTable alht, HashTable ht, char *name, int flags)
{
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)))
assignaliasdefs(pm, flags);
if ((al = (Alias) alht->getnode2(alht, name)) &&
flags == al->flags)
pm->u.str = dupstring(al->text);
else {
pm->u.str = dupstring("");
@ -1767,61 +1837,64 @@ getalias(HashTable ht, char *name, int global, int dis)
static HashNode
getpmralias(HashTable ht, char *name)
{
return getalias(ht, name, 0, 0);
return getalias(aliastab, ht, name, 0);
}
/**/
static HashNode
getpmdisralias(HashTable ht, char *name)
{
return getalias(ht, name, 0, 0);
return getalias(aliastab, ht, name, DISABLED);
}
/**/
static HashNode
getpmgalias(HashTable ht, char *name)
{
return getalias(ht, name, 1, 0);
return getalias(aliastab, ht, name, ALIAS_GLOBAL);
}
/**/
static HashNode
getpmdisgalias(HashTable ht, char *name)
{
return getalias(ht, name, 1, DISABLED);
return getalias(aliastab, ht, name, ALIAS_GLOBAL|DISABLED);
}
/**/
static HashNode
getpmsalias(HashTable ht, char *name)
{
return getalias(sufaliastab, ht, name, ALIAS_SUFFIX);
}
/**/
static HashNode
getpmdissalias(HashTable ht, char *name)
{
return getalias(sufaliastab, ht, name, ALIAS_SUFFIX|DISABLED);
}
/**/
static void
scanaliases(HashTable ht, ScanFunc func, int flags, int global, int dis)
scanaliases(HashTable alht, HashTable ht, ScanFunc func,
int pmflags, int alflags)
{
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;
assignaliasdefs(&pm, alflags);
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;
for (i = 0; i < alht->hsize; i++)
for (al = (Alias) alht->nodes[i]; al; al = (Alias) al->next) {
if (alflags == al->flags) {
pm.nam = al->nam;
if (func != scancountparams &&
((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
!(flags & SCANPM_WANTKEYS)))
((pmflags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
!(pmflags & SCANPM_WANTKEYS)))
pm.u.str = dupstring(al->text);
func((HashNode) &pm, flags);
func((HashNode) &pm, pmflags);
}
}
}
@ -1830,28 +1903,42 @@ scanaliases(HashTable ht, ScanFunc func, int flags, int global, int dis)
static void
scanpmraliases(HashTable ht, ScanFunc func, int flags)
{
scanaliases(ht, func, flags, 0, 0);
scanaliases(aliastab, ht, func, flags, 0);
}
/**/
static void
scanpmdisraliases(HashTable ht, ScanFunc func, int flags)
{
scanaliases(ht, func, flags, 0, DISABLED);
scanaliases(aliastab, ht, func, flags, DISABLED);
}
/**/
static void
scanpmgaliases(HashTable ht, ScanFunc func, int flags)
{
scanaliases(ht, func, flags, 1, 0);
scanaliases(aliastab, ht, func, flags, ALIAS_GLOBAL);
}
/**/
static void
scanpmdisgaliases(HashTable ht, ScanFunc func, int flags)
{
scanaliases(ht, func, flags, 1, DISABLED);
scanaliases(aliastab, ht, func, flags, ALIAS_GLOBAL|DISABLED);
}
/**/
static void
scanpmsaliases(HashTable ht, ScanFunc func, int flags)
{
scanaliases(sufaliastab, ht, func, flags, ALIAS_SUFFIX);
}
/**/
static void
scanpmdissaliases(HashTable ht, ScanFunc func, int flags)
{
scanaliases(sufaliastab, ht, func, flags, ALIAS_SUFFIX|DISABLED);
}
/* Table for defined parameters. */
@ -1932,12 +2019,18 @@ static struct pardef partab[] = {
{ "galiases", 0,
getpmgalias, scanpmgaliases, setpmgaliases,
NULL, NULL, stdunsetfn, NULL },
{ "saliases", 0,
getpmsalias, scanpmsaliases, setpmsaliases,
NULL, NULL, stdunsetfn, NULL },
{ "dis_aliases", 0,
getpmdisralias, scanpmdisraliases, setpmdisraliases,
NULL, NULL, stdunsetfn, NULL },
{ "dis_galiases", 0,
getpmdisgalias, scanpmdisgaliases, setpmdisgaliases,
NULL, NULL, stdunsetfn, NULL },
{ "dis_saliases", 0,
getpmdissalias, scanpmdissaliases, setpmdissaliases,
NULL, NULL, stdunsetfn, NULL },
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};

View file

@ -45,7 +45,7 @@ static struct builtin builtins[] =
BUILTIN("[", 0, bin_test, 0, -1, BIN_BRACKET, NULL, NULL),
BUILTIN(".", BINF_PSPECIAL, bin_dot, 1, -1, 0, NULL, NULL),
BUILTIN(":", BINF_PSPECIAL, bin_true, 0, -1, 0, NULL, NULL),
BUILTIN("alias", BINF_MAGICEQUALS | BINF_PLUSOPTS, bin_alias, 0, -1, 0, "Lgmr", NULL),
BUILTIN("alias", BINF_MAGICEQUALS | BINF_PLUSOPTS, bin_alias, 0, -1, 0, "Lgmrs", NULL),
BUILTIN("autoload", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "tUXwkz", "u"),
BUILTIN("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, NULL, NULL),
@ -55,11 +55,11 @@ static struct builtin builtins[] =
BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL),
BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%lprtux", NULL),
BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL),
BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmr", NULL),
BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmrs", NULL),
BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL),
BUILTIN("echo", BINF_PRINTOPTS | BINF_SKIPINVALID, bin_print, 0, -1, BIN_ECHO, "neE", "-"),
BUILTIN("emulate", 0, bin_emulate, 1, 1, 0, "LR", NULL),
BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmr", NULL),
BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmrs", NULL),
BUILTIN("eval", BINF_PSPECIAL, bin_eval, 0, -1, BIN_EVAL, NULL, NULL),
BUILTIN("exit", BINF_PSPECIAL, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
BUILTIN("export", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, BIN_EXPORT, "E:%F:%HL:%R:%TUZ:%afhi:%lprtu", "xg"),
@ -123,9 +123,9 @@ static struct builtin builtins[] =
BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsw", "v"),
BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%lprtuxm", NULL),
BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL),
BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "m", "a"),
BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "ms", "a"),
BUILTIN("unfunction", 0, bin_unhash, 1, -1, 0, "m", "f"),
BUILTIN("unhash", 0, bin_unhash, 1, -1, 0, "adfm", NULL),
BUILTIN("unhash", 0, bin_unhash, 1, -1, 0, "adfms", NULL),
BUILTIN("unset", BINF_PSPECIAL, bin_unset, 1, -1, 0, "fmv", NULL),
BUILTIN("unsetopt", 0, bin_setopt, 0, -1, BIN_UNSETOPT, NULL, NULL),
BUILTIN("wait", 0, bin_fg, 0, -1, BIN_WAIT, NULL, NULL),
@ -461,6 +461,8 @@ bin_enable(char *name, char **argv, Options ops, int func)
ht = shfunctab;
else if (OPT_ISSET(ops,'r'))
ht = reswdtab;
else if (OPT_ISSET(ops,'s'))
ht = sufaliastab;
else if (OPT_ISSET(ops,'a'))
ht = aliastab;
else
@ -2671,6 +2673,8 @@ bin_whence(char *nam, char **argv, Options ops, int func)
informed = 0;
if (!OPT_ISSET(ops,'p')) {
char *suf;
/* Look for alias */
if ((hn = aliastab->getnode(aliastab, *argv))) {
aliastab->printnode(hn, printflags);
@ -2678,6 +2682,15 @@ bin_whence(char *nam, char **argv, Options ops, int func)
continue;
informed = 1;
}
/* Look for suffix alias */
if ((suf = strrchr(*argv, '.')) && suf[1] &&
suf > *argv && suf[-1] != Meta &&
(hn = sufaliastab->getnode(sufaliastab, suf+1))) {
sufaliastab->printnode(hn, printflags);
if (!all)
continue;
informed = 1;
}
/* Look for reserved word */
if ((hn = reswdtab->getnode(reswdtab, *argv))) {
reswdtab->printnode(hn, printflags);
@ -2901,6 +2914,8 @@ bin_unhash(char *name, char **argv, Options ops, int func)
ht = nameddirtab; /* named directories */
else if (OPT_ISSET(ops,'f'))
ht = shfunctab; /* shell functions */
else if (OPT_ISSET(ops,'s'))
ht = sufaliastab; /* suffix aliases, must precede aliases */
else if (OPT_ISSET(ops,'a'))
ht = aliastab; /* aliases */
else
@ -2963,34 +2978,48 @@ bin_alias(char *name, char **argv, Options ops, int func)
Alias a;
Patprog pprog;
Asgment asg;
int haveflags = 0, returnval = 0;
int returnval = 0;
int flags1 = 0, flags2 = DISABLED;
int printflags = 0;
int type_opts;
HashTable ht = aliastab;
/* Did we specify the type of alias? */
if (OPT_ISSET(ops,'r') || OPT_ISSET(ops,'g')) {
if (OPT_ISSET(ops,'r') && OPT_ISSET(ops,'g')) {
type_opts = OPT_ISSET(ops, 'r') + OPT_ISSET(ops, 'g') +
OPT_ISSET(ops, 's');
if (type_opts) {
if (type_opts > 1) {
zwarnnam(name, "illegal combination of options", NULL, 0);
return 1;
}
haveflags = 1;
if (OPT_ISSET(ops,'g'))
flags1 |= ALIAS_GLOBAL;
else
flags2 |= ALIAS_GLOBAL;
if (OPT_ISSET(ops, 's')) {
/*
* Although we keep suffix aliases in a different table,
* it is useful to be able to distinguish Alias structures
* without reference to the table, so we have a separate
* flag, too.
*/
flags1 |= ALIAS_SUFFIX;
ht = sufaliastab;
} else
flags2 |= ALIAS_SUFFIX;
}
if (OPT_ISSET(ops,'L'))
printflags |= PRINT_LIST;
else if (OPT_PLUS(ops,'r') || OPT_PLUS(ops,'g')|| OPT_PLUS(ops,'m') ||
OPT_ISSET(ops,'+'))
else if (OPT_PLUS(ops,'g') || OPT_PLUS(ops,'r') || OPT_PLUS(ops,'s') ||
OPT_PLUS(ops,'m') || OPT_ISSET(ops,'+'))
printflags |= PRINT_NAMEONLY;
/* In the absence of arguments, list all aliases. If a command *
* line flag is specified, list only those of that type. */
if (!*argv) {
queue_signals();
scanhashtable(aliastab, 1, flags1, flags2, aliastab->printnode, printflags);
scanhashtable(ht, 1, flags1, flags2, ht->printnode, printflags);
unqueue_signals();
return 0;
}
@ -3003,8 +3032,8 @@ bin_alias(char *name, char **argv, Options ops, int func)
if ((pprog = patcompile(*argv, PAT_STATIC, NULL))) {
/* display the matching aliases */
queue_signals();
scanmatchtable(aliastab, pprog, flags1, flags2,
aliastab->printnode, printflags);
scanmatchtable(ht, pprog, flags1, flags2,
ht->printnode, printflags);
unqueue_signals();
} else {
untokenize(*argv);
@ -3021,14 +3050,15 @@ bin_alias(char *name, char **argv, Options ops, int func)
if (asg->value && !OPT_ISSET(ops,'L')) {
/* The argument is of the form foo=bar and we are not *
* forcing a listing with -L, so define an alias */
aliastab->addnode(aliastab, ztrdup(asg->name),
createaliasnode(ztrdup(asg->value), flags1));
} else if ((a = (Alias) aliastab->getnode(aliastab, asg->name))) {
ht->addnode(ht, ztrdup(asg->name),
createaliasnode(ztrdup(asg->value), flags1));
} else if ((a = (Alias) ht->getnode(ht, asg->name))) {
/* display alias if appropriate */
if (!haveflags ||
(OPT_ISSET(ops,'r') && !(a->flags & ALIAS_GLOBAL)) ||
(OPT_ISSET(ops,'g') && (a->flags & ALIAS_GLOBAL)))
aliastab->printnode((HashNode) a, printflags);
if (!type_opts || ht == sufaliastab ||
(OPT_ISSET(ops,'r') &&
!(a->flags & (ALIAS_GLOBAL|ALIAS_SUFFIX))) ||
(OPT_ISSET(ops,'g') && (a->flags & ALIAS_GLOBAL)))
ht->printnode((HashNode) a, printflags);
} else
returnval = 1;
}

View file

@ -1014,30 +1014,51 @@ printreswdnode(HashNode hn, int printflags)
/**/
mod_export HashTable aliastab;
/* Create new hash table for aliases */
/* has table containing suffix aliases */
/**/
mod_export HashTable sufaliastab;
/* Create new hash tables for aliases */
/**/
void
createaliastable(void)
createaliastable(HashTable ht)
{
ht->hash = hasher;
ht->emptytable = NULL;
ht->filltable = NULL;
ht->cmpnodes = strcmp;
ht->addnode = addhashnode;
ht->getnode = gethashnode;
ht->getnode2 = gethashnode2;
ht->removenode = removehashnode;
ht->disablenode = disablehashnode;
ht->enablenode = enablehashnode;
ht->freenode = freealiasnode;
ht->printnode = printaliasnode;
}
/**/
void
createaliastables(void)
{
/* Table for regular and global aliases */
aliastab = newhashtable(23, "aliastab", NULL);
aliastab->hash = hasher;
aliastab->emptytable = NULL;
aliastab->filltable = NULL;
aliastab->cmpnodes = strcmp;
aliastab->addnode = addhashnode;
aliastab->getnode = gethashnode;
aliastab->getnode2 = gethashnode2;
aliastab->removenode = removehashnode;
aliastab->disablenode = disablehashnode;
aliastab->enablenode = enablehashnode;
aliastab->freenode = freealiasnode;
aliastab->printnode = printaliasnode;
createaliastable(aliastab);
/* add the default aliases */
aliastab->addnode(aliastab, ztrdup("run-help"), createaliasnode(ztrdup("man"), 0));
aliastab->addnode(aliastab, ztrdup("which-command"), createaliasnode(ztrdup("whence"), 0));
/* Table for suffix aliases --- make this smaller */
sufaliastab = newhashtable(11, "sufaliastab", NULL);
createaliastable(sufaliastab);
}
/* Create a new alias node */
@ -1093,10 +1114,12 @@ printaliasnode(HashNode hn, int printflags)
if (printflags & PRINT_WHENCE_CSH) {
nicezputs(a->nam, stdout);
if (a->flags & ALIAS_GLOBAL)
printf(": globally aliased to ");
else
printf(": aliased to ");
printf(": ");
if (a->flags & ALIAS_SUFFIX)
printf("suffix ");
else if (a->flags & ALIAS_GLOBAL)
printf("globally ");
printf (" aliased to ");
nicezputs(a->text, stdout);
putchar('\n');
return;
@ -1104,10 +1127,14 @@ printaliasnode(HashNode hn, int printflags)
if (printflags & PRINT_WHENCE_VERBOSE) {
nicezputs(a->nam, stdout);
if (a->flags & ALIAS_GLOBAL)
printf(" is a global alias for ");
printf(" is a");
if (a->flags & ALIAS_SUFFIX)
printf(" suffix");
else if (a->flags & ALIAS_GLOBAL)
printf(" global");
else
printf(" is an alias for ");
printf("n");
printf(" alias for");
nicezputs(a->text, stdout);
putchar('\n');
return;
@ -1115,7 +1142,9 @@ printaliasnode(HashNode hn, int printflags)
if (printflags & PRINT_LIST) {
printf("alias ");
if (a->flags & ALIAS_GLOBAL)
if (a->flags & ALIAS_SUFFIX)
printf("-s ");
else if (a->flags & ALIAS_GLOBAL)
printf("-g ");
/* If an alias begins with `-', then we must output `-- ' *
@ -1127,6 +1156,7 @@ printaliasnode(HashNode hn, int printflags)
quotedzputs(a->nam, stdout);
putchar('=');
quotedzputs(a->text, stdout);
putchar('\n');
}

View file

@ -792,7 +792,7 @@ setupvals(void)
initlextabs(); /* initialize lexing tables */
createreswdtable(); /* create hash table for reserved words */
createaliastable(); /* create hash table for aliases */
createaliastables(); /* create hash tables for aliases */
createcmdnamtable(); /* create hash table for external commands */
createshfunctable(); /* create hash table for shell functions */
createbuiltintable(); /* create hash table for builtin commands */

View file

@ -1510,7 +1510,7 @@ parse_subscript(char *s, int sub)
mod_export int
parse_subst_string(char *s)
{
int c, l = strlen(s), err, olen;
int c, l = strlen(s), err, olen, lexstop_ret;
if (!*s || !strcmp(s, nulstring))
return 0;
@ -1522,6 +1522,7 @@ parse_subst_string(char *s)
bptr = tokstr = s;
bsiz = l + 1;
c = hgetc();
lexstop_ret = lexstop;
c = gettokstr(c, 1);
err = errflag;
strinend();
@ -1603,17 +1604,32 @@ exalias(void)
if (tok == STRING) {
/* Check for an alias */
an = (noaliases || unset(ALIASESOPT)) ? NULL :
(Alias) aliastab->getnode(aliastab, yytext);
if (an && !an->inuse && ((an->flags & ALIAS_GLOBAL) || incmdpos ||
inalmore)) {
inpush(an->text, INP_ALIAS, an);
if (an->text[0] == ' ')
aliasspaceflag = 1;
lexstop = 0;
if (yytext == copy)
yytext = tokstr;
return 1;
if (!noaliases && isset(ALIASESOPT)) {
char *suf;
an = (Alias) aliastab->getnode(aliastab, yytext);
if (an && !an->inuse &&
((an->flags & ALIAS_GLOBAL) || incmdpos || inalmore)) {
inpush(an->text, INP_ALIAS, an);
if (an->text[0] == ' ')
aliasspaceflag = 1;
lexstop = 0;
if (yytext == copy)
yytext = tokstr;
return 1;
}
if ((suf = strrchr(yytext, '.')) && suf[1] &&
suf > yytext && suf[-1] != Meta &&
(an = (Alias)sufaliastab->getnode(sufaliastab, suf+1)) &&
!an->inuse && incmdpos) {
inpush(dupstring(yytext), INP_ALIAS, NULL);
inpush(" ", INP_ALIAS, NULL);
inpush(an->text, INP_ALIAS, an);
lexstop = 0;
if (yytext == copy)
yytext = tokstr;
return 1;
}
}
/* Then check for a reserved word */

View file

@ -872,8 +872,11 @@ struct alias {
int inuse; /* alias is being expanded */
};
/* is this alias global */
/* bit 0 of flags is the DISABLED flag */
/* is this alias global? */
#define ALIAS_GLOBAL (1<<1)
/* is this an alias for suffix handling? */
#define ALIAS_SUFFIX (1<<2)
/* node in command path hash table (cmdnamtab) */