summaryrefslogtreecommitdiffstats
path: root/txr.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-06-09 22:22:27 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-06-09 22:22:27 -0700
commit6ac15da6c977a7f2c8d1be2292fee20b05864fe3 (patch)
tree4e5e6df4df2506aa0ec740a7efe1718a360b153c /txr.c
parent2ea6ca3ef8151d94d2a3f306a9035ae7ae001fcd (diff)
downloadtxr-6ac15da6c977a7f2c8d1be2292fee20b05864fe3.tar.gz
txr-6ac15da6c977a7f2c8d1be2292fee20b05864fe3.tar.bz2
txr-6ac15da6c977a7f2c8d1be2292fee20b05864fe3.zip
New variable stdlib, with a sysroot mechanism to compute
the path based on the "sysroot" where it is actually installed. * txr.c (progname_8u, progpath): New static variables. (get_self_path, sysroot_helper, sysroot, sysroot_init): New static functions. Sysroot creates a stdlib variable. (main): Initialize progname_u8 value, and call sysroot_init.
Diffstat (limited to 'txr.c')
-rw-r--r--txr.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/txr.c b/txr.c
index 27fbb353..4b96cc8a 100644
--- a/txr.c
+++ b/txr.c
@@ -34,6 +34,12 @@
#include <wchar.h>
#include <signal.h>
#include "config.h"
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
#include "lib.h"
#include "stream.h"
#include "gc.h"
@@ -49,6 +55,8 @@
const wchli_t *version = wli("89");
const wchar_t *progname = L"txr";
+static const char *progname_u8;
+static val progpath = nil;
/*
* Can implement an emergency allocator here from a fixed storage
@@ -154,12 +162,81 @@ static val remove_hash_bang_line(val spec)
}
}
+#if __linux__
+static val get_self_path(void)
+{
+ char self[PATH_MAX] = { 0 };
+ int nchar = readlink("/proc/self/exe", self, sizeof self);
+
+ if (nchar < 0 || nchar >= sizeof self)
+ return nil;
+ return string_utf8(self);
+}
+#elif HAVE_WINDOWS_H
+static val get_self_path(void)
+{
+ wchar_t self[MAX_PATH] = { 0 };
+ DWORD nchar;
+
+ SetLastError(0);
+ nchar = GetModuleFilename(NULL, self, MAX_PATH);
+
+ if (nchar == 0 ||
+ (nchar == MAX_PATH &&
+ (GetLastError() == ERROR_INSUFFICIENT_BUFFER) ||
+ (self[MAX_PATH - 1] != 0)))
+ return nil;
+
+ return string(self);
+}
+#else
+static val get_self_path(void)
+{
+ char self[PATH_MAX];
+
+ if (!progname_u8)
+ return nil;
+
+ if (realpath(progname_u8, self))
+ return string_utf8(self);
+
+ return nil;
+}
+#endif
+
+static val sysroot_helper(val exepart, val target)
+{
+ if (match_str(progpath, exepart, negone))
+ return format(nil, lit("~a~a"),
+ sub_str(progpath, 0, neg(length(exepart))),
+ target, nao);
+ return nil;
+}
+
+static val sysroot(val target)
+{
+ uses_or2;
+ return or4(sysroot_helper(lit("bin/txr"), target),
+ sysroot_helper(lit("bin/txr.exe"), target),
+ sysroot_helper(lit("txr"), target),
+ sysroot_helper(lit("txr.exe"), target));
+}
+
+static void sysroot_init(void)
+{
+ prot1(&progpath);
+ progpath = get_self_path();
+ reg_var(intern(lit("stdlib"), user_package),
+ sysroot(lit("share/txr/stdlib")));
+}
+
int txr_main(int argc, char **argv);
int main(int argc, char **argv)
{
val stack_bottom = nil;
progname = argv[0] ? utf8_dup_from(argv[0]) : progname;
+ progname_u8 = argv[0];
init(progname, oom_realloc_handler, &stack_bottom);
match_init();
parse_init();
@@ -167,6 +244,7 @@ int main(int argc, char **argv)
#if HAVE_SYSLOG
syslog_init();
#endif
+ sysroot_init();
return txr_main(argc, argv);
}
@@ -185,6 +263,7 @@ int txr_main(int argc, char **argv)
setvbuf(stderr, 0, _IOLBF, 0);
+
yyin_stream = std_input;
if (argc <= 1) {