From 4da12aae651dac2f0c6818f54d5d8b5f0a9e8bf6 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 29 Sep 2018 16:28:53 -0400 Subject: [PATCH] Implement 'shift' builtin --- builtin/builtin.c | 1 + builtin/shift.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ include/builtin.h | 1 + meson.build | 1 + 4 files changed, 52 insertions(+) create mode 100644 builtin/shift.c diff --git a/builtin/builtin.c b/builtin/builtin.c index 4e9a07c..bb42ca9 100644 --- a/builtin/builtin.c +++ b/builtin/builtin.c @@ -22,6 +22,7 @@ static const struct builtin builtins[] = { { "exit", builtin_exit, true }, { "false", builtin_false, false }, { "set", builtin_set, true }, + { "shift", builtin_shift, true }, { "times", builtin_times, true }, { "true", builtin_true, false }, }; diff --git a/builtin/shift.c b/builtin/shift.c new file mode 100644 index 0000000..0289813 --- /dev/null +++ b/builtin/shift.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include "builtin.h" + +static const char shift_usage[] = "usage: shift [n]\n"; + +int builtin_shift(struct mrsh_state *state, int argc, char *argv[]) { + if (argc > 2) { + fprintf(stderr, shift_usage); + return EXIT_FAILURE; + } + int n = 1; + if (argc == 2) { + char *endptr; + n = strtol(argv[1], &endptr, 10); + if (*endptr != '\0') { + fprintf(stderr, shift_usage); + if (!state->interactive) { + state->exit = EXIT_FAILURE; + } + return EXIT_FAILURE; + } + } + if (n == 0) { + return EXIT_SUCCESS; + } else if (n < 1) { + fprintf(stderr, "shift: [n] must be positive\n"); + if (!state->interactive) { + state->exit = EXIT_FAILURE; + } + return EXIT_FAILURE; + } else if (n > state->argc - 1) { + fprintf(stderr, "shift: [n] must be less than $#\n"); + if (!state->interactive) { + state->exit = EXIT_FAILURE; + } + return EXIT_FAILURE; + } + for (int i = 1, j = n + 1; j < state->argc; ++i, ++j) { + if (j <= state->argc - n) { + state->argv[i] = state->argv[j]; + } else { + free(state->argv[i]); + } + } + state->argc -= n; + return EXIT_SUCCESS; +} diff --git a/include/builtin.h b/include/builtin.h index 8ca90e4..07925e7 100644 --- a/include/builtin.h +++ b/include/builtin.h @@ -13,6 +13,7 @@ int builtin_cd(struct mrsh_state *state, int argc, char *argv[]); int builtin_colon(struct mrsh_state *state, int argc, char *argv[]); int builtin_exit(struct mrsh_state *state, int argc, char *argv[]); int builtin_eval(struct mrsh_state *state, int argc, char *argv[]); +int builtin_shift(struct mrsh_state *state, int argc, char *argv[]); int builtin_source(struct mrsh_state *state, int argc, char *argv[]); int builtin_times(struct mrsh_state *state, int argc, char *argv[]); int builtin_set(struct mrsh_state *state, int argc, char *argv[]); diff --git a/meson.build b/meson.build index 45d2c42..d0a665c 100644 --- a/meson.build +++ b/meson.build @@ -39,6 +39,7 @@ lib_mrsh = library( 'builtin/eval.c', 'builtin/exit.c', 'builtin/set.c', + 'builtin/shift.c', 'builtin/source.c', 'builtin/times.c', 'builtin/true.c', -- 2.38.5