Coder Social home page Coder Social logo

smason / cxx_argp Goto Github PK

View Code? Open in Web Editor NEW

This project forked from pboettch/cxx_argp

0.0 1.0 0.0 35 KB

Modern C++, header-only command line argument parser interface based on argp

License: GNU Lesser General Public License v3.0

C++ 93.68% CMake 6.32%

cxx_argp's Introduction

Modern C++ argument parser based on ARGP

Description

This project provides a header-only, C++ (C++11 and later) argument parser library manufactured around GLIBC's ARGP-library.

Its goal is to stick to a maximum to the original concepts and features of ARGP in regards to argument-parsing. However, it adds some more advanced features, especially the association of variables, check-functions and their option-arguments - represented by the argp-struct.

It's licensed under the term of the LGPL3 (as is argp inside the GLIBC). As a header-only library is has the same license-requirements as stated by the Eigen Project.

How to use it

Here's how this library can be used:

#include <cxx_argp_parser.h>
#include <iostream>

int main(int argc, char *argv[])
{
	// initializers are default values for omitted options
	std::string host = "127.0.0.1";

	// create parser object,
	cxx_argp::parser parser;

	// add option and associate to simple variables, the class creates a
	// conversion function (if the type is supported) which does a basic check
	// and fills the variable
	// Note: the first argument is the real 'struct argp_option'
	parser.add_option({nullptr, 'h', "host-address", 0, "IP address of host"},
	                  host);

	if (parser.parse(argc, argv)) {
		std::cerr << "parsing OK\n";
	} else {
		std::cerr << "there was an error - exiting\n";
		return 1;
	}

	std::cerr << "hostname " << host << "\n";

	// here, do more checks on the values passed to the program

	return 0;
}

Running this program (called readme, see the test-folder) without arguments, hostname keeps it default value

$ ./readme
parsing OK
hostname 127.0.0.1

Running it with -h google.com, hostname changes:

$ ./readme -h google.com
parsing OK
hostname google.com

Omitting the argument to the '-h' option, errors out:

$ ./readme -h
./readme: option requires an argument -- 'h'
Try `readme --help' or `readme --usage' for more information.

Printing the help, generated by argp: (note that the program exists before returning to main())

Usage: readme [OPTION...]

  -h host-address            IP address of host
  -?, --help                 Give this help list
      --usage                Give a short usage message

Adding options

The method add_option() adds an option to the parser-object. The first argment is a value of struct argp_option, the second argument is either a variable, which is used by reference, or a lamdba-function, std::function or std::bind (of prototype bool(const char *).

This second argument is used during argument parsing, if it was variable the option's argument is tried to be converted to the variable (based on its type), if this is not possible, an error is produced and argp will bail out.

If the second argument is a function, this function is called with the argument value (a const char *) for further processing. This function returns true if the argument is accepted, otherwise false.

Argument conversion

Basic types

The parser-library internally provides some conversion-functions for some variable-type, which will make parsing fail if conversion has not worked, e.g. using a string on a float-type variable.

Floating point, std::strings and integer argument conversion functions are built in,

float single = 1.1f;
double doublef = 2.2;
uint16_t port = 502;
int16_t sint = 0;
std::string host = "127.0.0.1";

cxx_argp::parser parser;

parser.add_option({"float", 's', "single", 0, "floating-point test"}, single);
parser.add_option({"double", 'd', "double", 0, "floating-point test"}, doublef);
parser.add_option({"port", 'p', "port", 0, "TCP port the server will listen on"}, port);
parser.add_option({"host", 'h', "host-address", 0, "IP address of host"}, host);

Boolean and switches

bool-variable-based options are consider as 'switches', i.e. the option is expected to not have an argument and if the option is present, the associated bool-variable is set to true.

bool enable = false;

parser.add_option({"enable", 'e', nullptr, 0, "enable"}, enable);

File streams and file names

The built-in conversion functions for file-streams is taking the argument as a filename and tries to open the file. If this does not work, the argument is considered as an error.

std::ifstream file;

parser.add_option({"file", 'f', "filename", 0, "a file"}, file);

Sometimes the filename and a stream is required. A paired type can then be used:

std::pair<std::ifstream, std::string> file_and_name;

parser.add_option({"file", 'f', "filename", 0, "a file"}, file_and_name);

This works the same way as for simple streams, except that the open file is the first-part of the pair and the second-part contains the filename as a std::string.

To just get a filename without any file-opening, std::string can be used.

Comma-separated list of integer

A more complex conversion function is built in, this converts are comma-separated list of integers into a std::vector<>:

std::vector<int> vec;

parser_.add_option({"vector", 'V', "list", 0, "list of ints"}, vec);

An argument for such a type can be given as 1,12,3, resulting the version containing 1, 12 and 3.

Custom argument converter

Custom argument converters can be implemented by passing a function as second argument to add_option(). The user has thus complete control of what to do with the raw argument const char *.

The prototype of the function to be given is bool(const char *).

The user has to return true if the argument is acceptable for this option, or false if not.

There are no limit in regards what can be done using this feature:

Lambdas

Toggle a boolean:

bool enable = false;

parser.add_option({"enable", 'e', nullptr, 0, "enable"},
                  [&enable] (const char *) { enable = !enable; return true; } );

A verbosity-level indicator:

int verbose = 0;

parser.add_option({nullptr, 'v', nullptr, 0, "verbosity level increase"},
                  [&verbose] (const char *) { verbose++; return true; } );

std::bind

A useful feature for when using std::bind could be to fill in a map-like object (think of JSON as a more complex example than a std::map).

std::map<std::string, std::string> cfg;

auto to_map = [&cfg] (const char *arg, const std::string &key) {
	map[key] = arg;
	return true;
};

parser.add_option({nullptr, 'a', nullptr, 0, "value A"},
                  std::bind(to_map, std::placeholders::_1, "value1"));
parser.add_option({nullptr, 'b', nullptr, 0, "value B"},
                  std::bind(to_map, std::placeholders::_1, "value2"));
parser.add_option({nullptr, 'c', nullptr, 0, "value C"},
                  std::bind(to_map, std::placeholders::_1, "value3"));

Contributing

Do not hesite to ask questions and issue pull-requests here on GitHub. Every help is more than welcome.

cxx_argp's People

Contributors

pboettch avatar smason avatar adri1mart1 avatar dgerin avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.