2.11 Formatting Help

Many programs have a -h or --help option which prints out a short message describing how to use the program. Mu supports automatically generating a usage message through the use of the help and arg_help fields of the MU_OPT structure (see Option Structure).

Function: void mu_opt_context_add_help (MU_OPT_CONTEXT *context, const char *usage, const char *short_description, const char *description, const char *notes, const char *section, const char *section_name, const char *source, const char *date)

Add usage information to context. The arguments are as follows:

usage

This is a short, human-readable description of the arguments your program takes. For example, ‘[OPTION]… [FILE]…’. If usage is left NULL, it will default to ‘[OPTION]…’ if there is a least one option in options or, if options is empty, it will default to ‘’ (the empty string). If you really want nothing to be printed for usage, pass ‘’ (the empty string) explicitly.

Alternative usages (including no arguments) can be specified, separated by newlines. For example, if your program is called prog and you pass a usage of ‘FOO\nBAR\n\nBAZ’ (note the two ‘\n’s after ‘BAR’), the help output will be as follows:

Usage: prog FOO
  or:  prog BAR
  or:  prog
  or:  prog BAZ
[...]

You can think of it as piping usage to

sed '1s/^/Usage: prog /; 2,/^/  or:  prog /'

(assuming your program is called prog).

short_description

This is a very short description (shorter than description) of the program. It is used as the description in the NAME section.

If this parameter is passed as NULL, a default will be substituted. This parameter is only used for man page output.

description

This is a short, human-readable description of whatever your program does. It is printed right below the usage line. It should be one or two sentences long. For example:

Frobnicate frobs. Nonexistent frobs will be treated as empty.

You may reference metasyntactic variables specified in usage here (e.g., ‘FILE’) if you like. If you set this to NULL, no description will be printed.

Note: you should not write

Mandatory arguments to long options are mandatory for short options too.

in description. This will automatically be added to the help text if it makes sense (i.e., if there exist long options with required arguments that have short option equivalents).

notes

This will be printed at the end of the help message, after the options. This is where you can put examples, bug report addresses, etc.

section

The section number of the manual page. This can be any string (but see section_name below), although it should be a number followed by an optional suffix. The optional suffix can be something like ncurses uses for its man pages, ‘NCURSES’ (so the full section would be ‘3NCURSES’). Most likely you should just set this to a number.

This parameter must not be NULL, unless man page output is not being used. This parameter is only used for man page output.

section_name

This is the name of the manual section. For example, ‘User Commands’.

If this parameter is passed as NULL, a default will be chosen based on section. In this case, section must start with a number between 1 and 9 inclusive except for 7. Section 7 does not have a default name because it is more of a “miscellaneous” section, and thus you must provide the name yourself.

This parameter is only used for man page output.

source

This is the “source” of your program. If your program is part of a suite, put the name and version of the suite here. Otherwise, put the name and version of your program here.

If this parameter is passed as NULL (not recommended), the name your program was invoked as will be used. This parameter is only used for man page output.

date

This is the date that the help text was last updated. Update date every time you change the help text for any option, or you change the name of an option or add a new one. You need not update this for trivial changes.

The format for date is conventionally ‘YYYY-MM-DD’.

If this parameter is passed as NULL (not recommended), the date at which your program was run to generate the man page will be used instead. Note that the date parameter is passed as NULL in the examples for simplicity, but this is still not recommended.

This parameter is only used for man page output.

Function: int mu_opt_context_add_help_options (MU_OPT_CONTEXT *context, int flags)

Add help options to context based on flags. If MU_HELP_PREPEND is present in flags, the help options will be prepended to the current options, i.e., inserted before them. Othewise, if MU_HELP_PREPEND is not present in flags, the help options will be appended to the current options, i.e., inserted after them.

flags tells mu_opt_context_add_help_options what kind of help options/environment variables should be created, in addition to whether it should append or prepend the help options. The following values may be passed in flags, and can be combined with | (bitwise OR).

MU_HELP_PREPEND

This indicates that mu_opt_context_add_help_options should add the help options before the current options, rather than after. Note that order of the help options themselves is unchanged.

MU_HELP_SHORT
MU_HELP_LONG
MU_HELP_QUESTION_MARK

These flags tell mu_opt_context_add_help_options to create an option which takes a single optional argument, format. MU_HELP_SHORT will create a short option, -h, while MU_HELP_LONG will create a long option, --help, and MU_HELP_QUESTION_MARK will create a short option, -?. format specifies the output format to use when outputting help. It can either be ‘man’ to output in a format which can be parsed by the man program, or it can be ‘plain’ or ‘text’ to output in a human-readable, plain-text format.

If format is omitted, it will default to the value of the MU_HELP_FORMAT environment variable if MU_HELP_ENV is passed in flags. Otherwise, if the MU_HELP_FORMAT environment variable is not set or does not have a value or MU_HELP_ENV was not passed in flags, format will default to ‘plain’.

Note: MU_HELP_QUESTION_MARK is not included in MU_HELP_ALL (see below). If you want to pass all flags including MU_HELP_QUESTION_MARK, you must pass it explicitly, like so: MU_HELP_ALL | MU_HELP_QUESTION_MARK.

MU_HELP_MAN_SHORT
MU_HELP_MAN_LONG

These flags tell mu_opt_context_add_help_options to create an option which takes no argument, and always outputs help in man format. MU_HELP_MAN_SHORT will create a short option, -m, while MU_HELP_MAN_LONG will create a long option, --man.

MU_HELP_ENV

This flag tells mu_opt_context_add_help_options to create an environment variable, MU_HELP_FORMAT, which will specify an output format to use if none was specified to -h or --help. You must only use this flag if MU_HELP_SHORT or MU_HELP_LONG was also passed in flags.

MU_HELP_BOTH

Equivalent to MU_HELP_SHORT | MU_HELP_LONG.

MU_HELP_MAN_BOTH

Equivalent to MU_HELP_MAN_SHORT | MU_HELP_MAN_LONG.

MU_HELP_ALL

Equivalent to passing all flags except for MU_HELP_QUESTION_MARK, i.e., MU_HELP_BOTH | MU_HELP_MAN_BOTH | MU_HELP_ENV.

Output formatted for the man program will be piped to man if standard output is a terminal (as determined by isatty), otherwise the raw roff code will be output to standard output. If standard output is a terminal but an error occurred while executing the man program, a warning message will be printed and the raw roff code will be output to standard output as if standard output was not a terminal.

Note: some systems may not provide the necessary functionality to run the man command. In that case, roff code will always be output, regardless of whether standard output is a terminal.

Function: int mu_format_help (FILE *stream, const MU_OPT_CONTEXT *context)
Function: int mu_format_help_man (FILE *stream, const MU_OPT_CONTEXT *context)

These functions format a help message, printing it to stream. If you’d like to automatically create a help option that does this, see mu_opt_context_add_help_options above. You might also want to call these functions manually, for example, if your program receives no arguments or if mu_parse_opts returns an error code (see Parsing Options and Environment and Option Parsing Errors).

mu_format_help will output a human-readable, plain text message, while mu_format_help_man will output roff code.

The strings passed to mu_opt_context_add_help are used in the help message, as well as the options in context.

Function: char * mu_format_help_string (const MU_OPT_CONTEXT *context, unsigned short goal, unsigned short width)
Function: char * mu_format_help_man_string (const MU_OPT_CONTEXT *context)

These functions are like mu_format_help and mu_format_help_man respectively (see above), except that they return the output as a string rather than printing it. If an error occurs, NULL will be returned and errno will be set to indicate the error. If the returned string is not NULL, it will by dynamically allocated and must be freed when you are done with it (see (libc)Freeing after Malloc).

Unlike mu_format_help, mu_format_help_string is unable to determine the goal and width to use, so you must specify these parameters yourself. See Formatting Text for the meanings of goal and width.

You should provide help text for individual options in the help and arg_help fields of the MU_OPT structure (see Option Structure).

arg_help is similar to the usage parameter to mu_format_help. It should be a simple string describing the kind of arguments the option takes. For example, you might write ‘FILE’ if your option takes a file argument, or ‘WxH’ if it takes a width and height argument, separated by an ‘x’. If this is left as NULL, a default will be chosen based on the type of argument your option takes, specified in the arg_type field of the MU_OPT structure.

Note: you should not use ‘[’ and ‘]’ in the arg_help string. The arg_help string will automatically be enclosed in ‘[’ and ‘]’ if the option takes an optional argument.

help is a short description of what the option does. Most GNU utilities use a single sentence, begun with a lowercase letter8 and ended without a period. However, you can format help however you like, but keep in mind that it should be fairly short. One sentence or, if you really must, two.

If the help field is left as NULL, the corresponding option will remain undocumented as if it did not exist. See Option Structure for more information.

Below is an example illustrating the usage of both mu_opt_context_add_help_options and mu_format_help. Note that the category field is used to denote option categories (see Option Structure).

#include <stdio.h>
#include <stdlib.h>
#include <mu/options.h>
#include <mu/compat.h>          /* For __attribute__() */
#include <mu/safe.h>            /* For mu_opt_context_x* */

__attribute__((noreturn))
int print_version(void *data, char *err) {
  puts("Version 1.0");
  exit(0);
}

int main(int argc, char **argv) {
  int ret;
  const MU_OPT opts_start[] = {
    {
     .short_opt = "n",
     .long_opt  = "none",
     .has_arg   = MU_OPT_NONE,
     .help      = "an option which takes no argument"
    },
    { .category = "Options taking arguments" },
    {
     .short_opt = "o",
     .long_opt  = "optional",
     .has_arg   = MU_OPT_OPTIONAL,
     .arg_type  = MU_OPT_STRING,
     .arg_help  = "OPTARG",
     .help      = "an option which optionally takes an argument"
    },
    {
     .short_opt = "r",
     .long_opt  = "required",
     .has_arg   = MU_OPT_REQUIRED,
     .arg_type  = MU_OPT_STRING,
     .arg_help  = "REQARG",
     .help      = "an option which requires an argument"
    },
    { .category = "Help options and environment variables" },
    { 0 }
  };
  /* Options to add after the help options. */
  const MU_OPT opts_end[] = {
    { .category = "Version information" },
    {
     .short_opt = "v",
     .long_opt  = "version",
     .has_arg   = MU_OPT_NONE,
     .callback_none = print_version,
     .help      = "print version information and exit"
    },
    { 0 }
  };
  MU_OPT_CONTEXT *context;

  context = mu_opt_context_xnew(argc, argv, opts_start,
                                MU_OPT_BUNDLE | MU_OPT_PERMUTE);

  /* Add the help data. */
  mu_opt_context_add_help(context, "[OPTION]...", "do stuff",
                          "Do stuff. If this text is really long, it "
                          "will be wrapped. Some more text to make "
                          "this text long enough to be wrapped.",
                          "Report bugs to <libmu-bug@nongnu.org>.",
                          "1", NULL, "Mu Examples", NULL);
  /* Create the help option. MU_HELP_ALL is equivalent to
     MU_HELP_SHORT | MU_HELP_LONG | MU_HELP_MAN_SHORT |
     MU_HELP_MAN_LONG | MU_HELP_ENV, so it will create the options
     '-h', '--help', '-m', and '--man', and it will create the
     environment variable 'MU_HELP_FORMAT'. */
  mu_opt_context_xadd_help_options(context, MU_HELP_ALL);
  /* Add the other options. */
  mu_opt_context_xadd_options(context, opts_end, MU_OPT_APPEND);

  /* Parse the options. */
  ret = mu_parse_opts(context);

  /* If there was an option parsing error, print a usage message so
     the user knows how to use us properly. */
  if (ret == MU_OPT_ERR_PARSE)
    mu_format_help(stderr, context);

  mu_opt_context_xfree(context);

  return !!MU_OPT_ERR(ret);
}

This is what the output looks like (note, the COLUMNS environment variable is set to 65 so that the output will look good in this manual):

$ COLUMNS=65
$ export COLUMNS
$ ./option-help --help
-| Usage: ./option-help [OPTION]...
-| Do stuff. If this text is really long, it will be wrapped. Some more text to make this text long
-| enough to be wrapped.
-|  
-| Mandatory arguments to long options are mandatory for short options too.
-|   -n, --none                  an option which takes no argument
-|  
-| Options taking arguments:
-|   -o, --optional[=OPTARG]     an option which optionally takes an argument
-|   -r, --required=REQARG       an option which requires an argument
-|  
-| Help options and environment variables:
-|   -h, --help[=plain|man]      print this help in plain text format if 'plain', or as a man(1) page
-|                                 if 'man'; if the argument is omitted, it will default to the value
-|                                 of the MU_HELP_FORMAT environment variable if set, otherwise
-|                                 'plain'.
-|   -m, --man                   print this help as a man(1) page
-|  
-| Version information:
-|   -v, --version               print version information and exit
-|  
-| ENVIRONMENT
-|  
-| Help options and environment variables:
-|   MU_HELP_FORMAT[=plain|man]  the default format for -h, --help
-|  
-| Report bugs to <libmu-bug@nongnu.org>.
$ ./option-help --foo
error→ ./option-help: '--foo': invalid option
error→ Usage: ./option-help [OPTION]...
error→ Do stuff. If this text is really long, it will be wrapped. Some more text to make this text long
error→ enough to be wrapped.
error→  
error→ Mandatory arguments to long options are mandatory for short options too.
error→   -n, --none                  an option which takes no argument
error→  
error→ Options taking arguments:
error→   -o, --optional[=OPTARG]     an option which optionally takes an argument
error→   -r, --required=REQARG       an option which requires an argument
error→  
error→ Help options and environment variables:
error→   -h, --help[=plain|man]      print this help in plain text format if 'plain', or as a man(1) page
error→                                 if 'man'; if the argument is omitted, it will default to the value
error→                                 of the MU_HELP_FORMAT environment variable if set, otherwise
error→                                 'plain'.
error→   -m, --man                   print this help as a man(1) page
error→  
error→ Version information:
error→   -v, --version               print version information and exit
error→  
error→ ENVIRONMENT
error→  
error→ Help options and environment variables:
error→   MU_HELP_FORMAT[=plain|man]  the default format for -h, --help
error→  
error→ Report bugs to <libmu-bug@nongnu.org>.

Footnotes

(8)

Unless it should be uppercase for another reason, for example a proper noun or acronym.