diff options
Diffstat (limited to 'usr/src/lib/libshell/common/bltins/whence.c')
-rw-r--r-- | usr/src/lib/libshell/common/bltins/whence.c | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/usr/src/lib/libshell/common/bltins/whence.c b/usr/src/lib/libshell/common/bltins/whence.c new file mode 100644 index 0000000000..7d05a741d6 --- /dev/null +++ b/usr/src/lib/libshell/common/bltins/whence.c @@ -0,0 +1,273 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1982-2007 AT&T Knowledge Ventures * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Knowledge Ventures * +* * +* A copy of the License is available at * +* http://www.opensource.org/licenses/cpl1.0.txt * +* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* David Korn <dgk@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * command [-pvVx] name [arg...] + * whence [-afvp] name... + * + * David Korn + * AT&T Labs + * + */ + +#include "defs.h" +#include <error.h> +#include "shtable.h" +#include "name.h" +#include "path.h" +#include "shlex.h" +#include "builtins.h" + +#define P_FLAG 1 +#define V_FLAG 2 +#define A_FLAG 4 +#define F_FLAG 010 +#define X_FLAG 020 + +static int whence(Shell_t *,char**, int); + +/* + * command is called with argc==0 when checking for -V or -v option + * In this case return 0 when -v or -V or unknown option, otherwise + * the shift count to the command is returned + */ +int b_command(register int argc,char *argv[],void *extra) +{ + register int n, flags=0; + register Shell_t *shp = (Shell_t*)extra; + opt_info.index = opt_info.offset = 0; + while((n = optget(argv,sh_optcommand))) switch(n) + { + case 'p': + if(sh_isoption(SH_RESTRICTED)) + errormsg(SH_DICT,ERROR_exit(1),e_restricted,"-p"); + sh_onstate(SH_DEFPATH); + break; + case 'v': + flags |= X_FLAG; + break; + case 'V': + flags |= V_FLAG; + break; + case 'x': + shp->xargexit = 1; + break; + case ':': + if(argc==0) + return(0); + errormsg(SH_DICT,2, "%s", opt_info.arg); + break; + case '?': + if(argc==0) + return(0); + errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); + break; + } + if(argc==0) + return(flags?0:opt_info.index); + argv += opt_info.index; + if(error_info.errors || !*argv) + errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0)); + return(whence(shp,argv, flags)); +} + +/* + * for the whence command + */ +int b_whence(int argc,char *argv[],void *extra) +{ + register int flags=0, n; + register Shell_t *shp = (Shell_t*)extra; + NOT_USED(argc); + if(*argv[0]=='t') + flags = V_FLAG; + while((n = optget(argv,sh_optwhence))) switch(n) + { + case 'a': + flags |= A_FLAG; + /* FALL THRU */ + case 'v': + flags |= V_FLAG; + break; + case 'f': + flags |= F_FLAG; + break; + case 'p': + flags |= P_FLAG; + break; + case ':': + errormsg(SH_DICT,2, "%s", opt_info.arg); + break; + case '?': + errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); + break; + } + argv += opt_info.index; + if(error_info.errors || !*argv) + errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0)); + return(whence(shp, argv, flags)); +} + +static int whence(Shell_t *shp,char **argv, register int flags) +{ + register const char *name; + register Namval_t *np; + register const char *cp; + register int aflag,r=0; + register const char *msg; + int tofree; + Dt_t *root; + Namval_t *nq; + char *notused; +#ifdef PATH_BFPATH + Pathcomp_t *pp; +#endif + int notrack = 1; + while(name= *argv++) + { + tofree=0; + aflag = ((flags&A_FLAG)!=0); + cp = 0; + np = 0; +#ifdef PATH_BFPATH + pp = 0; +#endif + if(flags&P_FLAG) + goto search; + /* reserved words first */ + if(sh_lookup(name,shtab_reserved)) + { + sfprintf(sfstdout,"%s%s\n",name,(flags&V_FLAG)?sh_translate(is_reserved):""); + if(!aflag) + continue; + aflag++; + } + /* non-tracked aliases */ + if((np=nv_search(name,shp->alias_tree,0)) + && !nv_isnull(np) && !(notrack=nv_isattr(np,NV_TAGGED)) + && (cp=nv_getval(np))) + { + if(flags&V_FLAG) + { + if(nv_isattr(np,NV_EXPORT)) + msg = sh_translate(is_xalias); + else + msg = sh_translate(is_alias); + sfprintf(sfstdout,msg,name); + } + sfputr(sfstdout,sh_fmtq(cp),'\n'); + if(!aflag) + continue; + cp = 0; + aflag++; + } + /* built-ins and functions next */ + root = (flags&F_FLAG)?shp->bltin_tree:shp->fun_tree; + if(np= nv_bfsearch(name, root, &nq, ¬used)) + { + if(is_abuiltin(np) && nv_isnull(np)) + goto search; + cp = ""; + if(flags&V_FLAG) + { + if(nv_isnull(np)) + cp = sh_translate(is_ufunction); + else if(is_abuiltin(np)) + cp = sh_translate(is_builtin); + else + cp = sh_translate(is_function); + } + sfprintf(sfstdout,"%s%s\n",name,cp); + if(!aflag) + continue; + cp = 0; + aflag++; + } + search: + if(sh_isstate(SH_DEFPATH)) + { + cp=0; + notrack=1; + } +#ifdef PATH_BFPATH + if(path_search(name,pp,2)) + cp = name; + else + { + cp = stakptr(PATH_OFFSET); + if(*cp==0) + cp = 0; + else if(*cp!='/') + { + cp = path_fullname(cp); + tofree=1; + } + } +#else + if(path_search(name,cp,2)) + cp = name; + else + cp = shp->lastpath; + shp->lastpath = 0; +#endif + if(cp) + { + if(flags&V_FLAG) + { + if(*cp!= '/') + { +#ifdef PATH_BFPATH + if(!np && (np=nv_search(name,shp->track_tree,0))) + sfprintf(sfstdout,"%s %s %s/%s\n",name,sh_translate(is_talias),path_pwd(0),cp); + else if(!np || nv_isnull(np)) +#else + if(!np || nv_isnull(np)) +#endif + sfprintf(sfstdout,"%s%s\n",name,sh_translate(is_ufunction)); + continue; + } + sfputr(sfstdout,sh_fmtq(name),' '); + /* built-in version of program */ + if(*cp=='/' && (np=nv_search(cp,shp->bltin_tree,0))) + msg = sh_translate(is_builtver); + /* tracked aliases next */ + else if(!notrack || strchr(name,'/')) + msg = sh_translate("is"); + else + msg = sh_translate(is_talias); + sfputr(sfstdout,msg,' '); + } + sfputr(sfstdout,sh_fmtq(cp),'\n'); + if(tofree) + free((char*)cp); + } + else if(aflag<=1) + { + r |= 1; + if(flags&V_FLAG) + { + sfprintf(sfstdout,sh_translate(e_found),sh_fmtq(name)); + sfputc(sfstdout,'\n'); + } + } + } + return(r); +} + |