~emersion/mrsh

4da12aae651dac2f0c6818f54d5d8b5f0a9e8bf6 — Drew DeVault 3 years ago ea3edb5
Implement 'shift' builtin
4 files changed, 52 insertions(+), 0 deletions(-)

M builtin/builtin.c
A builtin/shift.c
M include/builtin.h
M meson.build
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',