Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2008-2009 Katholieke Universiteit Leuven
  3.  *
  4.  * Use of this software is governed by the MIT license
  5.  *
  6.  * Written by Sven Verdoolaege, K.U.Leuven, Departement
  7.  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
  8.  */
  9.  
  10. #ifndef ISL_ARG_H
  11. #define ISL_ARG_H
  12.  
  13. #include <stddef.h>
  14. #include <stdlib.h>
  15.  
  16. #if defined(__cplusplus)
  17. extern "C" {
  18. #endif
  19.  
  20. struct isl_arg_choice {
  21.         const char      *name;
  22.         unsigned         value;
  23. };
  24.  
  25. struct isl_arg_flags {
  26.         const char      *name;
  27.         unsigned         mask;
  28.         unsigned         value;
  29. };
  30.  
  31. enum isl_arg_type {
  32.         isl_arg_end,
  33.         isl_arg_alias,
  34.         isl_arg_arg,
  35.         isl_arg_bool,
  36.         isl_arg_child,
  37.         isl_arg_choice,
  38.         isl_arg_flags,
  39.         isl_arg_footer,
  40.         isl_arg_int,
  41.         isl_arg_user,
  42.         isl_arg_long,
  43.         isl_arg_ulong,
  44.         isl_arg_str,
  45.         isl_arg_str_list,
  46.         isl_arg_version
  47. };
  48.  
  49. struct isl_args;
  50.  
  51. struct isl_arg {
  52.         enum isl_arg_type        type;
  53.         char                     short_name;
  54.         const char              *long_name;
  55.         const char              *argument_name;
  56. #define ISL_ARG_OFFSET_NONE     ((size_t) -1)
  57.         size_t                   offset;
  58.         const char              *help_msg;
  59. #define ISL_ARG_SINGLE_DASH     (1 << 0)
  60. #define ISL_ARG_BOOL_ARG        (1 << 1)
  61. #define ISL_ARG_HIDDEN          (1 << 2)
  62.         unsigned                 flags;
  63.         union {
  64.         struct {
  65.                 struct isl_arg_choice   *choice;
  66.                 unsigned                 default_value;
  67.                 unsigned                 default_selected;
  68.                 int (*set)(void *opt, unsigned val);
  69.         } choice;
  70.         struct {
  71.                 struct isl_arg_flags    *flags;
  72.                 unsigned                 default_value;
  73.         } flags;
  74.         struct {
  75.                 unsigned                 default_value;
  76.                 int (*set)(void *opt, unsigned val);
  77.         } b;
  78.         struct {
  79.                 int                     default_value;
  80.         } i;
  81.         struct {
  82.                 long                    default_value;
  83.                 long                    default_selected;
  84.                 int (*set)(void *opt, long val);
  85.         } l;
  86.         struct {
  87.                 unsigned long           default_value;
  88.         } ul;
  89.         struct {
  90.                 const char              *default_value;
  91.         } str;
  92.         struct {
  93.                 size_t                   offset_n;
  94.         } str_list;
  95.         struct {
  96.                 struct isl_args         *child;
  97.         } child;
  98.         struct {
  99.                 void (*print_version)(void);
  100.         } version;
  101.         struct {
  102.                 int (*init)(void*);
  103.                 void (*clear)(void*);
  104.         } user;
  105.         } u;
  106. };
  107.  
  108. struct isl_args {
  109.         size_t                   options_size;
  110.         struct isl_arg          *args;
  111. };
  112.  
  113. #define ISL_ARGS_START(s,name)                                          \
  114.         struct isl_arg name ## LIST[];                                  \
  115.         struct isl_args name = { sizeof(s), name ## LIST };             \
  116.         struct isl_arg name ## LIST[] = {
  117. #define ISL_ARGS_END                                                    \
  118.         { isl_arg_end } };
  119.  
  120. #define ISL_ARG_ALIAS(l)        {                                       \
  121.         .type = isl_arg_alias,                                          \
  122.         .long_name = l,                                                 \
  123. },
  124. #define ISL_ARG_ARG(st,f,a,d)   {                                       \
  125.         .type = isl_arg_arg,                                            \
  126.         .argument_name = a,                                             \
  127.         .offset = offsetof(st, f),                                      \
  128.         .u = { .str = { .default_value = d } }                          \
  129. },
  130. #define ISL_ARG_FOOTER(h)       {                                       \
  131.         .type = isl_arg_footer,                                         \
  132.         .help_msg = h,                                                  \
  133. },
  134. #define ISL_ARG_CHOICE(st,f,s,l,c,d,h)  {                               \
  135.         .type = isl_arg_choice,                                         \
  136.         .short_name = s,                                                \
  137.         .long_name = l,                                                 \
  138.         .offset = offsetof(st, f),                                      \
  139.         .help_msg = h,                                                  \
  140.         .u = { .choice = { .choice = c, .default_value = d,             \
  141.                             .default_selected = d, .set = NULL } }      \
  142. },
  143. #define ISL_ARG_OPT_CHOICE(st,f,s,l,c,d,ds,h)   {                       \
  144.         .type = isl_arg_choice,                                         \
  145.         .short_name = s,                                                \
  146.         .long_name = l,                                                 \
  147.         .offset = offsetof(st, f),                                      \
  148.         .help_msg = h,                                                  \
  149.         .u = { .choice = { .choice = c, .default_value = d,             \
  150.                             .default_selected = ds, .set = NULL } }     \
  151. },
  152. #define ISL_ARG_PHANTOM_USER_CHOICE_F(s,l,c,setter,d,h,fl)      {       \
  153.         .type = isl_arg_choice,                                         \
  154.         .short_name = s,                                                \
  155.         .long_name = l,                                                 \
  156.         .offset = ISL_ARG_OFFSET_NONE,                                  \
  157.         .help_msg = h,                                                  \
  158.         .flags = fl,                                                    \
  159.         .u = { .choice = { .choice = c, .default_value = d,             \
  160.                             .default_selected = d, .set = setter } }    \
  161. },
  162. #define ISL_ARG_USER_OPT_CHOICE(st,f,s,l,c,setter,d,ds,h)       {       \
  163.         .type = isl_arg_choice,                                         \
  164.         .short_name = s,                                                \
  165.         .long_name = l,                                                 \
  166.         .offset = offsetof(st, f),                                      \
  167.         .help_msg = h,                                                  \
  168.         .u = { .choice = { .choice = c, .default_value = d,             \
  169.                             .default_selected = ds, .set = setter } }   \
  170. },
  171. #define _ISL_ARG_BOOL_F(o,s,l,setter,d,h,fl)    {                       \
  172.         .type = isl_arg_bool,                                           \
  173.         .short_name = s,                                                \
  174.         .long_name = l,                                                 \
  175.         .offset = o,                                                    \
  176.         .help_msg = h,                                                  \
  177.         .flags = fl,                                                    \
  178.         .u = { .b = { .default_value = d, .set = setter } }             \
  179. },
  180. #define ISL_ARG_BOOL_F(st,f,s,l,d,h,fl)                                 \
  181.         _ISL_ARG_BOOL_F(offsetof(st, f),s,l,NULL,d,h,fl)
  182. #define ISL_ARG_BOOL(st,f,s,l,d,h)                                      \
  183.         ISL_ARG_BOOL_F(st,f,s,l,d,h,0)
  184. #define ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,fl)                         \
  185.         _ISL_ARG_BOOL_F(ISL_ARG_OFFSET_NONE,s,l,setter,0,h,fl)
  186. #define ISL_ARG_PHANTOM_BOOL(s,l,setter,h)                              \
  187.         ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,0)
  188. #define ISL_ARG_INT_F(st,f,s,l,a,d,h,fl)        {                       \
  189.         .type = isl_arg_int,                                            \
  190.         .short_name = s,                                                \
  191.         .long_name = l,                                                 \
  192.         .argument_name = a,                                             \
  193.         .offset = offsetof(st, f),                                      \
  194.         .help_msg = h,                                                  \
  195.         .flags = fl,                                                    \
  196.         .u = { .i = { .default_value = d } }                            \
  197. },
  198. #define ISL_ARG_INT(st,f,s,l,a,d,h)                                     \
  199.         ISL_ARG_INT_F(st,f,s,l,a,d,h,0)
  200. #define ISL_ARG_LONG(st,f,s,lo,d,h)     {                               \
  201.         .type = isl_arg_long,                                           \
  202.         .short_name = s,                                                \
  203.         .long_name = lo,                                                \
  204.         .offset = offsetof(st, f),                                      \
  205.         .help_msg = h,                                                  \
  206.         .u = { .l = { .default_value = d, .default_selected = d,        \
  207.                       .set = NULL } }                                   \
  208. },
  209. #define ISL_ARG_USER_LONG(st,f,s,lo,setter,d,h) {                       \
  210.         .type = isl_arg_long,                                           \
  211.         .short_name = s,                                                \
  212.         .long_name = lo,                                                \
  213.         .offset = offsetof(st, f),                                      \
  214.         .help_msg = h,                                                  \
  215.         .u = { .l = { .default_value = d, .default_selected = d,        \
  216.                       .set = setter } }                                 \
  217. },
  218. #define ISL_ARG_OPT_LONG(st,f,s,lo,d,ds,h)      {                       \
  219.         .type = isl_arg_long,                                           \
  220.         .short_name = s,                                                \
  221.         .long_name = lo,                                                \
  222.         .offset = offsetof(st, f),                                      \
  223.         .help_msg = h,                                                  \
  224.         .u = { .l = { .default_value = d, .default_selected = ds,       \
  225.                       .set = NULL } }                                   \
  226. },
  227. #define ISL_ARG_ULONG(st,f,s,l,d,h)     {                               \
  228.         .type = isl_arg_ulong,                                          \
  229.         .short_name = s,                                                \
  230.         .long_name = l,                                                 \
  231.         .offset = offsetof(st, f),                                      \
  232.         .help_msg = h,                                                  \
  233.         .u = { .ul = { .default_value = d } }                           \
  234. },
  235. #define ISL_ARG_STR_F(st,f,s,l,a,d,h,fl)        {                       \
  236.         .type = isl_arg_str,                                            \
  237.         .short_name = s,                                                \
  238.         .long_name = l,                                                 \
  239.         .argument_name = a,                                             \
  240.         .offset = offsetof(st, f),                                      \
  241.         .help_msg = h,                                                  \
  242.         .flags = fl,                                                    \
  243.         .u = { .str = { .default_value = d } }                          \
  244. },
  245. #define ISL_ARG_STR(st,f,s,l,a,d,h)                                     \
  246.         ISL_ARG_STR_F(st,f,s,l,a,d,h,0)
  247. #define ISL_ARG_STR_LIST(st,f_n,f_l,s,l,a,h)    {                       \
  248.         .type = isl_arg_str_list,                                       \
  249.         .short_name = s,                                                \
  250.         .long_name = l,                                                 \
  251.         .argument_name = a,                                             \
  252.         .offset = offsetof(st, f_l),                                    \
  253.         .help_msg = h,                                                  \
  254.         .u = { .str_list = { .offset_n = offsetof(st, f_n) } }          \
  255. },
  256. #define _ISL_ARG_CHILD(o,l,c,h,fl)      {                               \
  257.         .type = isl_arg_child,                                          \
  258.         .long_name = l,                                                 \
  259.         .offset = o,                                                    \
  260.         .help_msg = h,                                                  \
  261.         .flags = fl,                                                    \
  262.         .u = { .child = { .child = c } }                                \
  263. },
  264. #define ISL_ARG_CHILD(st,f,l,c,h)                                       \
  265.         _ISL_ARG_CHILD(offsetof(st, f),l,c,h,0)
  266. #define ISL_ARG_GROUP_F(l,c,h,fl)                                       \
  267.         _ISL_ARG_CHILD(ISL_ARG_OFFSET_NONE,l,c,h,fl)
  268. #define ISL_ARG_GROUP(l,c,h)                                            \
  269.         ISL_ARG_GROUP_F(l,c,h,0)
  270. #define ISL_ARG_FLAGS(st,f,s,l,c,d,h)   {                               \
  271.         .type = isl_arg_flags,                                          \
  272.         .short_name = s,                                                \
  273.         .long_name = l,                                                 \
  274.         .offset = offsetof(st, f),                                      \
  275.         .help_msg = h,                                                  \
  276.         .u = { .flags = { .flags = c, .default_value = d } }            \
  277. },
  278. #define ISL_ARG_USER(st,f,i,c) {                                        \
  279.         .type = isl_arg_user,                                           \
  280.         .offset = offsetof(st, f),                                      \
  281.         .u = { .user = { .init = i, .clear = c} }                       \
  282. },
  283. #define ISL_ARG_VERSION(print) {                                        \
  284.         .type = isl_arg_version,                                        \
  285.         .u = { .version = { .print_version = print } }                  \
  286. },
  287.  
  288. #define ISL_ARG_ALL             (1 << 0)
  289. #define ISL_ARG_SKIP_HELP       (1 << 1)
  290.  
  291. void isl_args_set_defaults(struct isl_args *args, void *opt);
  292. void isl_args_free(struct isl_args *args, void *opt);
  293. int isl_args_parse(struct isl_args *args, int argc, char **argv, void *opt,
  294.         unsigned flags);
  295.  
  296. #define ISL_ARG_DECL(prefix,st,args)                                    \
  297. extern struct isl_args args;                                            \
  298. st *prefix ## _new_with_defaults(void);                                 \
  299. void prefix ## _free(st *opt);                                          \
  300. int prefix ## _parse(st *opt, int argc, char **argv, unsigned flags);
  301.  
  302. #define ISL_ARG_DEF(prefix,st,args)                                     \
  303. st *prefix ## _new_with_defaults()                                      \
  304. {                                                                       \
  305.         st *opt = (st *)calloc(1, sizeof(st));                          \
  306.         if (opt)                                                        \
  307.                 isl_args_set_defaults(&(args), opt);                    \
  308.         return opt;                                                     \
  309. }                                                                       \
  310.                                                                         \
  311. void prefix ## _free(st *opt)                                           \
  312. {                                                                       \
  313.         isl_args_free(&(args), opt);                                    \
  314. }                                                                       \
  315.                                                                         \
  316. int prefix ## _parse(st *opt, int argc, char **argv, unsigned flags)    \
  317. {                                                                       \
  318.         return isl_args_parse(&(args), argc, argv, opt, flags);         \
  319. }
  320.  
  321. #if defined(__cplusplus)
  322. }
  323. #endif
  324.  
  325. #endif
  326.