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