[Bf-blender-cvs] [f25f7c8] master: Cycles: Re-implement some utilities to avoid use of boost

Sergey Sharybin noreply at git.blender.org
Sat Feb 6 19:47:57 CET 2016


Commit: f25f7c803020b9341e49e898abe94917c3235515
Author: Sergey Sharybin
Date:   Fri Feb 5 09:09:39 2016 +0100
Branches: master
https://developer.blender.org/rBf25f7c803020b9341e49e898abe94917c3235515

Cycles: Re-implement some utilities to avoid use of boost

The title says it all actually, the idea is to make Cycles
only requiring Boost via 3rd party dependencies like OIIO
and OSL.

So now there are only few places which still uses Boost:

- Foreach, function bindings and threading primitives.

  Those we can easily get rid with C++11 bump (which seems
  inevitable sooner or later if we'll want ot use newer
  LLVM for OSL),

- Networking devices

  There's no quick solution for those currently, but there
  are some patches around which improves serialization.

Reviewers: juicyfruit, mont29, campbellbarton, brecht, dingto

Reviewed By: brecht, dingto

Differential Revision: https://developer.blender.org/D1764

===================================================================

M	intern/cycles/device/device_cpu.cpp
M	intern/cycles/render/shader.h
M	intern/cycles/util/CMakeLists.txt
M	intern/cycles/util/util_optimization.h
M	intern/cycles/util/util_path.cpp
M	intern/cycles/util/util_path.h
M	intern/cycles/util/util_set.h
M	intern/cycles/util/util_string.cpp
M	intern/cycles/util/util_string.h
M	intern/cycles/util/util_system.cpp
M	intern/cycles/util/util_time.cpp
A	intern/cycles/util/util_windows.h

===================================================================

diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 83447b7..676b1279 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -19,15 +19,8 @@
 
 /* So ImathMath is included before our kernel_cpu_compat. */
 #ifdef WITH_OSL
-#  if defined(_MSC_VER)
-/* Prevent OSL from polluting the context with weird macros from windows.h.
- * TODO(sergey): Ideally it's only enough to have class/struct declarations in
- * the header and skip header include here.
- */
-#    define NOGDI
-#    define NOMINMAX
-#    define WIN32_LEAN_AND_MEAN
-#  endif
+/* So no context pollution happens from indirectly included windows.h */
+#  include "util_windows.h"
 #  include <OSL/oslexec.h>
 #endif
 
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index cc83ad0..6f4fd0e 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -18,15 +18,8 @@
 #define __SHADER_H__
 
 #ifdef WITH_OSL
-#  if defined(_MSC_VER)
-/* Prevent OSL from polluting the context with weird macros from windows.h.
- * TODO(sergey): Ideally it's only enough to have class/struct declarations in
- * the header and skip header include here.
- */
-#    define NOGDI
-#    define NOMINMAX
-#    define WIN32_LEAN_AND_MEAN
-#  endif
+/* So no context pollution happens from indirectly included windows.h */
+#  include "util_windows.h"
 #  include <OSL/oslexec.h>
 #endif
 
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index 9cf949b..8367d21 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -73,6 +73,7 @@ set(SRC_HEADERS
 	util_types.h
 	util_vector.h
 	util_view.h
+	util_windows.h
 	util_xml.h
 )
 
diff --git a/intern/cycles/util/util_optimization.h b/intern/cycles/util/util_optimization.h
index b1f9ee6..1fef0bd 100644
--- a/intern/cycles/util/util_optimization.h
+++ b/intern/cycles/util/util_optimization.h
@@ -111,10 +111,7 @@
 
 /* MinGW64 has conflicting declarations for these SSE headers in <windows.h>.
  * Since we can't avoid including <windows.h>, better only include that */
-#define NOGDI
-#define NOMINMAX
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+#include "util_windows.h"
 
 #endif
 
diff --git a/intern/cycles/util/util_path.cpp b/intern/cycles/util/util_path.cpp
index 06be607..e7a6135 100644
--- a/intern/cycles/util/util_path.cpp
+++ b/intern/cycles/util/util_path.cpp
@@ -21,28 +21,297 @@
 
 #include <OpenImageIO/strutil.h>
 #include <OpenImageIO/sysutil.h>
+
 OIIO_NAMESPACE_USING
 
 #include <stdio.h>
 
-#include <boost/filesystem.hpp> 
-#include <boost/algorithm/string.hpp>
+#include <sys/stat.h>
+
+#if defined(_WIN32)
+#  define DIR_SEP '\\'
+#  define DIR_SEP_ALT '/'
+#  include <direct.h>
+#else
+#  define DIR_SEP '/'
+#  define DIR_SEP_ALT '\\'
+#  include <dirent.h>
+#endif
+
+#ifdef HAVE_SHLWAPI_H
+#  include <shlwapi.h>
+#endif
+
+#include "util_windows.h"
 
 CCL_NAMESPACE_BEGIN
 
+#ifdef _WIN32
+#  if defined(_MSC_VER) || defined(__MINGW64__)
+typedef struct _stat64 path_stat_t;
+#  elif defined(__MINGW32__)
+typedef struct _stati64 path_stat_t;
+#  else
+typedef struct _stat path_stat_t;
+#  endif
+#  ifndef S_ISDIR
+#    define S_ISDIR(x) (((x) & _S_IFDIR) == _S_IFDIR)
+#  endif
+#  define mkdir(path, mode) _mkdir(path)
+#else
+typedef struct stat path_stat_t;
+#endif
+
 static string cached_path = "";
 static string cached_user_path = "";
 
-static boost::filesystem::path to_boost(const string& path)
-{
-	return boost::filesystem::path(path.c_str());
-}
+namespace {
+
+#ifdef _WIN32
+class directory_iterator {
+public:
+	class path_info {
+	public:
+		path_info(const string& path,
+		          const WIN32_FIND_DATAW& find_data)
+		: path_(path),
+		  find_data_(find_data)
+		{
+		}
+
+		string path() {
+			return path_join(path_, string_from_wstring(find_data_.cFileName));
+		}
+	protected:
+		const string& path_;
+		const WIN32_FIND_DATAW& find_data_;
+	};
+
+	directory_iterator()
+	: path_info_("", find_data_),
+	  h_find_(INVALID_HANDLE_VALUE)
+	{
+	}
+
+	directory_iterator(const string& path)
+	: path_(path),
+	  path_info_(path, find_data_)
+	{
+		string wildcard = path;
+		if(wildcard[wildcard.size() - 1] != DIR_SEP) {
+			wildcard += DIR_SEP;
+		}
+		wildcard += "*";
+		h_find_ = FindFirstFileW(string_to_wstring(wildcard).c_str(),
+		                         &find_data_);
+		if(h_find_ != INVALID_HANDLE_VALUE) {
+			skip_dots();
+		}
+	}
+
+	~directory_iterator()
+	{
+		if(h_find_ != INVALID_HANDLE_VALUE) {
+			FindClose(h_find_);
+		}
+	}
+
+	directory_iterator& operator++()
+	{
+		step();
+		return *this;
+	}
+
+	path_info* operator-> ()
+	{
+		return &path_info_;
+	}
+
+	bool operator!=(const directory_iterator& other)
+	{
+		return h_find_ != other.h_find_;
+	}
+
+protected:
+	bool step()
+	{
+		if(do_step()) {
+			return skip_dots();
+		}
+		return false;
+	}
+
+	bool do_step()
+	{
+		if(h_find_ != INVALID_HANDLE_VALUE) {
+			bool result = FindNextFileW(h_find_, &find_data_) == TRUE;
+			if(!result) {
+				FindClose(h_find_);
+				h_find_ = INVALID_HANDLE_VALUE;
+			}
+			return result;
+		}
+		return false;
+	}
+
+	bool skip_dots()
+	{
+		while(wcscmp(find_data_.cFileName, L".") == 0 ||
+		      wcscmp(find_data_.cFileName, L"..") == 0)
+		{
+			if(!do_step()) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	string path_;
+	path_info path_info_;
+	WIN32_FIND_DATAW find_data_;
+	HANDLE h_find_;
+};
+#else  /* _WIN32 */
+
+class directory_iterator {
+public:
+	class path_info {
+	public:
+		path_info(const string& path)
+		: path_(path)
+		{
+		}
 
-static string from_boost(const boost::filesystem::path& path)
+		string path() {
+			return path_join(path_, entry_->d_name);
+		}
+
+		void current_entry_set(const struct dirent *entry)
+		{
+			entry_ = entry;
+		}
+	protected:
+		const string& path_;
+		const struct dirent *entry_;
+	};
+
+	directory_iterator()
+	: path_info_(""),
+	  name_list_(NULL),
+	  num_entries_(-1),
+	  cur_entry_(-1)
+	{
+	}
+
+	directory_iterator(const string& path)
+	: path_(path),
+	  path_info_(path_),
+	  cur_entry_(0)
+	{
+		num_entries_ = scandir(path.c_str(),
+		                       &name_list_,
+		                       NULL,
+		                       alphasort);
+		if(num_entries_ < 0) {
+			perror("scandir");
+		}
+		else {
+			skip_dots();
+		}
+	}
+
+	~directory_iterator()
+	{
+		destroy_name_list();
+	}
+
+	directory_iterator& operator++()
+	{
+		step();
+		return *this;
+	}
+
+	path_info* operator-> ()
+	{
+		path_info_.current_entry_set(name_list_[cur_entry_]);
+		return &path_info_;
+	}
+
+	bool operator!=(const directory_iterator& other)
+	{
+		return name_list_ != other.name_list_;
+	}
+
+protected:
+	bool step()
+	{
+		if(do_step()) {
+			return skip_dots();
+		}
+		return false;
+	}
+
+	bool do_step()
+	{
+		++cur_entry_;
+		if(cur_entry_ >= num_entries_) {
+			destroy_name_list();
+			return false;
+		}
+		return true;
+	}
+
+	/* Skip . and .. folders. */
+	bool skip_dots()
+	{
+		while(strcmp(name_list_[cur_entry_]->d_name, ".") == 0 ||
+		      strcmp(name_list_[cur_entry_]->d_name, "..") == 0)
+		{
+			if(!step()) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	void destroy_name_list()
+	{
+		if(name_list_ == NULL) {
+			return;
+		}
+		for(int i = 0; i < num_entries_; ++i) {
+			free(name_list_[i]);
+		}
+		free(name_list_);
+		name_list_ = NULL;
+	}
+
+	string path_;
+	path_info path_info_;
+	struct dirent **name_list_;
+	int num_entries_, cur_entry_;
+};
+
+#endif  /* _WIN32 */
+
+size_t find_last_slash(const string& path)
 {
-	return path.string().c_str();
+	for(size_t i = 0; i < path.size(); ++i) {
+		size_t index = path.size() - 1 - i;
+#ifdef _WIN32
+		if(path[index] == DIR_SEP || path[index] == DIR_SEP_ALT)
+#else
+		if(path[index] == DIR_SEP)
+#endif
+		{
+			return index;
+		}
+	}
+	return string::npos;
 }
 
+}  /* namespace */
+
 static char *path_specials(const string& sub)
 {
 	static bool env_init = false;
@@ -90,49 +359,237 @@ string path_user_get(const string& sub)
 
 string path_filename(const string& path)
 {
-	return from_boost(to_boost(path).filename());
+	size_t index = find_last_slash(path);
+	if(index != string::npos) {
+		/* Corner cases to match boost behavior. */
+#ifndef _WIN32
+		if(index == 0 && path.size() == 1) {
+			return path;
+		}
+#endif
+		if(index == path.size() - 1) {
+#ifdef _WIN32
+			if(index == 2) {
+				return string(1, DIR_SEP);
+			}
+#endif
+			return ".";
+		}
+		return path.substr(index + 1, path.size() - index - 1);
+	}
+	return path;
 }
 
 string path_dirname(const string& path)
 {
-	return from_boost(to_boost(path).parent_path());
+	size_t index = find_last_slash(path);
+	if(index != string::npos) {
+#ifndef _WIN32
+		if(index == 0 && path.size() > 1) {
+			return string(1, DIR_SEP);
+		}
+#endif
+		return path.substr(0, index);
+	}
+	return "";
 }
 
 string path_join(const string& dir, const string& file)
 {
-	return from_boost((to_boost(dir) / to_boost(file)));
+	if(dir.size() == 0) {
+		return file;
+	}
+	if(file.size() == 0) {
+		return dir;
+	}
+	string result = dir;
+#ifndef _WIN32
+	if(result[result.size() - 1] != DIR_SEP &&
+	   file[0] != DIR_SEP)
+#else
+	if(result[result.size() - 1] != DIR_SEP &&
+	   result[result.size() - 1] != DIR_SEP_ALT &&
+	   file[0] != DIR_SEP &&
+	   file[0] != DIR_SEP_ALT)
+#endif
+	{
+		result += DIR_SEP;
+	}
+	result += file;
+	return result;
 }
 
 string path_escape(const string& path)
 {
 	string result = path;
-	boost::replace_all(result, " ", "\\ ");
+	string_replace(result, " ", "\\ ");
 	return result;
 }
 
 bool path_is_relative(const string& path)
 {
-	return to_boost(path).is_relative();
+#ifdef _WIN32
+#  ifdef HAVE_SHLWAPI_H
+	return PathIsRelative(path.c_str());
+#  else  /* HAVE_SHLWAPI_H */
+	if(path.size() >= 3) {
+		return !(((path[0] >= 'a' && path[0] <= 'z') ||
+		         (path[0] >= 'A' && path[0] <= 'Z')) &&
+		         path[1] == ':' && path[2] == DIR_SEP);
+	}
+	return true;
+#  endif  /* HAVE_SHLWAPI_H */
+#else  /* _WIN32 */
+	if(path.size() == 0) {
+		return 1;
+	}
+	return path[0] != DIR_SEP;
+#endif  /* _WIN32 */
+}
+
+#ifdef _WIN32
+/* Add a slash if the UNC path points to a share. */
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list