⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftw.scm

📁 MSYS在windows下模拟了一个类unix的终端
💻 SCM
📖 第 1 页 / 共 2 页
字号:
;;        FILENAME parameter to `nftw'.;;;;   chdir';;        If this flag is given the current working directory is;;        changed to the directory containing the reported object;;        before the callback procedure is called.;;;;   depth';;        If this option is given the procedure visits first all files;;        and subdirectories before the callback procedure is called;;        for the directory itself (depth-first processing).  This;;        also means the type flag given to the callback procedure is;;        `directory-processed' and not `directory'.;;;;   The return value is computed in the same way as for `ftw'.;;   `nftw' returns #t if no failure occurred in `nftw' and all;;   callback procedure call return values are also #t.  For internal;;   errors such as memory problems the error `ftw-error' is thrown.;;   If the return value of a callback invocation is not #t this;;   very same value is returned.;;; Code:(define-module (ice-9 ftw)  :export (ftw nftw))(define (directory-files dir)  (let ((dir-stream (opendir dir)))    (let loop ((new (readdir dir-stream))               (acc '()))      (if (eof-object? new)          acc          (loop (readdir dir-stream)                (if (or (string=? "."  new)             ;;; ignore                        (string=? ".." new))            ;;; ignore                    acc                    (cons new acc)))))))(define (pathify . nodes)  (let loop ((nodes nodes)             (result ""))    (if (null? nodes)        (or (and (string=? "" result) "")            (substring result 1 (string-length result)))        (loop (cdr nodes) (string-append result "/" (car nodes))))))(define (abs? filename)  (char=? #\/ (string-ref filename 0)))(define (visited?-proc size)  (let ((visited (make-hash-table size)))    (lambda (s)      (and s (let ((ino (stat:ino s)))               (or (hash-ref visited ino)                   (begin                     (hash-set! visited ino #t)                     #f)))))))(define (stat-dir-readable?-proc uid gid)  (let ((uid (getuid))        (gid (getgid)))    (lambda (s)      (let* ((perms (stat:perms s))             (perms-bit-set? (lambda (mask)                               (not (= 0 (logand mask perms))))))        (or (and (= uid (stat:uid s))                 (perms-bit-set? #o400))            (and (= gid (stat:gid s))                 (perms-bit-set? #o040))            (perms-bit-set? #o004))))))(define (stat&flag-proc dir-readable? . control-flags)  (let* ((directory-flag (if (memq 'depth control-flags)                             'directory-processed                             'directory))         (stale-symlink-flag (if (memq 'nftw-style control-flags)                                 'stale-symlink                                 'symlink))         (physical? (memq 'physical control-flags))         (easy-flag (lambda (s)                      (let ((type (stat:type s)))                        (if (eq? 'directory type)                            (if (dir-readable? s)                                directory-flag                                'directory-not-readable)                            'regular)))))    (lambda (name)      (let ((s (false-if-exception (lstat name))))        (cond ((not s)               (values s 'invalid-stat))              ((eq? 'symlink (stat:type s))               (let ((s-follow (false-if-exception (stat name))))                 (cond ((not s-follow)                        (values s stale-symlink-flag))                       ((and s-follow physical?)                        (values s 'symlink))                       ((and s-follow (not physical?))                        (values s-follow (easy-flag s-follow))))))              (else (values s (easy-flag s))))))))(define (clean name)  (let ((last-char-index (1- (string-length name))))    (if (char=? #\/ (string-ref name last-char-index))        (substring name 0 last-char-index)        name)))(define (ftw filename proc . options)  (let* ((visited? (visited?-proc (cond ((memq 'hash-size options) => cadr)                                        (else 211))))         (stat&flag (stat&flag-proc                     (stat-dir-readable?-proc (getuid) (getgid)))))    (letrec ((go (lambda (fullname)                   (call-with-values (lambda () (stat&flag fullname))                     (lambda (s flag)                       (or (visited? s)                           (let ((ret (proc fullname s flag))) ; callback                             (or (eq? #t ret)                                 (throw 'ftw-early-exit ret))                             (and (eq? 'directory flag)                                  (for-each                                   (lambda (child)                                     (go (pathify fullname child)))                                   (directory-files fullname)))                             #t)))))))      (catch 'ftw-early-exit             (lambda () (go (clean filename)))             (lambda (key val) val)))))(define (nftw filename proc . control-flags)  (let* ((od (getcwd))                  ; orig dir         (odev (let ((s (false-if-exception (lstat filename))))                 (if s (stat:dev s) -1)))         (same-dev? (if (memq 'mount control-flags)                        (lambda (s) (= (stat:dev s) odev))                        (lambda (s) #t)))         (base-sub (lambda (name base) (substring name 0 base)))         (maybe-cd (if (memq 'chdir control-flags)                       (if (abs? filename)                           (lambda (fullname base)                             (or (= 0 base)                                 (chdir (base-sub fullname base))))                           (lambda (fullname base)                             (chdir                              (pathify od (base-sub fullname base)))))                       (lambda (fullname base) #t)))         (maybe-cd-back (if (memq 'chdir control-flags)                            (lambda () (chdir od))                            (lambda () #t)))         (depth-first? (memq 'depth control-flags))         (visited? (visited?-proc                    (cond ((memq 'hash-size control-flags) => cadr)                          (else 211))))         (has-kids? (if depth-first?                        (lambda (flag) (eq? flag 'directory-processed))                        (lambda (flag) (eq? flag 'directory))))         (stat&flag (apply stat&flag-proc                           (stat-dir-readable?-proc (getuid) (getgid))                           (cons 'nftw-style control-flags))))    (letrec ((go (lambda (fullname base level)                   (call-with-values (lambda () (stat&flag fullname))                     (lambda (s flag)                       (letrec ((self (lambda ()                                        (maybe-cd fullname base)                                        ;; the callback                                        (let ((ret (proc fullname s flag                                                         base level)))                                          (maybe-cd-back)                                          (or (eq? #t ret)                                              (throw 'nftw-early-exit ret)))))                                (kids (lambda ()                                        (and (has-kids? flag)                                             (for-each                                              (lambda (child)                                                (go (pathify fullname child)                                                    (1+ (string-length                                                         fullname))                                                    (1+ level)))                                              (directory-files fullname))))))                         (or (visited? s)                             (not (same-dev? s))                             (if depth-first?                                 (begin (kids) (self))                                 (begin (self) (kids)))))))                   #t)))      (let ((ret (catch 'nftw-early-exit                        (lambda () (go (clean filename) 0 0))                        (lambda (key val) val))))        (chdir od)        ret))));;; ftw.scm ends here

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -