123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
- ;;;
- ;;; Port Author: Andrew Whatson
- ;;;
- ;;; Original Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
- ;;;
- ;;; scheme48-1.9.2/scheme/big/filename.scm
- ;;;
- ;;; Silly file name utilities
- ;;; These try to be operating-system independent, but fail, of course.
- ;;;
- ;;; Namelist = ((dir ...) basename type)
- ;;; or ((dir ...) basename)
- ;;; or (dir basename type)
- ;;; or (dir basename)
- ;;; or basename
- (define-module (prescheme filename)
- #:use-module (prescheme scheme48)
- #:export (namestring *scheme-file-type* *load-file-type*
- file-name-directory
- file-name-nondirectory
- translate
- set-global-translation!
- set-translation!
- make-translations with-translations
- current-translations))
- (define (namestring namelist dir default-type)
- (let* ((namelist (if (list? namelist) namelist (list '() namelist)))
- (subdirs (if (list? (car namelist))
- (car namelist)
- (list (car namelist))))
- (basename (cadr namelist))
- (type (if (null? (cddr namelist))
- (if (string? basename)
- #f
- default-type)
- (caddr namelist))))
- (string-append (or dir "")
- (apply string-append
- (map (lambda (subdir)
- (string-append
- (namestring-component subdir)
- directory-component-separator))
- subdirs))
- (namestring-component basename)
- (if type
- (string-append type-component-separator
- (namestring-component type))
- ""))))
- (define directory-component-separator "/") ;;unix sux
- (define type-component-separator ".")
- (define (namestring-component x)
- (cond ((string? x) x)
- ((symbol? x)
- (list->string (map file-name-preferred-case
- (string->list (symbol->string x)))))
- (else (assertion-violation 'namestring-component
- "bogus namelist component" x))))
- (define file-name-preferred-case char-downcase)
- (define *scheme-file-type* 'scm)
- (define *load-file-type* *scheme-file-type*) ;;#F for Pseudoscheme or T
- ;; Interface copied from gnu emacs:
- ;;file-name-directory
- ;; Function: Return the directory component in file name NAME.
- ;;file-name-nondirectory
- ;; Function: Return file name NAME sans its directory.
- ;;file-name-absolute-p
- ;; Function: Return t if file FILENAME specifies an absolute path name.
- ;;substitute-in-file-name
- ;; Function: Substitute environment variables referred to in STRING.
- ;;expand-file-name
- ;; Function: Convert FILENAME to absolute, and canonicalize it.
- (define (file-name-directory filename)
- (substring filename 0 (file-nondirectory-position filename)))
- (define (file-name-nondirectory filename)
- (substring filename
- (file-nondirectory-position filename)
- (string-length filename)))
- (define (file-nondirectory-position filename)
- (let loop ((i (- (string-length filename) 1)))
- (cond ((< i 0) 0)
- ;; Heuristic. Should work for DOS, Unix, VMS, MacOS.
- ((string-posq (string-ref filename i) "/:>]\\") (+ i 1))
- (else (loop (- i 1))))))
- (define (string-posq thing s)
- (let loop ((i 0))
- (cond ((>= i (string-length s)) #f)
- ((eq? thing (string-ref s i)) i)
- (else (loop (+ i 1))))))
- ;; Directory translations.
- ;; E.g. (set-translation! "foo;" "/usr/mumble/foo/")
- (define *global-translations* '())
- (define $translations (make-fluid (make-cell '())))
- (define (make-translations)
- (make-cell '()))
- (define (with-translations translations thunk)
- (with-fluids (($translations (make-cell '()))) (thunk)))
- (define (current-translations) (cell-ref (fluid-ref $translations)))
- (define (set-translations! new)
- (cell-set! (fluid-ref $translations) new))
- (define (set-global-translation! from to)
- (set! *global-translations*
- (amend-alist! from to *global-translations*)))
- (define (set-translation! from to)
- (set-translations! (amend-alist! from to (current-translations))))
- (define (amend-alist! from to alist)
- (let ((probe (assoc from alist)))
- (if probe
- (begin
- (set-cdr! probe to)
- alist)
- (cons (cons from to) alist))))
- (define (translate name)
- (let ((len (string-length name)))
- (let loop ((ts (append *global-translations* (current-translations))))
- (if (null? ts)
- name
- (let* ((from (caar ts))
- (to (cdar ts))
- (k (string-length from)))
- (if (and to
- (<= k len)
- (string=? (substring name 0 k) from))
- (string-append to (substring name k len))
- (loop (cdr ts))))))))
|