]> git.neil.brown.name Git - metad.git/blob - nargs.c
Assorted reformating
[metad.git] / nargs.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 struct handle
21 {
22         int argc;
23         char **argv;
24         char *ctl;
25         int nextarg, nextchar;
26 };
27
28 struct handle *args_init(int argc, char **argv, char *ctl)
29 {
30         /* if ctl is bad, return NULL, else a handle */
31         int i;
32         handle *h;
33         for (i=0 ; ctl[i]; i+= 2)
34                 if (ctl[i+1] != '?' && ctl[i+1] != '-' && ctl[i+1] != '+' && ctl[i+1] != ':')
35                         break;
36         if (ctl[i])
37                 return NULL;
38
39         h = (struct handle*)malloc(sizeof(struct handle));
40         if (h == NULL)
41                 return h;
42         h->argc = argc;
43         h->argv = argv;
44         h->ctl = ctl;
45         h->nextarg = 1;
46         h->nextchar = 0;
47         return h;
48 }
49
50 int args_next(struct handle *h, int *pos, int *inv, char **opt)
51 {
52         int invc = 0;
53         int invfound = 0;
54         int i;
55         char *a;
56         if (h->nextarg >= h->argc)
57                 return END_ARGS;
58         if (h->nextchar == 0)
59         {
60                 if (h->argv[h->nextarg][0] != '-')
61                 {
62                         if (pos) *pos = h->nextarg;
63                         if (inv) *inv = 0;
64                         if (opt) *opt = h->argv[h->nextarg];
65                         h->nextarg++;
66                         return NO_FLAG;
67                 }
68                 h->nextchar++;
69         }
70         a = h->argv[h->nextarg];
71         while (a[h->nextchar] == '~')
72         {
73                 invc = !invc;
74                 invfound = 1;
75                 h->nextchar++;
76         }
77         for (i=0 ; h->ctl[i] ; i+=2)
78                 if (h->ctl[i] == a[h->nextchar])
79                         break;
80         if (h->ctl[i] == 0)
81         {
82                 h->nextchar = 0;
83                 h->nextarg ++;
84                 return BAD_FLAG;
85         }
86         h->nextchar++;
87         if (pos) *pos = h->nextarg;
88         if (inv) *inv = invc;
89         if (a[h->nextchar] == 0)
90         {
91                 h->nextchar = 0;
92                 h->nextarg ++;
93         }
94         switch(h->ctl[i+1])
95         {
96         case '?':
97                 return h->ctl[i];
98         case '+':
99                 if (inv)
100                         return h->ctl[i];
101                 break;
102         case '-':
103                 if (!inv)
104                         return h->ctl[i];
105                 break;
106         case ':':
107                 break;
108         }
109         /* need optarg */
110         if (h->nextarg >= h->argc)
111                 return BAD_FLAG;
112         if (opt)
113                 *opt = h->argv[h->nextarg] + h->nextchar;
114         h->nextarg++;
115         h->nextchar=0;
116         return h->ctl[i];
117 }