Pathname host when merging relative pathnames




While looking into pathname issues in ASDF it has become apparent that the merging of relative pathnames is rather problematic. The usage in ASDF is to merge a relative pathname with a default base. The CL 'merge-pathnames is defined to merge a relative directory with the defaults base but will keep the specified host in this case. For example:

(merge-pathnames "TEST:;FILE.LISP" "/home/") => #P"TEST:HOME;FILE.LISP.NEWEST"
or
(merge-pathnames #p"file.lisp" #p"TEST:PATH;") => #P"/path/file.lisp"

The result is not usable because the host of the specified pathname is not necessarily applicable to the default base host.

CL requires the host in order to be able to parse the relative namestring. For example is not possible to parse the namestring ";FILE.LISP" alone.

The ASDF solution is to copy the default host when the specified directory is relative, and it defines a new function 'merge-pathnames* to do this.

CL defines *default-pathname-defaults*, and defines many functions to firstly merge an argument pathname with this, and also suggests this be the current working directory making. This makes it convenient to use relative pathnames for files based in the current working directory. However when working with multiple pathname hosts it becomes problematic using such relative pathnames because the host will not default along with the directory.

Having the host define the namestring format of the pathname seems a real plus for CL. URIs in contrast can not include a scheme in a URI reference (adding a scheme makes the URI absolute) so the full structure of a relative URI may not be parsed.

One workaround is to allow 'make-pathname to accept a host of 'nil and to not default this if supplied, so that a relative pathname could be created for which the standard merging rules would copy the host. However without the host the pathname may become unprintable, or at least fall back to a native format.

For example:
(merge-pathnames (make-pathname :host nil :defaults "TEST:;FILE.LISP") "/home/") => #P"/home/file.lisp"
(merge-pathnames (make-pathname :host nil :defaults "file.lisp") "TEST:PATH;") => #P"TEST:PATH;FILE.LISP"

Would much code break if an implementation just introduced a non-standard merging rule to copy over the host when the specified pathname directory is relative? For example:
(merge-pathnames "TEST:;FILE.LISP" "/home/") => #P"/home/file.lisp"
or
(merge-pathnames #p"file.lisp" #p"TEST:PATH;") => #P"TEST:PATH;FILE.LISP"
.



Relevant Pages

  • Re: delete-file & probe-file on directories
    ... > "host colon" syntactic space to say that if there's a host name in the ... > PARSE-NAMESTRING's job is to parse a representation of a pathname + ... physical namestring, why shouldn't PARSE-NAMESTRING parse the string ... I didn't say that Unix-based implementations have no use for it. ...
    (comp.lang.lisp)
  • Need help to understand URI
    ... scheme, userinfo, host, port, ... I could play at http://rubular.com/ to play more with URI. ...
    (comp.lang.ruby)
  • Re: Select
    ... u2.created) < 1 GROUP BY client_ip, host, uri, referer, agent HAVING ...
    (comp.databases)
  • Re: Select
    ... host, uri, referer, agent HAVING count>1) as a GROUP BY d ORDER BY ...
    (comp.databases)
  • Re: Select
    ... u1.created FROM user_requests u1 JOIN user_requests u2 USING (client_ip, host, uri, referer, agent) WHERE abs< 1 GROUP BY client_ip, host, uri, referer, agent HAVING ...
    (comp.databases)