|
Packit |
fb9d21 |
/*
|
|
Packit |
fb9d21 |
* Copyright 2008-2009 Katholieke Universiteit Leuven
|
|
Packit |
fb9d21 |
*
|
|
Packit |
fb9d21 |
* Use of this software is governed by the MIT license
|
|
Packit |
fb9d21 |
*
|
|
Packit |
fb9d21 |
* Written by Sven Verdoolaege, K.U.Leuven, Departement
|
|
Packit |
fb9d21 |
* Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
|
|
Packit |
fb9d21 |
*/
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
#ifndef ISL_ARG_H
|
|
Packit |
fb9d21 |
#define ISL_ARG_H
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
#include <stddef.h>
|
|
Packit |
fb9d21 |
#include <stdlib.h>
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
#if defined(__cplusplus)
|
|
Packit |
fb9d21 |
extern "C" {
|
|
Packit |
fb9d21 |
#endif
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
struct isl_arg_choice {
|
|
Packit |
fb9d21 |
const char *name;
|
|
Packit |
fb9d21 |
unsigned value;
|
|
Packit |
fb9d21 |
};
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
struct isl_arg_flags {
|
|
Packit |
fb9d21 |
const char *name;
|
|
Packit |
fb9d21 |
unsigned mask;
|
|
Packit |
fb9d21 |
unsigned value;
|
|
Packit |
fb9d21 |
};
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
enum isl_arg_type {
|
|
Packit |
fb9d21 |
isl_arg_end,
|
|
Packit |
fb9d21 |
isl_arg_alias,
|
|
Packit |
fb9d21 |
isl_arg_arg,
|
|
Packit |
fb9d21 |
isl_arg_bool,
|
|
Packit |
fb9d21 |
isl_arg_child,
|
|
Packit |
fb9d21 |
isl_arg_choice,
|
|
Packit |
fb9d21 |
isl_arg_flags,
|
|
Packit |
fb9d21 |
isl_arg_footer,
|
|
Packit |
fb9d21 |
isl_arg_int,
|
|
Packit |
fb9d21 |
isl_arg_user,
|
|
Packit |
fb9d21 |
isl_arg_long,
|
|
Packit |
fb9d21 |
isl_arg_ulong,
|
|
Packit |
fb9d21 |
isl_arg_str,
|
|
Packit |
fb9d21 |
isl_arg_str_list,
|
|
Packit |
fb9d21 |
isl_arg_version
|
|
Packit |
fb9d21 |
};
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
struct isl_args;
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
struct isl_arg {
|
|
Packit |
fb9d21 |
enum isl_arg_type type;
|
|
Packit |
fb9d21 |
char short_name;
|
|
Packit |
fb9d21 |
const char *long_name;
|
|
Packit |
fb9d21 |
const char *argument_name;
|
|
Packit |
fb9d21 |
size_t offset;
|
|
Packit |
fb9d21 |
const char *help_msg;
|
|
Packit |
fb9d21 |
#define ISL_ARG_SINGLE_DASH (1 << 0)
|
|
Packit |
fb9d21 |
#define ISL_ARG_BOOL_ARG (1 << 1)
|
|
Packit |
fb9d21 |
#define ISL_ARG_HIDDEN (1 << 2)
|
|
Packit |
fb9d21 |
unsigned flags;
|
|
Packit |
fb9d21 |
union {
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
struct isl_arg_choice *choice;
|
|
Packit |
fb9d21 |
unsigned default_value;
|
|
Packit |
fb9d21 |
unsigned default_selected;
|
|
Packit |
fb9d21 |
int (*set)(void *opt, unsigned val);
|
|
Packit |
fb9d21 |
} choice;
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
struct isl_arg_flags *flags;
|
|
Packit |
fb9d21 |
unsigned default_value;
|
|
Packit |
fb9d21 |
} flags;
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
unsigned default_value;
|
|
Packit |
fb9d21 |
int (*set)(void *opt, unsigned val);
|
|
Packit |
fb9d21 |
} b;
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
int default_value;
|
|
Packit |
fb9d21 |
} i;
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
long default_value;
|
|
Packit |
fb9d21 |
long default_selected;
|
|
Packit |
fb9d21 |
int (*set)(void *opt, long val);
|
|
Packit |
fb9d21 |
} l;
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
unsigned long default_value;
|
|
Packit |
fb9d21 |
} ul;
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
const char *default_value;
|
|
Packit |
fb9d21 |
} str;
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
size_t offset_n;
|
|
Packit |
fb9d21 |
} str_list;
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
struct isl_args *child;
|
|
Packit |
fb9d21 |
} child;
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
void (*print_version)(void);
|
|
Packit |
fb9d21 |
} version;
|
|
Packit |
fb9d21 |
struct {
|
|
Packit |
fb9d21 |
int (*init)(void*);
|
|
Packit |
fb9d21 |
void (*clear)(void*);
|
|
Packit |
fb9d21 |
} user;
|
|
Packit |
fb9d21 |
} u;
|
|
Packit |
fb9d21 |
};
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
struct isl_args {
|
|
Packit |
fb9d21 |
size_t options_size;
|
|
Packit |
fb9d21 |
struct isl_arg *args;
|
|
Packit |
fb9d21 |
};
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
#define ISL_ARGS_START(s,name) \
|
|
Packit |
fb9d21 |
struct isl_arg name ## LIST[]; \
|
|
Packit |
fb9d21 |
struct isl_args name = { sizeof(s), name ## LIST }; \
|
|
Packit |
fb9d21 |
struct isl_arg name ## LIST[] = {
|
|
Packit |
fb9d21 |
#define ISL_ARGS_END \
|
|
Packit |
fb9d21 |
{ isl_arg_end } };
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
#define ISL_ARG_ALIAS(l) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_alias, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_ARG(st,f,a,d) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_arg, \
|
|
Packit |
fb9d21 |
.argument_name = a, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.u = { .str = { .default_value = d } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_FOOTER(h) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_footer, \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_CHOICE(st,f,s,l,c,d,h) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_choice, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.u = { .choice = { .choice = c, .default_value = d, \
|
|
Packit |
fb9d21 |
.default_selected = d, .set = NULL } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_OPT_CHOICE(st,f,s,l,c,d,ds,h) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_choice, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.u = { .choice = { .choice = c, .default_value = d, \
|
|
Packit |
fb9d21 |
.default_selected = ds, .set = NULL } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_PHANTOM_USER_CHOICE_F(s,l,c,setter,d,h,fl) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_choice, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.offset = -1, \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.flags = fl, \
|
|
Packit |
fb9d21 |
.u = { .choice = { .choice = c, .default_value = d, \
|
|
Packit |
fb9d21 |
.default_selected = d, .set = setter } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_USER_OPT_CHOICE(st,f,s,l,c,setter,d,ds,h) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_choice, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.u = { .choice = { .choice = c, .default_value = d, \
|
|
Packit |
fb9d21 |
.default_selected = ds, .set = setter } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define _ISL_ARG_BOOL_F(o,s,l,setter,d,h,fl) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_bool, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.offset = o, \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.flags = fl, \
|
|
Packit |
fb9d21 |
.u = { .b = { .default_value = d, .set = setter } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_BOOL_F(st,f,s,l,d,h,fl) \
|
|
Packit |
fb9d21 |
_ISL_ARG_BOOL_F(offsetof(st, f),s,l,NULL,d,h,fl)
|
|
Packit |
fb9d21 |
#define ISL_ARG_BOOL(st,f,s,l,d,h) \
|
|
Packit |
fb9d21 |
ISL_ARG_BOOL_F(st,f,s,l,d,h,0)
|
|
Packit |
fb9d21 |
#define ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,fl) \
|
|
Packit |
fb9d21 |
_ISL_ARG_BOOL_F(-1,s,l,setter,0,h,fl)
|
|
Packit |
fb9d21 |
#define ISL_ARG_PHANTOM_BOOL(s,l,setter,h) \
|
|
Packit |
fb9d21 |
ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,0)
|
|
Packit |
fb9d21 |
#define ISL_ARG_INT_F(st,f,s,l,a,d,h,fl) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_int, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.argument_name = a, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.flags = fl, \
|
|
Packit |
fb9d21 |
.u = { .ul = { .default_value = d } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_INT(st,f,s,l,a,d,h) \
|
|
Packit |
fb9d21 |
ISL_ARG_INT_F(st,f,s,l,a,d,h,0)
|
|
Packit |
fb9d21 |
#define ISL_ARG_LONG(st,f,s,lo,d,h) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_long, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = lo, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.u = { .l = { .default_value = d, .default_selected = d, \
|
|
Packit |
fb9d21 |
.set = NULL } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_USER_LONG(st,f,s,lo,setter,d,h) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_long, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = lo, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.u = { .l = { .default_value = d, .default_selected = d, \
|
|
Packit |
fb9d21 |
.set = setter } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_OPT_LONG(st,f,s,lo,d,ds,h) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_long, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = lo, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.u = { .l = { .default_value = d, .default_selected = ds, \
|
|
Packit |
fb9d21 |
.set = NULL } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_ULONG(st,f,s,l,d,h) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_ulong, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.u = { .ul = { .default_value = d } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_STR_F(st,f,s,l,a,d,h,fl) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_str, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.argument_name = a, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.flags = fl, \
|
|
Packit |
fb9d21 |
.u = { .str = { .default_value = d } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_STR(st,f,s,l,a,d,h) \
|
|
Packit |
fb9d21 |
ISL_ARG_STR_F(st,f,s,l,a,d,h,0)
|
|
Packit |
fb9d21 |
#define ISL_ARG_STR_LIST(st,f_n,f_l,s,l,a,h) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_str_list, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.argument_name = a, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f_l), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.u = { .str_list = { .offset_n = offsetof(st, f_n) } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define _ISL_ARG_CHILD(o,l,c,h,fl) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_child, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.offset = o, \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.flags = fl, \
|
|
Packit |
fb9d21 |
.u = { .child = { .child = c } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_CHILD(st,f,l,c,h) \
|
|
Packit |
fb9d21 |
_ISL_ARG_CHILD(offsetof(st, f),l,c,h,0)
|
|
Packit |
fb9d21 |
#define ISL_ARG_GROUP_F(l,c,h,fl) \
|
|
Packit |
fb9d21 |
_ISL_ARG_CHILD(-1,l,c,h,fl)
|
|
Packit |
fb9d21 |
#define ISL_ARG_GROUP(l,c,h) \
|
|
Packit |
fb9d21 |
ISL_ARG_GROUP_F(l,c,h,0)
|
|
Packit |
fb9d21 |
#define ISL_ARG_FLAGS(st,f,s,l,c,d,h) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_flags, \
|
|
Packit |
fb9d21 |
.short_name = s, \
|
|
Packit |
fb9d21 |
.long_name = l, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.help_msg = h, \
|
|
Packit |
fb9d21 |
.u = { .flags = { .flags = c, .default_value = d } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_USER(st,f,i,c) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_user, \
|
|
Packit |
fb9d21 |
.offset = offsetof(st, f), \
|
|
Packit |
fb9d21 |
.u = { .user = { .init = i, .clear = c} } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
#define ISL_ARG_VERSION(print) { \
|
|
Packit |
fb9d21 |
.type = isl_arg_version, \
|
|
Packit |
fb9d21 |
.u = { .version = { .print_version = print } } \
|
|
Packit |
fb9d21 |
},
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
#define ISL_ARG_ALL (1 << 0)
|
|
Packit |
fb9d21 |
#define ISL_ARG_SKIP_HELP (1 << 1)
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
void isl_args_set_defaults(struct isl_args *args, void *opt);
|
|
Packit |
fb9d21 |
void isl_args_free(struct isl_args *args, void *opt);
|
|
Packit |
fb9d21 |
int isl_args_parse(struct isl_args *args, int argc, char **argv, void *opt,
|
|
Packit |
fb9d21 |
unsigned flags);
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
#define ISL_ARG_DECL(prefix,st,args) \
|
|
Packit |
fb9d21 |
extern struct isl_args args; \
|
|
Packit |
fb9d21 |
st *prefix ## _new_with_defaults(void); \
|
|
Packit |
fb9d21 |
void prefix ## _free(st *opt); \
|
|
Packit |
fb9d21 |
int prefix ## _parse(st *opt, int argc, char **argv, unsigned flags);
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
#define ISL_ARG_DEF(prefix,st,args) \
|
|
Packit |
fb9d21 |
st *prefix ## _new_with_defaults() \
|
|
Packit |
fb9d21 |
{ \
|
|
Packit |
fb9d21 |
st *opt = (st *)calloc(1, sizeof(st)); \
|
|
Packit |
fb9d21 |
if (opt) \
|
|
Packit |
fb9d21 |
isl_args_set_defaults(&(args), opt); \
|
|
Packit |
fb9d21 |
return opt; \
|
|
Packit |
fb9d21 |
} \
|
|
Packit |
fb9d21 |
\
|
|
Packit |
fb9d21 |
void prefix ## _free(st *opt) \
|
|
Packit |
fb9d21 |
{ \
|
|
Packit |
fb9d21 |
isl_args_free(&(args), opt); \
|
|
Packit |
fb9d21 |
} \
|
|
Packit |
fb9d21 |
\
|
|
Packit |
fb9d21 |
int prefix ## _parse(st *opt, int argc, char **argv, unsigned flags) \
|
|
Packit |
fb9d21 |
{ \
|
|
Packit |
fb9d21 |
return isl_args_parse(&(args), argc, argv, opt, flags); \
|
|
Packit |
fb9d21 |
}
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
#if defined(__cplusplus)
|
|
Packit |
fb9d21 |
}
|
|
Packit |
fb9d21 |
#endif
|
|
Packit |
fb9d21 |
|
|
Packit |
fb9d21 |
#endif
|