0
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
1 /*
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
2 * getopt - get option letter from argv
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
3 *
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
4 * This is a version of the public domain getopt() implementation by
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
5 * Henry Spencer, changed for 4.3BSD compatibility (in addition to System V).
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
6 * It allows rescanning of an option list by setting optind to 0 before
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
7 * calling, which is why we use it even if the system has its own (in fact,
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
8 * this one has a unique name so as not to conflict with the system's).
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
9 * Thanks to Dennis Ferguson for the appropriate modifications.
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
10 *
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
11 * This file is in the Public Domain.
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
12 */
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
13
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
14 #include <string.h>
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
15 #include <unistd.h>
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
16
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
17 char *optarg; /* Global argument pointer. */
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
18 int optind = 0; /* Global argv index. */
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
19 int opterr = 1; /* for compatibility, should error be printed? */
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
20 int optopt; /* for compatibility, option character checked */
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
21
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
22 static char *scan = NULL; /* Private scan pointer. */
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
23
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
24 /*
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
25 * Print message about a bad option.
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
26 */
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
27 static int badopt(const char *msg, int ch)
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
28 {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
29 if (opterr) {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
30 write(2, msg, strlen(msg));
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
31 write(2, &ch, 1);
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
32 write(2, "\n", 1);
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
33 }
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
34 return ('?');
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
35 }
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
36
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
37 int getopt(int argc, char *const argv[], const char *optstring)
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
38 {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
39 register char c;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
40 register const char *place;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
41 optarg = NULL;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
42
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
43 if (optind == 0) {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
44 scan = NULL;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
45 optind++;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
46 }
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
47
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
48 if (scan == NULL || *scan == '\0') {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
49 if (optind >= argc
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
50 || argv[optind][0] != '-'
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
51 || argv[optind][1] == '\0') {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
52 return (-1);
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
53 }
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
54 if (argv[optind][1] == '-'
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
55 && argv[optind][2] == '\0') {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
56 optind++;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
57 return (-1);
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
58 }
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
59 scan = argv[optind++]+1;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
60 }
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
61
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
62 c = *scan++;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
63 optopt = c & 0377;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
64 for (place = optstring; place != NULL && *place != '\0'; ++place)
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
65 if (*place == c)
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
66 break;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
67
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
68 if (place == NULL || *place == '\0' || c == ':' || c == '?') {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
69 return (badopt("getopt: unknown option -", c));
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
70 }
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
71
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
72 place++;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
73 if (*place == ':') {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
74 if (*scan != '\0') {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
75 optarg = scan;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
76 scan = NULL;
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
77 } else if (optind >= argc) {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
78 return (badopt("getopt: option requires argument -", c));
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
79 } else {
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
80 optarg = argv[optind++];
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
81 }
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
82 }
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
83 return (c & 0377);
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
84 }
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
85
|