~emersion/mrsh

f32a4580ddd5ace7946ab8eca36326ddee289eca — emersion 3 years ago 2379126
builtin: minor adjustements

* Fix usage strings
* Remove trailing whitespace
* Remove implicit long to int conversion
* Check errno when calling strtol
M builtin/alias.c => builtin/alias.c +1 -1
@@ 23,7 23,7 @@ int builtin_alias(struct mrsh_state *state, int argc, char *argv[]) {
		fprintf(stderr, alias_usage);
		return EXIT_FAILURE;
	}
	

	if (optind == argc) {
		mrsh_hashtable_for_each(&state->aliases, print_alias_iterator, NULL);
		return EXIT_SUCCESS;

M builtin/cd.c => builtin/cd.c +3 -3
@@ 9,7 9,7 @@
#include <unistd.h>
#include "builtin.h"

static const char cd_usage[] = "usage: cd [-|[-L|-P] directory]\n";
static const char cd_usage[] = "usage: cd [-L|-P] [-|directory]\n";

static int cd(struct mrsh_state *state, const char *path) {
	const char *oldPWD = mrsh_env_get(state, "PWD", NULL);


@@ 55,7 55,7 @@ int builtin_cd(struct mrsh_state *state, int argc, char *argv[]) {
		fprintf(stderr, cd_usage);
		return EXIT_FAILURE;
	}
	

	if (optind == argc) {
		const char *home = mrsh_env_get(state, "HOME", NULL);
		if (home && home[0] != '\0') {


@@ 65,7 65,7 @@ int builtin_cd(struct mrsh_state *state, int argc, char *argv[]) {
			"is not defined.\n");
		return EXIT_FAILURE;
	}
	

	char *curpath = argv[optind];
	// `cd -`
	if (strcmp(curpath, "-") == 0) {

M builtin/colon.c => builtin/colon.c +1 -2
@@ 3,6 3,5 @@
#include "builtin.h"

int builtin_colon(struct mrsh_state *state, int argc, char *argv[]) {
	/* this builtin does not do anything */
	return EXIT_SUCCESS;
	return EXIT_SUCCESS; // This builtin does not do anything
}

M builtin/exit.c => builtin/exit.c +6 -2
@@ 1,3 1,4 @@
#include <errno.h>
#include <mrsh/builtin.h>
#include <stdio.h>
#include <stdlib.h>


@@ 14,11 15,14 @@ int builtin_exit(struct mrsh_state *state, int argc, char *argv[]) {
	int status = 0;
	if (argc > 1) {
		char *endptr;
		status = strtol(argv[1], &endptr, 10);
		if (endptr[0] != '\0' || status < 0 || status > 255) {
		errno = 0;
		long status_long = strtol(argv[1], &endptr, 10);
		if (endptr[0] != '\0' || errno != 0 ||
				status_long < 0 || status_long > 255) {
			fprintf(stderr, exit_usage);
			return EXIT_FAILURE;
		}
		status = (int)status_long;
	}

	state->exit = status;

M builtin/export.c => builtin/export.c +1 -1
@@ 5,7 5,7 @@
#include <string.h>
#include "builtin.h"

static const char export_usage[] = "usage: %s (-p|name[=word]...)\n";
static const char export_usage[] = "usage: %s -p|name[=word]...\n";

int builtin_export(struct mrsh_state *state, int argc, char *argv[]) {
	uint32_t attrib = MRSH_VAR_ATTRIB_EXPORT;

M builtin/getopts.c => builtin/getopts.c +6 -6
@@ 34,7 34,7 @@ int builtin_getopts(struct mrsh_state *state, int argc, char *argv[]) {
	}
	char *optstring = argv[optind];
	char *name = argv[optind + 1];
	

	const char *optind_str = mrsh_env_get(state, "OPTIND", NULL);
	if (optind_str == NULL) {
		fprintf(stderr, "getopts: OPTIND is not defined\n");


@@ 47,14 47,14 @@ int builtin_getopts(struct mrsh_state *state, int argc, char *argv[]) {
		return EXIT_FAILURE;
	}
	optind = (int)optind_long;
	

	optopt = 0;
	int opt = getopt(optc, optv, optstring);
	

	char optind_fmt[16];
	snprintf(optind_fmt, sizeof(optind_fmt), "%d", optind);
	mrsh_env_set(state, "OPTIND", optind_fmt, MRSH_VAR_ATTRIB_NONE);
	

	if (optopt != 0) {
		if (opt == ':') {
			char value[] = {(char)optopt, '\0'};


@@ 85,10 85,10 @@ int builtin_getopts(struct mrsh_state *state, int argc, char *argv[]) {
	} else {
		mrsh_env_unset(state, "OPTARG");
	}
	

	char value[] = {opt == -1 ? (char)'?' : (char)opt, '\0'};
	mrsh_env_set(state, name, value, MRSH_VAR_ATTRIB_NONE);
	

	if (opt == -1) {
		return EXIT_FAILURE;
	}

M builtin/pwd.c => builtin/pwd.c +1 -1
@@ 27,7 27,7 @@ int builtin_pwd(struct mrsh_state *state, int argc, char *argv[]) {
		fprintf(stderr, pwd_usage);
		return EXIT_FAILURE;
	}
	

	const char *pwd = mrsh_env_get(state, "PWD", NULL);
	if (pwd == NULL) {
		fprintf(stderr, "pwd: Cannot return current directory as PWD was unset\n");

M builtin/read.c => builtin/read.c +5 -5
@@ 13,7 13,7 @@ static const char read_usage[] = "usage: read [-r] var...\n";

int builtin_read(struct mrsh_state *state, int argc, char *argv[]) {
	bool raw = false;
	

	optind = 1;
	int opt;
	while ((opt = getopt(argc, argv, ":r")) != -1) {


@@ 31,7 31,7 @@ int builtin_read(struct mrsh_state *state, int argc, char *argv[]) {
		fprintf(stderr, read_usage);
		return EXIT_FAILURE;
	}
	

	struct mrsh_buffer buf = {0};
	bool escaped = false;
	int c;


@@ 53,9 53,9 @@ int builtin_read(struct mrsh_state *state, int argc, char *argv[]) {
		mrsh_buffer_append_char(&buf, (char)c);
	}
	mrsh_buffer_append_char(&buf, '\0');
	

	struct mrsh_array fields = {0};
	

	struct mrsh_word_string *ws = mrsh_word_string_create(mrsh_buffer_steal(&buf), false);
	split_fields(&fields, &ws->word, mrsh_env_get(state, "IFS", NULL));
	mrsh_word_destroy(&ws->word);


@@ 84,7 84,7 @@ int builtin_read(struct mrsh_state *state, int argc, char *argv[]) {
		mrsh_env_set(state, argv[argc - 1], buf_last.data, MRSH_VAR_ATTRIB_NONE);
		mrsh_buffer_finish(&buf_last);
	}
	

	for (size_t i = 0; i < fields.len; ++i) {
		free(fields.data[i]);
	}

M builtin/shift.c => builtin/shift.c +5 -2
@@ 1,3 1,4 @@
#include <errno.h>
#include <mrsh/builtin.h>
#include <mrsh/shell.h>
#include <stdlib.h>


@@ 13,14 14,16 @@ int builtin_shift(struct mrsh_state *state, int argc, char *argv[]) {
	int n = 1;
	if (argc == 2) {
		char *endptr;
		n = strtol(argv[1], &endptr, 10);
		if (*endptr != '\0') {
		errno = 0;
		long n_long = strtol(argv[1], &endptr, 10);
		if (*endptr != '\0' || errno != 0) {
			fprintf(stderr, shift_usage);
			if (!state->interactive) {
				state->exit = EXIT_FAILURE;
			}
			return EXIT_FAILURE;
		}
		n = (int)n_long;
	}
	if (n == 0) {
		return EXIT_SUCCESS;

M builtin/type.c => builtin/type.c +5 -5
@@ 23,27 23,27 @@ int builtin_type(struct mrsh_state *state, int argc, char *argv[]) {
	bool error = false;
	for (int i = optind; i < argc; ++i) {
		char *name = argv[i];
		

		char *alias = mrsh_hashtable_get(&state->aliases, name);
		if (alias != NULL) {
			fprintf(stdout, "%s is an alias for %s\n", name, alias);
			continue;
		}
		

		if (mrsh_has_builtin(name)) {
			fprintf(stdout, "%s is a shell builtin\n", name);
			continue;
		}
		

		const char *path = expand_path(state, name, true);
		if (path) {
			fprintf(stdout, "%s is %s\n", name, path);
			continue;
		}
		

		fprintf(stdout, "%s: not found\n", name);
		error = true;
	}
	

	return error ? EXIT_FAILURE : EXIT_SUCCESS;
}

M builtin/unalias.c => builtin/unalias.c +4 -4
@@ 6,7 6,7 @@
#include <string.h>
#include "builtin.h"

static const char unalias_usage[] = "usage: unalias <-a|alias-name...>\n";
static const char unalias_usage[] = "usage: unalias -a|alias-name...\n";

static void delete_alias_iterator(const char *key, void *_value, void *user_data) {
	free(mrsh_hashtable_del((struct mrsh_hashtable*)user_data, key));


@@ 14,7 14,7 @@ static void delete_alias_iterator(const char *key, void *_value, void *user_data

int builtin_unalias(struct mrsh_state *state, int argc, char *argv[]) {
	bool all = false;
	

	optind = 1;
	int opt;
	while ((opt = getopt(argc, argv, ":a")) != -1) {


@@ 28,7 28,7 @@ int builtin_unalias(struct mrsh_state *state, int argc, char *argv[]) {
			return EXIT_FAILURE;
		}
	}
	

	if (all) {
		if (optind < argc) {
			fprintf(stderr, unalias_usage);


@@ 37,7 37,7 @@ int builtin_unalias(struct mrsh_state *state, int argc, char *argv[]) {
		mrsh_hashtable_for_each(&state->aliases, delete_alias_iterator, &state->aliases);
		return EXIT_SUCCESS;
	}
	

	if (optind == argc) {
		fprintf(stderr, unalias_usage);
		return EXIT_FAILURE;