• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
10 char *optarg;
11 int optind=1, opterr=1, optopt, __optpos, __optreset=0;
12 
13 #define optpos __optpos
14 weak_alias(__optreset, optreset);
15 
__getopt_msg(const char * a,const char * b,const char * c,size_t l)16 void __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 
getopt(int argc,char * const argv[],const char * optstring)28 int 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++] + optpos;
91 			optpos = 0;
92 		}
93 		if (optind > argc) {
94 			optopt = c;
95 			if (optstring[0] == ':') return ':';
96 			if (opterr) __getopt_msg(argv[0],
97 				": option requires an argument: ",
98 				optchar, k);
99 			return '?';
100 		}
101 	}
102 	return c;
103 }
104 
105 weak_alias(getopt, __posix_getopt);
106