]> git.neil.brown.name Git - metad.git/blob - args.c
Assorted reformating
[metad.git] / args.c
1
2 /*
3  * args - a getopt link argument processor
4  *
5  * void *handle = args_init(argc, argv, "argctl");
6  *
7  * args_next(handle, &pos, &inv, &optarg) -> BAD_FLAG/END_ARGS/NO_FLAG/opt
8  *
9  * argctl = {<optchar><typechar>}*
10  *  typechar ==  ?    -f  or -~f
11  *               +    -f arg or -~f
12  *               -    -f  or -~f arg
13  *               :    -f  arg   only
14  *
15  *
16  */
17
18 #define IN_ARGS
19 #include        "args.h"
20 void *malloc(int);
21 struct handle
22 {
23         int argc;
24         char **argv;
25         char *ctl;
26         int nextarg, nextchar;
27 };
28 #define NULLH ((struct handle *)0)
29
30 struct handle *args_init(int argc, char **argv, char *ctl)
31 {
32         /* if ctl is bad, return NULL, else a handle */
33         int i;
34         struct handle *h;
35         for (i=0 ; ctl[i]; i+= 2)
36                 if (ctl[i+1] != '?' && ctl[i+1] != '-' && ctl[i+1] != '+' && ctl[i+1] != ':')
37                         break;
38         if (ctl[i])
39                 return NULLH;
40
41         h = (struct handle*)malloc(sizeof(struct handle));
42         if (h == NULLH)
43                 return h;
44         h->argc = argc;
45         h->argv = argv;
46         h->ctl = ctl;
47         h->nextarg = 1;
48         h->nextchar = 0;
49         return h;
50 }
51
52 int args_next(struct handle *h, int *pos, int *inv, char **opt)
53 {
54         int invc = 0;
55         int invfound = 0;
56         int i;
57         char *a;
58         if (h->nextarg >= h->argc)
59                 return END_ARGS;
60         if (h->nextchar == 0)
61         {
62                 if (h->argv[h->nextarg][0] != '-')
63                 {
64                         if (pos) *pos = h->nextarg;
65                         if (inv) *inv = 0;
66                         if (opt) *opt = h->argv[h->nextarg];
67                         h->nextarg++;
68                         return NO_FLAG;
69                 }
70                 h->nextchar++;
71         }
72         a = h->argv[h->nextarg];
73         while (a[h->nextchar] == '~')
74         {
75                 invc = !invc;
76                 invfound = 1;
77                 h->nextchar++;
78         }
79         for (i=0 ; h->ctl[i] ; i+=2)
80                 if (h->ctl[i] == a[h->nextchar])
81                         break;
82         if (h->ctl[i] == 0)
83         {
84                 h->nextchar = 0;
85                 h->nextarg ++;
86                 return BAD_FLAG;
87         }
88         h->nextchar++;
89         if (pos) *pos = h->nextarg;
90         if (inv) *inv = invc;
91         if (a[h->nextchar] == 0)
92         {
93                 h->nextchar = 0;
94                 h->nextarg ++;
95         }
96         switch(h->ctl[i+1])
97         {
98         case '?':
99                 return h->ctl[i];
100         case '+':
101                 if (inv)
102                         return h->ctl[i];
103                 break;
104         case '-':
105                 if (!inv)
106                         return h->ctl[i];
107                 break;
108         case ':':
109                 break;
110         }
111         /* need optarg */
112         if (h->nextarg >= h->argc)
113                 return BAD_FLAG;
114         if (opt)
115                 *opt = h->argv[h->nextarg] + h->nextchar;
116         h->nextarg++;
117         h->nextchar=0;
118         return h->ctl[i];
119 }