Browse Source

Moving code around and renaming files.

Branimir Karadžić 8 years ago
parent
commit
d4906fd3bd

+ 27 - 1
include/bx/allocator.h

@@ -53,7 +53,33 @@ namespace bx
 		/// @param[in] _align Alignment.
 		/// @param[in] _file Debug file path info.
 		/// @param[in] _line Debug file line info.
-		virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) = 0;
+		virtual void* realloc(
+			  void* _ptr
+			, size_t _size
+			, size_t _align
+			, const char* _file
+			, uint32_t _line
+			) = 0;
+	};
+
+	///
+	class DefaultAllocator : public AllocatorI
+	{
+	public:
+		///
+		DefaultAllocator();
+
+		///
+		virtual ~DefaultAllocator();
+
+		///
+		virtual void* realloc(
+			  void* _ptr
+			, size_t _size
+			, size_t _align
+			, const char* _file
+			, uint32_t _line
+			) override;
 	};
 
 	/// Check if pointer is aligned. _align must be power of two.

+ 0 - 151
include/bx/crtimpl.h

@@ -1,151 +0,0 @@
-/*
- * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
- */
-
-#ifndef BX_CRTIMPL_H_HEADER_GUARD
-#define BX_CRTIMPL_H_HEADER_GUARD
-
-#include "allocator.h"
-#include "readerwriter.h"
-
-namespace bx
-{
-	///
-	class DefaultAllocator : public AllocatorI
-	{
-	public:
-		///
-		DefaultAllocator();
-
-		///
-		virtual ~DefaultAllocator();
-
-		///
-		virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) override;
-	};
-
-	///
-	ReaderI* getStdIn();
-
-	///
-	WriterI* getStdOut();
-
-	///
-	WriterI* getStdErr();
-
-	///
-	class FileReader : public FileReaderI
-	{
-	public:
-		///
-		FileReader();
-
-		///
-		virtual ~FileReader();
-
-		///
-		virtual bool open(const FilePath& _filePath, Error* _err) override;
-
-		///
-		virtual void close() override;
-
-		///
-		virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) override;
-
-		///
-		virtual int32_t read(void* _data, int32_t _size, Error* _err) override;
-
-	private:
-		BX_ALIGN_DECL(16, uint8_t) m_internal[64];
-	};
-
-	///
-	class FileWriter : public FileWriterI
-	{
-	public:
-		///
-		FileWriter();
-
-		///
-		virtual ~FileWriter();
-
-		///
-		virtual bool open(const FilePath& _filePath, bool _append, Error* _err) override;
-
-		///
-		virtual void close() override;
-
-		///
-		virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) override;
-
-		///
-		virtual int32_t write(const void* _data, int32_t _size, Error* _err) override;
-
-	private:
-		BX_ALIGN_DECL(16, uint8_t) m_internal[64];
-	};
-
-	///
-	class ProcessReader
-		: public ProcessOpenI
-		, public CloserI
-		, public ReaderI
-	{
-	public:
-		///
-		ProcessReader();
-
-		///
-		~ProcessReader();
-
-		///
-		virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err) override;
-
-		///
-		virtual void close() override;
-
-		///
-		virtual int32_t read(void* _data, int32_t _size, Error* _err) override;
-
-		///
-		int32_t getExitCode() const;
-
-	private:
-		void* m_file;
-		int32_t m_exitCode;
-	};
-
-	///
-	class ProcessWriter
-		: public ProcessOpenI
-		, public CloserI
-		, public WriterI
-	{
-	public:
-		///
-		ProcessWriter();
-
-		///
-		~ProcessWriter();
-
-		///
-		virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err) override;
-
-		///
-		virtual void close() override;
-
-		///
-		virtual int32_t write(const void* _data, int32_t _size, Error* _err) override;
-
-		///
-		int32_t getExitCode() const;
-
-	private:
-		void* m_file;
-		int32_t m_exitCode;
-	};
-
-} // namespace bx
-
-#endif // BX_CRTIMPL_H_HEADER_GUARD

+ 1 - 1
include/bx/easing.h

@@ -6,7 +6,7 @@
 #ifndef BX_EASING_H_HEADER_GUARD
 #define BX_EASING_H_HEADER_GUARD
 
-#include "fpumath.h"
+#include "math.h"
 
 // Reference:
 // http://easings.net/

+ 95 - 0
include/bx/file.h

@@ -0,0 +1,95 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_FILE_H_HEADER_GUARD
+#define BX_FILE_H_HEADER_GUARD
+
+#include "filepath.h"
+#include "readerwriter.h"
+
+namespace bx
+{
+	///
+	ReaderI* getStdIn();
+
+	///
+	WriterI* getStdOut();
+
+	///
+	WriterI* getStdErr();
+
+	///
+	class FileReader : public FileReaderI
+	{
+	public:
+		///
+		FileReader();
+
+		///
+		virtual ~FileReader();
+
+		///
+		virtual bool open(const FilePath& _filePath, Error* _err) override;
+
+		///
+		virtual void close() override;
+
+		///
+		virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) override;
+
+		///
+		virtual int32_t read(void* _data, int32_t _size, Error* _err) override;
+
+	private:
+		BX_ALIGN_DECL(16, uint8_t) m_internal[64];
+	};
+
+	///
+	class FileWriter : public FileWriterI
+	{
+	public:
+		///
+		FileWriter();
+
+		///
+		virtual ~FileWriter();
+
+		///
+		virtual bool open(const FilePath& _filePath, bool _append, Error* _err) override;
+
+		///
+		virtual void close() override;
+
+		///
+		virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) override;
+
+		///
+		virtual int32_t write(const void* _data, int32_t _size, Error* _err) override;
+
+	private:
+		BX_ALIGN_DECL(16, uint8_t) m_internal[64];
+	};
+
+	///
+	struct FileInfo
+	{
+		enum Enum
+		{
+			Regular,
+			Directory,
+
+			Count
+		};
+
+		uint64_t m_size;
+		Enum m_type;
+	};
+
+	///
+	bool stat(const char* _filePath, FileInfo& _fileInfo);
+
+} // namespace bx
+
+#endif // BX_FILE_H_HEADER_GUARD

+ 7 - 0
include/bx/filepath.h

@@ -11,6 +11,7 @@
 namespace bx
 {
 	const int32_t kMaxFilePath = 1024;
+	struct TempDir { enum Enum { Tag }; };
 
 	/// FilePath parser and helper.
 	///
@@ -27,6 +28,9 @@ namespace bx
 		///
 		FilePath();
 
+		///
+		FilePath(TempDir::Enum);
+
 		///
 		FilePath(const char* _str);
 
@@ -36,6 +40,9 @@ namespace bx
 		///
 		FilePath& operator=(const StringView& _rhs);
 
+		///
+		void set(TempDir::Enum);
+
 		///
 		void set(const StringView& _str);
 

+ 0 - 0
include/bx/inline/fpumath.inl → include/bx/inline/math.inl


+ 1 - 1
include/bx/fpumath.h → include/bx/math.h

@@ -488,6 +488,6 @@ namespace bx
 
 } // namespace bx
 
-#include "inline/fpumath.inl"
+#include "inline/math.inl"
 
 #endif // BX_FPU_MATH_H_HEADER_GUARD

+ 0 - 20
include/bx/os.h

@@ -18,20 +18,6 @@
 
 namespace bx
 {
-	struct FileInfo
-	{
-		enum Enum
-		{
-			Regular,
-			Directory,
-
-			Count
-		};
-
-		uint64_t m_size;
-		Enum m_type;
-	};
-
 	///
 	void sleep(uint32_t _ms);
 
@@ -68,12 +54,6 @@ namespace bx
 	///
 	char* pwd(char* _buffer, uint32_t _size);
 
-	///
-	bool getTempPath(char* _out, uint32_t* _inOutSize);
-
-	///
-	bool stat(const char* _filePath, FileInfo& _fileInfo);
-
 	///
 	void* exec(const char* const* _argv);
 

+ 1 - 1
include/bx/pixelformat.h

@@ -6,7 +6,7 @@
 #ifndef BX_PIXEL_FORMAT_H_HEADER_GUARD
 #define BX_PIXEL_FORMAT_H_HEADER_GUARD
 
-#include "fpumath.h"
+#include "math.h"
 #include "uint32_t.h"
 
 namespace bx

+ 75 - 0
include/bx/process.h

@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_PROCESS_H_HEADER_GUARD
+#define BX_PROCESS_H_HEADER_GUARD
+
+#include "readerwriter.h"
+
+namespace bx
+{
+	///
+	class ProcessReader
+		: public ProcessOpenI
+		, public CloserI
+		, public ReaderI
+	{
+	public:
+		///
+		ProcessReader();
+
+		///
+		~ProcessReader();
+
+		///
+		virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err) override;
+
+		///
+		virtual void close() override;
+
+		///
+		virtual int32_t read(void* _data, int32_t _size, Error* _err) override;
+
+		///
+		int32_t getExitCode() const;
+
+	private:
+		void* m_file;
+		int32_t m_exitCode;
+	};
+
+	///
+	class ProcessWriter
+		: public ProcessOpenI
+		, public CloserI
+		, public WriterI
+	{
+	public:
+		///
+		ProcessWriter();
+
+		///
+		~ProcessWriter();
+
+		///
+		virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err) override;
+
+		///
+		virtual void close() override;
+
+		///
+		virtual int32_t write(const void* _data, int32_t _size, Error* _err) override;
+
+		///
+		int32_t getExitCode() const;
+
+	private:
+		void* m_file;
+		int32_t m_exitCode;
+	};
+
+} // namespace bx
+
+#endif // BX_PROCESS_H_HEADER_GUARD

+ 1 - 1
include/bx/rng.h

@@ -7,7 +7,7 @@
 #define BX_RNG_H_HEADER_GUARD
 
 #include "bx.h"
-#include "fpumath.h"
+#include "math.h"
 #include "uint32_t.h"
 
 namespace bx

+ 1 - 1
include/bx/simd_t.h

@@ -7,7 +7,7 @@
 #define BX_SIMD_T_H_HEADER_GUARD
 
 #include "bx.h"
-#include "fpumath.h"
+#include "math.h"
 
 #define BX_SIMD_FORCE_INLINE BX_FORCE_INLINE
 #define BX_SIMD_INLINE inline

+ 74 - 0
src/allocator.cpp

@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/allocator.h>
+
+#include <malloc.h>
+
+#ifndef BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT
+#	define BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT 8
+#endif // BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT
+
+namespace bx
+{
+	DefaultAllocator::DefaultAllocator()
+	{
+	}
+
+	DefaultAllocator::~DefaultAllocator()
+	{
+	}
+
+	void* DefaultAllocator::realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line)
+	{
+		if (0 == _size)
+		{
+			if (NULL != _ptr)
+			{
+				if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
+				{
+					::free(_ptr);
+					return NULL;
+				}
+
+#	if BX_COMPILER_MSVC
+				BX_UNUSED(_file, _line);
+				_aligned_free(_ptr);
+#	else
+				bx::alignedFree(this, _ptr, _align, _file, _line);
+#	endif // BX_
+			}
+
+			return NULL;
+		}
+		else if (NULL == _ptr)
+		{
+			if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
+			{
+				return ::malloc(_size);
+			}
+
+#	if BX_COMPILER_MSVC
+			BX_UNUSED(_file, _line);
+			return _aligned_malloc(_size, _align);
+#	else
+			return bx::alignedAlloc(this, _size, _align, _file, _line);
+#	endif // BX_
+		}
+
+		if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
+		{
+			return ::realloc(_ptr, _size);
+		}
+
+#	if BX_COMPILER_MSVC
+		BX_UNUSED(_file, _line);
+		return _aligned_realloc(_ptr, _size, _align);
+#	else
+		return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line);
+#	endif // BX_
+	}
+
+} // namespace bx

+ 1 - 1
src/amalgamated.cpp

@@ -9,7 +9,7 @@
 #include "crtnone.cpp"
 #include "debug.cpp"
 #include "dtoa.cpp"
-#include "fpumath.cpp"
+#include "math.cpp"
 #include "mutex.cpp"
 #include "os.cpp"
 #include "semaphore.cpp"

+ 1 - 1
src/dtoa.cpp

@@ -4,7 +4,7 @@
  */
 
 #include <bx/cpu.h>
-#include <bx/fpumath.h>
+#include <bx/math.h>
 #include <bx/string.h>
 #include <bx/uint32_t.h>
 

+ 24 - 197
src/crtimpl.cpp → src/file.cpp

@@ -3,10 +3,10 @@
  * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  */
 
-#include <bx/crtimpl.h>
+#include <bx/file.h>
 
 #include <stdio.h>
-#include <malloc.h>
+#include <sys/stat.h>
 
 #ifndef BX_CONFIG_CRT_FILE_READER_WRITER
 #	define BX_CONFIG_CRT_FILE_READER_WRITER !(0 \
@@ -14,80 +14,8 @@
 			)
 #endif // BX_CONFIG_CRT_FILE_READER_WRITER
 
-#ifndef BX_CONFIG_CRT_PROCESS
-#	define BX_CONFIG_CRT_PROCESS !(0  \
-			|| BX_CRT_NONE            \
-			|| BX_PLATFORM_EMSCRIPTEN \
-			|| BX_PLATFORM_PS4        \
-			|| BX_PLATFORM_WINRT      \
-			|| BX_PLATFORM_XBOXONE    \
-			)
-#endif // BX_CONFIG_CRT_PROCESS
-
-#ifndef BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT
-#	define BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT 8
-#endif // BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT
-
 namespace bx
 {
-	DefaultAllocator::DefaultAllocator()
-	{
-	}
-
-	DefaultAllocator::~DefaultAllocator()
-	{
-	}
-
-	void* DefaultAllocator::realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line)
-	{
-		if (0 == _size)
-		{
-			if (NULL != _ptr)
-			{
-				if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
-				{
-					::free(_ptr);
-					return NULL;
-				}
-
-#	if BX_COMPILER_MSVC
-				BX_UNUSED(_file, _line);
-				_aligned_free(_ptr);
-#	else
-				bx::alignedFree(this, _ptr, _align, _file, _line);
-#	endif // BX_
-			}
-
-			return NULL;
-		}
-		else if (NULL == _ptr)
-		{
-			if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
-			{
-				return ::malloc(_size);
-			}
-
-#	if BX_COMPILER_MSVC
-			BX_UNUSED(_file, _line);
-			return _aligned_malloc(_size, _align);
-#	else
-			return bx::alignedAlloc(this, _size, _align, _file, _line);
-#	endif // BX_
-		}
-
-		if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
-		{
-			return ::realloc(_ptr, _size);
-		}
-
-#	if BX_COMPILER_MSVC
-		BX_UNUSED(_file, _line);
-		return _aligned_realloc(_ptr, _size, _align);
-#	else
-		return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line);
-#	endif // BX_
-	}
-
 #if BX_CONFIG_CRT_FILE_READER_WRITER
 
 #	if BX_CRT_MSVC
@@ -423,150 +351,49 @@ namespace bx
 		return &s_stdOut;
 	}
 
-#if BX_CONFIG_CRT_PROCESS
-
-#if BX_CRT_MSVC
-#	define popen  _popen
-#	define pclose _pclose
-#endif // BX_CRT_MSVC
-
-	ProcessReader::ProcessReader()
-		: m_file(NULL)
-	{
-	}
-
-	ProcessReader::~ProcessReader()
+	bool stat(const char* _filePath, FileInfo& _fileInfo)
 	{
-		BX_CHECK(NULL == m_file, "Process not closed!");
-	}
+		_fileInfo.m_size = 0;
+		_fileInfo.m_type = FileInfo::Count;
 
-	bool ProcessReader::open(const FilePath& _filePath, const StringView& _args, Error* _err)
-	{
-		BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+#if BX_COMPILER_MSVC
+		struct ::_stat64 st;
+		int32_t result = ::_stat64(_filePath, &st);
 
-		if (NULL != m_file)
+		if (0 != result)
 		{
-			BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessReader: File is already open.");
 			return false;
 		}
 
-		char tmp[kMaxFilePath*2];
-		strCopy(tmp, BX_COUNTOF(tmp), _filePath.get() );
-		strCat(tmp, BX_COUNTOF(tmp), " ");
-		strCat(tmp, BX_COUNTOF(tmp), _args);
-
-		m_file = popen(tmp, "r");
-		if (NULL == m_file)
+		if (0 != (st.st_mode & _S_IFREG) )
 		{
-			BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process.");
-			return false;
+			_fileInfo.m_type = FileInfo::Regular;
 		}
-
-		return true;
-	}
-
-	void ProcessReader::close()
-	{
-		BX_CHECK(NULL != m_file, "Process not open!");
-		FILE* file = (FILE*)m_file;
-		m_exitCode = pclose(file);
-		m_file = NULL;
-	}
-
-	int32_t ProcessReader::read(void* _data, int32_t _size, Error* _err)
-	{
-		BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
-
-		FILE* file = (FILE*)m_file;
-		int32_t size = (int32_t)fread(_data, 1, _size, file);
-		if (size != _size)
+		else if (0 != (st.st_mode & _S_IFDIR) )
 		{
-			if (0 != feof(file) )
-			{
-				BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "ProcessReader: EOF.");
-			}
-			else if (0 != ferror(file) )
-			{
-				BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "ProcessReader: read error.");
-			}
-
-			return size >= 0 ? size : 0;
+			_fileInfo.m_type = FileInfo::Directory;
 		}
-
-		return size;
-	}
-
-	int32_t ProcessReader::getExitCode() const
-	{
-		return m_exitCode;
-	}
-
-	ProcessWriter::ProcessWriter()
-		: m_file(NULL)
-	{
-	}
-
-	ProcessWriter::~ProcessWriter()
-	{
-		BX_CHECK(NULL == m_file, "Process not closed!");
-	}
-
-	bool ProcessWriter::open(const FilePath& _filePath, const StringView& _args, Error* _err)
-	{
-		BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
-
-		if (NULL != m_file)
+#else
+		struct ::stat st;
+		int32_t result = ::stat(_filePath, &st);
+		if (0 != result)
 		{
-			BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessWriter: File is already open.");
 			return false;
 		}
 
-		char tmp[kMaxFilePath*2];
-		strCopy(tmp, BX_COUNTOF(tmp), _filePath.get() );
-		strCat(tmp, BX_COUNTOF(tmp), " ");
-		strCat(tmp, BX_COUNTOF(tmp), _args);
-
-		m_file = popen(tmp, "w");
-		if (NULL == m_file)
+		if (0 != (st.st_mode & S_IFREG) )
 		{
-			BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process.");
-			return false;
+			_fileInfo.m_type = FileInfo::Regular;
 		}
-
-		return true;
-	}
-
-	void ProcessWriter::close()
-	{
-		BX_CHECK(NULL != m_file, "Process not open!");
-		FILE* file = (FILE*)m_file;
-		m_exitCode = pclose(file);
-		m_file = NULL;
-	}
-
-	int32_t ProcessWriter::write(const void* _data, int32_t _size, Error* _err)
-	{
-		BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
-
-		FILE* file = (FILE*)m_file;
-		int32_t size = (int32_t)fwrite(_data, 1, _size, file);
-		if (size != _size)
+		else if (0 != (st.st_mode & S_IFDIR) )
 		{
-			if (0 != ferror(file) )
-			{
-				BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "ProcessWriter: write error.");
-			}
-
-			return size >= 0 ? size : 0;
+			_fileInfo.m_type = FileInfo::Directory;
 		}
+#endif // BX_COMPILER_MSVC
 
-		return size;
-	}
+		_fileInfo.m_size = st.st_size;
 
-	int32_t ProcessWriter::getExitCode() const
-	{
-		return m_exitCode;
+		return true;
 	}
-#endif // BX_CONFIG_CRT_PROCESS
 
 } // namespace bx

+ 61 - 1
src/filepath.cpp

@@ -3,7 +3,8 @@
  * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  */
 
-#include <bx/filepath.h>
+#include <bx/file.h>
+#include <bx/os.h>
 #include <bx/readerwriter.h>
 
 namespace bx
@@ -128,11 +129,62 @@ namespace bx
 		return size;
 	}
 
+	static bool getTempPath(char* _out, uint32_t* _inOutSize)
+	{
+#if BX_PLATFORM_WINDOWS
+		uint32_t len = ::GetTempPathA(*_inOutSize, _out);
+		bool result = len != 0 && len < *_inOutSize;
+		*_inOutSize = len;
+		return result;
+#else
+		static const char* s_tmp[] =
+		{
+			"TMPDIR",
+			"TMP",
+			"TEMP",
+			"TEMPDIR",
+
+			NULL
+		};
+
+		for (const char** tmp = s_tmp; *tmp != NULL; ++tmp)
+		{
+			uint32_t len = *_inOutSize;
+			*_out = '\0';
+			bool result = getenv(*tmp, _out, &len);
+
+			if (result
+			&&  len != 0
+			&&  len < *_inOutSize)
+			{
+				*_inOutSize = len;
+				return result;
+			}
+		}
+
+		FileInfo fi;
+		if (stat("/tmp", fi)
+		&&  FileInfo::Directory == fi.m_type)
+		{
+			strCopy(_out, *_inOutSize, "/tmp");
+			*_inOutSize = 4;
+			return true;
+		}
+
+		return false;
+#endif // BX_PLATFORM_*
+	}
+
 	FilePath::FilePath()
 	{
 		set("");
 	}
 
+	FilePath::FilePath(TempDir::Enum)
+	{
+		set(TempDir::Tag);
+	}
+
 	FilePath::FilePath(const char* _rhs)
 	{
 		set(_rhs);
@@ -149,6 +201,14 @@ namespace bx
 		return *this;
 	}
 
+	void FilePath::set(TempDir::Enum)
+	{
+		char tmp[kMaxFilePath];
+		uint32_t len = BX_COUNTOF(tmp);
+		getTempPath(tmp, &len);
+		set(StringView(tmp, len) );
+	}
+
 	void FilePath::set(const StringView& _filePath)
 	{
 		normalizeFilePath(

+ 1 - 1
src/fpumath.cpp → src/math.cpp

@@ -3,7 +3,7 @@
  * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  */
 
-#include <bx/fpumath.h>
+#include <bx/math.h>
 #include <math.h>
 
 namespace bx

+ 1 - 93
src/os.cpp

@@ -3,14 +3,13 @@
  * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  */
 
+#include <bx/string.h>
 #include <bx/os.h>
 #include <bx/uint32_t.h>
-#include <bx/string.h>
 
 #if !BX_PLATFORM_NONE
 
 #include <stdio.h>
-#include <sys/stat.h>
 
 #if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
 #	include <windows.h>
@@ -298,97 +297,6 @@ namespace bx
 #endif // BX_COMPILER_
 	}
 
-	bool getTempPath(char* _out, uint32_t* _inOutSize)
-	{
-#if BX_PLATFORM_WINDOWS
-		uint32_t len = ::GetTempPathA(*_inOutSize, _out);
-		bool result = len != 0 && len < *_inOutSize;
-		*_inOutSize = len;
-		return result;
-#else
-		static const char* s_tmp[] =
-		{
-			"TMPDIR",
-			"TMP",
-			"TEMP",
-			"TEMPDIR",
-
-			NULL
-		};
-
-		for (const char** tmp = s_tmp; *tmp != NULL; ++tmp)
-		{
-			uint32_t len = *_inOutSize;
-			*_out = '\0';
-			bool result = getenv(*tmp, _out, &len);
-
-			if (result
-			&&  len != 0
-			&&  len < *_inOutSize)
-			{
-				*_inOutSize = len;
-				return result;
-			}
-		}
-
-		FileInfo fi;
-		if (stat("/tmp", fi)
-		&&  FileInfo::Directory == fi.m_type)
-		{
-			strCopy(_out, *_inOutSize, "/tmp");
-			*_inOutSize = 4;
-			return true;
-		}
-
-		return false;
-#endif // BX_PLATFORM_*
-	}
-
-	bool stat(const char* _filePath, FileInfo& _fileInfo)
-	{
-		_fileInfo.m_size = 0;
-		_fileInfo.m_type = FileInfo::Count;
-
-#if BX_COMPILER_MSVC
-		struct ::_stat64 st;
-		int32_t result = ::_stat64(_filePath, &st);
-
-		if (0 != result)
-		{
-			return false;
-		}
-
-		if (0 != (st.st_mode & _S_IFREG) )
-		{
-			_fileInfo.m_type = FileInfo::Regular;
-		}
-		else if (0 != (st.st_mode & _S_IFDIR) )
-		{
-			_fileInfo.m_type = FileInfo::Directory;
-		}
-#else
-		struct ::stat st;
-		int32_t result = ::stat(_filePath, &st);
-		if (0 != result)
-		{
-			return false;
-		}
-
-		if (0 != (st.st_mode & S_IFREG) )
-		{
-			_fileInfo.m_type = FileInfo::Regular;
-		}
-		else if (0 != (st.st_mode & S_IFDIR) )
-		{
-			_fileInfo.m_type = FileInfo::Directory;
-		}
-#endif // BX_COMPILER_MSVC
-
-		_fileInfo.m_size = st.st_size;
-
-		return true;
-	}
-
 	void* exec(const char* const* _argv)
 	{
 #if BX_PLATFORM_LINUX || BX_PLATFORM_HURD

+ 168 - 0
src/process.cpp

@@ -0,0 +1,168 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/process.h>
+
+#include <stdio.h>
+
+#ifndef BX_CONFIG_CRT_PROCESS
+#	define BX_CONFIG_CRT_PROCESS !(0  \
+			|| BX_CRT_NONE            \
+			|| BX_PLATFORM_EMSCRIPTEN \
+			|| BX_PLATFORM_PS4        \
+			|| BX_PLATFORM_WINRT      \
+			|| BX_PLATFORM_XBOXONE    \
+			)
+#endif // BX_CONFIG_CRT_PROCESS
+
+namespace bx
+{
+#if BX_CONFIG_CRT_PROCESS
+
+#if BX_CRT_MSVC
+#	define popen  _popen
+#	define pclose _pclose
+#endif // BX_CRT_MSVC
+
+	ProcessReader::ProcessReader()
+		: m_file(NULL)
+	{
+	}
+
+	ProcessReader::~ProcessReader()
+	{
+		BX_CHECK(NULL == m_file, "Process not closed!");
+	}
+
+	bool ProcessReader::open(const FilePath& _filePath, const StringView& _args, Error* _err)
+	{
+		BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+		if (NULL != m_file)
+		{
+			BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessReader: File is already open.");
+			return false;
+		}
+
+		char tmp[kMaxFilePath*2];
+		strCopy(tmp, BX_COUNTOF(tmp), _filePath.get() );
+		strCat(tmp, BX_COUNTOF(tmp), " ");
+		strCat(tmp, BX_COUNTOF(tmp), _args);
+
+		m_file = popen(tmp, "r");
+		if (NULL == m_file)
+		{
+			BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process.");
+			return false;
+		}
+
+		return true;
+	}
+
+	void ProcessReader::close()
+	{
+		BX_CHECK(NULL != m_file, "Process not open!");
+		FILE* file = (FILE*)m_file;
+		m_exitCode = pclose(file);
+		m_file = NULL;
+	}
+
+	int32_t ProcessReader::read(void* _data, int32_t _size, Error* _err)
+	{
+		BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
+
+		FILE* file = (FILE*)m_file;
+		int32_t size = (int32_t)fread(_data, 1, _size, file);
+		if (size != _size)
+		{
+			if (0 != feof(file) )
+			{
+				BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "ProcessReader: EOF.");
+			}
+			else if (0 != ferror(file) )
+			{
+				BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "ProcessReader: read error.");
+			}
+
+			return size >= 0 ? size : 0;
+		}
+
+		return size;
+	}
+
+	int32_t ProcessReader::getExitCode() const
+	{
+		return m_exitCode;
+	}
+
+	ProcessWriter::ProcessWriter()
+		: m_file(NULL)
+	{
+	}
+
+	ProcessWriter::~ProcessWriter()
+	{
+		BX_CHECK(NULL == m_file, "Process not closed!");
+	}
+
+	bool ProcessWriter::open(const FilePath& _filePath, const StringView& _args, Error* _err)
+	{
+		BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+
+		if (NULL != m_file)
+		{
+			BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessWriter: File is already open.");
+			return false;
+		}
+
+		char tmp[kMaxFilePath*2];
+		strCopy(tmp, BX_COUNTOF(tmp), _filePath.get() );
+		strCat(tmp, BX_COUNTOF(tmp), " ");
+		strCat(tmp, BX_COUNTOF(tmp), _args);
+
+		m_file = popen(tmp, "w");
+		if (NULL == m_file)
+		{
+			BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process.");
+			return false;
+		}
+
+		return true;
+	}
+
+	void ProcessWriter::close()
+	{
+		BX_CHECK(NULL != m_file, "Process not open!");
+		FILE* file = (FILE*)m_file;
+		m_exitCode = pclose(file);
+		m_file = NULL;
+	}
+
+	int32_t ProcessWriter::write(const void* _data, int32_t _size, Error* _err)
+	{
+		BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
+
+		FILE* file = (FILE*)m_file;
+		int32_t size = (int32_t)fwrite(_data, 1, _size, file);
+		if (size != _size)
+		{
+			if (0 != ferror(file) )
+			{
+				BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "ProcessWriter: write error.");
+			}
+
+			return size >= 0 ? size : 0;
+		}
+
+		return size;
+	}
+
+	int32_t ProcessWriter::getExitCode() const
+	{
+		return m_exitCode;
+	}
+#endif // BX_CONFIG_CRT_PROCESS
+
+} // namespace bx

+ 6 - 0
tests/filepath_test.cpp

@@ -116,3 +116,9 @@ TEST_CASE("FilePath", "")
 		REQUIRE(test.absolute == fp.isAbsolute() );
 	};
 }
+
+TEST_CASE("FilePath temp", "")
+{
+	bx::FilePath tmp(bx::TempDir::Tag);
+	REQUIRE(0 != bx::strCmp(".", tmp.getPath() ) );
+}

+ 1 - 1
tests/fpumath_test.cpp

@@ -4,7 +4,7 @@
  */
 
 #include "test.h"
-#include <bx/fpumath.h>
+#include <bx/math.h>
 
 #if !BX_COMPILER_MSVC || BX_COMPILER_MSVC >= 1800
 #include <cmath>

+ 0 - 7
tests/os_test.cpp

@@ -14,13 +14,6 @@ TEST_CASE("getProcessMemoryUsed", "")
 //	DBG("bx::getProcessMemoryUsed %d", bx::getProcessMemoryUsed() );
 }
 
-TEST_CASE("getTempPath", "")
-{
-	char tmpDir[512];
-	uint32_t len = BX_COUNTOF(tmpDir);
-	REQUIRE(bx::getTempPath(tmpDir, &len) );
-}
-
 #if !BX_PLATFORM_OSX
 TEST_CASE("semaphore_timeout", "")
 {

+ 1 - 1
tests/simd_test.cpp

@@ -5,7 +5,7 @@
 
 #include "test.h"
 #include <bx/simd_t.h>
-#include <bx/fpumath.h>
+#include <bx/math.h>
 #include <bx/string.h>
 
 #if 0

+ 0 - 1
tests/string_test.cpp

@@ -5,7 +5,6 @@
 
 #include "test.h"
 #include <bx/string.h>
-#include <bx/crtimpl.h>
 #include <bx/handlealloc.h>
 
 bx::AllocatorI* g_allocator;