Add ParserOptions::detect_flow_ml()

This commit is contained in:
Joao Paulo Magalhaes
2025-10-20 02:55:45 +01:00
parent 27b56e59e5
commit 3a750e8a3b
4 changed files with 59 additions and 4 deletions

View File

@@ -1537,7 +1537,7 @@ void ParseEngine<EventHandler>::_save_indentation()
template<class EventHandler>
void ParseEngine<EventHandler>::_end_map_flow()
{
bool multiline = m_evt_handler->m_parent->pos.line < m_evt_handler->m_curr->pos.line;
bool multiline = m_options.detect_flow_ml() && m_evt_handler->m_parent->pos.line < m_evt_handler->m_curr->pos.line;
_c4dbgpf("mapflow: end, multiline={}", multiline);
m_evt_handler->end_map_flow(multiline);
}
@@ -1545,7 +1545,7 @@ void ParseEngine<EventHandler>::_end_map_flow()
template<class EventHandler>
void ParseEngine<EventHandler>::_end_seq_flow()
{
bool multiline = m_evt_handler->m_parent->pos.line < m_evt_handler->m_curr->pos.line;
bool multiline = m_options.detect_flow_ml() && m_evt_handler->m_parent->pos.line < m_evt_handler->m_curr->pos.line;
_c4dbgpf("seqflow: end, multiline={}", multiline);
m_evt_handler->end_seq_flow(multiline);
}

View File

@@ -225,7 +225,8 @@ private:
typedef enum : uint32_t {
SCALAR_FILTERING = (1u << 0u),
LOCATIONS = (1u << 1u),
DEFAULTS = SCALAR_FILTERING,
DETECT_FLOW_ML = (1u << 2u),
DEFAULTS = SCALAR_FILTERING|DETECT_FLOW_ML,
} Flags_e;
uint32_t flags = DEFAULTS;
@@ -253,6 +254,28 @@ public:
/** @} */
public:
/** @name detection of @ref FLOW_ML container style */
/** @{ */
/** enable/disable detection of @ref FLOW_ML container style. When
* enabled, the parser will set @ref FLOW_ML as the style of flow
* containers which have the terminating bracket on a line
* different from that of the opening bracket. */
ParserOptions& detect_flow_ml(bool enabled) noexcept
{
if(enabled)
flags |= DETECT_FLOW_ML;
else
flags &= ~DETECT_FLOW_ML;
return *this;
}
/** query status of detection of @ref FLOW_ML container style. */
C4_ALWAYS_INLINE bool detect_flow_ml() const noexcept { return (flags & DETECT_FLOW_ML); }
/** @} */
public:
/** @name scalar filtering status (experimental; disable at your discretion) */

View File

@@ -182,7 +182,7 @@ C4_SUPPRESS_WARNING_GCC_POP
#if !(defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))
/** use this macro to add a case to the test group. */
/** use this macro to add a case (of type @ref Case) to the test group. */
#define ADD_CASE_TO_GROUP(...) \
group_cases__->emplace_back(csubstr(__FILE__), __LINE__+1, __VA_ARGS__)

View File

@@ -614,6 +614,38 @@ TEST(parse_in_arena, error_without_handler)
});
}
TEST(parse_flow_ml, respects_parser_options)
{
csubstr yaml = R"({
foo: 0,
bar: 1,
map: {
hell: yeah
},
seq: [
hell, yeah
]
})";
const ParserOptions defaults = ParserOptions{};
const ParserOptions no_flow_ml = ParserOptions{}.detect_flow_ml(false);
{
SCOPED_TRACE("default behavior: detect flow_ml");
test_check_emit_check_with_parser(yaml, defaults, [](const Tree& t, Parser const&){
EXPECT_TRUE(t.rootref().is_flow_ml());
EXPECT_TRUE(t["map"].is_flow_ml());
EXPECT_TRUE(t["seq"].is_flow_ml());
});
}
{
SCOPED_TRACE("custom behavior: do not detect flow_ml");
test_check_emit_check_with_parser(yaml, no_flow_ml, [](const Tree& t, Parser const&){
EXPECT_FALSE(t.rootref().is_flow_ml());
EXPECT_FALSE(t["map"].is_flow_ml());
EXPECT_FALSE(t["seq"].is_flow_ml());
});
}
}
//-----------------------------------------------------------------------------