~emersion/mrsh-dev

mrsh_getopt: handle repeated short options v1 PROPOSED

Drew DeVault: 1
 mrsh_getopt: handle repeated short options

 11 files changed, 25 insertions(+), 14 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~emersion/mrsh-dev/patches/3642/mbox | git am -3
Learn more about email & git

[PATCH] mrsh_getopt: handle repeated short options Export this patch

This handles cases like cmd -arvx (where optstring is "arvx"). This also
changes the reset to mrsh_optind = 0, matching non-POSIX extensions in
various libcs, so that the user needn't also reset mrsh_optpos (which is
not exported from this file).
---
 builtin/alias.c   |  2 +-
 builtin/cd.c      |  2 +-
 builtin/getopts.c |  2 +-
 builtin/pwd.c     |  2 +-
 builtin/read.c    |  2 +-
 builtin/type.c    |  2 +-
 builtin/ulimit.c  |  2 +-
 builtin/umask.c   |  2 +-
 builtin/unalias.c |  2 +-
 builtin/unset.c   |  2 +-
 getopt.c          | 19 +++++++++++++++----
 11 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/builtin/alias.c b/builtin/alias.c
index a55f446..1a5e2a7 100644
--- a/builtin/alias.c
@@ -17,7 +17,7 @@ static void print_alias_iterator(const char *key, void *_value,
}

int builtin_alias(struct mrsh_state *state, int argc, char *argv[]) {
	mrsh_optind = 1;
	mrsh_optind = 0;
	if (mrsh_getopt(argc, argv, ":") != -1) {
		fprintf(stderr, "alias: unknown option -- %c\n", mrsh_optopt);
		fprintf(stderr, alias_usage);
diff --git a/builtin/cd.c b/builtin/cd.c
index d0536a1..e977298 100644
--- a/builtin/cd.c
@@ -37,7 +37,7 @@ static int isdir(char *path) {
}

int builtin_cd(struct mrsh_state *state, int argc, char *argv[]) {
	mrsh_optind = 1;
	mrsh_optind = 0;
	int opt;
	while ((opt = mrsh_getopt(argc, argv, ":LP")) != -1) {
		switch (opt) {
diff --git a/builtin/getopts.c b/builtin/getopts.c
index b1d0519..80b8e08 100644
--- a/builtin/getopts.c
@@ -12,7 +12,7 @@
static const char getopts_usage[] = "usage: getopts optstring name [arg...]\n";

int builtin_getopts(struct mrsh_state *state, int argc, char *argv[]) {
	mrsh_optind = 1;
	mrsh_optind = 0;
	if (mrsh_getopt(argc, argv, ":") != -1) {
		fprintf(stderr, "getopts: unknown option -- %c\n", mrsh_optopt);
		fprintf(stderr, getopts_usage);
diff --git a/builtin/pwd.c b/builtin/pwd.c
index 19f380a..796340d 100644
--- a/builtin/pwd.c
@@ -8,7 +8,7 @@
static const char pwd_usage[] = "usage: pwd [-L|-P]\n";

int builtin_pwd(struct mrsh_state *state, int argc, char *argv[]) {
	mrsh_optind = 1;
	mrsh_optind = 0;
	int opt;
	while ((opt = mrsh_getopt(argc, argv, ":LP")) != -1) {
		switch (opt) {
diff --git a/builtin/read.c b/builtin/read.c
index 83f8d91..b79471f 100644
--- a/builtin/read.c
@@ -14,7 +14,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;

	mrsh_optind = 1;
	mrsh_optind = 0;
	int opt;
	while ((opt = mrsh_getopt(argc, argv, ":r")) != -1) {
		switch (opt) {
diff --git a/builtin/type.c b/builtin/type.c
index db082b7..739349d 100644
--- a/builtin/type.c
@@ -9,7 +9,7 @@
static const char type_usage[] = "usage: type name...\n";

int builtin_type(struct mrsh_state *state, int argc, char *argv[]) {
	mrsh_optind = 1;
	mrsh_optind = 0;
	if (mrsh_getopt(argc, argv, ":") != -1) {
		fprintf(stderr, "type: unknown option -- %c\n", mrsh_optopt);
		fprintf(stderr, type_usage);
diff --git a/builtin/ulimit.c b/builtin/ulimit.c
index 37b2e53..a33e880 100644
--- a/builtin/ulimit.c
@@ -14,7 +14,7 @@
static const char ulimit_usage[] = "usage: ulimit [-f] [blocks]\n";

int builtin_ulimit(struct mrsh_state *state, int argc, char *argv[]) {
	mrsh_optind = 1;
	mrsh_optind = 0;
	int opt;
	while ((opt = mrsh_getopt(argc, argv, ":f")) != -1) {
		if (opt == 'f') {
diff --git a/builtin/umask.c b/builtin/umask.c
index 11963d5..777ddb0 100644
--- a/builtin/umask.c
@@ -162,7 +162,7 @@ int builtin_umask(struct mrsh_state *state, int argc, char *argv[]) {
	mode_t mode;
	bool umask_symbolic = false;

	mrsh_optind = 1;
	mrsh_optind = 0;
	int opt;

	while ((opt = mrsh_getopt(argc, argv, ":S")) != -1) {
diff --git a/builtin/unalias.c b/builtin/unalias.c
index 8ff55ee..8590824 100644
--- a/builtin/unalias.c
@@ -15,7 +15,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;

	mrsh_optind = 1;
	mrsh_optind = 0;
	int opt;
	while ((opt = mrsh_getopt(argc, argv, ":a")) != -1) {
		switch (opt) {
diff --git a/builtin/unset.c b/builtin/unset.c
index 14a0e6e..b522624 100644
--- a/builtin/unset.c
@@ -11,7 +11,7 @@ static const char unset_usage[] = "usage: unset [-fv] name...\n";
int builtin_unset(struct mrsh_state *state, int argc, char *argv[]) {
	bool funcs = false;

	mrsh_optind = 1;
	mrsh_optind = 0;
	int opt;
	while ((opt = mrsh_getopt(argc, argv, ":fv")) != -1) {
		switch (opt) {
diff --git a/getopt.c b/getopt.c
index 0d4eba1..926ad76 100644
--- a/getopt.c
+++ b/getopt.c
@@ -7,11 +7,17 @@ char *mrsh_optarg = NULL;
int mrsh_optind = 1;
int mrsh_opterr = 1;
int mrsh_optopt = 0;
int mrsh_optpos = 1;

int mrsh_getopt(int argc, char *const argv[], const char *optstring) {
	assert(argv[argc] == NULL);
	mrsh_optarg = NULL;

	if (mrsh_optind == 0) {
		mrsh_optind = 1;
		mrsh_optpos = 1;
	}

	if (mrsh_optind >= argc) {
		return -1;
	}
@@ -35,19 +41,24 @@ int mrsh_getopt(int argc, char *const argv[], const char *optstring) {
	}

	mrsh_optopt = 0;
	int opt = argv[mrsh_optind][1];
	int opt = argv[mrsh_optind][mrsh_optpos];
	for (; *c != '\0'; c++) {
		if (*c != opt) {
			continue;
		}

		if (c[1] != ':') {
			mrsh_optind++;
			if (argv[mrsh_optind][mrsh_optpos + 1] == '\0') {
				mrsh_optind++;
				mrsh_optpos = 1;
			} else {
				mrsh_optpos++;
			}
			return opt;
		}

		if (argv[mrsh_optind][2] != '\0') {
			mrsh_optarg = &argv[mrsh_optind][2]; 
		if (argv[mrsh_optind][mrsh_optpos + 1] != '\0') {
			mrsh_optarg = &argv[mrsh_optind][mrsh_optpos];
		} else {
			if (mrsh_optind + 2 > argc) {
				mrsh_optopt = opt;
-- 
2.21.0
View this thread in the archives