chiark / gitweb /
Merge branches 'idx/verh' and 'idx/qmqpc'
[qmail] / subgetopt.c
1 /* subgetopt.c, subgetopt.h: (yet another) improved getopt clone, inner layer
2 D. J. Bernstein, djb@pobox.com.
3 No dependencies.
4 No system requirements.
5 19970228: Cleanups.
6 931129: Adapted from getopt.c.
7 No known patent problems.
8
9 Documentation in subgetopt.3.
10 */
11
12 #define SUBGETOPTNOSHORT
13 #include "subgetopt.h"
14
15 #define sgopt subgetopt
16 #define optind subgetoptind
17 #define optpos subgetoptpos
18 #define optarg subgetoptarg
19 #define optproblem subgetoptproblem
20 #define optdone subgetoptdone
21
22 int optind = 1;
23 int optpos = 0;
24 char *optarg = 0;
25 int optproblem = 0;
26 int optdone = SUBGETOPTDONE;
27
28 int sgopt(argc,argv,opts)
29 int argc;
30 char **argv;
31 char *opts;
32 {
33   int c;
34   char *s;
35
36   optarg = 0;
37   if (!argv || (optind >= argc) || !argv[optind]) return optdone;
38   if (optpos && !argv[optind][optpos]) {
39     ++optind;
40     optpos = 0;
41     if ((optind >= argc) || !argv[optind]) return optdone;
42   }
43   if (!optpos) {
44     if (argv[optind][0] != '-') return optdone;
45     ++optpos;
46     c = argv[optind][1];
47     if ((c == '-') || (c == 0)) {
48       if (c) ++optind;
49       optpos = 0;
50       return optdone;
51     }
52     /* otherwise c is reassigned below */
53   }
54   c = argv[optind][optpos];
55   ++optpos;
56   s = opts;
57   while (*s) {
58     if (c == *s) {
59       if (s[1] == ':') {
60         optarg = argv[optind] + optpos;
61         ++optind;
62         optpos = 0;
63         if (!*optarg) {
64           optarg = argv[optind];
65           if ((optind >= argc) || !optarg) { /* argument past end */
66             optproblem = c;
67             return '?';
68           }
69           ++optind;
70         }
71       }
72       return c;
73     }
74     ++s;
75     if (*s == ':') ++s;
76   }
77   optproblem = c;
78   return '?';
79 }