Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make a private nonstd.h header, and remove some inline definitions #6352

Merged
merged 13 commits into from
Jul 11, 2024
Merged
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,9 @@ else()
list(APPEND CCHOST_SOURCES src/host/snmalloc.cpp)
endif()

list(APPEND CCHOST_SOURCES ${CCF_DIR}/src/host/main.cpp)
list(APPEND CCHOST_SOURCES ${CCF_DIR}/src/host/main.cpp
${CCF_DIR}/src/ds/nonstd.cpp
)

if(COMPILE_TARGET STREQUAL "sgx")
list(APPEND CCHOST_SOURCES ${CCF_GENERATED_DIR}/ccf_u.cpp)
Expand Down Expand Up @@ -625,6 +627,7 @@ add_custom_target(ccf ALL)
set(CCF_IMPL_SOURCE
${CCF_DIR}/src/enclave/main.cpp ${CCF_DIR}/src/enclave/enclave_time.cpp
${CCF_DIR}/src/enclave/thread_local.cpp ${CCF_DIR}/src/node/quote.cpp
${CCF_DIR}/src/ds/nonstd.cpp
)

if(COMPILE_TARGET STREQUAL "sgx")
Expand Down Expand Up @@ -1018,6 +1021,7 @@ if(BUILD_TESTS)

add_test_bin(
kp_cert_test ${CMAKE_CURRENT_SOURCE_DIR}/src/crypto/test/kp_cert.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/ds/nonstd.cpp
)
target_link_libraries(kp_cert_test PRIVATE ${CMAKE_THREAD_LIBS_INIT})

Expand Down Expand Up @@ -1091,7 +1095,7 @@ if(BUILD_TESTS)
)

# Merkle Tree memory test
add_executable(merkle_mem src/node/test/merkle_mem.cpp)
add_executable(merkle_mem src/node/test/merkle_mem.cpp src/ds/nonstd.cpp)
target_compile_options(merkle_mem PRIVATE ${COMPILE_LIBCXX})
target_link_libraries(
merkle_mem PRIVATE ${CMAKE_THREAD_LIBS_INIT} ${LINK_LIBCXX}
Expand All @@ -1101,7 +1105,7 @@ if(BUILD_TESTS)
# Raft driver and scenario test
add_executable(
raft_driver ${CMAKE_CURRENT_SOURCE_DIR}/src/consensus/aft/test/driver.cpp
src/enclave/thread_local.cpp
src/enclave/thread_local.cpp src/ds/nonstd.cpp
)
target_link_libraries(raft_driver PRIVATE ccfcrypto.host)
target_include_directories(raft_driver PRIVATE src/aft)
Expand Down
7 changes: 5 additions & 2 deletions cmake/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

# Unit test wrapper
function(add_unit_test name)
add_executable(${name} ${CCF_DIR}/src/enclave/thread_local.cpp ${ARGN})
add_executable(
${name} ${CCF_DIR}/src/enclave/thread_local.cpp
${CCF_DIR}/src/ds/nonstd.cpp ${ARGN}
)
target_compile_options(${name} PRIVATE ${COMPILE_LIBCXX})
target_include_directories(
${name} PRIVATE src ${CCFCRYPTO_INC} ${CCF_DIR}/3rdparty/test
Expand Down Expand Up @@ -349,7 +352,7 @@ function(add_picobench name)
PARSE_ARGV 1 PARSED_ARGS "" "" "SRCS;INCLUDE_DIRS;LINK_LIBS"
)

add_executable(${name} ${PARSED_ARGS_SRCS})
add_executable(${name} src/ds/nonstd.cpp ${PARSED_ARGS_SRCS})

target_include_directories(${name} PRIVATE src ${PARSED_ARGS_INCLUDE_DIRS})

Expand Down
137 changes: 2 additions & 135 deletions include/ccf/ds/nonstd.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the Apache 2.0 License.
#pragma once

#include <algorithm>
#include <array>
#include <cctype>
#include <filesystem>
Expand Down Expand Up @@ -174,64 +173,9 @@ namespace ccf::nonstd

/** These convert strings to upper or lower case, in-place
*/
static inline void to_upper(std::string& s)
{
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) {
return std::toupper(c);
});
}

static inline void to_lower(std::string& s)
{
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) {
return std::tolower(c);
});
}

// Iterators for map-keys and map-values
template <typename TMapIterator>
class KeyIterator : public TMapIterator
{
public:
KeyIterator() : TMapIterator() {}
KeyIterator(TMapIterator it) : TMapIterator(it) {}

using Key =
typename std::iterator_traits<TMapIterator>::value_type::first_type;
using value_type = Key;
void to_upper(std::string& s);

Key* operator->()
{
return TMapIterator::operator->()->first;
}

Key operator*()
{
return TMapIterator::operator*().first;
}
};

template <typename TMapIterator>
class ValueIterator : public TMapIterator
{
public:
ValueIterator() : TMapIterator() {}
ValueIterator(TMapIterator it) : TMapIterator(it) {}

using Value =
typename std::iterator_traits<TMapIterator>::value_type::second_type;
using value_type = Value;

Value* operator->()
{
return TMapIterator::operator->()->second;
}

Value operator*()
{
return TMapIterator::operator*().second;
}
};
void to_lower(std::string& s);

/// Iterate through tuple, calling functor on each element
template <size_t I = 0, typename F, typename... Ts>
Expand All @@ -243,81 +187,4 @@ namespace ccf::nonstd
tuple_for_each<I + 1>(t, f);
}
}

static inline std::string expand_envvar(const std::string& str)
{
if (str.empty() || str[0] != '$')
{
return str;
}

char* e = std::getenv(str.c_str() + 1);
if (e == nullptr)
{
return str;
}
else
{
return std::string(e);
}
}

static inline std::string expand_envvars_in_path(const std::string& str)
{
std::filesystem::path path(str);

if (path.empty())
{
return str;
}

std::vector<std::filesystem::path> elements;
auto it = path.begin();
if (path.has_root_directory())
{
++it;
elements.push_back(path.root_directory());
}

while (it != path.end())
{
elements.push_back(expand_envvar(*it++));
}

std::filesystem::path resolved;
for (auto& element : elements)
{
resolved /= element;
}

return resolved.lexically_normal().string();
}

static inline std::string camel_case(
std::string s,
// Should the first character be upper-cased?
bool camel_first = true,
// Regex fragment to identify which characters should be upper-cased, by
// matching a separator preceding them. Default is to match any
// non-alphanumeric character
const std::string& separator_regex = "[^[:alnum:]]")
{
// Replacement is always a 1-character string
std::string replacement(1, '\0');

std::string prefix_matcher =
camel_first ? fmt::format("(^|{})", separator_regex) : separator_regex;
std::regex re(prefix_matcher + "[a-z]");
std::smatch match;

while (std::regex_search(s, match, re))
{
// Replacement is the upper-casing of the final character from the match
replacement[0] = std::toupper(match.str()[match.length() - 1]);

s = s.replace(match.position(), match.length(), replacement);
}

return s;
}
}
103 changes: 103 additions & 0 deletions src/ds/nonstd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the Apache 2.0 License.

#include "ccf/ds/nonstd.h"

#include "ds/nonstd.h"

#include <algorithm>
#include <regex>
#include <string>

#define FMT_HEADER_ONLY
#include <fmt/format.h>

namespace ccf::nonstd
{
// Implementations for ccf/ds/nonstd.h
void to_upper(std::string& s)
{
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) {
return std::toupper(c);
});
}

void to_lower(std::string& s)
{
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) {
return std::tolower(c);
});
}

// Implementations for ds/nonstd.h
std::string expand_envvar(const std::string& str)
{
if (str.empty() || str[0] != '$')
{
return str;
}

char* e = std::getenv(str.c_str() + 1);
if (e == nullptr)
{
return str;
}
else
{
return std::string(e);
}
}

std::string expand_envvars_in_path(const std::string& str)
{
std::filesystem::path path(str);

if (path.empty())
{
return str;
}

std::vector<std::filesystem::path> elements;
auto it = path.begin();
if (path.has_root_directory())
{
++it;
elements.push_back(path.root_directory());
}

while (it != path.end())
{
elements.push_back(expand_envvar(*it++));
}

std::filesystem::path resolved;
for (auto& element : elements)
{
resolved /= element;
}

return resolved.lexically_normal().string();
}

std::string camel_case(
std::string s, bool camel_first, const std::string& separator_regex)
{
// Replacement is always a 1-character string
std::string replacement(1, '\0');

std::string prefix_matcher =
camel_first ? fmt::format("(^|{})", separator_regex) : separator_regex;
std::regex re(prefix_matcher + "[a-z]");
std::smatch match;

while (std::regex_search(s, match, re))
{
// Replacement is the upper-casing of the final character from the match
replacement[0] = std::toupper(match.str()[match.length() - 1]);

s = s.replace(match.position(), match.length(), replacement);
}

return s;
}
}
65 changes: 65 additions & 0 deletions src/ds/nonstd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the Apache 2.0 License.
#pragma once
#include <string>

namespace ccf::nonstd
{
// Iterators for map-keys and map-values
template <typename TMapIterator>
class KeyIterator : public TMapIterator
{
public:
KeyIterator() : TMapIterator() {}
KeyIterator(TMapIterator it) : TMapIterator(it) {}

using Key =
typename std::iterator_traits<TMapIterator>::value_type::first_type;
using value_type = Key;

Key* operator->()
{
return TMapIterator::operator->()->first;
}

Key operator*()
{
return TMapIterator::operator*().first;
}
};

template <typename TMapIterator>
class ValueIterator : public TMapIterator
{
public:
ValueIterator() : TMapIterator() {}
ValueIterator(TMapIterator it) : TMapIterator(it) {}

using Value =
typename std::iterator_traits<TMapIterator>::value_type::second_type;
using value_type = Value;

Value* operator->()
{
return TMapIterator::operator->()->second;
}

Value operator*()
{
return TMapIterator::operator*().second;
}
};

std::string expand_envvar(const std::string& str);

std::string expand_envvars_in_path(const std::string& str);

std::string camel_case(
std::string s,
// Should the first character be upper-cased?
bool camel_first = true,
// Regex fragment to identify which characters should be upper-cased, by
// matching a separator preceding them. Default is to match any
// non-alphanumeric character
const std::string& separator_regex = "[^[:alnum:]]");
}
Loading
Loading