changeset 153:bd439dd6ffc5

*: make win stuff actually work, rename bsd.cc to xnu.cc It's been OS X only for ages, and these functions are different between most BSDs anyway
author Paper <mrpapersonic@gmail.com>
date Wed, 15 Nov 2023 13:28:18 -0500
parents 8700806c2cc2
children d43d68408d3c
files dep/animia/CMakeLists.txt dep/animia/include/animia/fd/bsd.h dep/animia/include/animia/fd/xnu.h dep/animia/include/animia/player.h dep/animia/src/animia.cc dep/animia/src/fd.cc dep/animia/src/fd/bsd.cc dep/animia/src/fd/xnu.cc dep/animia/src/strategist.cc dep/animia/src/util.cc dep/animia/src/win/win32.cc src/track/media.cc
diffstat 12 files changed, 154 insertions(+), 195 deletions(-) [+]
line wrap: on
line diff
--- a/dep/animia/CMakeLists.txt	Wed Nov 15 02:34:59 2023 -0500
+++ b/dep/animia/CMakeLists.txt	Wed Nov 15 13:28:18 2023 -0500
@@ -15,10 +15,10 @@
 		# linux
 		src/fd/linux.cc
 	)
-elseif(UNIX) # this won't run on Linux
+elseif(MACOSX) # this won't run on Linux
 	list(APPEND SRC_FILES
-		# bsd
-		src/fd/bsd.cc
+		# xnu stuff
+		src/fd/xnu.cc
 	)
 elseif(WIN32)
 	list(APPEND SRC_FILES
--- a/dep/animia/include/animia/fd/bsd.h	Wed Nov 15 02:34:59 2023 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-#ifndef __animia__animia__fd__linux_h
-#define __animia__animia__fd__linux_h
-
-#include <string>
-#include <set>
-
-#include "animia/types.h"
-#include "animia/fd.h"
-
-#ifdef unix
-#undef unix
-#endif
-
-namespace animia::internal::unix {
-
-class UnixFdTools final : public BaseFdTools {
-	public:
-		bool EnumerateOpenProcesses(process_proc_t process_proc) override;
-		bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) override;
-};
-
-}
-
-#endif // __animia__animia__fd__linux_h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dep/animia/include/animia/fd/xnu.h	Wed Nov 15 13:28:18 2023 -0500
@@ -0,0 +1,20 @@
+#ifndef __animia__animia__fd__xnu_h
+#define __animia__animia__fd__xnu_h
+
+#include <string>
+#include <set>
+
+#include "animia/types.h"
+#include "animia/fd.h"
+
+namespace animia::internal::xnu {
+
+class XnuFdTools final : public BaseFdTools {
+	public:
+		bool EnumerateOpenProcesses(process_proc_t process_proc) override;
+		bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) override;
+};
+
+}
+
+#endif // __animia__animia__fd__xnu_h
--- a/dep/animia/include/animia/player.h	Wed Nov 15 02:34:59 2023 -0500
+++ b/dep/animia/include/animia/player.h	Wed Nov 15 13:28:18 2023 -0500
@@ -7,7 +7,7 @@
 namespace animia {
 
 enum class Strategy {
-	WindowTitle, // unused
+	WindowTitle,
 	OpenFiles,
 	UiAutomation // unused
 };
--- a/dep/animia/src/animia.cc	Wed Nov 15 02:34:59 2023 -0500
+++ b/dep/animia/src/animia.cc	Wed Nov 15 13:28:18 2023 -0500
@@ -38,10 +38,10 @@
 }
 
 static bool PlayerHasStrategy(const Player& player, const Strategy& strategy) {
-	for (const auto& pstrategy : player.strategies) {
+	for (const auto& pstrategy : player.strategies)
 		if (pstrategy == strategy)
 			return true;
-	}
+
 	return false;
 }
 
--- a/dep/animia/src/fd.cc	Wed Nov 15 02:34:59 2023 -0500
+++ b/dep/animia/src/fd.cc	Wed Nov 15 13:28:18 2023 -0500
@@ -4,8 +4,8 @@
 #	include "animia/fd/win32.h"
 #elif defined(LINUX)
 #	include "animia/fd/linux.h"
-#elif defined(UNIX)
-#	include "animia/fd/bsd.h"
+#elif defined(MACOSX)
+#	include "animia/fd/xnu.h"
 #endif
 
 namespace animia::internal {
@@ -14,8 +14,8 @@
 win32::Win32FdTools os_fd;
 #elif defined(LINUX)
 linux::LinuxFdTools os_fd;
-#elif defined(UNIX)
-unix::UnixFdTools os_fd;
+#elif defined(MACOSX)
+xnu::XnuFdTools os_fd;
 #else
 BaseFdTools os_fd;
 #endif
--- a/dep/animia/src/fd/bsd.cc	Wed Nov 15 02:34:59 2023 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
-** fd/bsd.cpp
-**  - this ONLY* supports OS X as of now
-**     (*there is some FreeBSD support code)
-*/
-#include "animia/fd/bsd.h"
-#include "animia.h"
-
-#include <unordered_map>
-#include <vector>
-#include <string>
-
-#include <fcntl.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <sys/user.h>
-
-#ifdef __FreeBSD__
-#	include <libutil.h>
-#elif defined(__APPLE__)
-#	include <libproc.h>
-#endif
-
-namespace animia::internal::unix {
-
-static bool GetProcessName(pid_t pid, std::string& result) {
-#ifdef __FreeBSD__
-	struct kinfo_proc* proc = kinfo_getproc(pid);
-	if (!proc)
-		return false;
-	result = proc->ki_comm;
-
-	/* FreeBSD manpage for kinfo_getproc():
-	   "The pointer was obtained by an internal call to malloc(3) and
-	   must be freed by the caller with a call to free(3)." */
-	free(proc);
-
-	return true;
-#elif defined(__APPLE__)
-	struct proc_bsdinfo proc;
-
-	int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE);
-	if (st != PROC_PIDTBSDINFO_SIZE)
-		return false;
-
-	/* fixme: is this right? pbi_comm is an alternative, but it reduces the string size to
-	   16 chars. does pbi_name do the same, or is it different? */
-	result = proc.pbi_name;
-	return true;
-#endif
-}
-
-/* this is a cleaned up version of a function from... Apple?
-   ...anyway, what it essentially does is gets the size and stuff from
-   sysctl() and reserves the space in a vector to store the PIDs
-
-	TODO: https://kaashif.co.uk/2015/06/18/how-to-get-a-list-of-processes-on-openbsd-in-c/ */
-bool UnixFdTools::EnumerateOpenProcesses(process_proc_t process_proc) {
-	struct kinfo_proc* result = NULL;
-	size_t length = 0;
-	static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
-
-	/* get appropriate length from sysctl()
-	   note: the reason this isn't checked is actually because this will
-	   *always* return an error on OS X (or... maybe I'm doing it wrong :) ) */
-	sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0);
-
-	result = (struct kinfo_proc*)malloc(length);
-	if (result == NULL)
-		return std::vector<int>();
-
-	/* TODO: this might actually return ENOMEM if the amount of file handles changes between the
-	   original sysctl() call and this one, which is technically possible */
-	if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) {
-		assert(result != NULL);
-		free(result);
-		throw std::bad_alloc();
-	}
-
-	for (int i = 0; i < length / sizeof(*result); i++) {
-		const pid_t pid = result[i].kp_proc.p_pid;
-		if (!process_proc({pid, GetProcessName(pid)}))
-			return false;
-	}
-}
-
-/* this only works on OS X :( */
-bool UnixFdTools::EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) {
-	if (!open_file_proc)
-		return false;
-
-	for (const auto& pid : pids) {
-		int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
-		if (bufsz == -1)
-			return false;
-
-		struct proc_fdinfo* info = (struct proc_fdinfo*)malloc(bufsz);
-		if (!info)
-			return false;
-
-		proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info, bufsz);
-
-		for (int i = 0; i < bufsz / sizeof(info[0]); i++) {
-			if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) {
-				struct vnode_fdinfowithpath vnodeInfo;
-
-				int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE);
-				if (sz != PROC_PIDFDVNODEPATHINFO_SIZE)
-					return false;
-
-				/* this doesn't work!
-				if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR)
-					continue;
-				*/
-
-				if (!open_file_proc({pid, vnodeInfo.pvip.vip_path}))
-					return false;
-			}
-		}
-	}
-	return true;
-}
-
-} // namespace animia::internal::unix
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dep/animia/src/fd/xnu.cc	Wed Nov 15 13:28:18 2023 -0500
@@ -0,0 +1,101 @@
+/*
+** fd/xnu.cpp
+**  - provides support for XNU (part of Darwin)
+*/
+#include "animia/fd/xnu.h"
+#include "animia.h"
+
+#include <unordered_map>
+#include <vector>
+#include <string>
+
+#include <fcntl.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <libproc.h>
+
+namespace animia::internal::xnu {
+
+static bool GetProcessName(pid_t pid, std::string& result) {
+	struct proc_bsdinfo proc;
+
+	int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE);
+	if (st != PROC_PIDTBSDINFO_SIZE)
+		return false;
+
+	/* fixme: is this right? pbi_comm is an alternative, but it reduces the string size to
+	   16 chars. does pbi_name do the same, or is it different? */
+	result = proc.pbi_name;
+	return true;
+}
+
+/* this is a cleaned up version of a function from... Apple?
+   ...anyway, what it essentially does is gets the size and stuff from
+   sysctl() and reserves the space in a vector to store the PIDs */
+bool XnuFdTools::EnumerateOpenProcesses(process_proc_t process_proc) {
+	struct kinfo_proc* result = NULL;
+	size_t length = 0;
+	static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
+
+	/* get appropriate length from sysctl()
+	   note: the reason this isn't checked is actually because this will
+	   *always* return an error on OS X (or... maybe I'm doing it wrong :) ) */
+	sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0);
+
+	result = (struct kinfo_proc*)malloc(length);
+	if (result == NULL)
+		return false;
+
+	/* TODO: this might actually return ENOMEM if the amount of file handles changes between the
+	   original sysctl() call and this one, which is technically possible */
+	if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) {
+		assert(result != NULL);
+		free(result);
+		return false;
+	}
+
+	for (int i = 0; i < length / sizeof(*result); i++) {
+		const pid_t pid = result[i].kp_proc.p_pid;
+		if (!process_proc({pid, GetProcessName(pid)}))
+			return false;
+	}
+}
+
+bool XnuFdTools::EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) {
+	if (!open_file_proc)
+		return false;
+
+	for (const auto& pid : pids) {
+		int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
+		if (bufsz == -1)
+			return false;
+
+		struct proc_fdinfo* info = (struct proc_fdinfo*)malloc(bufsz);
+		if (!info)
+			return false;
+
+		proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info, bufsz);
+
+		for (int i = 0; i < bufsz / sizeof(info[0]); i++) {
+			if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) {
+				struct vnode_fdinfowithpath vnodeInfo;
+
+				int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE);
+				if (sz != PROC_PIDFDVNODEPATHINFO_SIZE)
+					return false;
+
+				/* this doesn't work!
+				if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR)
+					continue;
+				*/
+
+				if (!open_file_proc({pid, vnodeInfo.pvip.vip_path}))
+					return false;
+			}
+		}
+	}
+	return true;
+}
+
+} // namespace animia::internal::unix
--- a/dep/animia/src/strategist.cc	Wed Nov 15 02:34:59 2023 -0500
+++ b/dep/animia/src/strategist.cc	Wed Nov 15 13:28:18 2023 -0500
@@ -32,7 +32,6 @@
 			success |= ApplyOpenFilesStrategy();
 			break;
 		case ResultType::Window:
-			std::cout << "Wat" << std::endl;
 			success |= ApplyWindowTitleStrategy();
 			break;
 	}
--- a/dep/animia/src/util.cc	Wed Nov 15 02:34:59 2023 -0500
+++ b/dep/animia/src/util.cc	Wed Nov 15 13:28:18 2023 -0500
@@ -2,7 +2,6 @@
 #include <fstream>
 #include <sstream>
 #include <string>
-#include <cctype>
 #include <regex>
 
 #include <iostream>
@@ -27,12 +26,17 @@
 	return true;
 }
 
+/* this assumes ASCII... which really should be the case for what we need, anyway */
 bool EqualStrings(const std::string& str1, const std::string& str2) {
-	auto equal_chars = [](const char c1, const char c2) -> bool {
-		return std::tolower(static_cast<unsigned char>(c1)) == std::tolower(static_cast<unsigned char>(c2));
+	auto tolower = [](const char c) -> char {
+		return ('A' <= c && c <= 'Z') ? c + ('a' - 'A') : c;
 	};
 
-	return str1.size() == str2.size() && std::equal(str1.begin(), str1.end(), str2.begin(), equal_chars);
+	auto equal_chars = [&tolower](const char c1, const char c2) -> bool {
+		return tolower(c1) == tolower(c2);
+	};
+
+	return str1.length() == str2.length() && std::equal(str1.begin(), str1.end(), str2.begin(), equal_chars);
 }
 
 bool Stem(const std::string& filename, std::string& stem) {
--- a/dep/animia/src/win/win32.cc	Wed Nov 15 02:34:59 2023 -0500
+++ b/dep/animia/src/win/win32.cc	Wed Nov 15 13:28:18 2023 -0500
@@ -17,14 +17,21 @@
 
 	std::wstring buffer(kMaxSize, L'\0');
 	const auto size = ::GetClassNameW(hwnd, &buffer.front(), buffer.length());
+	/* for some reason GetClassName returns the actual size of the buffer *with* the
+	   terminating NULL byte */
+	buffer.resize(size);
 	return buffer;
 }
 
 static std::wstring GetWindowText(HWND hwnd) {
-	const int size = ::GetWindowTextLengthW(hwnd);
+	const int estimated_size = ::GetWindowTextLengthW(hwnd);
 
-	std::wstring buffer(size, L'\0');
-	::GetWindowTextW(hwnd, &buffer.front(), buffer.length());
+	std::wstring buffer(estimated_size + 1, L'\0');
+	const auto size = ::GetWindowTextW(hwnd, &buffer.front(), buffer.length());
+	/* GetWindowTextLength docs:
+	   "Under certain conditions, the GetWindowTextLength function may return a value
+	    that is larger than the actual length of the text." */
+	buffer.resize(size);
 	return buffer;
 }
 
@@ -55,7 +62,8 @@
 	if (!::QueryFullProcessImageNameW(process_handle.get(), 0, &buffer.front(), &buf_size))
 		return std::wstring();
 
-	return buffer.substr(0, buf_size + 1);
+	buffer.resize(buf_size);
+	return buffer;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/src/track/media.cc	Wed Nov 15 02:34:59 2023 -0500
+++ b/src/track/media.cc	Wed Nov 15 13:28:18 2023 -0500
@@ -41,6 +41,9 @@
 	for (const auto& result : results) {
 		for (const auto& media : result.media) {
 			for (const auto& info : media.information) {
+				switch (info.type) {
+					case 
+				}
 				std::cout << static_cast<int>(info.type) << ": " << info.value << std::endl;
 				vec.push_back(info.value);
 				success |= true;
@@ -51,33 +54,5 @@
 	return success;
 }
 
-/* this sucks. use anitomy directly like a real man */
-std::unordered_map<std::string, std::string> GetMapFromElements(const anitomy::Elements& elements) {
-	std::unordered_map<std::string, std::string> ret;
-
-	ret["title"] = Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle));
-	ret["filename"] = Strings::ToUtf8String(elements.get(anitomy::kElementFileName));
-	ret["language"] = Strings::ToUtf8String(elements.get(anitomy::kElementLanguage));
-	ret["group"] = Strings::ToUtf8String(elements.get(anitomy::kElementReleaseGroup));
-	ret["episode"] = Strings::ToUtf8String(elements.get(anitomy::kElementEpisodeNumber));
-	ret["resolution"] = Strings::ToUtf8String(elements.get(anitomy::kElementVideoResolution));
-
-	return ret;
-}
-
-std::unordered_map<std::string, std::string> GetFileElements(const std::string& basename) {
-	anitomy::Anitomy anitomy;
-	anitomy.Parse(Strings::ToWstring(basename));
-
-	return GetMapFromElements(anitomy.elements());
-}
-
-std::unordered_map<std::string, std::string> GetFileElements(const std::filesystem::path& path) {
-	anitomy::Anitomy anitomy;
-	anitomy.Parse(path.filename().wstring());
-
-	return GetMapFromElements(anitomy.elements());
-}
-
 } // namespace Media
 } // namespace Track