Commits

Michał Górny  committed a0f7ccd

Add support for mixed options and args, and for '--'.
Now args are returned through 'newargv'.

  • Participants
  • Parent commits 15ea064

Comments (0)

Files changed (3)

File mirage-getopt.c

 
 #ifndef NO_GETOPT_LONG
 
-const short int mirage_getopt(const int argc, char* const argv[], const struct mirage_opt* const opts, union mirage_optarg_val *outval) {
+const short int mirage_getopt(const int argc, char* const argv[], const struct mirage_opt* const opts, union mirage_optarg_val *outval, const char* newargv[]) {
 	const struct mirage_opt *op;
 	int arrlen = 1, buflen = 1;
 
 
 	const int ret = getopt_long(argc, argv, buf, longopts, NULL);
 
-	if (ret == -1) /* done parsing */
-		return -optind;
+	if (ret == -1) { /* done parsing, set up newargv */
+		int i, newargc;
+		for (i = optind, newargc = 0; i < argc; i++)
+			newargv[newargc++] = argv[i];
+		newargv[newargc] = NULL;
+		return -newargc;
+	}
 
 	for (op = opts; op->name; op++) {
 		if (op->val == ret) {
 
 #else
 
-const short int mirage_getopt(const int argc, char* const argv[], const struct mirage_opt* const opts, union mirage_optarg_val *outval) {
+const short int mirage_getopt(const int argc, char* const argv[], const struct mirage_opt* const opts, union mirage_optarg_val *outval, const char* newargv[]) {
 	static int argindex = 1;
 	static const char* shortptr = NULL;
+	static int newargc = 0;
 
 	const struct mirage_opt *op;
 
 		const struct mirage_opt* opt = NULL;
 		const char *val = NULL;
 
-		if (shortptr || (cp[0] == '-' && cp[1])) {
+		if (shortptr || (cp[0] == '-' && cp[1] && (cp[1] != '-' || cp[2]))) {
 			cp++;
 			if (!shortptr && cp[0] == '-') {
 				cp++;
 			}
 
 			return opt->val;
-		} else {
-			/* XXX: support mixing args & options */
-			fprintf(stderr, "NON-OPT %s @ %d *\n", cp, i);
-			return -i;
+		} else if (cp[0] == '-' && cp[1] == '-') {
+			int i;
+			for (i = argindex; argv[i]; i++)
+				newargv[newargc++] = argv[i];
+		} else { /* non-option */
+			newargv[newargc++] = cp;
+			continue;
 		}
 	}
 
-	return -argindex;
+	newargv[newargc] = NULL;
+	return -newargc;
 }
 
 #endif

File mirage-getopt.h

 	const char* const help;
 };
 
-const short int mirage_getopt(const int argc, char* const argv[], const struct mirage_opt* const opts, union mirage_optarg_val *outval);
+const short int mirage_getopt(const int argc, char* const argv[], const struct mirage_opt* const opts, union mirage_optarg_val *outval, const char* newargv[]);
 void mirage_getopt_help(const char* const argv0, const char* const synopsis, const struct mirage_opt* const opts);

File mirage2iso.c

 
 	int arg;
 	union mirage_optarg_val val;
+	const char* newargv[argc];
 
-	while ((arg = mirage_getopt(argc, argv, opts, &val)) >= 0) {
+	while ((arg = mirage_getopt(argc, argv, opts, &val, newargv)) >= 0) {
 		switch (arg) {
 			case 'c':
 				use_stdout = true;
 			fprintf(stderr, "--force has no effect when --stdout in use\n");
 	}
 
-	const char* const in = argv[-arg];
+	const char* const in = newargv[0];
 	if (!in) {
 		fprintf(stderr, "No input file specified\n");
 		return help(argv[0]);
 	}
 
-	const char* out = argv[-arg+1];
+	const char* out = newargv[1];
 	char* outbuf = NULL;
 	if (!out) {
 		if (!use_stdout) {