Fix warnings and small issues (#1178)

try some things with no standard libraries
Add arm64 and freebsd build and tests
fix a discrepancy in the handling of chars on Arm processors

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Philip Top
2025-07-18 07:18:26 -07:00
committed by GitHub
parent 587129a170
commit c5153634db
10 changed files with 117 additions and 30 deletions

25
.github/workflows/arm_mac_gcc.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: ARM GCC
on:
pull_request:
branches:
- main
jobs:
arm64_gcc:
name: ARM64 GCC
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v4
- name: Configure
run: |
cmake -S . -B build \
-DCMAKE_CXX_STANDARD=17
- name: Build
run: cmake --build build -j4
- name: Test
run: |
cd build
ctest --output-on-failure

28
.github/workflows/freebsd.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: freebsd
on:
push:
branches:
- main
pull_request:
jobs:
test:
runs-on: ubuntu-latest
name: run test on FreeBSD
steps:
- uses: actions/checkout@v4
- name: Test in FreeBSD
id: test
uses: vmactions/freebsd-vm@v1
with:
usesh: true
prepare: |
pkg install -y cmake pkgconf
run: |
cmake -S . -B build \
-DCMAKE_CXX_STANDARD=20
cmake --build build -j4
cd build
ctest --output-on-failure

View File

@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
std: ["11", "14", "17", "20"]
std: ["14", "17", "20","23"]
precompile: ["ON", "OFF"]
steps:
- uses: actions/checkout@v4
@@ -150,6 +150,22 @@ jobs:
run: ctest --output-on-failure
working-directory: build
sanitizer-build:
name: sanitizer build
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
submodules: true
# this build step will fail
- name: Configure
run: cmake -S . -B build -DCLI11_SANITIZERS=ON
- name: Build
run: cmake --build build -j2
- name: Run tests
run: ctest --output-on-failure
working-directory: build
meson-build:
name: Meson build
runs-on: ubuntu-latest
@@ -378,4 +394,12 @@ jobs:
uses: ./.github/actions/quick_cmake
with:
cmake-version: "3.31"
args: -DCLI11_SANITIZERS=ON -DCLI11_BUILD_EXAMPLES_JSON=ON
if: success() || failure()
- name: Check CMake 4.0
uses: ./.github/actions/quick_cmake
with:
cmake-version: "4.0"
args: -DCLI11_BUILD_EXAMPLES_JSON=ON
if: success() || failure()

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10...3.31)
# Note: this is a header only library. If you have an older CMake than 3.5,
cmake_minimum_required(VERSION 3.10...4.0)
# Note: this is a header only library. If you have an older CMake than 3.10,
# just add the CLI11/include directory and that's all you need to do.
set(VERSION_REGEX "#define CLI11_VERSION[ \t]+\"(.+)\"")
@@ -69,7 +69,7 @@ option(CLI11_WARNINGS_AS_ERRORS "Turn all warnings into errors (for CI)")
option(CLI11_SINGLE_FILE "Generate a single header file")
option(CLI11_PRECOMPILED "Generate a precompiled static library instead of a header-only" OFF)
cmake_dependent_option(CLI11_SANITIZERS "Download the sanitizers CMake config" OFF
"NOT CMAKE_VERSION VERSION_LESS 3.13" OFF)
"NOT CMAKE_VERSION VERSION_LESS 3.15" OFF)
cmake_dependent_option(CLI11_BUILD_DOCS "Build CLI11 documentation" ON "${build-docs}" OFF)
@@ -80,7 +80,7 @@ cmake_dependent_option(CLI11_BUILD_EXAMPLES "Build CLI11 examples" ON
"CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME;${examples_EXIST}" OFF)
cmake_dependent_option(CLI11_BUILD_EXAMPLES_JSON "Build CLI11 json example" OFF
"CLI11_BUILD_EXAMPLES;NOT CMAKE_VERSION VERSION_LESS 3.11" OFF)
"CLI11_BUILD_EXAMPLES;NOT CMAKE_VERSION VERSION_LESS 3.15" OFF)
cmake_dependent_option(CLI11_SINGLE_FILE_TESTS "Duplicate all the tests for a single file build"
OFF "BUILD_TESTING;CLI11_SINGLE_FILE" OFF)
@@ -113,12 +113,15 @@ if(NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
include(CLI11Warnings)
# Allow IDE's to group targets into folders
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
endif()
include(CLI11Warnings)
set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "")
set(CMAKE_CXX_STANDARD_LIBRARIES "")
endif()
# Sources

View File

@@ -10,17 +10,14 @@ function(add_cli_exe T)
endif()
endfunction()
if(CLI11_BUILD_EXAMPLES_JSON)
if(CLI11_BUILD_EXAMPLES_JSON AND CMAKE_VERSION VERSION_GREATER "3.14.7")
message(STATUS "Using nlohmann/json")
FetchContent_Declare(
json
URL https://github.com/nlohmann/json/releases/download/v3.7.3/include.zip
URL_HASH "SHA256=87b5884741427220d3a33df1363ae0e8b898099fbc59f1c451113f6732891014")
FetchContent_GetProperties(json)
if(NOT json_POPULATED)
FetchContent_Populate(json)
endif()
FetchContent_MakeAvailable(json)
add_cli_exe(json json.cpp)
target_include_directories(json PUBLIC SYSTEM "${json_SOURCE_DIR}/single_include")

View File

@@ -165,7 +165,7 @@ CLI11_INLINE bool valid_name_string(const std::string &str);
/// Verify an app name
inline bool valid_alias_name_string(const std::string &str) {
static const std::string badChars(std::string("\n") + '\0');
static const std::string badChars{'\n', '\0'};
return (str.find_first_of(badChars) == std::string::npos);
}

View File

@@ -1130,7 +1130,14 @@ bool lexical_cast(const std::string &input, T &output) {
output = static_cast<T>(input[0]);
return true;
}
return integral_conversion(input, output);
std::int8_t res{0};
// we do it this way as some systems have char as signed and not, this ensures consistency in the way things are
// handled
bool result = integral_conversion(input, res);
if(result) {
output = static_cast<T>(res);
}
return result;
}
/// Boolean values

View File

@@ -1,4 +1,4 @@
if(CLI11_SANITIZERS AND ${CMAKE_VERSION} VERSION_GREATER "3.13.0")
if(CLI11_SANITIZERS AND ${CMAKE_VERSION} VERSION_GREATER "3.15.0")
message(STATUS "Using arsenm/sanitizers-cmake")
FetchContent_Declare(
sanitizers
@@ -6,11 +6,7 @@ if(CLI11_SANITIZERS AND ${CMAKE_VERSION} VERSION_GREATER "3.13.0")
GIT_SHALLOW 1
GIT_TAG 0573e2e)
FetchContent_GetProperties(sanitizers)
if(NOT sanitizers_POPULATED)
FetchContent_Populate(sanitizers)
endif()
FetchContent_MakeAvailable(sanitizers)
list(APPEND CMAKE_MODULE_PATH "${sanitizers_SOURCE_DIR}/cmake")
@@ -119,6 +115,7 @@ foreach(DATA_FILE IN LISTS DATA_FILES)
VERBATIM)
endforeach()
add_custom_target(cli11_test_data DEPENDS ${DATA_FILES})
set_target_properties(cli11_test_data PROPERTIES FOLDER "Tests/Apps")
# Make a shim if we are building single file tests
if(CLI11_SINGLE_FILE AND CLI11_INSTALL_PACKAGE_TESTS)
@@ -132,6 +129,7 @@ set(CLI11_DEPENDENT_APPLICATIONS ensure_utf8 ensure_utf8_twice)
foreach(APP IN LISTS CLI11_DEPENDENT_APPLICATIONS)
add_executable(${APP} applications/${APP}.cpp)
target_include_directories(${APP} PRIVATE ${CMAKE_SOURCE_DIR}/include)
set_target_properties(${APP} PROPERTIES FOLDER "Tests/Apps")
endforeach()
function(add_dependent_application_definitions TARGET)
@@ -139,6 +137,10 @@ function(add_dependent_application_definitions TARGET)
string(TOUPPER ${APP} APP_UPPERCASE)
target_compile_definitions(${TARGET}
PRIVATE CLI11_${APP_UPPERCASE}_EXE="$<TARGET_FILE:${APP}>")
if(WIN32)
target_link_libraries(${APP} PRIVATE Shell32)
endif()
endforeach()
endfunction()
@@ -246,6 +248,7 @@ if(CLI11_FORCE_LIBCXX)
PROPERTY LINK_FLAGS -stdlib=libc++)
endif()
set_target_properties(informational PROPERTIES FOLDER "Tests/Apps")
# Force this to be in a standard location so CTest can find it
set_target_properties(
informational

View File

@@ -274,7 +274,7 @@ TEST_CASE("StringTools: binaryEscapeConversion", "[helpers]") {
testString2.push_back(0);
testString2.push_back(static_cast<char>(197));
testString2.push_back(78);
testString2.push_back(-34);
testString2.push_back(static_cast<char>(-34));
rstring = CLI::detail::extract_binary_string(CLI::detail::binary_escape_string(testString2));
CHECK(rstring == testString2);
@@ -294,8 +294,8 @@ TEST_CASE("StringTools: binaryEscapeConversion2", "[helpers]") {
testString.push_back(0);
testString.push_back(0);
testString.push_back(56);
testString.push_back(-112);
testString.push_back(-112);
testString.push_back(static_cast<char>(-112));
testString.push_back(static_cast<char>(-112));
testString.push_back(39);
testString.push_back(97);
std::string estring = CLI::detail::binary_escape_string(testString);
@@ -310,8 +310,8 @@ TEST_CASE("StringTools: binaryEscapeConversion_withX", "[helpers]") {
testString.push_back(0);
testString.push_back(0);
testString.push_back(56);
testString.push_back(-112);
testString.push_back(-112);
testString.push_back(static_cast<char>(-112));
testString.push_back(static_cast<char>(-112));
testString.push_back(39);
testString.push_back(97);
std::string estring = CLI::detail::binary_escape_string(testString);
@@ -324,12 +324,12 @@ TEST_CASE("StringTools: binaryEscapeConversion_withBrackets", "[helpers]") {
std::string vstr = R"raw('B"([\xb0\x0a\xb0/\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0])"')raw";
std::string testString("[");
testString.push_back(-80);
testString.push_back(static_cast<char>(-80));
testString.push_back('\n');
testString.push_back(-80);
testString.push_back(static_cast<char>(-80));
testString.push_back('/');
for(int ii = 0; ii < 13; ++ii) {
testString.push_back(-80);
testString.push_back(static_cast<char>(-80));
}
testString.push_back(']');

View File

@@ -112,8 +112,8 @@ CLI11_INLINE void check_identical_files(const char *path1, const char *path2) {
file1.seekg(0);
file2.seekg(0);
std::array<uint8_t, 10240> buffer1;
std::array<uint8_t, 10240> buffer2;
static std::array<uint8_t, 10240> buffer1;
static std::array<uint8_t, 10240> buffer2;
for(size_t ibuffer = 0; file1.good(); ++ibuffer) {
// Flawfinder: ignore