mirror of
https://github.com/fmtlib/fmt.git
synced 2025-08-02 12:14:43 +02:00
Fix dynamic named arg format spec handling (#4361)
When dealing with dynamic named format args, need to account for nested named args when skipping the content of the replacement. Fixes #4360
This commit is contained in:
@@ -1718,7 +1718,19 @@ class format_string_checker {
|
|||||||
-> const Char* {
|
-> const Char* {
|
||||||
context_.advance_to(begin);
|
context_.advance_to(begin);
|
||||||
if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_);
|
if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_);
|
||||||
while (begin != end && *begin != '}') ++begin;
|
|
||||||
|
// If id is out of range, it means we do not know the type and cannot parse
|
||||||
|
// the format at compile time. Instead, skip over content until we finish
|
||||||
|
// the format spec, accounting for any nested replacements.
|
||||||
|
auto bracket_count = 0;
|
||||||
|
while (begin != end && (bracket_count > 0 || *begin != '}')) {
|
||||||
|
if (*begin == '{')
|
||||||
|
++bracket_count;
|
||||||
|
else if (*begin == '}')
|
||||||
|
--bracket_count;
|
||||||
|
|
||||||
|
++begin;
|
||||||
|
}
|
||||||
return begin;
|
return begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -582,6 +582,8 @@ TEST(format_test, named_arg) {
|
|||||||
EXPECT_EQ("1/a/A", fmt::format("{_1}/{a_}/{A_}", fmt::arg("a_", 'a'),
|
EXPECT_EQ("1/a/A", fmt::format("{_1}/{a_}/{A_}", fmt::arg("a_", 'a'),
|
||||||
fmt::arg("A_", "A"), fmt::arg("_1", 1)));
|
fmt::arg("A_", "A"), fmt::arg("_1", 1)));
|
||||||
EXPECT_EQ(fmt::format("{0:{width}}", -42, fmt::arg("width", 4)), " -42");
|
EXPECT_EQ(fmt::format("{0:{width}}", -42, fmt::arg("width", 4)), " -42");
|
||||||
|
EXPECT_EQ(fmt::format("{value:{width}}", fmt::arg("value", -42),
|
||||||
|
fmt::arg("width", 4)), " -42");
|
||||||
EXPECT_EQ("st",
|
EXPECT_EQ("st",
|
||||||
fmt::format("{0:.{precision}}", "str", fmt::arg("precision", 2)));
|
fmt::format("{0:.{precision}}", "str", fmt::arg("precision", 2)));
|
||||||
EXPECT_EQ(fmt::format("{} {two}", 1, fmt::arg("two", 2)), "1 2");
|
EXPECT_EQ(fmt::format("{} {two}", 1, fmt::arg("two", 2)), "1 2");
|
||||||
|
Reference in New Issue
Block a user