aboutsummaryrefslogtreecommitdiff
path: root/source-common/Utils.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-05-24 21:47:55 -0700
committerrtk0c <[email protected]>2022-05-24 21:47:55 -0700
commitd18a28a9659092952aef70a30a47726e7c16d31a (patch)
treeb1d6304e631961a797225912ed1ef7ee55864f86 /source-common/Utils.cpp
parent123f741e3f5374b93ac39887b62bfa0d66762ae2 (diff)
Changeset: 38 Branch comment: [] Add infrastructure for codegen
Diffstat (limited to 'source-common/Utils.cpp')
-rw-r--r--source-common/Utils.cpp87
1 files changed, 87 insertions, 0 deletions
diff --git a/source-common/Utils.cpp b/source-common/Utils.cpp
new file mode 100644
index 0000000..53b3863
--- /dev/null
+++ b/source-common/Utils.cpp
@@ -0,0 +1,87 @@
+#include "Utils.hpp"
+
+#ifdef _WIN32
+# include <Windows.h>
+#endif
+
+#ifdef _WIN32
+# define BRUSSEL_MODE_STRING(string) L##string
+#else
+# define BRUSSEL_MODE_STRING(string) string
+#endif
+
+#if _WIN32
+using FopenModeString = const wchar_t*;
+#else
+using FopenModeString = const char*;
+#endif
+
+static FopenModeString GetModeString(Utils::IoMode mode, bool binary) {
+ using namespace Utils;
+ if (binary) {
+ switch (mode) {
+ case Read: return BRUSSEL_MODE_STRING("rb");
+ case WriteTruncate: return BRUSSEL_MODE_STRING("wb");
+ case WriteAppend: return BRUSSEL_MODE_STRING("ab");
+ }
+ } else {
+ switch (mode) {
+ case Read: return BRUSSEL_MODE_STRING("r");
+ case WriteTruncate: return BRUSSEL_MODE_STRING("w");
+ case WriteAppend: return BRUSSEL_MODE_STRING("a");
+ }
+ }
+ return nullptr;
+}
+
+FILE* Utils::OpenCstdioFile(const std::filesystem::path& path, IoMode mode, bool binary) {
+#ifdef _WIN32
+ // std::filesystem::path::c_str() returns `const wchar_t*` under Windows, because NT uses UTF-16 natively
+ // NOTE: _wfopen() only affects the type of path parameter, otherwise the file stream created is identical to the one by fopen()
+ return _wfopen(path.c_str(), ::GetModeString(mode, binary));
+#else
+ return fopen(path.c_str(), ::GetModeString(mode, binary));
+#endif
+}
+
+FILE* Utils::OpenCstdioFile(const char* path, IoMode mode, bool binary) {
+#ifdef _WIN32
+ // On Windows, fopen() accepts ANSI codepage encoded path, convert our UTF-8 string to UTF-16 to ensure that no matter what the locale is, the path continues to work
+ WCHAR platformPath[MAX_PATH];
+ if (MultiByteToWideChar(CP_UTF8, 0, path, -1, platformPath, MAX_PATH) == 0) {
+ return nullptr;
+ }
+ return _wfopen(platformPath, ::GetModeString(mode, binary));
+#else
+ return fopen(path, ::GetModeString(mode, binary));
+#endif
+}
+
+bool Utils::InRangeInclusive(int n, int lower, int upper) {
+ if (lower > upper) {
+ std::swap(lower, upper);
+ }
+ return n >= lower && n <= upper;
+}
+
+bool Utils::LineContains(glm::ivec2 p1, glm::ivec2 p2, glm::ivec2 candidate) {
+ bool verticalLine = p1.x == p2.x && InRangeInclusive(candidate.x, p1.x, p2.x);
+ bool horizontalLine = p1.y == p2.y && InRangeInclusive(candidate.y, p1.y, p2.y);
+ return verticalLine && horizontalLine;
+}
+
+bool Utils::IsColinear(glm::ivec2 p1, glm::ivec2 p2) {
+ return p1.x == p2.x || p1.y == p2.y;
+}
+
+std::string Utils::MakeRandomNumberedName(const char* tag) {
+ int n = std::rand();
+#define RNG_NAME_PATTERN "Unnamed %s #%d", tag, n
+ // NOTE: does not include null-terminator
+ int size = snprintf(nullptr, 0, RNG_NAME_PATTERN);
+ std::string result;
+ result.resize(size); // std::string::resize handles storage for null-terminator alreaedy
+ snprintf(result.data(), size, RNG_NAME_PATTERN);
+#undef RNG_NAME_PATTERN
+ return result;
+}