📄 clif.c
字号:
if (posix && arg != argv[i] && arg[-1] != sym) { err_bad_arg (optn, *arg, i); /* good way? */ return -1; } if (++i >= argc || (flags & _CLIF_STRICT_JOIN_ARG) ) { i--; if (!(flags & CLIF_OPTARG)) { err_bad_arg (optn, *arg, i); return -1; } opt_arg = NULL; } else opt_arg = argv[i]; } else if ((arg == argv[i] || arg[-1] == sym) && (flags & CLIF_MAY_JOIN_ARG) ) { opt_arg = ++arg; } else { /* inside a group... */ if (!(flags & CLIF_OPTARG) || (flags & CLIF_MAY_JOIN_ARG) ) { err_bad_arg (optn, *arg, i); return -1; } opt_arg = NULL; } } if (call_function (optn, opt_arg, sym) < 0) { err_bad_res (optn, optn->short_opt[0], opt_arg, i); return -1; } if (optn->flags & CLIF_EXIT) exit (0); } while (!opt_arg && *++arg); } /* for ( ... ) */ if ((parse_flags & CLIF_STRICT_EXCL) && exclusive_cnt != 0) { err_report ("One of these must be specified:\n %s\n", show_excl (option_list, 0)); return -1; } /* Now, after *ALL* options, handle arguments, if any. */ if (num_args < strict_beg + strict_end) { /* Missing some needed arguments. */ if (num_args < strict_beg) argm = argument_list + num_args; else argm = argument_list + ((num_args - strict_beg) + (num_argm - strict_end)); if (num_args == strict_beg + strict_end - 1) err_report ("Specify \"%s\" missing argument.", argm->name); else err_report ("Specify \"%s\" and other missing arguments.", argm->name); return -1; } if (num_args > 0) { _CLIF_index argm_index[MAX_ARGC_NUMBER]; /* assing argm (by index) for each arg... */ for (i = 0, j = 0; i < strict_beg; i++, j++) argm_index[i] = j; for (i = num_args - strict_end, j = num_argm - strict_end; i < num_args; i++, j++ ) argm_index[i] = j; for (i = strict_beg, j = strict_beg; i < num_args - strict_end && j < num_argm - strict_end; i++ ) { argm_index[i] = j; if (!(argument_list[j].flags & CLIF_MORE)) j++; } if (i < num_args - strict_end) { /* there are extra args... */ err_report ("Extra arg `%s' (position %d, argc %d)", argv[arg_n[i]], i + 1, arg_n[i]); return -1; } if (j < num_argm - strict_end && !(argument_list[j].flags & CLIF_MORE) && /* ...i.e, there are some missing optional args... */ (argument_list[j].flags & CLIF_ACC_PREV) ) { if (j == 0) err_report ("Incorrect argument list set: first arg " "cannot be `accompanied with previous'."); else err_report ("Arg \"%s\" must be specified because " "\"%s\" `%s' is used.", argument_list[j].name, argument_list[j - 1].name, argv[arg_n[i - 1]]); return -1; } if (argm_index[--i] == j && /* above is true only after OPTIONAL area scan and when `j' is stopped on CLIF_MORE */ ++j < num_argm - strict_end /* i.e: there is a *last* one (after CLIF_MORE) in the OPTIONAL area */ ) argm_index[i] = j; /* *last* is better than *more* */ /* ...and work now */ for (i = 0; i < num_args; i++) { argm = argument_list + argm_index[i]; if (argm->function && argm->function (argm, argv[arg_n[i]], i) < 0 ) { err_report ("Cannot handle \"%s\" cmdline arg `%s' " "on position %d (argc %d)", argm->name, argv[arg_n[i]], i + 1, arg_n[i]); return -1; } } /* That`s all. */ } return 0;}static void box_output (int start, int left, int width, const char *str, const char *arg_name) { char *p, *endp, *s; int l; char buf[1024]; char spacer[128]; /* assume it is enough */ if (left > sizeof (spacer) - 2) left = sizeof (spacer) - 2; if (width > sizeof (buf) - 1) width = sizeof (buf) - 1; spacer[0] = '\n'; memset (spacer + 1, ' ', left); spacer[left + 1] = '\0'; l = left - start; if (l > 0) { memset (buf, ' ', l); buf[l] = '\0'; fprintf (stderr, buf); } else fprintf (stderr, spacer); endp = buf + width; p = buf; while (*str) { while (*str && p < endp) { if (*str == '%' && arg_name) { if (str[1] == '%') { *p++ = '%'; str += 2; continue; } else if (str[1] == 's') { const char *a = arg_name; while (*a && p < endp) *p++ = *a++; str += 2; continue; } } *p++ = *str++; } *p = '\0'; if (p < endp) break; while (p > buf && *p != ' ' && *p != '\t') p--; if (p <= buf) return; /* foo on you */ *p = '\0'; fprintf (stderr, "%s", buf); fprintf (stderr, spacer); p++; for (s = buf; *p; *s++ = *p++) ; *s = '\0'; p = s; } fprintf (stderr, "%s", buf); return;}#define SHORT_LONG_DLM " "#define OPT_START_DLM " "#define OPT_FIELD_WIDTH 30#define ARG_MARK_STRICT "+ "#define ARG_MARK_GROUP0 " . "#define ARG_MARK_GROUP " ' "#define ARG_MARK_OPT " "#define ARG_FIELD_WIDTH 20#define SCREEN_WIDTH 80void CLIF_print_options (const char *header, const CLIF_option *option_list) { const CLIF_option *optn; char *excl; int excl_cnt = 0; /* Print a header string, if present... */ if (header) fprintf (stderr, "%s\n", header); if (!option_list) return; for (optn = option_list; optn->short_opt || optn->long_opt; optn++) { int len; /* generate and print an option usage */ if (optn->short_opt) { if (optn->long_opt) len = fprintf (stderr, OPT_START_DLM "%s" SHORT_LONG_DLM "%s", show_short (optn), show_long (optn)); else len = fprintf (stderr, OPT_START_DLM "%s", show_short (optn)); } else len = fprintf (stderr, OPT_START_DLM "%s", show_long (optn)); /* print a help string, if present */ if (optn->help_string) box_output (len, OPT_FIELD_WIDTH, SCREEN_WIDTH - OPT_FIELD_WIDTH, optn->help_string, optn->arg_name); fprintf (stderr, "\n"); /* a last one */ } excl = show_excl (option_list, &excl_cnt); if (excl_cnt > 0) { if (excl_cnt == 1) { if ((curr.parse_flags & CLIF_STRICT_EXCL) && curr.option_list == option_list ) fprintf (stderr, "Anyway `%s' must be specified.\n", excl); else /* simple ordinary option, because excl_cnt == 1 ... */; } else fprintf (stderr, "Only one of these may be specified:\n" " %s\n", excl); } return;} void CLIF_print_arguments (const char *header, const CLIF_argument *argument_list) { const CLIF_argument *argm; if (!argument_list) return; /* Print a header string, if present... */ if (header) fprintf (stderr, "%s\n", header); for (argm = argument_list; argm->name; argm++) { int len; if (argm->flags & CLIF_STRICT) len = fprintf (stderr, ARG_MARK_STRICT "%s", argm->name); else if (argm->flags & CLIF_MORE) len = fprintf (stderr, ARG_MARK_OPT "%s ...", argm->name); else if (argm->flags & CLIF_ACC_PREV) len = fprintf (stderr, ARG_MARK_GROUP "%s", argm->name); else if ((argm + 1)->name && ((argm + 1)->flags & CLIF_ACC_PREV)) len = fprintf (stderr, ARG_MARK_GROUP0 "%s", argm->name); else len = fprintf (stderr, ARG_MARK_OPT "%s", argm->name); if (argm->help_string) box_output (len, ARG_FIELD_WIDTH, SCREEN_WIDTH - ARG_FIELD_WIDTH, argm->help_string, argm->name); fprintf (stderr, "\n"); } return;}void CLIF_print_usage (const char *header, const char *progname, const CLIF_option *option_list, const CLIF_argument *argument_list) { if (!progname && curr.argv) progname = curr.argv[0]; if (!header) { if (progname) fprintf (stderr, "Usage: %s", progname); else fprintf (stderr, "Command line options:"); } else { if (progname) fprintf (stderr, "%s\n" OPT_START_DLM "%s", header, progname); else fprintf (stderr, "%s", header); } if (option_list) { const CLIF_option *optn; char m_buf[256], p_buf[256], mp_buf[256]; char *m = m_buf, *p = p_buf, *mp = mp_buf; char *end_m = m_buf + sizeof (m_buf) - 1; char *end_p = p_buf + sizeof (p_buf) - 1; char *end_mp = mp_buf + sizeof (mp_buf) - 1; char *excl; int excl_cnt = 0; /* first, show exclusive option list, if any... */ excl = show_excl (option_list, &excl_cnt); if (excl_cnt > 0) { if ((curr.parse_flags & CLIF_STRICT_EXCL) && curr.option_list == option_list ) { if (excl_cnt == 1) fprintf (stderr, " %s", excl); else fprintf (stderr, " { %s }", excl); } else fprintf (stderr, " [ %s ]", excl); } /* second, find short options without arguments... */ for (optn = option_list; optn->short_opt || optn->long_opt; optn++ ) { /* We don`t exclude CLIF_EXTRA hear: simple one char don`t eat a lot of space... */ if (!optn->short_opt || optn->arg_name || (optn->flags & CLIF_EXCL) ) continue; if (optn->function_plus) { if (optn->function) { if (mp < end_mp) *mp++ = optn->short_opt[0]; } else { if (p < end_p) *p++ = optn->short_opt[0]; } } else { if (m < end_m) *m++ = optn->short_opt[0]; } } if (m > (char *) m_buf) { *m = '\0'; fprintf (stderr, " [ -%s ]", m_buf); } if (p > (char *) p_buf) { *p = '\0'; fprintf (stderr, " [ +%s ]", p_buf); } if (mp > (char *) mp_buf) { *mp = '\0'; fprintf (stderr, " [ " SHORT_PLUS_MINUS "%s ]", mp_buf); } /* third, print all another... */ for (optn = option_list; optn->short_opt || optn->long_opt; optn++ ) { if (optn->flags & CLIF_EXTRA) continue; if (optn->flags & CLIF_EXCL) continue; /* already handled */ if (optn->short_opt) { if (optn->arg_name) fprintf (stderr, " [ %s ]", show_short (optn)); else /* already handled */; } else fprintf (stderr, " [ %s ]", show_long (optn)); } } if (argument_list) { const CLIF_argument *argm; int deep = 0; for (argm = argument_list; argm->name; argm++) { if (argm->flags & CLIF_STRICT) { if (deep > 0) { fputc (' ', stderr); while (deep--) fputc (']', stderr); deep = 0; } fprintf (stderr, " %s", argm->name); } else { if (argm->flags & CLIF_MORE) fprintf (stderr, " [ %s ...", argm->name); else if (argm->flags & CLIF_ACC_PREV) { fprintf (stderr, " %s", argm->name); --deep; /* ugly, but easy */ } else fprintf (stderr, " [ %s", argm->name); deep++; } } if (deep > 0) { fputc (' ', stderr); while (deep--) fputc (']', stderr); } } fprintf (stderr, "\n");}int CLIF_current_help (void) { if (!curr.argc) return -1; /* i.e., not inited... */ CLIF_print_usage ("Usage:", curr.argv[0], curr.option_list, curr.argument_list); if (curr.option_list) CLIF_print_options ("Options:", curr.option_list); if (curr.argument_list) CLIF_print_arguments ("\nArguments:", curr.argument_list); return 0;}/* Common useful option handlers. */int CLIF_version_handler (CLIF_option *optn, char *arg) { if (!optn->data) return -1; fprintf (stderr, "%s\n", ((char *) optn->data)); return 0; /* be happy */} int CLIF_set_flag (CLIF_option *optn, char *arg) { if (!optn->data) return -1; *((int *) optn->data) = 1; return 0;}int CLIF_unset_flag (CLIF_option *optn, char *arg) { if (!optn->data) return -1; *((int *) optn->data) = 0; return 0;}static int set_string (char **data, char *arg) { if (!data) return -1; *data = arg; return 0;}int CLIF_set_string (CLIF_option *optn, char *arg) { return set_string (optn->data, arg);}int CLIF_arg_string (CLIF_argument *argm, char *arg, int index) { return set_string (argm->data, arg);}static int set_int (int *data, char *arg) { char *q; if (!data) return -1; *data = (int) strtol (arg, &q, 0); return (q == arg) ? -1 : 0;}static int set_uint (unsigned int *data, char *arg) { char *q; if (!data) return -1; *data = (unsigned int) strtoul (arg, &q, 0); return (q == arg) ? -1 : 0;}static int set_double (double *data, char *arg) { char *q; if (!data) return -1; *data = strtod (arg, &q); return (q == arg) ? -1 : 0;}int CLIF_set_int (CLIF_option *optn, char *arg) { return set_int (optn->data, arg);}int CLIF_set_uint (CLIF_option *optn, char *arg) { return set_uint (optn->data, arg);}int CLIF_set_double (CLIF_option *optn, char *arg) { return set_double (optn->data, arg);}int CLIF_arg_int (CLIF_argument *argm, char *arg, int index) { return set_int (argm->data, arg);}int CLIF_arg_uint (CLIF_argument *argm, char *arg, int index) { return set_uint (argm->data, arg);}int CLIF_arg_double (CLIF_argument *argm, char *arg, int index) { return set_double (argm->data, arg);}int CLIF_call_func (CLIF_option *optn, char *arg) { if (!optn->data) return -1; if (optn->arg_name) { int (*func) (char *) = optn->data; return func (arg); } else { int (*func) (void) = optn->data; return func (); }}int CLIF_arg_func (CLIF_argument *argm, char *arg, int index) { int (*func) (char *, int); if (!argm->data) return -1; func = (int (*) (char *, int)) argm->data; return func (arg, index);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -