1
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
50
51
52
53
54
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
86
87
88
89
90
91
92
93
94
95
96
112
113
114
117
118
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
155
156
157
158
159
160
161
162
163
164
/* ... */
/* ... */
#include "argtable3.h"
#ifndef ARG_AMALGAMATION
#include "argtable3_private.h"
#endif
#include <stdlib.h>
static void arg_dbl_resetfn(struct arg_dbl* parent) {
ARG_TRACE(("%s:resetfn(%p)\n", __FILE__, parent));
parent->count = 0;
}{ ... }
static int arg_dbl_scanfn(struct arg_dbl* parent, const char* argval) {
int errorcode = 0;
if (parent->count == parent->hdr.maxcount) {
errorcode = ARG_ERR_MAXCOUNT;
}{...} else if (!argval) {
parent->count++;
}{...} else {
double val;
char* end;
val = strtod(argval, &end);
if (*end == 0)
parent->dval[parent->count++] = val;
else
errorcode = ARG_ERR_BADDOUBLE;
}{...}
ARG_TRACE(("%s:scanfn(%p) returns %d\n", __FILE__, parent, errorcode));
return errorcode;
}{ ... }
static int arg_dbl_checkfn(struct arg_dbl* parent) {
int errorcode = (parent->count < parent->hdr.mincount) ? ARG_ERR_MINCOUNT : 0;
ARG_TRACE(("%s:checkfn(%p) returns %d\n", __FILE__, parent, errorcode));
return errorcode;
}{ ... }
static void arg_dbl_errorfn(struct arg_dbl* parent, arg_dstr_t ds, int errorcode, const char* argval, const char* progname) {
const char* shortopts = parent->hdr.shortopts;
const char* longopts = parent->hdr.longopts;
const char* datatype = parent->hdr.datatype;
argval = argval ? argval : "";
arg_dstr_catf(ds, "%s: ", progname);
switch (errorcode) {
case ARG_ERR_MINCOUNT:
arg_dstr_cat(ds, "missing option ");
arg_print_option_ds(ds, shortopts, longopts, datatype, "\n");
break;
...
case ARG_ERR_MAXCOUNT:
arg_dstr_cat(ds, "excess option ");
arg_print_option_ds(ds, shortopts, longopts, argval, "\n");
break;
...
case ARG_ERR_BADDOUBLE:
arg_dstr_catf(ds, "invalid argument \"%s\" to option ", argval);
arg_print_option_ds(ds, shortopts, longopts, datatype, "\n");
break;...
}{...}
}{ ... }
struct arg_dbl* arg_dbl0(const char* shortopts, const char* longopts, const char* datatype, const char* glossary) {
return arg_dbln(shortopts, longopts, datatype, 0, 1, glossary);
}{ ... }
struct arg_dbl* arg_dbl1(const char* shortopts, const char* longopts, const char* datatype, const char* glossary) {
return arg_dbln(shortopts, longopts, datatype, 1, 1, glossary);
}{ ... }
struct arg_dbl* arg_dbln(const char* shortopts, const char* longopts, const char* datatype, int mincount, int maxcount, const char* glossary) {
size_t nbytes;
struct arg_dbl* result;
size_t addr;
size_t rem;
maxcount = (maxcount < mincount) ? mincount : maxcount;
nbytes = sizeof(struct arg_dbl)
+ (size_t)(maxcount + 1) * sizeof(double);
result = (struct arg_dbl*)xmalloc(nbytes);
result->hdr.flag = ARG_HASVALUE;
result->hdr.shortopts = shortopts;
result->hdr.longopts = longopts;
result->hdr.datatype = datatype ? datatype : "<double>";
result->hdr.glossary = glossary;
result->hdr.mincount = mincount;
result->hdr.maxcount = maxcount;
result->hdr.parent = result;
result->hdr.resetfn = (arg_resetfn*)arg_dbl_resetfn;
result->hdr.scanfn = (arg_scanfn*)arg_dbl_scanfn;
result->hdr.checkfn = (arg_checkfn*)arg_dbl_checkfn;
result->hdr.errorfn = (arg_errorfn*)arg_dbl_errorfn;
/* ... */
addr = (size_t)(result + 1);
rem = addr % sizeof(double);
result->dval = (double*)(addr + sizeof(double) - rem);
ARG_TRACE(("addr=%p, dval=%p, sizeof(double)=%d rem=%d\n", addr, result->dval, (int)sizeof(double), (int)rem));
result->count = 0;
ARG_TRACE(("arg_dbln() returns %p\n", result));
return result;
}{ ... }