diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/os/dir_access.cpp | 97 | ||||
-rw-r--r-- | core/os/dir_access.h | 4 | ||||
-rw-r--r-- | core/os/os.cpp | 27 | ||||
-rw-r--r-- | core/ustring.cpp | 11 | ||||
-rw-r--r-- | core/ustring.h | 2 |
5 files changed, 141 insertions, 0 deletions
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index 35e4443f2a..6d4b46f4da 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -98,6 +98,7 @@ static Error _erase_recursive(DirAccess *da) { err = _erase_recursive(da); if (err) { print_line("err recurso " + E->get()); + da->change_dir(".."); return err; } err = da->change_dir(".."); @@ -340,6 +341,102 @@ Error DirAccess::copy(String p_from, String p_to, int chmod_flags) { return err; } +// Changes dir for the current scope, returning back to the original dir +// when scope exits +class DirChanger { + DirAccess *da; + String original_dir; + +public: + DirChanger(DirAccess *p_da, String p_dir) { + da = p_da; + original_dir = p_da->get_current_dir(); + p_da->change_dir(p_dir); + } + + ~DirChanger() { + da->change_dir(original_dir); + } +}; + +Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags) { + List<String> dirs; + + String curdir = get_current_dir(); + list_dir_begin(); + String n = get_next(); + while (n != String()) { + + if (n != "." && n != "..") { + + if (current_is_dir()) + dirs.push_back(n); + else { + String rel_path = n; + if (!n.is_rel_path()) { + list_dir_end(); + return ERR_BUG; + } + Error err = copy(get_current_dir() + "/" + n, p_to + rel_path, p_chmod_flags); + if (err) { + list_dir_end(); + return err; + } + } + } + + n = get_next(); + } + + list_dir_end(); + + for (List<String>::Element *E = dirs.front(); E; E = E->next()) { + String rel_path = E->get(); + String target_dir = p_to + rel_path; + if (!p_target_da->dir_exists(target_dir)) { + Error err = p_target_da->make_dir(target_dir); + ERR_FAIL_COND_V(err, err); + } + + Error err = change_dir(E->get()); + ERR_FAIL_COND_V(err, err); + err = _copy_dir(p_target_da, p_to + rel_path + "/", p_chmod_flags); + if (err) { + change_dir(".."); + ERR_PRINT("Failed to copy recursively"); + return err; + } + err = change_dir(".."); + if (err) { + ERR_PRINT("Failed to go back"); + return err; + } + } + + return OK; +} + +Error DirAccess::copy_dir(String p_from, String p_to, int p_chmod_flags) { + ERR_FAIL_COND_V(!dir_exists(p_from), ERR_FILE_NOT_FOUND); + + DirAccess *target_da = DirAccess::create_for_path(p_to); + ERR_FAIL_COND_V(!target_da, ERR_CANT_CREATE); + + if (!target_da->dir_exists(p_to)) { + Error err = target_da->make_dir_recursive(p_to); + if (err) { + memdelete(target_da); + } + ERR_FAIL_COND_V(err, err); + } + + DirChanger dir_changer(this, p_from); + Error err = _copy_dir(target_da, p_to + "/", p_chmod_flags); + memdelete(target_da); + + return err; +} + bool DirAccess::exists(String p_dir) { DirAccess *da = DirAccess::create_for_path(p_dir); diff --git a/core/os/dir_access.h b/core/os/dir_access.h index 7fa3ce5cf1..f3d1320041 100644 --- a/core/os/dir_access.h +++ b/core/os/dir_access.h @@ -52,6 +52,9 @@ public: private: AccessType _access_type; static CreateFunc create_func[ACCESS_MAX]; ///< set this to instance a filesystem object + + Error _copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags); + protected: String _get_root_path() const; String _get_root_string() const; @@ -89,6 +92,7 @@ public: static bool exists(String p_dir); virtual size_t get_space_left() = 0; + Error copy_dir(String p_from, String p_to, int chmod_flags = -1); virtual Error copy(String p_from, String p_to, int chmod_flags = -1); virtual Error rename(String p_from, String p_to) = 0; virtual Error remove(String p_name) = 0; diff --git a/core/os/os.cpp b/core/os/os.cpp index 65d0b2e05d..dd71f8a9c6 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -548,6 +548,33 @@ bool OS::has_feature(const String &p_feature) { if (sizeof(void *) == 4 && p_feature == "32") { return true; } +#if defined(__x86_64) || defined(__x86_64__) + if (p_feature == "x86_64") { + return true; + } +#elif (defined(__i386) || defined(__i386__)) + if (p_feature == "x86") { + return true; + } +#elif defined(__aarch64__) + if (p_feature == "arm64") { + return true; + } +#elif defined(__arm__) +#if defined(__ARM_ARCH_7A__) + if (p_feature == "armv7a" || p_feature == "armv7") { + return true; + } +#endif +#if defined(__ARM_ARCH_7S__) + if (p_feature == "armv7s" || p_feature == "armv7") { + return true; + } +#endif + if (p_feature == "arm") { + return true; + } +#endif if (_check_internal_feature_support(p_feature)) return true; diff --git a/core/ustring.cpp b/core/ustring.cpp index 7c3a784c5b..8d40f56386 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -862,6 +862,17 @@ Vector<int> String::split_ints_mk(const Vector<String> &p_splitters, bool p_allo return ret; } +String String::join(Vector<String> parts) { + String ret; + for (int i = 0; i < parts.size(); ++i) { + if (i > 0) { + ret += *this; + } + ret += parts[i]; + } + return ret; +} + CharType String::char_uppercase(CharType p_char) { return _find_upper(p_char); diff --git a/core/ustring.h b/core/ustring.h index 353c8e6c1d..9c24133b55 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -169,6 +169,8 @@ public: Vector<int> split_ints(const String &p_splitter, bool p_allow_empty = true) const; Vector<int> split_ints_mk(const Vector<String> &p_splitters, bool p_allow_empty = true) const; + String join(Vector<String> parts); + static CharType char_uppercase(CharType p_char); static CharType char_lowercase(CharType p_char); String to_upper() const; |