[m-rev.] for review: Check availability of getopt() directly.

Peter Wang novalazy at gmail.com
Tue Jun 4 10:46:35 AEST 2019


On Mon, 3 Jun 2019 15:30:56 +1000 (AEST), Julien Fischer <jfischer at opturion.com> wrote:
> At a glance, the musl implementation looks ok.  The main difference
> between the GNU implementation and the above seems to be that GNU one
> performs argv permutation for getopt() and the *BSD / musl ones do not.
> (They do argv permutation for getopt_long() however.)

Yes, the musl implementation looks fine. It does require some changes
to build outside of musl, and some changes for (improved) portability,
but it's not too bad.

Peter


diff --git a/getopt/getopt.c b/getopt/getopt.c
index 864d52cdc..545add065 100644
--- a/getopt/getopt.c
+++ b/getopt/getopt.c
@@ -1,38 +1,36 @@
-#include <unistd.h>
-#include <wchar.h>
 #include <string.h>
-#include <limits.h>
-#include <stdlib.h>
-#include "locale_impl.h"
-#include "stdio_impl.h"
+#include <stdio.h>
+#define GETOPT_IMPL
+#include "getopt.h"
 
 char *optarg;
-int optind=1, opterr=1, optopt, __optpos, __optreset=0;
+int optind=1, opterr=1, optopt, __optpos, optreset=0;
 
 #define optpos __optpos
-weak_alias(__optreset, optreset);
 
 void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
 {
 	FILE *f = stderr;
-	b = __lctrans_cur(b);
-	FLOCK(f);
+	/* POSIX only */
+	/* flockfile(f); */
+	if (
 		fputs(a, f)>=0
 		&& fwrite(b, strlen(b), 1, f)
 		&& fwrite(c, 1, l, f)==l
-	&& putc('\n', f);
-	FUNLOCK(f);
+		&& putc('\n', f)
+	) { }
+	/* funlockfile(f); */
 }
 
 int getopt(int argc, char * const argv[], const char *optstring)
 {
 	int i;
-	wchar_t c, d;
+	int c, d;
 	int k, l;
 	char *optchar;
 
-	if (!optind || __optreset) {
-		__optreset = 0;
+	if (!optind || optreset) {
+		optreset = 0;
 		__optpos = 0;
 		optind = 1;
 	}
@@ -55,10 +53,8 @@ int getopt(int argc, char * const argv[], const char *optstring)
 		return optind++, -1;
 
 	if (!optpos) optpos++;
-	if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
+	c = argv[optind][optpos];
 	k = 1;
-		c = 0xfffd; /* replacement char */
-	}
 	optchar = argv[optind]+optpos;
 	optpos += k;
 
@@ -73,7 +69,8 @@ int getopt(int argc, char * const argv[], const char *optstring)
 	i = 0;
 	d = 0;
 	do {
-		l = mbtowc(&d, optstring+i, MB_LEN_MAX);
+		d = optstring[i];
+		l = d ? 1 : 0;
 		if (l>0) i+=l; else i++;
 	} while (l && d != c);
 
@@ -100,5 +97,3 @@ int getopt(int argc, char * const argv[], const char *optstring)
 	}
 	return c;
 }
-
-weak_alias(getopt, __posix_getopt);
diff --git a/getopt/getopt.h b/getopt/getopt.h
index 35cbd358b..214e46e56 100644
--- a/getopt/getopt.h
+++ b/getopt/getopt.h
@@ -23,6 +23,10 @@ int getopt_long_only(int, char *const *, const char *, const struct option *, in
 #define required_argument  1
 #define optional_argument  2
 
+#ifdef GETOPT_IMPL
+void __getopt_msg(const char *a, const char *b, const char *c, size_t l);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/getopt/getopt_long.c b/getopt/getopt_long.c
index 6949ab1c7..61b020830 100644
--- a/getopt/getopt_long.c
+++ b/getopt/getopt_long.c
@@ -1,13 +1,9 @@
-#define _GNU_SOURCE
-#include <stddef.h>
 #include <stdlib.h>
-#include <limits.h>
-#include <getopt.h>
-#include <stdio.h>
 #include <string.h>
-#include "stdio_impl.h"
+#define GETOPT_IMPL
+#include "getopt.h"
 
-extern int __optpos, __optreset;
+extern int __optpos;
 
 static void permute(char *const *argv, int dest, int src)
 {
@@ -24,8 +20,8 @@ static int __getopt_long_core(int argc, char *const *argv, const char *optstring
 static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
 {
 	int ret, skipped, resumed;
-	if (!optind || __optreset) {
-		__optreset = 0;
+	if (!optind || optreset) {
+		optreset = 0;
 		__optpos = 0;
 		optind = 1;
 	}
@@ -75,7 +71,7 @@ static int __getopt_long_core(int argc, char *const *argv, const char *optstring
 			}
 			cnt++;
 		}
-		if (cnt==1 && longonly && arg-start == mblen(start, MB_LEN_MAX)) {
+		if (cnt==1 && longonly && arg-start == 1) {
 			int l = arg-start;
 			for (i=0; optstring[i]; i++) {
 				int j;


More information about the reviews mailing list