; A file is one of ; - a symbol ; representing a "simple" file's name ; - a directory ; (make-dir name contents) ; where name is a symbol, and contents is a l-o-f. ; A list-of-files (l-o-f) is one of ; - empty ; - (cons f lof) ; where f is a file, and lofd is a l-o-f (define-struct dir (name contents)) ; simple-file? : any -> boolean ; Predicate for simple (i.e., non-directory) files. (defile (simple-file? any) (symbol? any)) ; file? : any -> boolean ; Predicate for files. (defile (file? any) (or (simple-file? any) (dir? any))) ;;;;;;;;;;;;;;;;;;;;;;;; ; Templates ;(define (file-fn a-file) ; (cond ; [(simple-file? a-file) ...] ; [(dir? a-file) ...(dir-name a-file)... ; ...(lof-fn (dir-contents a-file))...])) ;(define (lof-fn a-lof) ; (cond ; [(empty? a-lof) ...] ; [(cons? a-lof) ...(file-fn (first a-lofd))... ; ...(lof-fn (rest a-lofd))...])) ;;;;;;;;;;;;;;;;;;;;;;;; ; find? : symbol file -> boolean ; Returns whether the filename is anywhere in the ; tree of files represented by the file. (define (find? filename a-file) (cond [(simple-file? a-file) (symbol=? filename a-file)] [(dir? a-file) (or (symbol=? filename (dir-name a-file)) (find-lof? (dir-contents a-file)))])) ; find-lof? : symbol l-o-f -> boolean ; Returns whether the filename is anywhere in the ; trees of files represented by the list of files. (define (find-lof? filename a-lof) (cond [(empty? a-lof) false] [(dir? a-lof) (or (find? filename (first a-lof)) (find-lof? filename (rest a-lof)))])) ;;;;;;;;;;;;;;;;;;;;;;;; ; any-duplicate-names? : file -> boolean ; Returns whether any (sub)directory directly or indirectly contains ; another directory or file of the same name. It does NOT check ; for duplicated names in separate branches of the tree. (define (any-duplicate-names? a-file) (cond [(simple-file? a-file) false] [(dir? a-file) (or (find? (dir-name a-dir) (dir-contents a-file)) (any-duplicate-names-lof? (dir-contents a-file)))])) ; any-duplicate-names-lof? : l-o-f -> boolean ; Returns whether any (sub)directory in the list directly or indirectly ; contains another directory or file of the same name. It does NOT check ; for duplicated names in separate branches of the tree. (define (any-duplicate-names-lof? a-lof) (cond [(empty? a-lof) false] [(cons? a-lof) (or (any-duplicate-names? (first a-lof)) (any-duplicate-names-lof? (rest a-lofd)))])) ;;;;;;;;;;;;;;;;;;;;;;;; ; flatten-dir-once : symbol file -> (file or l-o-f) ; Returns a structure like the original file, except that any ; (sub)directory with that name is removed and its contents ; moved up one level. (define (flatten-dir-once dirname a-file) (cond [(simple-file? a-file) a-file] [(dir? a-file) (cond [(symbol=? dirname (dir-name a-file)) (flatten-dir-once-lof dirname (dir-contents a-file))] [else (make-dir (dir-name a-file) (flatten-dir-once-lof dirname (dir-contents a-dir)))])])) ; flatten-dir-once-lodf : symbol l-o-f -> l-o-f ; Returns a structure like the original list of files, except that any ; (sub)directory with that name is removed and its contents ; moved up one level. (define (flatten-dir-once-lof dirname a-lof) (cond [(empty? a-lof) empty] [(cons? a-lof) (flatten-helper (flatten-dir-once dirname (first a-lodf)) (flatten-dir-once-lof dirname (rest a-lodf)))])) ; flatten-helper : (file or l-o-f) l-o-f -> l-o-f ; Combines (an item or list) and a list into a new list. (define (flatten-helper a-file-or-lof a-lof) (cond [(file? a-file-or-lof) (cons a-file-or-lof a-lof)] [else (append a-file-or-lof a-lof)]))