aboutsummaryrefslogtreecommitdiff
path: root/src/stdlib/stdlib.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-12-21 15:57:21 -0500
committerBruce Hill <bruce@bruce-hill.com>2025-12-21 15:57:21 -0500
commit13c430fde1388703aa002fdb203548801082d4e3 (patch)
tree236718203fa84bcf78b755bf8ec3b69a1da716ad /src/stdlib/stdlib.c
parent86a08a38a8a60b6a0de0da62a5d3fa843f6db71f (diff)
parent434ffd71c9a7eebd46ec0cba1d97b0827b874901 (diff)
Merge branch 'dev'
Diffstat (limited to 'src/stdlib/stdlib.c')
-rw-r--r--src/stdlib/stdlib.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/src/stdlib/stdlib.c b/src/stdlib/stdlib.c
index f4e6d678..688f2eb4 100644
--- a/src/stdlib/stdlib.c
+++ b/src/stdlib/stdlib.c
@@ -17,6 +17,7 @@
#include "files.h"
#include "metamethods.h"
#include "optionals.h"
+#include "paths.h"
#include "print.h"
#include "siphash.h"
#include "stacktrace.h"
@@ -39,11 +40,66 @@ static ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) {
public
bool USE_COLOR;
+
+public
+const char *TOMO_PATH = "/usr/local";
+
public
-Text_t TOMO_VERSION_TEXT = Text(TOMO_VERSION);
+const char *TOMO_VERSION = "v0";
+
+public
+Text_t TOMO_VERSION_TEXT = Text("v0");
+
+#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD)
+#include <dlfcn.h>
+
+static inline const char *get_library_path(void *func) {
+ static Dl_info info;
+ if (dladdr(func, &info)) {
+ return info.dli_fname; // full path of the library
+ }
+ return NULL;
+}
+
+#elif defined(_WIN32)
+#include <windows.h>
+
+static inline const char *get_library_path(void *func) {
+ static char path[MAX_PATH];
+ HMODULE hm = NULL;
+ if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ (LPCSTR)func, &hm)) {
+ if (GetModuleFileName(hm, path, MAX_PATH)) {
+ return path;
+ }
+ }
+ return NULL;
+}
+
+#else
+#error "Unsupported platform"
+#endif
+
+const char *resolve_symlinks(const char *path) {
+ static char resolved[PATH_MAX];
+ if (realpath(path, resolved) != NULL) {
+ return resolved;
+ } else {
+ perror("realpath");
+ return NULL;
+ }
+}
public
-const char *TOMO_PATH = TOMO_INSTALL;
+void tomo_configure(void) {
+ const char *lib_path = resolve_symlinks(get_library_path(get_library_path));
+ Path_t path = Path$from_str(lib_path);
+ TOMO_PATH = Path$as_c_string(Path$parent(Path$parent(path)));
+ Text_t base_name = Path$base_name(path);
+ TOMO_VERSION_TEXT = Text$without_suffix(
+ Text$without_prefix(Text$without_prefix(base_name, Text("lib")), Text("tomo@")), Text(".so"));
+ TOMO_VERSION = Text$as_c_string(TOMO_VERSION_TEXT);
+}
static _Noreturn void signal_handler(int sig, siginfo_t *info, void *userdata) {
(void)info, (void)userdata;
@@ -60,6 +116,7 @@ static _Noreturn void signal_handler(int sig, siginfo_t *info, void *userdata) {
public
void tomo_init(void) {
GC_INIT();
+ tomo_configure();
const char *color_env = getenv("COLOR");
USE_COLOR = color_env ? strcmp(color_env, "1") == 0 : isatty(STDOUT_FILENO);
const char *no_color_env = getenv("NO_COLOR");