shithub: rgbds

Download patch

ref: 464a3a4892f31bfbedda6b35f7a605ec673156ea
parent: 88e1cc73024e3a2e242f5afce09966758c5fa589
author: Rangi <[email protected]>
date: Wed Feb 10 08:10:43 EST 2021

Separate extern getopt implementation from the unistd.h one

Fixes #710

--- a/include/extern/getopt.h
+++ b/include/extern/getopt.h
@@ -26,8 +26,8 @@
 #ifndef RGBDS_EXTERN_GETOPT_H
 #define RGBDS_EXTERN_GETOPT_H
 
-extern char *optarg;
-extern int optind, opterr, optopt, optreset;
+extern char *musl_optarg;
+extern int musl_optind, musl_opterr, musl_optopt, musl_optreset;
 
 struct option {
 	const char *name;
--- a/src/asm/main.c
+++ b/src/asm/main.c
@@ -177,8 +177,8 @@
 	while ((ch = musl_getopt_long_only(argc, argv, optstring, longopts, NULL)) != -1) {
 		switch (ch) {
 		case 'b':
-			if (strlen(optarg) == 2)
-				opt_B(&optarg[1]);
+			if (strlen(musl_optarg) == 2)
+				opt_B(&musl_optarg[1]);
 			else
 				errx(1, "Must specify exactly 2 characters for option 'b'");
 			break;
@@ -185,12 +185,12 @@
 
 			char *equals;
 		case 'D':
-			equals = strchr(optarg, '=');
+			equals = strchr(musl_optarg, '=');
 			if (equals) {
 				*equals = '\0';
-				sym_AddString(optarg, equals + 1);
+				sym_AddString(musl_optarg, equals + 1);
 			} else {
-				sym_AddString(optarg, "1");
+				sym_AddString(musl_optarg, "1");
 			}
 			break;
 
@@ -199,8 +199,8 @@
 			break;
 
 		case 'g':
-			if (strlen(optarg) == 4)
-				opt_G(&optarg[1]);
+			if (strlen(musl_optarg) == 4)
+				opt_G(&musl_optarg[1]);
 			else
 				errx(1, "Must specify exactly 4 characters for option 'g'");
 			break;
@@ -210,7 +210,7 @@
 			break;
 
 		case 'i':
-			fstk_AddIncludePath(optarg);
+			fstk_AddIncludePath(musl_optarg);
 			break;
 
 		case 'L':
@@ -218,23 +218,23 @@
 			break;
 
 		case 'M':
-			if (!strcmp("-", optarg))
+			if (!strcmp("-", musl_optarg))
 				dependfile = stdout;
 			else
-				dependfile = fopen(optarg, "w");
+				dependfile = fopen(musl_optarg, "w");
 			if (dependfile == NULL)
-				err(1, "Could not open dependfile %s", optarg);
+				err(1, "Could not open dependfile %s", musl_optarg);
 			break;
 
 		case 'o':
-			out_SetFileName(optarg);
+			out_SetFileName(musl_optarg);
 			break;
 
 			unsigned long fill;
 		case 'p':
-			fill = strtoul(optarg, &ep, 0);
+			fill = strtoul(musl_optarg, &ep, 0);
 
-			if (optarg[0] == '\0' || *ep != '\0')
+			if (musl_optarg[0] == '\0' || *ep != '\0')
 				errx(1, "Invalid argument for option 'p'");
 
 			if (fill < 0 || fill > 0xFF)
@@ -244,9 +244,9 @@
 			break;
 
 		case 'r':
-			maxRecursionDepth = strtoul(optarg, &ep, 0);
+			maxRecursionDepth = strtoul(musl_optarg, &ep, 0);
 
-			if (optarg[0] == '\0' || *ep != '\0')
+			if (musl_optarg[0] == '\0' || *ep != '\0')
 				errx(1, "Invalid argument for option 'r'");
 			break;
 
@@ -258,7 +258,7 @@
 			break;
 
 		case 'W':
-			processWarningFlag(optarg);
+			processWarningFlag(musl_optarg);
 			break;
 
 		case 'w':
@@ -278,9 +278,9 @@
 
 			case 'Q':
 			case 'T':
-				if (optind == argc)
+				if (musl_optind == argc)
 					errx(1, "-M%c takes a target file name argument", depType);
-				ep = optarg;
+				ep = musl_optarg;
 				if (depType == 'Q')
 					ep = make_escape(ep);
 
@@ -317,15 +317,15 @@
 	if (tzTargetFileName == NULL)
 		tzTargetFileName = tzObjectname;
 
-	if (argc == optind) {
+	if (argc == musl_optind) {
 		fputs("FATAL: No input files\n", stderr);
 		print_usage();
-	} else if (argc != optind + 1) {
+	} else if (argc != musl_optind + 1) {
 		fputs("FATAL: More than one input file given\n", stderr);
 		print_usage();
 	}
 
-	char const *mainFileName = argv[optind];
+	char const *mainFileName = argv[musl_optind];
 
 	if (verbose)
 		printf("Assembling %s\n", mainFileName);
--- a/src/extern/getopt.c
+++ b/src/extern/getopt.c
@@ -26,9 +26,6 @@
 #include <stddef.h>
 #include <stdlib.h>
 #include <limits.h>
-#ifndef _MSC_VER
-# include <unistd.h>
-#endif
 #include <stdio.h>
 #include <string.h>
 #include <wchar.h>
@@ -35,12 +32,10 @@
 
 #include "extern/getopt.h"
 
-#ifdef _MSC_VER
-char *optarg;
-int optind=1, opterr=1, optopt;
-#endif
-int optreset=0;
-static int optpos;
+char *musl_optarg;
+int musl_optind = 1, musl_opterr = 1, musl_optopt;
+int musl_optreset = 0;
+static int musl_optpos;
 
 static void musl_getopt_msg(const char *a, const char *b, const char *c, size_t l)
 {
@@ -52,7 +47,6 @@
 		putc('\n', f);
 }
 
-#ifdef _MSC_VER
 static int getopt(int argc, char *argv[], const char *optstring)
 {
 	int i;
@@ -60,40 +54,42 @@
 	int k, l;
 	char *optchar;
 
-	if (!optind || optreset) {
-		optreset = 0;
-		optpos = 0;
-		optind = 1;
+	if (!musl_optind || musl_optreset) {
+		musl_optreset = 0;
+		musl_optpos = 0;
+		musl_optind = 1;
 	}
 
-	if (optind >= argc || !argv[optind])
+	if (musl_optind >= argc || !argv[musl_optind])
 		return -1;
 
-	if (argv[optind][0] != '-') {
+	if (argv[musl_optind][0] != '-') {
 		if (optstring[0] == '-') {
-			optarg = argv[optind++];
+			musl_optarg = argv[musl_optind++];
 			return 1;
 		}
 		return -1;
 	}
 
-	if (!argv[optind][1])
+	if (!argv[musl_optind][1])
 		return -1;
 
-	if (argv[optind][1] == '-' && !argv[optind][2])
-		return optind++, -1;
+	if (argv[musl_optind][1] == '-' && !argv[musl_optind][2])
+		return musl_optind++, -1;
 
-	if (!optpos) optpos++;
-	if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
+	if (!musl_optpos)
+		musl_optpos++;
+	k = mbtowc(&c, argv[musl_optind] + musl_optpos, MB_LEN_MAX);
+	if (k < 0) {
 		k = 1;
 		c = 0xfffd; /* replacement char */
 	}
-	optchar = argv[optind]+optpos;
-	optpos += k;
+	optchar = argv[musl_optind] + musl_optpos;
+	musl_optpos += k;
 
-	if (!argv[optind][optpos]) {
-		optind++;
-		optpos = 0;
+	if (!argv[musl_optind][musl_optpos]) {
+		musl_optind++;
+		musl_optpos = 0;
 	}
 
 	if (optstring[0] == '-' || optstring[0] == '+')
@@ -103,39 +99,43 @@
 	d = 0;
 	do {
 		l = mbtowc(&d, optstring+i, MB_LEN_MAX);
-		if (l>0) i+=l; else i++;
+		if (l > 0)
+			i += l;
+		else
+			i++;
 	} while (l && d != c);
 
 	if (d != c || c == ':') {
-		optopt = c;
-		if (optstring[0] != ':' && opterr)
+		musl_optopt = c;
+		if (optstring[0] != ':' && musl_opterr)
 			musl_getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
 		return '?';
 	}
 	if (optstring[i] == ':') {
-		optarg = 0;
-		if (optstring[i+1] != ':' || optpos) {
-			optarg = argv[optind++] + optpos;
-			optpos = 0;
+		musl_optarg = 0;
+		if (optstring[i + 1] != ':' || musl_optpos) {
+			musl_optarg = argv[musl_optind++] + musl_optpos;
+			musl_optpos = 0;
 		}
-		if (optind > argc) {
-			optopt = c;
-			if (optstring[0] == ':') return ':';
-			if (opterr) musl_getopt_msg(argv[0],
-				": option requires an argument: ",
-				optchar, k);
+		if (musl_optind > argc) {
+			musl_optopt = c;
+			if (optstring[0] == ':')
+				return ':';
+			if (musl_opterr)
+				musl_getopt_msg(argv[0], ": option requires an argument: ",
+						optchar, k);
 			return '?';
 		}
 	}
 	return c;
 }
-#endif /* _MSC_VER */
 
 static void permute(char **argv, int dest, int src)
 {
 	char *tmp = argv[src];
 	int i;
-	for (i=src; i>dest; i--)
+
+	for (i = src; i > dest; i--)
 		argv[i] = argv[i-1];
 	argv[dest] = tmp;
 }
@@ -145,28 +145,35 @@
 static int musl_getopt_long(int argc, char **argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
 {
 	int ret, skipped, resumed;
-	if (!optind || optreset) {
-		optreset = 0;
-		optpos = 0;
-		optind = 1;
+
+	if (!musl_optind || musl_optreset) {
+		musl_optreset = 0;
+		musl_optpos = 0;
+		musl_optind = 1;
 	}
-	if (optind >= argc || !argv[optind]) return -1;
-	skipped = optind;
+
+	if (musl_optind >= argc || !argv[musl_optind])
+		return -1;
+
+	skipped = musl_optind;
 	if (optstring[0] != '+' && optstring[0] != '-') {
 		int i;
-		for (i=optind; ; i++) {
-			if (i >= argc || !argv[i]) return -1;
-			if (argv[i][0] == '-' && argv[i][1]) break;
+		for (i = musl_optind; ; i++) {
+			if (i >= argc || !argv[i])
+				return -1;
+			if (argv[i][0] == '-' && argv[i][1])
+				break;
 		}
-		optind = i;
+		musl_optind = i;
 	}
-	resumed = optind;
+	resumed = musl_optind;
 	ret = musl_getopt_long_core(argc, argv, optstring, longopts, idx, longonly);
 	if (resumed > skipped) {
-		int i, cnt = optind-resumed;
-		for (i=0; i<cnt; i++)
-			permute(argv, skipped, optind-1);
-		optind = skipped + cnt;
+		int i, cnt = musl_optind - resumed;
+
+		for (i = 0; i < cnt; i++)
+			permute(argv, skipped, musl_optind - 1);
+		musl_optind = skipped + cnt;
 	}
 	return ret;
 }
@@ -173,21 +180,26 @@
 
 static int musl_getopt_long_core(int argc, char **argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
 {
-	optarg = 0;
-	if (longopts && argv[optind][0] == '-' &&
-		((longonly && argv[optind][1] && argv[optind][1] != '-') ||
-		 (argv[optind][1] == '-' && argv[optind][2])))
-	{
-		int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':';
+	musl_optarg = 0;
+	if (longopts && argv[musl_optind][0] == '-' &&
+	    ((longonly && argv[musl_optind][1] && argv[musl_optind][1] != '-') ||
+	     (argv[musl_optind][1] == '-' && argv[musl_optind][2]))) {
+		int colon = optstring[optstring[0] == '+' || optstring[0] == '-'] == ':';
 		int i, cnt, match = 0;
-		char *arg = 0, *opt, *start = argv[optind]+1;
-		for (cnt=i=0; longopts[i].name; i++) {
+		char *arg = 0, *opt, *start = argv[musl_optind] + 1;
+
+		for (cnt = i = 0; longopts[i].name; i++) {
 			const char *name = longopts[i].name;
+
 			opt = start;
-			if (*opt == '-') opt++;
-			while (*opt && *opt != '=' && *opt == *name)
-				name++, opt++;
-			if (*opt && *opt != '=') continue;
+			if (*opt == '-')
+				opt++;
+			while (*opt && *opt != '=' && *opt == *name) {
+				name++;
+				opt++;
+			}
+			if (*opt && *opt != '=')
+				continue;
 			arg = opt;
 			match = i;
 			if (!*name) {
@@ -196,25 +208,28 @@
 			}
 			cnt++;
 		}
-		if (cnt==1 && longonly && arg-start == mblen(start, MB_LEN_MAX)) {
-			int l = arg-start;
-			for (i=0; optstring[i]; i++) {
-				int j;
-				for (j=0; j<l && start[j]==optstring[i+j]; j++);
-				if (j==l) {
+		if (cnt == 1 && longonly && arg - start == mblen(start, MB_LEN_MAX)) {
+			int l = arg - start;
+
+			for (i = 0; optstring[i]; i++) {
+				int j = 0;
+
+				while (j < l && start[j] == optstring[i + j])
+					j++;
+				if (j == l) {
 					cnt++;
 					break;
 				}
 			}
 		}
-		if (cnt==1) {
+		if (cnt == 1) {
 			i = match;
 			opt = arg;
-			optind++;
+			musl_optind++;
 			if (*opt == '=') {
 				if (!longopts[i].has_arg) {
-					optopt = longopts[i].val;
-					if (colon || !opterr)
+					musl_optopt = longopts[i].val;
+					if (colon || !musl_opterr)
 						return '?';
 					musl_getopt_msg(argv[0],
 						": option does not take an argument: ",
@@ -222,12 +237,15 @@
 						strlen(longopts[i].name));
 					return '?';
 				}
-				optarg = opt+1;
+				musl_optarg = opt + 1;
 			} else if (longopts[i].has_arg == required_argument) {
-				if (!(optarg = argv[optind])) {
-					optopt = longopts[i].val;
-					if (colon) return ':';
-					if (!opterr) return '?';
+				musl_optarg = argv[musl_optind];
+				if (!musl_optarg) {
+					musl_optopt = longopts[i].val;
+					if (colon)
+						return ':';
+					if (!musl_opterr)
+						return '?';
 					musl_getopt_msg(argv[0],
 						": option requires an argument: ",
 						longopts[i].name,
@@ -234,9 +252,10 @@
 						strlen(longopts[i].name));
 					return '?';
 				}
-				optind++;
+				musl_optind++;
 			}
-			if (idx) *idx = i;
+			if (idx)
+				*idx = i;
 			if (longopts[i].flag) {
 				*longopts[i].flag = longopts[i].val;
 				return 0;
@@ -243,15 +262,15 @@
 			}
 			return longopts[i].val;
 		}
-		if (argv[optind][1] == '-') {
-			optopt = 0;
-			if (!colon && opterr)
+		if (argv[musl_optind][1] == '-') {
+			musl_optopt = 0;
+			if (!colon && musl_opterr)
 				musl_getopt_msg(argv[0], cnt ?
 					": option is ambiguous: " :
 					": unrecognized option: ",
-					argv[optind]+2,
-					strlen(argv[optind]+2));
-			optind++;
+					argv[musl_optind] + 2,
+					strlen(argv[musl_optind] + 2));
+			musl_optind++;
 			return '?';
 		}
 	}
--- a/src/fix/main.c
+++ b/src/fix/main.c
@@ -973,17 +973,17 @@
 	char *endptr; \
 	unsigned long tmp; \
 	\
-	if (optarg[0] == 0) { \
+	if (musl_optarg[0] == 0) { \
 		report("error: Argument to option '" name "' may not be empty\n"); \
 	} else { \
-		if (optarg[0] == '$') { \
-			tmp = strtoul(&optarg[1], &endptr, 16); \
+		if (musl_optarg[0] == '$') { \
+			tmp = strtoul(&musl_optarg[1], &endptr, 16); \
 		} else { \
-			tmp = strtoul(optarg, &endptr, 0); \
+			tmp = strtoul(musl_optarg, &endptr, 0); \
 		} \
 		if (*endptr) \
 			report("error: Expected number as argument to option '" name "', got %s\n", \
-			       optarg); \
+			       musl_optarg); \
 		else if (tmp > 0xFF) \
 			report("error: Argument to option '" name "' is larger than 255: %lu\n", tmp); \
 		else \
@@ -1003,8 +1003,8 @@
 
 		case 'f':
 			fixSpec = 0;
-			while (*optarg) {
-				switch (*optarg) {
+			while (*musl_optarg) {
+				switch (*musl_optarg) {
 #define SPEC_l FIX_LOGO
 #define SPEC_L TRASH_LOGO
 #define SPEC_h FIX_HEADER_SUM
@@ -1041,15 +1041,15 @@
 
 				default:
 					fprintf(stderr, "warning: Ignoring '%c' in fix spec\n",
-						*optarg);
+						*musl_optarg);
 #undef or
 				}
-				optarg++;
+				musl_optarg++;
 			}
 			break;
 
 		case 'i':
-			gameID = optarg;
+			gameID = musl_optarg;
 			len = strlen(gameID);
 			if (len > 4) {
 				len = 4;
@@ -1069,7 +1069,7 @@
 			break;
 
 		case 'k':
-			newLicensee = optarg;
+			newLicensee = musl_optarg;
 			len = strlen(newLicensee);
 			if (len > 2) {
 				len = 2;
@@ -1085,14 +1085,15 @@
 			break;
 
 		case 'm':
-			cartridgeType = parseMBC(optarg);
+			cartridgeType = parseMBC(musl_optarg);
 			if (cartridgeType == MBC_BAD) {
-				report("error: Unknown MBC \"%s\"\n", optarg);
+				report("error: Unknown MBC \"%s\"\n", musl_optarg);
 			} else if (cartridgeType == MBC_WRONG_FEATURES) {
-				report("error: Features incompatible with MBC (\"%s\")\n", optarg);
+				report("error: Features incompatible with MBC (\"%s\")\n",
+				       musl_optarg);
 			} else if (cartridgeType == MBC_BAD_RANGE) {
 				report("error: Specified MBC ID out of range 0-255: %s\n",
-				       optarg);
+				       musl_optarg);
 			} else if (cartridgeType == ROM_RAM || cartridgeType == ROM_RAM_BATTERY) {
 				fprintf(stderr, "warning: ROM+RAM / ROM+RAM+BATTERY are under-specified and poorly supported\n");
 			}
@@ -1115,7 +1116,7 @@
 			break;
 
 		case 't':
-			title = optarg;
+			title = musl_optarg;
 			len = strlen(title);
 			uint8_t maxLen = maxTitleLen();
 
@@ -1170,7 +1171,7 @@
 			"warning: SGB compatibility enabled, but old licensee is %#x, not 0x33\n",
 			oldLicensee);
 
-	argv += optind;
+	argv += musl_optind;
 	bool failed = nbErrors;
 
 	if (!*argv) {
--- a/src/gfx/main.c
+++ b/src/gfx/main.c
@@ -96,7 +96,7 @@
 			opts.attrmapout = true;
 			break;
 		case 'a':
-			opts.attrmapfile = optarg;
+			opts.attrmapfile = musl_optarg;
 			break;
 		case 'C':
 			opts.colorcurve = true;
@@ -105,7 +105,7 @@
 			opts.debug = true;
 			break;
 		case 'd':
-			depth = strtoul(optarg, NULL, 0);
+			depth = strtoul(musl_optarg, NULL, 0);
 			break;
 		case 'F':
 			opts.hardfix = true;
@@ -121,19 +121,19 @@
 			opts.unique = true;
 			break;
 		case 'o':
-			opts.outfile = optarg;
+			opts.outfile = musl_optarg;
 			break;
 		case 'P':
 			opts.palout = true;
 			break;
 		case 'p':
-			opts.palfile = optarg;
+			opts.palfile = musl_optarg;
 			break;
 		case 'T':
 			opts.tilemapout = true;
 			break;
 		case 't':
-			opts.tilemapfile = optarg;
+			opts.tilemapfile = musl_optarg;
 			break;
 		case 'u':
 			opts.unique = true;
@@ -145,7 +145,7 @@
 			opts.verbose = true;
 			break;
 		case 'x':
-			opts.trim = strtoul(optarg, NULL, 0);
+			opts.trim = strtoul(musl_optarg, NULL, 0);
 			break;
 		default:
 			print_usage();
@@ -152,8 +152,8 @@
 			/* NOTREACHED */
 		}
 	}
-	argc -= optind;
-	argv += optind;
+	argc -= musl_optind;
+	argv += musl_optind;
 
 	if (argc == 0) {
 		fputs("FATAL: no input files\n", stderr);
--- a/src/link/main.c
+++ b/src/link/main.c
@@ -217,23 +217,23 @@
 			isWRA0Mode = true;
 			break;
 		case 'l':
-			linkerScriptName = optarg;
+			linkerScriptName = musl_optarg;
 			break;
 		case 'm':
-			mapFileName = optarg;
+			mapFileName = musl_optarg;
 			break;
 		case 'n':
-			symFileName = optarg;
+			symFileName = musl_optarg;
 			break;
 		case 'O':
-			overlayFileName = optarg;
+			overlayFileName = musl_optarg;
 			break;
 		case 'o':
-			outputFileName = optarg;
+			outputFileName = musl_optarg;
 			break;
 		case 'p':
-			value = strtoul(optarg, &endptr, 0);
-			if (optarg[0] == '\0' || *endptr != '\0') {
+			value = strtoul(musl_optarg, &endptr, 0);
+			if (musl_optarg[0] == '\0' || *endptr != '\0') {
 				error(NULL, 0, "Invalid argument for option 'p'");
 				value = 0xFF;
 			}
@@ -245,7 +245,7 @@
 			break;
 		case 's':
 			/* FIXME: nobody knows what this does, figure it out */
-			(void)optarg;
+			(void)musl_optarg;
 			warning(NULL, 0, "Nobody has any idea what `-s` does");
 			break;
 		case 't':
@@ -271,7 +271,7 @@
 		}
 	}
 
-	int curArgIndex = optind;
+	int curArgIndex = musl_optind;
 
 	/* If no input files were specified, the user must have screwed up */
 	if (curArgIndex == argc) {