+#define _BSD_SOURCE
#include <unistd.h>
#include <wchar.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
-#include "libc.h"
+#include "locale_impl.h"
+#include "stdio_impl.h"
char *optarg;
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);
+ fputs(a, f)>=0
+ && fwrite(b, strlen(b), 1, f)
+ && fwrite(c, 1, l, f)==l
+ && putc('\n', f);
+ FUNLOCK(f);
+}
+
int getopt(int argc, char * const argv[], const char *optstring)
{
int i;
c = 0xfffd; /* replacement char */
}
optchar = argv[optind]+optpos;
- optopt = c;
optpos += k;
if (!argv[optind][optpos]) {
optpos = 0;
}
- if (optstring[0] == '-')
+ if (optstring[0] == '-' || optstring[0] == '+')
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 (optstring[0] != ':' && opterr) {
- write(2, argv[0], strlen(argv[0]));
- write(2, ": illegal option: ", 18);
- write(2, optchar, k);
- write(2, "\n", 1);
- }
+ if (d != c || c == ':') {
+ optopt = c;
+ if (optstring[0] != ':' && opterr)
+ __getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
return '?';
}
- if (optstring[i+1] == ':') {
- if (optstring[i+2] == ':') optarg = 0;
- else 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 '?';
- }
- if (optstring[i+2] != ':' || optpos) {
+ if (optstring[i] == ':') {
+ optarg = 0;
+ if (optstring[i+1] != ':' || optpos) {
optarg = argv[optind++] + optpos;
optpos = 0;
}
+ if (optind > argc) {
+ optopt = c;
+ if (optstring[0] == ':') return ':';
+ if (opterr) __getopt_msg(argv[0],
+ ": option requires an argument: ",
+ optchar, k);
+ return '?';
+ }
}
return c;
}