M builtin/builtin.c => builtin/builtin.c +1 -0
@@ 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 },
};
A builtin/shift.c => builtin/shift.c +49 -0
@@ 0,0 1,49 @@
+#include <mrsh/builtin.h>
+#include <mrsh/shell.h>
+#include <stdlib.h>
+#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;
+}
M include/builtin.h => include/builtin.h +1 -0
@@ 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[]);
M meson.build => meson.build +1 -0
@@ 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',