summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/debugger/local_debugger.cpp4
-rw-r--r--core/input/input.cpp12
-rw-r--r--core/io/resource_loader.cpp2
-rw-r--r--core/string/ustring.cpp24
-rw-r--r--doc/classes/String.xml14
-rw-r--r--drivers/windows/dir_access_windows.cpp2
-rw-r--r--editor/code_editor.cpp6
-rw-r--r--editor/editor_help.cpp2
-rw-r--r--editor/editor_help_search.cpp2
-rw-r--r--editor/editor_inspector.cpp4
-rw-r--r--editor/find_in_files.cpp4
-rw-r--r--editor/project_manager.cpp4
-rw-r--r--modules/gdscript/gdscript_editor.cpp4
-rw-r--r--modules/gltf/gltf_document.cpp2
-rw-r--r--scene/resources/tile_set.cpp2
-rw-r--r--tests/test_string.h5
16 files changed, 57 insertions, 36 deletions
diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp
index 1dd7e268a5..ab368471e4 100644
--- a/core/debugger/local_debugger.cpp
+++ b/core/debugger/local_debugger.cpp
@@ -183,7 +183,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
print_line("Error: Unknown option " + key);
} else {
// Allow explicit tab character
- String value = key_value.right(value_pos + 1).replace("\\t", "\t");
+ String value = key_value.substr(value_pos + 1).replace("\\t", "\t");
options[key] = value;
}
@@ -348,7 +348,7 @@ Pair<String, int> LocalDebugger::to_breakpoint(const String &p_line) {
}
breakpoint.first = script_debugger->breakpoint_find_source(breakpoint_part.left(last_colon).strip_edges());
- breakpoint.second = breakpoint_part.right(last_colon).strip_edges().to_int();
+ breakpoint.second = breakpoint_part.substr(last_colon).strip_edges().to_int();
return breakpoint;
}
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 2304c05bf8..6eafec087d 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -1262,16 +1262,16 @@ void Input::parse_mapping(String p_mapping) {
} else if (output[0] == '-') {
output_range = NEGATIVE_HALF_AXIS;
}
- output = output.right(1);
+ output = output.substr(1);
}
JoyAxisRange input_range = FULL_AXIS;
if (input[0] == '+') {
input_range = POSITIVE_HALF_AXIS;
- input = input.right(1);
+ input = input.substr(1);
} else if (input[0] == '-') {
input_range = NEGATIVE_HALF_AXIS;
- input = input.right(1);
+ input = input.substr(1);
}
bool invert_axis = false;
if (input[input.length() - 1] == '~') {
@@ -1299,11 +1299,11 @@ void Input::parse_mapping(String p_mapping) {
switch (input[0]) {
case 'b':
binding.inputType = TYPE_BUTTON;
- binding.input.button = input.right(1).to_int();
+ binding.input.button = input.substr(1).to_int();
break;
case 'a':
binding.inputType = TYPE_AXIS;
- binding.input.axis.axis = input.right(1).to_int();
+ binding.input.axis.axis = input.substr(1).to_int();
binding.input.axis.range = input_range;
binding.input.axis.invert = invert_axis;
break;
@@ -1312,7 +1312,7 @@ void Input::parse_mapping(String p_mapping) {
String(entry[idx] + "\nInvalid hat input: " + input));
binding.inputType = TYPE_HAT;
binding.input.hat.hat = input.substr(1, 1).to_int();
- binding.input.hat.hat_mask = static_cast<HatMask>(input.right(3).to_int());
+ binding.input.hat.hat_mask = static_cast<HatMask>(input.substr(3).to_int());
break;
default:
ERR_CONTINUE_MSG(true, String(entry[idx] + "\nUnrecognised input string: " + input));
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 040e55b9db..b942c30086 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -867,7 +867,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
continue;
}
- String l = res_remaps[i].right(split + 1).strip_edges();
+ String l = res_remaps[i].substr(split + 1).strip_edges();
if (l == locale) { // Exact match.
new_path = res_remaps[i].left(split);
break;
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index bdb66526a4..3c1afc7f2c 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -3382,14 +3382,14 @@ String String::format(const Variant &values, String placeholder) const {
if (value_arr.size() == 2) {
Variant v_key = value_arr[0];
String key = v_key;
- if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") {
+ if (key.left(1) == "\"" && key.right(1) == "\"") {
key = key.substr(1, key.length() - 2);
}
Variant v_val = value_arr[1];
String val = v_val;
- if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
+ if (val.left(1) == "\"" && val.right(1) == "\"") {
val = val.substr(1, val.length() - 2);
}
@@ -3401,7 +3401,7 @@ String String::format(const Variant &values, String placeholder) const {
Variant v_val = values_arr[i];
String val = v_val;
- if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
+ if (val.left(1) == "\"" && val.right(1) == "\"") {
val = val.substr(1, val.length() - 2);
}
@@ -3421,11 +3421,11 @@ String String::format(const Variant &values, String placeholder) const {
String key = E->get();
String val = d[E->get()];
- if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") {
+ if (key.left(1) == "\"" && key.right(1) == "\"") {
key = key.substr(1, key.length() - 2);
}
- if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
+ if (val.left(1) == "\"" && val.right(1) == "\"") {
val = val.substr(1, val.length() - 2);
}
@@ -3529,6 +3529,10 @@ String String::repeat(int p_count) const {
}
String String::left(int p_pos) const {
+ if (p_pos < 0) {
+ p_pos = length() + p_pos;
+ }
+
if (p_pos <= 0) {
return "";
}
@@ -3541,15 +3545,19 @@ String String::left(int p_pos) const {
}
String String::right(int p_pos) const {
- if (p_pos >= length()) {
- return "";
+ if (p_pos < 0) {
+ p_pos = length() + p_pos;
}
if (p_pos <= 0) {
+ return "";
+ }
+
+ if (p_pos >= length()) {
return *this;
}
- return substr(p_pos, (length() - p_pos));
+ return substr(length() - p_pos);
}
char32_t String::unicode_at(int p_idx) const {
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index 416438e648..a81defa16c 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -397,7 +397,12 @@
<argument index="0" name="position" type="int">
</argument>
<description>
- Returns a number of characters from the left of the string.
+ Returns a number of characters from the left of the string. If negative [code]position[/code] is used, the characters are counted downwards from [String]'s length.
+ Examples:
+ [codeblock]
+ print("sample text".left(3)) #prints "sam"
+ print("sample text".left(-3)) #prints "sample t"
+ [/codeblock]
</description>
</method>
<method name="length" qualifiers="const">
@@ -669,7 +674,12 @@
<argument index="0" name="position" type="int">
</argument>
<description>
- Returns the right side of the string from a given position.
+ Returns a number of characters from the right of the string. If negative [code]position[/code] is used, the characters are counted downwards from [String]'s length.
+ Examples:
+ [codeblock]
+ print("sample text".right(3)) #prints "ext"
+ print("sample text".right(-3)) #prints "ple text"
+ [/codeblock]
</description>
</method>
<method name="rpad" qualifiers="const">
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index 5aa777757f..55f9e6de17 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -198,7 +198,7 @@ String DirAccessWindows::get_current_dir(bool p_include_drive) {
if (_get_root_string() == "") {
int p = current_dir.find(":");
if (p != -1) {
- return current_dir.right(p + 1);
+ return current_dir.substr(p + 1);
}
}
return current_dir;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 86f3850d91..12e78c3120 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -1012,7 +1012,7 @@ void CodeTextEditor::convert_indent_to_spaces() {
if (cursor_line == i && cursor_column > j) {
cursor_column += indent_size - 1;
}
- line = line.left(j) + indent + line.right(j + 1);
+ line = line.left(j) + indent + line.substr(j + 1);
}
j++;
}
@@ -1056,7 +1056,7 @@ void CodeTextEditor::convert_indent_to_tabs() {
if (cursor_line == i && cursor_column > j) {
cursor_column -= indent_size;
}
- line = line.left(j - indent_size) + "\t" + line.right(j + 1);
+ line = line.left(j - indent_size) + "\t" + line.substr(j + 1);
j = 0;
space_count = -1;
}
@@ -1114,7 +1114,7 @@ void CodeTextEditor::convert_case(CaseStyle p_case) {
new_line = text_editor->get_line(i).left(begin_col) + new_line;
}
if (i == end) {
- new_line = new_line + text_editor->get_line(i).right(end_col);
+ new_line = new_line + text_editor->get_line(i).substr(end_col);
}
text_editor->set_line(i, new_line);
}
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 6039f64b7c..3f94f43710 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -475,7 +475,7 @@ void EditorHelp::_update_doc() {
String linktxt = (cd.tutorials[i].title.is_empty()) ? link : DTR(cd.tutorials[i].title);
const int seppos = linktxt.find("//");
if (seppos != -1) {
- linktxt = link.right(seppos + 2);
+ linktxt = link.substr(seppos + 2);
}
class_desc->push_color(symbol_color);
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index 23226ffa9b..b93ffa9321 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -334,7 +334,7 @@ bool EditorHelpSearch::Runner::_phase_match_classes() {
for (int i = 0; i < class_doc.methods.size(); i++) {
String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.methods[i].name : class_doc.methods[i].name.to_lower();
if (method_name.find(term) > -1 ||
- (term.begins_with(".") && method_name.begins_with(term.right(1))) ||
+ (term.begins_with(".") && method_name.begins_with(term.substr(1))) ||
(term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) ||
(term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) {
match.methods.push_back(const_cast<DocData::MethodDoc *>(&class_doc.methods[i]));
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 5bb3c8b4d0..29cc4c3c46 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -1809,12 +1809,12 @@ void EditorInspector::update_tree() {
basename = group + "/" + basename;
}
- String name = (basename.find("/") != -1) ? basename.right(basename.rfind("/") + 1) : basename;
+ String name = (basename.find("/") != -1) ? basename.substr(basename.rfind("/") + 1) : basename;
if (capitalize_paths) {
int dot = name.find(".");
if (dot != -1) {
- String ov = name.right(dot);
+ String ov = name.substr(dot);
name = name.substr(0, dot);
name = name.capitalize();
name += ov;
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index 4fa131e991..322dfc13a9 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -530,7 +530,7 @@ void FindInFilesDialog::_on_replace_text_entered(String text) {
void FindInFilesDialog::_on_folder_selected(String path) {
int i = path.find("://");
if (i != -1) {
- path = path.right(i + 3);
+ path = path.substr(i + 3);
}
_folder_line_edit->set_text(path);
}
@@ -932,7 +932,7 @@ void FindInFilesPanel::apply_replaces_in_file(String fpath, const Vector<Result>
continue;
}
- line = line.left(repl_begin) + new_text + line.right(repl_end);
+ line = line.left(repl_begin) + new_text + line.substr(repl_end);
// keep an offset in case there are successive replaces in the same line
offset += new_text.length() - (repl_end - repl_begin);
}
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 2d0ff24723..49a6d28dc1 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -2138,8 +2138,8 @@ void ProjectManager::_run_project_confirm() {
const String &selected = selected_list[i].project_key;
String path = EditorSettings::get_singleton()->get("projects/" + selected);
- // `.right(6)` on `IMPORTED_FILES_PATH` strips away the leading "res://".
- if (!DirAccess::exists(path.plus_file(ProjectSettings::IMPORTED_FILES_PATH.right(6)))) {
+ // `.substr(6)` on `IMPORTED_FILES_PATH` strips away the leading "res://".
+ if (!DirAccess::exists(path.plus_file(ProjectSettings::IMPORTED_FILES_PATH.substr(6)))) {
run_error_diag->set_text(TTR("Can't run project: Assets need to be imported.\nPlease edit the project to trigger the initial import."));
run_error_diag->popup_centered();
continue;
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index c65f97e637..504c7414f6 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -2873,7 +2873,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
StringName parent = ClassDB::get_parent_class(class_name);
if (parent != StringName()) {
if (String(parent).begins_with("_")) {
- base_type.native_type = String(parent).right(1);
+ base_type.native_type = String(parent).substr(1);
} else {
base_type.native_type = parent;
}
@@ -3067,7 +3067,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
// proxy class remove the underscore.
if (r_result.class_name.begins_with("_")) {
- r_result.class_name = r_result.class_name.right(1);
+ r_result.class_name = r_result.class_name.substr(1);
}
return OK;
}
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 2d198b15f8..7b0392fbc1 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -664,7 +664,7 @@ static Vector<uint8_t> _parse_base64_uri(const String &uri) {
int start = uri.find(",");
ERR_FAIL_COND_V(start == -1, Vector<uint8_t>());
- CharString substr = uri.right(start + 1).ascii();
+ CharString substr = uri.substr(start + 1).ascii();
int strlen = substr.length();
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 3cc9627af3..3f6f5bb5fe 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -835,7 +835,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else if (what == "tile_mode") {
ctd->tile_mode = p_value;
} else if (what.left(9) == "autotile") {
- what = what.right(9);
+ what = what.substr(9);
if (what == "bitmask_mode") {
ctd->autotile_bitmask_mode = p_value;
} else if (what == "icon_coordinate") {
diff --git a/tests/test_string.h b/tests/test_string.h
index 486c17dbbd..6e214574af 100644
--- a/tests/test_string.h
+++ b/tests/test_string.h
@@ -299,6 +299,7 @@ TEST_CASE("[String] hex_encode_buffer") {
TEST_CASE("[String] Substr") {
String s = "Killer Baby";
CHECK(s.substr(3, 4) == "ler ");
+ CHECK(s.substr(3) == "ler Baby");
}
TEST_CASE("[String] Find") {
@@ -1252,8 +1253,10 @@ TEST_CASE("[String] Trim") {
TEST_CASE("[String] Right/Left") {
String s = "aaaTestbbb";
// ^
- CHECK(s.right(6) == "tbbb");
+ CHECK(s.right(6) == "estbbb");
+ CHECK(s.right(-6) == "tbbb");
CHECK(s.left(6) == "aaaTes");
+ CHECK(s.left(-6) == "aaaT");
}
TEST_CASE("[String] Repeat") {