Hi, Andy Wingo <wi...@pobox.com> writes:
> On Tue 20 Apr 2010 18:57, l...@gnu.org (Ludovic Courtès) writes: > >>> 2. I think a fluid is still necessary, because a file being >>> compiled can do an `include' or `include-from-path', or even >>> `open-input-file' in a macro, and all these cases you would want the >>> same %file-port-name-canonicalization to take effect. >> >> Indeed, this one is tricky. >> >> I still think it’s application-specific, though. How about calling the >> fluid, say, %compiler-file-name-canonicalization instead? :-) > > Are you proposing that all file-opening functions check the > %compiler-file-name-canonicalization fluid? No, I’m talking about file-opening functions of the compiler, which include ‘compile-file’, ‘include’, etc. > If you build out-of-source, you might end up with > > guile-tools compile -o ice-9/boot-9.go ../../modules/ice-9/boot-9.scm > > So the file you open is "../../modules/ice-9/boot-9.scm", but you want > to give it a "relative canonicalization" -- in this case > "ice-9/boot-9.scm" is the canonicalization of > ../../modules/ice-9/boot-9.scm, *relative* to "../../modules" (or indeed > to "/home/wingo/src/guile/modules"). OK, understood. >>> So you'd have to do a set-port-filename! on the port, mucking up your >>> code -- and how would you decide what to set? In N places you'd have to >>> duplicate fport_canonicalize_filename, and you'd probably have to make >>> scm_i_relativize_path public. >> >> I failed to get the transition at “So”. :-) >> >> What does scm_i_relativize_path do? (It lacks a leading comment, hint >> hint. ;-)) BTW, my understanding is that scm_i_relativize_path does lexical “relativization”, which doesn’t work on POSIX and GNU systems where ‘..’ resolution is /not/ lexical. (See <http://doc.cat-v.org/plan_9/4th_edition/papers/lexnames> for details.) The following should work: --8<---------------cut here---------------start------------->8--- (define (relativize-path path dir) ;; Return PATH relative to DIR or #f on failure. (let ((path (canonicalize-path path)) (dir (canonicalize-path dir))) (and=> (string-prefix-length dir path) (lambda (start) (substring path (+ 1 start) (string-length path)))))) scheme@(guile-user)> (relativize-path "../guile/module/ice-9/boot-9.scm" "module") "ice-9/boot-9.scm" scheme@(guile-user)> (relativize-path "module/ice-9/boot-9.scm" "../guile/module") "ice-9/boot-9.scm" --8<---------------cut here---------------end--------------->8--- It still does lexical relativization but does so after canonicalization of both arguments. > you would have to do: > > (define (open-input-file* path) > (let ((p (open-input-file path))) > (case (fluid-ref %file-port-name-canonicalization) > ((absolute) > (set-port-filename! p (canonicalize-path path))) > ((relative) > (set-port-filename! p (relativize-path (canonicalize-path path) > %load-path)))) > p)) > > which is a bit ugly; e.g. include-from-path would need to do this, as > would any third-party equivalent of include-from-path, and even > down to the open-file level. Yuk. Wouldn’t it suffice if only ‘compile-file’, ‘include’, and ‘include-from-path’ relativize paths? Thanks, Ludo’.