From b2f153feaf51cf8568b124b2e3192aa25e50b30c Mon Sep 17 00:00:00 2001 From: Stefan Farfeleder Date: Fri, 28 Oct 2005 18:37:09 +0000 Subject: [PATCH] Add the POSIX options -v and -V to the 'command' builtin. Both describe the type of their argument, if it is a shell function, an alias, a builtin, etc. -V is more verbose than -v. PR: 77259, 84539 --- bin/sh/eval.c | 14 +++++++++++- bin/sh/exec.c | 59 ++++++++++++++++++++++++++++++++++++++++----------- bin/sh/exec.h | 7 ++++++ 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/bin/sh/eval.c b/bin/sh/eval.c index ddf227526ad9..fecc4de6199d 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -976,6 +976,7 @@ commandcmd(int argc, char **argv) struct strlist *sp; char *path; int ch; + int cmd = -1; for (sp = cmdenviron; sp ; sp = sp->next) setvareq(sp->text, VEXPORT|VSTACK); @@ -983,11 +984,17 @@ commandcmd(int argc, char **argv) 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': + cmd = TYPECMD_SMALLV; + break; + case 'V': + cmd = TYPECMD_BIGV; + break; case '?': default: error("unknown option: -%c", optopt); @@ -996,6 +1003,11 @@ commandcmd(int argc, char **argv) argc -= optind; argv += optind; + if (cmd != -1) { + if (argc != 1) + error("wrong number of arguments"); + return typecmd_impl(2, argv - 1, cmd); + } if (argc != 0) { old = handler; handler = &loc; diff --git a/bin/sh/exec.c b/bin/sh/exec.c index 55e3fec543c3..d983849ff631 100644 --- a/bin/sh/exec.c +++ b/bin/sh/exec.c @@ -705,11 +705,12 @@ unsetfunc(char *name) } /* - * Locate and print what a word is... + * Shared code for the following builtin commands: + * type, command -v, command -V */ int -typecmd(int argc, char **argv) +typecmd_impl(int argc, char **argv, int cmd) { struct cmdentry entry; struct tblentry *cmdp; @@ -720,20 +721,28 @@ typecmd(int argc, char **argv) extern char *const parsekwd[]; for (i = 1; i < argc; i++) { - out1str(argv[i]); + if (cmd != TYPECMD_SMALLV) + 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"); + if (cmd == TYPECMD_SMALLV) + out1fmt("%s\n", argv[i]); + else + 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); + if (cmd == TYPECMD_SMALLV) + out1fmt("alias %s='%s'\n", argv[i], ap->val); + else + out1fmt(" is an alias for %s\n", ap->val); continue; } @@ -756,29 +765,55 @@ typecmd(int argc, char **argv) name = padvance(&path, argv[i]); stunalloc(name); } while (--j >= 0); - out1fmt(" is%s %s\n", - cmdp ? " a tracked alias for" : "", name); + if (cmd == TYPECMD_SMALLV) + out1fmt("%s\n", name); + else + out1fmt(" is%s %s\n", + (cmdp && cmd == TYPECMD_TYPE) ? + " a tracked alias for" : "", + name); } else { - if (access(argv[i], X_OK) == 0) - out1fmt(" is %s\n", argv[i]); + if (access(argv[i], X_OK) == 0) { + if (cmd == TYPECMD_SMALLV) + out1fmt("%s\n", argv[i]); + else + out1fmt(" is %s\n", argv[i]); + } else out1fmt(": %s\n", strerror(errno)); } break; } case CMDFUNCTION: - out1str(" is a shell function\n"); + if (cmd == TYPECMD_SMALLV) + out1fmt("%s\n", argv[i]); + else + out1str(" is a shell function\n"); break; case CMDBUILTIN: - out1str(" is a shell builtin\n"); + if (cmd == TYPECMD_SMALLV) + out1fmt("%s\n", argv[i]); + else + out1str(" is a shell builtin\n"); break; default: - out1str(": not found\n"); + if (cmd != TYPECMD_SMALLV) + out1str(": not found\n"); error |= 127; break; } } return error; } + +/* + * Locate and print what a word is... + */ + +int +typecmd(int argc, char **argv) +{ + return typecmd_impl(argc, argv, TYPECMD_TYPE); +} diff --git a/bin/sh/exec.h b/bin/sh/exec.h index 7542a534b4d0..429bfda7a5a9 100644 --- a/bin/sh/exec.h +++ b/bin/sh/exec.h @@ -39,6 +39,12 @@ #define CMDBUILTIN 1 /* command is a shell builtin */ #define CMDFUNCTION 2 /* command is a shell function */ +/* values for typecmd_impl's third parameter */ +enum { + TYPECMD_SMALLV, /* command -v */ + TYPECMD_BIGV, /* command -V */ + TYPECMD_TYPE /* type */ +}; struct cmdentry { int cmdtype; @@ -63,5 +69,6 @@ void deletefuncs(void); void addcmdentry(char *, struct cmdentry *); void defun(char *, union node *); int unsetfunc(char *); +int typecmd_impl(int, char **, int); int typecmd(int, char **); void clearcmdentry(int);