2.3.1 Negation Prefixes

By default, long options and suboptions are negated by prefixing them with ‘no-’ (see Negatable Options). However, alternative negation prefixes may be specified as well. For example, you might want to parse options in a similar style to XBoard, with options negated by a single ‘x’ (see (xboard)Options).

Negation prefixes, like regular options, are case sensitive. Thus, if you have a negation prefix of ‘no-’, ‘No-’ will not be recognized (or will be treated as a separate option).

Function: int mu_opt_context_set_no_prefixes (MU_OPT_CONTEXT *context, …)
Function: int mu_opt_context_set_no_prefix_array (MU_OPT_CONTEXT *context, char **strings)
Function: int mu_subopt_context_set_no_prefixes (MU_SUBOPT_CONTEXT *context, …)
Function: int mu_subopt_context_set_no_prefix_array (MU_SUBOPT_CONTEXT *context, char **strings)

Set a list of negation prefixes in context. In the case of mu_opt_context_set_no_prefixes and mu_subopt_context_set_no_prefixes, the negation prefixes are specified in the variable arguments. In the case of mu_opt_context_set_no_prefix_array and mu_subopt_context_set_no_prefix_array, the negation prefixes are specified in strings. In both cases, the list of negation prefixes must be terminated by NULL.

Duplicate negation prefixes are not allowed. If duplicates are present in strings or the variable arguments, errno will be set to EINVAL and these functions will return nonzero.

Subsequent calls to these functions are allowed, but will overwrite negation prefixes set by previous calls. However, it is not allowed to call these functions after context has been passed to mu_parse_opts or mu_parse_subopts.

Here is an example of how alternative negation prefixes may be used:

#include <stdio.h>
#include <mu/options.h>
#include <mu/safe.h>            /* For mu_opt_context_x* */

/* Print a message when we find the negatable option. */
static int print_negatable(int value, void *data, char *err) {
  printf("    Found the negatable option, and it was%s negated.\n",
         value ? " not" : "");
  return 0;
}

int main(int argc, char **argv) {
  int ret;
  const MU_OPT options[] = {
    {
     .short_opt          = "n",
     .long_opt           = "negatable",
     .has_arg            = MU_OPT_NONE,
     .negatable          = 1,
     .callback_negatable = print_negatable
    },
    { 0 }
  };
  MU_OPT_CONTEXT *context;

  context = mu_opt_context_xnew(argc, argv, options, MU_OPT_PERMUTE);

  /* Set the negation prefixes. This must be done *before*
     mu_parse_opts() is called. */
  mu_opt_context_xset_no_prefixes(context, "negate-", "no-", "x", NULL);

  /* Now parse the options. */
  ret = mu_parse_opts(context);
  mu_opt_context_xfree(context);
  if (MU_OPT_ERR(ret))
    return 1;

  return 0;
}

And the output:

$ ./negation-prefixes --negatable
-|     Found the negatable option, and it was not negated.
$ ./negation-prefixes --negate-negatable
-|     Found the negatable option, and it was negated.
$ ./negation-prefixes --no-negatable
-|     Found the negatable option, and it was negated.
$ ./negation-prefixes --xnegatable
-|     Found the negatable option, and it was negated.
$ ./negation-prefixes --foo-negatable
error→ ./negation-prefixes: '--foo-negatable': invalid option