Merge pull request #102427 from AThousandShips/fix_substr

Clean up some uses of `String::substr`
This commit is contained in:
Thaddeus Crews 2025-03-07 15:12:33 -06:00
commit 3c43508ed7
No known key found for this signature in database
GPG Key ID: 62181B86FE9E5D84
54 changed files with 123 additions and 123 deletions

View File

@ -208,7 +208,7 @@ String ProjectSettings::localize_path(const String &p_path) const {
if (plocal[plocal.length() - 1] == '/') {
sep += 1;
}
return plocal + path.substr(sep, path.size() - sep);
return plocal + path.substr(sep);
}
}
@ -1129,7 +1129,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
category = "";
} else {
category = category.substr(0, div);
name = name.substr(div + 1, name.size());
name = name.substr(div + 1);
}
save_props[category].push_back(name);
}

View File

@ -166,7 +166,7 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, co
int sp = bp.rfind_char(':');
ERR_CONTINUE_MSG(sp == -1, vformat("Invalid breakpoint: '%s', expected file:line format.", bp));
singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1, bp.length()).to_int(), bp.substr(0, sp));
singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1).to_int(), bp.substr(0, sp));
}
allow_focus_steal_fn = p_allow_focus_steal_fn;

View File

@ -51,7 +51,7 @@ void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const Proper
} else if (p_retinfo.type == Variant::INT && p_retinfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
p_method.return_enum = p_retinfo.class_name;
if (p_method.return_enum.begins_with("_")) { //proxy class
p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length());
p_method.return_enum = p_method.return_enum.substr(1);
}
p_method.return_is_bitfield = p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_BITFIELD;
p_method.return_type = "int";
@ -85,7 +85,7 @@ void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const
} else if (p_arginfo.type == Variant::INT && p_arginfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
p_argument.enumeration = p_arginfo.class_name;
if (p_argument.enumeration.begins_with("_")) { //proxy class
p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length());
p_argument.enumeration = p_argument.enumeration.substr(1);
}
p_argument.is_bitfield = p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_BITFIELD;
p_argument.type = "int";

View File

@ -1420,25 +1420,25 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
bool optional = field.begins_with("*");
if (optional) {
// This is an optional field, but if exists it has to exist in both.
field = field.substr(1, field.length());
field = field.substr(1);
}
bool added = field.begins_with("+");
if (added) {
// Meaning this field must either exist or contents may not exist.
field = field.substr(1, field.length());
field = field.substr(1);
}
bool enum_values = field.begins_with("$");
if (enum_values) {
// Meaning this field is a list of enum values.
field = field.substr(1, field.length());
field = field.substr(1);
}
bool allow_name_change = field.begins_with("@");
if (allow_name_change) {
// Meaning that when structurally comparing the old and new value, the dictionary entry 'name' may change.
field = field.substr(1, field.length());
field = field.substr(1);
}
Variant old_value;

View File

@ -219,7 +219,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
continue;
}
String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length());
String name = pi.name.substr(pi.name.find_char('/') + 1);
r_options->push_back(name.quote());
}
}

View File

@ -106,7 +106,7 @@ void InputMap::get_argument_options(const StringName &p_function, int p_idx, Lis
continue;
}
String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length());
String name = pi.name.substr(pi.name.find_char('/') + 1);
r_options->push_back(name.quote());
}
}
@ -304,7 +304,7 @@ void InputMap::load_from_project_settings() {
continue;
}
String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length());
String name = pi.name.substr(pi.name.find_char('/') + 1);
Dictionary action = GLOBAL_GET(pi.name);
float deadzone = action.has("deadzone") ? (float)action["deadzone"] : DEFAULT_DEADZONE;

View File

@ -118,7 +118,7 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() {
continue;
}
String key = s.substr(0, sp).strip_edges();
String value = s.substr(sp + 1, s.length()).strip_edges();
String value = s.substr(sp + 1).strip_edges();
ret[key] = value;
}

View File

@ -50,13 +50,13 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, Ref<TLSOp
String host_lower = conn_host.to_lower();
if (host_lower.begins_with("http://")) {
conn_host = conn_host.substr(7, conn_host.length() - 7);
conn_host = conn_host.substr(7);
tls_options.unref();
} else if (host_lower.begins_with("https://")) {
if (tls_options.is_null()) {
tls_options = TLSOptions::client();
}
conn_host = conn_host.substr(8, conn_host.length() - 8);
conn_host = conn_host.substr(8);
}
ERR_FAIL_COND_V(tls_options.is_valid() && tls_options->is_server(), ERR_INVALID_PARAMETER);
@ -508,11 +508,11 @@ Error HTTPClientTCP::poll() {
continue;
}
if (s.begins_with("content-length:")) {
body_size = s.substr(s.find_char(':') + 1, s.length()).strip_edges().to_int();
body_size = s.substr(s.find_char(':') + 1).strip_edges().to_int();
body_left = body_size;
} else if (s.begins_with("transfer-encoding:")) {
String encoding = header.substr(header.find_char(':') + 1, header.length()).strip_edges();
String encoding = header.substr(header.find_char(':') + 1).strip_edges();
if (encoding == "chunked") {
chunked = true;
}

View File

@ -148,7 +148,7 @@ void IPAddress::_parse_ipv6(const String &p_string) {
void IPAddress::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret) {
String ip;
if (p_start != 0) {
ip = p_string.substr(p_start, p_string.length() - p_start);
ip = p_string.substr(p_start);
} else {
ip = p_string;
}

View File

@ -189,7 +189,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
}
}
msg_context = "";
l = l.substr(7, l.length()).strip_edges();
l = l.substr(7).strip_edges();
status = STATUS_READING_CONTEXT;
entered_context = true;
}
@ -202,7 +202,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
}
// We don't record the message in "msgid_plural" itself as tr_n(), TTRN(), RTRN() interfaces provide the plural string already.
// We just have to reset variables related to plurals for "msgstr[]" later on.
l = l.substr(12, l.length()).strip_edges();
l = l.substr(12).strip_edges();
plural_index = -1;
msgs_plural.clear();
msgs_plural.resize(plural_forms);
@ -230,7 +230,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
}
}
l = l.substr(5, l.length()).strip_edges();
l = l.substr(5).strip_edges();
status = STATUS_READING_ID;
// If we did not encounter msgctxt, we reset context to empty to reset it.
if (!entered_context) {
@ -246,10 +246,10 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
if (l.begins_with("msgstr[")) {
ERR_FAIL_COND_V_MSG(status != STATUS_READING_PLURAL, Ref<Resource>(), vformat("Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: %s:%d.", path, line));
plural_index++; // Increment to add to the next slot in vector msgs_plural.
l = l.substr(9, l.length()).strip_edges();
l = l.substr(9).strip_edges();
} else if (l.begins_with("msgstr")) {
ERR_FAIL_COND_V_MSG(status != STATUS_READING_ID, Ref<Resource>(), vformat("Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: %s:%d.", path, line));
l = l.substr(6, l.length()).strip_edges();
l = l.substr(6).strip_edges();
status = STATUS_READING_STRING;
}
@ -263,7 +263,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, Ref<Resource>(), vformat("Invalid line '%s' while parsing: %s:%d.", l, path, line));
l = l.substr(1, l.length());
l = l.substr(1);
// Find final quote, ignoring escaped ones (\").
// The escape_next logic is necessary to properly parse things like \\"
// where the backslash is the one being escaped, not the quote.
@ -329,7 +329,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
continue;
}
String prop = c.substr(0, p).strip_edges();
String value = c.substr(p + 1, c.length()).strip_edges();
String value = c.substr(p + 1).strip_edges();
if (prop == "X-Language" || prop == "Language") {
translation->set_locale(value);

View File

@ -110,7 +110,7 @@ void __print_line_rich(const String &p_string) {
int brk_end = p_string.find_char(']', brk_pos + 1);
if (brk_end == -1) {
txt += p_string.substr(brk_pos, p_string.length() - brk_pos);
txt += p_string.substr(brk_pos);
output += txt;
break;
}

View File

@ -238,7 +238,7 @@ Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r
}
if (is_scheme_valid) {
r_scheme = base.substr(0, pos + 3).to_lower();
base = base.substr(pos + 3, base.length() - pos - 3);
base = base.substr(pos + 3);
}
}
pos = base.find_char('#');
@ -250,14 +250,14 @@ Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r
pos = base.find_char('/');
// Path
if (pos != -1) {
r_path = base.substr(pos, base.length() - pos);
r_path = base.substr(pos);
base = base.substr(0, pos);
}
// Host
pos = base.find_char('@');
if (pos != -1) {
// Strip credentials
base = base.substr(pos + 1, base.length() - pos - 1);
base = base.substr(pos + 1);
}
if (base.begins_with("[")) {
// Literal IPv6
@ -266,7 +266,7 @@ Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r
return ERR_INVALID_PARAMETER;
}
r_host = base.substr(1, pos - 1);
base = base.substr(pos + 1, base.length() - pos - 1);
base = base.substr(pos + 1);
} else {
// Anything else
if (base.get_slice_count(":") > 2) {
@ -278,7 +278,7 @@ Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r
base = "";
} else {
r_host = base.substr(0, pos);
base = base.substr(pos, base.length() - pos);
base = base.substr(pos);
}
}
if (r_host.is_empty()) {
@ -287,7 +287,7 @@ Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r
r_host = r_host.to_lower();
// Port
if (base.begins_with(":")) {
base = base.substr(1, base.length() - 1);
base = base.substr(1);
if (!base.is_valid_int()) {
return ERR_INVALID_PARAMETER;
}
@ -4861,7 +4861,7 @@ String String::pad_zeros(int p_digits) const {
String String::trim_prefix(const String &p_prefix) const {
String s = *this;
if (s.begins_with(p_prefix)) {
return s.substr(p_prefix.length(), s.length() - p_prefix.length());
return s.substr(p_prefix.length());
}
return s;
}
@ -4870,7 +4870,7 @@ String String::trim_prefix(const char *p_prefix) const {
String s = *this;
if (s.begins_with(p_prefix)) {
int prefix_length = strlen(p_prefix);
return s.substr(prefix_length, s.length() - prefix_length);
return s.substr(prefix_length);
}
return s;
}
@ -5030,8 +5030,8 @@ String String::path_to(const String &p_path) const {
return p_path; //impossible to do this
}
src = src.substr(src_begin.length(), src.length());
dst = dst.substr(dst_begin.length(), dst.length());
src = src.substr(src_begin.length());
dst = dst.substr(dst_begin.length());
}
//remove leading and trailing slash and split

View File

@ -1678,7 +1678,7 @@ template <typename T>
static void register_utility_function(const String &p_name, const Vector<String> &argnames) {
String name = p_name;
if (name.begins_with("_")) {
name = name.substr(1, name.length() - 1);
name = name.substr(1);
}
StringName sname = name;
ERR_FAIL_COND(utility_function_table.has(sname));

View File

@ -383,7 +383,7 @@ String DirAccessUnix::get_current_dir(bool p_include_drive) const {
if (!base.is_empty()) {
String bd = current_dir.replace_first(base, "");
if (bd.begins_with("/")) {
return _get_root_string() + bd.substr(1, bd.length());
return _get_root_string() + bd.substr(1);
} else {
return _get_root_string() + bd;
}

View File

@ -220,7 +220,7 @@ String DirAccessWindows::get_current_dir(bool p_include_drive) const {
if (!base.is_empty()) {
String bd = cdir.replace_first(base, "");
if (bd.begins_with("/")) {
return _get_root_string() + bd.substr(1, bd.length());
return _get_root_string() + bd.substr(1);
} else {
return _get_root_string() + bd;
}

View File

@ -4662,7 +4662,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
for (int i = 0; i < subindices.size(); i++) {
InsertData id = p_id;
id.type = Animation::TYPE_BEZIER;
id.value = subindices[i].is_empty() ? p_id.value : p_id.value.get(subindices[i].substr(1, subindices[i].length()));
id.value = subindices[i].is_empty() ? p_id.value : p_id.value.get(subindices[i].substr(1));
id.path = String(p_id.path) + subindices[i];
p_next_tracks = _confirm_insert(id, p_next_tracks, p_reset_wanted, p_reset_anim, false);
}
@ -6515,7 +6515,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
text = path;
int sep = text.find_char(':');
if (sep != -1) {
text = text.substr(sep + 1, text.length());
text = text.substr(sep + 1);
}
}

View File

@ -362,7 +362,7 @@ void EditorVisualProfiler::_update_frame(bool p_focus_selected) {
stack.push_back(category);
categories.push_back(category);
name = name.substr(1, name.length());
name = name.substr(1);
category->set_text(0, name);
category->set_metadata(1, cpu_time);

View File

@ -242,7 +242,7 @@ void EditorAutoloadSettings::_autoload_edited() {
String scr_path = GLOBAL_GET(base);
if (scr_path.begins_with("*")) {
scr_path = scr_path.substr(1, scr_path.length());
scr_path = scr_path.substr(1);
}
// Singleton autoloads are represented with a leading "*" in their path.
@ -494,7 +494,7 @@ void EditorAutoloadSettings::update_autoload() {
info.is_singleton = scr_path.begins_with("*");
if (info.is_singleton) {
scr_path = scr_path.substr(1, scr_path.length());
scr_path = scr_path.substr(1);
}
info.name = name;
@ -873,7 +873,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
info.is_singleton = scr_path.begins_with("*");
if (info.is_singleton) {
scr_path = scr_path.substr(1, scr_path.length());
scr_path = scr_path.substr(1);
}
info.name = name;

View File

@ -1846,7 +1846,7 @@ bool EditorFileSystem::_find_file(const String &p_file, EditorFileSystemDirector
if (!f.begins_with("res://")) {
return false;
}
f = f.substr(6, f.length());
f = f.substr(6);
f = f.replace("\\", "/");
Vector<String> path = f.split("/");
@ -1972,7 +1972,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p
return nullptr;
}
f = f.substr(6, f.length());
f = f.substr(6);
f = f.replace("\\", "/");
if (f.is_empty()) {
return filesystem;

View File

@ -2517,7 +2517,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, const C
int brk_end = bbcode.find_char(']', brk_pos + 1);
if (brk_end == -1) {
p_rt->add_text(bbcode.substr(brk_pos, bbcode.length() - brk_pos).replace("\n", "\n\n"));
p_rt->add_text(bbcode.substr(brk_pos).replace("\n", "\n\n"));
break;
}

View File

@ -6861,7 +6861,7 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
{
MutexLock lock(eta.execute_output_mutex);
if (prev_len != eta.output.length()) {
String to_add = eta.output.substr(prev_len, eta.output.length());
String to_add = eta.output.substr(prev_len);
prev_len = eta.output.length();
execute_outputs->add_text(to_add);
DisplayServer::get_singleton()->process_events(); // Get rid of pending events.

View File

@ -594,7 +594,7 @@ bool EditorPropertyPath::_can_drop_data_fw(const Point2 &p_point, const Variant
}
for (const String &extension : extensions) {
if (filesPaths[0].ends_with(extension.substr(1, extension.size() - 1))) {
if (filesPaths[0].ends_with(extension.substr(1))) {
return true;
}
}

View File

@ -803,11 +803,11 @@ void EditorPropertyArray::setup(Variant::Type p_array_type, const String &p_hint
String subtype_string = p_hint_string.substr(0, hint_subtype_separator);
int slash_pos = subtype_string.find_char('/');
if (slash_pos >= 0) {
subtype_hint = PropertyHint(subtype_string.substr(slash_pos + 1, subtype_string.size() - slash_pos - 1).to_int());
subtype_hint = PropertyHint(subtype_string.substr(slash_pos + 1).to_int());
subtype_string = subtype_string.substr(0, slash_pos);
}
subtype_hint_string = p_hint_string.substr(hint_subtype_separator + 1, p_hint_string.size() - hint_subtype_separator - 1);
subtype_hint_string = p_hint_string.substr(hint_subtype_separator + 1);
subtype = Variant::Type(subtype_string.to_int());
}
}
@ -1086,11 +1086,11 @@ void EditorPropertyDictionary::setup(PropertyHint p_hint, const String &p_hint_s
String key_subtype_string = key.substr(0, hint_key_subtype_separator);
int slash_pos = key_subtype_string.find_char('/');
if (slash_pos >= 0) {
key_subtype_hint = PropertyHint(key_subtype_string.substr(slash_pos + 1, key_subtype_string.size() - slash_pos - 1).to_int());
key_subtype_hint = PropertyHint(key_subtype_string.substr(slash_pos + 1).to_int());
key_subtype_string = key_subtype_string.substr(0, slash_pos);
}
key_subtype_hint_string = key.substr(hint_key_subtype_separator + 1, key.size() - hint_key_subtype_separator - 1);
key_subtype_hint_string = key.substr(hint_key_subtype_separator + 1);
key_subtype = Variant::Type(key_subtype_string.to_int());
Variant new_key = object->get_new_item_key();
@ -1105,11 +1105,11 @@ void EditorPropertyDictionary::setup(PropertyHint p_hint, const String &p_hint_s
String value_subtype_string = value.substr(0, hint_value_subtype_separator);
int slash_pos = value_subtype_string.find_char('/');
if (slash_pos >= 0) {
value_subtype_hint = PropertyHint(value_subtype_string.substr(slash_pos + 1, value_subtype_string.size() - slash_pos - 1).to_int());
value_subtype_hint = PropertyHint(value_subtype_string.substr(slash_pos + 1).to_int());
value_subtype_string = value_subtype_string.substr(0, slash_pos);
}
value_subtype_hint_string = value.substr(hint_value_subtype_separator + 1, value.size() - hint_value_subtype_separator - 1);
value_subtype_hint_string = value.substr(hint_value_subtype_separator + 1);
value_subtype = Variant::Type(value_subtype_string.to_int());
Variant new_value = object->get_new_item_value();

View File

@ -235,7 +235,7 @@ Vector<Vector<String>> get_extractable_message_list() {
list.push_back(msgs);
}
msg_context = "";
l = l.substr(7, l.length()).strip_edges();
l = l.substr(7).strip_edges();
status = STATUS_READING_CONTEXT;
entered_context = true;
}
@ -244,7 +244,7 @@ Vector<Vector<String>> get_extractable_message_list() {
if (status != STATUS_READING_ID) {
ERR_FAIL_V_MSG(Vector<Vector<String>>(), "Unexpected 'msgid_plural', was expecting 'msgid' before 'msgid_plural' while parsing: " + path + ":" + itos(line));
}
l = l.substr(12, l.length()).strip_edges();
l = l.substr(12).strip_edges();
status = STATUS_READING_PLURAL;
} else if (l.begins_with("msgid")) {
ERR_FAIL_COND_V_MSG(status == STATUS_READING_ID, Vector<Vector<String>>(), "Unexpected 'msgid', was expecting 'msgstr' while parsing: " + path + ":" + itos(line));
@ -257,7 +257,7 @@ Vector<Vector<String>> get_extractable_message_list() {
list.push_back(msgs);
}
l = l.substr(5, l.length()).strip_edges();
l = l.substr(5).strip_edges();
status = STATUS_READING_ID;
// If we did not encounter msgctxt, we reset context to empty to reset it.
if (!entered_context) {
@ -271,11 +271,11 @@ Vector<Vector<String>> get_extractable_message_list() {
if (l.begins_with("msgstr[")) {
ERR_FAIL_COND_V_MSG(status != STATUS_READING_PLURAL, Vector<Vector<String>>(),
"Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: " + path + ":" + itos(line));
l = l.substr(9, l.length()).strip_edges();
l = l.substr(9).strip_edges();
} else if (l.begins_with("msgstr")) {
ERR_FAIL_COND_V_MSG(status != STATUS_READING_ID, Vector<Vector<String>>(),
"Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: " + path + ":" + itos(line));
l = l.substr(6, l.length()).strip_edges();
l = l.substr(6).strip_edges();
status = STATUS_READING_STRING;
}
@ -286,7 +286,7 @@ Vector<Vector<String>> get_extractable_message_list() {
ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, Vector<Vector<String>>(), "Invalid line '" + l + "' while parsing: " + path + ":" + itos(line));
l = l.substr(1, l.length());
l = l.substr(1);
// Find final quote, ignoring escaped ones (\").
// The escape_next logic is necessary to properly parse things like \\"
// where the backslash is the one being escaped, not the quote.

View File

@ -1563,7 +1563,7 @@ void FileSystemDock::_update_resource_paths_after_move(const HashMap<String, Str
String extra_path;
int sep_pos = r->get_path().find("::");
if (sep_pos >= 0) {
extra_path = base_path.substr(sep_pos, base_path.length());
extra_path = base_path.substr(sep_pos);
base_path = base_path.substr(0, sep_pos);
}
@ -1629,7 +1629,7 @@ void FileSystemDock::_update_project_settings_after_move(const HashMap<String, S
// If the autoload resource paths has a leading "*", it indicates that it is a Singleton,
// so we have to handle both cases when updating.
String autoload = GLOBAL_GET(E.name);
String autoload_singleton = autoload.substr(1, autoload.length());
String autoload_singleton = autoload.substr(1);
if (p_renames.has(autoload)) {
ProjectSettings::get_singleton()->set_setting(E.name, p_renames[autoload]);
} else if (autoload.begins_with("*") && p_renames.has(autoload_singleton)) {
@ -3695,7 +3695,7 @@ void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) {
if (fpath.size() > String("res://").size()) {
fpath = fpath.left(fpath.size() - 2); // Remove last '/'.
const int slash_idx = fpath.rfind_char('/');
fpath = fpath.substr(slash_idx + 1, fpath.size() - slash_idx - 1);
fpath = fpath.substr(slash_idx + 1);
}
tree_item = tree->get_item_with_text(fpath);

View File

@ -172,7 +172,7 @@ void EditorFileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_file
if (!valid && filter_slice_count > 0) {
String str = (flt.get_slice(",", 0).strip_edges());
f += str.substr(1, str.length() - 1);
f += str.substr(1);
file->set_text(f.get_file());
valid = true;
}
@ -650,7 +650,7 @@ void EditorFileDialog::_action_pressed() {
if (!valid && filter_slice_count > 0) {
String str = (flt.get_slice(",", 0).strip_edges());
f += str.substr(1, str.length() - 1);
f += str.substr(1);
_request_single_thumbnail(get_current_dir().path_join(f.get_file()));
file->set_text(f.get_file());
valid = true;
@ -1436,7 +1436,7 @@ void EditorFileDialog::set_current_path(const String &p_path) {
set_current_file(p_path);
} else {
String path_dir = p_path.substr(0, pos);
String path_file = p_path.substr(pos + 1, p_path.length());
String path_file = p_path.substr(pos + 1);
set_current_dir(path_dir);
set_current_file(path_file);
}

View File

@ -66,7 +66,7 @@ void Collada::Vertex::fix_unit_scale(const Collada &p_state) {
static String _uri_to_id(const String &p_uri) {
if (p_uri.begins_with("#")) {
return p_uri.substr(1, p_uri.size() - 1);
return p_uri.substr(1);
} else {
return p_uri;
}

View File

@ -365,7 +365,7 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
face[1] = face[2];
}
} else if (l.begins_with("s ")) { //smoothing
String what = l.substr(2, l.length()).strip_edges();
String what = l.substr(2).strip_edges();
bool do_smooth;
if (what == "off") {
do_smooth = false;
@ -476,7 +476,7 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
}
if (l.begins_with("o ")) {
name = l.substr(2, l.length()).strip_edges();
name = l.substr(2).strip_edges();
}
if (l.begins_with("usemtl ")) {
@ -484,7 +484,7 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
}
if (l.begins_with("g ")) {
current_group = l.substr(2, l.length()).strip_edges();
current_group = l.substr(2).strip_edges();
}
} else if (l.begins_with("mtllib ")) { //parse material

View File

@ -435,7 +435,7 @@ static String _fixstr(const String &p_what, const String &p_str) {
what = what.substr(0, what.length() - 1);
}
String end = p_what.substr(what.length(), p_what.length() - what.length());
String end = p_what.substr(what.length());
if (what.containsn("$" + p_str)) { // Blender and other stuff.
return what.replace("$" + p_str, "") + end;

View File

@ -570,7 +570,7 @@ void LocalizationEditor::update_translations() {
const String &s2 = selected[j];
int qp = s2.rfind_char(':');
String path = s2.substr(0, qp);
String locale = s2.substr(qp + 1, s2.length());
String locale = s2.substr(qp + 1);
TreeItem *t2 = translation_remap_options->create_item(root2);
t2->set_editable(0, false);

View File

@ -907,7 +907,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons
for (int i = 0; i < headers.size(); i++) {
if (headers[i].findn("ETag:") == 0) { // Save etag
String cache_filename_base = EditorPaths::get_singleton()->get_cache_dir().path_join("assetimage_" + image_queue[p_queue_id].image_url.md5_text());
String new_etag = headers[i].substr(headers[i].find_char(':') + 1, headers[i].length()).strip_edges();
String new_etag = headers[i].substr(headers[i].find_char(':') + 1).strip_edges();
Ref<FileAccess> file = FileAccess::open(cache_filename_base + ".etag", FileAccess::WRITE);
if (file.is_valid()) {
file->store_line(new_etag);

View File

@ -520,7 +520,7 @@ String RenameDialog::_postprocess(const String &subject) {
buffer += result.substr(start, 1).to_upper();
end = start + 1;
}
buffer += result.substr(end, result.size() - (end + 1));
buffer += result.substr(end);
result = buffer.to_pascal_case();
}
}

View File

@ -4236,7 +4236,7 @@ int Main::start() {
Ref<DirAccess> da = DirAccess::open(local_game_path.substr(0, sep));
if (da.is_valid()) {
local_game_path = da->get_current_dir().path_join(
local_game_path.substr(sep + 1, local_game_path.length()));
local_game_path.substr(sep + 1));
}
}
}

View File

@ -3630,7 +3630,7 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t
}
}
String st = l.substr(tc, l.length()).strip_edges();
String st = l.substr(tc).strip_edges();
if (st.is_empty() || st.begins_with("#")) {
continue; //ignore!
}

View File

@ -636,7 +636,7 @@ String ExtendGDScriptParser::get_text_for_completion(const lsp::Position &p_curs
if (i == p_cursor.line) {
longthing += lines[i].substr(0, p_cursor.character);
longthing += String::chr(0xFFFF); // Not unicode, represents the cursor.
longthing += lines[i].substr(p_cursor.character, lines[i].size());
longthing += lines[i].substr(p_cursor.character);
} else {
longthing += lines[i];
}

View File

@ -1917,7 +1917,7 @@ static String marked_documentation(const String &p_bbcode) {
in_code_block = true;
line = "\n";
} else if (in_code_block) {
line = "\t" + line.substr(code_block_indent, line.length());
line = "\t" + line.substr(code_block_indent);
}
if (in_code_block && line.contains("[/codeblock]")) {

View File

@ -218,7 +218,7 @@ String BindingsGenerator::bbcode_to_text(const String &p_bbcode, const TypeInter
int brk_end = bbcode.find_char(']', brk_pos + 1);
if (brk_end == -1) {
String text = bbcode.substr(brk_pos, bbcode.length() - brk_pos);
String text = bbcode.substr(brk_pos);
if (code_tag || tag_stack.size() > 0) {
output.append("'" + text + "'");
}
@ -229,7 +229,7 @@ String BindingsGenerator::bbcode_to_text(const String &p_bbcode, const TypeInter
String tag = bbcode.substr(brk_pos + 1, brk_end - brk_pos - 1);
if (tag.begins_with("/")) {
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length());
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1);
if (!tag_ok) {
output.append("]");
@ -246,7 +246,7 @@ String BindingsGenerator::bbcode_to_text(const String &p_bbcode, const TypeInter
} else if (tag.begins_with("method ") || tag.begins_with("constructor ") || tag.begins_with("operator ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ") || tag.begins_with("theme_item ") || tag.begins_with("param ")) {
const int tag_end = tag.find_char(' ');
const String link_tag = tag.substr(0, tag_end);
const String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" ");
const String link_target = tag.substr(tag_end + 1).lstrip(" ");
const Vector<String> link_target_parts = link_target.split(".");
@ -401,7 +401,7 @@ String BindingsGenerator::bbcode_to_text(const String &p_bbcode, const TypeInter
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag.begins_with("url=")) {
String url = tag.substr(4, tag.length());
String url = tag.substr(4);
// Not supported. Just append the url.
output.append(url);
@ -497,7 +497,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
if (brk_end == -1) {
if (!line_del) {
String text = bbcode.substr(brk_pos, bbcode.length() - brk_pos);
String text = bbcode.substr(brk_pos);
if (code_tag || tag_stack.size() > 0) {
xml_output.append(text.xml_escape());
} else {
@ -522,7 +522,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
String tag = bbcode.substr(brk_pos + 1, brk_end - brk_pos - 1);
if (tag.begins_with("/")) {
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length());
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1);
if (!tag_ok) {
if (!line_del) {
@ -558,7 +558,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
} else if (tag.begins_with("method ") || tag.begins_with("constructor ") || tag.begins_with("operator ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ") || tag.begins_with("theme_item ") || tag.begins_with("param ")) {
const int tag_end = tag.find_char(' ');
const String link_tag = tag.substr(0, tag_end);
const String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" ");
const String link_target = tag.substr(tag_end + 1).lstrip(" ");
const Vector<String> link_target_parts = link_target.split(".");
@ -763,7 +763,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag.begins_with("url=")) {
String url = tag.substr(4, tag.length());
String url = tag.substr(4);
xml_output.append("<a href=\"");
xml_output.append(url);
xml_output.append("\">");
@ -3011,7 +3011,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
}
// Apparently the name attribute must not include the @
String param_tag_name = iarg.name.begins_with("@") ? iarg.name.substr(1, iarg.name.length()) : iarg.name;
String param_tag_name = iarg.name.begins_with("@") ? iarg.name.substr(1) : iarg.name;
// Escape < and > in the attribute default value
String param_def_arg = def_arg.replacen("<", "&lt;").replacen(">", "&gt;");

View File

@ -116,7 +116,7 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
continue;
}
String name = prop.name.substr(prop.name.find_char('/') + 1, prop.name.length());
String name = prop.name.substr(prop.name.find_char('/') + 1);
suggestions.push_back(quoted(name));
}
} break;

View File

@ -110,7 +110,7 @@ String sformat(const String &p_text, const String &p1, const String &p2,
search_from = result + 2;
}
new_string += p_text.substr(search_from, p_text.length() - search_from);
new_string += p_text.substr(search_from);
return new_string;
}

View File

@ -154,7 +154,7 @@ String DirAccessJAndroid::get_current_dir(bool p_include_drive) const {
if (bd.begins_with(root_string)) {
return bd;
} else if (bd.begins_with("/")) {
return root_string + bd.substr(1, bd.length());
return root_string + bd.substr(1);
} else {
return root_string + bd;
}

View File

@ -1629,7 +1629,7 @@ void EditorExportPlatformAndroid::_fix_resources(const Ref<EditorExportPreset> &
str = get_project_name(package_name);
} else {
String lang = str.substr(str.rfind_char('-') + 1, str.length()).replace("-", "_");
String lang = str.substr(str.rfind_char('-') + 1).replace("-", "_");
if (appnames.has(lang)) {
str = appnames[lang];
} else {

View File

@ -53,9 +53,9 @@ Error FileAccessAndroid::open_internal(const String &p_path, int p_mode_flags) {
String path = fix_path(p_path).simplify_path();
absolute_path = path;
if (path.begins_with("/")) {
path = path.substr(1, path.length());
path = path.substr(1);
} else if (path.begins_with("res://")) {
path = path.substr(6, path.length());
path = path.substr(6);
}
ERR_FAIL_COND_V(p_mode_flags & FileAccess::WRITE, ERR_UNAVAILABLE); //can't write on android..
@ -147,9 +147,9 @@ bool FileAccessAndroid::store_buffer(const uint8_t *p_src, uint64_t p_length) {
bool FileAccessAndroid::file_exists(const String &p_path) {
String path = fix_path(p_path).simplify_path();
if (path.begins_with("/")) {
path = path.substr(1, path.length());
path = path.substr(1);
} else if (path.begins_with("res://")) {
path = path.substr(6, path.length());
path = path.substr(6);
}
AAsset *at = AAssetManager_open(asset_manager, path.utf8().get_data(), AASSET_MODE_STREAMING);

View File

@ -930,7 +930,7 @@ bool JavaClassWrapper::_get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, St
if (str_type.begins_with("[")) {
t = JavaClass::ARG_ARRAY_BIT;
strsig = "[";
str_type = str_type.substr(1, str_type.length() - 1);
str_type = str_type.substr(1);
if (str_type.begins_with("[")) {
print_line("Nested arrays not supported for type: " + str_type);
return false;

View File

@ -982,7 +982,7 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres
} else {
print_verbose("rcodesign (" + p_path + "):\n" + str);
int next_nl = str.find_char('\n', rq_offset);
String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 23, -1) : str.substr(rq_offset + 23, next_nl - rq_offset - 23);
String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 23) : str.substr(rq_offset + 23, next_nl - rq_offset - 23);
add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), vformat(TTR("Notarization request UUID: \"%s\""), request_uuid));
add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), TTR("The notarization process generally takes less than an hour."));
add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t" + TTR("You can check progress manually by opening a Terminal and running the following command:"));
@ -1066,7 +1066,7 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres
} else {
print_verbose("notarytool (" + p_path + "):\n" + str);
int next_nl = str.find_char('\n', rq_offset);
String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 4, -1) : str.substr(rq_offset + 4, next_nl - rq_offset - 4);
String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 4) : str.substr(rq_offset + 4, next_nl - rq_offset - 4);
add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), vformat(TTR("Notarization request UUID: \"%s\""), request_uuid));
add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), TTR("The notarization process generally takes less than an hour."));
add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t" + TTR("You can check progress manually by opening a Terminal and running the following command:"));

View File

@ -49,11 +49,11 @@ Error HTTPClientWeb::connect_to_host(const String &p_host, int p_port, Ref<TLSOp
String host_lower = host.to_lower();
if (host_lower.begins_with("http://")) {
host = host.substr(7, host.length() - 7);
host = host.substr(7);
use_tls = false;
} else if (host_lower.begins_with("https://")) {
use_tls = true;
host = host.substr(8, host.length() - 8);
host = host.substr(8);
}
ERR_FAIL_COND_V(host.length() < HOST_MIN_LEN, ERR_INVALID_PARAMETER);

View File

@ -2114,7 +2114,7 @@ String CodeEdit::get_text_for_code_completion() const {
completion_text += line.substr(0, get_caret_column());
/* Not unicode, represents the caret. */
completion_text += String::chr(0xFFFF);
completion_text += line.substr(get_caret_column(), line.size());
completion_text += line.substr(get_caret_column());
} else {
completion_text += line;
}
@ -2413,7 +2413,7 @@ String CodeEdit::get_text_with_cursor_char(int p_line, int p_column) const {
result += line_text.substr(0, p_column);
/* Not unicode, represents the cursor. */
result += String::chr(0xFFFF);
result += line_text.substr(p_column, line_text.size());
result += line_text.substr(p_column);
} else {
result += line_text;
}

View File

@ -198,7 +198,7 @@ void FileDialog::_native_dialog_cb_with_options(bool p_ok, const Vector<String>
if (!valid && filter_slice_count > 0) {
String str = (flt.get_slice(",", 0).strip_edges());
f += str.substr(1, str.length() - 1);
f += str.substr(1);
file->set_text(f.get_file());
valid = true;
}
@ -573,7 +573,7 @@ void FileDialog::_action_pressed() {
if (!valid && filter_slice_count > 0) {
String str = (flt.get_slice(",", 0).strip_edges());
f += str.substr(1, str.length() - 1);
f += str.substr(1);
file->set_text(f.get_file());
valid = true;
}
@ -1192,7 +1192,7 @@ void FileDialog::set_current_path(const String &p_path) {
set_current_file(p_path);
} else {
String path_dir = p_path.substr(0, pos);
String path_file = p_path.substr(pos + 1, p_path.length());
String path_file = p_path.substr(pos + 1);
set_current_dir(path_dir);
set_current_file(path_file);
}

View File

@ -2016,7 +2016,7 @@ void LineEdit::insert_text_at_caret(String p_text) {
}
}
String pre = text.substr(0, caret_column);
String post = text.substr(caret_column, text.length() - caret_column);
String post = text.substr(caret_column);
text = pre + p_text + post;
_shape();
TextServer::Direction dir = TS->shaped_text_get_dominant_direction_in_range(text_rid, caret_column, caret_column + p_text.length());
@ -2611,7 +2611,7 @@ void LineEdit::_shape() {
t = s.repeat(text.length() + ime_text.length());
} else {
if (!ime_text.is_empty()) {
t = text.substr(0, caret_column) + ime_text + text.substr(caret_column, text.length());
t = text.substr(0, caret_column) + ime_text + text.substr(caret_column);
} else {
t = text;
}

View File

@ -4440,7 +4440,7 @@ void RichTextLabel::append_text(const String &p_bbcode) {
}
if (tag.begins_with("/") && tag_stack.size()) {
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length());
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1);
if (tag_stack.front()->get() == "b") {
in_bold = false;
@ -5920,7 +5920,7 @@ String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p
txt = txt.substr(0, p_selection.to_char);
}
if ((l.from != nullptr) && (p_frame == p_selection.from_frame) && (p_selection.from_item != nullptr) && (p_selection.from_item->index >= l.from->index) && (p_selection.from_item->index < end_idx)) {
txt = txt.substr(p_selection.from_char, -1);
txt = txt.substr(p_selection.from_char);
}
return txt;
}
@ -6940,7 +6940,7 @@ Dictionary RichTextLabel::parse_expressions_for_values(Vector<String> p_expressi
a.append(Color::html(values[j]));
} else if (nodepath.search(values[j]).is_valid()) {
if (values[j].begins_with("$")) {
String v = values[j].substr(1, values[j].length());
String v = values[j].substr(1);
a.append(NodePath(v));
}
} else if (boolean.search(values[j]).is_valid()) {

View File

@ -8596,7 +8596,7 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
}
/* STEP 3: Separate dest string in pre and post text. */
String postinsert_text = text[p_line].substr(p_char, text[p_line].size());
String postinsert_text = text[p_line].substr(p_char);
substrings.write[0] = text[p_line].substr(0, p_char) + substrings[0];
substrings.write[substrings.size() - 1] += postinsert_text;
@ -8660,7 +8660,7 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
ERR_FAIL_COND(p_to_line == p_from_line && p_to_column < p_from_column); // 'from > to'.
String pre_text = text[p_from_line].substr(0, p_from_column);
String post_text = text[p_to_line].substr(p_to_column, text[p_to_line].length());
String post_text = text[p_to_line].substr(p_to_column);
text.remove_range(p_from_line, p_to_line);
text.set(p_from_line, pre_text + post_text, structured_text_parser(st_parser, st_args, pre_text + post_text));

View File

@ -241,7 +241,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
for (const String &E : rheaders) {
if (E.containsn("Location: ")) {
new_request = E.substr(9, E.length()).strip_edges();
new_request = E.substr(9).strip_edges();
}
}

View File

@ -1584,7 +1584,7 @@ String VisualShader::validate_port_name(const String &p_port_name, VisualShaderN
}
while (port_name.length() && !is_ascii_alphabet_char(port_name[0])) {
port_name = port_name.substr(1, port_name.length() - 1);
port_name = port_name.substr(1);
}
if (!port_name.is_empty()) {
@ -1629,7 +1629,7 @@ String VisualShader::validate_port_name(const String &p_port_name, VisualShaderN
String VisualShader::validate_parameter_name(const String &p_name, const Ref<VisualShaderNodeParameter> &p_parameter) const {
String param_name = p_name; //validate name first
while (param_name.length() && !is_ascii_alphabet_char(param_name[0])) {
param_name = param_name.substr(1, param_name.length() - 1);
param_name = param_name.substr(1);
}
if (!param_name.is_empty()) {
String valid_name;

View File

@ -889,7 +889,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
if (p_default_actions.usage_defines.has(vnode->name) && !used_name_defines.has(vnode->name)) {
String define = p_default_actions.usage_defines[vnode->name];
if (define.begins_with("@")) {
define = p_default_actions.usage_defines[define.substr(1, define.length())];
define = p_default_actions.usage_defines[define.substr(1)];
}
r_gen_code.defines.push_back(define);
used_name_defines.insert(vnode->name);
@ -1006,7 +1006,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
if (p_default_actions.usage_defines.has(anode->name) && !used_name_defines.has(anode->name)) {
String define = p_default_actions.usage_defines[anode->name];
if (define.begins_with("@")) {
define = p_default_actions.usage_defines[define.substr(1, define.length())];
define = p_default_actions.usage_defines[define.substr(1)];
}
r_gen_code.defines.push_back(define);
used_name_defines.insert(anode->name);

View File

@ -1096,7 +1096,7 @@ bool ShaderPreprocessor::expand_macros_once(const String &p_line, int p_line_num
int arg_index_start = 0;
int arg_index = 0;
while (find_match(body, arg_name, arg_index, arg_index_start)) {
body = body.substr(0, arg_index) + args[i] + body.substr(arg_index + arg_name.length(), body.length() - (arg_index + arg_name.length()));
body = body.substr(0, arg_index) + args[i] + body.substr(arg_index + arg_name.length());
// Manually reset arg_index_start to where the arg value of the define finishes.
// This ensures we don't skip the other args of this macro in the string.
arg_index_start = arg_index + args[i].length() + 1;
@ -1105,11 +1105,11 @@ bool ShaderPreprocessor::expand_macros_once(const String &p_line, int p_line_num
concatenate_macro_body(body);
result = result.substr(0, index) + " " + body + " " + result.substr(args_end + 1, result.length());
result = result.substr(0, index) + " " + body + " " + result.substr(args_end + 1);
} else {
concatenate_macro_body(body);
result = result.substr(0, index) + " " + body + " " + result.substr(index + key.length(), result.length() - (index + key.length()));
result = result.substr(0, index) + " " + body + " " + result.substr(index + key.length());
}
r_expanded = result;
@ -1176,7 +1176,7 @@ void ShaderPreprocessor::concatenate_macro_body(String &r_body) {
index_start--;
}
r_body = r_body.substr(0, index_start) + r_body.substr(index_end, r_body.length() - index_end);
r_body = r_body.substr(0, index_start) + r_body.substr(index_end);
index_start = r_body.find("##", index_start);
}