📄 options.c
字号:
if (opt->nelt) nelt = *(opt->nelt); else nelt = 1; for (i=0; i<nelt; i++) { char *estr = bind_to_str(opt->variant.for_enum.var[i], opt->variant.for_enum.emap, opt->variant.for_enum.eval, opt->variant.for_enum.emap_sz); if (!estr) panic("could not bind boolean `%d' for option `%s'", opt->variant.for_enum.var[i], opt->name); fprintf(fd, opt->format, estr); fprintf(fd, " "); } break; case oc_string: if (!opt->nvars) { fprintf(fd, "%12s ", "<null>"); break; } if (opt->nelt) nelt = *(opt->nelt); else nelt = 1; if (nelt == 0) { fprintf(fd, "%12s ", "<null>"); break; } else { for (i=0; i<nelt; i++) { fprintf(fd, opt->format, (opt->variant.for_string.var[i] ? opt->variant.for_string.var[i] : "<null>")); fprintf(fd, " "); } } break; default: panic("bogus option class"); }}/* print any options header */static voidprint_option_header(struct opt_odb_t *odb,/* options database */ FILE *fd) /* output stream */{ if (!odb->header) return; fprintf(fd, "\n%s\n", odb->header);}/* print option notes */static voidprint_option_notes(struct opt_odb_t *odb,/* options database */ FILE *fd) /* output stream */{ struct opt_note_t *note; if (!odb->notes) return; fprintf(fd, "\n"); for (note=odb->notes; note != NULL; note=note->next) fprintf(fd, "%s\n", note->note); fprintf(fd, "\n");}/* builtin options */static struct opt_opt_t dumpconfig_opt = { NULL, "-dumpconfig", "dump configuration to a file", 0, NULL, NULL, FALSE, FALSE, oc_string };static struct opt_opt_t config_opt = { &dumpconfig_opt, "-config", "load configuration from a file", 0, NULL, NULL, FALSE, FALSE, oc_string };static struct opt_opt_t *builtin_options = &config_opt;/* return non-zero if the option is a NULL-valued string option */int /* non-zero if null string option */opt_null_string(struct opt_opt_t *opt){ return (opt != NULL && opt->oc == oc_string && (opt->nvars == 0 || (opt->nelt != NULL && *opt->nelt == 0) || (opt->nelt == NULL && (opt->variant.for_string.var == NULL || opt->variant.for_string.var[0] == NULL))));}/* print all options and current values */voidopt_print_options(struct opt_odb_t *odb,/* option data base */ FILE *fd, /* output stream */ int terse, /* print terse options? */ int notes) /* include notes? */{ struct opt_opt_t *opt; if (!odb) { /* no options */ return; } /* print any options header */ if (notes) print_option_header(odb, fd); /* dump out builtin options */ for (opt=builtin_options; opt != NULL; opt=opt->next) { if (terse) fprintf(fd, "# %-27s # %s\n", opt->name, opt->desc); else { fprintf(fd, "# %s\n", opt->desc); fprintf(fd, "# %-22s\n\n", opt->name); } } /* dump out options from options database */ for (opt=odb->options; opt != NULL; opt=opt->next) { if (terse) { if (!opt->print || opt_null_string(opt)) fprintf(fd, "# %-14s ", opt->name); else fprintf(fd, "%-16s ", opt->name); opt_print_option(opt, fd); if (opt->desc) fprintf(fd, "# %-22s", opt->desc); fprintf(fd, "\n"); } else { if (opt->desc) fprintf(fd, "# %s\n", opt->desc); if (!opt->print || opt_null_string(opt)) fprintf(fd, "# %-20s ", opt->name); else fprintf(fd, "%-22s ", opt->name); opt_print_option(opt, fd); fprintf(fd, "\n\n"); } } /* print option notes */ if (notes) print_option_notes(odb, fd);}/* print help information for an option */static voidprint_help(struct opt_opt_t *opt, /* option variable */ FILE *fd) /* output stream */{ char *s = NULL; fprintf(fd, "%-16s ", opt->name); switch (opt->oc) { case oc_int: if (opt->nvars == 1) s = "<int>"; else s = "<int list...>"; break; case oc_uint: if (opt->nvars == 1) s = "<uint>"; else s = "<uint list...>"; break; case oc_float: if (opt->nvars == 1) s = "<float>"; else s = "<float list...>"; break; case oc_double: if (opt->nvars == 1) s = "<double>"; else s = "<double list...>"; break; case oc_enum: if (opt->nvars == 1) s = "<enum>"; else s = "<enum list...>"; break; case oc_flag: if (opt->nvars == 1) s = "<true|false>"; else s = "<true|false list...>"; break; case oc_string: if (opt->nvars == 0 || opt->nvars == 1) s = "<string>"; else s = "<string list...>"; break; default: panic("bogus option class"); } fprintf(fd, "%-16s # ", s); opt_print_option(opt, fd); fprintf(fd, "# %-22s\n", opt->desc);}/* print option help page with default values */voidopt_print_help(struct opt_odb_t *odb, /* option data base */ FILE *fd) /* output stream */{ struct opt_opt_t *opt; /* print any options header */ print_option_header(odb, fd); fprintf(fd, "#\n"); fprintf(fd, "%-16s %-16s # %12s # %-22s\n", "# -option", "<args>", "<default>", "description"); fprintf(fd, "#\n"); /* print out help info for builtin options */ for (opt=builtin_options; opt != NULL; opt=opt->next) print_help(opt, fd); /* print out help info for options in options database */ for (opt=odb->options; opt != NULL; opt=opt->next) print_help(opt, fd); /* print option notes */ print_option_notes(odb, fd);}/* handle `-dumpconfig' builtin option, print options from file argument */static voiddump_config(struct opt_odb_t *odb, /* option data base */ char *fname) /* output file name, "-" == stdout */{ FILE *fd; /* open output file stream */ if (!strcmp(fname, "-")) fd = stdout; else { fd = fopen(fname, "w"); if (!fd) fatal("could not open file `%s'", fname); } /* print current option values to output stream */ opt_print_options(odb, fd, /* long */FALSE, /* !notes */FALSE); /* close output stream, if not a standard stream */ if (fd != stdout && fd != stderr) fclose(fd);}/* find an option by name in the option database, returns NULL if not found */struct opt_opt_t *opt_find_option(struct opt_odb_t *odb, /* option database */ char *opt_name) /* option name */{ struct opt_opt_t *opt; /* search builtin options */ for (opt = builtin_options; opt != NULL; opt = opt->next) { if (!strcmp(opt->name, opt_name)) { /* located option */ return opt; } } /* search user-installed options */ for (opt = odb->options; opt != NULL; opt = opt->next) { if (!strcmp(opt->name, opt_name)) { /* located option */ return opt; } } /* not found */ return NULL;}/* register an options header, the header is printed before the option list */voidopt_reg_header(struct opt_odb_t *odb, /* option database */ char *header) /* options header string */{ odb->header = header;}/* register an option note, notes are printed after the list of options */voidopt_reg_note(struct opt_odb_t *odb, /* option database */ char *note_str) /* option note */{ struct opt_note_t *note, *elt, *prev; note = (struct opt_note_t *)calloc(1, sizeof(struct opt_note_t)); if (!note) fatal("out of virtual memory"); /* record note */ note->next = NULL; note->note = note_str; /* add to end of option notes list */ for (prev=NULL, elt=odb->notes; elt != NULL; prev=elt, elt=elt->next) /* nada */; if (prev != NULL) prev->next = note; else /* prev == NULL */ odb->notes = note; note->next = NULL;}#ifdef TESTintf_orphan_fn(int i, int argc, char **argv){ fprintf(stdout, "orphans detected at index %d, arg = `%s'...\n", i, argv[i]); /* done processing */ return FALSE;}#define MAX_VARS 4voidmain(int argc, char **argv){ struct opt_odb_t *odb; int n_int_vars, n_uint_vars, n_float_vars, n_double_vars; int n_enum_vars, n_enum_eval_vars, n_flag_vars, n_string_vars; int int_var, int_vars[MAX_VARS]; unsigned int uint_var, uint_vars[MAX_VARS]; float float_var, float_vars[MAX_VARS]; double double_var, double_vars[MAX_VARS]; int flag_var, flag_vars[MAX_VARS]; char *string_var, *string_vars[MAX_VARS]; enum etest_t { enum_a, enum_b, enum_c, enum_d, enum_NUM }; static char *enum_emap[enum_NUM] = { "enum_a", "enum_b", "enum_c", "enum_d" }; static int enum_eval[enum_NUM] = { enum_d, enum_c, enum_b, enum_a }; int enum_var, enum_vars[MAX_VARS]; int enum_eval_var, enum_eval_vars[MAX_VARS]; /* get an options processor */ odb = opt_new(f_orphan_fn); opt_reg_int(odb, "-opt:int", "This is an integer option.", &int_var, 1, /* print */TRUE, /* default format */NULL); opt_reg_int_list(odb, "-opt:int:list", "This is an integer list option.", int_vars, MAX_VARS, &n_int_vars, 2, /* print */TRUE, /* default format */NULL); opt_reg_uint(odb, "-opt:uint", "This is an unsigned integer option.", &uint_var, 3, /* print */TRUE, /* default format */NULL); opt_reg_uint_list(odb, "-opt:uint:list", "This is an unsigned integer list option.", uint_vars, MAX_VARS, &n_uint_vars, 4, /* print */TRUE, /* default format */NULL); opt_reg_float(odb, "-opt:float", "This is a float option.", &float_var, 5.0, /* print */TRUE, /* default format */NULL); opt_reg_float_list(odb, "-opt:float:list", "This is a float list option.", float_vars, MAX_VARS, &n_float_vars, 6.0, /* print */TRUE, /* default format */NULL); opt_reg_double(odb, "-opt:double", "This is a double option.", &double_var, 7.0, /* print */TRUE, /* default format */NULL); opt_reg_double_list(odb, "-opt:double:list", "This is a double list option.", double_vars, MAX_VARS, &n_double_vars, 8.0, /* print */TRUE, /* default format */NULL); opt_reg_enum(odb, "-opt:enum", "This is an enumeration option.", &enum_var, "enum_a", enum_emap, /* index map */NULL, enum_NUM, /* print */TRUE, /* default format */NULL); opt_reg_enum_list(odb, "-opt:enum:list", "This is a enum list option.", enum_vars, MAX_VARS, &n_enum_vars, "enum_b", enum_emap, /* index map */NULL, enum_NUM, /* print */TRUE, /* default format */NULL); opt_reg_enum(odb, "-opt:enum:eval", "This is an enumeration option w/eval.", &enum_eval_var, "enum_b", enum_emap, enum_eval, enum_NUM, /* print */TRUE, /* default format */NULL); opt_reg_enum_list(odb, "-opt:enum:eval:list", "This is a enum list option w/eval.", enum_eval_vars, MAX_VARS, &n_enum_eval_vars, "enum_a", enum_emap, enum_eval, enum_NUM, /* print */TRUE, /* default format */NULL); opt_reg_flag(odb, "-opt:flag", "This is a boolean flag option.", &flag_var, FALSE, /* print */TRUE, /* default format */NULL); opt_reg_flag_list(odb, "-opt:flag:list", "This is a boolean flag list option.", flag_vars, MAX_VARS, &n_flag_vars, TRUE, /* print */TRUE, /* default format */NULL); opt_reg_string(odb, "-opt:string", "This is a string option.", &string_var, "a:string", /* print */TRUE, /* default format */NULL); opt_reg_string_list(odb, "-opt:string:list", "This is a string list option.", string_vars, MAX_VARS, &n_string_vars, "another:string", /* print */TRUE, /* default format */NULL); /* parse options */ opt_process_options(odb, argc, argv); /* print options */ fprintf(stdout, "## Current Option Values ##\n"); opt_print_options(odb, stdout, /* long */FALSE, /* notes */TRUE); /* all done */ opt_delete(odb); exit(0);}#endif /* TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -