Skip to content

Commit bda2918

Browse files
author
ph
committed
Merge branch 'master' into msvc
2 parents dbd3ecd + 5ada44d commit bda2918

File tree

4 files changed

+358
-87
lines changed

4 files changed

+358
-87
lines changed

tests.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,22 @@ using namespace YAML;
1313

1414
namespace YAML
1515
{
16-
doctest::String toString(EPathError value) { return (std::stringstream() << (int)value).str().c_str(); }
16+
template <typename TEnum>
17+
doctest::String DT2String(TEnum value, std::initializer_list<std::pair<TEnum, char const *>> map)
18+
{
19+
char const * p = YamlPathDetail::MapValue(value, map);
20+
if (p)
21+
return p;
22+
23+
return (std::stringstream() << "(" << (int)value << ")").str().c_str();
24+
}
25+
26+
doctest::String toString(EPathError value) { return DT2String(value, YamlPathDetail::MapEPathErrorName); }
1727

1828
namespace YamlPathDetail
1929
{
20-
doctest::String toString(EToken value) { return (std::stringstream() << (int)value).str().c_str(); }
21-
doctest::String toString(ESelector value) { return (std::stringstream() << (int)value).str().c_str(); }
30+
doctest::String toString(EToken value) { return DT2String(value, MapETokenName); }
31+
doctest::String toString(ESelector value) { return DT2String(value, MapESelectorName); }
2232
}
2333
}
2434

@@ -140,7 +150,7 @@ TEST_CASE("Internal: TokenScanner")
140150
{
141151
using namespace YamlPathDetail;
142152
{
143-
PathArg scanMe = "a.beta.'a b[c]'.\"a.b\".[].~.abc";
153+
PathArg scanMe = "a.beta.'a b[c]'.\"a.b\".[].#.abc";
144154
PathScanner scan(scanMe);
145155
CHECK(scan);
146156
CHECK(scan.NextToken().id == EToken::UnquotedIdentifier);
@@ -406,7 +416,7 @@ TEST_CASE("PathResolve - SeqMap")
406416
}
407417

408418

409-
TEST_CASE("PathResolve - SeqMapFilter")
419+
TEST_CASE("PathResolve - MapFilter (adapted from initial syntax)")
410420
{
411421
char const * sroot =
412422
R"(
@@ -448,7 +458,7 @@ TEST_CASE("PathResolve - SeqMapFilter")
448458

449459
{ // has no node with empty "name"
450460
auto node = YAML::Load(sroot);
451-
PathArg path = "{name=''}"; // all having a name
461+
PathArg path = "{name=''}";
452462
CHECK(PathResolve(node, path) == EPathError::NodeNotFound);
453463
CHECK(path == "{name=''}");
454464
CHECK(node.IsSequence());

yaml-path/yaml-path-internals.h

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ namespace YAML
6868
FetchArg,
6969
OpenBrace,
7070
CloseBrace,
71+
Exclamation,
72+
Caret,
73+
Asterisk,
74+
Tilde,
75+
Comma,
7176
};
7277
/* when adding a new token, also add to:
7378
- MapETokenName
@@ -92,17 +97,15 @@ namespace YAML
9297
None = 0,
9398
Key,
9499
Index,
95-
SeqMapFilter,
96-
KeyList,
100+
MapFilter,
97101
};
98102

99103
// Data for different selector types
100104
struct ArgNull {};
101105
struct ArgKey { PathArg key; };
102106
struct ArgIndex { size_t index; };
103-
struct ArgKVPair { PathArg key; std::optional<PathArg> value; }; // used in some selectors
104-
using ArgSeqMapFilter = ArgKVPair;
105-
using ArgKeyList = std::vector<ArgKVPair>;
107+
struct ArgKVPair { KVToken key; KVToken value; EKVOp op = EKVOp::Equal; };
108+
using ArgMapFilter = std::vector<ArgKVPair>;
106109

107110
/** \internal progressive scanner/parser for a YAML path as specified by YAML::Select
108111
This class implements two layers of the scan:
@@ -120,7 +123,7 @@ namespace YAML
120123
class PathScanner
121124
{
122125
public:
123-
using tSelectorData = std::variant<ArgNull, ArgKey, ArgIndex, ArgSeqMapFilter>; ///< union of the selector data for all selector types
126+
using tSelectorData = std::variant<ArgNull, ArgKey, ArgIndex, ArgMapFilter>; ///< union of the selector data for all selector types
124127

125128
private:
126129
PathArg m_rpath; // remainder of path to be scanned
@@ -151,6 +154,8 @@ namespace YAML
151154

152155
void SkipWS();
153156
bool NextSelectorToken(uint64_t validTokens, EPathError error = EPathError::InvalidToken);
157+
bool PeekSelectorToken(uint64_t validTokens);
158+
bool ReadKVToken(KVToken & result, uint64_t endTokens);
154159

155160
public:
156161
PathScanner(PathArg p, PathBoundArgs args = {}, PathException * diags = nullptr);
@@ -178,6 +183,14 @@ namespace YAML
178183

179184
inline static const uint64_t ValidTokensAtStart = BitsOf({ EToken::FetchArg, EToken::None, EToken::OpenBracket, EToken::OpenBrace, EToken::QuotedIdentifier, EToken::UnquotedIdentifier });
180185
};
186+
187+
template <typename T2, typename TEnum>
188+
T2 MapValue(TEnum value, std::initializer_list<std::pair<TEnum, T2>> values, T2 dflt = T2());
189+
190+
extern std::initializer_list<std::pair<EToken, char const *>> MapETokenName;
191+
extern std::initializer_list<std::pair<NodeType::value, char const *>> MapNodeTypeName;
192+
extern std::initializer_list<std::pair<ESelector, char const *>> MapESelectorName;
193+
extern std::initializer_list<std::pair<EPathError, char const *>> MapEPathErrorName;
181194
}
182195
}
183196

@@ -211,5 +224,16 @@ namespace YAML
211224
return ((TBits(1) << TBits(v)) & bits) != 0;
212225
}
213226

227+
/// \internal helper to map enum values to names, used for diagnostics
228+
template <typename T2, typename TEnum>
229+
T2 MapValue(TEnum value, std::initializer_list<std::pair<TEnum, T2>> values, T2 dflt)
230+
{
231+
for (auto && p : values)
232+
if (p.first == value)
233+
return p.second;
234+
return dflt;
235+
}
236+
237+
214238
}
215239
}

0 commit comments

Comments
 (0)