From 230d43fdbc41b356700b0d8a6984d69e00279ade Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 30 Jul 2019 14:53:05 -0700 Subject: Abstract out some of the descriptor Span-parsing helpers --- src/util/spanparsing.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ src/util/spanparsing.h | 29 +++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/util/spanparsing.cpp create mode 100644 src/util/spanparsing.h (limited to 'src/util') diff --git a/src/util/spanparsing.cpp b/src/util/spanparsing.cpp new file mode 100644 index 000000000..0c8575399 --- /dev/null +++ b/src/util/spanparsing.cpp @@ -0,0 +1,67 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include + +#include +#include + +namespace spanparsing { + +bool Const(const std::string& str, Span& sp) +{ + if ((size_t)sp.size() >= str.size() && std::equal(str.begin(), str.end(), sp.begin())) { + sp = sp.subspan(str.size()); + return true; + } + return false; +} + +bool Func(const std::string& str, Span& sp) +{ + if ((size_t)sp.size() >= str.size() + 2 && sp[str.size()] == '(' && sp[sp.size() - 1] == ')' && std::equal(str.begin(), str.end(), sp.begin())) { + sp = sp.subspan(str.size() + 1, sp.size() - str.size() - 2); + return true; + } + return false; +} + +Span Expr(Span& sp) +{ + int level = 0; + auto it = sp.begin(); + while (it != sp.end()) { + if (*it == '(') { + ++level; + } else if (level && *it == ')') { + --level; + } else if (level == 0 && (*it == ')' || *it == ',')) { + break; + } + ++it; + } + Span ret = sp.first(it - sp.begin()); + sp = sp.subspan(it - sp.begin()); + return ret; +} + +std::vector> Split(const Span& sp, char sep) +{ + std::vector> ret; + auto it = sp.begin(); + auto start = it; + while (it != sp.end()) { + if (*it == sep) { + ret.emplace_back(start, it); + start = it + 1; + } + ++it; + } + ret.emplace_back(start, it); + return ret; +} + +} // namespace spanparsing diff --git a/src/util/spanparsing.h b/src/util/spanparsing.h new file mode 100644 index 000000000..a2eb24b1f --- /dev/null +++ b/src/util/spanparsing.h @@ -0,0 +1,29 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_SPANPARSING_H +#define BITCOIN_UTIL_SPANPARSING_H + +#include + +#include +#include + +namespace spanparsing { + +/** Parse a constant. If successful, sp is updated to skip the constant and return true. */ +bool Const(const std::string& str, Span& sp); + +/** Parse a function call. If successful, sp is updated to be the function's argument(s). */ +bool Func(const std::string& str, Span& sp); + +/** Return the expression that sp begins with, and update sp to skip it. */ +Span Expr(Span& sp); + +/** Split a string on every instance of sep, returning a vector. */ +std::vector> Split(const Span& sp, char sep); + +} // namespace spanparsing + +#endif // BITCOIN_UTIL_SPANPARSING_H -- cgit v1.2.3 From 5e69aeec3f2a0fafd5e591b7222716f00145761d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 18 Sep 2019 12:25:55 -0700 Subject: Add documenting comments to spanparsing.h --- src/util/spanparsing.h | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'src/util') diff --git a/src/util/spanparsing.h b/src/util/spanparsing.h index a2eb24b1f..63f54758b 100644 --- a/src/util/spanparsing.h +++ b/src/util/spanparsing.h @@ -12,16 +12,37 @@ namespace spanparsing { -/** Parse a constant. If successful, sp is updated to skip the constant and return true. */ +/** Parse a constant. + * + * If sp's initial part matches str, sp is updated to skip that part, and true is returned. + * Otherwise sp is unmodified and false is returned. + */ bool Const(const std::string& str, Span& sp); -/** Parse a function call. If successful, sp is updated to be the function's argument(s). */ +/** Parse a function call. + * + * If sp's initial part matches str + "(", and sp ends with ")", sp is updated to be the + * section between the braces, and true is returned. Otherwise sp is unmodified and false + * is returned. + */ bool Func(const std::string& str, Span& sp); -/** Return the expression that sp begins with, and update sp to skip it. */ +/** Extract the expression that sp begins with. + * + * This function will return the initial part of sp, up to (but not including) the first + * comma or closing brace, skipping ones that are surrounded by braces. So for example, + * for "foo(bar(1),2),3" the initial part "foo(bar(1),2)" will be returned. sp will be + * updated to skip the initial part that is returned. + */ Span Expr(Span& sp); -/** Split a string on every instance of sep, returning a vector. */ +/** Split a string on every instance of sep, returning a vector. + * + * If sep does not occur in sp, a singleton with the entirety of sp is returned. + * + * Note that this function does not care about braces, so splitting + * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. + */ std::vector> Split(const Span& sp, char sep); } // namespace spanparsing -- cgit v1.2.3