1
0
Fork 0

Merge pull request #100024 from Ivorforce/optimize-string-single-char

Optimize string single char contains calls.
This commit is contained in:
Thaddeus Crews 2024-12-09 14:33:24 -06:00
commit a607bca2fd
No known key found for this signature in database
GPG Key ID: 62181B86FE9E5D84
61 changed files with 108 additions and 99 deletions

View File

@ -223,7 +223,7 @@ RemoteDebuggerPeer *RemoteDebuggerPeerTCP::create(const String &p_uri) {
String debug_host = p_uri.replace("tcp://", ""); String debug_host = p_uri.replace("tcp://", "");
uint16_t debug_port = 6007; uint16_t debug_port = 6007;
if (debug_host.contains(":")) { if (debug_host.contains_char(':')) {
int sep_pos = debug_host.rfind_char(':'); int sep_pos = debug_host.rfind_char(':');
debug_port = debug_host.substr(sep_pos + 1).to_int(); debug_port = debug_host.substr(sep_pos + 1).to_int();
debug_host = debug_host.substr(0, sep_pos); debug_host = debug_host.substr(0, sep_pos);

View File

@ -1205,7 +1205,7 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
if (F.name.begins_with("_")) { if (F.name.begins_with("_")) {
continue; //hidden property continue; //hidden property
} }
if (F.name.contains("/")) { if (F.name.contains_char('/')) {
// Ignore properties with '/' (slash) in the name. These are only meant for use in the inspector. // Ignore properties with '/' (slash) in the name. These are only meant for use in the inspector.
continue; continue;
} }

View File

@ -740,7 +740,7 @@ bool FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
String value = p_values[i]; String value = p_values[i];
if (value.contains("\"") || value.contains(p_delim) || value.contains("\n")) { if (value.contains_char('"') || value.contains(p_delim) || value.contains_char('\n')) {
value = "\"" + value.replace("\"", "\"\"") + "\""; value = "\"" + value.replace("\"", "\"\"") + "\"";
} }
if (i < size - 1) { if (i < size - 1) {

View File

@ -71,7 +71,7 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64
// Search for directory. // Search for directory.
PackedDir *cd = root; PackedDir *cd = root;
if (simplified_path.contains("/")) { // In a subdirectory. if (simplified_path.contains_char('/')) { // In a subdirectory.
Vector<String> ds = simplified_path.get_base_dir().split("/"); Vector<String> ds = simplified_path.get_base_dir().split("/");
for (int j = 0; j < ds.size(); j++) { for (int j = 0; j < ds.size(); j++) {
@ -104,7 +104,7 @@ void PackedData::remove_path(const String &p_path) {
// Search for directory. // Search for directory.
PackedDir *cd = root; PackedDir *cd = root;
if (simplified_path.contains("/")) { // In a subdirectory. if (simplified_path.contains_char('/')) { // In a subdirectory.
Vector<String> ds = simplified_path.get_base_dir().split("/"); Vector<String> ds = simplified_path.get_base_dir().split("/");
for (int j = 0; j < ds.size(); j++) { for (int j = 0; j < ds.size(); j++) {

View File

@ -202,7 +202,7 @@ IPAddress::IPAddress(const String &p_string) {
// Wildcard (not a valid IP) // Wildcard (not a valid IP)
wildcard = true; wildcard = true;
} else if (p_string.contains(":")) { } else if (p_string.contains_char(':')) {
// IPv6 // IPv6
_parse_ipv6(p_string); _parse_ipv6(p_string);
valid = true; valid = true;

View File

@ -1116,7 +1116,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
String enum_name = p_enum; String enum_name = p_enum;
if (!enum_name.is_empty()) { if (!enum_name.is_empty()) {
if (enum_name.contains(".")) { if (enum_name.contains_char('.')) {
enum_name = enum_name.get_slicec('.', 1); enum_name = enum_name.get_slicec('.', 1);
} }

View File

@ -3314,6 +3314,10 @@ int String::find(const String &p_str, int p_from) const {
return -1; // won't find anything! return -1; // won't find anything!
} }
if (src_len == 1) {
return find_char(p_str[0], p_from); // Optimize with single-char find.
}
const char32_t *src = get_data(); const char32_t *src = get_data();
const char32_t *str = p_str.get_data(); const char32_t *str = p_str.get_data();
@ -3354,6 +3358,10 @@ int String::find(const char *p_str, int p_from) const {
return -1; // won't find anything! return -1; // won't find anything!
} }
if (src_len == 1) {
return find_char(*p_str, p_from); // Optimize with single-char find.
}
const char32_t *src = get_data(); const char32_t *src = get_data();
if (src_len == 1) { if (src_len == 1) {
@ -4081,7 +4089,7 @@ String String::format(const Variant &values, const String &placeholder) const {
Variant v_val = values_arr[i]; Variant v_val = values_arr[i];
String val = v_val; String val = v_val;
if (placeholder.contains("_")) { if (placeholder.contains_char('_')) {
new_string = new_string.replace(placeholder.replace("_", i_as_str), val); new_string = new_string.replace(placeholder.replace("_", i_as_str), val);
} else { } else {
new_string = new_string.replace_first(placeholder, val); new_string = new_string.replace_first(placeholder, val);

View File

@ -432,6 +432,7 @@ public:
_FORCE_INLINE_ bool is_empty() const { return length() == 0; } _FORCE_INLINE_ bool is_empty() const { return length() == 0; }
_FORCE_INLINE_ bool contains(const char *p_str) const { return find(p_str) != -1; } _FORCE_INLINE_ bool contains(const char *p_str) const { return find(p_str) != -1; }
_FORCE_INLINE_ bool contains(const String &p_str) const { return find(p_str) != -1; } _FORCE_INLINE_ bool contains(const String &p_str) const { return find(p_str) != -1; }
_FORCE_INLINE_ bool contains_char(char32_t p_chr) const { return find_char(p_chr) != -1; }
_FORCE_INLINE_ bool containsn(const char *p_str) const { return findn(p_str) != -1; } _FORCE_INLINE_ bool containsn(const char *p_str) const { return findn(p_str) != -1; }
_FORCE_INLINE_ bool containsn(const String &p_str) const { return findn(p_str) != -1; } _FORCE_INLINE_ bool containsn(const String &p_str) const { return findn(p_str) != -1; }

View File

@ -1961,7 +1961,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::FLOAT: { case Variant::FLOAT: {
String s = rtos_fix(p_variant.operator double()); String s = rtos_fix(p_variant.operator double());
if (s != "inf" && s != "inf_neg" && s != "nan") { if (s != "inf" && s != "inf_neg" && s != "nan") {
if (!s.contains(".") && !s.contains("e")) { if (!s.contains_char('.') && !s.contains_char('e')) {
s += ".0"; s += ".0";
} }
} }

View File

@ -949,13 +949,13 @@ String OS_Unix::get_environment(const String &p_var) const {
} }
void OS_Unix::set_environment(const String &p_var, const String &p_value) const { void OS_Unix::set_environment(const String &p_var, const String &p_value) const {
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var)); ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains_char('='), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
int err = setenv(p_var.utf8().get_data(), p_value.utf8().get_data(), /* overwrite: */ 1); int err = setenv(p_var.utf8().get_data(), p_value.utf8().get_data(), /* overwrite: */ 1);
ERR_FAIL_COND_MSG(err != 0, vformat("Failed setting environment variable '%s', the system is out of memory.", p_var)); ERR_FAIL_COND_MSG(err != 0, vformat("Failed setting environment variable '%s', the system is out of memory.", p_var));
} }
void OS_Unix::unset_environment(const String &p_var) const { void OS_Unix::unset_environment(const String &p_var) const {
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var)); ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains_char('='), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
unsetenv(p_var.utf8().get_data()); unsetenv(p_var.utf8().get_data());
} }

View File

@ -523,7 +523,7 @@ void ConnectDialog::set_dst_node(Node *p_node) {
StringName ConnectDialog::get_dst_method_name() const { StringName ConnectDialog::get_dst_method_name() const {
String txt = dst_method->get_text(); String txt = dst_method->get_text();
if (txt.contains("(")) { if (txt.contains_char('(')) {
txt = txt.left(txt.find_char('(')).strip_edges(); txt = txt.left(txt.find_char('(')).strip_edges();
} }
return txt; return txt;

View File

@ -359,7 +359,7 @@ Dictionary DebugAdapterParser::req_setBreakpoints(const Dictionary &p_params) co
} }
// If path contains \, it's a Windows path, so we need to convert it to /, and make the drive letter uppercase // If path contains \, it's a Windows path, so we need to convert it to /, and make the drive letter uppercase
if (source.path.contains("\\")) { if (source.path.contains_char('\\')) {
source.path = source.path.replace("\\", "/"); source.path = source.path.replace("\\", "/");
source.path = source.path.substr(0, 1).to_upper() + source.path.substr(1); source.path = source.path.substr(0, 1).to_upper() + source.path.substr(1);
} }

View File

@ -47,7 +47,7 @@ private:
_FORCE_INLINE_ bool is_valid_path(const String &p_path) const { _FORCE_INLINE_ bool is_valid_path(const String &p_path) const {
// If path contains \, it's a Windows path, so we need to convert it to /, and check as case-insensitive. // If path contains \, it's a Windows path, so we need to convert it to /, and check as case-insensitive.
if (p_path.contains("\\")) { if (p_path.contains_char('\\')) {
String project_path = ProjectSettings::get_singleton()->get_resource_path(); String project_path = ProjectSettings::get_singleton()->get_resource_path();
String path = p_path.replace("\\", "/"); String path = p_path.replace("\\", "/");
return path.containsn(project_path); return path.containsn(project_path);

View File

@ -67,8 +67,8 @@ String DirectoryCreateDialog::_validate_path(const String &p_path) const {
return TTR("Folder name cannot be empty."); return TTR("Folder name cannot be empty.");
} }
} }
if (part.contains("\\") || part.contains(":") || part.contains("*") || if (part.contains_char('\\') || part.contains_char(':') || part.contains_char('*') ||
part.contains("|") || part.contains(">") || part.ends_with(".") || part.ends_with(" ")) { part.contains_char('|') || part.contains_char('>') || part.ends_with(".") || part.ends_with(" ")) {
if (is_file) { if (is_file) {
return TTR("File name contains invalid characters."); return TTR("File name contains invalid characters.");
} else { } else {
@ -101,7 +101,7 @@ void DirectoryCreateDialog::_on_dir_path_changed() {
const String error = _validate_path(path); const String error = _validate_path(path);
if (error.is_empty()) { if (error.is_empty()) {
if (path.contains("/")) { if (path.contains_char('/')) {
if (mode == MODE_DIRECTORY) { if (mode == MODE_DIRECTORY) {
validation_panel->set_message(EditorValidationPanel::MSG_ID_DEFAULT, TTR("Using slashes in folder names will create subfolders recursively."), EditorValidationPanel::MSG_OK); validation_panel->set_message(EditorValidationPanel::MSG_ID_DEFAULT, TTR("Using slashes in folder names will create subfolders recursively."), EditorValidationPanel::MSG_OK);
} else { } else {

View File

@ -472,7 +472,7 @@ void EditorFeatureProfileManager::_erase_selected_profile() {
void EditorFeatureProfileManager::_create_new_profile() { void EditorFeatureProfileManager::_create_new_profile() {
String name = new_profile_name->get_text().strip_edges(); String name = new_profile_name->get_text().strip_edges();
if (!name.is_valid_filename() || name.contains(".")) { if (!name.is_valid_filename() || name.contains_char('.')) {
EditorNode::get_singleton()->show_warning(TTR("Profile must be a valid filename and must not contain '.'")); EditorNode::get_singleton()->show_warning(TTR("Profile must be a valid filename and must not contain '.'"));
return; return;
} }

View File

@ -384,7 +384,7 @@ void EditorFileSystem::_scan_filesystem() {
FileCache fc; FileCache fc;
fc.type = split[1]; fc.type = split[1];
if (fc.type.contains("/")) { if (fc.type.contains_char('/')) {
fc.type = split[1].get_slice("/", 0); fc.type = split[1].get_slice("/", 0);
fc.resource_script_class = split[1].get_slice("/", 1); fc.resource_script_class = split[1].get_slice("/", 1);
} }

View File

@ -320,7 +320,7 @@ void EditorHelp::_class_desc_select(const String &p_select) {
} }
} }
if (link.contains(".")) { if (link.contains_char('.')) {
const int class_end = link.find_char('.'); const int class_end = link.find_char('.');
emit_signal(SNAME("go_to_help"), topic + ":" + link.left(class_end) + ":" + link.substr(class_end + 1)); emit_signal(SNAME("go_to_help"), topic + ":" + link.left(class_end) + ":" + link.substr(class_end + 1));
} }
@ -365,7 +365,7 @@ static void _add_type_to_rt(const String &p_type, const String &p_enum, bool p_i
bool is_enum_type = !p_enum.is_empty(); bool is_enum_type = !p_enum.is_empty();
bool is_bitfield = p_is_bitfield && is_enum_type; bool is_bitfield = p_is_bitfield && is_enum_type;
bool can_ref = !p_type.contains("*") || is_enum_type; bool can_ref = !p_type.contains_char('*') || is_enum_type;
String link_t = p_type; // For links in metadata String link_t = p_type; // For links in metadata
String display_t; // For display purposes. String display_t; // For display purposes.
@ -2552,7 +2552,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, const C
p_rt->push_meta("@" + link_tag + " " + link_target, underline_mode); p_rt->push_meta("@" + link_tag + " " + link_target, underline_mode);
if (link_tag == "member" && if (link_tag == "member" &&
((!link_target.contains(".") && (p_class == "ProjectSettings" || p_class == "EditorSettings")) || ((!link_target.contains_char('.') && (p_class == "ProjectSettings" || p_class == "EditorSettings")) ||
link_target.begins_with("ProjectSettings.") || link_target.begins_with("EditorSettings."))) { link_target.begins_with("ProjectSettings.") || link_target.begins_with("EditorSettings."))) {
// Special formatting for both ProjectSettings and EditorSettings. // Special formatting for both ProjectSettings and EditorSettings.
String prefix; String prefix;
@ -3665,7 +3665,7 @@ void EditorHelpBit::_meta_clicked(const String &p_select) {
return; return;
} }
if (link.contains(".")) { if (link.contains_char('.')) {
const int class_end = link.find_char('.'); const int class_end = link.find_char('.');
_go_to_help(topic + ":" + link.left(class_end) + ":" + link.substr(class_end + 1)); _go_to_help(topic + ":" + link.left(class_end) + ":" + link.substr(class_end + 1));
} else { } else {

View File

@ -281,7 +281,7 @@ void EditorProperty::_notification(int p_what) {
} else { } else {
color = get_theme_color(is_read_only() ? SNAME("readonly_color") : SNAME("property_color")); color = get_theme_color(is_read_only() ? SNAME("readonly_color") : SNAME("property_color"));
} }
if (label.contains(".")) { if (label.contains_char('.')) {
// FIXME: Move this to the project settings editor, as this is only used // FIXME: Move this to the project settings editor, as this is only used
// for project settings feature tag overrides. // for project settings feature tag overrides.
color.a = 0.5; color.a = 0.5;
@ -3177,7 +3177,7 @@ void EditorInspector::update_tree() {
} }
// Get the property label's string. // Get the property label's string.
String name_override = (path.contains("/")) ? path.substr(path.rfind_char('/') + 1) : path; String name_override = (path.contains_char('/')) ? path.substr(path.rfind_char('/') + 1) : path;
String feature_tag; String feature_tag;
{ {
const int dot = name_override.find_char('.'); const int dot = name_override.find_char('.');
@ -3326,7 +3326,7 @@ void EditorInspector::update_tree() {
array_element_prefix = class_name_components[0]; array_element_prefix = class_name_components[0];
editor_inspector_array = memnew(EditorInspectorArray(all_read_only)); editor_inspector_array = memnew(EditorInspectorArray(all_read_only));
String array_label = path.contains("/") ? path.substr(path.rfind_char('/') + 1) : path; String array_label = path.contains_char('/') ? path.substr(path.rfind_char('/') + 1) : path;
array_label = EditorPropertyNameProcessor::get_singleton()->process_name(property_label_string, property_name_style, p.name, doc_name); array_label = EditorPropertyNameProcessor::get_singleton()->process_name(property_label_string, property_name_style, p.name, doc_name);
int page = per_array_page.has(array_element_prefix) ? per_array_page[array_element_prefix] : 0; int page = per_array_page.has(array_element_prefix) ? per_array_page[array_element_prefix] : 0;
editor_inspector_array->setup_with_move_element_function(object, array_label, array_element_prefix, page, c, use_folding); editor_inspector_array->setup_with_move_element_function(object, array_label, array_element_prefix, page, c, use_folding);

View File

@ -837,7 +837,7 @@ void EditorPropertyLayersGrid::_rename_operation_confirm() {
if (new_name.length() == 0) { if (new_name.length() == 0) {
EditorNode::get_singleton()->show_warning(TTR("No name provided.")); EditorNode::get_singleton()->show_warning(TTR("No name provided."));
return; return;
} else if (new_name.contains("/") || new_name.contains("\\") || new_name.contains(":")) { } else if (new_name.contains_char('/') || new_name.contains_char('\\') || new_name.contains_char(':')) {
EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters.")); EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
return; return;
} }
@ -2873,7 +2873,7 @@ void EditorPropertyNodePath::update_property() {
const Node *target_node = base_node->get_node(p); const Node *target_node = base_node->get_node(p);
ERR_FAIL_NULL(target_node); ERR_FAIL_NULL(target_node);
if (String(target_node->get_name()).contains("@")) { if (String(target_node->get_name()).contains_char('@')) {
assign->set_button_icon(Ref<Texture2D>()); assign->set_button_icon(Ref<Texture2D>());
assign->set_text(p); assign->set_text(p);
return; return;

View File

@ -108,7 +108,7 @@ class SectionedInspectorFilter : public Object {
if (pi.name.begins_with(section + "/")) { if (pi.name.begins_with(section + "/")) {
pi.name = pi.name.replace_first(section + "/", ""); pi.name = pi.name.replace_first(section + "/", "");
if (!allow_sub && pi.name.contains("/")) { if (!allow_sub && pi.name.contains_char('/')) {
continue; continue;
} }
p_list->push_back(pi); p_list->push_back(pi);
@ -247,7 +247,7 @@ void SectionedInspector::update_category_list() {
continue; continue;
} }
if (pi.name.contains(":") || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script")) { if (pi.name.contains_char(':') || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script")) {
continue; continue;
} }

View File

@ -1803,7 +1803,7 @@ void FileSystemDock::_rename_operation_confirm() {
if (new_name.length() == 0) { if (new_name.length() == 0) {
EditorNode::get_singleton()->show_warning(TTR("No name provided.")); EditorNode::get_singleton()->show_warning(TTR("No name provided."));
rename_error = true; rename_error = true;
} else if (new_name.contains("/") || new_name.contains("\\") || new_name.contains(":")) { } else if (new_name.contains_char('/') || new_name.contains_char('\\') || new_name.contains_char(':')) {
EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters.")); EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
rename_error = true; rename_error = true;
} else if (new_name[0] == '.') { } else if (new_name[0] == '.') {
@ -2266,7 +2266,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
test_args.push_back("command -v " + terminal_emulator); test_args.push_back("command -v " + terminal_emulator);
const Error err = OS::get_singleton()->execute("bash", test_args, &pipe); const Error err = OS::get_singleton()->execute("bash", test_args, &pipe);
// Check if a path to the terminal executable exists. // Check if a path to the terminal executable exists.
if (err == OK && pipe.contains("/")) { if (err == OK && pipe.contains_char('/')) {
chosen_terminal_emulator = terminal_emulator; chosen_terminal_emulator = terminal_emulator;
break; break;
} else if (err == ERR_CANT_FORK) { } else if (err == ERR_CANT_FORK) {

View File

@ -759,7 +759,7 @@ bool SceneTreeEditor::_item_matches_all_terms(TreeItem *p_item, const PackedStri
const String &term = p_terms[i]; const String &term = p_terms[i];
// Recognize special filter. // Recognize special filter.
if (term.contains(":") && !term.get_slicec(':', 0).is_empty()) { if (term.contains_char(':') && !term.get_slicec(':', 0).is_empty()) {
String parameter = term.get_slicec(':', 0); String parameter = term.get_slicec(':', 0);
String argument = term.get_slicec(':', 1); String argument = term.get_slicec(':', 1);

View File

@ -1808,10 +1808,10 @@ void Collada::_parse_animation(XMLParser &p_parser) {
} }
} }
if (target.contains("/")) { //transform component if (target.contains_char('/')) { //transform component
track.target = target.get_slicec('/', 0); track.target = target.get_slicec('/', 0);
track.param = target.get_slicec('/', 1); track.param = target.get_slicec('/', 1);
if (track.param.contains(".")) { if (track.param.contains_char('.')) {
track.component = track.param.get_slice(".", 1).to_upper(); track.component = track.param.get_slice(".", 1).to_upper();
} }
track.param = track.param.get_slice(".", 0); track.param = track.param.get_slice(".", 0);

View File

@ -239,7 +239,7 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
List<StringName> anims; List<StringName> anims;
ap->get_animation_list(&anims); ap->get_animation_list(&anims);
for (const StringName &name : anims) { for (const StringName &name : anims) {
if (String(name).contains("/")) { if (String(name).contains_char('/')) {
continue; // Avoid animation library which may be created by importer dynamically. continue; // Avoid animation library which may be created by importer dynamically.
} }

View File

@ -1068,7 +1068,7 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
const String &new_name = p_text; const String &new_name = p_text;
ERR_FAIL_COND(new_name.is_empty() || new_name.contains(".") || new_name.contains("/")); ERR_FAIL_COND(new_name.is_empty() || new_name.contains_char('.') || new_name.contains_char('/'));
if (new_name == prev_name) { if (new_name == prev_name) {
return; //nothing to do return; //nothing to do

View File

@ -470,7 +470,7 @@ void AnimationLibraryEditor::_item_renamed() {
bool restore_text = false; bool restore_text = false;
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
if (String(text).contains("/") || String(text).contains(":") || String(text).contains(",") || String(text).contains("[")) { if (String(text).contains_char('/') || String(text).contains_char(':') || String(text).contains_char(',') || String(text).contains_char('[')) {
restore_text = true; restore_text = true;
} else { } else {
if (ti->get_parent() == tree->get_root()) { if (ti->get_parent() == tree->get_root()) {

View File

@ -504,7 +504,7 @@ void AnimationPlayerEditor::_animation_rename() {
String selected_name = animation->get_item_text(selected); String selected_name = animation->get_item_text(selected);
// Remove library prefix if present. // Remove library prefix if present.
if (selected_name.contains("/")) { if (selected_name.contains_char('/')) {
selected_name = selected_name.get_slice("/", 1); selected_name = selected_name.get_slice("/", 1);
} }
@ -537,7 +537,7 @@ void AnimationPlayerEditor::_animation_remove_confirmed() {
ERR_FAIL_COND(al.is_null()); ERR_FAIL_COND(al.is_null());
// For names of form lib_name/anim_name, remove library name prefix. // For names of form lib_name/anim_name, remove library name prefix.
if (current.contains("/")) { if (current.contains_char('/')) {
current = current.get_slice("/", 1); current = current.get_slice("/", 1);
} }
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
@ -626,7 +626,7 @@ void AnimationPlayerEditor::_animation_name_edited() {
// Extract library prefix if present. // Extract library prefix if present.
String new_library_prefix = ""; String new_library_prefix = "";
if (current.contains("/")) { if (current.contains_char('/')) {
new_library_prefix = current.get_slice("/", 0) + "/"; new_library_prefix = current.get_slice("/", 0) + "/";
current = current.get_slice("/", 1); current = current.get_slice("/", 1);
} }
@ -1340,7 +1340,7 @@ void AnimationPlayerEditor::_animation_duplicate() {
break; break;
} }
if (new_name.contains("/")) { if (new_name.contains_char('/')) {
// Discard library prefix. // Discard library prefix.
new_name = new_name.get_slice("/", 1); new_name = new_name.get_slice("/", 1);
} }

View File

@ -1618,7 +1618,7 @@ void AnimationNodeStateMachineEditor::_open_editor(const String &p_name) {
void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) { void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) {
const String &new_name = p_text; const String &new_name = p_text;
ERR_FAIL_COND(new_name.is_empty() || new_name.contains(".") || new_name.contains("/")); ERR_FAIL_COND(new_name.is_empty() || new_name.contains_char('.') || new_name.contains_char('/'));
if (new_name == prev_name) { if (new_name == prev_name) {
return; // Nothing to do. return; // Nothing to do.

View File

@ -113,7 +113,7 @@ void ResourcePreloaderEditor::_item_edited() {
return; return;
} }
if (new_name.is_empty() || new_name.contains("\\") || new_name.contains("/") || preloader->has_resource(new_name)) { if (new_name.is_empty() || new_name.contains_char('\\') || new_name.contains_char('/') || preloader->has_resource(new_name)) {
s->set_text(0, old_name); s->set_text(0, old_name);
return; return;
} }

View File

@ -183,7 +183,7 @@ void EditorStandardSyntaxHighlighter::_update_cache() {
if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) { if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) {
continue; continue;
} }
if (prop_name.contains("/")) { if (prop_name.contains_char('/')) {
continue; continue;
} }
highlighter->add_member_keyword_color(prop_name, member_variable_color); highlighter->add_member_keyword_color(prop_name, member_variable_color);

View File

@ -1636,7 +1636,7 @@ void ScriptTextEditor::_edit_option_toggle_inline_comment() {
script->get_language()->get_comment_delimiters(&comment_delimiters); script->get_language()->get_comment_delimiters(&comment_delimiters);
for (const String &script_delimiter : comment_delimiters) { for (const String &script_delimiter : comment_delimiters) {
if (!script_delimiter.contains(" ")) { if (!script_delimiter.contains_char(' ')) {
delimiter = script_delimiter; delimiter = script_delimiter;
break; break;
} }

View File

@ -1677,7 +1677,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
} }
// -- \t.func() -> \tsuper.func() Object // -- \t.func() -> \tsuper.func() Object
if (line.contains("(") && line.contains(".")) { if (line.contains_char('(') && line.contains_char('.')) {
line = reg_container.reg_super.sub(line, "$1super.$2", true); // TODO, not sure if possible, but for now this broke String text e.g. "Chosen .gitignore" -> "Chosen super.gitignore" line = reg_container.reg_super.sub(line, "$1super.$2", true); // TODO, not sure if possible, but for now this broke String text e.g. "Chosen .gitignore" -> "Chosen super.gitignore"
} }

View File

@ -834,7 +834,7 @@ void ProjectManager::_set_new_tag_name(const String p_name) {
return; return;
} }
if (p_name.contains(" ")) { if (p_name.contains_char(' ')) {
tag_error->set_text(TTR("Tag name can't contain spaces.")); tag_error->set_text(TTR("Tag name can't contain spaces."));
return; return;
} }

View File

@ -350,7 +350,7 @@ const char *ProjectList::SIGNAL_PROJECT_ASK_OPEN = "project_ask_open";
// Helpers. // Helpers.
bool ProjectList::project_feature_looks_like_version(const String &p_feature) { bool ProjectList::project_feature_looks_like_version(const String &p_feature) {
return p_feature.contains(".") && p_feature.substr(0, 3).is_numeric(); return p_feature.contains_char('.') && p_feature.substr(0, 3).is_numeric();
} }
// Notifications. // Notifications.
@ -581,7 +581,7 @@ void ProjectList::sort_projects() {
bool item_visible = true; bool item_visible = true;
if (!_search_term.is_empty()) { if (!_search_term.is_empty()) {
String search_path; String search_path;
if (search_term.contains("/")) { if (search_term.contains_char('/')) {
// Search path will match the whole path // Search path will match the whole path
search_path = item.path; search_path = item.path;
} else { } else {

View File

@ -268,7 +268,7 @@ void ProjectSettingsEditor::shortcut_input(const Ref<InputEvent> &p_event) {
String ProjectSettingsEditor::_get_setting_name() const { String ProjectSettingsEditor::_get_setting_name() const {
String name = property_box->get_text().strip_edges(); String name = property_box->get_text().strip_edges();
if (!name.begins_with("_") && !name.contains("/")) { if (!name.begins_with("_") && !name.contains_char('/')) {
name = "global/" + name; name = "global/" + name;
} }
return name; return name;

View File

@ -258,7 +258,7 @@ void PropertySelector::_update_search() {
TreeItem *item = search_options->create_item(category ? category : root); TreeItem *item = search_options->create_item(category ? category : root);
String desc; String desc;
if (mi.name.contains(":")) { if (mi.name.contains_char(':')) {
desc = mi.name.get_slice(":", 1) + " "; desc = mi.name.get_slice(":", 1) + " ";
mi.name = mi.name.get_slice(":", 0); mi.name = mi.name.get_slice(":", 0);
} else if (mi.return_val.type != Variant::NIL) { } else if (mi.return_val.type != Variant::NIL) {
@ -278,7 +278,7 @@ void PropertySelector::_update_search() {
if (arg_itr->type == Variant::NIL) { if (arg_itr->type == Variant::NIL) {
desc += ": Variant"; desc += ": Variant";
} else if (arg_itr->name.contains(":")) { } else if (arg_itr->name.contains_char(':')) {
desc += vformat(": %s", arg_itr->name.get_slice(":", 1)); desc += vformat(": %s", arg_itr->name.get_slice(":", 1));
arg_itr->name = arg_itr->name.get_slice(":", 0); arg_itr->name = arg_itr->name.get_slice(":", 0);
} else { } else {

View File

@ -744,7 +744,7 @@ ScriptLanguage::ScriptTemplate ScriptCreateDialog::_parse_template(const ScriptL
List<String> comment_delimiters; List<String> comment_delimiters;
p_language->get_comment_delimiters(&comment_delimiters); p_language->get_comment_delimiters(&comment_delimiters);
for (const String &script_delimiter : comment_delimiters) { for (const String &script_delimiter : comment_delimiters) {
if (!script_delimiter.contains(" ")) { if (!script_delimiter.contains_char(' ')) {
meta_delimiter = script_delimiter; meta_delimiter = script_delimiter;
break; break;
} }

View File

@ -292,7 +292,7 @@ void ShaderCreateDialog::_type_changed(int p_language) {
String extension = ""; String extension = "";
if (!path.is_empty()) { if (!path.is_empty()) {
if (path.contains(".")) { if (path.contains_char('.')) {
extension = path.get_extension(); extension = path.get_extension();
} }
if (extension.length() == 0) { if (extension.length() == 0) {

View File

@ -1290,7 +1290,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (N) { if (N) {
String vm = N->get(); String vm = N->get();
if (!vm.contains("x")) { // invalid parameter format if (!vm.contains_char('x')) { // invalid parameter format
OS::get_singleton()->print("Invalid resolution '%s', it should be e.g. '1280x720'.\n", OS::get_singleton()->print("Invalid resolution '%s', it should be e.g. '1280x720'.\n",
vm.utf8().get_data()); vm.utf8().get_data());
@ -1333,7 +1333,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (N) { if (N) {
String vm = N->get(); String vm = N->get();
if (!vm.contains(",")) { // invalid parameter format if (!vm.contains_char(',')) { // invalid parameter format
OS::get_singleton()->print("Invalid position '%s', it should be e.g. '80,128'.\n", OS::get_singleton()->print("Invalid position '%s', it should be e.g. '80,128'.\n",
vm.utf8().get_data()); vm.utf8().get_data());
@ -1832,7 +1832,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
// 'project.godot' file which will only be available through the network if this is enabled // 'project.godot' file which will only be available through the network if this is enabled
if (!remotefs.is_empty()) { if (!remotefs.is_empty()) {
int port; int port;
if (remotefs.contains(":")) { if (remotefs.contains_char(':')) {
port = remotefs.get_slicec(':', 1).to_int(); port = remotefs.get_slicec(':', 1).to_int();
remotefs = remotefs.get_slicec(':', 0); remotefs = remotefs.get_slicec(':', 0);
} else { } else {
@ -3275,7 +3275,7 @@ Error Main::setup2(bool p_show_boot_logo) {
// Dummy text driver cannot draw any text, making the editor unusable if selected. // Dummy text driver cannot draw any text, making the editor unusable if selected.
continue; continue;
} }
if (!text_driver_options.is_empty() && !text_driver_options.contains(",")) { if (!text_driver_options.is_empty() && !text_driver_options.contains_char(',')) {
// Not the first option; add a comma before it as a separator for the property hint. // Not the first option; add a comma before it as a separator for the property hint.
text_driver_options += ","; text_driver_options += ",";
} }

View File

@ -815,7 +815,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) { if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) {
continue; continue;
} }
if (prop_name.contains("/")) { if (prop_name.contains_char('/')) {
continue; continue;
} }
member_keywords[prop_name] = member_variable_color; member_keywords[prop_name] = member_variable_color;

View File

@ -1210,7 +1210,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_INTERNAL)) { if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_INTERNAL)) {
continue; continue;
} }
if (E.name.contains("/")) { if (E.name.contains_char('/')) {
continue; continue;
} }
int location = p_recursion_depth + _get_property_location(scr, E.name); int location = p_recursion_depth + _get_property_location(scr, E.name);
@ -1301,7 +1301,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_INTERNAL)) { if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_INTERNAL)) {
continue; continue;
} }
if (E.name.contains("/")) { if (E.name.contains_char('/')) {
continue; continue;
} }
int location = p_recursion_depth + _get_property_location(type, E.name); int location = p_recursion_depth + _get_property_location(type, E.name);
@ -1383,7 +1383,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_INTERNAL)) { if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_INTERNAL)) {
continue; continue;
} }
if (!String(E.name).contains("/")) { if (!String(E.name).contains_char('/')) {
ScriptLanguage::CodeCompletionOption option(E.name, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER, location); ScriptLanguage::CodeCompletionOption option(E.name, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER, location);
if (base_type.kind == GDScriptParser::DataType::ENUM) { if (base_type.kind == GDScriptParser::DataType::ENUM) {
// Sort enum members in their declaration order. // Sort enum members in their declaration order.
@ -2719,7 +2719,7 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex
} }
static void _find_enumeration_candidates(GDScriptParser::CompletionContext &p_context, const String &p_enum_hint, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result) { static void _find_enumeration_candidates(GDScriptParser::CompletionContext &p_context, const String &p_enum_hint, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result) {
if (!p_enum_hint.contains(".")) { if (!p_enum_hint.contains_char('.')) {
// Global constant or in the current class. // Global constant or in the current class.
StringName current_enum = p_enum_hint; StringName current_enum = p_enum_hint;
if (p_context.current_class && p_context.current_class->has_member(current_enum) && p_context.current_class->get_member(current_enum).type == GDScriptParser::ClassNode::Member::ENUM) { if (p_context.current_class && p_context.current_class->has_member(current_enum) && p_context.current_class->get_member(current_enum).type == GDScriptParser::ClassNode::Member::ENUM) {
@ -3474,7 +3474,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
for (const MethodInfo &mi : virtual_methods) { for (const MethodInfo &mi : virtual_methods) {
String method_hint = mi.name; String method_hint = mi.name;
if (method_hint.contains(":")) { if (method_hint.contains_char(':')) {
method_hint = method_hint.get_slice(":", 0); method_hint = method_hint.get_slice(":", 0);
} }
method_hint += "("; method_hint += "(";
@ -3484,7 +3484,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
method_hint += ", "; method_hint += ", ";
} }
String arg = arg_itr->name; String arg = arg_itr->name;
if (arg.contains(":")) { if (arg.contains_char(':')) {
arg = arg.substr(0, arg.find_char(':')); arg = arg.substr(0, arg.find_char(':'));
} }
method_hint += arg; method_hint += arg;
@ -3542,7 +3542,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
if (path_needs_quote) { if (path_needs_quote) {
// Ignore quote_style and just use double quotes for paths with apostrophes. // Ignore quote_style and just use double quotes for paths with apostrophes.
// Double quotes don't need to be checked because they're not valid in node and property names. // Double quotes don't need to be checked because they're not valid in node and property names.
opt = opt.quote(opt.contains("'") ? "\"" : quote_style); // Handle user preference. opt = opt.quote(opt.contains_char('\'') ? "\"" : quote_style); // Handle user preference.
} }
ScriptLanguage::CodeCompletionOption option(opt, ScriptLanguage::CODE_COMPLETION_KIND_NODE_PATH); ScriptLanguage::CodeCompletionOption option(opt, ScriptLanguage::CODE_COMPLETION_KIND_NODE_PATH);
options.insert(option.display, option); options.insert(option.display, option);

View File

@ -4323,7 +4323,7 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta
push_error(vformat(R"(Argument %d of annotation "%s" is empty.)", i + 1, p_annotation->name), p_annotation->arguments[i]); push_error(vformat(R"(Argument %d of annotation "%s" is empty.)", i + 1, p_annotation->name), p_annotation->arguments[i]);
return false; return false;
} }
if (arg_string.contains(",")) { if (arg_string.contains_char(',')) {
push_error(vformat(R"(Argument %d of annotation "%s" contains a comma. Use separate arguments instead.)", i + 1, p_annotation->name), p_annotation->arguments[i]); push_error(vformat(R"(Argument %d of annotation "%s" contains a comma. Use separate arguments instead.)", i + 1, p_annotation->name), p_annotation->arguments[i]);
return false; return false;
} }

View File

@ -67,7 +67,7 @@ lsp::Position GodotPosition::to_lsp(const Vector<String> &p_lines) const {
res.character = column - 1; res.character = column - 1;
String pos_line = p_lines[res.line]; String pos_line = p_lines[res.line];
if (pos_line.contains("\t")) { if (pos_line.contains_char('\t')) {
int tab_size = get_indent_size(); int tab_size = get_indent_size();
int in_col = 1; int in_col = 1;

View File

@ -34,7 +34,7 @@ const uint32_t PROP_EDITOR_SCRIPT_VAR = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_S
bool EditorSceneExporterGLTFSettings::_set(const StringName &p_name, const Variant &p_value) { bool EditorSceneExporterGLTFSettings::_set(const StringName &p_name, const Variant &p_value) {
String name_str = String(p_name); String name_str = String(p_name);
if (name_str.contains("/")) { if (name_str.contains_char('/')) {
return _set_extension_setting(name_str, p_value); return _set_extension_setting(name_str, p_value);
} }
if (p_name == StringName("image_format")) { if (p_name == StringName("image_format")) {
@ -55,7 +55,7 @@ bool EditorSceneExporterGLTFSettings::_set(const StringName &p_name, const Varia
bool EditorSceneExporterGLTFSettings::_get(const StringName &p_name, Variant &r_ret) const { bool EditorSceneExporterGLTFSettings::_get(const StringName &p_name, Variant &r_ret) const {
String name_str = String(p_name); String name_str = String(p_name);
if (name_str.contains("/")) { if (name_str.contains_char('/')) {
return _get_extension_setting(name_str, r_ret); return _get_extension_setting(name_str, r_ret);
} }
if (p_name == StringName("image_format")) { if (p_name == StringName("image_format")) {

View File

@ -4078,7 +4078,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
if (uri.begins_with("data:")) { // Embedded data using base64. if (uri.begins_with("data:")) { // Embedded data using base64.
data = _parse_base64_uri(uri); data = _parse_base64_uri(uri);
// mimeType is optional, but if we have it defined in the URI, let's use it. // mimeType is optional, but if we have it defined in the URI, let's use it.
if (mime_type.is_empty() && uri.contains(";")) { if (mime_type.is_empty() && uri.contains_char(';')) {
// Trim "data:" prefix which is 5 characters long, and end at ";base64". // Trim "data:" prefix which is 5 characters long, and end at ";base64".
mime_type = uri.substr(5, uri.find(";base64") - 5); mime_type = uri.substr(5, uri.find(";base64") - 5);
} }

View File

@ -877,7 +877,7 @@ void BindingsGenerator::_append_text_method(StringBuilder &p_output, const TypeI
} }
void BindingsGenerator::_append_text_member(StringBuilder &p_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) { void BindingsGenerator::_append_text_member(StringBuilder &p_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) {
if (p_link_target.contains("/")) { if (p_link_target.contains_char('/')) {
// Properties with '/' (slash) in the name are not declared in C#, so there is nothing to reference. // Properties with '/' (slash) in the name are not declared in C#, so there is nothing to reference.
_append_text_undeclared(p_output, p_link_target); _append_text_undeclared(p_output, p_link_target);
} else if (!p_target_itype || !p_target_itype->is_object_type) { } else if (!p_target_itype || !p_target_itype->is_object_type) {
@ -1158,7 +1158,7 @@ void BindingsGenerator::_append_xml_method(StringBuilder &p_xml_output, const Ty
} }
void BindingsGenerator::_append_xml_member(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) { void BindingsGenerator::_append_xml_member(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) {
if (p_link_target.contains("/")) { if (p_link_target.contains_char('/')) {
// Properties with '/' (slash) in the name are not declared in C#, so there is nothing to reference. // Properties with '/' (slash) in the name are not declared in C#, so there is nothing to reference.
_append_xml_undeclared(p_xml_output, p_link_target); _append_xml_undeclared(p_xml_output, p_link_target);
} else if (!p_target_itype || !p_target_itype->is_object_type) { } else if (!p_target_itype || !p_target_itype->is_object_type) {
@ -3870,7 +3870,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
continue; continue;
} }
if (property.name.contains("/")) { if (property.name.contains_char('/')) {
// Ignore properties with '/' (slash) in the name. These are only meant for use in the inspector. // Ignore properties with '/' (slash) in the name. These are only meant for use in the inspector.
continue; continue;
} }

View File

@ -443,7 +443,7 @@ void OpenXRCompositionLayer::_get_property_list(List<PropertyInfo> *p_property_l
for (const PropertyInfo &pinfo : extension_properties) { for (const PropertyInfo &pinfo : extension_properties) {
StringName prop_name = pinfo.name; StringName prop_name = pinfo.name;
if (!String(prop_name).contains("/")) { if (!String(prop_name).contains_char('/')) {
WARN_PRINT_ONCE(vformat("Discarding OpenXRCompositionLayer property name '%s' from extension because it doesn't contain a '/'.")); WARN_PRINT_ONCE(vformat("Discarding OpenXRCompositionLayer property name '%s' from extension because it doesn't contain a '/'."));
continue; continue;
} }

View File

@ -97,7 +97,7 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
if (parser->has_attribute("id")) { if (parser->has_attribute("id")) {
const String &gl_name = parser->get_named_attribute_value("id"); const String &gl_name = parser->get_named_attribute_value("id");
if (gl_name.begins_with("glyph")) { if (gl_name.begins_with("glyph")) {
int dot_pos = gl_name.find("."); int dot_pos = gl_name.find_char('.');
int64_t gl_idx = gl_name.substr(5, (dot_pos > 0) ? dot_pos - 5 : -1).to_int(); int64_t gl_idx = gl_name.substr(5, (dot_pos > 0) ? dot_pos - 5 : -1).to_int();
if (p_slot->glyph_index != gl_idx) { if (p_slot->glyph_index != gl_idx) {
parser->skip_section(); parser->skip_section();

View File

@ -97,7 +97,7 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
if (parser->has_attribute("id")) { if (parser->has_attribute("id")) {
const String &gl_name = parser->get_named_attribute_value("id"); const String &gl_name = parser->get_named_attribute_value("id");
if (gl_name.begins_with("glyph")) { if (gl_name.begins_with("glyph")) {
int dot_pos = gl_name.find("."); int dot_pos = gl_name.find_char('.');
int64_t gl_idx = gl_name.substr(5, (dot_pos > 0) ? dot_pos - 5 : -1).to_int(); int64_t gl_idx = gl_name.substr(5, (dot_pos > 0) ? dot_pos - 5 : -1).to_int();
if (p_slot->glyph_index != gl_idx) { if (p_slot->glyph_index != gl_idx) {
parser->skip_section(); parser->skip_section();

View File

@ -349,7 +349,7 @@ String EditorExportPlatformWindows::get_export_option_warning(const EditorExport
PackedStringArray version_array = file_version.split(".", false); PackedStringArray version_array = file_version.split(".", false);
if (version_array.size() != 4 || !version_array[0].is_valid_int() || if (version_array.size() != 4 || !version_array[0].is_valid_int() ||
!version_array[1].is_valid_int() || !version_array[2].is_valid_int() || !version_array[1].is_valid_int() || !version_array[2].is_valid_int() ||
!version_array[3].is_valid_int() || file_version.contains("-")) { !version_array[3].is_valid_int() || file_version.contains_char('-')) {
return TTR("Invalid file version."); return TTR("Invalid file version.");
} }
} }
@ -359,7 +359,7 @@ String EditorExportPlatformWindows::get_export_option_warning(const EditorExport
PackedStringArray version_array = product_version.split(".", false); PackedStringArray version_array = product_version.split(".", false);
if (version_array.size() != 4 || !version_array[0].is_valid_int() || if (version_array.size() != 4 || !version_array[0].is_valid_int() ||
!version_array[1].is_valid_int() || !version_array[2].is_valid_int() || !version_array[1].is_valid_int() || !version_array[2].is_valid_int() ||
!version_array[3].is_valid_int() || product_version.contains("-")) { !version_array[3].is_valid_int() || product_version.contains_char('-')) {
return TTR("Invalid product version."); return TTR("Invalid product version.");
} }
} }

View File

@ -1727,7 +1727,7 @@ String OS_Windows::get_environment(const String &p_var) const {
} }
void OS_Windows::set_environment(const String &p_var, const String &p_value) const { void OS_Windows::set_environment(const String &p_var, const String &p_value) const {
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var)); ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains_char('='), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
Char16String var = p_var.utf16(); Char16String var = p_var.utf16();
Char16String value = p_value.utf16(); Char16String value = p_value.utf16();
ERR_FAIL_COND_MSG(var.length() + value.length() + 2 > 32767, vformat("Invalid definition for environment variable '%s', cannot exceed 32767 characters.", p_var)); ERR_FAIL_COND_MSG(var.length() + value.length() + 2 > 32767, vformat("Invalid definition for environment variable '%s', cannot exceed 32767 characters.", p_var));
@ -1735,7 +1735,7 @@ void OS_Windows::set_environment(const String &p_var, const String &p_value) con
} }
void OS_Windows::unset_environment(const String &p_var) const { void OS_Windows::unset_environment(const String &p_var) const {
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var)); ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains_char('='), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
SetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), nullptr); // Null to delete. SetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), nullptr); // Null to delete.
} }

View File

@ -608,7 +608,7 @@ uint64_t Skeleton3D::get_version() const {
} }
int Skeleton3D::add_bone(const String &p_name) { int Skeleton3D::add_bone(const String &p_name) {
ERR_FAIL_COND_V_MSG(p_name.is_empty() || p_name.contains(":") || p_name.contains("/"), -1, vformat("Bone name cannot be empty or contain ':' or '/'.", p_name)); ERR_FAIL_COND_V_MSG(p_name.is_empty() || p_name.contains_char(':') || p_name.contains_char('/'), -1, vformat("Bone name cannot be empty or contain ':' or '/'.", p_name));
ERR_FAIL_COND_V_MSG(name_to_bone_index.has(p_name), -1, vformat("Skeleton3D \"%s\" already has a bone with name \"%s\".", to_string(), p_name)); ERR_FAIL_COND_V_MSG(name_to_bone_index.has(p_name), -1, vformat("Skeleton3D \"%s\" already has a bone with name \"%s\".", to_string(), p_name));
Bone b; Bone b;

View File

@ -1437,7 +1437,7 @@ void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNod
ERR_FAIL_COND(nodes.has(p_name)); ERR_FAIL_COND(nodes.has(p_name));
ERR_FAIL_COND(p_node.is_null()); ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(p_name == SceneStringName(output)); ERR_FAIL_COND(p_name == SceneStringName(output));
ERR_FAIL_COND(String(p_name).contains("/")); ERR_FAIL_COND(String(p_name).contains_char('/'));
Node n; Node n;
n.node = p_node; n.node = p_node;

View File

@ -294,7 +294,7 @@ StringName AnimationMixer::find_animation_library(const Ref<Animation> &p_animat
Error AnimationMixer::add_animation_library(const StringName &p_name, const Ref<AnimationLibrary> &p_animation_library) { Error AnimationMixer::add_animation_library(const StringName &p_name, const Ref<AnimationLibrary> &p_animation_library) {
ERR_FAIL_COND_V(p_animation_library.is_null(), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_animation_library.is_null(), ERR_INVALID_PARAMETER);
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
ERR_FAIL_COND_V_MSG(String(p_name).contains("/") || String(p_name).contains(":") || String(p_name).contains(",") || String(p_name).contains("["), ERR_INVALID_PARAMETER, "Invalid animation name: " + String(p_name) + "."); ERR_FAIL_COND_V_MSG(String(p_name).contains_char('/') || String(p_name).contains_char(':') || String(p_name).contains_char(',') || String(p_name).contains_char('['), ERR_INVALID_PARAMETER, "Invalid animation name: " + String(p_name) + ".");
#endif #endif
int insert_pos = 0; int insert_pos = 0;
@ -356,7 +356,7 @@ void AnimationMixer::rename_animation_library(const StringName &p_name, const St
return; return;
} }
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
ERR_FAIL_COND_MSG(String(p_new_name).contains("/") || String(p_new_name).contains(":") || String(p_new_name).contains(",") || String(p_new_name).contains("["), "Invalid animation library name: " + String(p_new_name) + "."); ERR_FAIL_COND_MSG(String(p_new_name).contains_char('/') || String(p_new_name).contains_char(':') || String(p_new_name).contains_char(',') || String(p_new_name).contains_char('['), "Invalid animation library name: " + String(p_new_name) + ".");
#endif #endif
bool found = false; bool found = false;

View File

@ -54,7 +54,7 @@ AnimationNodeStateMachineTransition::AdvanceMode AnimationNodeStateMachineTransi
void AnimationNodeStateMachineTransition::set_advance_condition(const StringName &p_condition) { void AnimationNodeStateMachineTransition::set_advance_condition(const StringName &p_condition) {
String cs = p_condition; String cs = p_condition;
ERR_FAIL_COND(cs.contains("/") || cs.contains(":")); ERR_FAIL_COND(cs.contains_char('/') || cs.contains_char(':'));
advance_condition = p_condition; advance_condition = p_condition;
if (!cs.is_empty()) { if (!cs.is_empty()) {
advance_condition_name = "conditions/" + cs; advance_condition_name = "conditions/" + cs;
@ -1257,7 +1257,7 @@ bool AnimationNodeStateMachine::is_parameter_read_only(const StringName &p_param
void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) { void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) {
ERR_FAIL_COND(states.has(p_name)); ERR_FAIL_COND(states.has(p_name));
ERR_FAIL_COND(p_node.is_null()); ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(String(p_name).contains("/")); ERR_FAIL_COND(String(p_name).contains_char('/'));
State state_new; State state_new;
state_new.node = p_node; state_new.node = p_node;
@ -1276,7 +1276,7 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation
void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<AnimationNode> p_node) { void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<AnimationNode> p_node) {
ERR_FAIL_COND(states.has(p_name) == false); ERR_FAIL_COND(states.has(p_name) == false);
ERR_FAIL_COND(p_node.is_null()); ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(String(p_name).contains("/")); ERR_FAIL_COND(String(p_name).contains_char('/'));
{ {
Ref<AnimationNode> node = states[p_name].node; Ref<AnimationNode> node = states[p_name].node;

View File

@ -325,7 +325,7 @@ bool AnimationNode::add_input(const String &p_name) {
// Root nodes can't add inputs. // Root nodes can't add inputs.
ERR_FAIL_COND_V(Object::cast_to<AnimationRootNode>(this) != nullptr, false); ERR_FAIL_COND_V(Object::cast_to<AnimationRootNode>(this) != nullptr, false);
Input input; Input input;
ERR_FAIL_COND_V(p_name.contains(".") || p_name.contains("/"), false); ERR_FAIL_COND_V(p_name.contains_char('.') || p_name.contains_char('/'), false);
input.name = p_name; input.name = p_name;
inputs.push_back(input); inputs.push_back(input);
emit_changed(); emit_changed();
@ -340,7 +340,7 @@ void AnimationNode::remove_input(int p_index) {
bool AnimationNode::set_input_name(int p_input, const String &p_name) { bool AnimationNode::set_input_name(int p_input, const String &p_name) {
ERR_FAIL_INDEX_V(p_input, inputs.size(), false); ERR_FAIL_INDEX_V(p_input, inputs.size(), false);
ERR_FAIL_COND_V(p_name.contains(".") || p_name.contains("/"), false); ERR_FAIL_COND_V(p_name.contains_char('.') || p_name.contains_char('/'), false);
inputs.write[p_input].name = p_name; inputs.write[p_input].name = p_name;
emit_changed(); emit_changed();
return true; return true;

View File

@ -33,11 +33,11 @@
#include "scene/scene_string_names.h" #include "scene/scene_string_names.h"
bool AnimationLibrary::is_valid_animation_name(const String &p_name) { bool AnimationLibrary::is_valid_animation_name(const String &p_name) {
return !(p_name.is_empty() || p_name.contains("/") || p_name.contains(":") || p_name.contains(",") || p_name.contains("[")); return !(p_name.is_empty() || p_name.contains_char('/') || p_name.contains_char(':') || p_name.contains_char(',') || p_name.contains_char('['));
} }
bool AnimationLibrary::is_valid_library_name(const String &p_name) { bool AnimationLibrary::is_valid_library_name(const String &p_name) {
return !(p_name.contains("/") || p_name.contains(":") || p_name.contains(",") || p_name.contains("[")); return !(p_name.contains_char('/') || p_name.contains_char(':') || p_name.contains_char(',') || p_name.contains_char('['));
} }
String AnimationLibrary::validate_library_name(const String &p_name) { String AnimationLibrary::validate_library_name(const String &p_name) {

View File

@ -37,7 +37,7 @@
bool Theme::_set(const StringName &p_name, const Variant &p_value) { bool Theme::_set(const StringName &p_name, const Variant &p_value) {
String sname = p_name; String sname = p_name;
if (sname.contains("/")) { if (sname.contains_char('/')) {
String type = sname.get_slicec('/', 1); String type = sname.get_slicec('/', 1);
String theme_type = sname.get_slicec('/', 0); String theme_type = sname.get_slicec('/', 0);
String prop_name = sname.get_slicec('/', 2); String prop_name = sname.get_slicec('/', 2);
@ -69,7 +69,7 @@ bool Theme::_set(const StringName &p_name, const Variant &p_value) {
bool Theme::_get(const StringName &p_name, Variant &r_ret) const { bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
String sname = p_name; String sname = p_name;
if (sname.contains("/")) { if (sname.contains_char('/')) {
String type = sname.get_slicec('/', 1); String type = sname.get_slicec('/', 1);
String theme_type = sname.get_slicec('/', 0); String theme_type = sname.get_slicec('/', 0);
String prop_name = sname.get_slicec('/', 2); String prop_name = sname.get_slicec('/', 2);

View File

@ -4147,7 +4147,7 @@ String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader::
if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) { if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
if (!p_input_vars[count].is_empty()) { if (!p_input_vars[count].is_empty()) {
String s = ports[idx].string; String s = ports[idx].string;
if (s.contains(":")) { if (s.contains_char(':')) {
shader_code += " " + s.get_slicec(':', 0) + " = " + p_input_vars[count] + "." + s.get_slicec(':', 1) + ";\n"; shader_code += " " + s.get_slicec(':', 0) + " = " + p_input_vars[count] + "." + s.get_slicec(':', 1) + ";\n";
} else { } else {
shader_code += " " + s + " = " + p_input_vars[count] + ";\n"; shader_code += " " + s + " = " + p_input_vars[count] + ";\n";

View File

@ -106,11 +106,11 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
if (reading_versions) { if (reading_versions) {
String l = line.strip_edges(); String l = line.strip_edges();
if (!l.is_empty()) { if (!l.is_empty()) {
if (!l.contains("=")) { if (!l.contains_char('=')) {
base_error = "Missing `=` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`."; base_error = "Missing `=` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`.";
break; break;
} }
if (!l.contains(";")) { if (!l.contains_char(';')) {
// We don't require a semicolon per se, but it's needed for clang-format to handle things properly. // We don't require a semicolon per se, but it's needed for clang-format to handle things properly.
base_error = "Missing `;` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`."; base_error = "Missing `;` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`.";
break; break;

View File

@ -181,7 +181,7 @@ static String _mkid(const String &p_id) {
static String f2sp0(float p_float) { static String f2sp0(float p_float) {
String num = rtos(p_float); String num = rtos(p_float);
if (!num.contains(".") && !num.contains("e")) { if (!num.contains_char('.') && !num.contains_char('e')) {
num += ".0"; num += ".0";
} }
return num; return num;