mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Refactor new b_hash(); better hash table clear (re: d8428a83)
The b_hash() function duplicated much of its code from b_alias(), while b_alias() retained some code to support being called as 'hash'. There is no reason why 'hash' and 'alias' can't be handled with a single function, as is the case several other builtins. Note that option parsing can easily be made dependent on the name the command was invoked with (in this case, argv[0]=='h'). The new hash builtin's -r option cleared the hash table by assigning to PATH its existing value, triggering its associated discipline function (put_restricted() in init.c) which then actually cleared the hash table. That's a bit of a hack. It's nicer if we can just do that directly. This requires taking a static handler function rehash() from init.c, which invalidates one hash table entry, and making it available to the builtin. src/cmd/ksh93/bltins/typeset.c, src/cmd/ksh93/include/builtins.h, src/cmd/ksh93/include/nval.h, src/cmd/ksh93/sh/init.c, src/cmd/ksh93/sh/name.c: - Merge b_hash() into b_alias(). - The -x option was still uselessly setting the NV_EXPORT flag. Exported aliases were in ksh88 but were removed in ksh93. - Rename rehash() handler function from init.c to nv_rehash (avoiding a possible conflict with another rehash() in cd_pwd.c) and move it to name.c just above nv_scan(), which it's meant to be used with. Make it an extern so typeset.c can use it. - b_alias(): Replace the PATH assignment by an nv_scan() call to clear the hash table directly using the nv_rehash() handler. src/cmd/ksh93/data/builtins.c: - POSIX compliance fix: Remove BLT_SPC (special builtin) flag from "alias" definition. 'alias' is specified as a regular builtin. - sh_optalias[]: Fix uninformative -t option documentation. - sh_opthash[]: Edit for conciseness and clarity. src/cmd/ksh93/sh.1: - Edit the 'alias -t' and 'hash' documentation. - Remove the -- prefix from the 'alias' entry, which indicated that it was supposed to be a declaration builtin like 'typeset', with assignment-arguments expanding tildes and not being subject to field splitting. However, my testing shows that 'alias' has never actually behaved that way on ksh93. Even adding the BLT_DCL flag in data/builtins.c doesn't seem to change that. (cherry picked from commit afa68dca5c786daa13213973e8b0f9bf3a1dadf6)
This commit is contained in:
parent
74b4162178
commit
80d9ae2b1c
8 changed files with 68 additions and 98 deletions
|
@ -133,56 +133,20 @@ int b_readonly(int argc,char *argv[],Shbltin_t *context)
|
|||
return(setall(argv,flag,tdata.sh->var_tree, &tdata));
|
||||
}
|
||||
|
||||
int b_hash(int argc,char *argv[],Shbltin_t *context)
|
||||
{
|
||||
register unsigned flag = NV_NOARRAY | NV_NOSCOPE | NV_ASSIGN | NV_TAGGED;
|
||||
register Dt_t *troot;
|
||||
register int rflag=0, n;
|
||||
struct tdata tdata;
|
||||
NOT_USED(argc);
|
||||
memset((void *)&tdata, 0, sizeof(tdata));
|
||||
tdata.sh = context->shp;
|
||||
troot = tdata.sh->alias_tree;
|
||||
|
||||
/* The hash utility should not be recognized as the alias builtin */
|
||||
tdata.aflag = '-';
|
||||
|
||||
while((n = optget(argv,sh_opthash))) switch(n)
|
||||
{
|
||||
case 'r':
|
||||
rflag = 1;
|
||||
break;
|
||||
case ':':
|
||||
error(2,"%s",opt_info.arg);
|
||||
break;
|
||||
case '?':
|
||||
error(ERROR_usage(0),"%s",opt_info.arg);
|
||||
return 2;
|
||||
}
|
||||
if (error_info.errors)
|
||||
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NULL));
|
||||
argv += (opt_info.index-1);
|
||||
|
||||
/* Handle -r */
|
||||
if (rflag)
|
||||
{
|
||||
Namval_t *np = nv_search((char *)PATHNOD, tdata.sh->var_tree, HASH_BUCKET);
|
||||
nv_putval(np, nv_getval(np), NV_RDONLY);
|
||||
}
|
||||
|
||||
troot = tdata.sh->track_tree;
|
||||
/* We must fork in subshells to avoid polluting the parent shell's hash table. */
|
||||
if(tdata.sh->subshell && !tdata.sh->subshare)
|
||||
sh_subfork();
|
||||
return setall(argv, flag, troot, &tdata);
|
||||
}
|
||||
|
||||
/*
|
||||
* 'alias' and 'hash' builtins
|
||||
*/
|
||||
#if 0
|
||||
/* for the dictionary generator */
|
||||
int b_hash(int argc,register char *argv[],Shbltin_t *context){}
|
||||
#endif
|
||||
int b_alias(int argc,register char *argv[],Shbltin_t *context)
|
||||
{
|
||||
register unsigned flag = NV_NOARRAY|NV_NOSCOPE|NV_ASSIGN;
|
||||
register Dt_t *troot;
|
||||
register int n;
|
||||
register int rflag=0, n;
|
||||
struct tdata tdata;
|
||||
Namval_t *np;
|
||||
NOT_USED(argc);
|
||||
memset((void*)&tdata,0,sizeof(tdata));
|
||||
tdata.sh = context->shp;
|
||||
|
@ -196,7 +160,7 @@ int b_alias(int argc,register char *argv[],Shbltin_t *context)
|
|||
*opt_info.option = 0;
|
||||
tdata.argnum = 0;
|
||||
tdata.aflag = *argv[1];
|
||||
while((n = optget(argv,sh_optalias))) switch(n)
|
||||
while((n = optget(argv, *argv[0]=='h' ? sh_opthash : sh_optalias))) switch(n)
|
||||
{
|
||||
case 'p':
|
||||
tdata.prefix = argv[0];
|
||||
|
@ -205,7 +169,10 @@ int b_alias(int argc,register char *argv[],Shbltin_t *context)
|
|||
flag |= NV_TAGGED;
|
||||
break;
|
||||
case 'x':
|
||||
flag |= NV_EXPORT;
|
||||
/* obsolete, ignored */
|
||||
break;
|
||||
case 'r':
|
||||
rflag=1;
|
||||
break;
|
||||
case ':':
|
||||
errormsg(SH_DICT,2, "%s", opt_info.arg);
|
||||
|
@ -217,11 +184,18 @@ int b_alias(int argc,register char *argv[],Shbltin_t *context)
|
|||
if(error_info.errors)
|
||||
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*)));
|
||||
argv += (opt_info.index-1);
|
||||
if(flag&NV_TAGGED)
|
||||
troot = tdata.sh->track_tree;
|
||||
}
|
||||
if(context->shp->subshell && !context->shp->subshare)
|
||||
/* fork a virtual subshell to avoid affecting parent shell's hash/alias table */
|
||||
if((argv[1] || rflag) && tdata.sh->subshell && !tdata.sh->subshare)
|
||||
sh_subfork();
|
||||
/* 'alias -t', 'hash' */
|
||||
if(flag&NV_TAGGED)
|
||||
{
|
||||
troot = tdata.sh->track_tree; /* use hash table */
|
||||
tdata.aflag = '-'; /* make setall() treat 'hash' like 'alias -t' */
|
||||
if(rflag) /* hash -r: clear hash table */
|
||||
nv_scan(troot,nv_rehash,(void*)0,NV_TAGGED,NV_TAGGED);
|
||||
}
|
||||
return(setall(argv,flag,troot,&tdata));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue