Blame isl-0.14/include/isl/arg.h

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_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