filename.scm 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  3. ; Silly file name utilities
  4. ; These try to be operating-system independent, but fail, of course.
  5. ; Namelist = ((dir ...) basename type)
  6. ; or ((dir ...) basename)
  7. ; or (dir basename type)
  8. ; or (dir basename)
  9. ; or basename
  10. (define (namestring namelist dir default-type)
  11. (let* ((namelist (if (list? namelist) namelist (list '() namelist)))
  12. (subdirs (if (list? (car namelist))
  13. (car namelist)
  14. (list (car namelist))))
  15. (basename (cadr namelist))
  16. (type (if (null? (cddr namelist))
  17. (if (string? basename)
  18. #f
  19. default-type)
  20. (caddr namelist))))
  21. (string-append (or dir "")
  22. (apply string-append
  23. (map (lambda (subdir)
  24. (string-append
  25. (namestring-component subdir)
  26. directory-component-separator))
  27. subdirs))
  28. (namestring-component basename)
  29. (if type
  30. (string-append type-component-separator
  31. (namestring-component type))
  32. ""))))
  33. (define directory-component-separator "/") ;unix sux
  34. (define type-component-separator ".")
  35. (define (namestring-component x)
  36. (cond ((string? x) x)
  37. ((symbol? x)
  38. (list->string (map file-name-preferred-case
  39. (string->list (symbol->string x)))))
  40. (else (assertion-violation 'namestring-component
  41. "bogus namelist component" x))))
  42. (define file-name-preferred-case char-downcase)
  43. (define *scheme-file-type* 'scm)
  44. (define *load-file-type* *scheme-file-type*) ;#F for Pseudoscheme or T
  45. ; Interface copied from gnu emacs:
  46. ;file-name-directory
  47. ; Function: Return the directory component in file name NAME.
  48. ;file-name-nondirectory
  49. ; Function: Return file name NAME sans its directory.
  50. ;file-name-absolute-p
  51. ; Function: Return t if file FILENAME specifies an absolute path name.
  52. ;substitute-in-file-name
  53. ; Function: Substitute environment variables referred to in STRING.
  54. ;expand-file-name
  55. ; Function: Convert FILENAME to absolute, and canonicalize it.
  56. (define (file-name-directory filename)
  57. (substring filename 0 (file-nondirectory-position filename)))
  58. (define (file-name-nondirectory filename)
  59. (substring filename
  60. (file-nondirectory-position filename)
  61. (string-length filename)))
  62. (define (file-nondirectory-position filename)
  63. (let loop ((i (- (string-length filename) 1)))
  64. (cond ((< i 0) 0)
  65. ;; Heuristic. Should work for DOS, Unix, VMS, MacOS.
  66. ((string-posq (string-ref filename i) "/:>]\\") (+ i 1))
  67. (else (loop (- i 1))))))
  68. (define (string-posq thing s)
  69. (let loop ((i 0))
  70. (cond ((>= i (string-length s)) #f)
  71. ((eq? thing (string-ref s i)) i)
  72. (else (loop (+ i 1))))))
  73. ; Directory translations.
  74. ; E.g. (set-translation! "foo;" "/usr/mumble/foo/")
  75. (define *global-translations* '())
  76. (define $translations (make-fluid (make-cell '())))
  77. (define (make-translations)
  78. (make-cell '()))
  79. (define (with-translations translations thunk)
  80. (let-fluid $translations (make-cell '()) thunk))
  81. (define (current-translations) (cell-ref (fluid $translations)))
  82. (define (set-translations! new)
  83. (cell-set! (fluid $translations) new))
  84. (define (set-global-translation! from to)
  85. (set! *global-translations*
  86. (amend-alist! from to *global-translations*)))
  87. (define (set-translation! from to)
  88. (set-translations! (amend-alist! from to (current-translations))))
  89. (define (amend-alist! from to alist)
  90. (let ((probe (assoc from alist)))
  91. (if probe
  92. (begin
  93. (set-cdr! probe to)
  94. alist)
  95. (cons (cons from to) alist))))
  96. (define (translate name)
  97. (let ((len (string-length name)))
  98. (let loop ((ts (append *global-translations* (current-translations))))
  99. (if (null? ts)
  100. name
  101. (let* ((from (caar ts))
  102. (to (cdar ts))
  103. (k (string-length from)))
  104. (if (and to
  105. (<= k len)
  106. (string=? (substring name 0 k) from))
  107. (string-append to (substring name k len))
  108. (loop (cdr ts))))))))