Browse Source

Fixed make_dir and make_dir_recursive erros, closes #1680 closes #1872

Juan Linietsky 9 years ago
parent
commit
61655d6dc2

+ 3 - 3
core/io/file_access_memory.cpp

@@ -46,7 +46,7 @@ void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) {
 		name = Globals::get_singleton()->globalize_path(p_name);
 	else
 		name = p_name;
-	name = DirAccess::normalize_path(name);
+	//name = DirAccess::normalize_path(name);
 
 	(*files)[name] = p_data;
 }
@@ -68,7 +68,7 @@ FileAccess* FileAccessMemory::create() {
 bool FileAccessMemory::file_exists(const String& p_name) {
 
 	String name = fix_path(p_name);
-	name = DirAccess::normalize_path(name);
+//	name = DirAccess::normalize_path(name);
 
 	return files && (files->find(name) != NULL);
 }
@@ -87,7 +87,7 @@ Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) {
 	ERR_FAIL_COND_V(!files, ERR_FILE_NOT_FOUND);
 
 	String name = fix_path(p_path);
-	name = DirAccess::normalize_path(name);
+//	name = DirAccess::normalize_path(name);
 
 	Map<String, Vector<uint8_t> >::Element* E = files->find(name);
 	ERR_FAIL_COND_V(!E, ERR_FILE_NOT_FOUND);

+ 34 - 100
core/os/dir_access.cpp

@@ -143,118 +143,52 @@ Error DirAccess::make_dir_recursive(String p_dir) {
 	};
 
 	String full_dir;
-	Globals* g = Globals::get_singleton();
 
-	if (!p_dir.is_abs_path()) {
-		//append current
+	if (p_dir.is_rel_path()) {
+		//append current		
+		full_dir=get_current_dir().plus_file(p_dir);
 
-		String cur = normalize_path(g->globalize_path(get_current_dir()));
-		if (cur[cur.length()-1] != '/') {
-			cur = cur + "/";
-		};
-
-		full_dir=(cur+"/"+p_dir).simplify_path();
 	} else {
-		//validate and use given
-		String dir = normalize_path(g->globalize_path(p_dir));
-		if (dir.length() < 1) {
-			return OK;
-		};
-		if (dir[dir.length()-1] != '/') {
-			dir = dir + "/";
-		};
-		full_dir=dir;
+		full_dir=p_dir;
 	}
 
-	//int slices = full_dir.get_slice_count("/");
-
-	int pos = 0;
-	while (pos < full_dir.length()) {
-
-		int n = full_dir.find("/", pos);
-		if (n < 0) {
-			n = full_dir.length();
-		};
-		pos = n + 1;
-
-		if (pos > 1) {
-			String to_create = full_dir.substr(0, pos -1);
-			//print_line("MKDIR: "+to_create);
-			Error err = make_dir(to_create);
-			if (err != OK && err != ERR_ALREADY_EXISTS) {
-
-				ERR_FAIL_V(err);
-			};
-		};
-	};
-
-	return OK;
-};
-
-
-String DirAccess::normalize_path(const String &p_path) {
-
-	static const int max_depth = 64;
-	int pos_stack[max_depth];
-	int curr = 0;
-
-	int pos = 0;
-	String cur_dir;
-
-	do {
+	full_dir=full_dir.replace("\\","/");
 
-		if (curr >= max_depth) {
-
-			ERR_PRINT("Directory depth too deep.");
-			return "";
-		};
-
-		int start = pos;
-
-		int next = p_path.find("/", pos);
-		if (next < 0) {
-			next = p_path.length() - 1;
-		};
-
-		pos = next + 1;
+	//int slices = full_dir.get_slice_count("/");
 
-		cur_dir = p_path.substr(start, next - start);
+	String base;
 
-		if (cur_dir == "" || cur_dir == ".") {
-			continue;
-		};
-		if (cur_dir == "..") {
+	if (full_dir.begins_with("res://"))
+		base="res://";
+	else if (full_dir.begins_with("user://"))
+		base="user://";
+	else if (full_dir.begins_with("/"))
+		base="/";
+	else if (full_dir.find(":/")!=-1) {
+		base=full_dir.substr(0,full_dir.find(":/")+2);
+	} else {
+		ERR_FAIL_V(ERR_INVALID_PARAMETER);
+	}
 
-			if (curr > 0) { // pop a dir
-				curr -= 2;
-			};
-			continue;
-		};
+	full_dir=full_dir.replace_first(base,"").simplify_path();
 
-		pos_stack[curr++] = start;
-		pos_stack[curr++] = next;
+	Vector<String> subdirs=full_dir.split("/");
 
-	} while (pos < p_path.length());
+	String curpath=base;
+	for(int i=0;i<subdirs.size();i++) {
 
-	String path;
-	if (p_path[0] == '/') {
-		path = "/";
-	};
+		curpath=curpath.plus_file(subdirs[i]);
+		Error err = make_dir(curpath);
+		if (err != OK && err != ERR_ALREADY_EXISTS) {
 
-	int i=0;
-	while (i < curr) {
-
-		int start = pos_stack[i++];
+			ERR_FAIL_V(err);
+		}
+	}
 
-		while ( ((i+1)<curr) && (pos_stack[i] == pos_stack[i+1]) ) {
+	return OK;
+}
 
-			++i;
-		};
-		path = path + p_path.substr(start, (pos_stack[i++] - start) + 1);
-	};
 
-	return path;
-};
 
 String DirAccess::get_next(bool* p_is_dir) {
 
@@ -276,9 +210,9 @@ String DirAccess::fix_path(String p_path) const {
 					String resource_path = Globals::get_singleton()->get_resource_path();
 					if (resource_path != "") {
 
-						return p_path.replace("res:/",resource_path);
+						return p_path.replace_first("res:/",resource_path);
 					};
-					return p_path.replace("res://", "");
+					return p_path.replace_first("res://", "");
 				}
 			}
 
@@ -292,9 +226,9 @@ String DirAccess::fix_path(String p_path) const {
 				String data_dir=OS::get_singleton()->get_data_dir();
 				if (data_dir != "") {
 
-					return p_path.replace("user:/",data_dir);
+					return p_path.replace_first("user:/",data_dir);
 				};
-				return p_path.replace("user://", "");
+				return p_path.replace_first("user://", "");
 			}
 
 		} break;

+ 0 - 2
core/os/dir_access.h

@@ -72,8 +72,6 @@ protected:
 
 public:
 
-	static String normalize_path(const String& p_path);
-
 	virtual bool list_dir_begin()=0; ///< This starts dir listing
 	virtual String get_next(bool* p_is_dir); // compatibility
 	virtual String get_next()=0;

+ 16 - 9
drivers/unix/dir_access_unix.cpp

@@ -66,7 +66,7 @@ bool DirAccessUnix::file_exists(String p_file) {
 
 
 	if (p_file.is_rel_path())
-		p_file=current_dir+"/"+p_file;
+		p_file=current_dir.plus_file(p_file);
 	else
 		p_file=fix_path(p_file);
 
@@ -104,7 +104,7 @@ bool DirAccessUnix::dir_exists(String p_dir) {
 uint64_t DirAccessUnix::get_modified_time(String p_file) {
 
 	if (p_file.is_rel_path())
-		p_file=current_dir+"/"+p_file;
+		p_file=current_dir.plus_file(p_file);
 	else
 		p_file=fix_path(p_file);
 
@@ -138,11 +138,9 @@ String DirAccessUnix::get_next() {
 	//typedef struct stat Stat;
 	struct stat flags;
 
-	String fname;
-	if (fname.parse_utf8(entry->d_name))
-		fname=entry->d_name; //no utf8, maybe latin?
+	String fname = fix_unicode_name(entry->d_name);
 
-	String f=current_dir+"/"+fname;
+	String f=current_dir.plus_file(fname);
 
 	if (stat(f.utf8().get_data(),&flags)==0) {
 
@@ -201,8 +199,17 @@ Error DirAccessUnix::make_dir(String p_dir) {
 
 	GLOBAL_LOCK_FUNCTION
 
-	p_dir=fix_path(p_dir);
-	
+	if (p_dir.is_rel_path())
+		p_dir=get_current_dir().plus_file(p_dir);
+	else
+		p_dir=fix_path(p_dir);
+#if 1
+
+
+	bool success=(mkdir(p_dir.utf8().get_data(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)==0);
+	int err = errno;
+
+#else
 	char real_current_dir_name[2048];
 	getcwd(real_current_dir_name,2048);
 	chdir(current_dir.utf8().get_data()); //ascii since this may be unicode or wathever the host os wants
@@ -211,7 +218,7 @@ Error DirAccessUnix::make_dir(String p_dir) {
 	int err = errno;
 
 	chdir(real_current_dir_name);
-
+#endif
 	if (success) {
 		return OK;
 	};

+ 4 - 1
drivers/unix/dir_access_unix.h

@@ -51,7 +51,10 @@ class DirAccessUnix : public DirAccess {
 	String current_dir;
 	bool _cisdir;
 	bool _cishidden;
-	
+protected:
+
+	virtual String fix_unicode_name(const char* p_name) const { return String::utf8(p_name); }
+
 public:
 	
 	virtual bool list_dir_begin(); ///< This starts dir listing

+ 7 - 8
drivers/windows/dir_access_windows.cpp

@@ -191,23 +191,21 @@ Error DirAccessWindows::make_dir(String p_dir) {
 
 #else
 
-	p_dir=fix_path(p_dir);
-
+	if (p_dir.is_rel_path())
+		p_dir=get_current_dir().plus_file(p_dir);
+	else
+		p_dir=fix_path(p_dir);
 	//p_dir.replace("/","\\");
 
 	bool success;
 	int err;
 
-	wchar_t real_current_dir_name[2048];
-	GetCurrentDirectoryW(2048,real_current_dir_name);
-
-	SetCurrentDirectoryW(current_dir.c_str());
+	p_dir="\\\\?\\"+p_dir; //done according to
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx
 
 	success=CreateDirectoryW(p_dir.c_str(), NULL);
 	err = GetLastError();
 
-	SetCurrentDirectoryW(real_current_dir_name);
-
 	if (success) {
 		return OK;
 	};
@@ -315,6 +313,7 @@ Error DirAccessWindows::remove(String p_path)  {
 	else
 		p_path=fix_path(p_path);
 
+
 	printf("erasing %s\n",p_path.utf8().get_data());
 	//WIN32_FILE_ATTRIBUTE_DATA    fileInfo;
 	//DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo);

+ 4 - 40
platform/osx/dir_access_osx.h

@@ -37,52 +37,16 @@
 #include <dirent.h>
 
 #include "os/dir_access.h"
+#include "drivers/unix/dir_access_unix.h"
 
 
 /**
 	@author Juan Linietsky <[email protected]>
 */
-class DirAccessOSX : public DirAccess {
+class DirAccessOSX : public DirAccessUnix {
+protected:
 
-	DIR *dir_stream;
-
-	static DirAccess *create_fs();
-
-	String current_dir;
-	bool _cisdir;
-	bool _cishidden;
-
-public:
-
-	virtual bool list_dir_begin(); ///< This starts dir listing
-	virtual String get_next();
-	virtual bool current_is_dir() const;
-	virtual bool current_is_hidden() const;
-
-	virtual void list_dir_end(); ///<
-
-	virtual int get_drive_count();
-	virtual String get_drive(int p_drive);
-
-	virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
-	virtual String get_current_dir(); ///< return current dir location
-	virtual Error make_dir(String p_dir);
-
-	virtual bool file_exists(String p_file);
-	virtual bool dir_exists(String p_dir);
-
-	virtual uint64_t get_modified_time(String p_file);
-
-
-
-	virtual Error rename(String p_from, String p_to);
-	virtual Error remove(String p_name);
-
-	virtual size_t get_space_left();
-
-
-	DirAccessOSX();
-	~DirAccessOSX();
+	virtual String fix_unicode_name(const char* p_name) const;
 
 };
 

+ 2 - 305
platform/osx/dir_access_osx.mm

@@ -30,324 +30,21 @@
 
 #if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
 
-#ifndef ANDROID_ENABLED
-#include <sys/statvfs.h>
-#endif
-
-#include <stdio.h>
-#include "os/memory.h"
-#include "print_string.h"
 #include <errno.h>
 
 #include <Foundation/NSString.h>
 
-DirAccess *DirAccessOSX::create_fs() {
-
-	return memnew( DirAccessOSX );
-}
-
-bool DirAccessOSX::list_dir_begin() {
-
-	list_dir_end(); //close any previous dir opening!
-
-
-//	char real_current_dir_name[2048]; //is this enough?!
-	//getcwd(real_current_dir_name,2048);
-	//chdir(curent_path.utf8().get_data());
-	dir_stream = opendir(current_dir.utf8().get_data());
-	//chdir(real_current_dir_name);
-	if (!dir_stream)
-		return true; //error!
-
-	return false;
-}
-
-bool DirAccessOSX::file_exists(String p_file) {
-
-	GLOBAL_LOCK_FUNCTION
-
-
-	if (p_file.is_rel_path())
-		p_file=current_dir+"/"+p_file;
-	else
-		p_file=fix_path(p_file);
-
-	struct stat flags;
-	bool success = 	(stat(p_file.utf8().get_data(),&flags)==0);
-
-	if (success && S_ISDIR(flags.st_mode)) {
-		success=false;
-	}
-
-	return success;
-
-}
-
-bool DirAccessOSX::dir_exists(String p_dir) {
-
-	GLOBAL_LOCK_FUNCTION
-
-
-	if (p_dir.is_rel_path())
-		p_dir=get_current_dir().plus_file(p_dir);
-	else
-		p_dir=fix_path(p_dir);
-
-	struct stat flags;
-	bool success = 	(stat(p_dir.utf8().get_data(),&flags)==0);
-
-	if (success && S_ISDIR(flags.st_mode))
-		return true;
-
-	return false;
-
-}
-
-uint64_t DirAccessOSX::get_modified_time(String p_file) {
-
-	if (p_file.is_rel_path())
-		p_file=current_dir+"/"+p_file;
-	else
-		p_file=fix_path(p_file);
-
-	struct stat flags;
-	bool success = 	(stat(p_file.utf8().get_data(),&flags)==0);
 
-	if (success) {
-		return flags.st_mtime;
-	} else {
-
-		ERR_FAIL_V(0);
-	};
-	return 0;
-};
-
-
-String DirAccessOSX::get_next() {
-
-	if (!dir_stream)
-		return "";
-	dirent *entry;
-
-	entry=readdir(dir_stream);
-
-	if (entry==NULL) {
-
-		list_dir_end();
-		return "";
-	}
-
-	//typedef struct stat Stat;
-	struct stat flags;
+String DirAccessOSX::fix_unicode_name(const char* p_name) const {
 
 	String fname;
-	NSString* nsstr = [[NSString stringWithUTF8String: entry->d_name] precomposedStringWithCanonicalMapping];
+	NSString* nsstr = [[NSString stringWithUTF8String: p_name] precomposedStringWithCanonicalMapping];
 
 	fname.parse_utf8([nsstr UTF8String]);
 
-	//[nsstr autorelease];
-
-	String f=current_dir+"/"+fname;
-
-	if (stat(f.utf8().get_data(),&flags)==0) {
-
-		if (S_ISDIR(flags.st_mode)) {
-
-			_cisdir=true;
-
-		} else {
-
-			_cisdir=false;
-		}
-
-	} else {
-
-		_cisdir=false;
-
-	}
-
-	_cishidden=(fname!="." && fname!=".." && fname.begins_with("."));
-
-
-
 	return fname;
-
-}
-
-bool DirAccessOSX::current_is_dir() const {
-
-	return _cisdir;
-}
-
-bool DirAccessOSX::current_is_hidden() const {
-
-	return _cishidden;
-}
-
-
-void DirAccessOSX::list_dir_end() {
-
-	if (dir_stream)
-		closedir(dir_stream);
-	dir_stream=0;
-	_cisdir=false;
-}
-
-int DirAccessOSX::get_drive_count() {
-
-	return 0;
-}
-String DirAccessOSX::get_drive(int p_drive) {
-
-	return "";
-}
-
-Error DirAccessOSX::make_dir(String p_dir) {
-
-	GLOBAL_LOCK_FUNCTION
-
-	p_dir=fix_path(p_dir);
-
-	char real_current_dir_name[2048];
-	getcwd(real_current_dir_name,2048);
-	chdir(current_dir.utf8().get_data()); //ascii since this may be unicode or wathever the host os wants
-
-	bool success=(mkdir(p_dir.utf8().get_data(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)==0);
-	int err = errno;
-
-	chdir(real_current_dir_name);
-
-	if (success) {
-		return OK;
-	};
-
-	if (err == EEXIST) {
-		return ERR_ALREADY_EXISTS;
-	};
-
-	return ERR_CANT_CREATE;
 }
 
 
-Error DirAccessOSX::change_dir(String p_dir) {
-
-	GLOBAL_LOCK_FUNCTION
-	p_dir=fix_path(p_dir);
-
-
-	char real_current_dir_name[2048];
-	getcwd(real_current_dir_name,2048);
-	String prev_dir;
-	if (prev_dir.parse_utf8(real_current_dir_name))
-		prev_dir=real_current_dir_name; //no utf8, maybe latin?
-
-	chdir(current_dir.utf8().get_data()); //ascii since this may be unicode or wathever the host os wants
-	bool worked=(chdir(p_dir.utf8().get_data())==0); // we can only give this utf8
-#ifndef IPHONE_ENABLED
-	String base = _get_root_path();
-	if (base!="") {
-
-		getcwd(real_current_dir_name,2048);
-		String new_dir;
-		new_dir.parse_utf8(real_current_dir_name);
-		if (!new_dir.begins_with(base))
-			worked=false;
-	}
-#endif
-	if (worked) {
-
-		getcwd(real_current_dir_name,2048);
-		if (current_dir.parse_utf8(real_current_dir_name))
-			current_dir=real_current_dir_name; //no utf8, maybe latin?
-	}
-
-	chdir(prev_dir.utf8().get_data());
-	return worked?OK:ERR_INVALID_PARAMETER;
-
-}
-
-String DirAccessOSX::get_current_dir() {
-
-	String base = _get_root_path();
-	if (base!="") {
-
-		String bd = current_dir.replace_first(base,"");
-		if (bd.begins_with("/"))
-			return _get_root_string()+bd.substr(1,bd.length());
-		else
-			return _get_root_string()+bd;
-
-	}
-	return current_dir;
-}
-
-Error DirAccessOSX::rename(String p_path,String p_new_path) {
-
-	if (p_path.is_rel_path())
-		p_path=get_current_dir().plus_file(p_path);
-	else
-		p_path=fix_path(p_path);
-
-	if (p_new_path.is_rel_path())
-		p_new_path=get_current_dir().plus_file(p_new_path);
-	else
-		p_new_path=fix_path(p_new_path);
-
-	return ::rename(p_path.utf8().get_data(),p_new_path.utf8().get_data())==0?OK:FAILED;
-}
-Error DirAccessOSX::remove(String p_path)  {
-
-	if (p_path.is_rel_path())
-		p_path=get_current_dir().plus_file(p_path);
-	else
-		p_path=fix_path(p_path);
-
-	struct stat flags;
-	if ((stat(p_path.utf8().get_data(),&flags)!=0))
-		return FAILED;
-
-	if (S_ISDIR(flags.st_mode))
-		return ::rmdir(p_path.utf8().get_data())==0?OK:FAILED;
-	else
-		return ::unlink(p_path.utf8().get_data())==0?OK:FAILED;
-}
-
-
-size_t DirAccessOSX::get_space_left() {
-
-#ifndef NO_STATVFS
-	struct statvfs vfs;
-	if (statvfs(current_dir.utf8().get_data(), &vfs) != 0) {
-
-		return 0;
-	};
-
-	return (size_t) (vfs.f_bavail * vfs.f_bsize);
-#else
-#warning THIS IS BROKEN
-	return 0;
-#endif
-};
-
-
-
-DirAccessOSX::DirAccessOSX() {
-
-	dir_stream=0;
-	current_dir=".";
-	_cisdir=false;
-
-	/* determine drive count */
-
-	change_dir(current_dir);
-
-}
-
-
-DirAccessOSX::~DirAccessOSX() {
-
-	list_dir_end();
-}
-
 
 #endif //posix_enabled

+ 0 - 94
tools/editor/editor_node.cpp

@@ -743,100 +743,6 @@ void EditorNode::_set_scene_metadata(const String& p_file) {
 
 }
 
-static Error _fix_object_paths(Object* obj, Node* root, String save_path) {
-
-	Globals* g = Globals::get_singleton();
-
-	String import_dir = root->get_meta("__editor_import_file__");
-	import_dir = import_dir.get_base_dir();
-	import_dir = DirAccess::normalize_path(import_dir);
-	if (import_dir[import_dir.length()-1] != '/') {
-		import_dir = import_dir + "/";
-	};
-
-	String resource_dir = DirAccess::normalize_path(g->get_resource_path());
-	if (resource_dir[resource_dir.length()-1] != '/') {
-		resource_dir = resource_dir + "/";
-	};
-
-
-	List<PropertyInfo> list;
-	obj->get_property_list(&list, false);
-
-	List<PropertyInfo>::Element *E = list.front();
-
-	while (E) {
-
-		Variant v = obj->get(E->get().name);
-		if (v.get_type() == Variant::OBJECT) {
-
-			Ref<Resource> res = (RefPtr)v;
-			if (res.is_null()) {
-				E = E->next();
-				continue;
-			}
-
-			if (res->get_path() != "") {
-
-				String res_path = res->get_path();
-				res_path = Globals::get_singleton()->globalize_path(res_path);
-				res_path = DirAccess::normalize_path(res_path);
-
-				if (res_path.find(resource_dir) != 0) {
-
-					// path of resource is not inside engine's resource path
-
-					String new_path;
-
-					if (res_path.find(import_dir) == 0) {
-
-						// path of resource is relative to path of import file
-						new_path = save_path + "/" + res_path.substr(import_dir.length(), res_path.length() - import_dir.length());
-
-					} else {
-
-						// path of resource is not relative to import file
-						new_path = save_path + "/" + res_path.get_file();
-					};
-
-					res->set_path(g->localize_path(new_path));
-					DirAccess* d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-					d->make_dir_recursive(new_path.get_base_dir());
-					printf("copying from %ls to %ls\n", res_path.c_str(), new_path.c_str());
-					Error err = d->copy(res_path, new_path);
-					memdelete(d);
-					ERR_FAIL_COND_V(err != OK, err);
-				}
-
-			} else {
-
-				_fix_object_paths(res.operator->(), root, save_path);
-			};
-		};
-
-
-		E = E->next();
-	};
-
-	return OK;
-};
-
-static Error _fix_imported_scene_paths(Node* node, Node* root, String save_path) {
-
-	if (node == root || node->get_owner() == root) {
-		Error e = _fix_object_paths(node, root, save_path);
-		ERR_FAIL_COND_V(e != OK, e);
-	};
-
-	for (int i=0; i<node->get_child_count(); i++) {
-
-		Error e = _fix_imported_scene_paths(node->get_child(i), root, save_path);
-		ERR_FAIL_COND_V(e != OK, e);
-	};
-
-	return OK;
-};
-
 
 bool EditorNode::_find_and_save_resource(RES res,Map<RES,bool>& processed,int32_t flags) {