Logo Search packages:      
Sourcecode: t1utils version File versions  Download package

int Clp_Next ( Clp_Parser clp  ) 

Parse and return the next argument from clp.

clp the parser
option ID of next option
Parse the next argument from the argument list, store information about that argument in the fields of clp, and return the option's ID.

If an argument was successfully parsed, that option's ID is returned. Other possible return values are:

There are no more arguments.
The next argument was not an option. The argument's text is clp->vstr (and clp->val.s).
The next argument was a bad option: either an option that wasn't understood, or an option lacking a required value, or an option whose value couldn't be parsed. The option has been skipped.
There was an internal error. This should never occur unless a user messes with, for example, a Clp_Option array.

The fields of clp are set as follows.

1 if the option was negated, 0 if it wasn't.
1 if the option had a value, 0 if it didn't. Note that negated options are not allowed to have values.
The value string, if any. NULL if there was no value.
An option's value type will parse the value string into this union.

The parsed argument is shifted off the argument list, so that sequential calls to Clp_Next() step through the arugment list.

Definition at line 1803 of file clp.c.

References Clp_BadOption, Clp_DisallowOptions, Clp_Done, Clp_Error, Clp_NotOption, Clp_Parser::have_val, Clp_Parser::internal, Clp_Parser::negated, Clp_Option::option_id, Clp_Parser::s, Clp_Parser::val, Clp_Option::val_type, and Clp_Parser::vstr.

    Clp_Internal *cli = clp->internal;
    int optno;
    const Clp_Option *opt;
    Clp_ParserState clpsave;
    int vtpos, complain;

    /* Set up clp */
    cli->current_option = -1;
    cli->ambiguous = 0;

    /* Get the next argument or option */
    if (!next_argument(clp, cli->option_processing ? 0 : 2)) {
      clp->val.s = clp->vstr;
      return clp->have_val ? Clp_NotOption : Clp_Done;

    clp->negated = cli->whole_negated;
    if (cli->is_short)
      optno = find_short(clp, cli->xtext);
      optno = find_long(clp, cli->xtext);

    /* If there's ambiguity between long & short options, and we couldn't
       find a long option, look for a short option */
    if (optno < 0 && cli->could_be_short) {
      optno = find_short(clp, cli->xtext);

    /* If we didn't find an option... */
    if (optno < 0 || (clp->negated && !cli->iopt[optno].ineg)) {
      /* default processing for the "--" option: turn off option processing
         and return the next argument */
      if (strcmp(cli->argv[0], "--") == 0) {
          Clp_SetOptionProcessing(clp, 0);
          return Clp_Next(clp);

      /* otherwise, report some error or other */
      if (cli->ambiguous)
          ambiguity_error(clp, cli->ambiguous, cli->ambiguous_values,
                      cli->opt, cli->iopt, cli->option_chars,
                      "option %`%s%s%' is ambiguous",
                      cli->option_chars, cli->xtext);
      else if (cli->is_short && !cli->could_be_short)
          Clp_OptionError(clp, "unrecognized option %`%s%C%'",
                      cli->option_chars, cli->xtext);
          Clp_OptionError(clp, "unrecognized option %`%s%s%'",
                      cli->option_chars, cli->xtext);

      return Clp_BadOption;

    /* Set the current option */
    cli->current_option = optno;
    cli->current_short = cli->is_short;
    cli->negated_by_no = clp->negated && !cli->whole_negated;

    /* The no-argument (or should-have-no-argument) case */
    if (clp->negated
      || (!cli->iopt[optno].imandatory && !cli->iopt[optno].ioptional)) {
      if (clp->have_val) {
          Clp_OptionError(clp, "%`%O%' can't take an argument");
          return Clp_BadOption;
      } else
          return cli->opt[optno].option_id;

    /* Get an argument if we need one, or if it's optional */
    /* Sanity-check the argument type. */
    opt = &cli->opt[optno];
    if (opt->val_type <= 0)
      return Clp_Error;
    vtpos = val_type_binsearch(cli, opt->val_type);
    if (vtpos == cli->nvaltype || cli->valtype[vtpos].val_type != opt->val_type)
      return Clp_Error;

    /* complain == 1 only if the argument was explicitly given,
       or it is mandatory. */
    complain = (clp->have_val != 0) || cli->iopt[optno].imandatory;
    Clp_SaveParser(clp, &clpsave);

    if (cli->iopt[optno].imandatory && !clp->have_val) {
      /* Mandatory argument case */
      /* Allow arguments to options to start with a dash, but only if the
         argument type allows it by not setting Clp_DisallowOptions */
      int disallow = (cli->valtype[vtpos].flags & Clp_DisallowOptions) != 0;
      next_argument(clp, disallow ? 1 : 2);
      if (!clp->have_val) {
          int got_option = cli->xtext != 0;
          Clp_RestoreParser(clp, &clpsave);
          if (got_option)
            Clp_OptionError(clp, "%`%O%' requires a non-option argument");
            Clp_OptionError(clp, "%`%O%' requires an argument");
          return Clp_BadOption;

    } else if (cli->is_short && !clp->have_val
             && cli->xtext[clp_utf8_charlen(cli, cli->xtext)])
      /* The -[option]argument case:
         Assume that the rest of the current string is the argument. */
      next_argument(clp, 1);

    /* Parse the argument */
    if (clp->have_val) {
      Clp_ValType *atr = &cli->valtype[vtpos];
      if (atr->func(clp, clp->vstr, complain, atr->user_data) <= 0) {
          /* parser failed */
          clp->have_val = 0;
          if (cli->iopt[optno].imandatory)
            return Clp_BadOption;
            Clp_RestoreParser(clp, &clpsave);

    return opt->option_id;

Generated by  Doxygen 1.6.0   Back to index