9f25cfbdb9f34baef4de0b32b800e168469bbace — Simon Ser 2 months ago 94b53b9
builtin/set: implement set -o to print all options
3 files changed, 23 insertions(+), 8 deletions(-)

M builtin/set.c
M include/builtin.h
M shell/task/word.c
M builtin/set.c => builtin/set.c +21 -6
@@ 9,7 9,11 @@
 #include "builtin.h"
 
 static const char set_usage[] =
-	"usage: set [(-|+)abCefhmnuvx] [-o option] [args...]\n";
+	"usage: set [(-|+)abCefhmnuvx] [-o option] [args...]\n"
+	"       set [(-|+)abCefhmnuvx] [+o option] [args...]\n"
+	"       set -- [args...]\n"
+	"       set -o\n"
+	"       set +o\n";
 
 struct option_map {
 	const char *name;


@@ 34,18 38,29 @@
 	{ "xtrace", 'x', MRSH_OPT_XTRACE },
 };
 
-const char *print_options(struct mrsh_state *state) {
+const char *state_get_options(struct mrsh_state *state) {
 	static char opts[sizeof(options) / sizeof(options[0]) + 1];
 	int i = 0;
 	for (size_t j = 0; j < sizeof(options) / sizeof(options[0]); ++j) {
-		if (options[j].short_name && (state->options & options[j].value)) {
+		if (options[j].short_name != '\0' &&
+				(state->options & options[j].value)) {
 			opts[i++] = options[j].short_name;
 		}
 	}
-	opts[i] = 0;
+	opts[i] = '\0';
 	return opts;
 }
 
+static void print_options(struct mrsh_state *state) {
+	for (size_t j = 0; j < sizeof(options) / sizeof(options[0]); ++j) {
+		if (options[j].name != NULL) {
+			printf("set %co %s\n",
+				(state->options & options[j].value) ? '-' : '+',
+				options[j].name);
+		}
+	}
+}
+
 static const struct option_map *find_option(char opt) {
 	for (size_t i = 0; i < sizeof(options) / sizeof(options[0]); ++i) {
 		if (options[i].short_name && options[i].short_name == opt) {


@@ 117,8 132,8 @@
 		switch (argv[i][1]) {
 		case 'o':
 			if (i + 1 == argc) {
-				fprintf(stderr, set_usage);
-				return 1;
+				print_options(state);
+				return 0;
 			}
 			option = find_long_option(argv[i + 1]);
 			if (!option) {

M include/builtin.h => include/builtin.h +1 -1
@@ 37,6 37,6 @@
 
 int builtin_unspecified(struct mrsh_state *state, int argc, char *argv[]);
 
-const char *print_options(struct mrsh_state *state);
+const char *state_get_options(struct mrsh_state *state);
 
 #endif

M shell/task/word.c => shell/task/word.c +1 -1
@@ 111,7 111,7 @@
 		sprintf(value, "%d", state->last_status);
 		return value;
 	} else if (strcmp(name, "-") == 0) {
-		return print_options(state);
+		return state_get_options(state);
 	} else if (strcmp(name, "$") == 0) {
 		sprintf(value, "%d", (int)getpid());
 		return value;