mailto:srfi-59@srfi.schemers.org
.
See instructions
here to subscribe to the list. You can access previous messages via the
archive of the mailing list.
All of these procedures are file-system dependent. Use of these vicinity procedures can make programs file-system independent.
Some programs use literal strings to locate accessory files, breaking on installations with different destinations. More savvy coders will construct pathnames from environment variables or compile-time definitions.
In most languages, programs intended for portability must condition all manipulations of pathnames to the syntax and capabilities of the host file-system. Inconsistent conditioning is a common cause of porting failures.
Common-Lisp attacks the general problem of naming files anywhere in any file system. It has a six-component pathname datatype to represent names in the most complicated file-system imaginable; names in simpler file systems use fewer components.
In this arrangement, portable file-handling programs must be capable
of handling pathnames with 6 components, and those employing fewer.
But which component will be used is not obvious. Is a
".txt"
filename suffix a type or part of the
name?
Vicinities attack a smaller problem, that of describing pathnames in 5
predefined locations, and their sub-vicinities. Those predefined
locations cover the usual areas for ancillary and configuration files
used by Scheme implementations and programs. The
program-vicinity
is particularly useful as it is the
directory where the currently loading file is located. This is
captured by redefining load
to fluid-let
a
top-level variable with its argument.
The make-vicinity
and pathname->vicinity
procedures provide means to create new base vicinities. Base
vicinities should generally be absolute pathnames.
Vicinities need not be tied to individual files in a file system. The files named could be members of a zip archive, as Java does. Vicinities can even be used on flat file systems (which have no directory structure) by having the vicinity express constraints on the file name. On most systems a vicinity is a string.
vicinity procedures are supported by all implementations in SLIB.
program-vicinity
can return incorrect values if your program
escapes back into a load
continuation.
home-vicinity
returns #f
.
load
,
open-input-file
, open-output-file
, etc. The
returned filename is filename in vicinity.
in-vicinity
should allow filename to override
vicinity when filename is an absolute pathname
and vicinity is equal to the value of
(user-vicinity)
. The behavior of
in-vicinity
when filename is absolute and
vicinity is not equal to the value of
(user-vicinity)
is unspecified. For most systems
in-vicinity
can be string-append
.
sub-vicinity
will
return a pathname of the subdirectory name of
vicinity.
in-vicinity
.
(pathname->vicinity "/usr/local/lib/scm/Link.scm") => "/usr/local/lib/scm/"
#f
otherwise. Typical vicinity suffixes are `/',
`:', and `\',
;;@ (implementation-vicinity) should be defined to be the pathname of ;;; the directory where any auxillary files to your Scheme ;;; implementation reside. (define (implementation-vicinity) (case (software-type) ((UNIX) "/usr/local/src/scheme/") ((VMS) "scheme$src:") ((MS-DOS) "C:\\scheme\\"))) ;;@ (library-vicinity) should be defined to be the pathname of the ;;; directory where files of Scheme library functions reside. (define library-vicinity (let ((library-path (or ;; Use this getenv if your implementation supports it. (getenv "SCHEME_LIBRARY_PATH") ;; Use this path if your scheme does not support GETENV ;; or if SCHEME_LIBRARY_PATH is not set. (case (software-type) ((UNIX) "/usr/local/lib/slib/") ((VMS) "lib$scheme:") ((MS-DOS) "C:\\SLIB\\") (else ""))))) (lambda () library-path))) ;;@ (home-vicinity) should return the vicinity of the user's HOME ;;; directory, the directory which typically contains files which ;;; customize a computer environment for a user. (define (home-vicinity) (let ((home (getenv "HOME"))) (and home (case (software-type) ((UNIX COHERENT MS-DOS) ;V7 unix has a / on HOME (if (eqv? #\/ (string-ref home (+ -1 (string-length home)))) home (string-append home "/"))) (else home))))) ;@ (define in-vicinity string-append) ;@ (define (user-vicinity) (case (software-type) ((VMS) "[.]") (else ""))) ;@ (define vicinity:suffix? (let ((suffi (case (software-type) ((AMIGA) '(#\: #\/)) ((MACOS THINKC) '(#\:)) ((MS-DOS WINDOWS ATARIST OS/2) '(#\\ #\/)) ((NOSVE) '(#\: #\.)) ((UNIX COHERENT PLAN9) '(#\/)) ((VMS) '(#\: #\])) (else (slib:warn "require.scm" 'unknown 'software-type (software-type)) "/")))) (lambda (chr) (and (memv chr suffi) #t)))) ;@ (define (pathname->vicinity pathname) (let loop ((i (- (string-length pathname) 1))) (cond ((negative? i) "") ((vicinity:suffix? (string-ref pathname i)) (substring pathname 0 (+ i 1))) (else (loop (- i 1)))))) (define (program-vicinity) (if *load-pathname* (pathname->vicinity *load-pathname*) (slib:error 'program-vicinity "called while not within load"))) ;@ (define sub-vicinity (case (software-type) ((VMS) (lambda (vic name) (let ((l (string-length vic))) (if (or (zero? (string-length vic)) (not (char=? #\] (string-ref vic (- l 1))))) (string-append vic "[" name "]") (string-append (substring vic 0 (- l 1)) "." name "]"))))) (else (let ((*vicinity-suffix* (case (software-type) ((NOSVE) ".") ((MACOS THINKC) ":") ((MS-DOS WINDOWS ATARIST OS/2) "\\") ((UNIX COHERENT PLAN9 AMIGA) "/")))) (lambda (vic name) (string-append vic name *vicinity-suffix*)))))) ;@ (define (make-vicinity pathname) pathname)
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Scheme Request For Implementation process or editors, except as needed for the purpose of developing SRFIs in which case the procedures for copyrights defined in the SRFI process must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by the authors or their successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.