Browse Source

FilePath: Added ability to retreive exectuable file path.

Бранимир Караџић 2 years ago
parent
commit
db15e54924
3 changed files with 65 additions and 19 deletions
  1. 4 3
      include/bx/filepath.h
  2. 34 16
      src/filepath.cpp
  3. 27 0
      tests/filepath_test.cpp

+ 4 - 3
include/bx/filepath.h

@@ -23,9 +23,10 @@ namespace bx
 		/// Special OS directories:
 		enum Enum
 		{
-			Current, //!< Current directory.
-			Temp,    //!< Temporary directory.
-			Home,    //!< User's home directory.
+			Current,    //!< Current directory.
+			Executable, //!< Executable file path.
+			Home,       //!< User's home directory.
+			Temp,       //!< Temporary directory.
 
 			Count
 		};

+ 34 - 16
src/filepath.cpp

@@ -16,7 +16,8 @@
 #endif // !BX_CRT_NONE
 
 #if BX_PLATFORM_WINDOWS
-extern "C" __declspec(dllimport) unsigned long __stdcall GetTempPathA(unsigned long _max, char* _ptr);
+extern "C" __declspec(dllimport) unsigned long __stdcall GetModuleFileNameA(void* _module, char* _outFilePath, unsigned long _size);
+extern "C" __declspec(dllimport) unsigned long __stdcall GetTempPathA(unsigned long _max, char* _outFilePath);
 #endif // BX_PLATFORM_WINDOWS
 
 namespace bx
@@ -180,7 +181,7 @@ namespace bx
 		return ::_getcwd(_buffer, (int32_t)_size);
 #else
 		return ::getcwd(_buffer, _size);
-#endif // BX_COMPILER_
+#endif // BX_PLATFORM_*
 	}
 
 	static bool getCurrentPath(char* _out, uint32_t* _inOutSize)
@@ -195,6 +196,29 @@ namespace bx
 		return false;
 	}
 
+	static bool getExecutablePath(char* _out, uint32_t* _inOutSize)
+	{
+#if BX_PLATFORM_WINDOWS
+		uint32_t len = ::GetModuleFileNameA(NULL, _out, *_inOutSize);
+		bool result = len != 0 && len < *_inOutSize;
+		*_inOutSize = len;
+		return result;
+#elif BX_PLATFORM_LINUX
+		char tmp[64];
+		snprintf(tmp, sizeof(tmp), "/proc/%d/exe", getpid() );
+		ssize_t result = readlink(tmp, _out, *_inOutSize);
+
+		if (-1 < result)
+		{
+			*_inOutSize = uint32_t(result);
+			return true;
+		}
+#elif BX_PLATFORM_OSX
+#endif // BX_PLATFORM_*
+
+		return false;
+	}
+
 	static bool getHomePath(char* _out, uint32_t* _inOutSize)
 	{
 		return false
@@ -287,28 +311,22 @@ namespace bx
 
 	void FilePath::set(Dir::Enum _dir)
 	{
+		bool ok = false;
 		char tmp[kMaxFilePath];
 		uint32_t len = BX_COUNTOF(tmp);
 
 		switch (_dir)
 		{
-		case Dir::Current:
-			getCurrentPath(tmp, &len);
-			break;
-
-		case Dir::Temp:
-			getTempPath(tmp, &len);
-			break;
+		case Dir::Current:    ok = getCurrentPath(tmp, &len);    break;
+		case Dir::Executable: ok = getExecutablePath(tmp, &len); break;
+		case Dir::Home:       ok = getHomePath(tmp, &len);       break;
+		case Dir::Temp:       ok = getTempPath(tmp, &len);       break;
 
-		case Dir::Home:
-			getHomePath(tmp, &len);
-			break;
-
-		default:
-			len = 0;
-			break;
+		default: break;
 		}
 
+		len = ok ? len : 0;
+
 		set(StringView(tmp, len) );
 	}
 

+ 27 - 0
tests/filepath_test.cpp

@@ -133,3 +133,30 @@ TEST_CASE("FilePath temp", "[filepath]")
 	REQUIRE(bx::removeAll(tmp, &err) );
 	REQUIRE(err.isOk() );
 }
+
+TEST_CASE("FilePath special", "[filepath]")
+{
+	{
+		bx::FilePath tmp(bx::Dir::Current);
+		bx::StringView sv(tmp);
+		DBG("%S", &sv);
+	}
+
+	{
+		bx::FilePath tmp(bx::Dir::Executable);
+		bx::StringView sv(tmp);
+		DBG("%S", &sv);
+	}
+
+	{
+		bx::FilePath tmp(bx::Dir::Home);
+		bx::StringView sv(tmp);
+		DBG("%S", &sv);
+	}
+
+	{
+		bx::FilePath tmp(bx::Dir::Temp);
+		bx::StringView sv(tmp);
+		DBG("%S", &sv);
+	}
+}