Line data Source code
1 : // Copyright (c) 2018-2022 The Bitcoin Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #ifndef BITCOIN_UTIL_SPANPARSING_H 6 : #define BITCOIN_UTIL_SPANPARSING_H 7 : 8 : #include <span.h> 9 : 10 : #include <string> 11 : #include <string_view> 12 : #include <vector> 13 : 14 : namespace spanparsing { 15 : 16 : /** Parse a constant. 17 : * 18 : * If sp's initial part matches str, sp is updated to skip that part, and true is returned. 19 : * Otherwise sp is unmodified and false is returned. 20 : */ 21 : bool Const(const std::string& str, Span<const char>& sp); 22 : 23 : /** Parse a function call. 24 : * 25 : * If sp's initial part matches str + "(", and sp ends with ")", sp is updated to be the 26 : * section between the braces, and true is returned. Otherwise sp is unmodified and false 27 : * is returned. 28 : */ 29 : bool Func(const std::string& str, Span<const char>& sp); 30 : 31 : /** Extract the expression that sp begins with. 32 : * 33 : * This function will return the initial part of sp, up to (but not including) the first 34 : * comma or closing brace, skipping ones that are surrounded by braces. So for example, 35 : * for "foo(bar(1),2),3" the initial part "foo(bar(1),2)" will be returned. sp will be 36 : * updated to skip the initial part that is returned. 37 : */ 38 : Span<const char> Expr(Span<const char>& sp); 39 : 40 : /** Split a string on any char found in separators, returning a vector. 41 : * 42 : * If sep does not occur in sp, a singleton with the entirety of sp is returned. 43 : * 44 : * Note that this function does not care about braces, so splitting 45 : * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. 46 : */ 47 : template <typename T = Span<const char>> 48 364 : std::vector<T> Split(const Span<const char>& sp, std::string_view separators) 49 : { 50 364 : std::vector<T> ret; 51 364 : auto it = sp.begin(); 52 364 : auto start = it; 53 3130 : while (it != sp.end()) { 54 2766 : if (separators.find(*it) != std::string::npos) { 55 4 : ret.emplace_back(start, it); 56 4 : start = it + 1; 57 4 : } 58 2766 : ++it; 59 : } 60 364 : ret.emplace_back(start, it); 61 364 : return ret; 62 364 : } 63 : 64 : /** Split a string on every instance of sep, returning a vector. 65 : * 66 : * If sep does not occur in sp, a singleton with the entirety of sp is returned. 67 : * 68 : * Note that this function does not care about braces, so splitting 69 : * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. 70 : */ 71 : template <typename T = Span<const char>> 72 364 : std::vector<T> Split(const Span<const char>& sp, char sep) 73 : { 74 364 : return Split<T>(sp, std::string_view{&sep, 1}); 75 : } 76 : 77 : } // namespace spanparsing 78 : 79 : #endif // BITCOIN_UTIL_SPANPARSING_H