1
// Copyright 2012 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
9
typedef struct Flag Flag;
17
void (*set)(char*, void*);
18
void (*set2)(char*, char*, void*);
26
static Flag *fhash[512];
27
static Flag *first, *last;
32
* Mac OS can't deal with files that only declare data.
33
* ARGBEGIN mentions this function so that this file gets pulled in.
35
void __fixargv0(void) { }
37
// FNV-1 hash. http://isthe.com/chongo/tech/comp/fnv/
45
h = (h*16777619) ^ (uchar)*p++;
50
lookflag(char *name, int namelen, int creat)
55
h = fnv(name, namelen) & (nelem(fhash)-1);
56
for(f=fhash[h]; f; f=f->next) {
57
if(f->namelen == namelen && memcmp(f->name, name, namelen) == 0) {
59
sysfatal("multiple definitions of flag -%s", name);
67
f = malloc(sizeof *f);
69
sysfatal("out of memory");
70
memset(f, 0, sizeof *f);
84
count(char *arg, void *p)
96
flagcount(char *name, char *desc, int *p)
100
f = lookflag(name, strlen(name), 1);
108
atollwhex(char *s, void *p)
112
*(int64*)p = strtoll(s, &t, 0);
113
if(*s == '\0' || *t != '\0')
114
sysfatal("invalid numeric argument -%s=%s", curflag->name, s);
118
flagint64(char *name, char *desc, int64 *p)
122
f = lookflag(name, strlen(name), 1);
129
atolwhex(char *s, void *p)
133
*(int32*)p = strtol(s, &t, 0);
134
if(*s == '\0' || *t != '\0')
135
sysfatal("invalid numeric argument -%s=%s", curflag->name, s);
139
flagint32(char *name, char *desc, int32 *p)
143
f = lookflag(name, strlen(name), 1);
150
string(char *s, void *p)
156
flagstr(char *name, char *desc, char **p)
161
f = lookflag(name, strlen(name), 1);
168
fn0(char *s, void *p)
171
((void(*)(void))p)();
175
flagfn0(char *name, char *desc, void (*fn)(void))
179
f = lookflag(name, strlen(name), 1);
187
fn1(char *s, void *p)
189
((void(*)(char*))p)(s);
193
flagfn1(char *name, char *desc, void (*fn)(char*))
197
f = lookflag(name, strlen(name), 1);
204
fn2(char *s, char *t, void *p)
206
((void(*)(char*, char*))p)(s, t);
210
flagfn2(char *name, char *desc, void (*fn)(char*, char*))
214
f = lookflag(name, strlen(name), 1);
221
flagparse(int *argcp, char ***argvp, void (*usage)(void))
238
// stop before non-flag or -
239
if(*p != '-' || p[1] == '\0')
244
if(p[1] == '-' && p[2] == '\0') {
248
// turn --foo into -foo
249
if(p[1] == '-' && p[2] != '-')
252
// allow -flag=arg if present
254
q = strchr(name, '=');
256
namelen = q++ - name;
258
namelen = strlen(name);
259
f = lookflag(name, namelen, 0);
261
if(strcmp(p, "-h") == 0 || strcmp(p, "-help") == 0 || strcmp(p, "-?") == 0)
263
sysfatal("unknown flag %s", p);
267
// otherwise consume next argument if non-boolean
268
if(!f->iscount && q == nil) {
270
sysfatal("missing argument to flag %s", p);
274
// and another if we need two
277
sysfatal("missing second argument to flag %s", p);
278
f->set2(q, *argv++, f->arg);
295
for(f=first; f; f=f->allnext) {
297
if(p == nil || *p == '\0') // undocumented flag
301
fprint(fd, " -%s %.*s\n \t%s\n", f->name, utfnlen(p, q-p), p, q+2);
302
else if(f->namelen > 1)
303
fprint(fd, " -%s\n \t%s\n", f->name, p);
305
fprint(fd, " -%s\t%s\n", f->name, p);