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