mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-05-01 21:23:52 +00:00
Merge branch 'master' into basic-enum
This commit is contained in:
commit
00e0506f53
@ -1,7 +1,10 @@
|
|||||||
## Version 1.1 (in progress)
|
## Version 1.1 (in progress)
|
||||||
* Added support for basic enumerations [#12](https://github.com/CLIUtils/CLI11/issues/12)
|
|
||||||
* Added `app.parse_order()` with original parse order
|
* Added simple support for enumerations, allow non-printable objects [#12](https://github.com/CLIUtils/CLI11/issues/12)
|
||||||
* Added `prefix_command()`, which is like `allow_extras` but instantly stops and returns.
|
* Added `app.parse_order()` with original parse order ([#13](https://github.com/CLIUtils/CLI11/issues/13), [#16](https://github.com/CLIUtils/CLI11/pull/16))
|
||||||
|
* Added `prefix_command()`, which is like `allow_extras` but instantly stops and returns. ([#8](https://github.com/CLIUtils/CLI11/issues/8), [#17](https://github.com/CLIUtils/CLI11/pull/17))
|
||||||
|
* Removed Windows error ([#10](https://github.com/CLIUtils/CLI11/issues/10), [#20](https://github.com/CLIUtils/CLI11/pull/20))
|
||||||
|
* Some improvements to CMake, detect Python and no dependencies on Python 2 (like Python 3) ([#18](https://github.com/CLIUtils/CLI11/issues/18), [#21](https://github.com/CLIUtils/CLI11/pull/21))
|
||||||
|
|
||||||
## Version 1.0
|
## Version 1.0
|
||||||
* Cleanup using `clang-tidy` and `clang-format`
|
* Cleanup using `clang-tidy` and `clang-format`
|
||||||
|
@ -13,7 +13,6 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
|||||||
# Be moderately paranoid with flags
|
# Be moderately paranoid with flags
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
add_definitions("/W4")
|
add_definitions("/W4")
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
|
||||||
else()
|
else()
|
||||||
add_definitions("-Wall -Wextra -pedantic")
|
add_definitions("-Wall -Wextra -pedantic")
|
||||||
endif()
|
endif()
|
||||||
@ -54,11 +53,18 @@ add_library(CLI11 INTERFACE)
|
|||||||
target_include_directories(CLI11 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
target_include_directories(CLI11 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||||
|
|
||||||
# Single file test
|
# Single file test
|
||||||
option(CLI_SINGLE_FILE "Generate a single header file (and test)" ${CUR_PROJ})
|
find_package(PythonInterp)
|
||||||
|
if(CUR_PROJ AND PYTHONINTERP_FOUND)
|
||||||
|
set(CLI_SINGLE_FILE_DEFAULT ON)
|
||||||
|
else()
|
||||||
|
set(CLI_SINGLE_FILE_DEFAULT OFF)
|
||||||
|
endif()
|
||||||
|
option(CLI_SINGLE_FILE "Generate a single header file (and test)" ${CLI_SINGLE_FILE_DEFAULT})
|
||||||
if(CLI_SINGLE_FILE)
|
if(CLI_SINGLE_FILE)
|
||||||
|
find_package(PythonInterp REQUIRED)
|
||||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include")
|
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include")
|
||||||
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp"
|
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp"
|
||||||
COMMAND python "${CMAKE_CURRENT_SOURCE_DIR}/scripts/MakeSingleHeader.py" "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp"
|
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/MakeSingleHeader.py" "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp"
|
||||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/CLI/CLI.hpp" ${CLI_headers}
|
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/CLI/CLI.hpp" ${CLI_headers}
|
||||||
)
|
)
|
||||||
add_custom_target(generate_cli_single_file ALL
|
add_custom_target(generate_cli_single_file ALL
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
CLI11 provides all the features you expect in a powerful command line parser, with a beautiful, minimal syntax and no dependencies beyond C++11. It is header only, and comes in a single file form for easy inclusion in projects. It is easy to use for small projects, but powerful enough for complex command line projects, and can be customized for frameworks.
|
CLI11 provides all the features you expect in a powerful command line parser, with a beautiful, minimal syntax and no dependencies beyond C++11. It is header only, and comes in a single file form for easy inclusion in projects. It is easy to use for small projects, but powerful enough for complex command line projects, and can be customized for frameworks.
|
||||||
It is tested on [Travis] and [AppVeyor], and is being included in the [GooFit GPU fitting framework][GooFit]. It was inspired by [`plumbum.cli`][Plumbum] for Python. CLI11 has a user friendly introduction in this README, a more indepth tutorial [GitBook], as well as [API documentation][api-docs] generated by Travis.
|
It is tested on [Travis] and [AppVeyor], and is being included in the [GooFit GPU fitting framework][GooFit]. It was inspired by [`plumbum.cli`][Plumbum] for Python. CLI11 has a user friendly introduction in this README, a more indepth tutorial [GitBook], as well as [API documentation][api-docs] generated by Travis.
|
||||||
See the [changelog](./CHANGELOG.md) or [GitHub Releases] for details for current and past releases. The 1.0 announcement post can be found [here](http://iscinumpy.blogspot.com/2017/06/announcing-cli11-version-10.html).
|
See the [changelog](./CHANGELOG.md) or [GitHub Releases] for details for current and past releases. The version 1.0 announcement post can be found [here](http://iscinumpy.blogspot.com/2017/06/announcing-cli11-version-10.html).
|
||||||
|
|
||||||
### Why write another CLI parser?
|
### Why write another CLI parser?
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ app.add_set_ignore_case(... // String only
|
|||||||
App* subcom = app.add_subcommand(name, discription);
|
App* subcom = app.add_subcommand(name, discription);
|
||||||
```
|
```
|
||||||
|
|
||||||
An option name must start with a alphabetic character or underscore. For long options, anything but an equals sign or a comma is valid after that. Names are given as a comma separated string, with the dash or dashes. An option or flag can have as many names as you want, and afterward, using `count`, you can use any of the names, with dashes as needed, to count the options. One of the names is allowed to be given without proceeding dash(es); if present the option is a positional option, and that name will be used on help line for its positional form. If you want the default value to print in the help description, pass in `true` for the final parameter for `add_option` or `add_set`.
|
An option name must start with a alphabetic character or underscore. For long options, anything but an equals sign or a comma is valid after that. Names are given as a comma separated string, with the dash or dashes. An option or flag can have as many names as you want, and afterward, using `count`, you can use any of the names, with dashes as needed, to count the options. One of the names is allowed to be given without proceeding dash(es); if present the option is a positional option, and that name will be used on help line for its positional form. If you want the default value to print in the help description, pass in `true` for the final parameter for `add_option` or `add_set`. The set options allow your users to pick from a set of predefined options.
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
|
@ -46,6 +46,8 @@ gtest_build_tests
|
|||||||
gtest_disable_pthreads
|
gtest_disable_pthreads
|
||||||
gtest_force_shared_crt
|
gtest_force_shared_crt
|
||||||
gtest_hide_internal_symbols
|
gtest_hide_internal_symbols
|
||||||
|
BUILD_GMOCK
|
||||||
|
BUILD_GTEST
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(gtest gtest_main gmock gmock_main
|
set_target_properties(gtest gtest_main gmock gmock_main
|
||||||
|
@ -909,9 +909,25 @@ class App {
|
|||||||
// Get envname options if not yet passed
|
// Get envname options if not yet passed
|
||||||
for(const Option_p &opt : options_) {
|
for(const Option_p &opt : options_) {
|
||||||
if(opt->count() == 0 && opt->envname_ != "") {
|
if(opt->count() == 0 && opt->envname_ != "") {
|
||||||
char *ename = std::getenv(opt->envname_.c_str());
|
char *buffer = nullptr;
|
||||||
if(ename != nullptr) {
|
std::string ename_string;
|
||||||
opt->add_result(std::string(ename));
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// Windows version
|
||||||
|
size_t sz = 0;
|
||||||
|
if(_dupenv_s(&buffer, &sz, opt->envname_.c_str()) == 0 && buffer != nullptr) {
|
||||||
|
ename_string = std::string(buffer);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// This also works on Windows, but gives a warning
|
||||||
|
buffer = std::getenv(opt->envname_.c_str());
|
||||||
|
if(buffer != nullptr)
|
||||||
|
ename_string = std::string(buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!ename_string.empty()) {
|
||||||
|
opt->add_result(ename_string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,24 +4,24 @@
|
|||||||
|
|
||||||
from __future__ import print_function, unicode_literals
|
from __future__ import print_function, unicode_literals
|
||||||
|
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import argparse
|
import argparse
|
||||||
from pathlib import Path
|
|
||||||
from subprocess import check_output
|
from subprocess import check_output
|
||||||
|
|
||||||
includes_local = re.compile(r"""^#include "(.*)"$""", re.MULTILINE)
|
includes_local = re.compile(r"""^#include "(.*)"$""", re.MULTILINE)
|
||||||
includes_system = re.compile(r"""^#include \<(.*)\>$""", re.MULTILINE)
|
includes_system = re.compile(r"""^#include \<(.*)\>$""", re.MULTILINE)
|
||||||
|
|
||||||
DIR = Path(__file__).resolve().parent
|
DIR = os.path.dirname(os.path.abspath(__file__)) # Path(__file__).resolve().parent
|
||||||
BDIR = DIR.parent / 'include'
|
BDIR = os.path.join(os.path.dirname(DIR), 'include') # DIR.parent / 'include'
|
||||||
|
|
||||||
print("Git directory:", DIR)
|
print("Git directory:", DIR)
|
||||||
|
|
||||||
TAG = check_output(['git', 'describe', '--tags', '--always'], cwd=str(DIR)).decode("utf-8")
|
TAG = check_output(['git', 'describe', '--tags', '--always'], cwd=str(DIR)).decode("utf-8")
|
||||||
|
|
||||||
def MakeHeader(out):
|
def MakeHeader(out):
|
||||||
main_header = BDIR / 'CLI/CLI.hpp'
|
main_header = os.path.join(BDIR, 'CLI', 'CLI.hpp')
|
||||||
with main_header.open() as f:
|
with open(main_header) as f:
|
||||||
header = f.read()
|
header = f.read()
|
||||||
|
|
||||||
include_files = includes_local.findall(header)
|
include_files = includes_local.findall(header)
|
||||||
@ -29,7 +29,7 @@ def MakeHeader(out):
|
|||||||
headers = set()
|
headers = set()
|
||||||
output = ''
|
output = ''
|
||||||
for inc in include_files:
|
for inc in include_files:
|
||||||
with (BDIR / inc).open() as f:
|
with open(os.path.join(BDIR, inc)) as f:
|
||||||
inner = f.read()
|
inner = f.read()
|
||||||
headers |= set(includes_system.findall(inner))
|
headers |= set(includes_system.findall(inner))
|
||||||
output += '\n// From {inc}\n\n'.format(inc=inc)
|
output += '\n// From {inc}\n\n'.format(inc=inc)
|
||||||
@ -50,7 +50,7 @@ def MakeHeader(out):
|
|||||||
{header_list}
|
{header_list}
|
||||||
{output}'''.format(header_list=header_list, output=output, tag=TAG)
|
{output}'''.format(header_list=header_list, output=output, tag=TAG)
|
||||||
|
|
||||||
with Path(out).open('w') as f:
|
with open(out, 'w') as f:
|
||||||
f.write(output)
|
f.write(output)
|
||||||
|
|
||||||
print("Created {out}".format(out=out))
|
print("Created {out}".format(out=out))
|
||||||
@ -58,6 +58,6 @@ def MakeHeader(out):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("output", nargs='?', default=BDIR / 'CLI11.hpp')
|
parser.add_argument("output", nargs='?', default=os.path.join(BDIR, 'CLI11.hpp'))
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
MakeHeader(args.output)
|
MakeHeader(args.output)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user