Skip to content

Commit

Permalink
Add parsing utilities (#3090)
Browse files Browse the repository at this point in the history
* Add util/parsers skeletton

* Add find_matching_parentheses

* conditional refactor

* Add find_not_in_parentheses

* Add some doc

* Add find_not_in_parentheses substr overload

* Add glob_match

* Remove warning
  • Loading branch information
AntoinePrv authored Jan 2, 2024
1 parent 30d62af commit 1b56e38
Show file tree
Hide file tree
Showing 7 changed files with 571 additions and 19 deletions.
3 changes: 3 additions & 0 deletions libmamba/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ set(
${LIBMAMBA_SOURCE_DIR}/util/encoding.cpp
${LIBMAMBA_SOURCE_DIR}/util/environment.cpp
${LIBMAMBA_SOURCE_DIR}/util/os_win.cpp
${LIBMAMBA_SOURCE_DIR}/util/parsers.cpp
${LIBMAMBA_SOURCE_DIR}/util/path_manip.cpp
${LIBMAMBA_SOURCE_DIR}/util/string.cpp
${LIBMAMBA_SOURCE_DIR}/util/url.cpp
Expand Down Expand Up @@ -259,6 +260,7 @@ set(
${LIBMAMBA_INCLUDE_DIR}/mamba/util/build.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/cast.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/compare.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/conditional.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/cryptography.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/deprecation.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/encoding.hpp
Expand All @@ -271,6 +273,7 @@ set(
${LIBMAMBA_INCLUDE_DIR}/mamba/util/iterator.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/json.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/os_win.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/parsers.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/path_manip.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/string.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/util/tuple_hash.hpp
Expand Down
40 changes: 40 additions & 0 deletions libmamba/include/mamba/util/conditional.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2023, QuantStack and Mamba Contributors
//
// Distributed under the terms of the BSD 3-Clause License.
//
// The full license is in the file LICENSE, distributed with this software.

#ifndef MAMBA_UTIL_CONDITIONAL_HPP
#define MAMBA_UTIL_CONDITIONAL_HPP

#include <type_traits>

namespace mamba::util
{

template <typename Int>
[[nodiscard]] auto if_else(bool condition, Int true_val, Int false_val) noexcept -> Int;

/********************
* Implementation *
********************/

template <typename Int>
auto if_else(bool condition, Int true_val, Int false_val) noexcept -> Int
{
if constexpr (std::is_enum_v<Int>)
{
using int_t = std::underlying_type_t<Int>;
return static_cast<Int>(
if_else(condition, static_cast<int_t>(true_val), static_cast<int_t>(false_val))
);
}
else
{
using int_t = Int;
return static_cast<int_t>(condition) * true_val
+ (int_t(1) - static_cast<int_t>(condition)) * false_val;
}
}
}
#endif
108 changes: 108 additions & 0 deletions libmamba/include/mamba/util/parsers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright (c) 2023, QuantStack and Mamba Contributors
//
// Distributed under the terms of the BSD 3-Clause License.
//
// The full license is in the file LICENSE, distributed with this software.

#ifndef MAMBA_UTIL_PARSERS_HPP
#define MAMBA_UTIL_PARSERS_HPP

#include <string_view>
#include <utility>

#include <tl/expected.hpp>

namespace mamba::util
{

enum struct ParseError
{
Ok,
InvalidInput,
NotFound,
};

/**
* Find the next matching parenthesese pair.
*
* Correctly matches parenteses together so that inner parentheses pairs are skipped.
* Open and closing pairs need not be differents.
* If an error is encountered, @p err is modified to contain the error, otherwise it is left
* as it is.
*/
auto find_matching_parentheses_idx( //
std::string_view text,
ParseError& err,
char open = '(',
char close = ')'
) noexcept -> std::pair<std::size_t, std::size_t>;

/**
* Find the next matching parenthesese pair.
*
* Correctly matches parentheses together so that inner parentheses pairs are skipped.
* Open and closing pairs need not be differents.
*/
[[nodiscard]] auto find_matching_parentheses_idx( //
std::string_view text,
char open = '(',
char close = ')'
) noexcept -> tl::expected<std::pair<std::size_t, std::size_t>, ParseError>;

auto find_matching_parentheses_str( //
std::string_view text,
ParseError& err,
char open = '(',
char close = ')'
) noexcept -> std::string_view;

[[nodiscard]] auto find_matching_parentheses_str( //
std::string_view text,
char open = '(',
char close = ')'
) noexcept -> tl::expected<std::string_view, ParseError>;

/**
* Find a character, except in mathcing parentheses pairs.
*
* Find the first occurence of the given character, except if such character is inside a valid
* pair of parentheses.
* Open and closing pairs need not be differents.
*/
auto find_not_in_parentheses( //
std::string_view text,
char c,
ParseError& err,
char open = '(',
char close = ')'
) noexcept -> std::size_t;

auto find_not_in_parentheses( //
std::string_view text,
std::string_view val,
ParseError& err,
char open = '(',
char close = ')'
) noexcept -> std::size_t;

[[nodiscard]] auto find_not_in_parentheses( //
std::string_view text,
char c,
char open = '(',
char close = ')'
) noexcept -> tl::expected<std::size_t, ParseError>;

[[nodiscard]] auto find_not_in_parentheses( //
std::string_view text,
std::string_view val,
char open = '(',
char close = ')'
) noexcept -> tl::expected<std::size_t, ParseError>;

/**
* Test wether the glob pattern @p pattern matches the string @p str.
*/
[[nodiscard]] auto glob_match(std::string_view pattern, std::string_view str, char glob = '*')
-> bool;
}
#endif
20 changes: 1 addition & 19 deletions libmamba/src/util/encoding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
#include <array>
#include <cstdint>
#include <cstring>
#include <type_traits>

#include <openssl/evp.h>

#include "mamba/util/compare.hpp"
#include "mamba/util/conditional.hpp"
#include "mamba/util/encoding.hpp"
#include "mamba/util/string.hpp"

Expand All @@ -37,24 +37,6 @@ namespace mamba::util
high |= low & nibble_low_mask;
return high;
}

template <typename Int>
[[nodiscard]] auto if_else(bool condition, Int true_val, Int false_val) noexcept -> Int
{
if constexpr (std::is_enum_v<Int>)
{
using int_t = std::underlying_type_t<Int>;
return static_cast<Int>(
if_else(condition, static_cast<int_t>(true_val), static_cast<int_t>(false_val))
);
}
else
{
using int_t = Int;
return static_cast<int_t>(condition) * true_val
+ (int_t(1) - static_cast<int_t>(condition)) * false_val;
}
}
}

auto nibble_to_hex(std::byte b) noexcept -> char
Expand Down
Loading

0 comments on commit 1b56e38

Please sign in to comment.