diff --git a/ChangeLog b/ChangeLog index c8e169879..2fc8d746b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2014-01-11 Peter Stephenson + + * 32246: Doc/Zsh/builtins.yo, Src/builtin.c, Test/.distfiles, + Test/B08shift.ztst: add "shift -p" to pop arguments from the end + of arrays. + 2014-01-10 Peter Stephenson * Koen Wilde: 32245: Completion/Unix/Command/_mpc: complete more diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 8c7bc85ea..ea2f68d10 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1500,12 +1500,15 @@ POSIX standard, but tt(setopt) is not. ) findex(shift) cindex(parameters, positional) -item(tt(shift) [ var(n) ] [ var(name) ... ])( +item(tt(shift) [ tt(-p) ] [ var(n) ] [ var(name) ... ])( The positional parameters tt(${)var(n)PLUS()1tt(}) ... are renamed to tt($1) ..., where var(n) is an arithmetic expression that defaults to 1. If any var(name)s are given then the arrays with these names are shifted instead of the positional parameters. + +If the option tt(-p) is given arguments are instead removed (popped) +from the end rather than the start of the array. ) findex(source) item(tt(source) var(file) [ var(arg) ... ])( diff --git a/Src/builtin.c b/Src/builtin.c index c3f0169c7..9bcbcf707 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -111,7 +111,7 @@ static struct builtin builtins[] = BUILTIN("return", BINF_PSPECIAL, bin_break, 0, 1, BIN_RETURN, NULL, NULL), BUILTIN("set", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_set, 0, -1, 0, NULL, NULL), BUILTIN("setopt", 0, bin_setopt, 0, -1, BIN_SETOPT, NULL, NULL), - BUILTIN("shift", BINF_PSPECIAL, bin_shift, 0, -1, 0, NULL, NULL), + BUILTIN("shift", BINF_PSPECIAL, bin_shift, 0, -1, 0, "p", NULL), BUILTIN("source", BINF_PSPECIAL, bin_dot, 1, -1, 0, NULL, NULL), BUILTIN("suspend", 0, bin_suspend, 0, 0, 0, "f", NULL), BUILTIN("test", BINF_HANDLES_OPTS, bin_test, 0, -1, BIN_TEST, NULL, NULL), @@ -4509,7 +4509,7 @@ bin_print(char *name, char **args, Options ops, int func) /**/ int -bin_shift(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) +bin_shift(char *name, char **argv, Options ops, UNUSED(int func)) { int num = 1, l, ret = 0; char **s; @@ -4533,7 +4533,19 @@ bin_shift(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) ret++; continue; } - s = zarrdup(s + num); + if (OPT_ISSET(ops,'p')) { + char **s2, **src, **dst; + int count; + l = arrlen(s); + src = s; + dst = s2 = (char **)zalloc((l - num + 1) * sizeof(char *)); + for (count = l - num; count; count--) + *dst++ = ztrdup(*src++); + *dst = NULL; + s = s2; + } else { + s = zarrdup(s + num); + } setaparam(*argv, s); } } else { @@ -4542,9 +4554,16 @@ bin_shift(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) ret = 1; } else { s = zalloc((l - num + 1) * sizeof(char *)); - memcpy(s, pparams + num, (l - num + 1) * sizeof(char *)); - while (num--) - zsfree(pparams[num]); + if (OPT_ISSET(ops,'p')) { + memcpy(s, pparams, (l - num) * sizeof(char *)); + s[l-num] = NULL; + while (num--) + zsfree(pparams[l-1-num]); + } else { + memcpy(s, pparams + num, (l - num + 1) * sizeof(char *)); + while (num--) + zsfree(pparams[num]); + } zfree(pparams, (l + 1) * sizeof(char *)); pparams = s; } diff --git a/Test/.distfiles b/Test/.distfiles index 1c0102818..5826e7574 100644 --- a/Test/.distfiles +++ b/Test/.distfiles @@ -15,6 +15,7 @@ B04read.ztst B05eval.ztst B06fc.ztst B07emulate.ztst +B08shift.ztst C01arith.ztst C02cond.ztst C03traps.ztst diff --git a/Test/B08shift.ztst b/Test/B08shift.ztst index e69de29bb..0aa922673 100644 --- a/Test/B08shift.ztst +++ b/Test/B08shift.ztst @@ -0,0 +1,33 @@ +# Test the shift builtin. + +%test + + set -- one two three four five six seven eight nine ten + shift + print $* + shift 2 + print $* + shift -p 3 + print $* + shift -p + print $* +0:shifting positional parameters +>two three four five six seven eight nine ten +>four five six seven eight nine ten +>four five six seven +>four five six + + array=(yan tan tether mether pip azer sezar akker conter dick) + shift 2 array + print $array + shift array + print $array + shift -p 3 array + print $array + shift -p array + print $array +0:shifting array +>tether mether pip azer sezar akker conter dick +>mether pip azer sezar akker conter dick +>mether pip azer sezar +>mether pip azer