diff -ru bin/sh.orig/eval.c bin/sh/eval.c --- bin/sh.orig/eval.c Wed Aug 3 20:11:02 2005 +++ bin/sh/eval.c Thu Aug 4 09:53:53 2005 @@ -971,7 +971,9 @@ struct jmploc loc, *old; struct strlist *sp; char *path; - int ch; + int ch, i; + int verbose = 0; + int err = 0; for (sp = cmdenviron; sp ; sp = sp->next) setvareq(sp->text, VEXPORT|VSTACK); @@ -979,11 +981,17 @@ optind = optreset = 1; opterr = 0; - while ((ch = getopt(argc, argv, "p")) != -1) { + while ((ch = getopt(argc, argv, "pvV")) != -1) { switch (ch) { case 'p': path = stdpath; break; + case 'v': + verbose = VERBOSE_NAME; + break; + case 'V': + verbose = VERBOSE_DESCR; + break; case '?': default: error("unknown option: -%c", optopt); @@ -993,14 +1001,25 @@ argv += optind; if (argc != 0) { - old = handler; - handler = &loc; - if (setjmp(handler->loc) == 0) - shellexec(argv, environment(), path, 0); - handler = old; - if (exception == EXEXEC) - exit(exerrno); - exraise(exception); + if (verbose > 0) + for (i = 0; i < argc; i++) { + if (verbose == VERBOSE_NAME) + err = name_command(argv[i]); + if (verbose == VERBOSE_DESCR) + err = describe_command(argv[i]); + + return (err); + } + else { + old = handler; + handler = &loc; + if (setjmp(handler->loc) == 0) + shellexec(argv, environment(), path, 0); + handler = old; + if (exception == EXEXEC) + exit(exerrno); + exraise(exception); + } } /* diff -ru bin/sh.orig/eval.h bin/sh/eval.h --- bin/sh.orig/eval.h Wed Aug 3 20:11:02 2005 +++ bin/sh/eval.h Thu Aug 4 09:10:48 2005 @@ -68,3 +68,7 @@ #define SKIPCONT 2 #define SKIPFUNC 3 #define SKIPFILE 4 + +/* verbose levels */ +#define VERBOSE_NAME 5 +#define VERBOSE_DESCR 6 diff -ru bin/sh.orig/exec.c bin/sh/exec.c --- bin/sh.orig/exec.c Wed Aug 3 20:11:02 2005 +++ bin/sh/exec.c Thu Aug 4 10:04:53 2005 @@ -100,6 +100,146 @@ STATIC struct tblentry *cmdlookup(char *, int); STATIC void delete_cmd_entry(void); +int +describe_command(char *command) +{ + struct cmdentry entry; + struct tblentry *cmdp; + char **pp; + struct alias *ap; + int error = 0; + extern char *const parsekwd[]; + + out1str(command); + /* First look at the keywords */ + for (pp = (char **)parsekwd; *pp; pp++) + if (**pp == *command && equal(*pp, command)) + break; + + if (*pp) { + out1str(" is a shell keyword\n"); + return (0); + } + + /* Then look at the aliases */ + if ((ap = lookupalias(command, 1)) != NULL) { + out1fmt(" is an alias for %s\n", ap->val); + return (0); + } + + /* Then check if it is a tracked alias */ + if ((cmdp = cmdlookup(command, 0)) != NULL) { + entry.cmdtype = cmdp->cmdtype; + entry.u = cmdp->param; + } else + /* Finally use brute force */ + find_command(command, &entry, 0, pathval()); + + switch (entry.cmdtype) { + case CMDNORMAL: + if (strchr(command, '/') == NULL) { + char *path = pathval(), *name; + int j = entry.u.index; + do { + name = padvance(&path, command); + stunalloc(name); + } while (--j >= 0); + out1fmt(" is%s %s\n", + cmdp ? " a tracked alias for" : "", name); + } else { + if (access(command, X_OK) == 0) + out1fmt(" is %s\n", command); + else + out1fmt(": %s\n", strerror(errno)); + } + break; + + case CMDFUNCTION: + out1str(" is a shell function\n"); + break; + + case CMDBUILTIN: + out1str(" is a shell builtin\n"); + break; + + default: + out1str(": not found\n"); + error |= 127; + break; + } + return (error); +} + +int +name_command(char *command) +{ + struct cmdentry entry; + struct tblentry *cmdp; + char **pp; + struct alias *ap; + int error = 0; + extern char *const parsekwd[]; + + /* First look at the keywords */ + for (pp = (char **)parsekwd; *pp; pp++) + if (**pp == *command && equal(*pp, command)) + break; + + if (*pp) { + /* for shell keywords: just print it */ + out1fmt("%s\n", command); + return (0); + } + + /* Then look at the aliases */ + if ((ap = lookupalias(command, 1)) != NULL) { + /* for aliases: alias command='value' */ + out1fmt("alias %s='%s'\n", command, ap->val); + return (0); + } + + /* Then check if it is a tracked alias */ + if ((cmdp = cmdlookup(command, 0)) != NULL) { + entry.cmdtype = cmdp->cmdtype; + entry.u = cmdp->param; + } + else + /* Finally use brute force */ + find_command(command, &entry, 0, pathval()); + + switch (entry.cmdtype) { + case CMDNORMAL: + if (strchr(command, '/') == NULL) { + char *path = pathval(), *name; + int j = entry.u.index; + do { + name = padvance(&path, command); + stunalloc(name); + } while (--j >= 0); + out1fmt("%s\n", name); + } else { + if (access(command, X_OK) == 0) + out1fmt("%s\n", command); + else + out1fmt("%s: %s\n", command, strerror(errno)); + } + break; + + case CMDFUNCTION: + out1fmt("%s\n", command); + break; + + case CMDBUILTIN: + out1fmt("%s\n", command); + break; + + default: + out1fmt("%s: not found\n", command); + error |= 127; + break; + } + return (error); +} /* @@ -711,74 +851,11 @@ int typecmd(int argc, char **argv) { - struct cmdentry entry; - struct tblentry *cmdp; - char **pp; - struct alias *ap; int i; int error = 0; - extern char *const parsekwd[]; - - for (i = 1; i < argc; i++) { - out1str(argv[i]); - /* First look at the keywords */ - for (pp = (char **)parsekwd; *pp; pp++) - if (**pp == *argv[i] && equal(*pp, argv[i])) - break; - - if (*pp) { - out1str(" is a shell keyword\n"); - continue; - } - - /* Then look at the aliases */ - if ((ap = lookupalias(argv[i], 1)) != NULL) { - out1fmt(" is an alias for %s\n", ap->val); - continue; - } - - /* Then check if it is a tracked alias */ - if ((cmdp = cmdlookup(argv[i], 0)) != NULL) { - entry.cmdtype = cmdp->cmdtype; - entry.u = cmdp->param; - } - else { - /* Finally use brute force */ - find_command(argv[i], &entry, 0, pathval()); - } - - switch (entry.cmdtype) { - case CMDNORMAL: { - if (strchr(argv[i], '/') == NULL) { - char *path = pathval(), *name; - int j = entry.u.index; - do { - name = padvance(&path, argv[i]); - stunalloc(name); - } while (--j >= 0); - out1fmt(" is%s %s\n", - cmdp ? " a tracked alias for" : "", name); - } else { - if (access(argv[i], X_OK) == 0) - out1fmt(" is %s\n", argv[i]); - else - out1fmt(": %s\n", strerror(errno)); - } - break; - } - case CMDFUNCTION: - out1str(" is a shell function\n"); - break; - case CMDBUILTIN: - out1str(" is a shell builtin\n"); - break; - - default: - out1str(": not found\n"); - error |= 127; - break; - } - } - return error; + for (i = 1; i < argc; i++) + error = describe_command(argv[i]); + + return (error); } diff -ru bin/sh.orig/exec.h bin/sh/exec.h --- bin/sh.orig/exec.h Wed Aug 3 20:11:02 2005 +++ bin/sh/exec.h Thu Aug 4 10:05:46 2005 @@ -65,3 +65,5 @@ int unsetfunc(char *); int typecmd(int, char **); void clearcmdentry(int); +int describe_command(char*); +int name_command(char *);