Skip to content

Commit

Permalink
changes for release 0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
max committed Jun 23, 2017
1 parent 3a13d70 commit ac4686c
Show file tree
Hide file tree
Showing 12 changed files with 422 additions and 172 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,9 @@
*.exe
*.out
*.app

# yarg specific
examples/yarg-example-???
test/catch.hpp
test/test_yarg-1?-clang
test/test_yarg-1?-gcc
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

MIT License

Copyright (c) 2016 massimo morara
Copyright (c) 2016, 2017 massimo morara

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
55 changes: 51 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

## Yet Another Reinvented Getotp

Yarg is a one-header-only C++11 object oriented replacement for `getopt()`.
Yarg is a one-header-only C++11 replacement for `getopt()` that is object oriented and typed.

Support long options (example: `--help`), short options (`-h`), more short options in sequence (`-hvl`), options without values (flags) or followed by a value, negative flags (`--verbose` and `--noverbose` bounded on the same flag), repeatable options (`--name foo --name=bar --name "foo bar"`) and the special `--` argument to stop the option recognition.
Support long options (example: `--help`), short options (`-h`), more short options in sequence (`-hvl`), options without values (flags) or followed by a value, negative flags (`--verbose` and `--noverbose` bounded on the same flag), repeatable options (`--name foo --name=bar --name "foo bar"`), special `--` argument to stop the option recognition and automatic generation of usage/help message.

Every option is associated with a specific type (`bool` for flags) and trying to assign a wrong type value (as in `--level three` when "level" is defined of type `int`) cause an error in the parsing phase.

Expand All @@ -29,6 +29,12 @@ int main (int argc, char * argv[])

if ( y.parse(argc, argv) )
std::cout << "level is " << l << std::endl;
else
{
std::cerr << std::endl << y.getParserError() << std::endl;

y.usage();
}

return EXIT_SUCCESS;
}
Expand Down Expand Up @@ -87,7 +93,7 @@ Argument description:
+ **shortOption** - a single char that set the short option; by example, pass `'h'` to activate the `-h` recognition; to exclude the use of short option, pass `0` (zero)
+ **longOption** - a string that set the long option, excluding the starting `--`; by example, pass `"help"` to activate `--help` recognition; to exclude the use of long option, pass `""` (empty string); if **revert** is `true` (only for flags) this value activate a double long option (see **revert**)
+ **description** - a human understandable description of the option; an example: "show this help and exit"; intended for a future `getHelp()` method
+ **description** - a human understandable description of the option; an example: "show this help and exit"; used by `usage()`
+ **revert** - only for flags (`addFlag()` and `addFlagCont()`); if `true` and if a not empty **longOption** (see) is set, activate another long option (pre posing "no") to intercept a negative value; by example, if `true` and the long option is `"verbose"`, set to `true` the flag (or add a `true` flag in the container, when repeatable) when (a) `--verbose` argument is encountered and set to `false` the same flag (o add a `false` flag in the container, when repeatable) when (a) `--noverbose` argument is encountered
+ **defaultValue** - default value for the flag (or option) value (or container of values); can be used to set the template type (not in `addFlag()`, where is fixed to `bool`), otherwise is necessary to explicit it (se "option declaration examples")
Expand Down Expand Up @@ -154,12 +160,53 @@ if ( ! y.parse(argc, argv) )
### Program name
After the parsing phase (without errors) you can get the name of the program (the classic `argv[0]` argument) using the method `getArgv0()`, that return a `std::string`.
After the parsing phase, you can get the name of the program (the classic `argv[0]` argument) using the method `getArgv0()`, that return a `std::string`.
### Not options arguments
After the parsing phase (without errors) you can get the not options values arguments list using the method `getNoOpts()` that return a `std::deque` of `std::string`.
### Automatic usage/help message generation
Yarg permits the printing of a usage/help message automatically generated using, mainly, the `description` argument of `addFlag()`, `addOpt()`, `addFlagCont()` and `addOptCont()` methods.
By example, in the executable obtained from the minimal example that you can see in "Minimale example" section, the call to `usage()` print the following message
```
Usage: ./yarg-example-001 [options]

where options are

-l, --level = <value>
set the level value
```
The following is the corresponding interface
```c++
// set a short otional description for the arguments (imput parameters post
// options and flags) that is printed in head of the usage() message
void setUsageArgsDescr (std::string const & ad);
// set an optional initial description that is printed after the head of the
// usage() message and before the list of the options
void setUsageInitalDescr (std::string const & id);
// set an optional final description that is printed after the list of the
// options, at the end of the usage() message
void setUsageFinalDescr (std::string const & fd);
// set the width (number of columns) available for the usage() message; the
// default value is 79
void setUsageWidth (std::size_t uw);
// print the usage() message to the 'os' output stream (the default is
// std::cerr)
void usage (std::ostream & os = std::cerr) const
```

You can see a detailed use example in `examples/yarg-example-003.cpp`.

### Line command examples

Calling the executable obtained from the minimal example that you can see in "Minimale example" section (that intercept only a `-l`/`--level` integer option) with the following command line
Expand Down
10 changes: 10 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@

0.2.0 - 2017.06.23

- usage() method added with some help support methods (setUsageArgsDescr(),
setUsageInitialDescr(), setUsageFinalDescr(), setUsageWidth())
- added a third example (yarg-example-003) to show the use of usage()
and support methods
- Makefile for examples improved
- minor corrections and minor (mainly aesthetic) changes


0.1.1 - 2016.09.21

- regex error corrected
Expand Down
7 changes: 6 additions & 1 deletion examples/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# Copyright (c) 2016 massimo morara
# Copyright (c) 2016, 2017 massimo morara

# Distributed under the Mit License
# See accompanying file LICENSE
Expand All @@ -10,12 +10,17 @@ CPPFLAGS = -c -g -O0 -Wall -Wextra -ansi -pedantic -Wno-unknown-pragmas \
-std=c++14 -stdlib=libc++ -I. -I../src
LDFLAGS = -stdlib=libc++
EXES = $(shell ls *.cpp | sed 's/.cpp//')
YARGH = ../src/yarg/yarg.h

all: $(EXES)

clean:
- rm $(EXES) $(EXES:%=%.o) >& /dev/null

yargDependent = *.o

$(yargDependent): $(YARGH)

%.o: %.cpp Makefile
$(CC) -o $@ $(CPPFLAGS) $<

Expand Down
9 changes: 8 additions & 1 deletion examples/yarg-example-001.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

// Copyright (c) 2016 massimo morara
// Copyright (c) 2016, 2017 massimo morara

// Distributed under the Mit License
// See accompanying file LICENSE
Expand All @@ -18,6 +18,13 @@ int main (int argc, char * argv[])

if ( y.parse(argc, argv) )
std::cout << "level is " << l << std::endl;
else
{
std::cerr << std::endl << y.getParserError() << std::endl;

y.usage();
}


return EXIT_SUCCESS;
}
Expand Down
17 changes: 10 additions & 7 deletions examples/yarg-example-002.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

// Copyright (c) 2016 massimo morara
// Copyright (c) 2016, 2017 massimo morara

// Distributed under the Mit License
// See accompanying file LICENSE
Expand All @@ -15,13 +15,12 @@ int main (int argc, char * argv[])

try
{
// creation of a yarg instance; no parameter for constructor
// creation of a yarg instance; no parameters for constructor
yarg::yarg y;

// add a flag (an option without an argument) that can be set with a
// short option ("-h") and with a long option ("--help") without
// expliciting a default value (so the default default value is
// "false")
// expliciting a default value (so the default value is "false")
auto & b0 = y.addFlag('h', "help", "some help");

// add another flag that can be set with a long option only
Expand All @@ -43,7 +42,7 @@ int main (int argc, char * argv[])
// add another option of type long expliciting the type (via template
// argument); the default value is long{} (so 0L); this option can be
// set only by a short argument (the second parameter is empty)
auto & l0 = y.addOpt<long>('o', "", "set a long option only");
auto & l0 = y.addOpt<long>('o', "", "set a short option only");

// add a container option (a repeatable option) of type int and store
// the values in a `std::vector<int>`
Expand All @@ -58,11 +57,15 @@ int main (int argc, char * argv[])
// std::deque<std::string>; can be done post parse()
auto & args = y.getNoOpts();

// parse argc and argv; in case of error return false, the parsing
// parse argc and argv; in case of error return false; the parsing
// error (a std::string) can be extract from getParserError()
if ( false == y.parse(argc, argv) )
{
y.usage();

throw std::runtime_error("yarg parsing error: " + y.getParserError()
+ "]");
}

// the name of the program
std::cout << "argv0 ? " << argv0 << std::endl;
Expand Down Expand Up @@ -90,7 +93,7 @@ int main (int argc, char * argv[])

errExit = false;
}
catch ( std::exception & e )
catch ( std::exception const & e )
{
std::cerr << "\nmain(): standard exception of type \""
<< typeid(e).name() <<"\"\n"
Expand Down
80 changes: 80 additions & 0 deletions examples/yarg-example-003.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@

// Copyright (c) 2016, 2017 massimo morara

// Distributed under the Mit License
// See accompanying file LICENSE.txt
// See https://github.com/massimomorara/yarg for latest version

#include <set>
#include <iostream>

#include <yarg/yarg.h>

int main (int argc, char * argv[])
{
yarg::yarg y;

y.setUsageArgsDescr("[args]");
y.setUsageInitialDescr("Initial (optional) description message, printed"
" before of the options description. Can be used"
" to give a short description of the program.");
y.setUsageFinalDescr("Final (optional) description message, printed after"
" the options description. Can be used to give a"
" longer and exaustive description of the program.");

// some flags and options with description
y.addFlag('a', "flag0", "a flag, not reversible, not repeatable, with"
" long and short option");
y.addFlag('b', "", "a flag, not reversible, not repeatable, with short"
" option only");
y.addFlag(0, "flag2", "a flag, not reversible, not repeatable, with long"
" option only");
y.addFlag('d', "flag3", "a flag, reversible, not repeatable, with long"
" and short option", true);
y.addFlag(0, "flag4", "a flag, reversible, not repeatable, with long"
" option only", true);
y.addFlagCont<std::set<int>>('f', "flag5", "a flag, not reversible,"
" repeatable, with long and short option",
false);
y.addFlagCont<std::set<int>>('g', "", "a flag, not reversible,"
" repeatable, with short option only",
false);
y.addFlagCont<std::set<int>>(0, "flag7", "a flag, not reversible,"
" repeatable, with long option only", false);
y.addFlagCont<std::set<int>>('i', "flag8", "a flag, reversible,"
" repeatable, with long and short option",
true);
y.addFlagCont<std::set<int>>(0, "flag9", "a flag, reversible, repeatable,"
" with long option only", true);
y.addOpt('k', "option0", "an option, not repeatable, with long and short"
" option", 0);
y.addOpt('l', "", "an option, not repeatable, with short option only", 0);
y.addOpt(0, "option2", "an option, not repeatable, with long option only",
0);
y.addOptCont<std::set<int>>('n', "option3", "an option, repeatable, with"
" long and short option");
y.addOptCont<std::set<int>>('o', "", "an option, repeatable, with short"
" option only");
y.addOptCont<std::set<int>>(0, "option5", "an option, repeatable, with"
" long option only and a longer, really"
" longer than usual, description; and with"
" \"really longer than usual\", I really"
" intend longer");

y.parse(argc, argv);

std::cerr << "---- help to std::cerr, 79 chars lines" << std::endl;

y.setUsageWidth(79U); // length of the help lines (79 is the default)

y.usage(); // by default to std::cerr

std::cerr << "---- help to std::cout, 59 chars lines" << std::endl;

y.setUsageWidth(59U); // reduced length of the help lines: 59 chars only

y.usage(std::cout); // send to std::cout

return EXIT_SUCCESS;
}

Loading

0 comments on commit ac4686c

Please sign in to comment.