filename.scm 5.0 KB

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