diff options
author | stefanf <stefanf@FreeBSD.org> | 2005-10-28 18:37:09 +0000 |
---|---|---|
committer | stefanf <stefanf@FreeBSD.org> | 2005-10-28 18:37:09 +0000 |
commit | 21aa82a5ae17d4a50a4fa35697043c3434de308a (patch) | |
tree | 0e857bf6739f08f4e56d9fa1aee34ddce7a13452 | |
parent | 85be5dff385854a1208209ce69c374ab63970002 (diff) | |
download | FreeBSD-src-21aa82a5ae17d4a50a4fa35697043c3434de308a.zip FreeBSD-src-21aa82a5ae17d4a50a4fa35697043c3434de308a.tar.gz |
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
-rw-r--r-- | bin/sh/eval.c | 14 | ||||
-rw-r--r-- | bin/sh/exec.c | 59 | ||||
-rw-r--r-- | 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 ddf2275..fecc4de 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 55e3fec..d983849 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 7542a53..429bfda 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); |