edicl / cl-fad Goto Github PK
View Code? Open in Web Editor NEWPortable pathname library for Common Lisp
Home Page: https://edicl.github.io/cl-fad/
License: Other
Portable pathname library for Common Lisp
Home Page: https://edicl.github.io/cl-fad/
License: Other
Hello,
I am using Clozure CL 1.9 64 bits on Windows.
After loading CL-FAD from Quicklisp, WITH-OPEN-TEMPORARY-FILE does not work because the logical host TEMPORARY-FILES is not defined:
? (cl-fad:with-open-temporary-file (stream) (write 'hello :stream stream))
> Error: "TEMPORARY-FILES" is not a defined logical host
> While executing: CCL::PATHNAME-HOST-SSTR, in process listener(1).
Although the TEMP environment variable is properly set on my system.
Camille
With all due respect, loading a directory containing a file with a "[" in its name creates a path containing a "\[". With two backslashes. The first backslash escapes the second, resulting in a backslash before the brace. The file cannot be opened because of the extra backslash.
For example, given a file "[xxx", list-directory presents it as #P"\[xxx" in the path. The resultant (wrong) filename is therefore "[xxx" instead of "[xxx".
This is a bug that needs to be addressed - I'd hate to kludge a workaround searching for backslashes before an open brace.
Please do not close this issue without investigating it. This is confusing because github does its own escaping, so I think that my previous issue was not understood correctly.
(pathname-directory (fad:pathname-as-directory "~")) => (:ABSOLUTE "Users" "devon" "")
but should be (:ABSOLUTE "Users" "devon")
I implemented a function using some of the functions of cl-fad, the function is called copy-directory-recursive, as the name says, it recursively copies a directory, I missed a function like that in cl-fad, it's here:
(defun copy-directory-recursive (origin destination &key (overwrite nil))
(let ((list-dir (cl-fad:list-directory origin)))
(ensure-directories-exist destination)
(dolist (path list-dir)
(cond ((cl-fad:directory-exists-p path)
(progn (ensure-directories-exist (merge-directory-with-subtract-path path origin destination))
(copy-directory-recursive path
(merge-directory-with-subtract-path path origin destination)
:overwrite t)))
((pathname-is-file path)
(cl-fad:copy-file path (merge-file-with-subtract-path path origin destination)
:overwrite overwrite))))))
(defun merge-directory-with-subtract-path (path origin destination)
(cl-fad:merge-pathnames-as-directory destination (pathname-subtract origin path)))
(defun merge-file-with-subtract-path (path origin destination)
(cl-fad:merge-pathnames-as-file
(cl-fad:merge-pathnames-as-file destination (pathname-subtract origin path))
(concatenate 'string (pathname-name path) (if (pathname-type path) ".") (pathname-type path))))
(defun pathname-subtract (path-1 path-2)
"Compare path-1 with path-2, and return new pathname with rest of path-2 at the point where it differentiated."
(let* ((list-path-1 (pathname-directory path-1))
(list-path-2 (pathname-directory path-2))
(new-list (list-subtract list-path-1 list-path-2))
(new-path "/"))
(dolist (el new-list)
(setf new-path (cl-fad:merge-pathnames-as-directory new-path
(concatenate 'string el "/"))))
(pathname (subseq (namestring new-path) 1))))
(defun list-subtract (list-1 list-2)
"Compare elements of list-1 with elements of list-2, return new list with elements of list-2 not contained in list-1. Return immediately for elements differents, the comparison follow order of elements."
;;; Example:
;;; (list-subtract '("home" "you" "lisp")' ("home" "new" "you" "lisp" "child-dir" "you"))
(do ((c 0 (incf c))
(i list-1 (cdr i))
(j list-2 (cdr j))
(new-list list-2
(if (string= (car i)
(car j))
(progn (pop new-list)
new-list)
(return new-list))))
((>= c (length list-1)) new-list)))
I also have the test for her. But I will not extend too much here. If you want to add it, tell me how to proceed to integrate it into cl-fad, which I will refactor it and do whatever has to be done.
Hello.
As cl-fad is one of the most often downloaded Quicklisp systems, cl-fad testsuite is being constantly tested by cl-test-grid on various lisps and OSes:
http://common-lisp.net/project/cl-test-grid/library/cl-fad.html
When cl-fad test-suite changes it breaks cl-test-grid adapter which needs to be updated (there were already two such cases: once when the test code has moved from test.lisp to fad.test.lisp, next when the test code was separated into several files and organized into an ASDF system).
It is definitely good that the testsuite is being extended.
I would appreciate if cl-fad developers drop a note to [email protected] when they start planning or implementing the testsuite changes. Otherwise some time passes before I notice the breakage and also some time is needed to implement the adjustment; during this time cl-fad is not covered by cl-test-grid.
Let me also make some notes about the current testsuite state.
The part of the tests defined in the fad.test.lisp is implemented using cl:assert.
Another part, defined in temporary-files.test.lisp is implemented using the unit-test framework and not integrated into the documented function cl-fad-test:test.
A disadvantage of the unit-test framework is that it's main function
unit-test:run-all-tests return value does not provide list of failed test cases,
it only returns true/false meaning "all passed" or "some failed".
It would be better if all tests were implemented using the same test framework,
preferably one allowing to determine what test cases has failed (clunit, eos, fiveam, lift, nst, rt, stefil, ...).
These problems are not critical, and of course I do not expect anyone to immediately jump in and start spending efforts on it. I just hope these notes may be useful if someone if the future will work with the tests.
Best regards,
directory-exists-p returns non nil for strings that are interpreted as existing directory names, as "" or ".." in unix (the documentation says: "Checks whether the file named by the pathname designator pathspec exists and if it is a directory"). Similarly, (pathname-absolute-p "") return T, or (pathname-relative-p "..") returns T, etc.
directory-pathname-p instead returns nil for unix directory names as "~" or "..", and this is counter-intuitive given the above results. I think that this functions should returns the same result as directory-exists-p for those special strings, since they are valid directory pathnames (at least in unix-like notation).
Am I missing something as to why this does not exist in cl-fad? I'd be happy to add it if it doesn't already exist in some form that I can't really discover.
Would you please consider adding a :description option to your system definition of cl-fad?
I just did a (ql:update-all-dists) before rebuilding some of my own code, and ran into a build error in cl-fad/temporary-files. The error was caused by the last form in the (eval-when ...); the cause appears to be that lispworks, like clisp, throws a simple-error instead of a type-error when asked to provide a non-existent logical pathname translation.
One possible solution is to replace #-clisp/#+clisp with #-(or clisp lispworks)/#+(or clisp lispworks), but I think that simply trapping "error" instead is a better solution.
I.e,
(handler-case
(logical-pathname-translations "TEMPORARY-FILES")
(error () ...))
cl-fad 0.7.0, delivered with quicklisp 2012-02-17 has doesn't work on CMUCL.
Assuming you have this version of quicklisp, here are the steps to reproduce:
lisps/cmucl-20c/bin/lisp -noinit -nositeinit
(push "quicklisp/dists/quicklisp/software/cl-fad-0.7.0/" asdf:*central-registry*)
(push "quicklisp/dists/quicklisp/software/alexandria-20130128-git/" asdf:*central-registry*)
(push "quicklisp/dists/quicklisp/software/bordeaux-threads-0.8.2/" asdf:*central-registry*)
(ql:quickload :cl-fad)
File-error in function LISP::FIND-LOGICAL-HOST:
Logical host not yet defined: "TEMPORARY-FILES"
[Condition of type KERNEL:SIMPLE-FILE-ERROR]
Restarts:
0: [CONTINUE ] Return NIL from load of #P"/home/testgrid/.cache/common-lisp/cmu-20c_release-20c__20c_unicode_-linux-x86/home/testgrid/quicklisp/dists/quicklisp/software/cl-fad-0.7.0/temporary-files.sse2f".
1: [TRY-RECOMPILING] Recompile temporary-files and try loading it again
2: [RETRY ] Retry
loading FASL for #<CL-SOURCE-FILE "cl-fad" "temporary-files">.
3: [ACCEPT ] Continue, treating
loading FASL for #<CL-SOURCE-FILE "cl-fad" "temporary-files">
as having been successful.
4: [ABORT ] Return to Top-Level.
Debug (type H for help)
(LISP::FIND-LOGICAL-HOST "TEMPORARY-FILES" T)
Current version (as in Quicklisp latest release) of cl-fad is not usable in CentOS 6 with SBCL out of the box, because it's using the sb-ext:delete-directory
function that appeared in SBCL 1.0.44.
I wonder how easy it is to add compatibility to that. If that's simple enough, then I think it's worth the trouble.
A user of my software (pgloader, which depends on cl-fad) reported some details:
[rjgonzale@cloud1 pgloader]$ cat /etc/redhat-release
CentOS release 6.4 (Final)
from epel I installed
[rjgonzale@cloud1 pgloader]$ sbcl --version
SBCL 1.0.38-3.el6
And the error is...
[rjgonzale@cloud1 pgloader]$ ./pgloader.lisp --help
; Upgrading ASDF from version 2.010 to version 2.26
Loading quicklisp and the pgloader project and its dependencies...
;
; compilation aborted because of fatal error:
; SB-INT:SIMPLE-READER-PACKAGE-ERROR at 13483 (line 282, column 30)
on
#<SB-SYS:FD-STREAM ;
for
"file /home/rjgonzale/quicklisp/dists/quicklisp/software/cl-fad-0.7.2/fad.lisp" ;
{10042479D1}>: ; Symbol "DELETE-DIRECTORY" not found in the SB-EXT
package.
I have a minor suggestion to prevent infinite symlink loops in walk directory, by keeping a list of the current recursion and throwing an error on detections of repeated files. To wit:
Observed on a Xubuntu 14.04 with SBCL.
To verify the issue, please
The resultant path cannot be opened...
In fad.test.lisp, close to the bottom, it creates a list of namestrings and bind the variabe list to it , and then searches in this list using find. But it searches for namestrings of truenames, which may be different, for example if the pathname is a link.
It causes the assertion to fail for "test 29".
Can be fixed by calling truename on the paths thatgo in the list, for example changing line 148:
(list (mapcar #'namestring (list-directory fad-dir))))
to
(list (mapcar #'namestring (mapcar 'truename(list-directory fad-dir)))))
The function get-default-temporary-directory
doesn't return a useful directory pathname on LispWorks. The problem is that probe-file
returns a truename, which has all of its unset components initialized to :unspecific
, and this prevents anything from being merged with it.
This patch fixes it:
diff --git a/temporary-files.lisp b/temporary-files.lisp
index 23f6f03..3c435d6 100644
--- a/temporary-files.lisp
+++ b/temporary-files.lisp
@@ -58,7 +58,8 @@
(defun get-default-temporary-directory ()
(or (directory-from-environment "TMPDIR")
#-clisp
- (probe-file #P"/tmp/")
+ (and (probe-file #P"/tmp/")
+ #P"/tmp/")
#+clisp
(and (ext:probe-directory #P"/tmp/")
#P"/tmp/")))
This happens by default on at least CCL and CMU CL; :follow-symlinks t
may thus not be a great default given how common broken symlinks are. Moreover, :follow-symlinks nil
only has an effect on SBCL and CCL; there's no way to work around this with CMU CL.
Update: A similar issue in OSICAT is discussed here: osicat/osicat#15
The download shortcut at http://weitz.de/cl-fad points to https://github.com/edicl/cl-fad/archive/master.zip whereas the Download and installation section points to http://weitz.de/files/cl-fad.tar.gz and this is somewhat confusing.
Is there something similar to python's tempfile.TemporaryDirectory() or this lisp code for creating a temp folder in cl-fad
?
(defvar *random-dir-chars*
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890")
(defun random-temp-dir (&optional (length 12))
(flet ((random-char ()
(alexandria:random-elt *random-dir-chars*)))
(let ((result (make-string length)))
(map-into result #'random-char)
(merge-pathnames (make-pathname :directory (list :relative result))
*notebooks-dir*))))
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.