summaryrefslogtreecommitdiffstats
path: root/parser.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-04-25 00:14:23 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-04-25 00:14:23 -0700
commite3a06759eebdc2b4e2d0b8d08cb64eb99a40d3e3 (patch)
treef9a7c20e14a49a92a156a1f9a652cc18fd1e1e45 /parser.c
parentec69fdce7fae00a34d0ae88dae388705fedc1f8f (diff)
downloadtxr-e3a06759eebdc2b4e2d0b8d08cb64eb99a40d3e3.tar.gz
txr-e3a06759eebdc2b4e2d0b8d08cb64eb99a40d3e3.tar.bz2
txr-e3a06759eebdc2b4e2d0b8d08cb64eb99a40d3e3.zip
New: load can search multiple directories.
* eval.c (load_search_dirs_s): New symbol variable. (load): Initialize the name variable whose address is passed as the third argument of open_txr_file, which is now an in-out parameter. Pass t for the new search_dirs parameter, so that load benefits from the searching. (eval_init): Initialize load_search_dirs_s and register the *load-search-dirs* special variable. * eval.h (load_search_dirs_s): Declared. (load_search_dirs): New macro. * match.c (v_load): Initialize the variable passed as third argument of open_txr_file. * parser.c (open_txr_file): Take a new argument, search_dirs. If this is t, it tells the function "if the path is not found, then recurse on the *load-search-dirs* variable. Otherwise, if the value is not t, it is a list of the remaining directories to try. The existing parameter orig_in_resolved_out must now point to a location which is initialized. It is assumed to hold the original target that was passed to the load function. The first_try_path is a the path to actually try, derived from that one. Thus, the caller of open_txr_file gets to determine the initial try path using its own algorithm. Then any recursive calls that go through *load-search-dirs* will pass a first argument which is made of the original name, combined with a search dir. (load_rcfile): Pass pointer to initialized location as third argument of open-txr_file, and pass a nil value for search_dirs: no search takes place when looking for that file, which is at a single, fixed location. * parser.h (open_txr_file): Declaration updated. * txr.c (sysroot_init): Initialize *load-search-dirs*. (txr_main): Ensure third argument in all calls to open_txr_file points to initialized variable, with the correct value, and pass t for the search_dirs argument. * txr.1: Documented. * stdlib/doc-syms.tl: Updated. New: load can search multiple directories. * eval.c (load_search_dirs_s): New symbol variable. (load): Initialize the name variable whose address is passed as the third argument of open_txr_file, which is now an in-out parameter. Pass t for the new search_dirs parameter, so that load benefits from the searching. (eval_init): Initialize load_search_dirs_s and register the *load-search-dirs* special variable. * eval.h (load_search_dirs_s): Declared. (load_search_dirs): New macro. * match.c (v_load): Initialize the variable passed as third * argument of open_txr_file. * parser.c (open_txr_file): Take a new argument, search_dirs. If this is t, it tells the function "if the path is not found, then recurse on the *load-search-dirs* variable. Otherwise, if the value is not t, it is a list of the remaining directories to try. The existing parameter orig_in_resolved_out must now point to a location which is initialized. It is assumed to hold the original target that was passed to the load function. The first_try_path is a the path to actually try, derived from that one. Thus, the caller of open_txr_file gets to determine the initial try path using its own algorithm. Then any recursive calls that go through *load-search-dirs* will pass a first argument which is made of the original name, combined with a search dir. (load_rcfile): Pass pointer to initialized location as third argument of open-txr_file, and pass a nil value for search_dirs: no search takes place when looking for that file, which is at a single, fixed location. * parser.h (open_txr_file): Declaration updated. * txr.c (sysroot_init): Initialize *load-search-dirs*. (txr_main): Ensure third argument in all calls to open_txr_file points to initialized variable, with the correct value, and pass t for the search_dirs argument. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/parser.c b/parser.c
index 9564d276..cdfceff1 100644
--- a/parser.c
+++ b/parser.c
@@ -513,7 +513,8 @@ val parser_circ_ref(parser_t *p, val num)
}
void open_txr_file(val first_try_path, val *txr_lisp_p,
- val *orig_in_resolved_out, val *stream, val self)
+ val *orig_in_resolved_out, val *stream,
+ val search_dirs, val self)
{
enum { none, tl, tlo, txr } suffix;
@@ -599,11 +600,26 @@ void open_txr_file(val first_try_path, val *txr_lisp_p,
}
if (in == 0) {
+ val try_next;
#ifdef ENOENT
except:
#endif
- uw_ethrowf(errno_to_file_error(errno),
- lit("unable to open ~a"), try_path, nao);
+ if (abs_path_p(*orig_in_resolved_out))
+ search_dirs = nil;
+ else if (search_dirs == t)
+ search_dirs = load_search_dirs;
+
+#ifdef ENOENT
+ if (errno != ENOENT || search_dirs == nil)
+#else
+ if (search_dirs == nil)
+#endif
+ uw_ethrowf(errno_to_file_error(errno),
+ lit("~a: ~a not found"), self, *orig_in_resolved_out, nao);
+ try_next = path_cat(pop(&search_dirs), *orig_in_resolved_out);
+ open_txr_file(try_next, txr_lisp_p, orig_in_resolved_out, stream,
+ search_dirs, self);
+ return;
}
found:
@@ -899,14 +915,14 @@ static void report_security_problem(val name)
static void load_rcfile(val name)
{
val self = lit("listener");
- val resolved_name;
+ val resolved_name = name;
val lisp_p = t;
val stream = nil;
val path_private_to_me_p = intern(lit("path-private-to-me-p"), user_package);
uw_catch_begin (catch_error, sy, va);
- open_txr_file(name, &lisp_p, &resolved_name, &stream, self);
+ open_txr_file(name, &lisp_p, &resolved_name, &stream, nil, self);
if (stream) {
if (!funcall1(path_private_to_me_p, stream)) {