jinja : fix split and replace with empty first arg (#24574)
* fix split and replace with empty first arg * fix reserve size
This commit is contained in:
+23
-4
@@ -673,6 +673,9 @@ const func_builtins & value_string_t::get_builtins() const {
|
|||||||
std::string str = val_input->as_string().str();
|
std::string str = val_input->as_string().str();
|
||||||
// FIXME: Support non-specified delimiter (split on consecutive (no leading or trailing) whitespace)
|
// FIXME: Support non-specified delimiter (split on consecutive (no leading or trailing) whitespace)
|
||||||
std::string delim = (args.count() > 1) ? args.get_pos(1)->as_string().str() : " ";
|
std::string delim = (args.count() > 1) ? args.get_pos(1)->as_string().str() : " ";
|
||||||
|
if (delim.empty()) {
|
||||||
|
throw raised_exception("empty separator");
|
||||||
|
}
|
||||||
int64_t maxsplit = (args.count() > 2) ? args.get_pos(2)->as_int() : -1;
|
int64_t maxsplit = (args.count() > 2) ? args.get_pos(2)->as_int() : -1;
|
||||||
auto result = mk_val<value_array>();
|
auto result = mk_val<value_array>();
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
@@ -697,6 +700,9 @@ const func_builtins & value_string_t::get_builtins() const {
|
|||||||
std::string str = val_input->as_string().str();
|
std::string str = val_input->as_string().str();
|
||||||
// FIXME: Support non-specified delimiter (split on consecutive (no leading or trailing) whitespace)
|
// FIXME: Support non-specified delimiter (split on consecutive (no leading or trailing) whitespace)
|
||||||
std::string delim = (args.count() > 1) ? args.get_pos(1)->as_string().str() : " ";
|
std::string delim = (args.count() > 1) ? args.get_pos(1)->as_string().str() : " ";
|
||||||
|
if (delim.empty()) {
|
||||||
|
throw raised_exception("empty separator");
|
||||||
|
}
|
||||||
int64_t maxsplit = (args.count() > 2) ? args.get_pos(2)->as_int() : -1;
|
int64_t maxsplit = (args.count() > 2) ? args.get_pos(2)->as_int() : -1;
|
||||||
auto result = mk_val<value_array>();
|
auto result = mk_val<value_array>();
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
@@ -722,10 +728,23 @@ const func_builtins & value_string_t::get_builtins() const {
|
|||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
throw not_implemented_exception("String replace with count argument not implemented");
|
throw not_implemented_exception("String replace with count argument not implemented");
|
||||||
}
|
}
|
||||||
size_t pos = 0;
|
if (old_str != new_str) {
|
||||||
while ((pos = str.find(old_str, pos)) != std::string::npos) {
|
size_t pos = 0;
|
||||||
str.replace(pos, old_str.length(), new_str);
|
if (old_str.empty()) {
|
||||||
pos += new_str.length();
|
std::string new_res;
|
||||||
|
new_res.reserve(str.length() + new_str.length() * (str.length() + 1));
|
||||||
|
new_res += new_str;
|
||||||
|
for (const char c : str) {
|
||||||
|
new_res.push_back(c);
|
||||||
|
new_res += new_str;
|
||||||
|
}
|
||||||
|
str = new_res;
|
||||||
|
} else {
|
||||||
|
while ((pos = str.find(old_str, pos)) != std::string::npos) {
|
||||||
|
str.replace(pos, old_str.length(), new_str);
|
||||||
|
pos += new_str.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto res = mk_val<value_string>(str);
|
auto res = mk_val<value_string>(str);
|
||||||
res->val_str.mark_input_based_on(args.get_pos(0)->val_str);
|
res->val_str.mark_input_based_on(args.get_pos(0)->val_str);
|
||||||
|
|||||||
@@ -1320,6 +1320,12 @@ static void test_string_methods(testing & t) {
|
|||||||
"hello jinja"
|
"hello jinja"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_template(t, "string.replace() empty",
|
||||||
|
"{{ s.replace('', '.') }}",
|
||||||
|
{{"s", "hello world"}},
|
||||||
|
".h.e.l.l.o. .w.o.r.l.d."
|
||||||
|
);
|
||||||
|
|
||||||
test_template(t, "string.replace() with count",
|
test_template(t, "string.replace() with count",
|
||||||
"{{ s.replace('a', 'X', 2) }}",
|
"{{ s.replace('a', 'X', 2) }}",
|
||||||
{{"s", "banana"}},
|
{{"s", "banana"}},
|
||||||
|
|||||||
Reference in New Issue
Block a user