Greetings, and thanks so much for this report!  Alas, the quote option
won't work as is, as the directory implementation depends on the shell
expanding wildcards.  gcl won't even build xgcl with your patch.  (Other
non-directory popen quotes might be good, though.)

I'll include the almost finished path.l lisp implementation for gcl in
case you have any comments.  It will require slight edits for
Version_2_6_13pre.

Take care,
-- 
Camm Maguire                                        c...@maguirefamily.org
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah
=============================================================================
path.l
=============================================================================
(in-package :si)

(defun asub (s l)
  (labels ((m (s l &optional (b 0))
              (let* ((z (reduce (lambda (y x &aux (f (string-match (car x) s 
b)))
                                  (if (when (>= f 0) (if y (> (car y) f) t)) 
(cons f x) y))
                                l :initial-value nil))
                     (d (pop z)))
                (cond (z (concatenate 'string (subseq s b d) (cdr z) (m s l (1+ 
d))))
                      ((eql b 0) s)
                      ((subseq s b))))))
    (m s l)))

(defun regexp-conv (stream)

  (let ((tem (make-array 10 :element-type 'character :fill-pointer 0)))
    (or (eql (read-char stream) #\")
        (error "sharp-u-reader reader needs a \" right after it"))
    (loop
     (let ((ch (read-char stream)))
       (cond ((eql ch #\") (return tem))
             ((eql ch #\\)
              (setq ch (read-char stream))
              (setq ch (or (cdr (assoc ch '((#\n . #\newline)
                                            (#\t . #\tab)
                                            (#\r . #\return))))
                           ch))))
       (vector-push-extend ch tem)))
    tem))

(defun sharp-u-reader (stream subchar arg)
  (declare (ignore subchar arg))
  (regexp-conv stream))

(defun sharp-v-reader (stream subchar arg)
  (declare (ignore subchar arg))
  `(load-time-value (compile-regexp ,(regexp-conv stream))))

(set-dispatch-macro-character #\# #\u 'sharp-u-reader)
(set-dispatch-macro-character #\# #\v 'sharp-v-reader)

(defconstant +glob-to-regexp+ (list (cons #v"\\?" "(.)")(cons #v"\\*" 
"(.*)")(cons #v"\\." "\\.")))

(defun mregexp (x) (compile-regexp (concatenate 'string "^" (asub x 
+glob-to-regexp+) "$")))

(defun peq (x y) (or (eq x y) (eq y :wild) (not y) (when (and (vectorp y) 
(stringp x)) (eql (string-match y x) 0))))

(defun match-list-1 (x)
  (labels ((m (&optional (s 0) (i 1) &aux (b (match-beginning i)))
              (unless (eql b -1)
                (let* ((e (match-end i))(r (m e (1+ i))))
                  (if (>= b s) (cons (subseq x b e) r) r)))))
    (or (m) x)))

(defun peqq (x y) 
  (cond ((or (eq x y) (eq y :wild) (not y)) x)
        ((when (and (vectorp y) (stringp x)) (eql (string-match y x) 0)) 
(match-list-1 x))
        (:false)))

(defun pedd (x y &optional f)
  (cond ((eq x y) x)
        ((unless f (not y)) x)
        ((and x y)
         (let* ((cx (pop x))(cy (pop y)))
           (if (eq cy :wild-inferiors)
               (let ((r (pedd (last x (length y)) y t)))
                 (if (eq r :false) r (cons cx (nconc (butlast x (length y)) 
r))))
             (let ((rq (peqq cx cy))(rd (pedd x y t)))
               (if (or (eq rq :false) (eq rd :false)) :false (cons rq rd))))))
        ((equal y '(:absolute :wild-inferiors)) x)
        (:false)))

(defun ped (x y &optional f)
  (cond ((eq x y))
        ((unless f (not y)))
        ((and x y)
         (let* ((cx (pop x))(cy (pop y)))
           (if (eq cy :wild-inferiors)
               (ped (last x (length y)) y t)
             (when (peq cx cy) (ped x y t)))))))

(defun pmp (lp lw)
  (mapcar (lambda (cp cw &aux (r (if (listp cp) (pedd cp cw) (peqq cp cw))))
            (if (eq :false r) (return-from pmp nil) r)) lp lw))
         
#.`(defun mlp (p &optional r &aux (p (pathname p)))
     (labels ((mrxp (x) (cond ((listp x) (mapcar #'mrxp x))((when r (stringp 
x)) (mregexp x))(x))))
       (list
        ,@(mapcar (lambda (x &aux (y (intern (concatenate 'string "PATHNAME-" 
(string-upcase x)))))
                    `(mrxp (,y p)))
                  '(:host :device :directory :name :type :version)))))

(defun pathname-match-p (p w)
  (pmp (mlp p) (mlp w t)))
  
(defun host-key (k) (if (stringp k) (string-right-trim ":" (string-downcase k)) 
k))

(defun (setf logical-pathname-translations) (v k &aux (k (host-key k)))
  (setf (cdr (or (assoc k *pathname-logical* :test 'equal) (car (push (cons k 
nil) *pathname-logical*)))) 
        (if (listp v) (mapcar (lambda (x) (list (parse-namestring (car x) k) 
(parse-namestring (cadr x)))) v) v)))

(defun logical-pathname-translations (k)
  (cdr (assoc (host-key k) *pathname-logical* :test 'equal)))

(remprop 'logical-pathname-translations 'si::setf-update-fn)

(defun match-list (fr s &aux (f (string-match fr s)))
  (labels ((m (&optional (i 1) &aux (c (cons (match-beginning i) (match-end 
i))))
              (unless (eql -1 (car c))
                (cons c (member-if (lambda (x) (> (cdr x) (cdr c))) (m (1+ 
i)))))))
    (unless (eql -1 f)
      (m))))

(defun repss (s fr to)
  (labels ((r (x l &optional (b 0) &aux (f (string-match #v"\\*" x b)))
              (if (eql f -1) (if (eql b 0) x (subseq x b))
                (concatenate 'string (subseq x b f) (subseq s (caar l) (cdar 
l)) (r x (cdr l) (1+ f))))))
    (r to (match-list fr s))))

(defun translate-pathname-component (x fr to &aux (to (if (if to (eq to :wild) 
t) "*" to)))
  (cond ((stringp to) (if (stringp x) (repss x fr to) x))
        ((listp to) (mapcar (lambda (x y z) (translate-pathname-component x y 
z)) x fr to))
        (to)))

(defun do-repl (x y)
  (labels ((r (x l &optional (b 0) &aux (f (string-match #v"\\*" x b)))
              (if (eql f -1) (if (eql b 0) x (subseq x b))
                (concatenate 'string (subseq x b f) (car l) (r x (cdr l) (1+ 
f))))))
    (r y x)))
  

(defun splice-pathname (lr lt)
  (mapcar (lambda (x y) (if (consp y) (splice-pathname x y) 
                          (cond ((if y (eq y :wild) t) x)
                                ((stringp y) (do-repl x y))
                                (y)))) lr lt))

#.`(defun translate-pathname (s fr to &key &aux (r (pathname-match-p s fr)))
     (apply 'make-pathname (cddr (mapcan 'list '(:host :device :directory :name 
:type :version) (splice-pathname r (mlp to))))))

(defun translate-logical-pathname (p &key &aux (p (pathname p)))
  (if (typep p 'logical-pathname)
      (apply 'translate-pathname p (assoc p (logical-pathname-translations 
(pathname-host p)) :test 'pathname-match-p))
    p))

(defconstant +d-type-alist+ (d-type-list))

(defun wreaddir (x y &aux (r (readdir x y))(c (consp r))(s (if c (car r) r)))
  (cond ((or (member s '("." "..") :test 'string-equal)) (wreaddir x y))
        (c (cons s (cdr (assoc (cdr r) +d-type-alist+))))
        (r)))

(defun getdir-loop (x y &aux (z (wreaddir x y)))
  (if z (cons z (getdir-loop x y)) (progn (closedir x) nil)))

(defun getsdir (x &optional (y :unknown) &aux (x (namestring x)))
  (getdir-loop (opendir x) (car (or (rassoc y +d-type-alist+) (rassoc :unknown 
+d-type-alist+)))))

(defun getdir (x &optional (y :unknown) &aux (x (namestring x)))
  (labels ((mp (s tp) (pathname (concatenate 'string x s (if (eq tp :directory) 
"/" "")))))
    (mapcar (lambda (q) (if (consp q) (cons (mp (pop q) q) q) (mp q y)))
            (getsdir x y))))
                 
(defun getrdir (x &aux (r (getdir x :directory)))
  (if r (mapcan 'getrdir r) (list x)))

(defun wjoind (l &aux (w (member :wild l)))
  (if w
      (let ((d (ldiff l w)))
        (mapcan (lambda (x) (wjoind (append d (cons x (cdr w))))) (getsdir 
(make-pathname :directory d) :directory)))
    (when (stat (make-pathname :directory l))
      (list l))))
         
(defun wjoinp (p)
  (mapcar (lambda (x) (make-pathname :directory x)) (wjoind (pathname-directory 
p))))

(defun wjoini (p &aux (l (pathname-directory p))(w (member :wild-inferiors l)))
  (when w
      (remove-if-not (lambda (x) (pathname-match-p x p))
                     (getrdir (make-pathname :directory (ldiff l w))))))

(defun exppathd (p)
  (or (wjoini p) (wjoinp p)))

(defun directory (p &key &aux (p (pathname p))(l (exppathd p)))
  (if (or (pathname-name p) (pathname-type p) (pathname-version p))
      (let ((pp (make-pathname :name (pathname-name p) :type (pathname-type p) 
:version (pathname-version p))))
        (mapcan (lambda (x) (when (pathname-match-p x pp) (list 
(merge-pathnames x p))))
                (mapcan (lambda (x) (mapcar 'pathname (getsdir x :file))) l)))
    l))
=============================================================================

Reply via email to