- (let ((quoted nil)
- (any-quotes nil)
- (last-regular-char nil)
- (index start))
- (flet ((flush-pending-regulars ()
- (when last-regular-char
- (pattern (if any-quotes
- (remove-backslashes namestr
- last-regular-char
- index)
- (subseq namestr last-regular-char index)))
- (setf any-quotes nil)
- (setf last-regular-char nil))))
- (loop
- (when (>= index end)
- (return))
- (let ((char (schar namestr index)))
- (cond (quoted
- (incf index)
- (setf quoted nil))
- ((char= char #\\)
- (setf quoted t)
- (setf any-quotes t)
- (unless last-regular-char
- (setf last-regular-char index))
- (incf index))
- ((char= char #\?)
- (flush-pending-regulars)
- (pattern :single-char-wild)
- (incf index))
- ((char= char #\*)
- (flush-pending-regulars)
- (pattern :multi-char-wild)
- (incf index))
- ((char= char #\[)
- (flush-pending-regulars)
- (let ((close-bracket
- (position #\] namestr :start index :end end)))
- (unless close-bracket
- (error 'namestring-parse-error
- :complaint "#\\[ with no corresponding #\\]"
- :namestring namestr
- :offset index))
- (pattern (list :character-set
- (subseq namestr
- (1+ index)
- close-bracket)))
- (setf index (1+ close-bracket))))
- (t
- (unless last-regular-char
- (setf last-regular-char index))
- (incf index)))))
- (flush-pending-regulars)))
- (cond ((null (pattern))
- "")
- ((null (cdr (pattern)))
- (let ((piece (first (pattern))))
- (typecase piece
- ((member :multi-char-wild) :wild)
- (simple-string piece)
- (t
- (make-pattern (pattern))))))
- (t
- (make-pattern (pattern)))))))
+ (let ((quoted nil)
+ (any-quotes nil)
+ (last-regular-char nil)
+ (index start))
+ (flet ((flush-pending-regulars ()
+ (when last-regular-char
+ (pattern (if any-quotes
+ (remove-backslashes namestr
+ last-regular-char
+ index)
+ (subseq namestr last-regular-char index)))
+ (setf any-quotes nil)
+ (setf last-regular-char nil))))
+ (loop
+ (when (>= index end)
+ (return))
+ (let ((char (schar namestr index)))
+ (cond (quoted
+ (incf index)
+ (setf quoted nil))
+ ((char= char #\\)
+ (setf quoted t)
+ (setf any-quotes t)
+ (unless last-regular-char
+ (setf last-regular-char index))
+ (incf index))
+ ((char= char #\?)
+ (flush-pending-regulars)
+ (pattern :single-char-wild)
+ (incf index))
+ ((char= char #\*)
+ (flush-pending-regulars)
+ (pattern :multi-char-wild)
+ (incf index))
+ ((char= char #\[)
+ (flush-pending-regulars)
+ (let ((close-bracket
+ (position #\] namestr :start index :end end)))
+ (unless close-bracket
+ (error 'namestring-parse-error
+ :complaint "#\\[ with no corresponding #\\]"
+ :namestring namestr
+ :offset index))
+ (pattern (cons :character-set
+ (subseq namestr
+ (1+ index)
+ close-bracket)))
+ (setf index (1+ close-bracket))))
+ (t
+ (unless last-regular-char
+ (setf last-regular-char index))
+ (incf index)))))
+ (flush-pending-regulars)))
+ (cond ((null (pattern))
+ "")
+ ((null (cdr (pattern)))
+ (let ((piece (first (pattern))))
+ (typecase piece
+ ((member :multi-char-wild) :wild)
+ (simple-string piece)
+ (t
+ (make-pattern (pattern))))))
+ (t
+ (make-pattern (pattern)))))))
- nil ; no device for Unix namestrings
- (collect ((dirs))
- (dolist (piece pieces)
- (let ((piece-start (car piece))
- (piece-end (cdr piece)))
- (unless (= piece-start piece-end)
- (cond ((string= namestr ".."
- :start1 piece-start
- :end1 piece-end)
- (dirs :up))
- ((string= namestr "**"
- :start1 piece-start
- :end1 piece-end)
- (dirs :wild-inferiors))
- (t
- (dirs (maybe-make-pattern namestr
- piece-start
- piece-end)))))))
- (cond (absolute
- (cons :absolute (dirs)))
- ((dirs)
- (cons :relative (dirs)))
- (t
- nil)))
- name
- type
- version))))
+ nil ; no device for Unix namestrings
+ (collect ((dirs))
+ (dolist (piece pieces)
+ (let ((piece-start (car piece))
+ (piece-end (cdr piece)))
+ (unless (= piece-start piece-end)
+ (cond ((string= namestring ".."
+ :start1 piece-start
+ :end1 piece-end)
+ (dirs :up))
+ ((string= namestring "**"
+ :start1 piece-start
+ :end1 piece-end)
+ (dirs :wild-inferiors))
+ (t
+ (dirs (maybe-make-pattern namestring
+ piece-start
+ piece-end)))))))
+ (cond (absolute
+ (cons :absolute (dirs)))
+ ((dirs)
+ (cons :relative (dirs)))
+ (t
+ nil)))
+ name
+ type
+ version))))
+
+(defun parse-native-unix-namestring (namestring start end)
+ (declare (type simple-string namestring)
+ (type index start end))
+ (setf namestring (coerce namestring 'simple-base-string))
+ (multiple-value-bind (absolute ranges)
+ (split-at-slashes namestring start end)
+ (let* ((components (loop for ((start . end) . rest) on ranges
+ for piece = (subseq namestring start end)
+ collect (if (and (string= piece "..") rest)
+ :up
+ piece)))
+ (name-and-type
+ (let* ((end (first (last components)))
+ (dot (position #\. end :from-end t)))
+ ;; FIXME: can we get this dot-interpretation knowledge
+ ;; from existing code? EXTRACT-NAME-TYPE-AND-VERSION
+ ;; does slightly more work than that.
+ (cond
+ ((string= end "")
+ (list nil nil))
+ ((and dot (> dot 0))
+ (list (subseq end 0 dot) (subseq end (1+ dot))))
+ (t
+ (list end nil))))))
+ (values nil
+ nil
+ (cons (if absolute :absolute :relative) (butlast components))
+ (first name-and-type)
+ (second name-and-type)
+ nil))))
- (concatenate 'simple-string
- (unparse-unix-directory pathname)
- (unparse-unix-file pathname)))
+ (concatenate 'simple-base-string
+ (unparse-unix-directory pathname)
+ (unparse-unix-file pathname)))
+
+(defun unparse-native-unix-namestring (pathname)
+ (declare (type pathname pathname))
+ (let ((directory (pathname-directory pathname))
+ (name (pathname-name pathname))
+ (type (pathname-type pathname)))
+ (coerce
+ (with-output-to-string (s)
+ (ecase (car directory)
+ (:absolute (write-char #\/ s))
+ (:relative))
+ (dolist (piece (cdr directory))
+ (typecase piece
+ ((member :up) (write-string ".." s))
+ (string (write-string piece s))
+ (t (error "ungood piece in NATIVE-NAMESTRING: ~S" piece)))
+ (write-char #\/ s))
+ (when name
+ (unless (stringp name)
+ (error "non-STRING name in NATIVE-NAMESTRING: ~S" name))
+ (write-string name s)
+ (when type
+ (unless (stringp type)
+ (error "non-STRING type in NATIVE-NAMESTRING: ~S" name))
+ (write-char #\. s)
+ (write-string type s))))
+ 'simple-base-string)))
- (defaults-directory (%pathname-directory defaults))
- (prefix-len (length defaults-directory))
- (result-directory
- (cond ((and (> prefix-len 1)
- (>= (length pathname-directory) prefix-len)
- (compare-component (subseq pathname-directory
- 0 prefix-len)
- defaults-directory))
- ;; Pathname starts with a prefix of default. So
- ;; just use a relative directory from then on out.
- (cons :relative (nthcdr prefix-len pathname-directory)))
- ((eq (car pathname-directory) :absolute)
- ;; We are an absolute pathname, so we can just use it.
- pathname-directory)
- (t
- ;; We are a relative directory. So we lose.
- (lose)))))
- (strings (unparse-unix-directory-list result-directory)))
+ (defaults-directory (%pathname-directory defaults))
+ (prefix-len (length defaults-directory))
+ (result-directory
+ (cond ((null pathname-directory) '(:relative))
+ ((eq (car pathname-directory) :relative)
+ pathname-directory)
+ ((and (> prefix-len 1)
+ (>= (length pathname-directory) prefix-len)
+ (compare-component (subseq pathname-directory
+ 0 prefix-len)
+ defaults-directory))
+ ;; Pathname starts with a prefix of default. So
+ ;; just use a relative directory from then on out.
+ (cons :relative (nthcdr prefix-len pathname-directory)))
+ ((eq (car pathname-directory) :absolute)
+ ;; We are an absolute pathname, so we can just use it.
+ pathname-directory)
+ (t
+ (bug "Bad fallthrough in ~S" 'unparse-unix-enough)))))
+ (strings (unparse-unix-directory-list result-directory)))
- (type-needed (and pathname-type
- (not (eq pathname-type :unspecific))))
- (pathname-name (%pathname-name pathname))
- (name-needed (or type-needed
- (and pathname-name
- (not (compare-component pathname-name
- (%pathname-name
- defaults)))))))
- (when name-needed
- (unless pathname-name (lose))
- (when (and (null pathname-type)
- (position #\. pathname-name :start 1))
- (error "too many dots in the name: ~S" pathname))
- (strings (unparse-unix-piece pathname-name)))
- (when type-needed
- (when (or (null pathname-type) (eq pathname-type :unspecific))
- (lose))
- (when (typep pathname-type 'simple-base-string)
- (when (position #\. pathname-type)
- (error "type component can't have a #\. inside: ~S" pathname)))
- (strings ".")
- (strings (unparse-unix-piece pathname-type))))
+ (type-needed (and pathname-type
+ (not (eq pathname-type :unspecific))))
+ (pathname-name (%pathname-name pathname))
+ (name-needed (or type-needed
+ (and pathname-name
+ (not (compare-component pathname-name
+ (%pathname-name
+ defaults)))))))
+ (when name-needed
+ (unless pathname-name (lose))
+ (when (and (null pathname-type)
+ (position #\. pathname-name :start 1))
+ (error "too many dots in the name: ~S" pathname))
+ (strings (unparse-unix-piece pathname-name)))
+ (when type-needed
+ (when (or (null pathname-type) (eq pathname-type :unspecific))
+ (lose))
+ (when (typep pathname-type 'simple-base-string)
+ (when (position #\. pathname-type)
+ (error "type component can't have a #\. inside: ~S" pathname)))
+ (strings ".")
+ (strings (unparse-unix-piece pathname-type))))
- `(if follow-links
- (sb!unix:unix-stat ,name)
- (sb!unix:unix-lstat ,name)))
- (with-directory-node-noted ((head) &body body)
- `(multiple-value-bind (res dev ino mode)
- (unix-xstat ,head)
- (when (and res (eql (logand mode sb!unix:s-ifmt)
- sb!unix:s-ifdir))
- (let ((nodes (cons (cons dev ino) nodes)))
- ,@body))))
- (with-directory-node-removed ((head) &body body)
- `(multiple-value-bind (res dev ino mode)
- (unix-xstat ,head)
- (when (and res (eql (logand mode sb!unix:s-ifmt)
- sb!unix:s-ifdir))
- (let ((nodes (remove (cons dev ino) nodes :test #'equal)))
- ,@body)))))
+ `(if follow-links
+ (sb!unix:unix-stat ,name)
+ (sb!unix:unix-lstat ,name)))
+ (with-directory-node-noted ((head) &body body)
+ `(multiple-value-bind (res dev ino mode)
+ (unix-xstat ,head)
+ (when (and res (eql (logand mode sb!unix:s-ifmt)
+ sb!unix:s-ifdir))
+ (let ((nodes (cons (cons dev ino) nodes)))
+ ,@body))))
+ (with-directory-node-removed ((head) &body body)
+ `(multiple-value-bind (res dev ino mode)
+ (unix-xstat ,head)
+ (when (and res (eql (logand mode sb!unix:s-ifmt)
+ sb!unix:s-ifdir))
+ (let ((nodes (remove (cons dev ino) nodes :test #'equal)))
+ ,@body)))))
- (let ((piece (car tail)))
- (etypecase piece
- (simple-string
- (let ((head (concatenate 'base-string head piece)))
- (with-directory-node-noted (head)
- (%enumerate-directories (concatenate 'base-string head "/")
- (cdr tail) pathname
- verify-existence follow-links
- nodes function))))
- ((member :wild-inferiors)
- ;; now with extra error case handling from CLHS
- ;; 19.2.2.4.3 -- CSR, 2004-01-24
- (when (member (cadr tail) '(:up :back))
- (error 'simple-file-error
- :pathname pathname
- :format-control "~@<invalid use of ~S after :WILD-INFERIORS~@:>."
- :format-arguments (list (cadr tail))))
- (%enumerate-directories head (rest tail) pathname
- verify-existence follow-links
- nodes function)
- (dolist (name (ignore-errors (directory-lispy-filenames head)))
- (let ((subdir (concatenate 'base-string head name)))
- (multiple-value-bind (res dev ino mode)
- (unix-xstat subdir)
- (declare (type (or fixnum null) mode))
- (when (and res (eql (logand mode sb!unix:s-ifmt)
- sb!unix:s-ifdir))
- (unless (dolist (dir nodes nil)
- (when (and (eql (car dir) dev)
- (eql (cdr dir) ino))
- (return t)))
- (let ((nodes (cons (cons dev ino) nodes))
- (subdir (concatenate 'base-string subdir "/")))
- (%enumerate-directories subdir tail pathname
- verify-existence follow-links
- nodes function))))))))
- ((or pattern (member :wild))
- (dolist (name (directory-lispy-filenames head))
- (when (or (eq piece :wild) (pattern-matches piece name))
- (let ((subdir (concatenate 'base-string head name)))
- (multiple-value-bind (res dev ino mode)
- (unix-xstat subdir)
- (declare (type (or fixnum null) mode))
- (when (and res
- (eql (logand mode sb!unix:s-ifmt)
- sb!unix:s-ifdir))
- (let ((nodes (cons (cons dev ino) nodes))
- (subdir (concatenate 'base-string subdir "/")))
- (%enumerate-directories subdir (rest tail) pathname
- verify-existence follow-links
- nodes function))))))))
- ((member :up)
- (when (string= head "/")
- (error 'simple-file-error
- :pathname pathname
- :format-control "~@<invalid use of :UP after :ABSOLUTE.~@:>"))
- (with-directory-node-removed (head)
- (let ((head (concatenate 'base-string head "..")))
- (with-directory-node-noted (head)
- (%enumerate-directories (concatenate 'base-string head "/")
- (rest tail) pathname
- verify-existence follow-links
- nodes function)))))
- ((member :back)
- ;; :WILD-INFERIORS is handled above, so the only case here
- ;; should be (:ABSOLUTE :BACK)
- (aver (string= head "/"))
- (error 'simple-file-error
- :pathname pathname
- :format-control "~@<invalid use of :BACK after :ABSOLUTE.~@:>"))))
- (%enumerate-files head pathname verify-existence function))))
+ (let ((piece (car tail)))
+ (etypecase piece
+ (simple-string
+ (let ((head (concatenate 'base-string head piece)))
+ (with-directory-node-noted (head)
+ (%enumerate-directories (concatenate 'base-string head "/")
+ (cdr tail) pathname
+ verify-existence follow-links
+ nodes function))))
+ ((member :wild-inferiors)
+ ;; now with extra error case handling from CLHS
+ ;; 19.2.2.4.3 -- CSR, 2004-01-24
+ (when (member (cadr tail) '(:up :back))
+ (error 'simple-file-error
+ :pathname pathname
+ :format-control "~@<invalid use of ~S after :WILD-INFERIORS~@:>."
+ :format-arguments (list (cadr tail))))
+ (%enumerate-directories head (rest tail) pathname
+ verify-existence follow-links
+ nodes function)
+ (dolist (name (ignore-errors (directory-lispy-filenames head)))
+ (let ((subdir (concatenate 'base-string head name)))
+ (multiple-value-bind (res dev ino mode)
+ (unix-xstat subdir)
+ (declare (type (or fixnum null) mode))
+ (when (and res (eql (logand mode sb!unix:s-ifmt)
+ sb!unix:s-ifdir))
+ (unless (dolist (dir nodes nil)
+ (when (and (eql (car dir) dev)
+ (eql (cdr dir) ino))
+ (return t)))
+ (let ((nodes (cons (cons dev ino) nodes))
+ (subdir (concatenate 'base-string subdir "/")))
+ (%enumerate-directories subdir tail pathname
+ verify-existence follow-links
+ nodes function))))))))
+ ((or pattern (member :wild))
+ (dolist (name (directory-lispy-filenames head))
+ (when (or (eq piece :wild) (pattern-matches piece name))
+ (let ((subdir (concatenate 'base-string head name)))
+ (multiple-value-bind (res dev ino mode)
+ (unix-xstat subdir)
+ (declare (type (or fixnum null) mode))
+ (when (and res
+ (eql (logand mode sb!unix:s-ifmt)
+ sb!unix:s-ifdir))
+ (let ((nodes (cons (cons dev ino) nodes))
+ (subdir (concatenate 'base-string subdir "/")))
+ (%enumerate-directories subdir (rest tail) pathname
+ verify-existence follow-links
+ nodes function))))))))
+ ((member :up)
+ (when (string= head "/")
+ (error 'simple-file-error
+ :pathname pathname
+ :format-control "~@<invalid use of :UP after :ABSOLUTE.~@:>"))
+ (with-directory-node-removed (head)
+ (let ((head (concatenate 'base-string head "..")))
+ (with-directory-node-noted (head)
+ (%enumerate-directories (concatenate 'base-string head "/")
+ (rest tail) pathname
+ verify-existence follow-links
+ nodes function)))))
+ ((member :back)
+ ;; :WILD-INFERIORS is handled above, so the only case here
+ ;; should be (:ABSOLUTE :BACK)
+ (aver (string= head "/"))
+ (error 'simple-file-error
+ :pathname pathname
+ :format-control "~@<invalid use of :BACK after :ABSOLUTE.~@:>"))))
+ (%enumerate-files head pathname verify-existence function))))
- (/noshow0 "UNSPECIFIC, more or less")
- (when (or (not verify-existence)
- (sb!unix:unix-file-kind directory))
- (funcall function directory)))
- ((or (pattern-p name)
- (pattern-p type)
- (eq name :wild)
- (eq type :wild))
- (/noshow0 "WILD, more or less")
- ;; I IGNORE-ERRORS here just because the original CMU CL
- ;; code did. I think the intent is that it's not an error
- ;; to request matches to a wild pattern when no matches
- ;; exist, but I haven't tried to figure out whether
- ;; everything is kosher. (E.g. what if we try to match a
- ;; wildcard but we don't have permission to read one of the
- ;; relevant directories?) -- WHN 2001-04-17
- (dolist (complete-filename (ignore-errors
- (directory-lispy-filenames directory)))
- (multiple-value-bind
- (file-name file-type file-version)
- (let ((*ignore-wildcards* t))
- (extract-name-type-and-version
- complete-filename 0 (length complete-filename)))
- (when (and (components-match file-name name)
- (components-match file-type type)
- (components-match file-version version))
- (funcall function
- (concatenate 'base-string
- directory
- complete-filename))))))
- (t
- (/noshow0 "default case")
- (let ((file (concatenate 'base-string directory name)))
- (/noshow "computed basic FILE")
- (unless (or (null type) (eq type :unspecific))
- (/noshow0 "tweaking FILE for more-or-less-:UNSPECIFIC case")
- (setf file (concatenate 'base-string file "." type)))
- (unless (member version '(nil :newest :wild :unspecific))
- (/noshow0 "tweaking FILE for more-or-less-:WILD case")
- (setf file (concatenate 'base-string file "."
- (quick-integer-to-string version))))
- (/noshow0 "finished possibly tweaking FILE")
- (when (or (not verify-existence)
- (sb!unix:unix-file-kind file t))
- (/noshow0 "calling FUNCTION on FILE")
- (funcall function file)))))))
+ (/noshow0 "UNSPECIFIC, more or less")
+ (let ((directory (coerce directory 'base-string)))
+ (when (or (not verify-existence)
+ (sb!unix:unix-file-kind directory))
+ (funcall function directory))))
+ ((or (pattern-p name)
+ (pattern-p type)
+ (eq name :wild)
+ (eq type :wild))
+ (/noshow0 "WILD, more or less")
+ ;; I IGNORE-ERRORS here just because the original CMU CL
+ ;; code did. I think the intent is that it's not an error
+ ;; to request matches to a wild pattern when no matches
+ ;; exist, but I haven't tried to figure out whether
+ ;; everything is kosher. (E.g. what if we try to match a
+ ;; wildcard but we don't have permission to read one of the
+ ;; relevant directories?) -- WHN 2001-04-17
+ (dolist (complete-filename (ignore-errors
+ (directory-lispy-filenames directory)))
+ (multiple-value-bind
+ (file-name file-type file-version)
+ (let ((*ignore-wildcards* t))
+ (extract-name-type-and-version
+ complete-filename 0 (length complete-filename)))
+ (when (and (components-match file-name name)
+ (components-match file-type type)
+ (components-match file-version version))
+ (funcall function
+ (concatenate 'base-string
+ directory
+ complete-filename))))))
+ (t
+ (/noshow0 "default case")
+ (let ((file (concatenate 'base-string directory name)))
+ (/noshow "computed basic FILE")
+ (unless (or (null type) (eq type :unspecific))
+ (/noshow0 "tweaking FILE for more-or-less-:UNSPECIFIC case")
+ (setf file (concatenate 'base-string file "." type)))
+ (unless (member version '(nil :newest :wild :unspecific))
+ (/noshow0 "tweaking FILE for more-or-less-:WILD case")
+ (setf file (concatenate 'base-string file "."
+ (quick-integer-to-string version))))
+ (/noshow0 "finished possibly tweaking FILE")
+ (when (or (not verify-existence)
+ (sb!unix:unix-file-kind file t))
+ (/noshow0 "calling FUNCTION on FILE")
+ (funcall function file)))))))
- (write-to-string n :base 10 :radix nil))
- ((zerop n) "0")
- ((eql n 1) "1")
- ((minusp n)
- (concatenate 'simple-base-string "-"
- (the simple-base-string (quick-integer-to-string (- n)))))
- (t
- (do* ((len (1+ (truncate (integer-length n) 3)))
- (res (make-string len :element-type 'base-char))
- (i (1- len) (1- i))
- (q n)
- (r 0))
- ((zerop q)
- (incf i)
- (replace res res :start2 i :end2 len)
- (shrink-vector res (- len i)))
- (declare (simple-string res)
- (fixnum len i r q))
- (multiple-value-setq (q r) (truncate q 10))
- (setf (schar res i) (schar "0123456789" r))))))
+ (write-to-string n :base 10 :radix nil))
+ ((zerop n) "0")
+ ((eql n 1) "1")
+ ((minusp n)
+ (concatenate 'simple-base-string "-"
+ (the simple-base-string (quick-integer-to-string (- n)))))
+ (t
+ (do* ((len (1+ (truncate (integer-length n) 3)))
+ (res (make-string len :element-type 'base-char))
+ (i (1- len) (1- i))
+ (q n)
+ (r 0))
+ ((zerop q)
+ (incf i)
+ (replace res res :start2 i :end2 len)
+ (%shrink-vector res (- len i)))
+ (declare (simple-string res)
+ (fixnum len i r q))
+ (multiple-value-setq (q r) (truncate q 10))
+ (setf (schar res i) (schar "0123456789" r))))))
- (or (equal (pathname-directory x) '(:relative))
- ;; KLUDGE: I'm not sure this second check should really
- ;; have to be here. But on sbcl-0.6.12.7,
- ;; (PATHNAME-DIRECTORY (PATHNAME "")) is NIL, and
- ;; (PATHNAME "") seems to act like an empty relative
- ;; pathname, so in order to work with that, I test
- ;; for NIL here. -- WHN 2001-05-18
- (null (pathname-directory x)))
- (null (pathname-name x))
- (null (pathname-type x)))
- ;; (The ANSI definition of "pathname specifier" has
+ (or (equal (pathname-directory x) '(:relative))
+ ;; KLUDGE: I'm not sure this second check should really
+ ;; have to be here. But on sbcl-0.6.12.7,
+ ;; (PATHNAME-DIRECTORY (PATHNAME "")) is NIL, and
+ ;; (PATHNAME "") seems to act like an empty relative
+ ;; pathname, so in order to work with that, I test
+ ;; for NIL here. -- WHN 2001-05-18
+ (null (pathname-directory x)))
+ (null (pathname-name x))
+ (null (pathname-type x)))
+ ;; (The ANSI definition of "pathname specifier" has
- ((loop-possible-wild-inferiors-matches
- (lower-bound bounding-sequence order)
- (let ((index (gensym)) (g2 (gensym)) (g3 (gensym)) (l (gensym)))
- `(let ((,l (length ,bounding-sequence)))
- (loop for ,index from ,lower-bound to ,l
- append (mapcar (lambda (,g2)
- (append
- (butlast ,bounding-sequence (- ,l ,index))
- ,g2))
- (mapcar
- (lambda (,g3)
- (append
- (if (eq (car (nthcdr ,index ,bounding-sequence))
- :wild-inferiors)
- '(:wild-inferiors)
- nil) ,g3))
- (intersect-directory-helper
- ,@(if order
- `((nthcdr ,index one) (cdr two))
- `((cdr one) (nthcdr ,index two)))))))))))
+ ((loop-possible-wild-inferiors-matches
+ (lower-bound bounding-sequence order)
+ (let ((index (gensym)) (g2 (gensym)) (g3 (gensym)) (l (gensym)))
+ `(let ((,l (length ,bounding-sequence)))
+ (loop for ,index from ,lower-bound to ,l
+ append (mapcar (lambda (,g2)
+ (append
+ (butlast ,bounding-sequence (- ,l ,index))
+ ,g2))
+ (mapcar
+ (lambda (,g3)
+ (append
+ (if (eq (car (nthcdr ,index ,bounding-sequence))
+ :wild-inferiors)
+ '(:wild-inferiors)
+ nil) ,g3))
+ (intersect-directory-helper
+ ,@(if order
+ `((nthcdr ,index one) (cdr two))
+ `((cdr one) (nthcdr ,index two)))))))))))
- ((and (eq (car one) :wild-inferiors)
- (eq (car two) :wild-inferiors))
- (delete-duplicates
- (append (mapcar (lambda (x) (cons :wild-inferiors x))
- (intersect-directory-helper (cdr one) (cdr two)))
- (loop-possible-wild-inferiors-matches 2 one t)
- (loop-possible-wild-inferiors-matches 2 two nil))
- :test 'equal))
- ((eq (car one) :wild-inferiors)
- (delete-duplicates (loop-possible-wild-inferiors-matches 0 two nil)
- :test 'equal))
- ((eq (car two) :wild-inferiors)
- (delete-duplicates (loop-possible-wild-inferiors-matches 0 one t)
- :test 'equal))
- ((and (null one) (null two)) (list nil))
- ((null one) nil)
- ((null two) nil)
- (t (and (simple-intersection (car one) (car two))
- (mapcar (lambda (x) (cons (simple-intersection
- (car one) (car two)) x))
- (intersect-directory-helper (cdr one) (cdr two)))))))))
+ ((and (eq (car one) :wild-inferiors)
+ (eq (car two) :wild-inferiors))
+ (delete-duplicates
+ (append (mapcar (lambda (x) (cons :wild-inferiors x))
+ (intersect-directory-helper (cdr one) (cdr two)))
+ (loop-possible-wild-inferiors-matches 2 one t)
+ (loop-possible-wild-inferiors-matches 2 two nil))
+ :test 'equal))
+ ((eq (car one) :wild-inferiors)
+ (delete-duplicates (loop-possible-wild-inferiors-matches 0 two nil)
+ :test 'equal))
+ ((eq (car two) :wild-inferiors)
+ (delete-duplicates (loop-possible-wild-inferiors-matches 0 one t)
+ :test 'equal))
+ ((and (null one) (null two)) (list nil))
+ ((null one) nil)
+ ((null two) nil)
+ (t (and (simple-intersection (car one) (car two))
+ (mapcar (lambda (x) (cons (simple-intersection
+ (car one) (car two)) x))
+ (intersect-directory-helper (cdr one) (cdr two)))))))))
- (aver (not (logical-pathname-p pathname)))
- (!enumerate-matches (match pathname)
- (let* ((*ignore-wildcards* t)
- ;; FIXME: Why not TRUENAME? As reported by
- ;; Milan Zamazal sbcl-devel 2003-10-05, using
- ;; TRUENAME causes a race condition whereby
- ;; removal of a file during the directory
- ;; operation causes an error. It's not clear
- ;; what the right thing to do is, though. --
- ;; CSR, 2003-10-13
- (truename (probe-file match)))
- (when truename
- (setf (gethash (namestring truename) truenames)
- truename)))))
- (do-directory (pathname)
- (if (logical-pathname-p pathname)
- (let ((host (intern-logical-host (pathname-host pathname))))
- (dolist (x (logical-host-canon-transls host))
- (destructuring-bind (from to) x
- (let ((intersections
- (pathname-intersections pathname from)))
- (dolist (p intersections)
- (do-directory (translate-pathname p from to)))))))
- (do-physical-directory pathname))))
+ (aver (not (logical-pathname-p pathname)))
+ (!enumerate-matches (match pathname)
+ (let* ((*ignore-wildcards* t)
+ ;; FIXME: Why not TRUENAME? As reported by
+ ;; Milan Zamazal sbcl-devel 2003-10-05, using
+ ;; TRUENAME causes a race condition whereby
+ ;; removal of a file during the directory
+ ;; operation causes an error. It's not clear
+ ;; what the right thing to do is, though. --
+ ;; CSR, 2003-10-13
+ (truename (probe-file match)))
+ (when truename
+ (setf (gethash (namestring truename) truenames)
+ truename)))))
+ (do-directory (pathname)
+ (if (logical-pathname-p pathname)
+ (let ((host (intern-logical-host (pathname-host pathname))))
+ (dolist (x (logical-host-canon-transls host))
+ (destructuring-bind (from to) x
+ (let ((intersections
+ (pathname-intersections pathname from)))
+ (dolist (p intersections)
+ (do-directory (translate-pathname p from to)))))))
+ (do-physical-directory pathname))))
- do (let ((newpath (make-pathname
- :host (pathname-host pathname)
- :device (pathname-device pathname)
- :directory (subseq dir 0 i))))
- (unless (probe-file newpath)
- (let ((namestring (namestring newpath)))
- (when verbose
- (format *standard-output*
- "~&creating directory: ~A~%"
- namestring))
- (sb!unix:unix-mkdir namestring mode)
- (unless (probe-file namestring)
- (error 'simple-file-error
- :pathname pathspec
- :format-control "can't create directory ~A"
- :format-arguments (list namestring)))
- (setf created-p t)))))
+ do (let ((newpath (make-pathname
+ :host (pathname-host pathname)
+ :device (pathname-device pathname)
+ :directory (subseq dir 0 i))))
+ (unless (probe-file newpath)
+ (let ((namestring (coerce (namestring newpath) 'base-string)))
+ (when verbose
+ (format *standard-output*
+ "~&creating directory: ~A~%"
+ namestring))
+ (sb!unix:unix-mkdir namestring mode)
+ (unless (probe-file namestring)
+ (restart-case (error 'simple-file-error
+ :pathname pathspec
+ :format-control "can't create directory ~A"
+ :format-arguments (list namestring))
+ (retry ()
+ :report "Retry directory creation."
+ (ensure-directories-exist pathspec :verbose verbose :mode mode))
+ (continue ()
+ :report "Continue as if directory creation was successful."
+ nil)))
+ (setf created-p t)))))