Logo Search packages:      
Sourcecode: ksh version File versions  Download package

whence.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*          Copyright (c) 1982-2007 AT&T Intellectual Property          *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                    by AT&T Intellectual Property                     *
*                                                                      *
*                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
#define Q_FLAG    040

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;
            flags &= ~V_FLAG;
            break;
          case 'q':
            flags |= Q_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;
      if(flags&Q_FLAG)
            flags &= ~A_FLAG;
      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;
            if(flags&Q_FLAG)
                  goto bltins;
            /* 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 */
      bltins:
            root = (flags&F_FLAG)?shp->bltin_tree:shp->fun_tree;
            if(np= nv_bfsearch(name, root, &nq, &notused))
            {
                  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);
                  }
                  if(flags&Q_FLAG)
                        continue;
                  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(flags&Q_FLAG)
                  r |= !cp;
            else 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);
}


Generated by  Doxygen 1.6.0   Back to index