From: Frank Goenninger DG1SBG
Subject: portable pathname construction tools anywhere?
Date: 
Message-ID: <87fzclslpk.fsf@stargate.de.goenninger.com>
Hi all:

Not sure if it's just me, but:

I was unable to find a set of tools that handles dealing with
filenames and pathnames correctly.

What I want to do is just something like

(make-a-path-to-a-file "/this/part1/of/path/" "this/part2" "thefile.lisp")

and I get the clean path

  "/this/part1/of/path/this/part2/thefile.lisp"

and the function takes care of adding "/" if needed (or even deleting those 
if toomany in the spec - just as if "/this/part2" had been given - to avoid 
a "//").

Of course, this should be portable between implementations and platforms.

Any pointers?

Thx a lot.

Regards,
  Frank

From: Rudi Schlatte
Subject: Re: portable pathname construction tools anywhere?
Date: 
Message-ID: <m2eks58tz9.fsf@Rudi-Schlattes-Computer.local>
Frank Goenninger DG1SBG <················@goenninger.com> writes:

> 
> What I want to do is just something like
> 
> (make-a-path-to-a-file "/this/part1/of/path/" "this/part2" "thefile.lisp")
> 
> and I get the clean path
> 
>   "/this/part1/of/path/this/part2/thefile.lisp"
> 

Something like this, perhaps?

(merge-pathnames
 (make-pathname :name "thefile" :type "lisp")
 (merge-pathnames
  (make-pathname :directory '(:relative "this" "part2"))
  (make-pathname :directory '(:absolute "this" "part1" "of" "path"))))

Cheers,

Rudi
From: Björn Lindberg
Subject: Re: portable pathname construction tools anywhere?
Date: 
Message-ID: <hcshdwzny0s.fsf@tjatte.nada.kth.se>
Frank Goenninger DG1SBG <················@goenninger.com> writes:

> Hi all:
> 
> Not sure if it's just me, but:
> 
> I was unable to find a set of tools that handles dealing with
> filenames and pathnames correctly.
> 
> What I want to do is just something like
> 
> (make-a-path-to-a-file "/this/part1/of/path/" "this/part2" "thefile.lisp")

You could try to first convert the strings into pathnames, and then
put those together to form the full path:

* (mapcar #'(lambda (x)
	      (pathname-directory (pathname x)))
	  '("/this/part1/of/path/" "this/part2" "thefile.lisp"))
==> ((:ABSOLUTE "this" "part1" "of" "path") (:RELATIVE "this") NIL)

A problem -- as you can see -- is that on Unix your second string will
likely be parsed as directory + filename, unless you put an extra '/'
at the end of it, which will make the approach fail.

My suggestion, based on how I percieve your example, is to simply
concatenate the strings with intermediate '/':s. You can then pass the
resulting string to PATHNAME and on to NAMESTRING to get rid of
superfluous slash characters:

* (namestring (pathname (concatenate 'string
                                     "/this/part1/of/path/"
                                     "/"
                                     "this/part2"
                                     "/"
                                     "thefile.lisp")))
==> "/this/part1/of/path/this/part2/thefile.lisp"

This is perhaps not very elegant, but I can't see any other way around
the problem described above other than this or some preprocessing of
the individual strings to ensure that they get converted into the
right pathnames by PATHNAME, and then merging the resulting pathnames
themselves.

> and I get the clean path
> 
>   "/this/part1/of/path/this/part2/thefile.lisp"
> 
> and the function takes care of adding "/" if needed (or even deleting those 
> if toomany in the spec - just as if "/this/part2" had been given - to avoid 
> a "//").
> 
> Of course, this should be portable between implementations and platforms.

Hm. Your initial data does not seem particularly portable to me to
begin with. Where are you getting it from? User input or something you
have more control over?


Bj�rn
From: Peter Seibel
Subject: Re: portable pathname construction tools anywhere?
Date: 
Message-ID: <m3ptbnxnc5.fsf@javamonkey.com>
·······@nada.kth.se (Bj�rn Lindberg) writes:

> Frank Goenninger DG1SBG <················@goenninger.com> writes:
>
>> Hi all:
>> 
>> Not sure if it's just me, but:
>> 
>> I was unable to find a set of tools that handles dealing with
>> filenames and pathnames correctly.
>> 
>> What I want to do is just something like
>> 
>> (make-a-path-to-a-file "/this/part1/of/path/" "this/part2" "thefile.lisp")
>
> You could try to first convert the strings into pathnames, and then
> put those together to form the full path:
>
> * (mapcar #'(lambda (x)
> 	      (pathname-directory (pathname x)))
> 	  '("/this/part1/of/path/" "this/part2" "thefile.lisp"))
> ==> ((:ABSOLUTE "this" "part1" "of" "path") (:RELATIVE "this") NIL)
>
> A problem -- as you can see -- is that on Unix your second string will
> likely be parsed as directory + filename, unless you put an extra '/'
> at the end of it, which will make the approach fail.
>
> My suggestion, based on how I percieve your example, is to simply
> concatenate the strings with intermediate '/':s. You can then pass the
> resulting string to PATHNAME and on to NAMESTRING to get rid of
> superfluous slash characters:

Or more portably you can use the approach I used in the code posted in:

  <http://groups.google.com/groups?selm=m3hdxb7ywv.fsf%40javamonkey.com>

Which manipulates pathnames to convert from "file form" to "path form"

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Marco Antoniotti
Subject: Re: portable pathname construction tools anywhere?
Date: 
Message-ID: <7XG3c.93$IJ5.76755@typhoon.nyu.edu>
Frank Goenninger DG1SBG wrote:

> Hi all:
> 
> Not sure if it's just me, but:
> 
> I was unable to find a set of tools that handles dealing with
> filenames and pathnames correctly.
> 
> What I want to do is just something like
> 
> (make-a-path-to-a-file "/this/part1/of/path/" "this/part2" "thefile.lisp")
> 
> and I get the clean path
> 
>   "/this/part1/of/path/this/part2/thefile.lisp"
> 
> and the function takes care of adding "/" if needed (or even deleting those 
> if toomany in the spec - just as if "/this/part2" had been given - to avoid 
> a "//").
> 
> Of course, this should be portable between implementations and platforms.
> 
> Any pointers?
> 
> Thx a lot.
> 
> Regards,
>   Frank
> 


I don't like the neither the MAKE-A-PATH-TO-A-FILE, nor the MAKE-PATH 
names, but here it is.

(defun make-path (pathspec &rest pathspecs)
   (let ((p (pathname pathspec)))
     (cond ((null pathspecs) p)
           (t
            (when (and (pathname-name p) (not (eq :unspecific
                                                  (pathname-name p))))
              (warn "Pathname ~S has a name.  ~
                     It will be discarded in the ··············@
                     Please make sure that that is the ········@
                     Are you sure you have not forgotten a ~
                     \"directory\" marker at the end?"
                    p))
            (merge-pathnames (apply #'make-path (first pathspecs)
                                                (rest pathspecs))
                             p)))))


There are some necessary explanations here to be made, but, all in all 
the above is protable across platforms and implementations.  (if not 
contact you vendor, implementor :) )

Cheers

--
Marco