Lisp HUG Maillist Archive

Underscore in logical pathname

Hi,

I have one question regarding logical pathnames. How can I specify a 
file name / folder name which includes the underscore character? Here is 
a simple example:

(setf (logical-pathname-translations "myapp")
      `(("root;**;*.*"  "c:\\Development\\myapp\\**\\")))

(translate-logical-pathname "myapp:root;simple-application.lisp")

works fine, but:

(translate-logical-pathname "myapp:root;simple_application.lisp")

does not work (can't parse the logical pathname).

Thank you,
Lukas



Re: Underscore in logical pathname

* I wrote:
> (merge-pathnames #P"current/source_1.dat" 
>                  (translate-logical-pathname #P"DATA:LOCAL;FOO.BAR"))

Incidentally, if you really don't like to wire in physical pathnames,
you can do something like the following hack (this is not really
tested):

(set-dispatch-macro-character #\# #\P
  #'(lambda (s sub infix)
      (declare (ignore infix))
      (let* ((*read-eval* nil)
             (read (read s)))
        (typecase read
          (list (apply #'make-pathname read))
          (t (parse-namestring read))))))

And now #P(:directory (:relative "local") :name "source_1" :type "dat")

Is legal syntax.

--tim




Re: Underscore in logical pathname

* Lukas Trejtnar wrote:
> I have one question regarding logical pathnames. How can I specify a 
> file name / folder name which includes the underscore character? Here is 
> a simple example:

You can't: underscore isn't legal syntax in logical pathnames.

If you want to special-case some translation so you can refer to a
physical name with an underscore you could do something like that:

CL-USER 1 > (setf (logical-pathname-translations "MYLH")
                  '(("FOO;**;ZIG-BAT.*.*" "C:/temp/foo/**/zig_bat.lisp")
                    ("FOO;**;*.*.*" "C:/temp/foo/**/*.*")))
(("FOO;**;ZIG-BAT.*.*" "C:/temp/foo/**/zig_bat.lisp") ("FOO;**;*.*.*" "C:/temp/foo/**/*.*"))

CL-USER 2 > (translate-logical-pathname "MYLH:FOO;GRUB.LISP")
#P"C:/temp/foo/grub.lisp"

CL-USER 3 > (translate-logical-pathname "MYLH:FOO;ZIG-BAT.LISP")
#P"C:/temp/foo/zig_bat.lisp"

A better way of working, if you want to refer to completely general
physical pathnames while using the logical pathname machinery is to
agree that the physical directory structure will suitably agree with
the logical one, and then use logical pathnames to simply find the
appropriate directories, then use physical names to actually derive
pathnames.

(setf (logical-pathname-translations "DATA")
      ;; there are two sources of data.
      '(("LOCAL;**;*.*.*" "C:/data/**/*.*")
        ("GLOBAL;**;*.*.*" "//fs/data/**/*.*")))

Then you can say

(merge-pathnames #P"current/source_1.dat" 
                 (translate-logical-pathname #P"DATA:LOCAL;FOO.BAR"))

for instance.  Really you're just using logical pathnames as a source
of abstract directory names, and then plunging into physical
pathnames for the hairy stuff.  Doing this, with a couple of utilities
to abstractify it, is quite pleasant.

--tim



Updated at: 2020-12-10 08:58 UTC