mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
Allow builds on MSVC (#518)
* Import cxxopts to replace getopts usage * Add visual studio build things * Fixup abseil build parts * Replace __attribute__((unused)) with ABSL_ATTRIBUTE_UNUSED * Fixup minor windows build issues * Replace getopts usage * Temporarily fixup .rc files * More minor windows fixes * Get a working build * Revert .rc files * Revert changes to nodedb
This commit is contained in:
parent
52b2b3bf44
commit
0195152e05
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -35,6 +35,7 @@ testnet_tmp
|
||||||
|
|
||||||
*.pid
|
*.pid
|
||||||
vsproject/
|
vsproject/
|
||||||
|
.vs
|
||||||
|
|
||||||
daemon.ini
|
daemon.ini
|
||||||
lokinet-win32.exe
|
lokinet-win32.exe
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
cmake_minimum_required(VERSION 3.6.0)
|
cmake_minimum_required(VERSION 3.6.0)
|
||||||
|
|
||||||
set(PROJECT_NAME lokinet)
|
set(PROJECT_NAME lokinet)
|
||||||
project(${PROJECT_NAME} C CXX ASM)
|
project(${PROJECT_NAME} C CXX)
|
||||||
|
|
||||||
# Core options
|
# Core options
|
||||||
option(USE_AVX2 "enable avx2 code" )
|
option(USE_AVX2 "enable avx2 code" )
|
||||||
|
@ -28,6 +28,14 @@ if(CCACHE_PROGRAM)
|
||||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (MSVC_VERSION)
|
||||||
|
enable_language(ASM_MASM)
|
||||||
|
list(APPEND CMAKE_ASM_MASM_SOURCE_FILE_EXTENSIONS s)
|
||||||
|
add_definitions(/D_WIN32_WINNT=0x0600 /DNOMINMAX /DSODIUM_STATIC)
|
||||||
|
else()
|
||||||
|
enable_language(ASM)
|
||||||
|
endif(MSVC_VERSION)
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||||
# check if we have the (saner) emulation of epoll here
|
# check if we have the (saner) emulation of epoll here
|
||||||
# it's basically linux epoll but with a sane method of
|
# it's basically linux epoll but with a sane method of
|
||||||
|
@ -72,6 +80,7 @@ if (WIN32 AND NOT STATIC_LINK_RUNTIME)
|
||||||
message("for release builds, turn on STATIC_LINK_RUNTIME in cmake options")
|
message("for release builds, turn on STATIC_LINK_RUNTIME in cmake options")
|
||||||
endif(WIN32 AND NOT STATIC_LINK_RUNTIME)
|
endif(WIN32 AND NOT STATIC_LINK_RUNTIME)
|
||||||
|
|
||||||
|
add_subdirectory(vendor/cxxopts)
|
||||||
add_subdirectory(vendor/nlohmann)
|
add_subdirectory(vendor/nlohmann)
|
||||||
|
|
||||||
# still need the headers unconditionally
|
# still need the headers unconditionally
|
||||||
|
@ -90,11 +99,13 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
add_compile_options(-Wno-unknown-warning-option)
|
add_compile_options(-Wno-unknown-warning-option)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT MSVC_VERSION)
|
||||||
add_compile_options(-Wall -Wextra -Wno-unknown-pragmas)
|
add_compile_options(-Wall -Wextra -Wno-unknown-pragmas)
|
||||||
# vla are evil
|
# vla are evil
|
||||||
add_compile_options(-Wvla)
|
add_compile_options(-Wvla)
|
||||||
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fpermissive>)
|
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fpermissive>)
|
||||||
add_compile_options(-Wno-unused-function -Wno-deprecated-declarations -Wno-unknown-pragmas)
|
add_compile_options(-Wno-unused-function -Wno-deprecated-declarations -Wno-unknown-pragmas)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
add_compile_options(-Wthread-safety)
|
add_compile_options(-Wthread-safety)
|
||||||
|
@ -127,7 +138,7 @@ if (WOW64_CROSS_COMPILE OR WIN64_CROSS_COMPILE)
|
||||||
endif()
|
endif()
|
||||||
endif(WOW64_CROSS_COMPILE OR WIN64_CROSS_COMPILE)
|
endif(WOW64_CROSS_COMPILE OR WIN64_CROSS_COMPILE)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32 AND NOT MSVC_VERSION)
|
||||||
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-bad-function-cast>)
|
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-bad-function-cast>)
|
||||||
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-cast-function-type>)
|
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-cast-function-type>)
|
||||||
# unlike unix where you get a *single* compiler ID string in .comment
|
# unlike unix where you get a *single* compiler ID string in .comment
|
||||||
|
@ -135,7 +146,7 @@ if(WIN32)
|
||||||
# to .r[o]data section one after the other!
|
# to .r[o]data section one after the other!
|
||||||
add_compile_options(-fno-ident)
|
add_compile_options(-fno-ident)
|
||||||
set(FS_LIB stdc++fs)
|
set(FS_LIB stdc++fs)
|
||||||
endif(WIN32)
|
endif()
|
||||||
|
|
||||||
if(DEBIAN)
|
if(DEBIAN)
|
||||||
add_definitions(-DDEBIAN)
|
add_definitions(-DDEBIAN)
|
||||||
|
@ -184,10 +195,10 @@ if(TESTNET)
|
||||||
add_definitions(-DTESTNET=1)
|
add_definitions(-DTESTNET=1)
|
||||||
endif(TESTNET)
|
endif(TESTNET)
|
||||||
|
|
||||||
if(NOT DEBIAN)
|
if(NOT DEBIAN AND NOT MSVC_VERSION)
|
||||||
set(OPTIMIZE_FLAGS -O3)
|
set(OPTIMIZE_FLAGS -O3)
|
||||||
set(DEBUG_FLAGS -O0 -g3)
|
set(DEBUG_FLAGS -O0 -g3)
|
||||||
endif(NOT DEBIAN)
|
endif()
|
||||||
|
|
||||||
if(ASAN)
|
if(ASAN)
|
||||||
set(DEBUG_FLAGS ${DEBUG_FLAGS} -fsanitize=address -fno-omit-frame-pointer)
|
set(DEBUG_FLAGS ${DEBUG_FLAGS} -fsanitize=address -fno-omit-frame-pointer)
|
||||||
|
@ -232,8 +243,9 @@ endif(NON_PC_TARGET)
|
||||||
add_compile_options(${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS})
|
add_compile_options(${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS})
|
||||||
|
|
||||||
if(NOT GIT_VERSION)
|
if(NOT GIT_VERSION)
|
||||||
exec_program("git" ${CMAKE_CURRENT_SOURCE_DIR} ARGS "rev-parse --short HEAD" OUTPUT_VARIABLE GIT_VERSION)
|
exec_program("git" ${CMAKE_CURRENT_SOURCE_DIR} ARGS "rev-parse --short HEAD" OUTPUT_VARIABLE GIT_VERSION_UNSTRIP)
|
||||||
add_definitions(-DGIT_REV="${GIT_VERSION}")
|
string(STRIP "${GIT_VERSION_UNSTRIP}" GIT_VERSION)
|
||||||
|
add_definitions("-DGIT_REV=\"${GIT_VERSION}\"")
|
||||||
endif(NOT GIT_VERSION)
|
endif(NOT GIT_VERSION)
|
||||||
|
|
||||||
if(RELEASE_MOTTO)
|
if(RELEASE_MOTTO)
|
||||||
|
@ -320,7 +332,7 @@ if(UNIX)
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
get_filename_component(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-windows.c ABSOLUTE)
|
get_filename_component(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-windows.c ABSOLUTE)
|
||||||
get_filename_component(EV_SRC "llarp/ev/ev_win32.cpp" ABSOLUTE)
|
get_filename_component(EV_SRC "llarp/ev/ev_win32.cpp" ABSOLUTE)
|
||||||
add_definitions(-DWIN32_LEAN_AND_MEAN -DWIN32 -DWINVER=0x500 -D_WIN32_WINNT=0x500)
|
add_definitions(-DWIN32_LEAN_AND_MEAN -DWIN32 -DWINVER=0x0602 -D_WIN32_WINNT=0x0602)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "What operating system _are_ you building on/for?")
|
message(FATAL_ERROR "What operating system _are_ you building on/for?")
|
||||||
endif(UNIX)
|
endif(UNIX)
|
||||||
|
@ -366,12 +378,17 @@ target_link_libraries(${ABYSS_LIB} PUBLIC ${PLATFORM_LIB})
|
||||||
if (NOT WIN32)
|
if (NOT WIN32)
|
||||||
add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp)
|
add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp)
|
||||||
target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} Threads::Threads)
|
target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} Threads::Threads)
|
||||||
else()
|
elseif(NOT MSVC_VERSION)
|
||||||
add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp llarp/win32/abyss.rc)
|
add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp llarp/win32/abyss.rc)
|
||||||
target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} ${STATIC_LIB} ws2_32)
|
target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} ${STATIC_LIB} ws2_32)
|
||||||
|
else()
|
||||||
|
add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp)
|
||||||
|
target_link_libraries(${ABYSS_EXE} PUBLIC ${ABYSS_LIB} ${STATIC_LIB} ws2_32)
|
||||||
endif(NOT WIN32)
|
endif(NOT WIN32)
|
||||||
|
|
||||||
target_include_directories(${ABYSS_LIB} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/${ABYSS}/include")
|
target_include_directories(${ABYSS_LIB} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/${ABYSS}/include")
|
||||||
target_include_directories(${ABYSS_EXE} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/${ABYSS}/include")
|
target_include_directories(${ABYSS_EXE} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/${ABYSS}/include")
|
||||||
|
|
||||||
# for freebsd
|
# for freebsd
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
target_include_directories(${ABYSS_LIB} PUBLIC /usr/local/include)
|
target_include_directories(${ABYSS_LIB} PUBLIC /usr/local/include)
|
||||||
|
@ -395,8 +412,10 @@ if(SHADOW)
|
||||||
else()
|
else()
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
add_executable(${EXE} ${EXE_SRC})
|
add_executable(${EXE} ${EXE_SRC})
|
||||||
else()
|
elseif(NOT MSVC_VERSION)
|
||||||
add_executable(${EXE} ${EXE_SRC} llarp/win32/version.rc)
|
add_executable(${EXE} ${EXE_SRC} llarp/win32/version.rc)
|
||||||
|
else()
|
||||||
|
add_executable(${EXE} ${EXE_SRC})
|
||||||
endif(NOT WIN32)
|
endif(NOT WIN32)
|
||||||
|
|
||||||
add_log_tag(${EXE})
|
add_log_tag(${EXE})
|
||||||
|
@ -424,6 +443,6 @@ endif(SHADOW)
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
if (NOT SHADOW)
|
if (NOT SHADOW AND NOT MSVC_VERSION)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
endif()
|
endif()
|
||||||
|
|
16
CMakeSettings.json
Normal file
16
CMakeSettings.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "x64-Debug",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"configurationType": "Debug",
|
||||||
|
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||||
|
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
|
||||||
|
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
|
||||||
|
"cmakeCommandArgs": "",
|
||||||
|
"buildCommandArgs": "-v",
|
||||||
|
"ctestCommandArgs": "",
|
||||||
|
"variables": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -19,8 +19,7 @@
|
||||||
/* C++Builder defines a "random" macro */
|
/* C++Builder defines a "random" macro */
|
||||||
#undef random
|
#undef random
|
||||||
|
|
||||||
static const randombytes_implementation *implementation =
|
static const randombytes_implementation *implementation = 0;
|
||||||
&randombytes_salsa20_implementation;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
randombytes_init_if_needed(void)
|
randombytes_init_if_needed(void)
|
||||||
|
|
|
@ -70,7 +70,11 @@ typedef NTSTATUS(FAR PASCAL *CNGAPI_DRBG)(BCRYPT_ALG_HANDLE, UCHAR *, ULONG,
|
||||||
|
|
||||||
#ifndef TLS
|
#ifndef TLS
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define TLS __declspec(thread)
|
||||||
|
#else
|
||||||
#define TLS __thread
|
#define TLS __thread
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define TLS
|
#define TLS
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
#include <config.hpp> // for ensure_config
|
#include <config.hpp> // for ensure_config
|
||||||
#include <libgen.h>
|
|
||||||
#include <llarp.h>
|
#include <llarp.h>
|
||||||
#include <util/fs.hpp>
|
#include <util/fs.hpp>
|
||||||
#include <util/logger.hpp>
|
#include <util/logger.hpp>
|
||||||
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#if !defined(_WIN32) && !defined(__OpenBSD__)
|
#if !defined(_WIN32) && !defined(__OpenBSD__)
|
||||||
#include <wordexp.h>
|
#include <wordexp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cxxopts.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -104,43 +103,75 @@ main(int argc, char *argv[])
|
||||||
absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
|
absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int opt = 0;
|
// clang-format off
|
||||||
|
cxxopts::Options options(
|
||||||
|
"lokinet",
|
||||||
|
"Lokinet is a private, decentralized and IP based overlay network for the internet"
|
||||||
|
);
|
||||||
|
options.add_options()
|
||||||
|
("v,verbose", "Verbose", cxxopts::value<bool>())
|
||||||
|
("h,help", "help", cxxopts::value<bool>())
|
||||||
|
("g,generate", "generate config", cxxopts::value<bool>())
|
||||||
|
("c,config", "generate config", cxxopts::value<bool>())
|
||||||
|
("r,router", "run as router", cxxopts::value<bool>())
|
||||||
|
("f,force", "overwrite", cxxopts::value<bool>());
|
||||||
|
options.parse_positional({"config_file"});
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
bool genconfigOnly = false;
|
bool genconfigOnly = false;
|
||||||
bool asRouter = false;
|
bool asRouter = false;
|
||||||
bool overWrite = false;
|
bool overWrite = false;
|
||||||
while((opt = getopt(argc, argv, "hgcfrv")) != -1)
|
|
||||||
{
|
|
||||||
switch(opt)
|
|
||||||
{
|
|
||||||
case 'v':
|
|
||||||
SetLogLevel(llarp::eLogDebug);
|
|
||||||
llarp::LogDebug("debug logging activated");
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
return printHelp(argv[0], 0);
|
|
||||||
case 'g':
|
|
||||||
genconfigOnly = true;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
genconfigOnly = true;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
asRouter = true;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
overWrite = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return printHelp(argv[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string conffname; // suggestions: confFName? conf_fname?
|
std::string conffname; // suggestions: confFName? conf_fname?
|
||||||
|
|
||||||
if(optind < argc)
|
try
|
||||||
|
{
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
if(result.count("verbose") > 0)
|
||||||
|
{
|
||||||
|
SetLogLevel(llarp::eLogDebug);
|
||||||
|
llarp::LogDebug("debug logging activated");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result.count("help"))
|
||||||
|
{
|
||||||
|
return printHelp(argv[0], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result.count("generate") > 0 || result.count("config") > 0)
|
||||||
|
{
|
||||||
|
genconfigOnly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result.count("force") > 0)
|
||||||
|
{
|
||||||
|
overWrite = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result.count("router") > 0)
|
||||||
|
{
|
||||||
|
asRouter = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result.count("config_file") > 0)
|
||||||
|
{
|
||||||
|
auto vec = result["config_file"].as< std::vector< std::string > >();
|
||||||
|
if(!vec.empty())
|
||||||
|
{
|
||||||
|
conffname = vec[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const cxxopts::option_not_exists_exception& ex)
|
||||||
|
{
|
||||||
|
std::cerr << ex.what();
|
||||||
|
return printHelp(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!conffname.empty())
|
||||||
{
|
{
|
||||||
// when we have an explicit filepath
|
// when we have an explicit filepath
|
||||||
fs::path fname = fs::path(argv[optind]);
|
fs::path fname = fs::path(conffname);
|
||||||
fs::path basedir = fname.parent_path();
|
fs::path basedir = fname.parent_path();
|
||||||
conffname = fname.string();
|
conffname = fname.string();
|
||||||
conffname = resolvePath(conffname);
|
conffname = resolvePath(conffname);
|
||||||
|
|
|
@ -77,6 +77,7 @@
|
||||||
* - t_tun_in6_addr: struct in6_addr/IN6_ADDR
|
* - t_tun_in6_addr: struct in6_addr/IN6_ADDR
|
||||||
*/
|
*/
|
||||||
#if defined Windows
|
#if defined Windows
|
||||||
|
#include <windows.h>
|
||||||
#include <in6addr.h>
|
#include <in6addr.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
typedef HANDLE t_tun;
|
typedef HANDLE t_tun;
|
||||||
|
|
|
@ -15,7 +15,7 @@ struct DemoHandler : public abyss::httpd::IRPCHandler
|
||||||
|
|
||||||
absl::optional< Response >
|
absl::optional< Response >
|
||||||
HandleJSONRPC(Method_t method,
|
HandleJSONRPC(Method_t method,
|
||||||
__attribute__((unused)) const Params& params) override
|
ABSL_ATTRIBUTE_UNUSED const Params& params) override
|
||||||
{
|
{
|
||||||
llarp::LogInfo("method: ", method);
|
llarp::LogInfo("method: ", method);
|
||||||
return Response::object();
|
return Response::object();
|
||||||
|
@ -50,7 +50,7 @@ struct DemoCall : public abyss::http::IRPCClientHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PopulateReqHeaders(__attribute__((unused))
|
PopulateReqHeaders(ABSL_ATTRIBUTE_UNUSED
|
||||||
abyss::http::Headers_t& hdr) override
|
abyss::http::Headers_t& hdr) override
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ struct DemoServer : public abyss::httpd::BaseReqHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
|
main(ABSL_ATTRIBUTE_UNUSED int argc, ABSL_ATTRIBUTE_UNUSED char* argv[])
|
||||||
{
|
{
|
||||||
// Ignore on Windows, we don't even get SIGPIPE (even though native *and*
|
// Ignore on Windows, we don't even get SIGPIPE (even though native *and*
|
||||||
// emulated UNIX pipes exist - CreatePipe(2), pipe(3))
|
// emulated UNIX pipes exist - CreatePipe(2), pipe(3))
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace abyss
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
OnTick(__attribute__((unused)) llarp_tcp_conn* conn)
|
OnTick(ABSL_ATTRIBUTE_UNUSED llarp_tcp_conn* conn)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ typedef uint32 utp_link_t;
|
||||||
#pragma warning(disable : 4200)
|
#pragma warning(disable : 4200)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <absl/base/attributes.h>
|
||||||
|
|
||||||
typedef uint32 (*utp_hash_compute_t)(const void *keyp, size_t keysize);
|
typedef uint32 (*utp_hash_compute_t)(const void *keyp, size_t keysize);
|
||||||
typedef uint (*utp_hash_equal_t)(const void *key_a, const void *key_b,
|
typedef uint (*utp_hash_equal_t)(const void *key_a, const void *key_b,
|
||||||
size_t keysize);
|
size_t keysize);
|
||||||
|
@ -146,12 +148,12 @@ class utpHashTable
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static uint
|
static uint
|
||||||
compare(const void *k1, const void *k2, __attribute__((unused)) size_t ks)
|
compare(const void *k1, const void *k2, ABSL_ATTRIBUTE_UNUSED size_t ks)
|
||||||
{
|
{
|
||||||
return *((K *)k1) == *((K *)k2);
|
return *((K *)k1) == *((K *)k2);
|
||||||
}
|
}
|
||||||
static uint32
|
static uint32
|
||||||
compute_hash(const void *k, __attribute__((unused)) size_t ks)
|
compute_hash(const void *k, ABSL_ATTRIBUTE_UNUSED size_t ks)
|
||||||
{
|
{
|
||||||
return ((K *)k)->compute_hash();
|
return ((K *)k)->compute_hash();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <mach/mach_time.h>
|
#include <mach/mach_time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <absl/base/attributes.h>
|
||||||
#include "utp_utils.h"
|
#include "utp_utils.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -286,20 +287,20 @@ utp_default_get_udp_overhead(utp_callback_arguments *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64
|
uint64
|
||||||
utp_default_get_random(__attribute__((unused)) utp_callback_arguments *args)
|
utp_default_get_random(ABSL_ATTRIBUTE_UNUSED utp_callback_arguments *args)
|
||||||
{
|
{
|
||||||
return rand();
|
return rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64
|
uint64
|
||||||
utp_default_get_milliseconds(__attribute__((unused))
|
utp_default_get_milliseconds(ABSL_ATTRIBUTE_UNUSED
|
||||||
utp_callback_arguments *args)
|
utp_callback_arguments *args)
|
||||||
{
|
{
|
||||||
return UTP_GetMilliseconds();
|
return UTP_GetMilliseconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64
|
uint64
|
||||||
utp_default_get_microseconds(__attribute__((unused))
|
utp_default_get_microseconds(ABSL_ATTRIBUTE_UNUSED
|
||||||
utp_callback_arguments *args)
|
utp_callback_arguments *args)
|
||||||
{
|
{
|
||||||
return UTP_GetMicroseconds();
|
return UTP_GetMicroseconds();
|
||||||
|
|
|
@ -46,12 +46,12 @@ set(LIB_UTIL_SRC
|
||||||
|
|
||||||
add_library(${UTIL_LIB} STATIC ${LIB_UTIL_SRC})
|
add_library(${UTIL_LIB} STATIC ${LIB_UTIL_SRC})
|
||||||
target_include_directories(${UTIL_LIB} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include)
|
target_include_directories(${UTIL_LIB} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include)
|
||||||
target_link_libraries(${UTIL_LIB} PUBLIC absl::synchronization)
|
target_link_libraries(${UTIL_LIB} PUBLIC absl::synchronization absl::hash)
|
||||||
target_link_libraries(${UTIL_LIB} PUBLIC nlohmann_json::nlohmann_json)
|
target_link_libraries(${UTIL_LIB} PUBLIC nlohmann_json::nlohmann_json)
|
||||||
|
|
||||||
# cut back on fluff
|
# cut back on fluff
|
||||||
if (NOT WIN32)
|
if (NOT WIN32)
|
||||||
target_link_libraries(${UTIL_LIB} PUBLIC absl::optional absl::variant absl::strings absl::hash cppbackport)
|
target_link_libraries(${UTIL_LIB} PUBLIC absl::optional absl::variant absl::strings cppbackport)
|
||||||
endif(NOT WIN32)
|
endif(NOT WIN32)
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
|
@ -239,7 +239,7 @@ endif()
|
||||||
|
|
||||||
add_library(${STATIC_LIB} STATIC ${LIB_SRC})
|
add_library(${STATIC_LIB} STATIC ${LIB_SRC})
|
||||||
set(LIBS ${LIBS} libutp)
|
set(LIBS ${LIBS} libutp)
|
||||||
target_link_libraries(${STATIC_LIB} PUBLIC ${ABYSS_LIB} ${PLATFORM_LIB} ${UTIL_LIB} ${CRYPTOGRAPHY_LIB} ${LIBS})
|
target_link_libraries(${STATIC_LIB} PUBLIC cxxopts ${ABYSS_LIB} ${PLATFORM_LIB} ${UTIL_LIB} ${CRYPTOGRAPHY_LIB} ${LIBS})
|
||||||
|
|
||||||
if(WITH_SHARED)
|
if(WITH_SHARED)
|
||||||
add_library(${SHARED_LIB} SHARED ${LIB_SRC})
|
add_library(${SHARED_LIB} SHARED ${LIB_SRC})
|
||||||
|
|
|
@ -16,11 +16,9 @@
|
||||||
#include <util/scheduler.hpp>
|
#include <util/scheduler.hpp>
|
||||||
|
|
||||||
#include <absl/strings/str_split.h>
|
#include <absl/strings/str_split.h>
|
||||||
#include <getopt.h>
|
#include <cxxopts.hpp>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <sys/param.h> // for MIN
|
|
||||||
|
|
||||||
#if(__FreeBSD__) || (__OpenBSD__) || (__NetBSD__)
|
#if(__FreeBSD__) || (__OpenBSD__) || (__NetBSD__)
|
||||||
#include <pthread_np.h>
|
#include <pthread_np.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -645,50 +643,40 @@ extern "C"
|
||||||
const char *
|
const char *
|
||||||
handleBaseCmdLineArgs(int argc, char *argv[])
|
handleBaseCmdLineArgs(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const char *conffname = "daemon.ini";
|
|
||||||
int c;
|
// clang-format off
|
||||||
while(1)
|
cxxopts::Options options(
|
||||||
{
|
"lokinet",
|
||||||
static struct option long_options[] = {
|
"Lokinet is a private, decentralized and IP based overlay network for the internet"
|
||||||
{"config", required_argument, 0, 'c'},
|
);
|
||||||
{"logLevel", required_argument, 0, 'o'},
|
options.add_options()
|
||||||
{0, 0, 0, 0}};
|
("c,config", "Config file", cxxopts::value< std::string >()->default_value("daemon.ini"))
|
||||||
int option_index = 0;
|
("o,logLevel", "logging level");
|
||||||
c = getopt_long(argc, argv, "c:o:", long_options, &option_index);
|
// clang-format on
|
||||||
if(c == -1)
|
|
||||||
break;
|
auto result = options.parse(argc, argv);
|
||||||
switch(c)
|
std::string logLevel = result["logLevel"].as< std::string >();
|
||||||
{
|
|
||||||
case 0:
|
if(logLevel == "debug")
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
conffname = optarg;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
if(strncmp(optarg, "debug", std::min(strlen(optarg), size_t(5))) == 0)
|
|
||||||
{
|
{
|
||||||
cSetLogLevel(eLogDebug);
|
cSetLogLevel(eLogDebug);
|
||||||
}
|
}
|
||||||
else if(strncmp(optarg, "info", std::min(strlen(optarg), size_t(4)))
|
else if(logLevel == "info")
|
||||||
== 0)
|
|
||||||
{
|
{
|
||||||
cSetLogLevel(eLogInfo);
|
cSetLogLevel(eLogInfo);
|
||||||
}
|
}
|
||||||
else if(strncmp(optarg, "warn", std::min(strlen(optarg), size_t(4)))
|
else if(logLevel == "warn")
|
||||||
== 0)
|
|
||||||
{
|
{
|
||||||
cSetLogLevel(eLogWarn);
|
cSetLogLevel(eLogWarn);
|
||||||
}
|
}
|
||||||
else if(strncmp(optarg, "error", std::min(strlen(optarg), size_t(5)))
|
else if(logLevel == "error")
|
||||||
== 0)
|
|
||||||
{
|
{
|
||||||
cSetLogLevel(eLogError);
|
cSetLogLevel(eLogError);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
// this isn't thread safe, but reconfiguring during run is likely unsafe either way
|
||||||
break;
|
static std::string confname = result["config"].as< std::string >();
|
||||||
}
|
|
||||||
}
|
return confname.c_str();
|
||||||
return conffname;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,7 @@ dns_iptracker_init()
|
||||||
|
|
||||||
// not sure we want tunGatewayIP... we'll know when we get further
|
// not sure we want tunGatewayIP... we'll know when we get further
|
||||||
bool
|
bool
|
||||||
dns_iptracker_setup_dotLokiLookup(dotLokiLookup *dll,
|
dns_iptracker_setup_dotLokiLookup(dotLokiLookup *dll, ABSL_ATTRIBUTE_UNUSED
|
||||||
__attribute__((unused))
|
|
||||||
llarp::huint32_t tunGatewayIp)
|
llarp::huint32_t tunGatewayIp)
|
||||||
{
|
{
|
||||||
dll->ip_tracker = &g_dns_iptracker;
|
dll->ip_tracker = &g_dns_iptracker;
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
#include <netdb.h> /* getaddrinfo, getnameinfo */
|
#include <netdb.h> /* getaddrinfo, getnameinfo */
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h> /* close */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h> /* exit */
|
#include <stdlib.h> /* exit */
|
||||||
#include <string.h> /* memset */
|
#include <string.h> /* memset */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h> /* close */
|
|
||||||
|
|
||||||
#include <algorithm> // for std::find_if
|
#include <algorithm> // for std::find_if
|
||||||
#include <stdio.h> // sprintf
|
#include <stdio.h> // sprintf
|
||||||
|
@ -814,7 +814,7 @@ llarp_dnsc_init(struct dnsc_context *const dnsc, llarp::Logic *const logic,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
llarp_dnsc_stop(__attribute__((unused)) struct dnsc_context *const dnsc)
|
llarp_dnsc_stop(ABSL_ATTRIBUTE_UNUSED struct dnsc_context *const dnsc)
|
||||||
{
|
{
|
||||||
// delete(sockaddr_in *)dnsc->server; // deallocation
|
// delete(sockaddr_in *)dnsc->server; // deallocation
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -9,9 +9,14 @@
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <wspiapi.h>
|
#include <wspiapi.h>
|
||||||
#ifndef ssize_t
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <BaseTsd.h>
|
||||||
|
typedef SSIZE_T ssize_t;
|
||||||
|
#else
|
||||||
#define ssize_t long
|
#define ssize_t long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
// writev
|
// writev
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <win32/win32_up.h>
|
#include <win32/win32_up.h>
|
||||||
|
|
|
@ -35,6 +35,12 @@ win32_tun_io::queue_write(const byte_t* buf, size_t sz)
|
||||||
bool
|
bool
|
||||||
win32_tun_io::setup()
|
win32_tun_io::setup()
|
||||||
{
|
{
|
||||||
|
// Create a critical section to synchronise access to the TUN handler.
|
||||||
|
// This *probably* has the effect of making packets move in order now
|
||||||
|
// as only one IOCP thread will have access to the TUN handler at a
|
||||||
|
// time
|
||||||
|
InitializeCriticalSection(&HandlerMtx);
|
||||||
|
|
||||||
if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, 0) == -1)
|
if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, 0) == -1)
|
||||||
{
|
{
|
||||||
llarp::LogWarn("failed to start interface");
|
llarp::LogWarn("failed to start interface");
|
||||||
|
@ -59,12 +65,6 @@ win32_tun_io::setup()
|
||||||
if(tunif->tun_fd == INVALID_HANDLE_VALUE)
|
if(tunif->tun_fd == INVALID_HANDLE_VALUE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Create a critical section to synchronise access to the TUN handler.
|
|
||||||
// This *probably* has the effect of making packets move in order now
|
|
||||||
// as only one IOCP thread will have access to the TUN handler at a
|
|
||||||
// time
|
|
||||||
InitializeCriticalSection(&HandlerMtx);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <ev/pipe.hpp>
|
#include <ev/pipe.hpp>
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
llarp_ev_pkt_pipe::llarp_ev_pkt_pipe(llarp_ev_loop_ptr loop)
|
llarp_ev_pkt_pipe::llarp_ev_pkt_pipe(llarp_ev_loop_ptr loop)
|
||||||
|
|
|
@ -38,14 +38,14 @@ namespace llarp
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DecodeKey(__attribute__((unused)) const llarp_buffer_t& key,
|
DecodeKey(ABSL_ATTRIBUTE_UNUSED const llarp_buffer_t& key,
|
||||||
__attribute__((unused)) llarp_buffer_t* buf) override
|
ABSL_ATTRIBUTE_UNUSED llarp_buffer_t* buf) override
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HandleMessage(__attribute__((unused)) AbstractRouter* router) const override
|
HandleMessage(ABSL_ATTRIBUTE_UNUSED AbstractRouter* router) const override
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include <util/logger.hpp>
|
#include <util/logger.hpp>
|
||||||
#include <util/metrics.hpp>
|
#include <util/metrics.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace llarp
|
namespace llarp
|
||||||
{
|
{
|
||||||
struct InboundMessageParser::msg_holder_t
|
struct InboundMessageParser::msg_holder_t
|
||||||
|
@ -21,18 +23,21 @@ namespace llarp
|
||||||
DHTImmediateMessage m;
|
DHTImmediateMessage m;
|
||||||
LR_CommitMessage c;
|
LR_CommitMessage c;
|
||||||
DiscardMessage x;
|
DiscardMessage x;
|
||||||
|
|
||||||
|
msg_holder_t() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
InboundMessageParser::InboundMessageParser(AbstractRouter* _router)
|
InboundMessageParser::InboundMessageParser(AbstractRouter* _router)
|
||||||
: router(_router)
|
: router(_router)
|
||||||
, from(nullptr)
|
, from(nullptr)
|
||||||
, msg(nullptr)
|
, msg(nullptr)
|
||||||
, holder(std::make_unique< msg_holder_t >())
|
, holder(new msg_holder_t())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
InboundMessageParser::~InboundMessageParser()
|
InboundMessageParser::~InboundMessageParser()
|
||||||
{
|
{
|
||||||
|
delete holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace llarp
|
||||||
ILinkMessage* msg;
|
ILinkMessage* msg;
|
||||||
|
|
||||||
struct msg_holder_t;
|
struct msg_holder_t;
|
||||||
std::unique_ptr< msg_holder_t > holder;
|
msg_holder_t *holder;
|
||||||
};
|
};
|
||||||
} // namespace llarp
|
} // namespace llarp
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -240,7 +240,7 @@ namespace llarp
|
||||||
|
|
||||||
for(const std::string &val : toSend)
|
for(const std::string &val : toSend)
|
||||||
{
|
{
|
||||||
ssize_t sentLen = 0;
|
int sentLen = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace llarp
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
checksumDstIPv4TCP(byte_t *pld, __attribute__((unused)) size_t psz,
|
checksumDstIPv4TCP(byte_t *pld, ABSL_ATTRIBUTE_UNUSED size_t psz,
|
||||||
size_t fragoff, size_t chksumoff, nuint32_t oSrcIP,
|
size_t fragoff, size_t chksumoff, nuint32_t oSrcIP,
|
||||||
nuint32_t oDstIP, nuint32_t nSrcIP, nuint32_t nDstIP)
|
nuint32_t oDstIP, nuint32_t nSrcIP, nuint32_t nDstIP)
|
||||||
{
|
{
|
||||||
|
@ -117,7 +117,7 @@ namespace llarp
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
checksumDstIPv4UDP(byte_t *pld, __attribute__((unused)) size_t psz,
|
checksumDstIPv4UDP(byte_t *pld, ABSL_ATTRIBUTE_UNUSED size_t psz,
|
||||||
size_t fragoff, nuint32_t oSrcIP, nuint32_t oDstIP,
|
size_t fragoff, nuint32_t oSrcIP, nuint32_t oDstIP,
|
||||||
nuint32_t nSrcIP, nuint32_t nDstIP)
|
nuint32_t nSrcIP, nuint32_t nDstIP)
|
||||||
{
|
{
|
||||||
|
@ -186,7 +186,7 @@ namespace llarp
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
checksumSrcIPv4TCP(byte_t *pld, __attribute__((unused)) size_t psz,
|
checksumSrcIPv4TCP(byte_t *pld, ABSL_ATTRIBUTE_UNUSED size_t psz,
|
||||||
size_t fragoff, size_t chksumoff, nuint32_t oSrcIP,
|
size_t fragoff, size_t chksumoff, nuint32_t oSrcIP,
|
||||||
nuint32_t oDstIP)
|
nuint32_t oDstIP)
|
||||||
{
|
{
|
||||||
|
@ -206,7 +206,7 @@ namespace llarp
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
checksumSrcIPv4UDP(byte_t *pld, __attribute__((unused)) size_t psz,
|
checksumSrcIPv4UDP(byte_t *pld, ABSL_ATTRIBUTE_UNUSED size_t psz,
|
||||||
size_t fragoff, nuint32_t oSrcIP, nuint32_t oDstIP)
|
size_t fragoff, nuint32_t oSrcIP, nuint32_t oDstIP)
|
||||||
{
|
{
|
||||||
if(fragoff > 6)
|
if(fragoff > 6)
|
||||||
|
|
|
@ -11,6 +11,12 @@
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <BaseTsd.h>
|
||||||
|
typedef SSIZE_T ssize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nodedb.hpp
|
* nodedb.hpp
|
||||||
*
|
*
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <util/threading.hpp>
|
#include <util/threading.hpp>
|
||||||
#include <util/time.hpp>
|
#include <util/time.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
|
@ -11,8 +11,8 @@ namespace llarp
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PoW::DecodeKey(__attribute__((unused)) const llarp_buffer_t& k,
|
PoW::DecodeKey(ABSL_ATTRIBUTE_UNUSED const llarp_buffer_t& k,
|
||||||
__attribute__((unused)) llarp_buffer_t* val)
|
ABSL_ATTRIBUTE_UNUSED llarp_buffer_t* val)
|
||||||
{
|
{
|
||||||
// TODO: implement me
|
// TODO: implement me
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace llarp
|
||||||
NetID::BEncode(llarp_buffer_t *buf) const
|
NetID::BEncode(llarp_buffer_t *buf) const
|
||||||
{
|
{
|
||||||
auto term = std::find(begin(), end(), '\0');
|
auto term = std::find(begin(), end(), '\0');
|
||||||
return bencode_write_bytestring(buf, begin(), std::distance(begin(), term));
|
return bencode_write_bytestring(buf, data(), std::distance(begin(), term));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -20,7 +20,7 @@ bool
|
||||||
llarp_buffer_t::writef(const char* fmt, ...)
|
llarp_buffer_t::writef(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
int written;
|
int written;
|
||||||
ssize_t sz = size_left();
|
size_t sz = size_left();
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
written = vsnprintf(reinterpret_cast< char* >(cur), sz, fmt, args);
|
written = vsnprintf(reinterpret_cast< char* >(cur), sz, fmt, args);
|
||||||
|
|
|
@ -128,12 +128,14 @@ struct llarp_buffer_t
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
bool
|
bool
|
||||||
writef(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
|
writef(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
|
||||||
;
|
|
||||||
#else
|
#elif defined(__MINGW64__) || defined(__MINGW32__)
|
||||||
bool
|
bool
|
||||||
writef(const char *fmt, ...)
|
writef(const char *fmt, ...)
|
||||||
__attribute__((__format__(__MINGW_PRINTF_FORMAT, 2, 3)));
|
__attribute__((__format__(__MINGW_PRINTF_FORMAT, 2, 3)));
|
||||||
;
|
#else
|
||||||
|
bool
|
||||||
|
writef(const char *fmt, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -16,7 +16,9 @@ namespace fs = std::experimental::filesystem;
|
||||||
namespace fs = cpp17::filesystem;
|
namespace fs = cpp17::filesystem;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace llarp
|
namespace llarp
|
||||||
{
|
{
|
||||||
|
@ -26,6 +28,15 @@ namespace llarp
|
||||||
using PathIter = std::function< void(const fs::path &, PathVisitor) >;
|
using PathIter = std::function< void(const fs::path &, PathVisitor) >;
|
||||||
|
|
||||||
static PathIter IterDir = [](const fs::path &path, PathVisitor visit) {
|
static PathIter IterDir = [](const fs::path &path, PathVisitor visit) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
for(auto &p : fs::directory_iterator(path))
|
||||||
|
{
|
||||||
|
if(!visit(p.path()))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
DIR *d = opendir(path.string().c_str());
|
DIR *d = opendir(path.string().c_str());
|
||||||
if(d == nullptr)
|
if(d == nullptr)
|
||||||
return;
|
return;
|
||||||
|
@ -42,6 +53,7 @@ namespace llarp
|
||||||
break;
|
break;
|
||||||
} while(ent);
|
} while(ent);
|
||||||
closedir(d);
|
closedir(d);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace llarp
|
} // namespace llarp
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef LLARP_UTIL_LOGGER_INTERNAL_HPP
|
#ifndef LLARP_UTIL_LOGGER_INTERNAL_HPP
|
||||||
#define LLARP_UTIL_LOGGER_INTERNAL_HPP
|
#define LLARP_UTIL_LOGGER_INTERNAL_HPP
|
||||||
|
|
||||||
|
#include <absl/time/clock.h>
|
||||||
|
#include <absl/time/time.h>
|
||||||
#include <util/time.hpp>
|
#include <util/time.hpp>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
@ -55,8 +57,7 @@ namespace llarp
|
||||||
(void)ts;
|
(void)ts;
|
||||||
return out << time_now_ms();
|
return out << time_now_ms();
|
||||||
#else
|
#else
|
||||||
auto now = llarp::Clock_t::to_time_t(llarp::Clock_t::now());
|
return out << absl::FormatTime(ts.format, absl::Now(), absl::LocalTimeZone());
|
||||||
return out << std::put_time(std::localtime(&now), ts.format);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include <util/mem.h>
|
#include <util/mem.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <absl/base/attributes.h>
|
||||||
|
|
||||||
namespace llarp
|
namespace llarp
|
||||||
{
|
{
|
||||||
void
|
void
|
||||||
|
@ -17,9 +19,9 @@ namespace llarp
|
||||||
} // namespace llarp
|
} // namespace llarp
|
||||||
|
|
||||||
void
|
void
|
||||||
llarp_mem_slab(__attribute__((unused)) struct llarp_alloc *mem,
|
llarp_mem_slab(ABSL_ATTRIBUTE_UNUSED struct llarp_alloc *mem,
|
||||||
__attribute__((unused)) uint32_t *buf,
|
ABSL_ATTRIBUTE_UNUSED uint32_t *buf,
|
||||||
__attribute__((unused)) size_t sz)
|
ABSL_ATTRIBUTE_UNUSED size_t sz)
|
||||||
{
|
{
|
||||||
// not implemented
|
// not implemented
|
||||||
abort();
|
abort();
|
||||||
|
|
|
@ -93,15 +93,4 @@ namespace llarp
|
||||||
|
|
||||||
} // namespace llarp
|
} // namespace llarp
|
||||||
|
|
||||||
#if __cplusplus < 201402L
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
template < typename T, typename... Args >
|
|
||||||
std::unique_ptr< T >
|
|
||||||
make_unique(Args &&... args)
|
|
||||||
{
|
|
||||||
return std::unique_ptr< T >(new T(std::forward< Args >(args)...));
|
|
||||||
}
|
|
||||||
} // namespace std
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace llarp
|
||||||
/// a lock that does nothing
|
/// a lock that does nothing
|
||||||
struct SCOPED_LOCKABLE NullLock
|
struct SCOPED_LOCKABLE NullLock
|
||||||
{
|
{
|
||||||
NullLock(__attribute__((unused)) const NullMutex* mtx)
|
NullLock(ABSL_ATTRIBUTE_UNUSED const NullMutex* mtx)
|
||||||
EXCLUSIVE_LOCK_FUNCTION(mtx)
|
EXCLUSIVE_LOCK_FUNCTION(mtx)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ upoll_wait_select(upoll_t* upq, upoll_event_t* evs, int nev, int timeout)
|
||||||
if(nev > FD_SETSIZE)
|
if(nev > FD_SETSIZE)
|
||||||
nev = FD_SETSIZE;
|
nev = FD_SETSIZE;
|
||||||
|
|
||||||
unote_t* nvec[nev];
|
unote_t** nvec = calloc(nev, sizeof(unote_t *));
|
||||||
int i, maxfd = 0, e = 0, nfds = 0;
|
int i, maxfd = 0, e = 0, nfds = 0;
|
||||||
|
|
||||||
fd_set pollin, pollout, pollerr;
|
fd_set pollin, pollout, pollerr;
|
||||||
|
@ -240,6 +240,7 @@ upoll_wait_select(upoll_t* upq, upoll_event_t* evs, int nev, int timeout)
|
||||||
if(rc == SOCKET_ERROR)
|
if(rc == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
assert(WSAGetLastError() == WSAENOTSOCK);
|
assert(WSAGetLastError() == WSAENOTSOCK);
|
||||||
|
free(nvec);
|
||||||
return -WSAGetLastError();
|
return -WSAGetLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,6 +270,7 @@ upoll_wait_select(upoll_t* upq, upoll_event_t* evs, int nev, int timeout)
|
||||||
++e;
|
++e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(nvec);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,5 +67,5 @@ if(NOT WIN32)
|
||||||
target_link_libraries(${TEST_EXE} PUBLIC absl::variant)
|
target_link_libraries(${TEST_EXE} PUBLIC absl::variant)
|
||||||
else()
|
else()
|
||||||
target_sources(${TEST_EXE} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/win32/test.rc")
|
target_sources(${TEST_EXE} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/win32/test.rc")
|
||||||
target_link_libraries(${TEST_EXE} PUBLIC ws2_32 iphlpapi)
|
target_link_libraries(${TEST_EXE} PUBLIC ws2_32 iphlpapi shlwapi)
|
||||||
endif(NOT WIN32)
|
endif(NOT WIN32)
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct AbyssTestBase : public ::testing::Test
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
CancelIt(void* u, __attribute__((unused)) uint64_t orig, uint64_t left)
|
CancelIt(void* u, ABSL_ATTRIBUTE_UNUSED uint64_t orig, uint64_t left)
|
||||||
{
|
{
|
||||||
if(left)
|
if(left)
|
||||||
return;
|
return;
|
||||||
|
@ -104,12 +104,12 @@ struct ClientHandler : public abyss::http::IRPCClientHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PopulateReqHeaders(__attribute__((unused)) abyss::http::Headers_t& hdr)
|
PopulateReqHeaders(ABSL_ATTRIBUTE_UNUSED abyss::http::Headers_t& hdr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HandleResponse(__attribute__((unused)) abyss::http::RPC_Response response)
|
HandleResponse(ABSL_ATTRIBUTE_UNUSED abyss::http::RPC_Response response)
|
||||||
{
|
{
|
||||||
test->AsyncStop();
|
test->AsyncStop();
|
||||||
return true;
|
return true;
|
||||||
|
@ -125,7 +125,7 @@ struct ServerHandler : public abyss::httpd::IRPCHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::optional< Response >
|
absl::optional< Response >
|
||||||
HandleJSONRPC(Method_t method, __attribute__((unused)) const Params& params)
|
HandleJSONRPC(Method_t method, ABSL_ATTRIBUTE_UNUSED const Params& params)
|
||||||
{
|
{
|
||||||
test->AssertMethod(method);
|
test->AssertMethod(method);
|
||||||
test->called = true;
|
test->called = true;
|
||||||
|
|
4
vendor/abseil-cpp/CMakeLists.txt
vendored
4
vendor/abseil-cpp/CMakeLists.txt
vendored
|
@ -69,11 +69,11 @@ endif()
|
||||||
list(APPEND ABSL_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
|
list(APPEND ABSL_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
# -std=X
|
# -std=X
|
||||||
if (WIN32)
|
if (WIN32 AND NOT MSVC_VERSION)
|
||||||
set(CMAKE_CXX_FLAGS "${ABSL_STD_CXX_FLAG} ${CMAKE_CXX_FLAGS} -fno-ident")
|
set(CMAKE_CXX_FLAGS "${ABSL_STD_CXX_FLAG} ${CMAKE_CXX_FLAGS} -fno-ident")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_CXX_FLAGS "${ABSL_STD_CXX_FLAG} ${CMAKE_CXX_FLAGS}")
|
set(CMAKE_CXX_FLAGS "${ABSL_STD_CXX_FLAG} ${CMAKE_CXX_FLAGS}")
|
||||||
endif(WIN32)
|
endif(WIN32 AND NOT MSVC_VERSION)
|
||||||
|
|
||||||
# -fexceptions
|
# -fexceptions
|
||||||
set(ABSL_EXCEPTIONS_FLAG "${CMAKE_CXX_EXCEPTIONS}")
|
set(ABSL_EXCEPTIONS_FLAG "${CMAKE_CXX_EXCEPTIONS}")
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
#pragma comment(lib, "shlwapi.lib")
|
||||||
#else
|
#else
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
|
@ -181,9 +181,9 @@ absl_cc_library(
|
||||||
NAME
|
NAME
|
||||||
leak_check
|
leak_check
|
||||||
HDRS
|
HDRS
|
||||||
"$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:leak_check.h>"
|
"leak_check.h"
|
||||||
SRCS
|
SRCS
|
||||||
"$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:leak_check.cc>"
|
"leak_check.cc"
|
||||||
COPTS
|
COPTS
|
||||||
${ABSL_DEFAULT_COPTS}
|
${ABSL_DEFAULT_COPTS}
|
||||||
DEPS
|
DEPS
|
||||||
|
|
8
vendor/cxxopts/.gitignore
vendored
Normal file
8
vendor/cxxopts/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
*.swp
|
||||||
|
build*
|
||||||
|
CMakeCache.txt
|
||||||
|
Makefile
|
||||||
|
CMakeFiles/
|
||||||
|
Testing/
|
||||||
|
CTestTestfile.cmake
|
||||||
|
cmake_install.cmake
|
70
vendor/cxxopts/.travis.yml
vendored
Normal file
70
vendor/cxxopts/.travis.yml
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
language: cpp
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: linux
|
||||||
|
env: COMPILER=g++-4.9
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- g++-4.9
|
||||||
|
sources: &sources
|
||||||
|
- llvm-toolchain-trusty-3.8
|
||||||
|
- llvm-toolchain-trusty-5.0
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- os: linux
|
||||||
|
env: COMPILER=g++-4.9 UNICODE_OPTIONS=-DCXXOPTS_USE_UNICODE_HELP=Yes
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- g++-4.9
|
||||||
|
sources: *sources
|
||||||
|
- os: linux
|
||||||
|
env: COMPILER=g++-5
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- g++-5
|
||||||
|
sources: *sources
|
||||||
|
- os: linux
|
||||||
|
env: COMPILER=g++-5 UNICODE_OPTIONS=-DCXXOPTS_USE_UNICODE_HELP=Yes
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- g++-5
|
||||||
|
sources: *sources
|
||||||
|
- os: linux
|
||||||
|
env: COMPILER=clang++-3.8 CXXFLAGS=-stdlib=libc++
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- clang-3.8
|
||||||
|
- libc++-dev
|
||||||
|
sources: *sources
|
||||||
|
- os: linux
|
||||||
|
env: COMPILER=clang++-3.8 CXXFLAGS=-stdlib=libc++ UNICODE_OPTIONS=-DCXXOPTS_USE_UNICODE_HELP=Yes
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- clang-3.8
|
||||||
|
- libc++-dev
|
||||||
|
sources: *sources
|
||||||
|
- os: linux
|
||||||
|
env: COMPILER=clang++-5.0 CMAKE_OPTIONS=-DCXXOPTS_CXX_STANDARD=17
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- clang-5.0
|
||||||
|
- g++-5
|
||||||
|
sources: *sources
|
||||||
|
script: >
|
||||||
|
cmake -DCXXOPTS_BUILD_TESTS=ON -DCMAKE_CXX_COMPILER=$COMPILER
|
||||||
|
-DCMAKE_CXX_FLAGS=$CXXFLAGS $UNICODE_OPTIONS $CMAKE_OPTIONS .
|
||||||
|
&& make && make ARGS=--output-on-failure test
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install icu4c; fi
|
82
vendor/cxxopts/CHANGELOG.md
vendored
Normal file
82
vendor/cxxopts/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
This is the changelog for `cxxopts`, a C++11 library for parsing command line
|
||||||
|
options. The project adheres to semantic versioning.
|
||||||
|
|
||||||
|
## 2.2
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Allow integers to have leading zeroes.
|
||||||
|
* Build the tests by default.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* Iterator inputs to `parse_positional`.
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Fix a warning about possible loss of data.
|
||||||
|
* Fix version numbering in CMakeLists.txt
|
||||||
|
* Remove unused declaration of the undefined `ParseResult::get_option`.
|
||||||
|
* Throw on invalid option syntax when beginning with a `-`.
|
||||||
|
* Throw in `as` when option wasn't present.
|
||||||
|
* Fix catching exceptions by reference.
|
||||||
|
|
||||||
|
## 2.1.1
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Revert the change adding `const` type for `argv`, because most users expect
|
||||||
|
to pass a non-const `argv` from `main`.
|
||||||
|
|
||||||
|
## 2.1
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Options with implicit arguments now require the `--option=value` form if
|
||||||
|
they are to be specified with an option. This is to remove the ambiguity
|
||||||
|
when a positional argument could follow an option with an implicit value.
|
||||||
|
For example, `--foo value`, where `foo` has an implicit value, will be
|
||||||
|
parsed as `--foo=implicit` and a positional argument `value`.
|
||||||
|
* Boolean values are no longer special, but are just an option with a default
|
||||||
|
and implicit value.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* Added support for `std::optional` as a storage type.
|
||||||
|
* Allow the help string to be customised.
|
||||||
|
* Use `const` for the type in the `argv` parameter, since the contents of the
|
||||||
|
arguments is never modified.
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Building against GCC 4.9 was broken due to overly strict shadow warnings.
|
||||||
|
* Fixed an ambiguous overload in the `parse_positional` function when an
|
||||||
|
`initializer_list` was directly passed.
|
||||||
|
* Fixed precedence in the Boolean value regex.
|
||||||
|
|
||||||
|
## 2.0
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* `Options::parse` returns a ParseResult rather than storing the parse
|
||||||
|
result internally.
|
||||||
|
* Options with default values now get counted as appearing once if they
|
||||||
|
were not specified by the user.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* A new `ParseResult` object that is the immutable result of parsing. It
|
||||||
|
responds to the same `count` and `operator[]` as `Options` of 1.x did.
|
||||||
|
* The function `ParseResult::arguments` returns a vector of the parsed
|
||||||
|
arguments to iterate through in the order they were provided.
|
||||||
|
* The symbol `cxxopts::version` for the version of the library.
|
||||||
|
* Booleans can be specified with various strings and explicitly set false.
|
||||||
|
|
||||||
|
## 1.x
|
||||||
|
|
||||||
|
The 1.x series was the first major version of the library, with release numbers
|
||||||
|
starting to follow semantic versioning, after 0.x being unstable. It never had
|
||||||
|
a changelog maintained for it. Releases mostly contained bug fixes, with the
|
||||||
|
occasional feature added.
|
104
vendor/cxxopts/CMakeLists.txt
vendored
Normal file
104
vendor/cxxopts/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
# Copyright (c) 2014 Jarryd Beck
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
cmake_minimum_required(VERSION 3.1)
|
||||||
|
|
||||||
|
# parse the current version from the cxxopts header
|
||||||
|
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/cxxopts.hpp" cxxopts_version_defines
|
||||||
|
REGEX "#define CXXOPTS__VERSION_(MAJOR|MINOR|PATCH)")
|
||||||
|
foreach(ver ${cxxopts_version_defines})
|
||||||
|
if(ver MATCHES "#define CXXOPTS__VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$")
|
||||||
|
set(CXXOPTS__VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(VERSION ${CXXOPTS__VERSION_MAJOR}.${CXXOPTS__VERSION_MINOR}.${CXXOPTS__VERSION_PATCH})
|
||||||
|
message(STATUS "cxxopts version ${VERSION}")
|
||||||
|
|
||||||
|
project(cxxopts VERSION "${VERSION}")
|
||||||
|
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
option(CXXOPTS_BUILD_EXAMPLES "Set to ON to build examples" ON)
|
||||||
|
option(CXXOPTS_BUILD_TESTS "Set to ON to build tests" ON)
|
||||||
|
|
||||||
|
# request c++11 without gnu extension for the whole project and enable more warnings
|
||||||
|
if (CXXOPTS_CXX_STANDARD)
|
||||||
|
set(CMAKE_CXX_STANDARD ${CXXOPTS_CXX_STANDARD})
|
||||||
|
else()
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W2")
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wextra -Wshadow")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(cxxopts INTERFACE)
|
||||||
|
|
||||||
|
# optionally, enable unicode support using the ICU library
|
||||||
|
set(CXXOPTS_USE_UNICODE_HELP FALSE CACHE BOOL "Use ICU Unicode library")
|
||||||
|
if(CXXOPTS_USE_UNICODE_HELP)
|
||||||
|
find_package(PkgConfig)
|
||||||
|
pkg_check_modules(ICU REQUIRED icu-uc)
|
||||||
|
|
||||||
|
target_link_libraries(cxxopts INTERFACE ${ICU_LDFLAGS})
|
||||||
|
target_compile_options(cxxopts INTERFACE ${ICU_CFLAGS})
|
||||||
|
target_compile_definitions(cxxopts INTERFACE CXXOPTS_USE_UNICODE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(cxxopts INTERFACE
|
||||||
|
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
||||||
|
$<INSTALL_INTERFACE:include>
|
||||||
|
)
|
||||||
|
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
set(CXXOPTS_CMAKE_DIR "lib/cmake/cxxopts" CACHE STRING
|
||||||
|
"Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.")
|
||||||
|
set(version_config "${PROJECT_BINARY_DIR}/cxxopts-config-version.cmake")
|
||||||
|
set(project_config "${PROJECT_BINARY_DIR}/cxxopts-config.cmake")
|
||||||
|
set(targets_export_name cxxopts-targets)
|
||||||
|
|
||||||
|
# Generate the version, config and target files into the build directory.
|
||||||
|
write_basic_package_version_file(
|
||||||
|
${version_config}
|
||||||
|
VERSION ${VERSION}
|
||||||
|
COMPATIBILITY AnyNewerVersion)
|
||||||
|
configure_package_config_file(
|
||||||
|
${PROJECT_SOURCE_DIR}/cxxopts-config.cmake.in
|
||||||
|
${project_config}
|
||||||
|
INSTALL_DESTINATION ${CXXOPTS_CMAKE_DIR})
|
||||||
|
export(TARGETS cxxopts NAMESPACE cxxopts::
|
||||||
|
FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake)
|
||||||
|
|
||||||
|
# Install version, config and target files.
|
||||||
|
install(
|
||||||
|
FILES ${project_config} ${version_config}
|
||||||
|
DESTINATION ${CXXOPTS_CMAKE_DIR})
|
||||||
|
install(EXPORT ${targets_export_name} DESTINATION ${CXXOPTS_CMAKE_DIR}
|
||||||
|
NAMESPACE cxxopts::)
|
||||||
|
|
||||||
|
# Install the header file and export the target
|
||||||
|
install(TARGETS cxxopts EXPORT ${targets_export_name} DESTINATION lib)
|
||||||
|
install(FILES ${PROJECT_SOURCE_DIR}/include/cxxopts.hpp DESTINATION include)
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
||||||
|
add_subdirectory(test)
|
23
vendor/cxxopts/INSTALL
vendored
Normal file
23
vendor/cxxopts/INSTALL
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
== System installation ==
|
||||||
|
|
||||||
|
This library is header only. So you can either copy `include/cxxopts.hpp` to `/usr/include` or `/usr/local/include`, or add `include` to your search path.
|
||||||
|
|
||||||
|
== Building the examples and tests ==
|
||||||
|
|
||||||
|
It is preferable to build out of source. Make a build directory somewhere, and then
|
||||||
|
do the following, where `${CXXOPTS_DIR}` is the path that you checked out `cxxopts`
|
||||||
|
to:
|
||||||
|
|
||||||
|
cmake ${CXXOPTS_DIR}
|
||||||
|
make
|
||||||
|
|
||||||
|
You can use another build tool, such as ninja.
|
||||||
|
|
||||||
|
cmake -G Ninja ${CXXOPTS_DIR}
|
||||||
|
ninja
|
||||||
|
|
||||||
|
|
||||||
|
To run the tests, you have to configure `cxxopts` with another flag:
|
||||||
|
cmake -D CXXOPTS_BUILD_TESTS=On ${CXXOPTS_DIR}
|
||||||
|
make
|
||||||
|
make test
|
19
vendor/cxxopts/LICENSE
vendored
Normal file
19
vendor/cxxopts/LICENSE
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright (c) 2014 Jarryd Beck
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
136
vendor/cxxopts/README.md
vendored
Normal file
136
vendor/cxxopts/README.md
vendored
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
[![Build Status](https://travis-ci.org/jarro2783/cxxopts.svg?branch=master)](https://travis-ci.org/jarro2783/cxxopts)
|
||||||
|
|
||||||
|
# Release versions
|
||||||
|
|
||||||
|
Note that `master` is generally a work in progress, and you probably want to use a
|
||||||
|
tagged release version.
|
||||||
|
|
||||||
|
# Quick start
|
||||||
|
|
||||||
|
This is a lightweight C++ option parser library, supporting the standard GNU
|
||||||
|
style syntax for options.
|
||||||
|
|
||||||
|
Options can be given as:
|
||||||
|
|
||||||
|
--long
|
||||||
|
--long=argument
|
||||||
|
--long argument
|
||||||
|
-a
|
||||||
|
-ab
|
||||||
|
-abc argument
|
||||||
|
|
||||||
|
where c takes an argument, but a and b do not.
|
||||||
|
|
||||||
|
Additionally, anything after `--` will be parsed as a positional argument.
|
||||||
|
|
||||||
|
## Basics
|
||||||
|
|
||||||
|
#include <cxxopts.hpp>
|
||||||
|
|
||||||
|
Create a cxxopts::Options instance.
|
||||||
|
|
||||||
|
cxxopts::Options options("MyProgram", "One line description of MyProgram");
|
||||||
|
|
||||||
|
Then use `add_options`.
|
||||||
|
|
||||||
|
options.add_options()
|
||||||
|
("d,debug", "Enable debugging")
|
||||||
|
("f,file", "File name", cxxopts::value<std::string>())
|
||||||
|
;
|
||||||
|
|
||||||
|
Options are declared with a long and an optional short option. A description
|
||||||
|
must be provided. The third argument is the value, if omitted it is boolean.
|
||||||
|
Any type can be given as long as it can be parsed, with operator>>.
|
||||||
|
|
||||||
|
To parse the command line do:
|
||||||
|
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
To retrieve an option use `result.count("option")` to get the number of times
|
||||||
|
it appeared, and
|
||||||
|
|
||||||
|
result["opt"].as<type>()
|
||||||
|
|
||||||
|
to get its value. If "opt" doesn't exist, or isn't of the right type, then an
|
||||||
|
exception will be thrown.
|
||||||
|
|
||||||
|
Note that the result of `options.parse` should only be used as long as the
|
||||||
|
`options` object that created it is in scope.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
Exceptional situations throw C++ exceptions. There are two types of
|
||||||
|
exceptions: errors defining the options, and errors when parsing a list of
|
||||||
|
arguments. All exceptions derive from `cxxopts::OptionException`. Errors
|
||||||
|
defining options derive from `cxxopts::OptionSpecException` and errors
|
||||||
|
parsing arguments derive from `cxxopts::OptionParseException`.
|
||||||
|
|
||||||
|
All exceptions define a `what()` function to get a printable string
|
||||||
|
explaining the error.
|
||||||
|
|
||||||
|
## Help groups
|
||||||
|
|
||||||
|
Options can be placed into groups for the purposes of displaying help messages.
|
||||||
|
To place options in a group, pass the group as a string to `add_options`. Then,
|
||||||
|
when displaying the help, pass the groups that you would like displayed as a
|
||||||
|
vector to the `help` function.
|
||||||
|
|
||||||
|
## Positional Arguments
|
||||||
|
|
||||||
|
Positional arguments can be optionally parsed into one or more options.
|
||||||
|
To set up positional arguments, call
|
||||||
|
|
||||||
|
options.parse_positional({"first", "second", "last"})
|
||||||
|
|
||||||
|
where "last" should be the name of an option with a container type, and the
|
||||||
|
others should have a single value.
|
||||||
|
|
||||||
|
## Default and implicit values
|
||||||
|
|
||||||
|
An option can be declared with a default or an implicit value, or both.
|
||||||
|
|
||||||
|
A default value is the value that an option takes when it is not specified
|
||||||
|
on the command line. The following specifies a default value for an option:
|
||||||
|
|
||||||
|
cxxopts::value<std::string>()->default_value("value")
|
||||||
|
|
||||||
|
An implicit value is the value that an option takes when it is given on the
|
||||||
|
command line without an argument. The following specifies an implicit value:
|
||||||
|
|
||||||
|
cxxopts::value<std::string>()->implicit_value("implicit")
|
||||||
|
|
||||||
|
If an option had both, then not specifying it would give the value `"value"`,
|
||||||
|
writing it on the command line as `--option` would give the value `"implicit"`,
|
||||||
|
and writing `--option=another` would give it the value `"another"`.
|
||||||
|
|
||||||
|
Note that the default and implicit value is always stored as a string,
|
||||||
|
regardless of the type that you want to store it in. It will be parsed as
|
||||||
|
though it was given on the command line.
|
||||||
|
|
||||||
|
## Boolean values
|
||||||
|
|
||||||
|
Boolean options have a default implicit value of `"true"`, which can be
|
||||||
|
overridden. The effect is that writing `-o` by itself will set option `o` to
|
||||||
|
`true`. However, they can also be written with various strings using `=value`.
|
||||||
|
There is no way to disambiguate positional arguments from the value following
|
||||||
|
a boolean, so we have chosen that they will be positional arguments, and
|
||||||
|
therefore, `-o false` does not work.
|
||||||
|
|
||||||
|
## Custom help
|
||||||
|
|
||||||
|
The string after the program name on the first line of the help can be
|
||||||
|
completely replaced by calling `options.custom_help`. Note that you might
|
||||||
|
also want to override the positional help by calling `options.positional_help`.
|
||||||
|
|
||||||
|
# Linking
|
||||||
|
|
||||||
|
This is a header only library.
|
||||||
|
|
||||||
|
# Requirements
|
||||||
|
|
||||||
|
The only build requirement is a C++ compiler that supports C++11 regular
|
||||||
|
expressions. For example GCC >= 4.9 or clang with libc++.
|
||||||
|
|
||||||
|
# TODO list
|
||||||
|
|
||||||
|
* Allow unrecognised options.
|
4
vendor/cxxopts/cxxopts-config.cmake.in
vendored
Normal file
4
vendor/cxxopts/cxxopts-config.cmake.in
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
|
||||||
|
check_required_components(cxxopts)
|
2082
vendor/cxxopts/include/cxxopts.hpp
vendored
Normal file
2082
vendor/cxxopts/include/cxxopts.hpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
vendor/cxxopts/src/.gitignore
vendored
Normal file
1
vendor/cxxopts/src/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
example
|
24
vendor/cxxopts/src/CMakeLists.txt
vendored
Normal file
24
vendor/cxxopts/src/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (c) 2014 Jarryd Beck
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
if(CXXOPTS_BUILD_EXAMPLES)
|
||||||
|
add_executable(example example.cpp)
|
||||||
|
target_link_libraries(example cxxopts)
|
||||||
|
endif()
|
151
vendor/cxxopts/src/example.cpp
vendored
Normal file
151
vendor/cxxopts/src/example.cpp
vendored
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2014 Jarryd Beck
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "cxxopts.hpp"
|
||||||
|
|
||||||
|
cxxopts::ParseResult
|
||||||
|
parse(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cxxopts::Options options(argv[0], " - example command line options");
|
||||||
|
options
|
||||||
|
.positional_help("[optional args]")
|
||||||
|
.show_positional_help();
|
||||||
|
|
||||||
|
bool apple = false;
|
||||||
|
|
||||||
|
options
|
||||||
|
.allow_unrecognised_options()
|
||||||
|
.add_options()
|
||||||
|
("a,apple", "an apple", cxxopts::value<bool>(apple))
|
||||||
|
("b,bob", "Bob")
|
||||||
|
("t,true", "True", cxxopts::value<bool>()->default_value("true"))
|
||||||
|
("f, file", "File", cxxopts::value<std::vector<std::string>>(), "FILE")
|
||||||
|
("i,input", "Input", cxxopts::value<std::string>())
|
||||||
|
("o,output", "Output file", cxxopts::value<std::string>()
|
||||||
|
->default_value("a.out")->implicit_value("b.def"), "BIN")
|
||||||
|
("positional",
|
||||||
|
"Positional arguments: these are the arguments that are entered "
|
||||||
|
"without an option", cxxopts::value<std::vector<std::string>>())
|
||||||
|
("long-description",
|
||||||
|
"thisisareallylongwordthattakesupthewholelineandcannotbebrokenataspace")
|
||||||
|
("help", "Print help")
|
||||||
|
("int", "An integer", cxxopts::value<int>(), "N")
|
||||||
|
("float", "A floating point number", cxxopts::value<float>())
|
||||||
|
("option_that_is_too_long_for_the_help", "A very long option")
|
||||||
|
#ifdef CXXOPTS_USE_UNICODE
|
||||||
|
("unicode", u8"A help option with non-ascii: à. Here the size of the"
|
||||||
|
" string should be correct")
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
options.add_options("Group")
|
||||||
|
("c,compile", "compile")
|
||||||
|
("d,drop", "drop", cxxopts::value<std::vector<std::string>>());
|
||||||
|
|
||||||
|
options.parse_positional({"input", "output", "positional"});
|
||||||
|
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
if (result.count("help"))
|
||||||
|
{
|
||||||
|
std::cout << options.help({"", "Group"}) << std::endl;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apple)
|
||||||
|
{
|
||||||
|
std::cout << "Saw option ‘a’ " << result.count("a") << " times " <<
|
||||||
|
std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("b"))
|
||||||
|
{
|
||||||
|
std::cout << "Saw option ‘b’" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("f"))
|
||||||
|
{
|
||||||
|
auto& ff = result["f"].as<std::vector<std::string>>();
|
||||||
|
std::cout << "Files" << std::endl;
|
||||||
|
for (const auto& f : ff)
|
||||||
|
{
|
||||||
|
std::cout << f << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("input"))
|
||||||
|
{
|
||||||
|
std::cout << "Input = " << result["input"].as<std::string>()
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("output"))
|
||||||
|
{
|
||||||
|
std::cout << "Output = " << result["output"].as<std::string>()
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("positional"))
|
||||||
|
{
|
||||||
|
std::cout << "Positional = {";
|
||||||
|
auto& v = result["positional"].as<std::vector<std::string>>();
|
||||||
|
for (const auto& s : v) {
|
||||||
|
std::cout << s << ", ";
|
||||||
|
}
|
||||||
|
std::cout << "}" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("int"))
|
||||||
|
{
|
||||||
|
std::cout << "int = " << result["int"].as<int>() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("float"))
|
||||||
|
{
|
||||||
|
std::cout << "float = " << result["float"].as<float>() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Arguments remain = " << argc << std::endl;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (const cxxopts::OptionException& e)
|
||||||
|
{
|
||||||
|
std::cout << "error parsing options: " << e.what() << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
auto result = parse(argc, argv);
|
||||||
|
auto arguments = result.arguments();
|
||||||
|
std::cout << "Saw " << arguments.size() << " arguments" << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
1
vendor/cxxopts/test/.gitignore
vendored
Normal file
1
vendor/cxxopts/test/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
options_test
|
35
vendor/cxxopts/test/CMakeLists.txt
vendored
Normal file
35
vendor/cxxopts/test/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
if (CXXOPTS_BUILD_TESTS)
|
||||||
|
add_executable(options_test main.cpp options.cpp)
|
||||||
|
target_link_libraries(options_test cxxopts)
|
||||||
|
add_test(options options_test)
|
||||||
|
|
||||||
|
# test if the targets are findable from the build directory
|
||||||
|
add_test(find-package-test ${CMAKE_CTEST_COMMAND}
|
||||||
|
-C ${CMAKE_BUILD_TYPE}
|
||||||
|
--build-and-test
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/find-package-test"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/find-package-test"
|
||||||
|
--build-generator ${CMAKE_GENERATOR}
|
||||||
|
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
|
||||||
|
--build-options
|
||||||
|
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
|
||||||
|
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
|
||||||
|
"-Dcxxopts_DIR=${PROJECT_BINARY_DIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# test if the targets are findable when add_subdirectory is used
|
||||||
|
add_test(add-subdirectory-test ${CMAKE_CTEST_COMMAND}
|
||||||
|
-C ${CMAKE_BUILD_TYPE}
|
||||||
|
--build-and-test
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/add-subdirectory-test"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/add-subdirectory-test"
|
||||||
|
--build-generator ${CMAKE_GENERATOR}
|
||||||
|
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
|
||||||
|
--build-options
|
||||||
|
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
|
||||||
|
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(link_test link_a.cpp link_b.cpp)
|
||||||
|
target_link_libraries(link_test cxxopts)
|
||||||
|
endif()
|
11
vendor/cxxopts/test/add-subdirectory-test/CMakeLists.txt
vendored
Normal file
11
vendor/cxxopts/test/add-subdirectory-test/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
cmake_minimum_required(VERSION 3.1)
|
||||||
|
|
||||||
|
project(cxxopts-test)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
add_subdirectory(../.. cxxopts EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
add_executable(library-test "../../src/example.cpp")
|
||||||
|
target_link_libraries(library-test cxxopts)
|
10460
vendor/cxxopts/test/catch.hpp
vendored
Normal file
10460
vendor/cxxopts/test/catch.hpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
11
vendor/cxxopts/test/find-package-test/CMakeLists.txt
vendored
Normal file
11
vendor/cxxopts/test/find-package-test/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
cmake_minimum_required(VERSION 3.1)
|
||||||
|
|
||||||
|
project(cxxopts-test)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
find_package(cxxopts REQUIRED)
|
||||||
|
|
||||||
|
add_executable(library-test "../../src/example.cpp")
|
||||||
|
target_link_libraries(library-test cxxopts::cxxopts)
|
6
vendor/cxxopts/test/link_a.cpp
vendored
Normal file
6
vendor/cxxopts/test/link_a.cpp
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include "cxxopts.hpp"
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
1
vendor/cxxopts/test/link_b.cpp
vendored
Normal file
1
vendor/cxxopts/test/link_b.cpp
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include <cxxopts.hpp>
|
2
vendor/cxxopts/test/main.cpp
vendored
Normal file
2
vendor/cxxopts/test/main.cpp
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include "catch.hpp"
|
550
vendor/cxxopts/test/options.cpp
vendored
Normal file
550
vendor/cxxopts/test/options.cpp
vendored
Normal file
|
@ -0,0 +1,550 @@
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include <initializer_list>
|
||||||
|
|
||||||
|
#include "cxxopts.hpp"
|
||||||
|
|
||||||
|
class Argv {
|
||||||
|
public:
|
||||||
|
|
||||||
|
Argv(std::initializer_list<const char*> args)
|
||||||
|
: m_argv(new char*[args.size()])
|
||||||
|
, m_argc(args.size())
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
auto iter = args.begin();
|
||||||
|
while (iter != args.end()) {
|
||||||
|
auto len = strlen(*iter) + 1;
|
||||||
|
auto ptr = std::unique_ptr<char[]>(new char[len]);
|
||||||
|
|
||||||
|
strcpy(ptr.get(), *iter);
|
||||||
|
m_args.push_back(std::move(ptr));
|
||||||
|
m_argv.get()[i] = m_args.back().get();
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char** argv() const {
|
||||||
|
return m_argv.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
int argc() const {
|
||||||
|
return m_argc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<char[]>> m_args;
|
||||||
|
std::unique_ptr<char*[]> m_argv;
|
||||||
|
int m_argc;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE("Basic options", "[options]")
|
||||||
|
{
|
||||||
|
|
||||||
|
cxxopts::Options options("tester", " - test basic options");
|
||||||
|
|
||||||
|
options.add_options()
|
||||||
|
("long", "a long option")
|
||||||
|
("s,short", "a short option")
|
||||||
|
("value", "an option with a value", cxxopts::value<std::string>())
|
||||||
|
("a,av", "a short option with a value", cxxopts::value<std::string>())
|
||||||
|
("6,six", "a short number option")
|
||||||
|
("p, space", "an option with space between short and long")
|
||||||
|
("nothing", "won't exist", cxxopts::value<std::string>())
|
||||||
|
;
|
||||||
|
|
||||||
|
Argv argv({
|
||||||
|
"tester",
|
||||||
|
"--long",
|
||||||
|
"-s",
|
||||||
|
"--value",
|
||||||
|
"value",
|
||||||
|
"-a",
|
||||||
|
"b",
|
||||||
|
"-6",
|
||||||
|
"-p",
|
||||||
|
"--space",
|
||||||
|
});
|
||||||
|
|
||||||
|
char** actual_argv = argv.argv();
|
||||||
|
auto argc = argv.argc();
|
||||||
|
|
||||||
|
auto result = options.parse(argc, actual_argv);
|
||||||
|
|
||||||
|
CHECK(result.count("long") == 1);
|
||||||
|
CHECK(result.count("s") == 1);
|
||||||
|
CHECK(result.count("value") == 1);
|
||||||
|
CHECK(result.count("a") == 1);
|
||||||
|
CHECK(result["value"].as<std::string>() == "value");
|
||||||
|
CHECK(result["a"].as<std::string>() == "b");
|
||||||
|
CHECK(result.count("6") == 1);
|
||||||
|
CHECK(result.count("p") == 2);
|
||||||
|
CHECK(result.count("space") == 2);
|
||||||
|
|
||||||
|
auto& arguments = result.arguments();
|
||||||
|
REQUIRE(arguments.size() == 7);
|
||||||
|
CHECK(arguments[0].key() == "long");
|
||||||
|
CHECK(arguments[0].value() == "true");
|
||||||
|
CHECK(arguments[0].as<bool>() == true);
|
||||||
|
|
||||||
|
CHECK(arguments[1].key() == "short");
|
||||||
|
CHECK(arguments[2].key() == "value");
|
||||||
|
CHECK(arguments[3].key() == "av");
|
||||||
|
|
||||||
|
CHECK_THROWS_AS(result["nothing"].as<std::string>(), std::domain_error&);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Short options", "[options]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("test_short", " - test short options");
|
||||||
|
|
||||||
|
options.add_options()
|
||||||
|
("a", "a short option", cxxopts::value<std::string>());
|
||||||
|
|
||||||
|
Argv argv({"test_short", "-a", "value"});
|
||||||
|
|
||||||
|
auto actual_argv = argv.argv();
|
||||||
|
auto argc = argv.argc();
|
||||||
|
|
||||||
|
auto result = options.parse(argc, actual_argv);
|
||||||
|
|
||||||
|
CHECK(result.count("a") == 1);
|
||||||
|
CHECK(result["a"].as<std::string>() == "value");
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(options.add_options()("", "nothing option"),
|
||||||
|
cxxopts::invalid_option_format_error&);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("No positional", "[positional]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("test_no_positional",
|
||||||
|
" - test no positional options");
|
||||||
|
|
||||||
|
Argv av({"tester", "a", "b", "def"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
REQUIRE(argc == 4);
|
||||||
|
CHECK(strcmp(argv[1], "a") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("All positional", "[positional]")
|
||||||
|
{
|
||||||
|
std::vector<std::string> positional;
|
||||||
|
|
||||||
|
cxxopts::Options options("test_all_positional", " - test all positional");
|
||||||
|
options.add_options()
|
||||||
|
("positional", "Positional parameters",
|
||||||
|
cxxopts::value<std::vector<std::string>>(positional))
|
||||||
|
;
|
||||||
|
|
||||||
|
Argv av({"tester", "a", "b", "c"});
|
||||||
|
|
||||||
|
auto argc = av.argc();
|
||||||
|
auto argv = av.argv();
|
||||||
|
|
||||||
|
std::vector<std::string> pos_names = {"positional"};
|
||||||
|
|
||||||
|
options.parse_positional(pos_names.begin(), pos_names.end());
|
||||||
|
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
REQUIRE(argc == 1);
|
||||||
|
REQUIRE(positional.size() == 3);
|
||||||
|
|
||||||
|
CHECK(positional[0] == "a");
|
||||||
|
CHECK(positional[1] == "b");
|
||||||
|
CHECK(positional[2] == "c");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Some positional explicit", "[positional]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("positional_explicit", " - test positional");
|
||||||
|
|
||||||
|
options.add_options()
|
||||||
|
("input", "Input file", cxxopts::value<std::string>())
|
||||||
|
("output", "Output file", cxxopts::value<std::string>())
|
||||||
|
("positional", "Positional parameters",
|
||||||
|
cxxopts::value<std::vector<std::string>>())
|
||||||
|
;
|
||||||
|
|
||||||
|
options.parse_positional({"input", "output", "positional"});
|
||||||
|
|
||||||
|
Argv av({"tester", "--output", "a", "b", "c", "d"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
CHECK(argc == 1);
|
||||||
|
CHECK(result.count("output"));
|
||||||
|
CHECK(result["input"].as<std::string>() == "b");
|
||||||
|
CHECK(result["output"].as<std::string>() == "a");
|
||||||
|
|
||||||
|
auto& positional = result["positional"].as<std::vector<std::string>>();
|
||||||
|
|
||||||
|
REQUIRE(positional.size() == 2);
|
||||||
|
CHECK(positional[0] == "c");
|
||||||
|
CHECK(positional[1] == "d");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("No positional with extras", "[positional]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("posargmaster", "shows incorrect handling");
|
||||||
|
options.add_options()
|
||||||
|
("dummy", "oh no", cxxopts::value<std::string>())
|
||||||
|
;
|
||||||
|
|
||||||
|
Argv av({"extras", "--", "a", "b", "c", "d"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
auto old_argv = argv;
|
||||||
|
auto old_argc = argc;
|
||||||
|
|
||||||
|
options.parse(argc, argv);
|
||||||
|
|
||||||
|
REQUIRE(argc == old_argc - 1);
|
||||||
|
CHECK(argv[0] == std::string("extras"));
|
||||||
|
CHECK(argv[1] == std::string("a"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Empty with implicit value", "[implicit]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("empty_implicit", "doesn't handle empty");
|
||||||
|
options.add_options()
|
||||||
|
("implicit", "Has implicit", cxxopts::value<std::string>()
|
||||||
|
->implicit_value("foo"));
|
||||||
|
|
||||||
|
Argv av({"implicit", "--implicit="});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
REQUIRE(result.count("implicit") == 1);
|
||||||
|
REQUIRE(result["implicit"].as<std::string>() == "");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Default values", "[default]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("defaults", "has defaults");
|
||||||
|
options.add_options()
|
||||||
|
("default", "Has implicit", cxxopts::value<int>()
|
||||||
|
->default_value("42"));
|
||||||
|
|
||||||
|
SECTION("Sets defaults") {
|
||||||
|
Argv av({"implicit"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
CHECK(result.count("default") == 0);
|
||||||
|
CHECK(result["default"].as<int>() == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("When values provided") {
|
||||||
|
Argv av({"implicit", "--default", "5"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
CHECK(result.count("default") == 1);
|
||||||
|
CHECK(result["default"].as<int>() == 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Parse into a reference", "[reference]")
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
|
||||||
|
cxxopts::Options options("into_reference", "parses into a reference");
|
||||||
|
options.add_options()
|
||||||
|
("ref", "A reference", cxxopts::value(value));
|
||||||
|
|
||||||
|
Argv av({"into_reference", "--ref", "42"});
|
||||||
|
|
||||||
|
auto argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
CHECK(result.count("ref") == 1);
|
||||||
|
CHECK(value == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Integers", "[options]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("parses_integers", "parses integers correctly");
|
||||||
|
options.add_options()
|
||||||
|
("positional", "Integers", cxxopts::value<std::vector<int>>());
|
||||||
|
|
||||||
|
Argv av({"ints", "--", "5", "6", "-6", "0", "0xab", "0xAf", "0x0"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
options.parse_positional("positional");
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
REQUIRE(result.count("positional") == 7);
|
||||||
|
|
||||||
|
auto& positional = result["positional"].as<std::vector<int>>();
|
||||||
|
REQUIRE(positional.size() == 7);
|
||||||
|
CHECK(positional[0] == 5);
|
||||||
|
CHECK(positional[1] == 6);
|
||||||
|
CHECK(positional[2] == -6);
|
||||||
|
CHECK(positional[3] == 0);
|
||||||
|
CHECK(positional[4] == 0xab);
|
||||||
|
CHECK(positional[5] == 0xaf);
|
||||||
|
CHECK(positional[6] == 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Leading zero integers", "[options]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("parses_integers", "parses integers correctly");
|
||||||
|
options.add_options()
|
||||||
|
("positional", "Integers", cxxopts::value<std::vector<int>>());
|
||||||
|
|
||||||
|
Argv av({"ints", "--", "05", "06", "0x0ab", "0x0001"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
options.parse_positional("positional");
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
REQUIRE(result.count("positional") == 4);
|
||||||
|
|
||||||
|
auto& positional = result["positional"].as<std::vector<int>>();
|
||||||
|
REQUIRE(positional.size() == 4);
|
||||||
|
CHECK(positional[0] == 5);
|
||||||
|
CHECK(positional[1] == 6);
|
||||||
|
CHECK(positional[2] == 0xab);
|
||||||
|
CHECK(positional[3] == 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Unsigned integers", "[options]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("parses_unsigned", "detects unsigned errors");
|
||||||
|
options.add_options()
|
||||||
|
("positional", "Integers", cxxopts::value<std::vector<unsigned int>>());
|
||||||
|
|
||||||
|
Argv av({"ints", "--", "-2"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
options.parse_positional("positional");
|
||||||
|
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type&);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Integer bounds", "[integer]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("integer_boundaries", "check min/max integer");
|
||||||
|
options.add_options()
|
||||||
|
("positional", "Integers", cxxopts::value<std::vector<int8_t>>());
|
||||||
|
|
||||||
|
SECTION("No overflow")
|
||||||
|
{
|
||||||
|
Argv av({"ints", "--", "127", "-128", "0x7f", "-0x80", "0x7e"});
|
||||||
|
|
||||||
|
auto argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
options.parse_positional("positional");
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
REQUIRE(result.count("positional") == 5);
|
||||||
|
|
||||||
|
auto& positional = result["positional"].as<std::vector<int8_t>>();
|
||||||
|
CHECK(positional[0] == 127);
|
||||||
|
CHECK(positional[1] == -128);
|
||||||
|
CHECK(positional[2] == 0x7f);
|
||||||
|
CHECK(positional[3] == -0x80);
|
||||||
|
CHECK(positional[4] == 0x7e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Overflow on boundary", "[integer]")
|
||||||
|
{
|
||||||
|
using namespace cxxopts::values;
|
||||||
|
|
||||||
|
int8_t si;
|
||||||
|
uint8_t ui;
|
||||||
|
|
||||||
|
CHECK_THROWS_AS((integer_parser("128", si)), cxxopts::argument_incorrect_type&);
|
||||||
|
CHECK_THROWS_AS((integer_parser("-129", si)), cxxopts::argument_incorrect_type&);
|
||||||
|
CHECK_THROWS_AS((integer_parser("256", ui)), cxxopts::argument_incorrect_type&);
|
||||||
|
CHECK_THROWS_AS((integer_parser("-0x81", si)), cxxopts::argument_incorrect_type&);
|
||||||
|
CHECK_THROWS_AS((integer_parser("0x80", si)), cxxopts::argument_incorrect_type&);
|
||||||
|
CHECK_THROWS_AS((integer_parser("0x100", ui)), cxxopts::argument_incorrect_type&);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Integer overflow", "[options]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("reject_overflow", "rejects overflowing integers");
|
||||||
|
options.add_options()
|
||||||
|
("positional", "Integers", cxxopts::value<std::vector<int8_t>>());
|
||||||
|
|
||||||
|
Argv av({"ints", "--", "128"});
|
||||||
|
|
||||||
|
auto argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
options.parse_positional("positional");
|
||||||
|
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type&);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Floats", "[options]")
|
||||||
|
{
|
||||||
|
cxxopts::Options options("parses_floats", "parses floats correctly");
|
||||||
|
options.add_options()
|
||||||
|
("double", "Double precision", cxxopts::value<double>())
|
||||||
|
("positional", "Floats", cxxopts::value<std::vector<float>>());
|
||||||
|
|
||||||
|
Argv av({"floats", "--double", "0.5", "--", "4", "-4", "1.5e6", "-1.5e6"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
options.parse_positional("positional");
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
REQUIRE(result.count("double") == 1);
|
||||||
|
REQUIRE(result.count("positional") == 4);
|
||||||
|
|
||||||
|
CHECK(result["double"].as<double>() == 0.5);
|
||||||
|
|
||||||
|
auto& positional = result["positional"].as<std::vector<float>>();
|
||||||
|
CHECK(positional[0] == 4);
|
||||||
|
CHECK(positional[1] == -4);
|
||||||
|
CHECK(positional[2] == 1.5e6);
|
||||||
|
CHECK(positional[3] == -1.5e6);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Invalid integers", "[integer]") {
|
||||||
|
cxxopts::Options options("invalid_integers", "rejects invalid integers");
|
||||||
|
options.add_options()
|
||||||
|
("positional", "Integers", cxxopts::value<std::vector<int>>());
|
||||||
|
|
||||||
|
Argv av({"ints", "--", "Ae"});
|
||||||
|
|
||||||
|
char **argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
options.parse_positional("positional");
|
||||||
|
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type&);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Booleans", "[boolean]") {
|
||||||
|
cxxopts::Options options("parses_floats", "parses floats correctly");
|
||||||
|
options.add_options()
|
||||||
|
("bool", "A Boolean", cxxopts::value<bool>())
|
||||||
|
("debug", "Debugging", cxxopts::value<bool>())
|
||||||
|
("timing", "Timing", cxxopts::value<bool>())
|
||||||
|
("noExplicitDefault", "No Explicit Default", cxxopts::value<bool>())
|
||||||
|
("defaultTrue", "Timing", cxxopts::value<bool>()->default_value("true"))
|
||||||
|
("defaultFalse", "Timing", cxxopts::value<bool>()->default_value("false"))
|
||||||
|
("others", "Other arguments", cxxopts::value<std::vector<std::string>>())
|
||||||
|
;
|
||||||
|
|
||||||
|
options.parse_positional("others");
|
||||||
|
|
||||||
|
Argv av({"booleans", "--bool=false", "--debug=true", "--timing", "extra"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
|
||||||
|
REQUIRE(result.count("bool") == 1);
|
||||||
|
REQUIRE(result.count("debug") == 1);
|
||||||
|
REQUIRE(result.count("timing") == 1);
|
||||||
|
REQUIRE(result.count("noExplicitDefault") == 0);
|
||||||
|
REQUIRE(result.count("defaultTrue") == 0);
|
||||||
|
REQUIRE(result.count("defaultFalse") == 0);
|
||||||
|
|
||||||
|
CHECK(result["bool"].as<bool>() == false);
|
||||||
|
CHECK(result["debug"].as<bool>() == true);
|
||||||
|
CHECK(result["timing"].as<bool>() == true);
|
||||||
|
CHECK(result["noExplicitDefault"].as<bool>() == false);
|
||||||
|
CHECK(result["defaultTrue"].as<bool>() == true);
|
||||||
|
CHECK(result["defaultFalse"].as<bool>() == false);
|
||||||
|
|
||||||
|
REQUIRE(result.count("others") == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CXXOPTS_HAS_OPTIONAL
|
||||||
|
TEST_CASE("std::optional", "[optional]") {
|
||||||
|
std::optional<std::string> optional;
|
||||||
|
cxxopts::Options options("optional", " - tests optional");
|
||||||
|
options.add_options()
|
||||||
|
("optional", "an optional option", cxxopts::value<std::optional<std::string>>(optional));
|
||||||
|
|
||||||
|
Argv av({"optional", "--optional", "foo"});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
options.parse(argc, argv);
|
||||||
|
|
||||||
|
REQUIRE(optional.has_value());
|
||||||
|
CHECK(*optional == "foo");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_CASE("Unrecognised options", "[options]") {
|
||||||
|
cxxopts::Options options("unknown_options", " - test unknown options");
|
||||||
|
|
||||||
|
options.add_options()
|
||||||
|
("long", "a long option")
|
||||||
|
("s,short", "a short option");
|
||||||
|
|
||||||
|
Argv av({
|
||||||
|
"unknown_options",
|
||||||
|
"--unknown",
|
||||||
|
"--long",
|
||||||
|
"-su",
|
||||||
|
"--another_unknown",
|
||||||
|
});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
SECTION("Default behaviour") {
|
||||||
|
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_not_exists_exception&);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("After allowing unrecognised options") {
|
||||||
|
options.allow_unrecognised_options();
|
||||||
|
CHECK_NOTHROW(options.parse(argc, argv));
|
||||||
|
REQUIRE(argc == 3);
|
||||||
|
CHECK_THAT(argv[1], Catch::Equals("--unknown"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Invalid option syntax", "[options]") {
|
||||||
|
cxxopts::Options options("invalid_syntax", " - test invalid syntax");
|
||||||
|
|
||||||
|
Argv av({
|
||||||
|
"invalid_syntax",
|
||||||
|
"--a",
|
||||||
|
});
|
||||||
|
|
||||||
|
char** argv = av.argv();
|
||||||
|
auto argc = av.argc();
|
||||||
|
|
||||||
|
SECTION("Default behaviour") {
|
||||||
|
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_syntax_exception&);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue