diff options
author | jilles <jilles@FreeBSD.org> | 2014-01-26 21:19:33 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2014-01-26 21:19:33 +0000 |
commit | 9b565c0250634c44a36639e518e7ca3ba7a88ebd (patch) | |
tree | b13e00aabd499f2e76efcb8c8749c5884decc848 /bin | |
parent | 51348c881e5f79078f88a6d96345fa6b4798b378 (diff) | |
download | FreeBSD-src-9b565c0250634c44a36639e518e7ca3ba7a88ebd.zip FreeBSD-src-9b565c0250634c44a36639e518e7ca3ba7a88ebd.tar.gz |
sh: Allow aliases to force alias substitution on the following word.
If an alias's value ends with a space or tab, the next word is also
checked for aliases.
This is a POSIX feature. It is useful with utilities like command and
nohup (alias them to themselves followed by a space).
Diffstat (limited to 'bin')
-rw-r--r-- | bin/sh/input.c | 8 | ||||
-rw-r--r-- | bin/sh/parser.c | 6 | ||||
-rw-r--r-- | bin/sh/parser.h | 1 | ||||
-rw-r--r-- | bin/sh/sh.1 | 16 | ||||
-rw-r--r-- | bin/sh/tests/parser/Makefile | 2 | ||||
-rw-r--r-- | bin/sh/tests/parser/alias14.0 | 6 | ||||
-rw-r--r-- | bin/sh/tests/parser/alias15.0 | 12 | ||||
-rw-r--r-- | bin/sh/tests/parser/alias15.0.stdout | 4 |
8 files changed, 52 insertions, 3 deletions
diff --git a/bin/sh/input.c b/bin/sh/input.c index da225bc..05cc1eb 100644 --- a/bin/sh/input.c +++ b/bin/sh/input.c @@ -367,12 +367,16 @@ popstring(void) struct strpush *sp = parsefile->strpush; INTOFF; + if (sp->ap) { + if (parsenextc != sp->ap->val && + (parsenextc[-1] == ' ' || parsenextc[-1] == '\t')) + forcealias(); + sp->ap->flag &= ~ALIASINUSE; + } parsenextc = sp->prevstring; parsenleft = sp->prevnleft; parselleft = sp->prevlleft; /*out2fmt_flush("*** calling popstring: restoring to '%s'\n", parsenextc);*/ - if (sp->ap) - sp->ap->flag &= ~ALIASINUSE; parsefile->strpush = sp->prev; if (sp != &(parsefile->basestrpush)) ckfree(sp); diff --git a/bin/sh/parser.c b/bin/sh/parser.c index a0def64..e6e9f82 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -683,6 +683,12 @@ makebinary(int type, union node *n1, union node *n2) } void +forcealias(void) +{ + checkkwd |= CHKALIAS; +} + +void fixredir(union node *n, const char *text, int err) { TRACE(("Fix redir %s %d\n", text, err)); diff --git a/bin/sh/parser.h b/bin/sh/parser.h index d500d2f..5982594 100644 --- a/bin/sh/parser.h +++ b/bin/sh/parser.h @@ -76,6 +76,7 @@ extern const char *const parsekwd[]; union node *parsecmd(int); +void forcealias(void); void fixredir(union node *, const char *, int); int goodname(const char *); int isassignment(const char *); diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index dc1716c..fb8328c 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -32,7 +32,7 @@ .\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95 .\" $FreeBSD$ .\" -.Dd January 3, 2014 +.Dd January 26, 2014 .Dt SH 1 .Os .Sh NAME @@ -533,6 +533,20 @@ would become .Pp .Dl "ls -F foobar" .Pp +Aliases are also recognized after an alias +whose value ends with a space or tab. +For example, if there is also an alias called +.Dq Li nohup +with the value +.Dq Li "nohup " , +then the input +.Pp +.Dl "nohup lf foobar" +.Pp +would become +.Pp +.Dl "nohup ls -F foobar" +.Pp Aliases provide a convenient way for naive users to create shorthands for commands without having to learn how to create functions with arguments. diff --git a/bin/sh/tests/parser/Makefile b/bin/sh/tests/parser/Makefile index 6803de3..03650b1 100644 --- a/bin/sh/tests/parser/Makefile +++ b/bin/sh/tests/parser/Makefile @@ -18,6 +18,8 @@ FILES+= alias10.0 FILES+= alias11.0 FILES+= alias12.0 FILES+= alias13.0 +FILES+= alias14.0 +FILES+= alias15.0 alias15.0.stdout FILES+= and-pipe-not.0 FILES+= case1.0 FILES+= case2.0 diff --git a/bin/sh/tests/parser/alias14.0 b/bin/sh/tests/parser/alias14.0 new file mode 100644 index 0000000..1b92fc0 --- /dev/null +++ b/bin/sh/tests/parser/alias14.0 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +alias command='command ' +alias alias0=exit +eval 'command alias0 0' +exit 3 diff --git a/bin/sh/tests/parser/alias15.0 b/bin/sh/tests/parser/alias15.0 new file mode 100644 index 0000000..f0fbadb --- /dev/null +++ b/bin/sh/tests/parser/alias15.0 @@ -0,0 +1,12 @@ +# $FreeBSD$ + +f_echoanddo() { + printf '%s\n' "$*" + "$@" +} + +alias echoanddo='f_echoanddo ' +alias alias0='echo test2' +eval 'echoanddo echo test1' +eval 'echoanddo alias0' +exit 0 diff --git a/bin/sh/tests/parser/alias15.0.stdout b/bin/sh/tests/parser/alias15.0.stdout new file mode 100644 index 0000000..6dd179c --- /dev/null +++ b/bin/sh/tests/parser/alias15.0.stdout @@ -0,0 +1,4 @@ +echo test1 +test1 +echo test2 +test2 |