Branch data 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 : 24369 : std::vector<T> Split(const Span<const char>& sp, std::string_view separators) 49 : : { 50 : 24369 : std::vector<T> ret; 51 : 24369 : auto it = sp.begin(); 52 : 24369 : auto start = it; 53 [ + + ]: 3593119 : while (it != sp.end()) { 54 [ + + ]: 3568750 : if (separators.find(*it) != std::string::npos) { 55 [ + - ]: 5019 : ret.emplace_back(start, it); 56 : 5019 : start = it + 1; 57 : 5019 : } 58 : 3568750 : ++it; 59 : : } 60 [ + - ]: 24369 : ret.emplace_back(start, it); 61 : 24369 : return ret; 62 [ + - ]: 24369 : } 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 : 24369 : std::vector<T> Split(const Span<const char>& sp, char sep) 73 : : { 74 : 24369 : return Split<T>(sp, std::string_view{&sep, 1}); 75 : : } 76 : : 77 : : } // namespace spanparsing 78 : : 79 : : #endif // BITCOIN_UTIL_SPANPARSING_H