Commits

Michał Górny  committed bcf096b

Remove 'optarg' from main code, use value-return union instead.

  • Participants
  • Parent commits a6ccd6f

Comments (0)

Files changed (3)

File mirage-getopt.c

 
 #ifndef NO_GETOPT_LONG
 #	define _GNU_SOURCE 1
-#	include <stdlib.h>
 #	include <getopt.h>
 #else
 #	define _ISOC99_SOURCE 1
 #	warning "Currently NO_GETOPT_LONG implies *no* argument parsing, sorry."
 #endif
 
+#include <stdlib.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <string.h>
 
-const short int mirage_getopt(const int argc, char* const argv[], const struct mirage_opt* const opts) {
+static const bool try_atoi(const char* const val, int* const out) {
+	char *end;
+	int tmp;
+
+	tmp = strtol(val, &end, 0);
+	if (end && *end)
+		return false;
+
+	*out = tmp;
+	return true;
+}
+
+const short int mirage_getopt(const int argc, char* const argv[], const struct mirage_opt* const opts, union mirage_optarg_val *val) {
 #ifndef NO_GETOPT_LONG
 	const struct mirage_opt *op;
 	int arrlen = 1, buflen = 1;
 	if (ret == -1) /* done parsing */
 		return -optind;
 
+	for (op = opts; op->name; op++) {
+		if (op->val == ret) {
+			switch (op->arg) {
+				case mirage_arg_int:
+					if (!try_atoi(optarg, &(val->as_int))) {
+						fprintf(stderr, "--%s requires integer argument which '%s' apparently isn't\n", op->name, optarg);
+						return '?';
+					}
+					break;
+				case mirage_arg_str:
+					val->as_str = optarg;
+			}
+		}
+	}
+
 	return ret;
 #else
 	return -1;

File mirage-getopt.h

 
 enum mirage_optarg {
 	mirage_arg_none,
-	mirage_arg_int
+	mirage_arg_int,
+	mirage_arg_str
+};
+
+union mirage_optarg_val {
+	int as_int;
+	const char* as_str;
 };
 
 struct mirage_opt {
 	const char* const help;
 };
 
-const short int mirage_getopt(const int argc, char* const argv[], const struct mirage_opt* const opts);
+const short int mirage_getopt(const int argc, char* const argv[], const struct mirage_opt* const opts, union mirage_optarg_val *val);
 void mirage_getopt_help(const char* const argv0, const char* const synopsis, const struct mirage_opt* const opts);

File mirage2iso.c

 	fprintf(stderr, "mirage2iso %s, using libmirage %s\n", VERSION, ver ? ver : "unknown");
 }
 
-static const bool try_atoi(const char* const val, int* const out) {
-	char *end;
-	int tmp;
-
-	tmp = strtol(val, &end, 0);
-	if (end && *end)
-		return false;
-
-	*out = tmp;
-	return true;
-}
-
 static const int output_track(const char* const fn, const int track_num) {
 	const bool use_stdout = !fn;
 #ifndef NO_MMAPIO
 	bool use_stdout = false;
 
 	int arg;
+	union mirage_optarg_val val;
 
-	while ((arg = mirage_getopt(argc, argv, opts)) >= 0) {
+	while ((arg = mirage_getopt(argc, argv, opts, &val)) >= 0) {
 		switch (arg) {
 			case 'c':
 				use_stdout = true;
 				quiet = true;
 				break;
 			case 's':
-				if (!try_atoi(optarg, &session_num))
-					fprintf(stderr, "--session requires integer argument which '%s' isn't\n", optarg);
+				session_num = val.as_int;
 				break;
 			case 'S':
 #ifndef NO_MMAPIO