mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-05-01 13:13:53 +00:00
Overflow (#84)
* Overflowing an integer conversion now results in a conversion failure * CMake improvements for VERSION and inital packing support * Fix for recent addition of overflow check * Conan file now gets version from Version.hpp file too
This commit is contained in:
parent
316363061b
commit
79a1847605
@ -1,9 +1,19 @@
|
|||||||
cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
|
||||||
|
|
||||||
project(CLI11 LANGUAGES CXX)
|
set(VERSION_REGEX "#define CLI11_VERSION[ \t]+\"(.+)\"")
|
||||||
|
|
||||||
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
# Read in the line containing the version
|
||||||
|
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/CLI/Version.hpp"
|
||||||
|
VERSION_STRING REGEX ${VERSION_REGEX})
|
||||||
|
|
||||||
|
# Pick out just the version
|
||||||
|
string(REGEX REPLACE ${VERSION_REGEX} "\\1" VERSION_STRING "${VERSION_STRING}")
|
||||||
|
|
||||||
|
project(CLI11 LANGUAGES CXX VERSION ${VERSION_STRING})
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||||
|
|
||||||
|
# User settable
|
||||||
set(CLI_CXX_STD "11" CACHE STRING "The CMake standard to require")
|
set(CLI_CXX_STD "11" CACHE STRING "The CMake standard to require")
|
||||||
|
|
||||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||||
@ -70,6 +80,18 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/CLI DESTINATION include)
|
|||||||
# to Config.cmake (otherwise we'd have a custom config and would
|
# to Config.cmake (otherwise we'd have a custom config and would
|
||||||
# import Targets.cmake
|
# import Targets.cmake
|
||||||
|
|
||||||
|
# Add the version in a CMake readable way
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
write_basic_package_version_file(
|
||||||
|
CLI11ConfigVersion.cmake
|
||||||
|
VERSION ${CLI11_VERSION}
|
||||||
|
COMPATIBILITY AnyNewerVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make version available in the install
|
||||||
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CLI11ConfigVersion.cmake"
|
||||||
|
DESTINATION lib/cmake/CLI11)
|
||||||
|
|
||||||
# Make an export target
|
# Make an export target
|
||||||
install(TARGETS CLI11
|
install(TARGETS CLI11
|
||||||
EXPORT CLI11Targets)
|
EXPORT CLI11Targets)
|
||||||
@ -129,3 +151,24 @@ if(CLI_EXAMPLES)
|
|||||||
add_subdirectory(examples)
|
add_subdirectory(examples)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Packaging support
|
||||||
|
set(CPACK_PACKAGE_VENDOR "github.com/CLIUtils/CLI11")
|
||||||
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Command line interface")
|
||||||
|
set(CPACK_PACKAGE_VERSION_MAJOR ${CLI11_VERSION_MAJOR})
|
||||||
|
set(CPACK_PACKAGE_VERSION_MINOR ${CLI11_VERSION_MINOR})
|
||||||
|
set(CPACK_PACKAGE_VERSION_PATCH ${CLI11_VERSION_PATCH})
|
||||||
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||||
|
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
||||||
|
set(CPACK_SOURCE_GENERATOR "TGZ;ZIP")
|
||||||
|
# CPack collects *everything* except what's listed here.
|
||||||
|
set(CPACK_SOURCE_IGNORE_FILES
|
||||||
|
/.git
|
||||||
|
/dist
|
||||||
|
/.*build.*
|
||||||
|
/\\\\.DS_Store
|
||||||
|
/.*\\\\.egg-info
|
||||||
|
/var
|
||||||
|
/Pipfile.*$
|
||||||
|
)
|
||||||
|
include(CPack)
|
||||||
|
|
||||||
|
@ -15,7 +15,11 @@ download_project(PROJ googletest
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
# CMake warning suppression will not be needed in version 1.9
|
||||||
|
set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS 1 CACHE BOOL "")
|
||||||
add_subdirectory(${googletest_SOURCE_DIR} ${googletest_SOURCE_DIR} EXCLUDE_FROM_ALL)
|
add_subdirectory(${googletest_SOURCE_DIR} ${googletest_SOURCE_DIR} EXCLUDE_FROM_ALL)
|
||||||
|
unset(CMAKE_SUPPRESS_DEVELOPER_WARNINGS)
|
||||||
|
|
||||||
if (CMAKE_CONFIGURATION_TYPES)
|
if (CMAKE_CONFIGURATION_TYPES)
|
||||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
|
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
|
||||||
|
14
conanfile.py
14
conanfile.py
@ -1,14 +1,24 @@
|
|||||||
from conans import ConanFile, CMake
|
from conans import ConanFile, CMake
|
||||||
|
from conans.tools import load
|
||||||
|
import re
|
||||||
|
|
||||||
|
def get_version():
|
||||||
|
try:
|
||||||
|
content = load("include/CLI/Version.hpp")
|
||||||
|
version = re.search(r'#define CLI11_VERSION "(.*)"', content).group(1)
|
||||||
|
return version
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
class HelloConan(ConanFile):
|
class HelloConan(ConanFile):
|
||||||
name = "CLI11"
|
name = "CLI11"
|
||||||
version = "1.3.0"
|
version = get_version()
|
||||||
url = "https://github.com/CLIUtils/CLI11"
|
url = "https://github.com/CLIUtils/CLI11"
|
||||||
settings = "os", "compiler", "arch", "build_type"
|
settings = "os", "compiler", "arch", "build_type"
|
||||||
license = "BSD 3 clause"
|
license = "BSD 3 clause"
|
||||||
description = "Command Line Interface toolkit for C++11"
|
description = "Command Line Interface toolkit for C++11"
|
||||||
|
|
||||||
exports_sources = "LICENCE", "include/*", "cmake/*", "CMakeLists.txt", "tests/*"
|
exports_sources = "LICENSE", "README.md", "include/*", "cmake/*", "CMakeLists.txt", "tests/*"
|
||||||
|
|
||||||
def build(self): # this is not building a library, just tests
|
def build(self): # this is not building a library, just tests
|
||||||
cmake = CMake(self)
|
cmake = CMake(self)
|
||||||
|
@ -79,8 +79,9 @@ template <typename T,
|
|||||||
bool lexical_cast(std::string input, T &output) {
|
bool lexical_cast(std::string input, T &output) {
|
||||||
try {
|
try {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
output = static_cast<T>(std::stoll(input, &n, 0));
|
long long output_ll = std::stoll(input, &n, 0);
|
||||||
return n == input.size();
|
output = static_cast<T>(output_ll);
|
||||||
|
return n == input.size() && static_cast<long long>(output) == output_ll;
|
||||||
} catch(const std::invalid_argument &) {
|
} catch(const std::invalid_argument &) {
|
||||||
return false;
|
return false;
|
||||||
} catch(const std::out_of_range &) {
|
} catch(const std::out_of_range &) {
|
||||||
@ -97,8 +98,9 @@ bool lexical_cast(std::string input, T &output) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
output = static_cast<T>(std::stoull(input, &n, 0));
|
unsigned long long output_ll = std::stoull(input, &n, 0);
|
||||||
return n == input.size();
|
output = static_cast<T>(output_ll);
|
||||||
|
return n == input.size() && static_cast<unsigned long long>(output) == output_ll;
|
||||||
} catch(const std::invalid_argument &) {
|
} catch(const std::invalid_argument &) {
|
||||||
return false;
|
return false;
|
||||||
} catch(const std::out_of_range &) {
|
} catch(const std::out_of_range &) {
|
||||||
|
@ -348,6 +348,16 @@ TEST(Types, TypeName) {
|
|||||||
EXPECT_EQ("TEXT", text2_name);
|
EXPECT_EQ("TEXT", text2_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Types, OverflowSmall) {
|
||||||
|
char x;
|
||||||
|
auto strmax = std::to_string(INT8_MAX + 1);
|
||||||
|
EXPECT_FALSE(CLI::detail::lexical_cast(strmax, x));
|
||||||
|
|
||||||
|
unsigned char y;
|
||||||
|
strmax = std::to_string(UINT8_MAX + 1);
|
||||||
|
EXPECT_FALSE(CLI::detail::lexical_cast(strmax, y));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Types, LexicalCastInt) {
|
TEST(Types, LexicalCastInt) {
|
||||||
std::string signed_input = "-912";
|
std::string signed_input = "-912";
|
||||||
int x_signed;
|
int x_signed;
|
||||||
@ -357,7 +367,7 @@ TEST(Types, LexicalCastInt) {
|
|||||||
std::string unsigned_input = "912";
|
std::string unsigned_input = "912";
|
||||||
unsigned int x_unsigned;
|
unsigned int x_unsigned;
|
||||||
EXPECT_TRUE(CLI::detail::lexical_cast(unsigned_input, x_unsigned));
|
EXPECT_TRUE(CLI::detail::lexical_cast(unsigned_input, x_unsigned));
|
||||||
EXPECT_EQ(912, x_unsigned);
|
EXPECT_EQ((unsigned int)912, x_unsigned);
|
||||||
|
|
||||||
EXPECT_FALSE(CLI::detail::lexical_cast(signed_input, x_unsigned));
|
EXPECT_FALSE(CLI::detail::lexical_cast(signed_input, x_unsigned));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user