Skip to content
Dmitry Lavnikevich edited this page Aug 29, 2014 · 4 revisions

Extopts allows to create convinient CLI. This page presents its key features.

For thorough description of extopts functionality please see [[https://github.com/githaff/extopts/wiki/api][API]] page. Working example of most of library capabilities can be found within [[https://github.com/githaff/extopts/tree/master/src/example][source tree]].

Command line arguments parsing

Minimal arguments parsing example:

#include <stdio.h>
#include <extopts/extopts.h>


int opts_int = 31;
const char *opts_str = NULL;
bool opts_flag = false;

struct extopt opts[] = {
	{
		.name_long = "str",
		EXTOPT_ARG_STR("STR", &opts_str),
		.desc = "some string argument",
	}, {
		.name_long = "int",
		.name_short = 'i',
		EXTOPT_ARG_INT("INT", &opts_int),
		.desc = "some int argument",
	}, {
		.name_short = 'f',
		EXTOPT_NO_ARG(&opts_flag),
		.desc = "some boolean argument option",
	},
	EXTOPTS_END
};

int main(int argc, char *argv[])
{
	if (extopts_get(&argc, argv, opts))
		return 1;

	printf("Configured options:\n");
	printf("  integer: %d\n", opts_int);
	printf("  string: \"%s\"\n", opts_str ? opts_str : "-empty-");
	printf("  flag: %s\n", opts_flag ? "set" : "unset");

	return 0;
}

So the main idea is to declare (statically or dynamically) extopts structures array with description of command line arguments. The only condition is that this array should be terminated with EXTOPTS_END extopt structure.

In the example above there are two arguments implemented. In case -i 42 will be specified within command line arguments 42 will be stored in opts_int. Otherwise it will keep its default value 31. By analogy --str "Hello Extopts" will store pointer to argument "Hello Extopts" into opts_str. Boolean argument -f does not have parameter and the only information about whether it is present in command line will be written into boolean variable opts_flag.

Note: if flag option will not present in command line then it will keep default value, which is not necessarily false.

For readability sake EXTOPT_ARG_* macros can be used to substitude some extopt structure fields depending on argument type. Of course, manual structures configuration is also possible, but standard macro definitions should cover pretty much every useful case. For more info on argument types see API reference.

Remaining extopt structure fields that should or can be filled by user are:

  • char *name_long - argument long name (e.g. "--help");
  • char name_short - argument short name (e.g. "-h");
  • char *desc - argument description which should be used in usage autogeneration (see below).

Unlike with getopts library, with extopts you should not implement logic for parsing command line. Arguments will be parsed and stored in specified variables according to arguments description. To perform it function extopts_get() should be used. In case of parsing error it will return non-zero code and print error message to stderr.

Note: Extopts understands only arguments with or without parameter. Optional parameters are too rarely used and usualy bring undesirable complexity into usage, so this concept was dropped in extopts.

Note: extopts_get() call will rearrange argv command line arguments and change argc value. For details see extopts_get.

Apart from mentioned earlier structure filling macros EXTOPT_ARG_* extopts also presents additional macros implementing most commonly used command line arguments like --help or --version:

...
bool opts_help;
bool opts_version;

struct extopt opts[] = {
	{
		.name_long = "str",
		EXTOPT_ARG_STR("STR", &opts_str),
		.desc = "some string argument",
	}, {
		.name_long = "int",
		.name_short = 'i',
		EXTOPT_ARG_INT("INT", &opts_int),
		.desc = "some int argument",
	}, {
		.name_short = 'f',
		EXTOPT_NO_ARG(&opts_flag),
		.desc = "some boolean argument option",
	},
	EXTOPTS_HELP(&opts_help),
	EXTOPTS_VERSION(&opts_version),
	EXTOPTS_END
};

This will create options

-h, --help   print this help and exit
--version   print version information and exit

which are in fact just boolean arguments (EXTOPT_NO_ARG) with specified short, long names and description.

Usage autogeneration

One of main features of extopt library is usage autogeneration. This allows you to print aligned usage info into stdout stream based on info in extopt description structures.

All info required for usage generation is presented with fields name_long, name_short, desc, arg_name struct extopt.

Usage print can be preformed with call extopts_usage().

Simple example:

#include <stdio.h>
#include <extopts/extopts.h>


int opts_int = 31;
const char *opts_str = NULL;
bool opts_flag = false;

struct extopt opts[] = {
	{
		.name_long = "str",
		EXTOPT_ARG_STR("STR", &opts_str),
		.desc = "some string argument",
	}, {
		.name_long = "int",
		.name_short = 'i',
		EXTOPT_ARG_INT("INT", &opts_int),
		.desc = "some int argument plus really long description "
		"which probably will be aligned and sliced into separate "
		"lines during usage generation",
	}, {
		.name_short = 'f',
		EXTOPT_NO_ARG(&opts_flag),
		.desc = "some boolean argument option",
	},
	EXTOPTS_END
};

int main(int argc, char *argv[])
{
	extopts_usage(opts);

	return 0;
}

This example will produce following output:

      --str STR    some string argument
  -i, --int INT    some int argument plus really long description which probably
                   will be aligned and sliced into separate lines during usage
                   generation
  -f               some boolean argument option

Note: there are also usage autogeneration functions regarding extmods usage which is described on extmods page.

Clone this wiki locally