master
  1#define _BSD_SOURCE
  2#include <unistd.h>
  3#include <wchar.h>
  4#include <string.h>
  5#include <limits.h>
  6#include <stdlib.h>
  7#include "locale_impl.h"
  8#include "stdio_impl.h"
  9
 10char *optarg;
 11int optind=1, opterr=1, optopt, __optpos, __optreset=0;
 12
 13#define optpos __optpos
 14weak_alias(__optreset, optreset);
 15
 16void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
 17{
 18	FILE *f = stderr;
 19	b = __lctrans_cur(b);
 20	FLOCK(f);
 21	fputs(a, f)>=0
 22	&& fwrite(b, strlen(b), 1, f)
 23	&& fwrite(c, 1, l, f)==l
 24	&& putc('\n', f);
 25	FUNLOCK(f);
 26}
 27
 28int getopt(int argc, char * const argv[], const char *optstring)
 29{
 30	int i;
 31	wchar_t c, d;
 32	int k, l;
 33	char *optchar;
 34
 35	if (!optind || __optreset) {
 36		__optreset = 0;
 37		__optpos = 0;
 38		optind = 1;
 39	}
 40
 41	if (optind >= argc || !argv[optind])
 42		return -1;
 43
 44	if (argv[optind][0] != '-') {
 45		if (optstring[0] == '-') {
 46			optarg = argv[optind++];
 47			return 1;
 48		}
 49		return -1;
 50	}
 51
 52	if (!argv[optind][1])
 53		return -1;
 54
 55	if (argv[optind][1] == '-' && !argv[optind][2])
 56		return optind++, -1;
 57
 58	if (!optpos) optpos++;
 59	if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
 60		k = 1;
 61		c = 0xfffd; /* replacement char */
 62	}
 63	optchar = argv[optind]+optpos;
 64	optpos += k;
 65
 66	if (!argv[optind][optpos]) {
 67		optind++;
 68		optpos = 0;
 69	}
 70
 71	if (optstring[0] == '-' || optstring[0] == '+')
 72		optstring++;
 73
 74	i = 0;
 75	d = 0;
 76	do {
 77		l = mbtowc(&d, optstring+i, MB_LEN_MAX);
 78		if (l>0) i+=l; else i++;
 79	} while (l && d != c);
 80
 81	if (d != c || c == ':') {
 82		optopt = c;
 83		if (optstring[0] != ':' && opterr)
 84			__getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
 85		return '?';
 86	}
 87	if (optstring[i] == ':') {
 88		optarg = 0;
 89		if (optstring[i+1] != ':' || optpos) {
 90			optarg = argv[optind++];
 91			if (optpos) optarg += optpos;
 92			optpos = 0;
 93		}
 94		if (optind > argc) {
 95			optopt = c;
 96			if (optstring[0] == ':') return ':';
 97			if (opterr) __getopt_msg(argv[0],
 98				": option requires an argument: ",
 99				optchar, k);
100			return '?';
101		}
102	}
103	return c;
104}
105
106weak_alias(getopt, __posix_getopt);