if (unset && p->opt) return opterror(opt, "takes no value", flags); if (unset && (opt->flags & PARSE_OPT_NONEG)) return opterror(opt, "isn't available", flags); if (opt->flags & PARSE_OPT_DISABLED) return opterror(opt, "is not usable", flags);
if (opt->flags & PARSE_OPT_EXCLUSIVE) { if (p->excl_opt && p->excl_opt != opt) { char msg[128];
if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
p->excl_opt->long_name == NULL) {
snprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
p->excl_opt->short_name);
} else {
snprintf(msg, sizeof(msg), "cannot be used with %s",
p->excl_opt->long_name);
}
opterror(opt, msg, flags); return -3;
}
p->excl_opt = opt;
} if (!(flags & OPT_SHORT) && p->opt) { switch (opt->type) { case OPTION_CALLBACK: if (!(opt->flags & PARSE_OPT_NOARG)) break; /* FALLTHROUGH */ case OPTION_BOOLEAN: case OPTION_INCR: case OPTION_BIT: case OPTION_SET_UINT: case OPTION_SET_PTR: return opterror(opt, "takes no value", flags); case OPTION_END: case OPTION_ARGUMENT: case OPTION_GROUP: case OPTION_STRING: case OPTION_INTEGER: case OPTION_UINTEGER: case OPTION_LONG: case OPTION_ULONG: case OPTION_U64: default: break;
}
}
err = snprintf(reason, sizeof(reason),
opt->flags & PARSE_OPT_CANSKIP ? "is being ignored because %s " : "is not available because %s",
opt->build_opt);
reason[sizeof(reason) - 1] = '\0';
if (err < 0)
strncpy(reason, opt->flags & PARSE_OPT_CANSKIP ? "is being ignored" : "is not available", sizeof(reason));
if (!(opt->flags & PARSE_OPT_CANSKIP)) return opterror(opt, reason, flags);
err = 0; if (unset)
noarg = true; if (opt->flags & PARSE_OPT_NOARG)
noarg = true; if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
noarg = true;
switch (opt->type) { case OPTION_BOOLEAN: case OPTION_INCR: case OPTION_BIT: case OPTION_SET_UINT: case OPTION_SET_PTR: case OPTION_END: case OPTION_ARGUMENT: case OPTION_GROUP:
noarg = true; break; case OPTION_CALLBACK: case OPTION_STRING: case OPTION_INTEGER: case OPTION_UINTEGER: case OPTION_LONG: case OPTION_ULONG: case OPTION_U64: default: break;
}
if (!noarg)
err = get_arg(p, opt, flags, NULL); if (err) return err;
optwarning(opt, reason, flags); return 0;
}
switch (opt->type) { case OPTION_BIT: if (unset)
*(int *)opt->value &= ~opt->defval; else
*(int *)opt->value |= opt->defval; return 0;
case OPTION_BOOLEAN:
*(bool *)opt->value = unset ? false : true; if (opt->set)
*(bool *)opt->set = true; return 0;
retry: for (; options->type != OPTION_END; options++) { constchar *rest; int flags = 0;
if (!options->long_name) continue;
rest = skip_prefix(arg, options->long_name); if (options->type == OPTION_ARGUMENT) { if (!rest) continue; if (*rest == '=') return opterror(options, "takes no value", flags); if (*rest) continue;
p->out[p->cpidx++] = arg - 2; return 0;
} if (!rest) { if (strstarts(options->long_name, "no-")) { /* * The long name itself starts with "no-", so * accept the option without "no-" so that users * do not have to enter "no-no-" to get the * negation.
*/
rest = skip_prefix(arg, options->long_name + 3); if (rest) {
flags |= OPT_UNSET; goto match;
} /* Abbreviated case */ if (strstarts(options->long_name + 3, arg)) {
flags |= OPT_UNSET; goto is_abbreviated;
}
} /* abbreviated? */ if (!strncmp(options->long_name, arg, arg_end - arg)) {
is_abbreviated: if (abbrev_option) { /* * If this is abbreviated, it is * ambiguous. So when there is no * exact match later, we need to * error out.
*/
ambiguous_option = abbrev_option;
ambiguous_flags = abbrev_flags;
} if (!(flags & OPT_UNSET) && *arg_end)
p->opt = arg_end + 1;
abbrev_option = options;
abbrev_flags = flags; continue;
} /* negated and abbreviated very much? */ if (strstarts("no-", arg)) {
flags |= OPT_UNSET; goto is_abbreviated;
} /* negated? */ if (strncmp(arg, "no-", 3)) continue;
flags |= OPT_UNSET;
rest = skip_prefix(arg + 3, options->long_name); /* abbreviated and negated? */ if (!rest && strstarts(options->long_name, arg + 3)) goto is_abbreviated; if (!rest) continue;
}
match: if (*rest) { if (*rest != '=') continue;
p->opt = rest + 1;
} return get_value(p, options, flags);
}
if (ambiguous_option) {
fprintf(stderr, " Error: Ambiguous option: %s (could be --%s%s or --%s%s)\n",
arg,
(ambiguous_flags & OPT_UNSET) ? "no-" : "",
ambiguous_option->long_name,
(abbrev_flags & OPT_UNSET) ? "no-" : "",
abbrev_option->long_name); return -1;
} if (abbrev_option) return get_value(p, abbrev_option, abbrev_flags);
if (options->parent) {
options = options->parent; goto retry;
}
if (strstarts(arg, "no-")) {
fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg); exit(129);
}
for (; options->type != OPTION_END; options++) { if (!options->long_name) continue; if (strstarts(options->long_name, arg)) {
fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg); exit(129);
}
}
}
/* flatten the options that have parents */ for (p = opts; p != NULL; p = o->parent) { for (o = p; o->type != OPTION_END; o++)
++nr_opts;
/* * the length is given by the number of options plus a null * terminator for the last loop iteration.
*/
len = sizeof(*o) * (nr_opts + !o->parent);
group = realloc(ordered, len); if (!group) goto out;
ordered = group;
memcpy(&ordered[nr_parent], p, sizeof(*o) * (nr_opts - nr_parent));
nr_parent = nr_opts;
} /* copy the last OPTION_END */
memcpy(&ordered[nr_opts], o, sizeof(*o));
/* sort each option group individually */ for (opt = group = ordered; opt->type != OPTION_END; opt++) { if (opt->type == OPTION_GROUP) {
qsort(group, nr_group, sizeof(*opt), option__cmp);
group = opt + 1;
nr_group = 0; continue;
}
nr_group++;
}
qsort(group, nr_group, sizeof(*opt), option__cmp);
out: return ordered;
}
staticbool option__in_argv(conststruct option *opt, conststruct parse_opt_ctx_t *ctx)
{ int i;
for (i = 1; i < ctx->argc; ++i) { constchar *arg = ctx->argv[i];
if (arg[0] != '-') { if (arg[1] == '\0') { if (arg[0] == opt->short_name) returntrue; continue;
}
if (opt->long_name && strcmp(opt->long_name, arg) == 0) returntrue;
if (opt->help && strcasestr(opt->help, arg) != NULL) returntrue;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.