فهرست منبع

fix getopt handling of ':' modifier for multibyte option characters

the previous hard-coded offsets of +1 and +2 contained a hidden
assumption that the option character matched was single-byte, despite
this implementation of getopt attempting to support multibyte option
characters. this patch reworks the matching logic to leave the final
index pointing just past the matched character so that fixed offsets
can be used to check for ':'.
Rich Felker 10 سال پیش
والد
کامیت
014275b547
1فایلهای تغییر یافته به همراه9 افزوده شده و 4 حذف شده
  1. 9 4
      src/misc/getopt.c

+ 9 - 4
src/misc/getopt.c

@@ -58,7 +58,12 @@ int getopt(int argc, char * const argv[], const char *optstring)
 	if (optstring[0] == '-')
 	if (optstring[0] == '-')
 		optstring++;
 		optstring++;
 
 
-	for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1);
+	i = 0;
+	d = 0;
+	do {
+		l = mbtowc(&d, optstring+i, MB_LEN_MAX);
+		if (l>0) i+=l; else i++;
+	} while (l && d != c);
 
 
 	if (d != c) {
 	if (d != c) {
 		if (optstring[0] != ':' && opterr) {
 		if (optstring[0] != ':' && opterr) {
@@ -69,8 +74,8 @@ int getopt(int argc, char * const argv[], const char *optstring)
 		}
 		}
 		return '?';
 		return '?';
 	}
 	}
-	if (optstring[i+1] == ':') {
-		if (optstring[i+2] == ':') optarg = 0;
+	if (optstring[i] == ':') {
+		if (optstring[i+1] == ':') optarg = 0;
 		else if (optind >= argc) {
 		else if (optind >= argc) {
 			if (optstring[0] == ':') return ':';
 			if (optstring[0] == ':') return ':';
 			if (opterr) {
 			if (opterr) {
@@ -81,7 +86,7 @@ int getopt(int argc, char * const argv[], const char *optstring)
 			}
 			}
 			return '?';
 			return '?';
 		}
 		}
-		if (optstring[i+2] != ':' || optpos) {
+		if (optstring[i+1] != ':' || optpos) {
 			optarg = argv[optind++] + optpos;
 			optarg = argv[optind++] + optpos;
 			optpos = 0;
 			optpos = 0;
 		}
 		}