Page 2 of 6 FirstFirst 123456 LastLast
Results 26 to 50 of 150
  1. #26
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    free (hol->entries);
    free (hol->short_options);

    hol->entries = entries;
    hol->num_entries = num_entries;
    hol->short_options = short_options;
    }
    }

    hol_free (more);
    }

    /* Inserts enough spaces to make sure STREAM is at column COL. */
    static void
    indent_to (argp_fmtstream_t stream, unsigned col)
    {
    int needed = col - __argp_fmtstream_point (stream);
    while (needed-- > 0)
    __argp_fmtstream_putc (stream, ' ');
    }

    /* Output to STREAM either a space, or a newline if there isn't room for at
    least ENSURE characters before the right margin. */
    static void
    space (argp_fmtstream_t stream, size_t ensure)
    {
    if (__argp_fmtstream_point (stream) + ensure
    >= __argp_fmtstream_rmargin (stream))
    __argp_fmtstream_putc (stream, '\n');
    else
    __argp_fmtstream_putc (stream, ' ');
    }

    /* If the option REAL has an argument, we print it in using the printf
    format REQ_FMT or OPT_FMT depending on whether it's a required or
    optional argument. */
    static void
    arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
    const char *domain, argp_fmtstream_t stream)
    {
    if (real->arg)
    {
    if (real->flags & OPTION_ARG_OPTIONAL)
    __argp_fmtstream_printf (stream, opt_fmt,
    dgettext (domain, real->arg));
    else
    __argp_fmtstream_printf (stream, req_fmt,
    dgettext (domain, real->arg));
    }
    }

    /* Helper functions for hol_entry_help. */

    /* State used during the execution of hol_help. */
    struct hol_help_state
    {
    /* PREV_ENTRY should contain the previous entry printed, or 0. */
    struct hol_entry *prev_entry;

    /* If an entry is in a different group from the previous one, and SEP_GROUPS
    is true, then a blank line will be printed before any output. */
    int sep_groups;

    /* True if a duplicate option argument was suppressed (only ever set if
    UPARAMS.dup_args is false). */
    int suppressed_dup_arg;
    };

    /* Some state used while printing a help entry (used to communicate with
    helper functions). See the doc for hol_entry_help for more info, as most
    of the fields are copied from its arguments. */
    struct pentry_state
    {
    const struct hol_entry *entry;
    argp_fmtstream_t stream;
    struct hol_help_state *hhstate;

    /* True if nothing's been printed so far. */
    int first;

    /* If non-zero, the state that was used to print this help. */
    const struct argp_state *state;
    };

    /* If a user doc filter should be applied to DOC, do so. */
    static const char *
    filter_doc (const char *doc, int key, const struct argp *argp,
    const struct argp_state *state)
    {
    if (argp && argp->help_filter)
    /* We must apply a user filter to this output. */
    {
    void *input = __argp_input (argp, state);
    return (*argp->help_filter) (key, doc, input);
    }
    else
    /* No filter. */
    return doc;
    }

    /* Prints STR as a header line, with the margin lines set appropiately, and
    notes the fact that groups should be separated with a blank line. ARGP is
    the argp that should dictate any user doc filtering to take place. Note
    that the previous wrap margin isn't restored, but the left margin is reset
    to 0. */
    static void
    print_header (const char *str, const struct argp *argp,
    struct pentry_state *pest)
    {
    const char *tstr = dgettext (argp->argp_domain, str);
    const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);

    if (fstr)
    {
    if (*fstr)
    {
    if (pest->hhstate->prev_entry)
    /* Precede with a blank line. */
    __argp_fmtstream_putc (pest->stream, '\n');
    indent_to (pest->stream, uparams.header_col);
    __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
    __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
    __argp_fmtstream_puts (pest->stream, fstr);
    __argp_fmtstream_set_lmargin (pest->stream, 0);
    __argp_fmtstream_putc (pest->stream, '\n');
    }

    pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
    }

    if (fstr != tstr)
    free ((char *) fstr);
    }

    /* Inserts a comma if this isn't the first item on the line, and then makes
    sure we're at least to column COL. If this *is* the first item on a line,
    prints any pending whitespace/headers that should precede this line. Also
    clears FIRST. */
    static void
    comma (unsigned col, struct pentry_state *pest)
    {
    if (pest->first)
    {
    const struct hol_entry *pe = pest->hhstate->prev_entry;
    const struct hol_cluster *cl = pest->entry->cluster;

    if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
    __argp_fmtstream_putc (pest->stream, '\n');

    if (cl && cl->header && *cl->header
    && (!pe
    || (pe->cluster != cl
    && !hol_cluster_is_child (pe->cluster, cl))))
    /* If we're changing clusters, then this must be the start of the
    ENTRY's cluster unless that is an ancestor of the previous one
    (in which case we had just popped into a sub-cluster for a bit).
    If so, then print the cluster's header line. */
    {
    int old_wm = __argp_fmtstream_wmargin (pest->stream);
    print_header (cl->header, cl->argp, pest);
    __argp_fmtstream_set_wmargin (pest->stream, old_wm);
    }

    pest->first = 0;
    }
    else
    __argp_fmtstream_puts (pest->stream, ", ");

    indent_to (pest->stream, col);
    }

    /* Print help for ENTRY to STREAM. */
    static void
    hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
    argp_fmtstream_t stream, struct hol_help_state *hhstate)
    {
    unsigned num;
    const struct argp_option *real = entry->opt, *opt;
    char *so = entry->short_options;
    int have_long_opt = 0; /* We have any long options. */
    /* Saved margins. */
    int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
    int old_wm = __argp_fmtstream_wmargin (stream);
    /* PEST is a state block holding some of our variables that we'd like to
    share with helper functions. */
    struct pentry_state pest = { entry, stream, hhstate, 1, state };

    if (! odoc (real))
    for (opt = real, num = entry->num; num > 0; opt++, num--)
    if (opt->name && ovisible (opt))
    {
    have_long_opt = 1;
    break;
    }

    /* First emit short options. */
    __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
    for (opt = real, num = entry->num; num > 0; opt++, num--)
    if (oshort (opt) && opt->key == *so)
    /* OPT has a valid (non shadowed) short option. */
    {
    if (ovisible (opt))
    {
    comma (uparams.short_opt_col, &pest);
    __argp_fmtstream_putc (stream, '-');
    __argp_fmtstream_putc (stream, *so);
    if (!have_long_opt || uparams.dup_args)
    arg (real, " %s", "[%s]",
    state == NULL ? NULL : state->root_argp->argp_domain,
    stream);
    else if (real->arg)
    hhstate->suppressed_dup_arg = 1;
    }
    so++;
    }

    /* Now, long options. */
    if (odoc (real))
    /* A `do entation' option. */
    {
    __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
    for (opt = real, num = entry->num; num > 0; opt++, num--)
    if (opt->name && ovisible (opt))
    {
    comma (uparams.doc_opt_col, &pest);
    /* Calling gettext here isn't quite right, since sorting will
    have been done on the original; but do entation options
    should be pretty rare anyway... */
    __argp_fmtstream_puts (stream,
    dgettext (state == NULL ? NULL
    : state->root_argp->argp_domain,
    opt->name));
    }
    }
    else
    /* A real long option. */
    {
    __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
    for (opt = real, num = entry->num; num > 0; opt++, num--)
    if (opt->name && ovisible (opt))
    {
    comma (uparams.long_opt_col, &pest);
    __argp_fmtstream_printf (stream, "--%s", opt->name);
    arg (real, "=%s", "[=%s]",
    state == NULL ? NULL : state->root_argp->argp_domain, stream);
    }
    }

    /* Next, do entation strings. */
    __argp_fmtstream_set_lmargin (stream, 0);

    if (pest.first)
    {
    /* Didn't print any switches, what's up? */
    if (!oshort (real) && !real->name)
    /* This is a group header, print it nicely. */
    print_header (real->doc, entry->argp, &pest);
    else
    /* Just a totally shadowed option or null header; print nothing. */
    goto cleanup; /* Just return, after cleaning up. */
    }
    else
    {
    const char *tstr = real->doc ? dgettext (state == NULL ? NULL
    : state->root_argp->argp_domain,
    real->doc) : 0;
    const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
    if (fstr && *fstr)
    {
    unsigned int col = __argp_fmtstream_point (stream);

    __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
    __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);

    if (col > (unsigned int) (uparams.opt_doc_col + 3))
    __argp_fmtstream_putc (stream, '\n');
    else if (col >= (unsigned int) uparams.opt_doc_col)
    __argp_fmtstream_puts (stream, " ");
    else
    indent_to (stream, uparams.opt_doc_col);

    __argp_fmtstream_puts (stream, fstr);
    }
    if (fstr && fstr != tstr)
    free ((char *) fstr);

    /* Reset the left margin. */
    __argp_fmtstream_set_lmargin (stream, 0);
    __argp_fmtstream_putc (stream, '\n');
    }

    hhstate->prev_entry = entry;

    cleanup:
    __argp_fmtstream_set_lmargin (stream, old_lm);
    __argp_fmtstream_set_wmargin (stream, old_wm);
    }

    /* Output a long help message about the options in HOL to STREAM. */
    static void
    hol_help (struct hol *hol, const struct argp_state *state,
    argp_fmtstream_t stream)
    {
    unsigned num;
    struct hol_entry *entry;
    struct hol_help_state hhstate = { 0, 0, 0 };

    for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
    hol_entry_help (entry, state, stream, &hhstate);

    if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
    {
    const char *tstr = dgettext (state == NULL ? NULL
    : state->root_argp->argp_domain, "\
    Mandatory or optional arguments to long options are also mandatory or \
    optional for any corresponding short options.");
    const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
    state ? state->root_argp : 0, state);
    if (fstr && *fstr)
    {
    __argp_fmtstream_putc (stream, '\n');
    __argp_fmtstream_puts (stream, fstr);
    __argp_fmtstream_putc (stream, '\n');
    }
    if (fstr && fstr != tstr)
    free ((char *) fstr);
    }
    }

    /* Helper functions for hol_usage. */

    /* If OPT is a short option without an arg, append its key to the string
    pointer pointer to by COOKIE, and advance the pointer. */
    static int
    add_argless_short_opt (const struct argp_option *opt,
    const struct argp_option *real,
    const char *domain, void *cookie)
    {
    char **snao_end = cookie;
    if (!(opt->arg || real->arg)
    && !((opt->flags | real->flags) & OPTION_NO_USAGE))
    *(*snao_end)++ = opt->key;
    return 0;
    }

    /* If OPT is a short option with an arg, output a usage entry for it to the
    stream pointed at by COOKIE. */
    static int
    usage_argful_short_opt (const struct argp_option *opt,
    const struct argp_option *real,
    const char *domain, void *cookie)
    {
    argp_fmtstream_t stream = cookie;
    const char *arg = opt->arg;
    int flags = opt->flags | real->flags;

    if (! arg)
    arg = real->arg;

    if (arg && !(flags & OPTION_NO_USAGE))
    {
    arg = dgettext (domain, arg);

    if (flags & OPTION_ARG_OPTIONAL)
    __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
    else
    {
    /* Manually do line wrapping so that it (probably) won't
    get wrapped at the embedded space. */
    space (stream, 6 + strlen (arg));
    __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
    }
    }

    return 0;
    }

    /* Output a usage entry for the long option opt to the stream pointed at by
    COOKIE. */
    static int
    usage_long_opt (const struct argp_option *opt,
    const struct argp_option *real,
    const char *domain, void *cookie)
    {
    argp_fmtstream_t stream = cookie;
    const char *arg = opt->arg;
    int flags = opt->flags | real->flags;

    if (! arg)
    arg = real->arg;

    if (! (flags & OPTION_NO_USAGE))
    {
    if (arg)
    {
    arg = dgettext (domain, arg);
    if (flags & OPTION_ARG_OPTIONAL)
    __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
    else
    __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
    }
    else
    __argp_fmtstream_printf (stream, " [--%s]", opt->name);
    }

    return 0;
    }

    /* Print a short usage description for the arguments in HOL to STREAM. */
    static void
    hol_usage (struct hol *hol, argp_fmtstream_t stream)
    {
    if (hol->num_entries > 0)
    {
    unsigned nentries;
    struct hol_entry *entry;
    char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
    char *snao_end = short_no_arg_opts;

    /* First we put a list of short options without arguments. */
    for (entry = hol->entries, nentries = hol->num_entries
    ; nentries > 0
    ; entry++, nentries--)
    hol_entry_short_iterate (entry, add_argless_short_opt,
    entry->argp->argp_domain, &snao_end);
    if (snao_end > short_no_arg_opts)
    {
    *snao_end++ = 0;
    __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
    }

    /* Now a list of short options *with* arguments. */
    for (entry = hol->entries, nentries = hol->num_entries
    ; nentries > 0
    ; entry++, nentries--)
    hol_entry_short_iterate (entry, usage_argful_short_opt,
    entry->argp->argp_domain, stream);

    /* Finally, a list of long options (whew!). */
    for (entry = hol->entries, nentries = hol->num_entries
    ; nentries > 0
    ; entry++, nentries--)
    hol_entry_long_iterate (entry, usage_long_opt,
    entry->argp->argp_domain, stream);
    }
    }

  2. #27
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Make a HOL containing all levels of options in ARGP. CLUSTER is the
    cluster in which ARGP's entries should be clustered, or 0. */
    static struct hol *
    argp_hol (const struct argp *argp, struct hol_cluster *cluster)
    {
    const struct argp_child *child = argp->children;
    struct hol *hol = make_hol (argp, cluster);
    if (child)
    while (child->argp)
    {
    struct hol_cluster *child_cluster =
    ((child->group || child->header)
    /* Put CHILD->argp within its own cluster. */
    ? hol_add_cluster (hol, child->group, child->header,
    child - argp->children, cluster, argp)
    /* Just merge it into the parent's cluster. */
    : cluster);
    hol_append (hol, argp_hol (child->argp, child_cluster)) ;
    child++;
    }
    return hol;
    }


    /* Calculate how many different levels with alternative args strings exist in
    ARGP. */
    static size_t
    argp_args_levels (const struct argp *argp)
    {
    size_t levels = 0;
    const struct argp_child *child = argp->children;

    if (argp->args_doc && strchr (argp->args_doc, '\n'))
    levels++;

    if (child)
    while (child->argp)
    levels += argp_args_levels ((child++)->argp);

    return levels;
    }

    /* Print all the non-option args do ented in ARGP to STREAM. Any output is
    preceded by a space. LEVELS is a pointer to a byte vector the length
    returned by argp_args_levels; it should be initialized to zero, and
    updated by this routine for the next call if ADVANCE is true. True is
    returned as long as there are more patterns to output. */
    static int
    argp_args_usage (const struct argp *argp, const struct argp_state *state,
    char **levels, int advance, argp_fmtstream_t stream)
    {
    char *our_level = *levels;
    int multiple = 0;
    const struct argp_child *child = argp->children;
    const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
    const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);

    if (fdoc)
    {
    const char *cp = fdoc;
    nl = __strchrnul (cp, '\n');
    if (*nl != '\0')
    /* This is a `multi-level' args doc; advance to the correct position
    as determined by our state in LEVELS, and update LEVELS. */
    {
    int i;
    multiple = 1;
    for (i = 0; i < *our_level; i++)
    cp = nl + 1, nl = __strchrnul (cp, '\n');
    (*levels)++;
    }

    /* Manually do line wrapping so that it (probably) won't get wrapped at
    any embedded spaces. */
    space (stream, 1 + nl - cp);

    __argp_fmtstream_write (stream, cp, nl - cp);
    }
    if (fdoc && fdoc != tdoc)
    free ((char *)fdoc); /* Free user's modified doc string. */

    if (child)
    while (child->argp)
    advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);

    if (advance && multiple)
    {
    /* Need to increment our level. */
    if (*nl)
    /* There's more we can do here. */
    {
    (*our_level)++;
    advance = 0; /* Our parent shouldn't advance also. */
    }
    else if (*our_level > 0)
    /* We had multiple levels, but used them up; reset to zero. */
    *our_level = 0;
    }

    return !advance;
    }

    /* Print the do entation for ARGP to STREAM; if POST is false, then
    everything preceeding a `\v' character in the do entation strings (or
    the whole string, for those with none) is printed, otherwise, everything
    following the `\v' character (nothing for strings without). Each separate
    bit of do entation is separated a blank line, and if PRE_BLANK is true,
    then the first is as well. If FIRST_ONLY is true, only the first
    occurrence is output. Returns true if anything was output. */
    static int
    argp_doc (const struct argp *argp, const struct argp_state *state,
    int post, int pre_blank, int first_only,
    argp_fmtstream_t stream)
    {
    const char *text;
    const char *inp_text;
    void *input = 0;
    int anything = 0;
    size_t inp_text_limit = 0;
    const char *doc = dgettext (argp->argp_domain, argp->doc);
    const struct argp_child *child = argp->children;

    if (doc)
    {
    char *vt = strchr (doc, '\v');
    inp_text = post ? (vt ? vt + 1 : 0) : doc;
    inp_text_limit = (!post && vt) ? (vt - doc) : 0;
    }
    else
    inp_text = 0;

    if (argp->help_filter)
    /* We have to filter the doc strings. */
    {
    if (inp_text_limit)
    /* Copy INP_TEXT so that it's nul-terminated. */
    inp_text = __strndup (inp_text, inp_text_limit);
    input = __argp_input (argp, state);
    text =
    (*argp->help_filter) (post
    ? ARGP_KEY_HELP_POST_DOC
    : ARGP_KEY_HELP_PRE_DOC,
    inp_text, input);
    }
    else
    text = (const char *) inp_text;

    if (text)
    {
    if (pre_blank)
    __argp_fmtstream_putc (stream, '\n');

    if (text == inp_text && inp_text_limit)
    __argp_fmtstream_write (stream, inp_text, inp_text_limit);
    else
    __argp_fmtstream_puts (stream, text);

    if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
    __argp_fmtstream_putc (stream, '\n');

    anything = 1;
    }

    if (text && text != inp_text)
    free ((char *) text); /* Free TEXT returned from the help filter. */
    if (inp_text && inp_text_limit && argp->help_filter)
    free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */

    if (post && argp->help_filter)
    /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
    {
    text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
    if (text)
    {
    if (anything || pre_blank)
    __argp_fmtstream_putc (stream, '\n');
    __argp_fmtstream_puts (stream, text);
    free ((char *) text);
    if (__argp_fmtstream_point (stream)
    > __argp_fmtstream_lmargin (stream))
    __argp_fmtstream_putc (stream, '\n');
    anything = 1;
    }
    }

    if (child)
    while (child->argp && !(first_only && anything))
    anything |=
    argp_doc ((child++)->argp, state,
    post, anything || pre_blank, first_only,
    stream);

    return anything;
    }

    /* Output a usage message for ARGP to STREAM. If called from
    argp_state_help, STATE is the relevent parsing state. FLAGS are from the
    set ARGP_HELP_*. NAME is what to use wherever a `program name' is
    needed. */
    static void
    _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
    unsigned flags, char *name)
    {
    int anything = 0; /* Whether we've output anything. */
    struct hol *hol = 0;
    argp_fmtstream_t fs;

    if (! stream)
    return;

    #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
    __flockfile (stream);
    #endif

    fill_in_uparams (state);

    fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
    if (! fs)
    {
    #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
    __funlockfile (stream);
    #endif
    return;
    }

    if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
    {
    hol = argp_hol (argp, 0);

    /* If present, these options always come last. */
    hol_set_group (hol, "help", -1);
    hol_set_group (hol, "version", -1);

    hol_sort (hol);
    }

    if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
    /* Print a short `Usage:' message. */
    {
    int first_pattern = 1, more_patterns;
    size_t num_pattern_levels = argp_args_levels (argp);
    char *pattern_levels = alloca (num_pattern_levels);

    memset (pattern_levels, 0, num_pattern_levels);

    do
    {
    int old_lm;
    int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
    char *levels = pattern_levels;

    if (first_pattern)
    __argp_fmtstream_printf (fs, "%s %s",
    dgettext (argp->argp_domain, "Usage:"),
    name);
    else
    __argp_fmtstream_printf (fs, "%s %s",
    dgettext (argp->argp_domain, " or: "),
    name);

    /* We set the lmargin as well as the wmargin, because hol_usage
    manually wraps options with newline to avoid annoying breaks. */
    old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);

    if (flags & ARGP_HELP_SHORT_USAGE)
    /* Just show where the options go. */
    {
    if (hol->num_entries > 0)
    __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
    " [OPTION...]"));
    }
    else
    /* Actually print the options. */
    {
    hol_usage (hol, fs);
    flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */
    }

    more_patterns = argp_args_usage (argp, state, &levels, 1, fs);

    __argp_fmtstream_set_wmargin (fs, old_wm);
    __argp_fmtstream_set_lmargin (fs, old_lm);

    __argp_fmtstream_putc (fs, '\n');
    anything = 1;

    first_pattern = 0;
    }
    while (more_patterns);
    }

    if (flags & ARGP_HELP_PRE_DOC)
    anything |= argp_doc (argp, state, 0, 0, 1, fs);

    if (flags & ARGP_HELP_SEE)
    {
    __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
    Try `%s --help' or `%s --usage' for more information.\n"),
    name, name);
    anything = 1;
    }

    if (flags & ARGP_HELP_LONG)
    /* Print a long, detailed help message. */
    {
    /* Print info about all the options. */
    if (hol->num_entries > 0)
    {
    if (anything)
    __argp_fmtstream_putc (fs, '\n');
    hol_help (hol, state, fs);
    anything = 1;
    }
    }

    if (flags & ARGP_HELP_POST_DOC)
    /* Print any do entation strings at the end. */
    anything |= argp_doc (argp, state, 1, anything, 0, fs);

    if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
    {
    if (anything)
    __argp_fmtstream_putc (fs, '\n');
    __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
    "Report bugs to %s.\n"),
    argp_program_bug_address);
    anything = 1;
    }

    #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
    __funlockfile (stream);
    #endif

    if (hol)
    hol_free (hol);

    __argp_fmtstream_free (fs);
    }

    /* Output a usage message for ARGP to STREAM. FLAGS are from the set
    ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
    void __argp_help (const struct argp *argp, FILE *stream,
    unsigned flags, char *name)
    {
    _help (argp, 0, stream, flags, name);
    }
    #ifdef weak_alias
    weak_alias (__argp_help, argp_help)
    #endif

    #ifndef _LIBC
    char *__argp_basename (char *name)
    {
    char *short_name = strrchr (name, '/');
    return short_name ? short_name + 1 : name;
    }

    char *
    __argp_short_program_name (void)
    {
    # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
    return program_invocation_short_name;
    # elif HAVE_DECL_PROGRAM_INVOCATION_NAME
    return __argp_basename (program_invocation_name);
    # else
    /* FIXME: What now? Miles suggests that it is better to use NULL,
    but currently the value is passed on directly to fputs_unlocked,
    so that requires more changes. */
    # if __GNUC__
    # warning No reasonable value to return
    # endif /* __GNUC__ */
    return "";
    # endif
    }
    #endif

    /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
    from the set ARGP_HELP_*. */
    void
    __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
    {
    if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
    {
    if (state && (state->flags & ARGP_LONG_ONLY))
    flags |= ARGP_HELP_LONG_ONLY;

    _help (state ? state->root_argp : 0, state, stream, flags,
    state ? state->name : __argp_short_program_name ());

    if (!state || ! (state->flags & ARGP_NO_EXIT))
    {
    if (flags & ARGP_HELP_EXIT_ERR)
    exit (argp_err_exit_status);
    if (flags & ARGP_HELP_EXIT_OK)
    exit (0);
    }
    }
    }
    #ifdef weak_alias
    weak_alias (__argp_state_help, argp_state_help)
    #endif

    /* If appropriate, print the printf string FMT and following args, preceded
    by the program name and `:', to stderr, and followed by a `Try ... --help'
    message, then exit (1). */
    void
    __argp_error (const struct argp_state *state, const char *fmt, ...)
    {
    if (!state || !(state->flags & ARGP_NO_ERRS))
    {
    FILE *stream = state ? state->err_stream : stderr;

    if (stream)
    {
    va_list ap;

    #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
    __flockfile (stream);
    #endif

    va_start (ap, fmt);

    #ifdef _LIBC
    char *buf;

    if (_IO_vasprintf (&buf, fmt, ap) < 0)
    buf = NULL;

    __fxprintf (stream, "%s: %s\n",
    state ? state->name : __argp_short_program_name (), buf);

    free (buf);
    #else
    fputs_unlocked (state ? state->name : __argp_short_program_name (),
    stream);
    putc_unlocked (':', stream);
    putc_unlocked (' ', stream);

    vfprintf (stream, fmt, ap);

    putc_unlocked ('\n', stream);
    #endif

    __argp_state_help (state, stream, ARGP_HELP_STD_ERR);

    va_end (ap);

  3. #28
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
    __funlockfile (stream);
    #endif
    }
    }
    }
    #ifdef weak_alias
    weak_alias (__argp_error, argp_error)
    #endif

    /* Similar to the standard gnu error-reporting function error(), but will
    respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
    to STATE->err_stream. This is useful for argument parsing code that is
    shared between program startup (when exiting is desired) and runtime
    option parsing (when typically an error code is returned instead). The
    difference between this function and argp_error is that the latter is for
    *parsing errors*, and the former is for other problems that occur during
    parsing but don't reflect a (syntactic) problem with the input. */
    void
    __argp_failure (const struct argp_state *state, int status, int errnum,
    const char *fmt, ...)
    {
    if (!state || !(state->flags & ARGP_NO_ERRS))
    {
    FILE *stream = state ? state->err_stream : stderr;

    if (stream)
    {
    #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
    __flockfile (stream);
    #endif

    #ifdef _LIBC
    __fxprintf (stream, "%s",
    state ? state->name : __argp_short_program_name ());
    #else
    fputs_unlocked (state ? state->name : __argp_short_program_name (),
    stream);
    #endif

    if (fmt)
    {
    va_list ap;

    va_start (ap, fmt);
    #ifdef _LIBC
    char *buf;

    if (_IO_vasprintf (&buf, fmt, ap) < 0)
    buf = NULL;

    __fxprintf (stream, ": %s", buf);

    free (buf);
    #else
    putc_unlocked (':', stream);
    putc_unlocked (' ', stream);

    vfprintf (stream, fmt, ap);
    #endif

    va_end (ap);
    }

    if (errnum)
    {
    char buf[200];

    #ifdef _LIBC
    __fxprintf (stream, ": %s",
    __strerror_r (errnum, buf, sizeof (buf)));
    #else
    putc_unlocked (':', stream);
    putc_unlocked (' ', stream);
    # ifdef HAVE_STRERROR_R
    fputs (__strerror_r (errnum, buf, sizeof (buf)), stream);
    # else
    fputs (strerror (errnum), stream);
    # endif
    #endif
    }

    if (_IO_fwide (stream, 0) > 0)
    putwc_unlocked (L'\n', stream);
    else
    putc_unlocked ('\n', stream);

    #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
    __funlockfile (stream);
    #endif

    if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
    exit (status);
    }
    }
    }
    #ifdef weak_alias
    weak_alias (__argp_failure, argp_failure)
    #endif

  4. #29
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Name frobnication for compiling argp outside of glibc
    Copyright (C) 1997, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <[email protected]>.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    #if !_LIBC
    /* This code is written for inclusion in gnu-libc, and uses names in the
    namespace reserved for libc. If we're not compiling in libc, define those
    names to be the normal ones instead. */

    /* argp-parse functions */
    #undef __argp_parse
    #define __argp_parse argp_parse
    #undef __option_is_end
    #define __option_is_end _option_is_end
    #undef __option_is_short
    #define __option_is_short _option_is_short
    #undef __argp_input
    #define __argp_input _argp_input

    /* argp-help functions */
    #undef __argp_help
    #define __argp_help argp_help
    #undef __argp_error
    #define __argp_error argp_error
    #undef __argp_failure
    #define __argp_failure argp_failure
    #undef __argp_state_help
    #define __argp_state_help argp_state_help
    #undef __argp_usage
    #define __argp_usage argp_usage

    /* argp-fmtstream functions */
    #undef __argp_make_fmtstream
    #define __argp_make_fmtstream argp_make_fmtstream
    #undef __argp_fmtstream_free
    #define __argp_fmtstream_free argp_fmtstream_free
    #undef __argp_fmtstream_putc
    #define __argp_fmtstream_putc argp_fmtstream_putc
    #undef __argp_fmtstream_puts
    #define __argp_fmtstream_puts argp_fmtstream_puts
    #undef __argp_fmtstream_write
    #define __argp_fmtstream_write argp_fmtstream_write
    #undef __argp_fmtstream_printf
    #define __argp_fmtstream_printf argp_fmtstream_printf
    #undef __argp_fmtstream_set_lmargin
    #define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
    #undef __argp_fmtstream_set_rmargin
    #define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
    #undef __argp_fmtstream_set_wmargin
    #define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
    #undef __argp_fmtstream_point
    #define __argp_fmtstream_point argp_fmtstream_point
    #undef __argp_fmtstream_update
    #define __argp_fmtstream_update _argp_fmtstream_update
    #undef __argp_fmtstream_ensure
    #define __argp_fmtstream_ensure _argp_fmtstream_ensure
    #undef __argp_fmtstream_lmargin
    #define __argp_fmtstream_lmargin argp_fmtstream_lmargin
    #undef __argp_fmtstream_rmargin
    #define __argp_fmtstream_rmargin argp_fmtstream_rmargin
    #undef __argp_fmtstream_wmargin
    #define __argp_fmtstream_wmargin argp_fmtstream_wmargin

    #include "mempcpy.h"
    #include "strcase.h"
    #include "strchrnul.h"
    #include "strndup.h"

    /* normal libc functions we call */
    #undef __flockfile
    #define __flockfile flockfile
    #undef __funlockfile
    #define __funlockfile funlockfile
    #undef __mempcpy
    #define __mempcpy mempcpy
    #undef __sleep
    #define __sleep sleep
    #undef __strcasecmp
    #define __strcasecmp strcasecmp
    #undef __strchrnul
    #define __strchrnul strchrnul
    #undef __strerror_r
    #define __strerror_r strerror_r
    #undef __strndup
    #define __strndup strndup
    #undef __vsnprintf
    #define __vsnprintf vsnprintf

    #if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED
    # define clearerr_unlocked(x) clearerr (x)
    #endif
    #if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED
    # define feof_unlocked(x) feof (x)
    # endif
    #if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED
    # define ferror_unlocked(x) ferror (x)
    # endif
    #if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED
    # define fflush_unlocked(x) fflush (x)
    # endif
    #if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED
    # define fgets_unlocked(x,y,z) fgets (x,y,z)
    # endif
    #if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED
    # define fputc_unlocked(x,y) fputc (x,y)
    # endif
    #if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED
    # define fputs_unlocked(x,y) fputs (x,y)
    # endif
    #if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED
    # define fread_unlocked(w,x,y,z) fread (w,x,y,z)
    # endif
    #if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED
    # define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
    # endif
    #if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED
    # define getc_unlocked(x) getc (x)
    # endif
    #if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED
    # define getchar_unlocked() getchar ()
    # endif
    #if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED
    # define putc_unlocked(x,y) putc (x,y)
    # endif
    #if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED
    # define putchar_unlocked(x) putchar (x)
    # endif

    extern char *__argp_basename (char *name);

    #endif /* !_LIBC */

    #ifndef __set_errno
    #define __set_errno(e) (errno = (e))
    #endif

    #if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
    # define __argp_short_program_name() (program_invocation_short_name)
    #else
    extern char *__argp_short_program_name (void);
    #endif

  5. #30
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Hierarchial argument parsing, layered over getopt
    Copyright (C) 1995-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <[email protected]>.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif

    /* AIX requires this to be the first thing in the file. */
    #ifndef __GNUC__
    # if HAVE_ALLOCA_H || defined _LIBC
    # include <alloca.h>
    # else
    # ifdef _AIX
    #pragma alloca
    # else
    # ifndef alloca /* predefined by HP cc +Olibcalls */
    char *alloca ();
    # endif
    # endif
    # endif
    #endif

    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <limits.h>
    #include <getopt.h>
    #include <getopt_int.h>

    #ifndef _
    /* This is for other GNU distributions with internationalized messages.
    When compiling libc, the _ macro is predefined. */
    # if defined HAVE_LIBINTL_H || defined _LIBC
    # include <libintl.h>
    # ifdef _LIBC
    # undef dgettext
    # define dgettext(domain, msgid) \
    __dcgettext (domain, msgid, LC_MESSAGES)
    # endif
    # else
    # define dgettext(domain, msgid) (msgid)
    # define gettext(msgid) (msgid)
    # endif
    #endif
    #ifndef N_
    # define N_(msgid) (msgid)
    #endif

    #include "argp.h"
    #include "argp-namefrob.h"

    /* Getopt return values. */
    #define KEY_END (-1) /* The end of the options. */
    #define KEY_ARG 1 /* A non-option argument. */
    #define KEY_ERR '?' /* An error parsing the options. */

    /* The meta-argument used to prevent any further arguments being interpreted
    as options. */
    #define QUOTE "--"

    /* The number of bits we steal in a long-option value for our own use. */
    #define GROUP_BITS CHAR_BIT

    /* The number of bits available for the user value. */
    #define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS)
    #define USER_MASK ((1 << USER_BITS) - 1)

    /* EZ alias for ARGP_ERR_UNKNOWN. */
    #define EBADKEY ARGP_ERR_UNKNOWN

    /* Default options. */

    /* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
    for one second intervals, decrementing _ARGP_HANG until it's zero. Thus
    you can force the program to continue by attaching a debugger and setting
    it to 0 yourself. */
    static volatile int _argp_hang;

    #define OPT_PROGNAME -2
    #define OPT_USAGE -3
    #define OPT_HANG -4

    static const struct argp_option argp_default_options[] =
    {
    {"help", '?', 0, 0, N_("Give this help list"), -1},
    {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message")},
    {"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name")},
    {"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
    N_("Hang for SECS seconds (default 3600)")},
    {0, 0}
    };

    static error_t
    argp_default_parser (int key, char *arg, struct argp_state *state)
    {
    switch (key)
    {
    case '?':
    __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
    break;
    case OPT_USAGE:
    __argp_state_help (state, state->out_stream,
    ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
    break;

    case OPT_PROGNAME: /* Set the program name. */
    #if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME
    program_invocation_name = arg;
    #endif
    /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
    __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
    to be that, so we have to be a bit careful here.] */

    /* Update what we use for messages. */
    state->name = strrchr (arg, '/');
    if (state->name)
    state->name++;
    else
    state->name = arg;

    #if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
    program_invocation_short_name = state->name;
    #endif

    if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
    == ARGP_PARSE_ARGV0)
    /* Update what getopt uses too. */
    state->argv[0] = arg;

    break;

    case OPT_HANG:
    _argp_hang = atoi (arg ? arg : "3600");
    while (_argp_hang-- > 0)
    __sleep (1);
    break;

    default:
    return EBADKEY;
    }
    return 0;
    }

    static const struct argp argp_default_argp =
    {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};


    static const struct argp_option argp_version_options[] =
    {
    {"version", 'V', 0, 0, N_("Print program version"), -1},
    {0, 0}
    };

    static error_t
    argp_version_parser (int key, char *arg, struct argp_state *state)
    {
    switch (key)
    {
    case 'V':
    if (argp_program_version_hook)
    (*argp_program_version_hook) (state->out_stream, state);
    else if (argp_program_version)
    fprintf (state->out_stream, "%s\n", argp_program_version);
    else
    __argp_error (state, dgettext (state->root_argp->argp_domain,
    "(PROGRAM ERROR) No version known!?"));
    if (! (state->flags & ARGP_NO_EXIT))
    exit (0);
    break;
    default:
    return EBADKEY;
    }
    return 0;
    }

    static const struct argp argp_version_argp =
    {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};

    /* Returns the offset into the getopt long options array LONG_OPTIONS of a
    long option with called NAME, or -1 if none is found. Passing NULL as
    NAME will return the number of options. */
    static int
    find_long_option (struct option *long_options, const char *name)
    {
    struct option *l = long_options;
    while (l->name != NULL)
    if (name != NULL && strcmp (l->name, name) == 0)
    return l - long_options;
    else
    l++;
    if (name == NULL)
    return l - long_options;
    else
    return -1;
    }


    /* The state of a `group' during parsing. Each group corresponds to a
    particular argp structure from the tree of such descending from the top
    level argp passed to argp_parse. */
    struct group
    {
    /* This group's parsing function. */
    argp_parser_t parser;

    /* Which argp this group is from. */
    const struct argp *argp;

    /* Points to the point in SHORT_OPTS corresponding to the end of the short
    options for this group. We use it to determine from which group a
    particular short options is from. */
    char *short_end;

    /* The number of non-option args sucessfully handled by this parser. */
    unsigned args_processed;

    /* This group's parser's parent's group. */
    struct group *parent;
    unsigned parent_index; /* And the our position in the parent. */

    /* These fields are swapped into and out of the state structure when
    calling this group's parser. */
    void *input, **child_inputs;
    void *hook;
    };

    /* Call GROUP's parser with KEY and ARG, swapping any group-specific info
    from STATE before calling, and back into state afterwards. If GROUP has
    no parser, EBADKEY is returned. */
    static error_t
    group_parse (struct group *group, struct argp_state *state, int key, char *arg)
    {
    if (group->parser)
    {
    error_t err;
    state->hook = group->hook;
    state->input = group->input;
    state->child_inputs = group->child_inputs;
    state->arg_num = group->args_processed;
    err = (*group->parser)(key, arg, state);
    group->hook = state->hook;
    return err;
    }
    else
    return EBADKEY;
    }

    struct parser
    {
    const struct argp *argp;

    /* SHORT_OPTS is the getopt short options string for the union of all the
    groups of options. */
    char *short_opts;
    /* LONG_OPTS is the array of getop long option structures for the union of
    all the groups of options. */
    struct option *long_opts;
    /* OPT_DATA is the getopt data used for the re-entrant getopt. */
    struct _getopt_data opt_data;

    /* States of the various parsing groups. */
    struct group *groups;
    /* The end of the GROUPS array. */
    struct group *egroup;
    /* An vector containing storage for the CHILD_INPUTS field in all groups. */
    void **child_inputs;

    /* True if we think using getopt is still useful; if false, then
    remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is
    cleared whenever getopt returns KEY_END, but may be set again if the user
    moves the next argument pointer backwards. */
    int try_getopt;

    /* State block supplied to parsing routines. */
    struct argp_state state;

    /* Memory used by this parser. */
    void *storage;
    };

    /* The next usable entries in the various parser tables being filled in by
    convert_options. */
    struct parser_convert_state
    {
    struct parser *parser;
    char *short_end;
    struct option *long_end;
    void **child_inputs_end;
    };

    /* Converts all options in ARGP (which is put in GROUP) and ancestors
    into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and
    CVT->LONG_END are the points at which new options are added. Returns the
    next unused group entry. CVT holds state used during the conversion. */
    static struct group *
    convert_options (const struct argp *argp,
    struct group *parent, unsigned parent_index,
    struct group *group, struct parser_convert_state *cvt)
    {
    /* REAL is the most recent non-alias value of OPT. */
    const struct argp_option *real = argp->options;
    const struct argp_child *children = argp->children;

    if (real || argp->parser)
    {
    const struct argp_option *opt;

    if (real)
    for (opt = real; !__option_is_end (opt); opt++)
    {
    if (! (opt->flags & OPTION_ALIAS))
    /* OPT isn't an alias, so we can use values from it. */
    real = opt;

    if (! (real->flags & OPTION_DOC))
    /* A real option (not just do entation). */
    {
    if (__option_is_short (opt))
    /* OPT can be used as a short option. */
    {
    *cvt->short_end++ = opt->key;
    if (real->arg)
    {
    *cvt->short_end++ = ':';
    if (real->flags & OPTION_ARG_OPTIONAL)
    *cvt->short_end++ = ':';
    }
    *cvt->short_end = '\0'; /* keep 0 terminated */
    }

    if (opt->name
    && find_long_option (cvt->parser->long_opts, opt->name) < 0)
    /* OPT can be used as a long option. */
    {
    cvt->long_end->name = opt->name;
    cvt->long_end->has_arg =
    (real->arg
    ? (real->flags & OPTION_ARG_OPTIONAL
    ? optional_argument
    : required_argument)
    : no_argument);
    cvt->long_end->flag = 0;
    /* we add a disambiguating code to all the user's
    values (which is removed before we actually call
    the function to parse the value); this means that
    the user loses use of the high 8 bits in all his
    values (the sign of the lower bits is preserved
    however)... */
    cvt->long_end->val =
    ((opt->key ? opt->key : real->key) & USER_MASK)
    + (((group - cvt->parser->groups) + 1) << USER_BITS);

    /* Keep the LONG_OPTS list terminated. */
    (++cvt->long_end)->name = NULL;
    }
    }
    }

    group->parser = argp->parser;
    group->argp = argp;
    group->short_end = cvt->short_end;
    group->args_processed = 0;
    group->parent = parent;
    group->parent_index = parent_index;
    group->input = 0;
    group->hook = 0;
    group->child_inputs = 0;

    if (children)
    /* Assign GROUP's CHILD_INPUTS field some space from
    CVT->child_inputs_end.*/
    {
    unsigned num_children = 0;
    while (children[num_children].argp)
    num_children++;
    group->child_inputs = cvt->child_inputs_end;
    cvt->child_inputs_end += num_children;
    }

    parent = group++;
    }
    else
    parent = 0;

    if (children)
    {
    unsigned index = 0;
    while (children->argp)
    group =
    convert_options (children++->argp, parent, index++, group, cvt);
    }

    return group;
    }

    /* Find the merged set of getopt options, with keys appropiately prefixed. */
    static void
    parser_convert (struct parser *parser, const struct argp *argp, int flags)
    {
    struct parser_convert_state cvt;

    cvt.parser = parser;
    cvt.short_end = parser->short_opts;
    cvt.long_end = parser->long_opts;
    cvt.child_inputs_end = parser->child_inputs;

    if (flags & ARGP_IN_ORDER)
    *cvt.short_end++ = '-';
    else if (flags & ARGP_NO_ARGS)
    *cvt.short_end++ = '+';
    *cvt.short_end = '\0';

    cvt.long_end->name = NULL;

    parser->argp = argp;

    if (argp)
    parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt);
    else
    parser->egroup = parser->groups; /* No parsers at all! */
    }

    /* Lengths of various parser fields which we will allocated. */
    struct parser_sizes
    {
    size_t short_len; /* Getopt short options string. */
    size_t long_len; /* Getopt long options vector. */
    size_t num_groups; /* Group structures we allocate. */
    size_t num_child_inputs; /* Child input slots. */
    };

  6. #31
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* For ARGP, increments the NUM_GROUPS field in SZS by the total number of
    argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by
    the maximum lengths of the resulting merged getopt short options string and
    long-options array, respectively. */
    static void
    calc_sizes (const struct argp *argp, struct parser_sizes *szs)
    {
    const struct argp_child *child = argp->children;
    const struct argp_option *opt = argp->options;

    if (opt || argp->parser)
    {
    szs->num_groups++;
    if (opt)
    {
    int num_opts = 0;
    while (!__option_is_end (opt++))
    num_opts++;
    szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */
    szs->long_len += num_opts;
    }
    }

    if (child)
    while (child->argp)
    {
    calc_sizes ((child++)->argp, szs);
    szs->num_child_inputs++;
    }
    }

    /* Initializes PARSER to parse ARGP in a manner described by FLAGS. */
    static error_t
    parser_init (struct parser *parser, const struct argp *argp,
    int argc, char **argv, int flags, void *input)
    {
    error_t err = 0;
    struct group *group;
    struct parser_sizes szs;
    struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;

    szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
    szs.long_len = 0;
    szs.num_groups = 0;
    szs.num_child_inputs = 0;

    if (argp)
    calc_sizes (argp, &szs);

    /* Lengths of the various bits of storage used by PARSER. */
    #define GLEN (szs.num_groups + 1) * sizeof (struct group)
    #define CLEN (szs.num_child_inputs * sizeof (void *))
    #define LLEN ((szs.long_len + 1) * sizeof (struct option))
    #define SLEN (szs.short_len + 1)

    parser->storage = malloc (GLEN + CLEN + LLEN + SLEN);
    if (! parser->storage)
    return ENOMEM;

    parser->groups = parser->storage;
    parser->child_inputs = parser->storage + GLEN;
    parser->long_opts = parser->storage + GLEN + CLEN;
    parser->short_opts = parser->storage + GLEN + CLEN + LLEN;
    parser->opt_data = opt_data;

    memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
    parser_convert (parser, argp, flags);

    memset (&parser->state, 0, sizeof (struct argp_state));
    parser->state.root_argp = parser->argp;
    parser->state.argc = argc;
    parser->state.argv = argv;
    parser->state.flags = flags;
    parser->state.err_stream = stderr;
    parser->state.out_stream = stdout;
    parser->state.next = 0; /* Tell getopt to initialize. */
    parser->state.pstate = parser;

    parser->try_getopt = 1;

    /* Call each parser for the first time, giving it a chance to propagate
    values to child parsers. */
    if (parser->groups < parser->egroup)
    parser->groups->input = input;
    for (group = parser->groups;
    group < parser->egroup && (!err || err == EBADKEY);
    group++)
    {
    if (group->parent)
    /* If a child parser, get the initial input value from the parent. */
    group->input = group->parent->child_inputs[group->parent_index];

    if (!group->parser
    && group->argp->children && group->argp->children->argp)
    /* For the special case where no parsing function is supplied for an
    argp, propagate its input to its first child, if any (this just
    makes very simple wrapper argps more convenient). */
    group->child_inputs[0] = group->input;

    err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0);
    }
    if (err == EBADKEY)
    err = 0; /* Some parser didn't understand. */

    if (err)
    return err;

    if (parser->state.flags & ARGP_NO_ERRS)
    {
    parser->opt_data.opterr = 0;
    if (parser->state.flags & ARGP_PARSE_ARGV0)
    /* getopt always skips ARGV[0], so we have to fake it out. As long
    as OPTERR is 0, then it shouldn't actually try to access it. */
    parser->state.argv--, parser->state.argc++;
    }
    else
    parser->opt_data.opterr = 1; /* Print error messages. */

    if (parser->state.argv == argv && argv[0])
    /* There's an argv[0]; use it for messages. */
    {
    char *short_name = strrchr (argv[0], '/');
    parser->state.name = short_name ? short_name + 1 : argv[0];
    }
    else
    parser->state.name = __argp_short_program_name ();

    return 0;
    }

    /* Free any storage consumed by PARSER (but not PARSER itself). */
    static error_t
    parser_finalize (struct parser *parser,
    error_t err, int arg_ebadkey, int *end_index)
    {
    struct group *group;

    if (err == EBADKEY && arg_ebadkey)
    /* Suppress errors generated by unparsed arguments. */
    err = 0;

    if (! err)
    {
    if (parser->state.next == parser->state.argc)
    /* We successfully parsed all arguments! Call all the parsers again,
    just a few more times... */
    {
    for (group = parser->groups;
    group < parser->egroup && (!err || err==EBADKEY);
    group++)
    if (group->args_processed == 0)
    err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0);
    for (group = parser->egroup - 1;
    group >= parser->groups && (!err || err==EBADKEY);
    group--)
    err = group_parse (group, &parser->state, ARGP_KEY_END, 0);

    if (err == EBADKEY)
    err = 0; /* Some parser didn't understand. */

    /* Tell the user that all arguments are parsed. */
    if (end_index)
    *end_index = parser->state.next;
    }
    else if (end_index)
    /* Return any remaining arguments to the user. */
    *end_index = parser->state.next;
    else
    /* No way to return the remaining arguments, they must be bogus. */
    {
    if (!(parser->state.flags & ARGP_NO_ERRS)
    && parser->state.err_stream)
    fprintf (parser->state.err_stream,
    dgettext (parser->argp->argp_domain,
    "%s: Too many arguments\n"),
    parser->state.name);
    err = EBADKEY;
    }
    }

    /* Okay, we're all done, with either an error or success; call the parsers
    to indicate which one. */

    if (err)
    {
    /* Maybe print an error message. */
    if (err == EBADKEY)
    /* An appropriate message describing what the error was should have
    been printed earlier. */
    __argp_state_help (&parser->state, parser->state.err_stream,
    ARGP_HELP_STD_ERR);

    /* Since we didn't exit, give each parser an error indication. */
    for (group = parser->groups; group < parser->egroup; group++)
    group_parse (group, &parser->state, ARGP_KEY_ERROR, 0);
    }
    else
    /* Notify parsers of success, and propagate back values from parsers. */
    {
    /* We pass over the groups in reverse order so that child groups are
    given a chance to do there processing before passing back a value to
    the parent. */
    for (group = parser->egroup - 1
    ; group >= parser->groups && (!err || err == EBADKEY)
    ; group--)
    err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0);
    if (err == EBADKEY)
    err = 0; /* Some parser didn't understand. */
    }

    /* Call parsers once more, to do any final cleanup. Errors are ignored. */
    for (group = parser->egroup - 1; group >= parser->groups; group--)
    group_parse (group, &parser->state, ARGP_KEY_FINI, 0);

    if (err == EBADKEY)
    err = EINVAL;

    free (parser->storage);

    return err;
    }

    /* Call the user parsers to parse the non-option argument VAL, at the current
    position, returning any error. The state NEXT pointer is assumed to have
    been adjusted (by getopt) to point after this argument; this function will
    adjust it correctly to reflect however many args actually end up being
    consumed. */
    static error_t
    parser_parse_arg (struct parser *parser, char *val)
    {
    /* Save the starting value of NEXT, first adjusting it so that the arg
    we're parsing is again the front of the arg vector. */
    int index = --parser->state.next;
    error_t err = EBADKEY;
    struct group *group;
    int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */

    /* Try to parse the argument in each parser. */
    for (group = parser->groups
    ; group < parser->egroup && err == EBADKEY
    ; group++)
    {
    parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */
    key = ARGP_KEY_ARG;
    err = group_parse (group, &parser->state, key, val);

    if (err == EBADKEY)
    /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */
    {
    parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */
    key = ARGP_KEY_ARGS;
    err = group_parse (group, &parser->state, key, 0);
    }
    }

    if (! err)
    {
    if (key == ARGP_KEY_ARGS)
    /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't
    changed by the user, *all* arguments should be considered
    consumed. */
    parser->state.next = parser->state.argc;

    if (parser->state.next > index)
    /* Remember that we successfully processed a non-option
    argument -- but only if the user hasn't gotten tricky and set
    the clock back. */
    (--group)->args_processed += (parser->state.next - index);
    else
    /* The user wants to reparse some args, give getopt another try. */
    parser->try_getopt = 1;
    }

    return err;
    }

    /* Call the user parsers to parse the option OPT, with argument VAL, at the
    current position, returning any error. */
    static error_t
    parser_parse_opt (struct parser *parser, int opt, char *val)
    {
    /* The group key encoded in the high bits; 0 for short opts or
    group_number + 1 for long opts. */
    int group_key = opt >> USER_BITS;
    error_t err = EBADKEY;

    if (group_key == 0)
    /* A short option. By comparing OPT's position in SHORT_OPTS to the
    various starting positions in each group's SHORT_END field, we can
    determine which group OPT came from. */
    {
    struct group *group;
    char *short_index = strchr (parser->short_opts, opt);

    if (short_index)
    for (group = parser->groups; group < parser->egroup; group++)
    if (group->short_end > short_index)
    {
    err = group_parse (group, &parser->state, opt,
    parser->opt_data.optarg);
    break;
    }
    }
    else
    /* A long option. We use shifts instead of masking for extracting
    the user value in order to preserve the sign. */
    err =
    group_parse (&parser->groups[group_key - 1], &parser->state,
    (opt << GROUP_BITS) >> GROUP_BITS,
    parser->opt_data.optarg);

    if (err == EBADKEY)
    /* At least currently, an option not recognized is an error in the
    parser, because we pre-compute which parser is supposed to deal
    with each option. */
    {
    static const char bad_key_err[] =
    N_("(PROGRAM ERROR) Option should have been recognized!?");
    if (group_key == 0)
    __argp_error (&parser->state, "-%c: %s", opt,
    dgettext (parser->argp->argp_domain, bad_key_err));
    else
    {
    struct option *long_opt = parser->long_opts;
    while (long_opt->val != opt && long_opt->name)
    long_opt++;
    __argp_error (&parser->state, "--%s: %s",
    long_opt->name ? long_opt->name : "???",
    dgettext (parser->argp->argp_domain, bad_key_err));
    }
    }

    return err;
    }

    /* Parse the next argument in PARSER (as indicated by PARSER->state.next).
    Any error from the parsers is returned, and *ARGP_EBADKEY indicates
    whether a value of EBADKEY is due to an unrecognized argument (which is
    generally not fatal). */
    static error_t
    parser_parse_next (struct parser *parser, int *arg_ebadkey)
    {
    int opt;
    error_t err = 0;

    if (parser->state.quoted && parser->state.next < parser->state.quoted)
    /* The next argument pointer has been moved to before the quoted
    region, so pretend we never saw the quoting `--', and give getopt
    another chance. If the user hasn't removed it, getopt will just
    process it again. */
    parser->state.quoted = 0;

    if (parser->try_getopt && !parser->state.quoted)
    /* Give getopt a chance to parse this. */
    {
    /* Put it back in OPTIND for getopt. */
    parser->opt_data.optind = parser->state.next;
    /* Distinguish KEY_ERR from a real option. */
    parser->opt_data.optopt = KEY_END;
    if (parser->state.flags & ARGP_LONG_ONLY)
    opt = _getopt_long_only_r (parser->state.argc, parser->state.argv,
    parser->short_opts, parser->long_opts, 0,
    &parser->opt_data);
    else
    opt = _getopt_long_r (parser->state.argc, parser->state.argv,
    parser->short_opts, parser->long_opts, 0,
    &parser->opt_data);
    /* And see what getopt did. */
    parser->state.next = parser->opt_data.optind;

    if (opt == KEY_END)
    /* Getopt says there are no more options, so stop using
    getopt; we'll continue if necessary on our own. */
    {
    parser->try_getopt = 0;
    if (parser->state.next > 1
    && strcmp (parser->state.argv[parser->state.next - 1], QUOTE)
    == 0)
    /* Not only is this the end of the options, but it's a
    `quoted' region, which may have args that *look* like
    options, so we definitely shouldn't try to use getopt past
    here, whatever happens. */
    parser->state.quoted = parser->state.next;
    }
    else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END)
    /* KEY_ERR can have the same value as a valid user short
    option, but in the case of a real error, getopt sets OPTOPT
    to the offending character, which can never be KEY_END. */
    {
    *arg_ebadkey = 0;
    return EBADKEY;
    }
    }
    else
    opt = KEY_END;

    if (opt == KEY_END)
    {
    /* We're past what getopt considers the options. */
    if (parser->state.next >= parser->state.argc
    || (parser->state.flags & ARGP_NO_ARGS))
    /* Indicate that we're done. */
    {
    *arg_ebadkey = 1;
    return EBADKEY;
    }
    else
    /* A non-option arg; simulate what getopt might have done. */
    {
    opt = KEY_ARG;
    parser->opt_data.optarg = parser->state.argv[parser->state.next++];
    }
    }

    if (opt == KEY_ARG)
    /* A non-option argument; try each parser in turn. */
    err = parser_parse_arg (parser, parser->opt_data.optarg);
    else
    err = parser_parse_opt (parser, opt, parser->opt_data.optarg);

    if (err == EBADKEY)
    *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);

    return err;
    }

  7. #32
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Parse the options strings in ARGC & ARGV according to the argp in ARGP.
    FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the
    index in ARGV of the first unparsed option is returned in it. If an
    unknown option is present, EINVAL is returned; if some parser routine
    returned a non-zero value, it is returned; otherwise 0 is returned. */
    error_t
    __argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags,
    int *end_index, void *input)
    {
    error_t err;
    struct parser parser;

    /* If true, then err == EBADKEY is a result of a non-option argument failing
    to be parsed (which in some cases isn't actually an error). */
    int arg_ebadkey = 0;

    if (! (flags & ARGP_NO_HELP))
    /* Add our own options. */
    {
    struct argp_child *child = alloca (4 * sizeof (struct argp_child));
    struct argp *top_argp = alloca (sizeof (struct argp));

    /* TOP_ARGP has no options, it just serves to group the user & default
    argps. */
    memset (top_argp, 0, sizeof (*top_argp));
    top_argp->children = child;

    memset (child, 0, 4 * sizeof (struct argp_child));

    if (argp)
    (child++)->argp = argp;
    (child++)->argp = &argp_default_argp;
    if (argp_program_version || argp_program_version_hook)
    (child++)->argp = &argp_version_argp;
    child->argp = 0;

    argp = top_argp;
    }

    /* Construct a parser for these arguments. */
    err = parser_init (&parser, argp, argc, argv, flags, input);

    if (! err)
    /* Parse! */
    {
    while (! err)
    err = parser_parse_next (&parser, &arg_ebadkey);
    err = parser_finalize (&parser, err, arg_ebadkey, end_index);
    }

    return err;
    }
    #ifdef weak_alias
    weak_alias (__argp_parse, argp_parse)
    #endif

    /* Return the input field for ARGP in the parser corresponding to STATE; used
    by the help routines. */
    void *
    __argp_input (const struct argp *argp, const struct argp_state *state)
    {
    if (state)
    {
    struct group *group;
    struct parser *parser = state->pstate;

    for (group = parser->groups; group < parser->egroup; group++)
    if (group->argp == argp)
    return group->input;
    }

    return 0;
    }
    #ifdef weak_alias
    weak_alias (__argp_input, _argp_input)
    #endif

  8. #33
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Default definition for ARGP_PROGRAM_VERSION.
    Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <[email protected]>.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    /* If set by the user program to a non-zero value, then a default option
    --version is added (unless the ARGP_NO_HELP flag is used), which will
    print this this string followed by a newline and exit (unless the
    ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
    const char *argp_program_version;

  9. #34
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Default definition for ARGP_PROGRAM_VERSION_HOOK.
    Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <[email protected]>.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif

    #include "argp.h"

    /* If set by the user program to a non-zero value, then a default option
    --version is added (unless the ARGP_NO_HELP flag is used), which calls
    this function with a stream to print the version to and a pointer to the
    current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
    used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
    void (*argp_program_version_hook) (FILE *stream, struct argp_state *state);

  10. #35
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Test program for argp argument parser
    Copyright (C) 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <[email protected]>.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif

    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #include <argp.h>

    const char *argp_program_version = "argp-test 1.0";

    struct argp_option sub_options[] =
    {
    {"subopt1", 's', 0, 0, "Nested option 1"},
    {"subopt2", 'S', 0, 0, "Nested option 2"},

    { 0, 0, 0, 0, "Some more nested options:", 10},
    {"subopt3", 'p', 0, 0, "Nested option 3"},

    {"subopt4", 'q', 0, 0, "Nested option 4", 1},

    {0}
    };

    static const char sub_args_doc[] = "STRING...\n-";
    static const char sub_doc[] = "\vThis is the doc string from the sub-arg-parser.";

    static error_t
    sub_parse_opt (int key, char *arg, struct argp_state *state)
    {
    switch (key)
    {
    case ARGP_KEY_NO_ARGS:
    printf ("NO SUB ARGS\n");
    break;
    case ARGP_KEY_ARG:
    printf ("SUB ARG: %s\n", arg);
    break;

    case 's' : case 'S': case 'p': case 'q':
    printf ("SUB KEY %c\n", key);
    break;

    default:
    return ARGP_ERR_UNKNOWN;
    }
    return 0;
    }

    static char *
    sub_help_filter (int key, const char *text, void *input)
    {
    if (key == ARGP_KEY_HELP_EXTRA)
    return strdup ("This is some extra text from the sub parser (note that it \
    is preceded by a blank line).");
    else
    return (char *)text;
    }

    static struct argp sub_argp = {
    sub_options, sub_parse_opt, sub_args_doc, sub_doc, 0, sub_help_filter
    };

    /* Structure used to communicate with the parsing functions. */
    struct params
    {
    unsigned foonly; /* Value parsed for foonly. */
    unsigned foonly_default; /* Default value for it. */
    };

    #define OPT_PGRP 1
    #define OPT_SESS 2

    struct argp_option options[] =
    {
    {"pid", 'p', "PID", 0, "List the process PID"},
    {"pgrp", OPT_PGRP,"PGRP",0, "List processes in the process group PGRP"},
    {"no-parent", 'P', 0, 0, "Include processes without parents"},
    {0, 'x', 0, OPTION_ALIAS},
    {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
    " if there's some reason ps can't"
    " print a field for any process, it's"
    " removed from the output entirely)" },
    {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
    {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
    {"session", OPT_SESS,"SID", OPTION_ARG_OPTIONAL,
    "Add the processes from the session"
    " SID (which defaults to the sid of"
    " the current process)" },

    {0,0,0,0, "Here are some more options:"},
    {"foonly", 'f', "ZOT", OPTION_ARG_OPTIONAL, "Glork a foonly"},
    {"zaza", 'z', 0, 0, "Snit a zar"},

    {0}
    };

    static const char args_doc[] = "STRING";
    static const char doc[] = "Test program for argp."
    "\vThis doc string comes after the options."
    "\nHey! Some manual formatting!"
    "\nThe current time is: %s";

    static void
    popt (int key, char *arg)
    {
    char buf[10];
    if (isprint (key))
    sprintf (buf, "%c", key);
    else
    sprintf (buf, "%d", key);
    if (arg)
    printf ("KEY %s: %s\n", buf, arg);
    else
    printf ("KEY %s\n", buf);
    }

    static error_t
    parse_opt (int key, char *arg, struct argp_state *state)
    {
    struct params *params = state->input;

    switch (key)
    {
    case ARGP_KEY_NO_ARGS:
    printf ("NO ARGS\n");
    break;

    case ARGP_KEY_ARG:
    if (state->arg_num > 0)
    return ARGP_ERR_UNKNOWN; /* Leave it for the sub-arg parser. */
    printf ("ARG: %s\n", arg);
    break;

    case 'f':
    if (arg)
    params->foonly = atoi (arg);
    else
    params->foonly = params->foonly_default;
    popt (key, arg);
    break;

    case 'p': case 'P': case OPT_PGRP: case 'x': case 'Q':
    case 'r': case OPT_SESS: case 'z':
    popt (key, arg);
    break;

    default:
    return ARGP_ERR_UNKNOWN;
    }
    return 0;
    }

    static char *
    help_filter (int key, const char *text, void *input)
    {
    char *new_text;
    struct params *params = input;

    if (key == ARGP_KEY_HELP_POST_DOC && text)
    {
    time_t now = time (0);
    asprintf (&new_text, text, ctime (&now));
    }
    else if (key == 'f')
    /* Show the default for the --foonly option. */
    asprintf (&new_text, "%s (ZOT defaults to %x)",
    text, params->foonly_default);
    else
    new_text = (char *)text;

    return new_text;
    }

    static struct argp_child argp_children[] = { { &sub_argp }, { 0 } };
    static struct argp argp = {
    options, parse_opt, args_doc, doc, argp_children, help_filter
    };

    int
    main (int argc, char **argv)
    {
    struct params params;
    params.foonly = 0;
    params.foonly_default = random ();
    argp_parse (&argp, argc, argv, 0, 0, &params);
    printf ("After parsing: foonly = %x\n", params.foonly);
    return 0;
    }

  11. #36
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Real definitions for extern inline functions in argp.h
    Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <[email protected]>.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    #ifdef HAVE_CONFIG_H
    # include <config.h>
    #endif

    #if defined _LIBC || defined HAVE_FEATURES_H
    # include <features.h>
    #endif

    #ifndef __USE_EXTERN_INLINES
    # define __USE_EXTERN_INLINES 1
    #endif
    #define ARGP_EI
    #undef __OPTIMIZE__
    #define __OPTIMIZE__ 1
    #include "argp.h"

    /* Add weak aliases. */
    #if _LIBC - 0 && defined (weak_alias)

    weak_alias (__argp_usage, argp_usage)
    weak_alias (__option_is_short, _option_is_short)
    weak_alias (__option_is_end, _option_is_end)

    #endif

  12. #37
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    #include <argp.h>


    static const struct argp_option test_options[] =
    {
    { NULL, 'a', NULL, OPTION_DOC, NULL },
    { NULL, 'b', NULL, OPTION_DOC, NULL },
    { NULL, 0, NULL, 0, NULL }
    };

    static struct argp test_argp =
    {
    test_options
    };


    static int
    do_test (int argc, char *argv[])
    {
    int i;
    argp_parse (&test_argp, argc, argv, 0, &i, NULL);
    return 0;
    }

    #define TEST_FUNCTION do_test (argc, argv)
    #include "../test-skeleton.c"

  13. #38
    Banned
    My Team
    San Antonio Spurs
    Join Date
    May 2012
    Post Count
    49,723
    nah, it's obvious you haven't studied the illegal drone program, or you choose to ignore it. Children and families are being terrorized and murdered. He's a terrorist. He's a war criminal. He's a mass child murderer. It's just a fact.

    In before the lie gets spewed about how they are all terrorists over there including kids and terrorists use kids as shields so it isn't our fault even though we are in illegal wars and shouldn't be there to begin with, etc blah blah blah..

    Ignorance
    Do you even know what a terrorist is? The president of the Uniteed States of America a terrorist, hahahahaha!!!!!!!!!! Dude, yank yor head out of your ass, ok?

  14. #39
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    #include <argp.h>
    #include <stdio.h>
    #include <stdlib.h>

    static struct argp_option argp_options[] = {
    { "dstaddr", 'd', "ADDR", 0,
    "set destination (peer) address to ADDR" },
    { "peer", 'p', "ADDR", OPTION_ALIAS },
    { NULL }
    };

    static error_t parse_opt (int key, char *arg, struct argp_state *state);

    static struct argp argp =
    {
    argp_options, parse_opt
    };

    static int cnt;

    static int
    do_test (int argc, char *argv[])
    {
    int remaining;
    argp_parse (&argp, argc, argv, 0, &remaining, NULL);
    return cnt != 4;
    }

    static error_t
    parse_opt (int key, char *arg, struct argp_state *state)
    {
    switch (key)
    {
    case 'd':
    case 'p':
    printf ("got '%c' with argument '%s'\n", key, arg);
    ++cnt;
    break;
    case 0:
    case ARGP_KEY_END:
    case ARGP_KEY_NO_ARGS:
    case ARGP_KEY_INIT:
    case ARGP_KEY_SUCCESS:
    case ARGP_KEY_FINI:
    // Ignore.
    return ARGP_ERR_UNKNOWN;
    default:
    printf ("invalid key '%x'\n", key);
    exit (1);
    }
    return 0;
    }

    #define TEST_FUNCTION do_test (argc, argv)
    #include "../test-skeleton.c"

  15. #40
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    # Copyright (C) 1997,2002,2003,2006,2007,2010,2012
    # Free Software Foundation, Inc.
    # This file is part of the GNU C Library.

    # The GNU C Library is free software; you can redistribute it and/or
    # modify it under the terms of the GNU Lesser General Public
    # License as published by the Free Software Foundation; either
    # version 2.1 of the License, or (at your option) any later version.

    # The GNU C Library is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    # Lesser General Public License for more details.

    # You should have received a copy of the GNU Lesser General Public
    # License along with the GNU C Library; if not, see
    # <http://www.gnu.org/licenses/>.

    #
    # Makefile for argp.
    #
    subdir := argp

    headers = argp.h
    routines = $(addprefix argp-, ba fmtstream fs-xinl help parse pv \
    pvh xinl eexst)

    tests = argp-test tst-argp1 bug-argp1 tst-argp2 bug-argp2

    CFLAGS-argp-help.c = $(uses-callbacks) -fexceptions
    CFLAGS-argp-parse.c = $(uses-callbacks)
    CFLAGS-argp-fmtstream.c = -fexceptions

    bug-argp1-ARGS = -- --help
    bug-argp2-ARGS = -- -d 111 --dstaddr 222 -p 333 --peer 444

    include ../Rules

  16. #41
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <[email protected]>, 2002.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    #include <argp.h>




    #define OPT_TO_THREAD 300
    #define OPT_TO_PROCESS 301
    #define OPT_SYNC_SIGNAL 302
    #define OPT_SYNC_JOIN 303
    #define OPT_TOPLEVEL 304


    static const struct argp_option test_options[] =
    {
    { NULL, 0, NULL, 0, "\
    This is a test for threads so we allow ther user to selection the number of \
    threads which are used at any one time. Independently the total number of \
    rounds can be selected. This is the total number of threads which will have \
    run when the process terminates:" },
    { "threads", 't', "NUMBER", 0, "Number of threads used at once" },
    { "starts", 's', "NUMBER", 0, "Total number of working threads" },
    { "toplevel", OPT_TOPLEVEL, "NUMBER", 0,
    "Number of toplevel threads which start the other threads; this \
    implies --sync-join" },

    { NULL, 0, NULL, 0, "\
    Each thread can do one of two things: sleep or do work. The latter is 100% \
    CPU bound. The work load is the probability a thread does work. All values \
    from zero to 100 (inclusive) are valid. How often each thread repeats this \
    can be determined by the number of rounds. The work cost determines how long \
    each work session (not sleeping) takes. If it is zero a thread would \
    effectively nothing. By setting the number of rounds to zero the thread \
    does no work at all and pure thread creation times can be measured." },
    { "workload", 'w', "PERCENT", 0, "Percentage of time spent working" },
    { "workcost", 'c', "NUMBER", 0,
    "Factor in the cost of each round of working" },
    { "rounds", 'r', "NUMBER", 0, "Number of rounds each thread runs" },

    { NULL, 0, NULL, 0, "\
    There are a number of different methods how thread creation can be \
    synchronized. Synchronization is necessary since the number of concurrently \
    running threads is limited." },
    { "sync-signal", OPT_SYNC_SIGNAL, NULL, 0,
    "Synchronize using a signal (default)" },
    { "sync-join", OPT_SYNC_JOIN, NULL, 0, "Synchronize using pthread_join" },

    { NULL, 0, NULL, 0, "\
    One parameter for each threads execution is the size of the stack. If this \
    parameter is not used the system's default stack size is used. If many \
    threads are used the stack size should be chosen quite small." },
    { "stacksize", 'S', "BYTES", 0, "Size of threads stack" },
    { "guardsize", 'g', "BYTES", 0,
    "Size of stack guard area; must fit into the stack" },

    { NULL, 0, NULL, 0, "Signal options:" },
    { "to-thread", OPT_TO_THREAD, NULL, 0, "Send signal to main thread" },
    { "to-process", OPT_TO_PROCESS, NULL, 0,
    "Send signal to process (default)" },

    { NULL, 0, NULL, 0, "Administrative options:" },
    { "progress", 'p', NULL, 0, "Show signs of progress" },
    { "timing", 'T', NULL, 0,
    "Measure time from startup to the last thread finishing" },
    { NULL, 0, NULL, 0, NULL }
    };

    /* Prototype for option handler. */
    static error_t parse_opt (int key, char *arg, struct argp_state *state);

    /* Data structure to communicate with argp functions. */
    static struct argp argp =
    {
    test_options, parse_opt
    };


    static int
    do_test (void)
    {
    int argc = 2;
    char *argv[3] = { (char *) "tst-argp1", (char *) "--help", NULL };
    int remaining;

    /* Parse and process arguments. */
    argp_parse (&argp, argc, argv, 0, &remaining, NULL);

    return 0;
    }


    /* Handle program arguments. */
    static error_t
    parse_opt (int key, char *arg, struct argp_state *state)
    {
    return ARGP_ERR_UNKNOWN;
    }

    #define TEST_FUNCTION do_test ()
    #include "../test-skeleton.c"

  17. #42
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Copyright (C) 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <[email protected]>, 2007.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    #include <argp.h>

    static const struct argp_option opt1[] =
    {
    { "opt1", '1', "NUMBER", 0, "Option 1" },
    { NULL, 0, NULL, 0, NULL }
    };

    static const struct argp_option opt2[] =
    {
    { "opt2", '2', "NUMBER", 0, "Option 2" },
    { NULL, 0, NULL, 0, NULL }
    };

    static const struct argp_option opt3[] =
    {
    { "opt3", '3', "NUMBER", 0, "Option 3" },
    { NULL, 0, NULL, 0, NULL }
    };

    static const struct argp_option opt4[] =
    {
    { "opt4", '4', "NUMBER", 0, "Option 4" },
    { NULL, 0, NULL, 0, NULL }
    };

    static const struct argp_option opt5[] =
    {
    { "opt5", '5', "NUMBER", 0, "Option 5" },
    { NULL, 0, NULL, 0, NULL }
    };

    static struct argp argp5 =
    {
    opt5, NULL, "args doc5", "doc5", NULL, NULL, NULL
    };

    static struct argp argp4 =
    {
    opt4, NULL, "args doc4", "doc4", NULL, NULL, NULL
    };

    static struct argp argp3 =
    {
    opt3, NULL, "args doc3", "doc3", NULL, NULL, NULL
    };

    static struct argp_child children2[] =
    {
    { &argp4, 0, "child3", 3 },
    { &argp5, 0, "child4", 4 },
    { NULL, 0, NULL, 0 }
    };

    static struct argp argp2 =
    {
    opt2, NULL, "args doc2", "doc2", children2, NULL, NULL
    };

    static struct argp_child children1[] =
    {
    { &argp2, 0, "child1", 1 },
    { &argp3, 0, "child2", 2 },
    { NULL, 0, NULL, 0 }
    };

    static struct argp argp1 =
    {
    opt1, NULL, "args doc1", "doc1", children1, NULL, NULL
    };


    static int
    do_test (void)
    {
    argp_help (&argp1, stdout, ARGP_HELP_LONG, (char *) "tst-argp2");
    return 0;
    }


    #define TEST_FUNCTION do_test ()
    #include "../test-skeleton.c"

  18. #43
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    libc {
    GLIBC_2.1 {
    # variables in normal name space
    argp_err_exit_status; argp_program_bug_address; argp_program_version;
    argp_program_version_hook;

    # a*
    argp_error; argp_failure; argp_help; argp_parse; argp_state_help;
    argp_usage;
    }
    }

  19. #44
    Banned
    My Team
    San Antonio Spurs
    Join Date
    May 2012
    Post Count
    49,723
    Mental re ation and the internet, not a good combo.

  20. #45
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Copyright (C) 1991-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    #include <assert.h>
    #include <atomic.h>
    #include <ldsodefs.h>
    #include <libintl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sysdep.h>
    #include <unistd.h>
    #include <sys/mman.h>


    extern const char *__progname;

    #include <wchar.h>
    #include <libio/iolibio.h>
    #define fflush(s) _IO_fflush (s)

    /* This function, when passed a string containing an asserted
    expression, a filename, and a line number, prints a message
    on the standard error stream of the form:
    a.c:10: foobar: Assertion `a == b' failed.
    It then aborts program execution via a call to `abort'. */

    #ifdef FATAL_PREPARE_INCLUDE
    # include FATAL_PREPARE_INCLUDE
    #endif


    void
    __assert_fail_base (const char *fmt, const char *assertion, const char *file,
    unsigned int line, const char *function)
    {
    char *str;

    #ifdef FATAL_PREPARE
    FATAL_PREPARE;
    #endif

    int total;
    if (__asprintf (&str, fmt,
    __progname, __progname[0] ? ": " : "",
    file, line,
    function ? function : "", function ? ": " : "",
    assertion, &total) >= 0)
    {
    /* Print the message. */
    (void) __fxprintf (NULL, "%s", str);
    (void) fflush (stderr);

    total = (total + 1 + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1);
    struct abort_msg_s *buf = __mmap (NULL, total, PROT_READ | PROT_WRITE,
    MAP_ANON | MAP_PRIVATE, -1, 0);
    if (__builtin_expect (buf != MAP_FAILED, 1))
    {
    buf->size = total;
    strcpy (buf->msg, str);

    /* We have to free the old buffer since the application might
    catch the SIGABRT signal. */
    struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg, buf);

    if (old != NULL)
    __munmap (old, old->size);
    }

    free (str);
    }
    else
    {
    /* At least print a minimal message. */
    static const char errstr[] = "Unexpected error.\n";
    __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
    }

    abort ();
    }


    #undef __assert_fail
    void
    __assert_fail (const char *assertion, const char *file, unsigned int line,
    const char *function)
    {
    __assert_fail_base (_("%s%s%s:%u: %s%sAssertion `%s' failed.\n%n"),
    assertion, file, line, function);
    }
    hidden_def(__assert_fail)

  21. #46
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Copyright (C) 1991,1992,1994-2001,2003,2004,2007,2011,2012
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    /*
    * ISO C99 Standard: 7.2 Diagnostics <assert.h>
    */

    #ifdef _ASSERT_H

    # undef _ASSERT_H
    # undef assert
    # undef __ASSERT_VOID_CAST

    # ifdef __USE_GNU
    # undef assert_perror
    # endif

    #endif /* assert.h */

    #define _ASSERT_H 1
    #include <features.h>

    #if defined __cplusplus && __GNUC_PREREQ (2,95)
    # define __ASSERT_VOID_CAST static_cast<void>
    #else
    # define __ASSERT_VOID_CAST (void)
    #endif

    /* void assert (int expression);

    If NDEBUG is defined, do nothing.
    If not, and EXPRESSION is zero, print an error message and abort. */

    #ifdef NDEBUG

    # define assert(expr) (__ASSERT_VOID_CAST (0))

    /* void assert_perror (int errnum);

    If NDEBUG is defined, do nothing. If not, and ERRNUM is not zero, print an
    error message with the error text for ERRNUM and abort.
    (This is a GNU extension.) */

    # ifdef __USE_GNU
    # define assert_perror(errnum) (__ASSERT_VOID_CAST (0))
    # endif

    #else /* Not NDEBUG. */

    __BEGIN_DECLS

    /* This prints an "Assertion failed" message and aborts. */
    extern void __assert_fail (const char *__assertion, const char *__file,
    unsigned int __line, const char *__function)
    __THROW __attribute__ ((__noreturn__));

    /* Likewise, but prints the error text for ERRNUM. */
    extern void __assert_perror_fail (int __errnum, const char *__file,
    unsigned int __line, const char *__function)
    __THROW __attribute__ ((__noreturn__));


    /* The following is not at all used here but needed for standard
    compliance. */
    extern void __assert (const char *__assertion, const char *__file, int __line)
    __THROW __attribute__ ((__noreturn__));


    __END_DECLS

    # define assert(expr) \
    ((expr) \
    ? __ASSERT_VOID_CAST (0) \
    : __assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION))

    # ifdef __USE_GNU
    # define assert_perror(errnum) \
    (!(errnum) \
    ? __ASSERT_VOID_CAST (0) \
    : __assert_perror_fail ((errnum), __FILE__, __LINE__, __ASSERT_FUNCTION))
    # endif

    /* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
    which contains the name of the function currently being defined.
    This is broken in G++ before version 2.6.
    C9x has a similar variable called __func__, but prefer the GCC one since
    it demangles C++ function names. */
    # if defined __cplusplus ? __GNUC_PREREQ (2, 6) : __GNUC_PREREQ (2, 4)
    # define __ASSERT_FUNCTION __PRETTY_FUNCTION__
    # else
    # if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
    # define __ASSERT_FUNCTION __func__
    # else
    # define __ASSERT_FUNCTION ((const char *) 0)
    # endif
    # endif

    #endif /* NDEBUG. */


    #if defined __USE_ISOC11 && !defined __cplusplus
    /* Static assertion. Requires support in the compiler. */
    # undef static_assert
    # define static_assert _Static_assert
    #endif

  22. #47
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    /* We have to see the prototype. */
    #undef NDEBUG
    #include <assert.h>

    void
    __assert (const char *assertion, const char *file, int line)
    {
    __assert_fail (assertion, file, line, (const char *) 0);
    }

  23. #48
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    /* Copyright (C) 1994-1998,2001,2002,2005,2009,2011
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.

    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>. */

    #include <assert.h>
    #include <libintl.h>
    #include <string.h>


    /* This function, when passed an error number, a filename, and a line
    number, prints a message on the standard error stream of the form:
    a.c:10: foobar: Unexpected error: Computer bought the farm
    It then aborts program execution via a call to `abort'. */
    void
    __assert_perror_fail (int errnum,
    const char *file, unsigned int line,
    const char *function)
    {
    char errbuf[1024];

    char *e = __strerror_r (errnum, errbuf, sizeof errbuf);
    __assert_fail_base (_("%s%s%s:%u: %s%sUnexpected error: %s.\n"),
    e, file, line, function);
    }
    libc_hidden_def (__assert_perror_fail)

  24. #49
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    iconvdata
    localedata

  25. #50
    俺はまんこが大好きなんだよ baseline bum's Avatar
    My Team
    San Antonio Spurs
    Join Date
    Mar 2003
    Post Count
    97,881
    # Copyright (C) 1991, 1994, 1997, 1998, 2000 Free Software Foundation, Inc.
    # This file is part of the GNU C Library.

    # The GNU C Library is free software; you can redistribute it and/or
    # modify it under the terms of the GNU Lesser General Public
    # License as published by the Free Software Foundation; either
    # version 2.1 of the License, or (at your option) any later version.

    # The GNU C Library is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    # Lesser General Public License for more details.

    # You should have received a copy of the GNU Lesser General Public
    # License along with the GNU C Library; if not, see
    # <http://www.gnu.org/licenses/>.

    #
    # Sub-makefile for assert portion of the library.
    #
    subdir := assert
    headers := assert.h

    routines := assert assert-perr __assert
    tests := test-assert test-assert-perr

    include ../Rules

    test-assert-ENV = LANGUAGE=C
    test-assert-perr-ENV = LANGUAGE=C

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •