Home | History | Annotate | Download | only in util
      1 #ifndef __PERF_PARSE_OPTIONS_H
      2 #define __PERF_PARSE_OPTIONS_H
      3 
      4 #include <linux/kernel.h>
      5 #include <stdbool.h>
      6 
      7 enum parse_opt_type {
      8 	/* special types */
      9 	OPTION_END,
     10 	OPTION_ARGUMENT,
     11 	OPTION_GROUP,
     12 	/* options with no arguments */
     13 	OPTION_BIT,
     14 	OPTION_BOOLEAN,
     15 	OPTION_INCR,
     16 	OPTION_SET_UINT,
     17 	OPTION_SET_PTR,
     18 	/* options with arguments (usually) */
     19 	OPTION_STRING,
     20 	OPTION_INTEGER,
     21 	OPTION_LONG,
     22 	OPTION_CALLBACK,
     23 	OPTION_U64,
     24 	OPTION_UINTEGER,
     25 };
     26 
     27 enum parse_opt_flags {
     28 	PARSE_OPT_KEEP_DASHDASH = 1,
     29 	PARSE_OPT_STOP_AT_NON_OPTION = 2,
     30 	PARSE_OPT_KEEP_ARGV0 = 4,
     31 	PARSE_OPT_KEEP_UNKNOWN = 8,
     32 	PARSE_OPT_NO_INTERNAL_HELP = 16,
     33 };
     34 
     35 enum parse_opt_option_flags {
     36 	PARSE_OPT_OPTARG  = 1,
     37 	PARSE_OPT_NOARG   = 2,
     38 	PARSE_OPT_NONEG   = 4,
     39 	PARSE_OPT_HIDDEN  = 8,
     40 	PARSE_OPT_LASTARG_DEFAULT = 16,
     41 };
     42 
     43 struct option;
     44 typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
     45 
     46 /*
     47  * `type`::
     48  *   holds the type of the option, you must have an OPTION_END last in your
     49  *   array.
     50  *
     51  * `short_name`::
     52  *   the character to use as a short option name, '\0' if none.
     53  *
     54  * `long_name`::
     55  *   the long option name, without the leading dashes, NULL if none.
     56  *
     57  * `value`::
     58  *   stores pointers to the values to be filled.
     59  *
     60  * `argh`::
     61  *   token to explain the kind of argument this option wants. Keep it
     62  *   homogenous across the repository.
     63  *
     64  * `help`::
     65  *   the short help associated to what the option does.
     66  *   Must never be NULL (except for OPTION_END).
     67  *   OPTION_GROUP uses this pointer to store the group header.
     68  *
     69  * `flags`::
     70  *   mask of parse_opt_option_flags.
     71  *   PARSE_OPT_OPTARG: says that the argument is optionnal (not for BOOLEANs)
     72  *   PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs
     73  *   PARSE_OPT_NONEG: says that this option cannot be negated
     74  *   PARSE_OPT_HIDDEN this option is skipped in the default usage, showed in
     75  *                    the long one.
     76  *
     77  * `callback`::
     78  *   pointer to the callback to use for OPTION_CALLBACK.
     79  *
     80  * `defval`::
     81  *   default value to fill (*->value) with for PARSE_OPT_OPTARG.
     82  *   OPTION_{BIT,SET_UINT,SET_PTR} store the {mask,integer,pointer} to put in
     83  *   the value when met.
     84  *   CALLBACKS can use it like they want.
     85  */
     86 struct option {
     87 	enum parse_opt_type type;
     88 	int short_name;
     89 	const char *long_name;
     90 	void *value;
     91 	const char *argh;
     92 	const char *help;
     93 
     94 	int flags;
     95 	parse_opt_cb *callback;
     96 	intptr_t defval;
     97 };
     98 
     99 #define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v )
    100 
    101 #define OPT_END()                   { .type = OPTION_END }
    102 #define OPT_ARGUMENT(l, h)          { .type = OPTION_ARGUMENT, .long_name = (l), .help = (h) }
    103 #define OPT_GROUP(h)                { .type = OPTION_GROUP, .help = (h) }
    104 #define OPT_BIT(s, l, v, h, b)      { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h), .defval = (b) }
    105 #define OPT_BOOLEAN(s, l, v, h)     { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = check_vtype(v, bool *), .help = (h) }
    106 #define OPT_INCR(s, l, v, h)        { .type = OPTION_INCR, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h) }
    107 #define OPT_SET_UINT(s, l, v, h, i)  { .type = OPTION_SET_UINT, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned int *), .help = (h), .defval = (i) }
    108 #define OPT_SET_PTR(s, l, v, h, p)  { .type = OPTION_SET_PTR, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (p) }
    109 #define OPT_INTEGER(s, l, v, h)     { .type = OPTION_INTEGER, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h) }
    110 #define OPT_UINTEGER(s, l, v, h)    { .type = OPTION_UINTEGER, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned int *), .help = (h) }
    111 #define OPT_LONG(s, l, v, h)        { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = check_vtype(v, long *), .help = (h) }
    112 #define OPT_U64(s, l, v, h)         { .type = OPTION_U64, .short_name = (s), .long_name = (l), .value = check_vtype(v, u64 *), .help = (h) }
    113 #define OPT_STRING(s, l, v, a, h)   { .type = OPTION_STRING,  .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h) }
    114 #define OPT_DATE(s, l, v, h) \
    115 	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
    116 #define OPT_CALLBACK(s, l, v, a, h, f) \
    117 	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f) }
    118 #define OPT_CALLBACK_NOOPT(s, l, v, a, h, f) \
    119 	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f), .flags = PARSE_OPT_NOARG }
    120 #define OPT_CALLBACK_DEFAULT(s, l, v, a, h, f, d) \
    121 	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f), .defval = (intptr_t)d, .flags = PARSE_OPT_LASTARG_DEFAULT }
    122 #define OPT_CALLBACK_DEFAULT_NOOPT(s, l, v, a, h, f, d) \
    123 	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l),\
    124 	.value = (v), (a), .help = (h), .callback = (f), .defval = (intptr_t)d,\
    125 	.flags = PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NOARG}
    126 
    127 /* parse_options() will filter out the processed options and leave the
    128  * non-option argments in argv[].
    129  * Returns the number of arguments left in argv[].
    130  */
    131 extern int parse_options(int argc, const char **argv,
    132                          const struct option *options,
    133                          const char * const usagestr[], int flags);
    134 
    135 extern NORETURN void usage_with_options(const char * const *usagestr,
    136                                         const struct option *options);
    137 
    138 /*----- incremantal advanced APIs -----*/
    139 
    140 enum {
    141 	PARSE_OPT_HELP = -1,
    142 	PARSE_OPT_DONE,
    143 	PARSE_OPT_LIST,
    144 	PARSE_OPT_UNKNOWN,
    145 };
    146 
    147 /*
    148  * It's okay for the caller to consume argv/argc in the usual way.
    149  * Other fields of that structure are private to parse-options and should not
    150  * be modified in any way.
    151  */
    152 struct parse_opt_ctx_t {
    153 	const char **argv;
    154 	const char **out;
    155 	int argc, cpidx;
    156 	const char *opt;
    157 	int flags;
    158 };
    159 
    160 extern int parse_options_usage(const char * const *usagestr,
    161 			       const struct option *opts);
    162 
    163 extern void parse_options_start(struct parse_opt_ctx_t *ctx,
    164 				int argc, const char **argv, int flags);
    165 
    166 extern int parse_options_step(struct parse_opt_ctx_t *ctx,
    167 			      const struct option *options,
    168 			      const char * const usagestr[]);
    169 
    170 extern int parse_options_end(struct parse_opt_ctx_t *ctx);
    171 
    172 
    173 /*----- some often used options -----*/
    174 extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
    175 extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
    176 extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
    177 
    178 #define OPT__VERBOSE(var)  OPT_BOOLEAN('v', "verbose", (var), "be verbose")
    179 #define OPT__QUIET(var)    OPT_BOOLEAN('q', "quiet",   (var), "be quiet")
    180 #define OPT__VERBOSITY(var) \
    181 	{ OPTION_CALLBACK, 'v', "verbose", (var), NULL, "be more verbose", \
    182 	  PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }, \
    183 	{ OPTION_CALLBACK, 'q', "quiet", (var), NULL, "be more quiet", \
    184 	  PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }
    185 #define OPT__DRY_RUN(var)  OPT_BOOLEAN('n', "dry-run", (var), "dry run")
    186 #define OPT__ABBREV(var)  \
    187 	{ OPTION_CALLBACK, 0, "abbrev", (var), "n", \
    188 	  "use <n> digits to display SHA-1s", \
    189 	  PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 }
    190 
    191 extern const char *parse_options_fix_filename(const char *prefix, const char *file);
    192 
    193 #endif /* __PERF_PARSE_OPTIONS_H */
    194