aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-08-22 01:05:05 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-08-22 01:05:05 +0200
commitba0750ff48bcf97ef99602fe27322fa706a93b6b (patch)
tree0a6e0110e1940610266d280e2c857195819ffa1a
parent28b87e4d9c60b49d46b03a19b7b83e23e222087a (diff)
downloadEpisodeBrowser-ba0750ff48bcf97ef99602fe27322fa706a93b6b.tar.gz
Add Buf class.
-rw-r--r--c/util.h45
-rw-r--r--c/win.cpp45
-rw-r--r--c/win.h4
3 files changed, 54 insertions, 40 deletions
diff --git a/c/util.h b/c/util.h
index 1d8d222..698ce10 100644
--- a/c/util.h
+++ b/c/util.h
@@ -4,42 +4,51 @@
#include <algorithm>
#include <cstring>
#include <memory>
+#include <string>
#include <SWI-Prolog.h>
#include <windows.h>
-#define CAT(a, b) a##b
-#define APPLY(a, ...) a(__VA_ARGS__)
-#define UNUSED APPLY(CAT, unused_, __COUNTER__)
+/* Buf is a span-like structure of a buffer and its size. */
+template <typename T>
+struct Buf
+{
+ T* data;
+ size_t size;
+ Buf(T* data, size_t size) : data(data), size(size) {}
+ Buf(std::basic_string<T>& s) : data(s.data()), size(s.capacity()) {}
+ template <size_t N> Buf(T (&data)[N]) : data(data), size(N) {}
+ operator T*() { return data; }
+ T& operator *() { return *data; }
+ T& operator [](size_t i) { return data[i]; }
+};
-/* Format static wide string. */
-template<size_t N, typename... T>
-inline int Swprintf(wchar_t (&buf)[N], const wchar_t* const fmt, T... xs)
+/* Format wide string. */
+template<typename... T>
+inline int Swprintf(Buf<wchar_t> buf, const wchar_t* const fmt, T... xs)
{
- return _snwprintf_s(buf, N, _TRUNCATE, fmt, xs...);
+ return _snwprintf_s(buf, buf.size, _TRUNCATE, fmt, xs...);
}
/* Format static narrow string. */
-template<size_t N, typename... T>
-inline int Sprintf(char (&buf)[N], const char* const fmt, T... xs)
+template<typename... T>
+inline int Sprintf(Buf<char> buf, const char* const fmt, T... xs)
{
- return _snprintf_s(buf, N, _TRUNCATE, fmt, xs...);
+ return _snprintf_s(buf, buf.size, _TRUNCATE, fmt, xs...);
}
/* Copy to static wide string buffer. */
-template <size_t N>
-inline wchar_t* Wcscpy(wchar_t (&dst)[N], const wchar_t* const src)
+inline wchar_t* Wcscpy(Buf<wchar_t> dst, const wchar_t* const src)
{
- const size_t len = std::min(N, wcslen(src)+1);
+ const size_t len = std::min(dst.size, wcslen(src)+1);
memcpy(dst, src, len*sizeof(wchar_t));
dst[len-1] = 0;
return dst;
}
/* Copy to static narrow string buffer. */
-template <size_t N>
-inline char* Strcpy(char (&dst)[N], const char* const src)
+inline char* Strcpy(Buf<char> dst, const char* const src)
{
- const size_t len = std::min(N, strlen(src)+1);
+ const size_t len = std::min(dst.size, strlen(src)+1);
memcpy(dst, src, len);
dst[len-1] = 0;
return dst;
@@ -52,4 +61,8 @@ inline int Cmp(const int a, const int b)
return -1;
}
+#define CAT(a, b) a##b
+#define APPLY(a, ...) a(__VA_ARGS__)
+#define UNUSED APPLY(CAT, unused_, __COUNTER__)
+
#endif
diff --git a/c/win.cpp b/c/win.cpp
index ea47fb0..c7ce7ec 100644
--- a/c/win.cpp
+++ b/c/win.cpp
@@ -1,4 +1,5 @@
#include <utility>
+#include <string>
#include <SWI-Prolog.h>
#include <windows.h>
@@ -7,28 +8,6 @@
#include "win.h"
#include "wcharptr.h"
-void ShowException(const wchar_t* const fmt, const wchar_t* const title, const UINT uType) noexcept
-{
- const wchar_t* what = L"an exception";
- WcharPtr why;
-
- try {
- std::rethrow_exception(std::current_exception());
- } catch (const term_t& t) {
- what = L"a Prolog exception";
- try { why = PlString(t); } catch (...) {}
- } catch (const Win32Error& e) {
- what = L"a Windows error";
- try { why = WcharPtr::Copy(e.What()); } catch (...) {}
- } catch (const std::exception& e) {
- try { why = WcharPtr::FromNarrow(e.what()); } catch (...) {}
- } catch (...) {}
-
- wchar_t msg[512];
- Swprintf(msg, fmt, what, static_cast<wchar_t*>(why));
- EBMessageBox(msg, title, uType);
-}
-
void WithNextWindow(void (*proc)(HWND))
{
/* WithNextWindow uses a CBT hook to call an arbitrary
@@ -103,6 +82,28 @@ int EBMessageBox(const std::wstring_view text, const std::wstring_view caption,
return MessageBox(g_hWnd, text.data(), caption.data(), uType);
}
+void ShowException(const wchar_t* const fmt, const wchar_t* const title, const UINT uType) noexcept
+{
+ const wchar_t* what = L"an exception";
+ WcharPtr why;
+
+ try {
+ std::rethrow_exception(std::current_exception());
+ } catch (const term_t& t) {
+ what = L"a Prolog exception";
+ try { why = PlString(t); } catch (...) {}
+ } catch (const Win32Error& e) {
+ what = L"a Windows error";
+ try { why = WcharPtr::Copy(e.What()); } catch (...) {}
+ } catch (const std::exception& e) {
+ try { why = WcharPtr::FromNarrow(e.what()); } catch (...) {}
+ } catch (...) {}
+
+ std::wstring msg(wcslen(fmt)+wcslen(what)+wcslen(why), 0);
+ Swprintf(msg, fmt, what, static_cast<wchar_t*>(why));
+ EBMessageBox(msg, title, uType);
+}
+
int GetRelativeCursorPos(const HWND hWnd, POINT* const pt) noexcept
{
RECT rc;
diff --git a/c/win.h b/c/win.h
index 3bb0d6e..ab5cf05 100644
--- a/c/win.h
+++ b/c/win.h
@@ -5,12 +5,12 @@
#include <string_view>
#include <windows.h>
-/* Show message box for current exception. */
-void ShowException(const wchar_t* fmt, const wchar_t* title, UINT uType = MB_ICONWARNING) noexcept;
/* Run given procedure at creation of next window. */
void WithNextWindow(void (*proc)(HWND));
/* Display message box centered in main window. */
int EBMessageBox(std::wstring_view text, std::wstring_view data, UINT uType);
+/* Show message box for current exception. */
+void ShowException(const wchar_t* fmt, const wchar_t* title, UINT uType = MB_ICONWARNING) noexcept;
/* Retrieve mouse position relative to given window's client area. */
int GetRelativeCursorPos(HWND hWnd, POINT* pt) noexcept;
/* Cached values from GetSystemMetrics. */