Skip to content

Commit 2953371

Browse files
TheBearodactylwaruqiluadebug
authored
cppli: add package (#8644)
* cppli: add package * Update xmake.lua * Update xmake.lua * Try downgrade minimum required cmake version * Update xmake.lua * Create fix-clang.patch * Update fix-clang.patch * Update xmake.lua * Try resolve NDK issue * Update xmake.lua * Update xmake.lua * Update xmake.lua * Drop FreeBSD support * Keep FreeBSD --------- Co-authored-by: ruki <[email protected]> Co-authored-by: Saikari <[email protected]>
1 parent 76ad497 commit 2953371

File tree

2 files changed

+220
-0
lines changed

2 files changed

+220
-0
lines changed
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
diff --git a/CMakeLists.txt b/CMakeLists.txt
2+
index 1e4e1b6..c919063 100644
3+
--- a/CMakeLists.txt
4+
+++ b/CMakeLists.txt
5+
@@ -1,4 +1,4 @@
6+
-cmake_minimum_required(VERSION 4.1.1)
7+
+cmake_minimum_required(VERSION 3.5)
8+
9+
project(
10+
cppli
11+
@@ -7,7 +7,7 @@ project(
12+
LANGUAGES CXX
13+
)
14+
15+
-set(CMAKE_CXX_STANDARD 23)
16+
+set(CMAKE_CXX_STANDARD 20)
17+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
18+
set(CMAKE_CXX_EXTENSIONS OFF)
19+
20+
@@ -31,7 +31,7 @@ target_include_directories(
21+
$<INSTALL_INTERFACE:include>
22+
)
23+
24+
-target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
25+
+target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)
26+
27+
#if(MSVC)
28+
# target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX)
29+
@@ -78,7 +78,7 @@ if(CPPLI_BUILD_TESTS)
30+
PRIVATE ${PROJECT_NAME} Catch2::Catch2WithMain
31+
)
32+
33+
- target_compile_features(cppli_tests PRIVATE cxx_std_23)
34+
+ target_compile_features(cppli_tests PRIVATE cxx_std_20)
35+
36+
include(CTest)
37+
include(Catch)
38+
diff --git a/src/cppli_types.cpp b/src/cppli_types.cpp
39+
index 91f17c3..d8f4ba0 100644
40+
--- a/src/cppli_types.cpp
41+
+++ b/src/cppli_types.cpp
42+
@@ -1,57 +1,102 @@
43+
-#include <charconv>
44+
#include <cppli_error.hpp>
45+
#include <cppli_types.hpp>
46+
#include <string>
47+
#include <system_error>
48+
49+
+#if __cpp_lib_charconv >= 201606L && !defined(__GNUC__) || __GNUC__ >= 8
50+
+ #define USE_FROM_CHARS
51+
+#endif
52+
+
53+
+#if defined(USE_FROM_CHARS)
54+
+ #include <charconv>
55+
+#else
56+
+ #include <sstream>
57+
+#endif
58+
+
59+
namespace cli {
60+
- Result<int> ValueConverter<int>::from_string(std::string_view str) {
61+
- int value{};
62+
- auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
63+
+#ifdef USE_FROM_CHARS
64+
+ Result<int> ValueConverter<int>::from_string(std::string_view str) {
65+
+ int value{};
66+
+ auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
67+
+
68+
+ if (ec == std::errc()) {
69+
+ return Result<int>::ok(value);
70+
+ }
71+
72+
- if (ec == std::errc()) {
73+
- return Result<int>::ok(value);
74+
- }
75+
+ if (ec == std::errc::invalid_argument) {
76+
+ return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
77+
+ }
78+
79+
- if (ec == std::errc::invalid_argument) {
80+
- return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
81+
- }
82+
+ if (ec == std::errc::result_out_of_range) {
83+
+ return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Integer out of range"));
84+
+ }
85+
86+
- if (ec == std::errc::result_out_of_range) {
87+
- return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Integer out of range"));
88+
- }
89+
+ return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
90+
+ }
91+
92+
- return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
93+
- }
94+
+ Result<double> ValueConverter<double>::from_string(std::string_view str) {
95+
+ double value{};
96+
+ auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
97+
98+
- Result<double> ValueConverter<double>::from_string(std::string_view str) {
99+
- double value{};
100+
- auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
101+
+ if (ec == std::errc()) {
102+
+ return Result<double>::ok(value);
103+
+ }
104+
105+
- if (ec == std::errc()) {
106+
- return Result<double>::ok(value);
107+
- }
108+
+ if (ec == std::errc::invalid_argument) {
109+
+ return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
110+
+ }
111+
112+
- if (ec == std::errc::invalid_argument) {
113+
- return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
114+
- }
115+
+ if (ec == std::errc::result_out_of_range) {
116+
+ return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Floating-point out of range"));
117+
+ }
118+
119+
- if (ec == std::errc::result_out_of_range) {
120+
- return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Floating-point out of range"));
121+
- }
122+
+ return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
123+
+ }
124+
+#else
125+
+ Result<int> ValueConverter<int>::from_string(std::string_view str) {
126+
+ try {
127+
+ std::string str_copy(str);
128+
+ std::istringstream iss(str_copy);
129+
+ int value{};
130+
+ iss >> value;
131+
+
132+
+ if (iss.fail() || !iss.eof()) {
133+
+ return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
134+
+ }
135+
+
136+
+ return Result<int>::ok(value);
137+
+ } catch (const std::exception&) {
138+
+ return Result<int>::err(Error(ErrorCode::InvalidFlagValue, "Invalid integer format"));
139+
+ }
140+
+ }
141+
142+
- return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Unknown conversion error"));
143+
- }
144+
+ Result<double> ValueConverter<double>::from_string(std::string_view str) {
145+
+ try {
146+
+ std::string str_copy(str);
147+
+ std::istringstream iss(str_copy);
148+
+ double value{};
149+
+ iss >> value;
150+
+
151+
+ if (iss.fail() || !iss.eof()) {
152+
+ return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
153+
+ }
154+
+
155+
+ return Result<double>::ok(value);
156+
+ } catch (const std::exception&) {
157+
+ return Result<double>::err(Error(ErrorCode::InvalidFlagValue, "Invalid floating-point format"));
158+
+ }
159+
+ }
160+
+#endif
161+
162+
- Result<bool> ValueConverter<bool>::from_string(std::string_view str) {
163+
- if (str == "true" || str == "1" || str == "yes" || str == "on") {
164+
- return Result<bool>::ok(true);
165+
- }
166+
+ Result<bool> ValueConverter<bool>::from_string(std::string_view str) {
167+
+ if (str == "true" || str == "1" || str == "yes" || str == "on") {
168+
+ return Result<bool>::ok(true);
169+
+ }
170+
171+
- if (str == "false" || str == "0" || str == "no" || str == "off") {
172+
- return Result<bool>::ok(false);
173+
- }
174+
+ if (str == "false" || str == "0" || str == "no" || str == "off") {
175+
+ return Result<bool>::ok(false);
176+
+ }
177+
178+
- return Result<bool>::err(Error(ErrorCode::InvalidFlagValue, "Invalid boolean value (expected: true/false, 1/0, yes/no, on/off)"));
179+
- }
180+
-}// namespace cli
181+
+ return Result<bool>::err(Error(ErrorCode::InvalidFlagValue, "Invalid boolean value (expected: true/false, 1/0, yes/no, on/off)"));
182+
+ }
183+
+} // namespace cli

packages/c/cppli/xmake.lua

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package("cppli")
2+
set_homepage("https://cppli.bearodactyl.dev")
3+
set_description("an intuitive CLI framework for C++")
4+
5+
add_urls("https://github.com/TheBearodactyl/cppli.git")
6+
7+
add_versions("2025.10.22", "98c8c2e8ee65d7a5a6b160cf0b85ba1be39ffb05")
8+
9+
add_patches("2025.10.22", "patches/2025.10.22/fix-clang.patch", "7d7c1363774e4279636455b7cfe4806138a272a03d10f6bfce6dda00b3b17d0d")
10+
11+
add_configs("shared", {description = "Build shared library.", default = false, type = "boolean", readonly = true})
12+
13+
add_deps("cmake")
14+
15+
on_check(function (package)
16+
assert(package:check_cxxsnippets({test = [[
17+
#if !__has_include(<source_location>)
18+
# error source_location is not supported by compiler
19+
#endif
20+
]]}, {configs = {languages = "c++20"}}), "package(cppli): need std::source_location from <source_location> header.")
21+
end)
22+
23+
on_install(function (package)
24+
local configs = {}
25+
table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:is_debug() and "Debug" or "Release"))
26+
table.insert(configs, "-DCPPLI_BUILD_TESTS=OFF")
27+
import("package.tools.cmake").install(package, configs)
28+
end)
29+
30+
on_test(function (package)
31+
assert(package:check_cxxsnippets({test = [[
32+
void test() {
33+
cli::Parser parser("myapp", "A test application");
34+
std::string help = parser.generate_help();
35+
}
36+
]]}, {configs = {languages = "c++20"}, includes = "cppli.hpp"}))
37+
end)

0 commit comments

Comments
 (0)