From 835ebc0785988034da89caf1896534c5f4f93435 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 1 May 2010 08:29:53 -0600 Subject: [PATCH] add in-directory --- collects/racket/private/for.rkt | 37 +++++++++++++++++++ .../scribblings/reference/filesystem.scrbl | 9 ++--- .../scribblings/reference/sequences.scrbl | 8 ++++ 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/collects/racket/private/for.rkt b/collects/racket/private/for.rkt index b496e1b63b..1a48248a21 100644 --- a/collects/racket/private/for.rkt +++ b/collects/racket/private/for.rkt @@ -41,6 +41,7 @@ in-hash-keys in-hash-values in-hash-pairs + in-directory in-sequences in-cycle @@ -1321,5 +1322,41 @@ (raise-type-error 'in-input-port-chars "input-port" p*)) (lambda () (read-char p*))) eof)]]))) + + (define in-directory + (case-lambda + [(dir) + (when dir + (unless (path-string? dir) + (raise-type-error 'in-directory "#f, path, or path string" dir))) + (let ([make-gen (lambda () + (call-with-continuation-prompt + (lambda () + (define (reply v) + (let/cc k + (abort-current-continuation + (default-continuation-prompt-tag) + (lambda () (cons (lambda () v) k))))) + (let loop ([dir (path->complete-path (or dir (current-directory)))] + [prefix dir]) + (for ([i (in-list (directory-list dir))]) + (let ([p (if prefix (build-path prefix i) i)] + [fp (build-path dir i)]) + (reply p) + (when (directory-exists? fp) + (loop fp p))))) + (reply eof))))]) + (make-do-sequence + (lambda () + (values + (lambda (gen) ((car gen))) + (lambda (gen) (call-with-continuation-prompt + (lambda () + ((cdr gen))))) + (make-gen) + (lambda (gen) (not (eof-object? ((car gen))))) + (lambda (val) #t) + (lambda (gen val) #t)))))] + [() (in-directory #f)])) ) diff --git a/collects/scribblings/reference/filesystem.scrbl b/collects/scribblings/reference/filesystem.scrbl index 9fae770b9a..99ebff5760 100644 --- a/collects/scribblings/reference/filesystem.scrbl +++ b/collects/scribblings/reference/filesystem.scrbl @@ -382,12 +382,11 @@ directory is not deleted successfully, the @defproc[(directory-list [path path-string? (current-directory)]) (listof path?)]{ +@margin-note{See also the @scheme[in-directory] sequence constructor.} + Returns a list of all files and directories in the directory specified -by @racket[path]. If @racket[path] is omitted, a list of files and -directories in the current directory is returned. Under @|AllUnix|, an -element of the list can start with @litchar{./~} if it would otherwise -start with @litchar{~}. Under Windows, an element of the list may -start with @litchar{\\?\REL\\}.} +by @racket[path]. Under Windows, an element of the list may start with +@litchar{\\?\REL\\}.} @defproc[(filesystem-root-list) (listof path?)]{ diff --git a/collects/scribblings/reference/sequences.scrbl b/collects/scribblings/reference/sequences.scrbl index 67f2711f5e..835676cd3d 100644 --- a/collects/scribblings/reference/sequences.scrbl +++ b/collects/scribblings/reference/sequences.scrbl @@ -193,6 +193,14 @@ its value from @scheme[hash] (as opposed to using @scheme[hash] directly as a sequence to get the key and value as separate values for each element).} +@defproc[(in-directory [dir (or/c #f path-string?)]) sequence?]{ + +Return a sequence that produces all of the paths for files, +directories, and links with @racket[dir]. If @racket[dir] is not +@racket[#f], then every produced path starts with @racket[dir] as its +prefix. If @racket[dir] is @racket[#f], then paths in and relative to +the current directory are produced.} + @defproc[(in-producer [producer procedure?] [stop any/c] [args any/c] ...) sequence?]{ Returns a sequence that contains values from sequential calls to