-- Title -- Pathnames & filenames -- Author -- Taylor Campbell -- Abstract -- ... -- Issues -- ... -- Rationale -- Portability & expressiveness of names for file system objects. -- Specification sketch -- * Pathnames & filenames New disjoint type, pathname, any of whose components can be false: host - host descriptor base - device, logical name, environment variable, or CURRENT directory - list of filenames representing directory components file - filename Another new disjoint type, filename, any of whose parts can be false: name - string or symbol extension - string or symbol generation - positive integer or symbol NEWEST File operations from R5RS & filesys.text are extended to work with pathnames, namestrings, & namelists as specified here. (MAKE-FILENAME name ext gen) -> filename (X->FILENAME object) -> filename or #F (FILENAME? object) -> boolean (FILENAME-NAME filename) -> string, symbol, or #F ...&c. (FILENAME-WITH-NAME filename name) -> filename ...&c. (MODIFY-FILENAME-NAME filename modifier) -> filename ...&c. (FILENAME-DEFAULT filename name extension generation) -> filename (FILENAME-COMPONENTS filename) -> [name ext gen] (MAKE-PATHNAME host base directory file) -> pathname (PATHNAME? object) -> boolean (X->PATHNAME object [default-host]) -> pathname or #F (X->NAMELIST object) -> namelist or #F (X->NAMESTRING object) -> string or #F (PATHNAME-HOST pathname) -> host (PATHNAME-BASE pathname) -> base ...&c. (PATHNAME-WITH-BASE pathname host) -> pathname ...&c. (MODIFY-PATHNAME-BASE pathname modifier) -> pathname ...&c. Also: the above for the file's components, e.g. PATHNAME-EXTENSION. (PATHNAME-DEFAULT pathname base directory file) -> pathname (PATHNAME-COMPONENTS pathname) -> [host base directory filename] (PATHNAME-COMPONENTS* pathname) -> [host base directory name extension generation] ; forcer doesn't like the latter's name. Here are some other possible ; suggestions: ; PATHNAME/FILE-COMPONENTS ; PATHNAME-COMPONENTS/FILE ; PATHNAME+FILE-COMPONENTS ; PATHNAME-FILE-COMPONENTS ; PATHNAME-AND-FILE-COMPONENTS ; PATH-COMPONENTS ; PATH+FILE-COMPONENTS (PATHNAME=? pathname ...) -> boolean (EXPAND-PATHNAME pathname) -> pathname ; Expand logical names (MERGE-PATHNAMES pathname [defaults-pathname]) -> pathname The second argument defaults to the working directory. (FILE-NAMESTRING pathname) -> namestring (DIRECTORY-NAMESTRING pathname) -> namestring (HOST-NAMESTRING pathname) -> namestring (ENOUGH-NAMESTRING pathname relative) -> namestring (FILE-PATHNAME pathname) -> pathname (DIRECTORY-PATHNAME pathname) -> pathname (ENOUGH-PATHNAME pathname relative) -> pathname (FILE-PATHNAME? pathname) -> boolean (PATHNAME-AS-FILE pathname) -> pathname (DIRECTORY-PATHNAME? pathname) -> boolean (PATHNAME-AS-DIRECTORY pathname) -> pathname (PATHNAME-PARENT-DIRECTORY pathname) -> pathname Returns the parent directory of PATHNAME as a file pathname. For example, (x->namelist (pathname-parent-directory (x->pathname '((A B C) (D TEXT))))) returns ((A B) C) -- that is, a pathname with the file component of simply C and the directory components A & B. On Unix, the two pathnames would be represented as "a/b/c/d.text" & "a/b/c". * Hosts (LOCAL-HOST) -> host (HOST? object) -> boolean (HOST=? host-a host-b ...) -> boolean Note that hosts are _not_ disjoint. * Working directory (WORKING-DIRECTORY) -> pathname (SET-WORKING-DIRECTORY! pathname) (WITH-WORKING-DIRECTORY pathname thunk) * Namelists -> | () | ( ) | ( ) | ( ) -> #F | | () | ( ) | ( ) -> string or symbol -> string or symbol -> #F | positive integer | NEWEST -> #F | | (*) -> ... -> ... Examples: ((hello-world txt)) hello-world.txt HELLO-WORLD.TXT (programming scheme) programming/scheme [.PROGRAMMING]SCHEME (hello (world txt)) hello/world.txt [.HELLO]WORLD.TXT ((scheme rts) (defenum scm)) scheme/rts/defenum.scm [.SCHEME.RTS]DEFENUM.SCM ((home riastradh) (programming scheme srfi) (filesys text 3)) ~riastradh/programming/scheme/srfi/filesys.text.~3~ [USERS.RIASTRADH.PROGRAMMING.SCHEME.SRFI]FILESYS.TEXT;3 (linker source (sp32_link t)) $LINKER/source/sp32_link.t LINKER:[SOURCE]SP32_LINK.T (linker (source sparc) (elf32 t)) $LINKER/source/sparc/elf32.t LINKER:[SOURCE.SPARC]ELF32.T -- Design rationale -- Naming of objects on file systems is a complicated matter. The goal of portability is the main cause of this, but also generality. The most common representation of pathnames, simply strings in a particular format, is inadequate for several reasons: - It does not contain any information about how the pathname should be interpreted. - The format is typically extremely OS-specific and non-portable. - It requires parsing & reparsing the pathname every time any information is queried about it. - It is not amenable to complex operations such as MERGE-PATHNAMES. - The base of the pathname generally uses an ad-hoc mechanism that does not generalize well. The current design tries to be as simple as possible while still being portable & able to express pathnames well. The 'base' abstraction is very general and can map onto many different file system designs. For example: - Relative pathnames are specified by a base of the symbol CURRENT. ; Perhaps that should just be #F. - On Unix, a pathname base can simply be a symbol or string that is mapped to an environment variable, or it could be a list (HOME ) that refers to the user's home directory. - On Aegis / Domain/OS, it can be a logical name. - On DOS, a pathname base can represent a drive. - On VMS, it can represent a logical name or a device. URLs are a useful abstraction for many network-related purposes, but they do not suffice for pathnames: they suffer from the same sorts of problems as string-based pathname representations. URLs are trivially mapped onto pathnames, too: the host can include the URL's scheme & host, the base can be ignored, and the directory & file components have obvious meaning. The base can be used for nested URL strings, such as JAR URLs; "jar:http://web.foo.com/bar/baz.jar!quux/zot.scm" can be represented as (JAR-HOST ((HTTP-HOST "web.foo.com") BAR (BAZ JAR)) QUUX (ZOT SCM)), which is a pathname whose host is a JAR host, whose base is an HTTP pathname (URL), and whose directory & file components are self- explanatory. ; To describe: why a separate filename type, how generations work, why ; namelists & namestrings both, why symbols are valid components of ; pathnames & filenames...what else? -- Copyright -- Copyright (C) 2005 Taylor Campbell. All rights reserved. Don't distribute this. I'm not liable; if stuff goes wrong, it's all your fault, *nyah nyah*. This copyright notice will change in the real SRFI document to something reasonable (in particular, the official SRFI copyright notice, surprise surprise).