📄 options.c
字号:
if (!strcmp(str, emap[i])) { if (eval) { /* bind to eval value */ *res = eval[i]; } else { /* bind to string index */ *res = i; } return TRUE; } } /* not found */ *res = -1; return FALSE;}/* bind a enumeration value to an enumeration string */static char *bind_to_str(int val, /* enumeration value */ char **emap, /* enumeration string map */ int *eval, /* enumeration value map, optional */ int emap_sz) /* size of maps */{ int i; if (eval) { /* bind to first matching eval value */ for (i=0; i<emap_sz; i++) { if (eval[i] == val) { /* found */ return emap[i]; } } /* not found */ return NULL; } else { /* bind to string at index */ if (val >= emap_sz) { /* invalid index */ return NULL; } /* else, index is in range */ return emap[val]; }}/* register an enumeration option variable, NOTE: all enumeration option variables must be of type `int', since true enum variables may be allocated with variable sizes by some compilers */voidopt_reg_enum(struct opt_odb_t *odb, /* option data base */ char *name, /* option name */ char *desc, /* option description */ int *var, /* target variable */ char *def_val, /* default variable value */ char **emap, /* enumeration string map */ int *eval, /* enumeration value map, optional */ int emap_sz, /* size of maps */ int print, /* print during `-dumpconfig'? */ char *format) /* option value print format */{ int enum_val; struct opt_opt_t *opt; opt = (struct opt_opt_t *)calloc(1, sizeof(struct opt_opt_t)); if (!opt) fatal("out of virtual memory"); opt->name = name; opt->desc = desc; opt->nvars = 1; opt->nelt = NULL; opt->format = format ? format : "%12s"; opt->oc = oc_enum; opt->variant.for_enum.var = var; opt->variant.for_enum.emap = emap; opt->variant.for_enum.eval = eval; opt->variant.for_enum.emap_sz = emap_sz; if (def_val) { if (!bind_to_enum(def_val, emap, eval, emap_sz, &enum_val)) fatal("could not bind default value for option `%s'", name); } else enum_val = 0; opt->print = print; opt->accrue = FALSE; /* place on ODB's option list */ opt->next = NULL; add_option(odb, opt); /* set default value */ *var = enum_val;}/* register an enumeration option array, NOTE: all enumeration option variables must be of type `int', since true enum variables may be allocated with variable sizes by some compilers */voidopt_reg_enum_list(struct opt_odb_t *odb,/* option data base */ char *name, /* option name */ char *desc, /* option description */ int *vars, /* target array */ int nvars, /* target array size */ int *nelt, /* number of args parsed goes here */ char *def_val, /* default variable value */ char **emap, /* enumeration string map */ int *eval, /* enumeration value map, optional */ int emap_sz, /* size of maps */ int print, /* print during `-dumpconfig'? */ char *format, /* option value print format */ int accrue) /* accrue list across uses */{ int i, enum_val; struct opt_opt_t *opt; opt = (struct opt_opt_t *)calloc(1, sizeof(struct opt_opt_t)); if (!opt) fatal("out of virtual memory"); opt->name = name; opt->desc = desc; opt->nvars = nvars; opt->nelt = nelt; opt->format = format ? format : "%s"; opt->oc = oc_enum; opt->variant.for_enum.var = vars; opt->variant.for_enum.emap = emap; opt->variant.for_enum.eval = eval; opt->variant.for_enum.emap_sz = emap_sz; if (def_val) { if (!bind_to_enum(def_val, emap, eval, emap_sz, &enum_val)) fatal("could not bind default value for option `%s'", name); } else enum_val = 0; opt->print = print; opt->accrue = accrue; /* place on ODB's option list */ opt->next = NULL; add_option(odb, opt); /* set default value */ for (i=0; i < *nelt; i++) vars[i] = enum_val;}/* pre-defined boolean flag operands */#define NUM_FLAGS 22static char *flag_emap[NUM_FLAGS] = { "true", "t", "T", "True", "TRUE", "1", "y", "Y", "yes", "Yes", "YES", "false", "f", "F", "False", "FALSE", "0", "n", "N", "no", "No", "NO"};static int flag_eval[NUM_FLAGS] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};/* register a boolean flag option variable */voidopt_reg_flag(struct opt_odb_t *odb, /* option data base */ char *name, /* option name */ char *desc, /* option description */ int *var, /* target variable */ int def_val, /* default variable value */ int print, /* print during `-dumpconfig'? */ char *format) /* optional value print format */{ struct opt_opt_t *opt; opt = (struct opt_opt_t *)calloc(1, sizeof(struct opt_opt_t)); if (!opt) fatal("out of virtual memory"); opt->name = name; opt->desc = desc; opt->nvars = 1; opt->nelt = NULL; opt->format = format ? format : "%12s"; opt->oc = oc_flag; opt->variant.for_enum.var = var; opt->variant.for_enum.emap = flag_emap; opt->variant.for_enum.eval = flag_eval; opt->variant.for_enum.emap_sz = NUM_FLAGS; opt->print = print; opt->accrue = FALSE; /* place on ODB's option list */ opt->next = NULL; add_option(odb, opt); /* set default value */ *var = def_val;}/* register a boolean flag option array */voidopt_reg_flag_list(struct opt_odb_t *odb,/* option database */ char *name, /* option name */ char *desc, /* option description */ int *vars, /* pointer to option array */ int nvars, /* total entries in option array */ int *nelt, /* number of elements parsed */ int *def_val, /* default array value */ int print, /* print during `-dumpconfig'? */ char *format, /* optional value print format */ int accrue) /* accrue list across uses */{ int i; struct opt_opt_t *opt; opt = (struct opt_opt_t *)calloc(1, sizeof(struct opt_opt_t)); if (!opt) fatal("out of virtual memory"); opt->name = name; opt->desc = desc; opt->nvars = nvars; opt->nelt = nelt; opt->format = format ? format : "%s"; opt->oc = oc_flag; opt->variant.for_enum.var = vars; opt->variant.for_enum.emap = flag_emap; opt->variant.for_enum.eval = flag_eval; opt->variant.for_enum.emap_sz = NUM_FLAGS; opt->print = print; opt->accrue = accrue; /* place on ODB's option list */ opt->next = NULL; add_option(odb, opt); /* set default value */ for (i=0; i < *nelt; i++) vars[i] = def_val[i];}/* register a string option variable */voidopt_reg_string(struct opt_odb_t *odb, /* option data base */ char *name, /* option name */ char *desc, /* option description */ char **var, /* pointer to string option variable */ char *def_val, /* default variable value */ int print, /* print during `-dumpconfig'? */ char *format) /* optional value print format */{ struct opt_opt_t *opt; opt = (struct opt_opt_t *)calloc(1, sizeof(struct opt_opt_t)); if (!opt) fatal("out of virtual memory"); opt->name = name; opt->desc = desc; opt->nvars = 1; opt->nelt = NULL; opt->format = format ? format : "%12s"; opt->oc = oc_string; opt->variant.for_string.var = var; opt->print = print; opt->accrue = FALSE; /* place on ODB's option list */ opt->next = NULL; add_option(odb, opt); /* set default value */ *var = def_val;}/* register a string option array */voidopt_reg_string_list(struct opt_odb_t *odb,/* option data base */ char *name, /* option name */ char *desc, /* option description */ char **vars, /* pointer to option string array */ int nvars, /* target array size */ int *nelt, /* number of args parsed goes here */ char **def_val, /* default variable value */ int print, /* print during `-dumpconfig'? */ char *format, /* optional value print format */ int accrue) /* accrue list across uses */{ int i; struct opt_opt_t *opt; opt = (struct opt_opt_t *)calloc(1, sizeof(struct opt_opt_t)); if (!opt) fatal("out of virtual memory"); opt->name = name; opt->desc = desc; opt->nvars = nvars; opt->nelt = nelt; opt->format = format ? format : "%s"; opt->oc = oc_string; opt->variant.for_string.var = vars; opt->print = print; opt->accrue = accrue; /* place on ODB's option list */ opt->next = NULL; add_option(odb, opt); /* set default value */ for (i=0; i < *nelt; i++) vars[i] = def_val[i];}/* process command line arguments, returns index of next argument to parse */intprocess_option(struct opt_odb_t *odb, /* option database */ int index, /* index of the first arg to parse */ int argc, /* total number of arguments */ char **argv) /* argument string array */{ int cnt, ent, nvars; char *endp; double tmp; struct opt_opt_t *opt; /* locate the option in the option database */ for (opt=odb->options; opt != NULL; opt=opt->next) { if (!strcmp(opt->name, argv[index])) break; } if (!opt) { /* no one registered this option */ fatal("option `%s' is undefined", argv[index]); } index++; /* process option arguments */ switch (opt->oc) { case oc_int: /* this option needs at least one argument */ if (index >= argc || argv[index][0] == '-') { /* no arguments available */ fatal("option `%s' requires an argument", opt->name); } cnt = 0; if (opt->accrue) { ent = opt->nelt ? *opt->nelt : 0; nvars = 1; if (ent >= opt->nvars) fatal("too many invocations of option `%s'", opt->name); } else { ent = 0; if (opt->nelt) *opt->nelt = 0; nvars = opt->nvars; } /* parse all arguments */ while (index < argc && cnt < nvars && argv[index][0] != '-') { opt->variant.for_int.var[ent] = strtol(argv[index], &endp, 0); if (*endp) { /* could not parse entire argument */ fatal("could not parse argument `%s' of option `%s'", argv[index], opt->name); } /* else, argument converted correctly */ if (opt->nelt) (*opt->nelt)++; cnt++; index++; ent++; } break; case oc_uint: /* this option needs at least one argument */ if (index >= argc || argv[index][0] == '-') { /* no arguments available */ fatal("option `%s' requires an argument", opt->name); } cnt = 0; if (opt->accrue) { ent = opt->nelt ? *opt->nelt : 0; nvars = 1; if (ent >= opt->nvars) fatal("too many invocations of option `%s'", opt->name); } else { ent = 0; if (opt->nelt) *opt->nelt = 0; nvars = opt->nvars; } /* parse all arguments */ while (index < argc && cnt < nvars && argv[index][0] != '-') { opt->variant.for_uint.var[ent] = strtoul(argv[index], &endp, 0); if (*endp) { /* could not parse entire argument */ fatal("could not parse argument `%s' of option `%s'", argv[index], opt->name); } /* else, argument converted correctly */ if (opt->nelt) (*opt->nelt)++; cnt++; index++; ent++; } break; case oc_float: /* this option needs at least one argument */ if (index >= argc || argv[index][0] == '-') { /* no arguments available */ fatal("option `%s' requires an argument", opt->name); } cnt = 0; if (opt->accrue) { ent = opt->nelt ? *opt->nelt : 0; nvars = 1; if (ent >= opt->nvars) fatal("too many invocations of option `%s'", opt->name); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -