about summary refs log tree commit diff
path: root/src/misc/getopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/misc/getopt.c')
-rw-r--r--src/misc/getopt.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/misc/getopt.c b/src/misc/getopt.c
new file mode 100644
index 00000000..abf0e847
--- /dev/null
+++ b/src/misc/getopt.c
@@ -0,0 +1,63 @@
+#include <unistd.h>
+#include <wchar.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+
+char *optarg;
+int optind=1, opterr=1, optopt;
+static int optpos;
+
+int getopt(int argc, char * const argv[], const char *optstring)
+{
+	int i;
+	wchar_t c, d;
+	int k, l;
+	char *optchar;
+
+	if (optind >= argc || !argv[optind] || argv[optind][0] != '-' || !argv[optind][1])
+		return -1;
+	if (argv[optind][1] == '-' && !argv[optind][2])
+		return optind++, -1;
+
+	if (!optpos) optpos++;
+	if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
+		k = 1;
+		c = 0xfffd; /* replacement char */
+	}
+	optchar = argv[optind]+optpos;
+	optopt = c;
+	optpos += k;
+
+	if (!argv[optind][optpos]) {
+		optind++;
+		optpos = 0;
+	}
+
+	for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1);
+
+	if (d != c) {
+		if (optstring[0] != ':' && opterr) {
+			write(2, argv[0], strlen(argv[0]));
+			write(2, ": illegal option: ", 18);
+			write(2, optchar, k);
+			write(2, "\n", 1);
+		}
+		return '?';
+	}
+	if (optstring[i+1] == ':') {
+		if (optind >= argc) {
+			if (optstring[0] == ':') return ':';
+			if (opterr) {
+				write(2, argv[0], strlen(argv[0]));
+				write(2, ": option requires an argument: ", 31);
+				write(2, optchar, k);
+				write(2, "\n", 1);
+			}
+			return '?';
+		}
+		optarg = argv[optind++] + optpos;
+		optpos = 0;
+	}
+	return c;
+}