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