annotate getopt.c @ 0:c55ea9478c80

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