Skip to content

Commit

Permalink
wip property rework
Browse files Browse the repository at this point in the history
  • Loading branch information
gulrak committed Sep 16, 2024
1 parent 50e9d44 commit 5f34728
Show file tree
Hide file tree
Showing 49 changed files with 2,072 additions and 1,677 deletions.
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.16)

project(cadmium VERSION 1.1.11 LANGUAGES C CXX)
project(cadmium VERSION 1.1.15 LANGUAGES C CXX)
cmake_policy(VERSION 3.16)

include(cmake/BuildSettings.cmake)
Expand All @@ -22,7 +22,6 @@ add_subdirectory(resources)
add_subdirectory(src)
add_subdirectory(test)


set(CPACK_PACKAGE_VENDOR "gulrak.net")
set(CPACK_PACKAGE_CONTACT "s.schuemann@pobox.com")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/gulrak/cadmium")
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ the changing `main` branch head between `v1.0.0` and `v1.0.2`.

## Compiling from Source

_Cadmium_ is written in C++17 and uses CMake as a build solution. To build it,
_Cadmium_ is written in C++20 and uses CMake as a build solution. To build it,
checkout or download the source.

### Linux / macOS
Expand Down
19 changes: 19 additions & 0 deletions cmake/BuildSettings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,22 @@ if(GIT_FOUND)
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()

option(BUILD_DOC "Build documentation" ON)

find_package(Doxygen)
if(DOXYGEN_FOUND)
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in)
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)

configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
message("Doxygen build started")

add_custom_target(doc_doxygen ALL
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM )
else()
message("Doxygen need to be installed to generate the doxygen documentation")
endif()
16 changes: 16 additions & 0 deletions docs/Doxyfile.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/doc_doxygen/
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/src/ @CMAKE_CURRENT_SOURCE_DIR@/docs

CLASS_DIAGRAMS = YES
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
DOT_GRAPH_MAX_NODES = 100
DOT_TRANSPARENT = YES
#EXTRACT_ALL = YES
HAVE_DOT = YES
HIDE_UNDOC_RELATIONS = YES
MAX_DOT_GRAPH_DEPTH = 0
RECURSIVE = YES
TEMPLATE_RELATIONS = YES
UML_LIMIT_NUM_FIELDS = 0
UML_LOOK = NO
52 changes: 27 additions & 25 deletions external/ghc/cli.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <cstdlib>
#include <functional>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <sstream>
Expand Down Expand Up @@ -66,16 +67,24 @@ class CLI
struct Info
{
ValuePtr valPtr;
std::function<void(std::string, std::string, ValuePtr)> converter;
std::function<void(std::string, std::string, const Info&)> converter;
std::string help;
std::string category;
std::function<void(std::string)> triggerCallback;
std::function<bool()> condition;
int64_t minVal{std::numeric_limits<int64_t>::min()};
int64_t maxVal{std::numeric_limits<int64_t>::max()};
Info& dependsOn(std::function<bool()> dependCondition)
{
condition = std::move(dependCondition);
return *this;
}
Info& range(int64_t minV, int64_t maxV)
{
minVal = minV;
maxVal = maxV;
return *this;
}
};
CLI(int argc, char* argv[])
{
Expand All @@ -98,24 +107,10 @@ class CLI
static_assert(Contains<T*, ValuePtr>::value, "CLI: supported option types are only bool, int, std::int64_t, std::string or std::vector<std::string>");
auto iter = handler.insert({names,
{&destVal,
[](const std::string& name, const std::string& arg, ValuePtr valp) {
[](const std::string& name, const std::string& arg, const Info& valInfo) {
std::visit(visitor{[name, arg](bool* val) { *val = !*val; },
[name, arg](int* val) {
errno = 0;
char* endPtr{};
*val = static_cast<int>(std::strtol(arg.c_str(), &endPtr, 0));
if (errno > 0 || endPtr != arg.c_str() + arg.length()) {
throw std::runtime_error("Conversion error for option " + name);
}
},
[name, arg](std::int64_t* val) {
errno = 0;
char* endPtr{};
*val = std::strtoll(arg.c_str(), &endPtr, 0);
if (errno > 0 || endPtr != arg.c_str() + arg.length()) {
throw std::runtime_error("Conversion error for option " + name);
}
},
[name, arg, &valInfo](int* val) { handleInt(val, arg, name, valInfo); },
[name, arg, &valInfo](std::int64_t* val) { handleInt(val, arg, name, valInfo); },
[name, arg](std::string* val) { *val = arg; }, [name, arg](std::vector<std::string>* val) { val->push_back(arg); },
[name, arg](Combo* val) {
int idx = 0;
Expand All @@ -130,7 +125,7 @@ class CLI
}

},
valp);
valInfo.valPtr);
},
description,
currentCategory,
Expand All @@ -143,7 +138,7 @@ class CLI
{
callbackArgs.push_back(T{});
auto& val = std::get<T>(callbackArgs.back());
option(names, val, description, [callback,&val](std::string name){ callback(name, val); });
return option(names, val, description, [callback,&val](std::string name){ callback(name, val); });
}
void positional(std::vector<std::string>& dest, std::string description = std::string())
{
Expand Down Expand Up @@ -193,6 +188,17 @@ class CLI
std::cout << "...\n " << positionalHelp << "\n" << std::endl;
}
private:
template <typename T>
static void handleInt(T* val, const std::string& arg, const std::string& name, const Info& info) {
errno = 0;
char* endPtr{};
long long int llVal = static_cast<long long int>(std::strtoll(arg.c_str(), &endPtr, 0));
if (errno > 0 || endPtr != arg.c_str() + arg.length() || llVal < std::numeric_limits<T>::min() || llVal > std::numeric_limits<T>::max() || llVal < info.minVal || llVal > info.maxVal) {
throw std::runtime_error("Conversion error for option: " + name);
}
*val = static_cast<T>(llVal);
}

bool handleOption(std::vector<std::string>::iterator& iter)
{
static const std::map<std::string,bool> boolKeys = {{"true", true}, {"false", false}, {"yes", true}, {"no", false}, {"on", true}, {"off", false}};
Expand All @@ -213,11 +219,7 @@ class CLI
if(iter == argList.end()) {
throw std::runtime_error("Missing argument to option " + name);
}
errno = 0;
info.converter(name, *iter++, info.valPtr);
if(errno) {
throw std::runtime_error("Conversion error for option " + name);
}
info.converter(name, *iter++, info);
}
else if(iter != argList.end() && boolKeys.count(*iter)) {
*std::get<bool*>(info.valPtr) = boolKeys.at(*iter++);
Expand Down
Loading

0 comments on commit 5f34728

Please sign in to comment.