From e3a06759eebdc2b4e2d0b8d08cb64eb99a40d3e3 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 25 Apr 2022 00:14:23 -0700 Subject: 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. --- parser.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'parser.c') 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)) { -- cgit v1.2.3