;;; PARSE-PATHNAME THING &OPTIONAL WITH-RESPECT-TO (DEFAULTS *DEFAULT-PATHNAME-DEFAULTS*) ;;; Parses a string (or whatever) into a pathname. ;;; DEFAULT-PATHNAME &OPTIONAL DEFAULTS HOST DEFAULT-TYPE DEFAULT-VERSION ;;; Returns the default for the given HOST from DEFAULTS. ;;; SET-DEFAULT-PATHNAME PATHNAME &OPTIONAL DEFAULTS ;;; Sets the default for either the host of the pathname or the NIL default. ;;; MAKE-PATHNAME-DEFAULTS ;;; Returns an alist that you can pass to the functions below that take a set of defaults. ;;; Most things that take a set of defaults will also take a single pathname. ;;; MERGE-PATHNAME-DEFAULTS PATHNAME &OPTIONAL DEFAULTS DEFAULT-TYPE DEFAULT-VERSION ;;; Fill in slots in PATHNAME from program defaults. This is what most ;;; programs interface to. ;;; MERGE-AND-SET-PATHNAME-DEFAULTS PATHNAME &OPTIONAL DEFAULTS DEFAULT-TYPE DEFAULT-VERSION ;;; Does parse, merge, and updating of defaults. ;;; DESCRIBE-PATHNAME PATHNAME ;;; Describes all files that look like pathname. Also useful when you cannot remember what ;;; directory a file is in. ;;; PATHNAME-PLIST PATHNAME ;;; Advertised messages on pathnames: ;;; :GET INDICATOR --- see below for a discourse on pathname properties ;;; :PUTPROP PROP INDICATOR ;;; :REMPROP INDICATOR ;;; :DEVICE, :DIRECTORY, :NAME, :TYPE, :VERSION ;;; :NEW-DEVICE, :NEW-DIRECTORY, :NEW-NAME, :NEW-TYPE, :NEW-VERSION ;;; :NEW-PATHNAME &REST OPTIONS ;;; :DEFAULT-NAMESTRING STRING ;;; :GENERIC-PATHNAME ;;; :STRING-FOR-HOST, :STRING-FOR-PRINTING, :STRING-FOR-WHOLINE, :STRING-FOR-EDITOR ;;; :STRING-FOR-DIRED ;;; :INIT-FILE PROGRAM-NAME ;;; Advertised special variables: ;;; *KNOWN-TYPES* - list of types unimportant for the sake of generic pathnames. ;;; *DEFAULTS-ARE-PER-HOST* - user option. If NIL, pathnames defaults are maintained all ;;; together for all hosts. ;;; *ITS-UNINTERESTING-TYPES* - types that do not deserve the FN2 slot. ;;; *ALWAYS-MERGE-TYPE-AND-VERSION* - user option. If T, gives TENEX style defaulting ;;; of pathnames. Default is NIL. ;;; Other system types (pathname syntaxes) must implement at least the following messages: ;;; They can then be mixed with CHAOS-PATHNAME for use with the QFILE chaosnet file ;;; job protocol. ;;; :STRING-FOR-HOST - returns a string that can be sent to the file computer that ;;; specifying the file in question. ;;; :PARSE-NAMESTRING - takes a string and returns multiple values for various components ;;; present in the string. ;;; See ITS-PATHNAME-MIXIN and/or TOPS20-PATHNAME-MIXIN for additional details. ;;; To add another protocol, implement the messages of CHAOS-PATHNAME for generic file ;;; manipulation. That flavor is defined in QFILE. ;;; Interaction with host objects: ;;; The HOST instance variable of a pathname is a host object, as ;;; outlined in SYS: SYS2; HOST ;;; *PATHNAME-HOST-LIST* is the set of all logical pathname hosts. ;;; *PATHNAME-HOST-LIST* is the set of all physical pathname hosts. ;;; When parsing a string into a pathname, the specified host ;;; (the part of the string before the colon) is sent in the :PATHNAME-HOST-NAMEP ;;; message to each host in this list. When that returns T, that host is used. ;;; The host is sent a :PATHNAME-FLAVOR message to determine the flavor of the ;;; pathname to instantiate. (If the reply to :PATHNAME-FLAVOR returns multiple ;;; values, the second is an addition for the INIT-PLIST to use when instantiating.) ;;; Normally, when printing the host portion of a pathname, the host is ;;; sent a :NAME-AS-FILE-COMPUTER message. ;;;TRUENAMEs refer exactly to a single instance of a single file on a single filecomputer. ;;;LOGICAL-HOSTS are provided in an attempt to improve portability of source ;;; file systems to various file computers. The general idea is we gain by ;;; refering to SYS: SYS; instead of AI: LISPM; . The mapping between logical hosts ;;; and physical hosts is usally controlled by site options; however that need not ;;; necessarily be true. However, if this mapping is changed in a running system, ;;; it must be realized that the consequence is that already loaded files will, in ;;; some sense, be assumed to have "come" from the new place. Being more abstract ;;; objects than physical hosts, logical hosts are preferred when contructing ;;; generic pathnames (see below). ;;;LOGICAL-PATHNAMES are pathnames whose host is a LOGICAL-HOST. ;;;GENERIC-PATHNAMES ;;; A generic-pathname is a single pathname common to a logical group of files, ;;; where a logical group consists of all versions and forms (LISP, QFASL, etc.) of a file. ;;; Generic-pathnames are used for ;;; storing properties about the logical group. For example, the mode-line properties ;;; and information about what packages the file has been loaded into are stored on ;;; the generic pathname. The generic pathname is obtained ;;; by sending a :GENERIC-PATHNAME message to a PATHNAME. ;;; The following properties are held on GENERIC-PATHNAMES: ;;; :FILE-ID-PACKAGE-ALIST Alist keyed on package. Remembers which forms of ;;; this file have been loaded into which packages. Association is (currently) ;;; a two list ( ). ;;; is a dotted pair ( . ) ;;; is the acceess pathname used for the load. It can be ;;; SYS: SYS; MLAP QFASL > or AI: LISPM; MLAP QFASL, etc. ;;; A generic pathname normally has a type of unspecific, but not always. Consider ;;; FOO.LISP, FOO.QFASL, FOO.DOC and FOO.PRESS. Being as this is the lisp machine ;;; (and we have to worry about ITS), the generic pathname for FOO.LISP and FOO.QFASL ;;; is defined to be FOO.unspecific. However, we also provide a mechanism to deal with ;;; cases where certain types of files on certain hosts represent separate logical ;;; "groups" (.DOC and .PRESS for example). This consists of sending the host a ;;; a :GENERIC-BASE-TYPE message when computing a generic pathname. So we ;;; might get back "DOC" in the case of .DOC and .PRESS rather than the usual UNSPECIFIC. ;;; The default :GENERIC-BASE-TYPE method of BASIC-HOST looks at *GENERIC-BASE-TYPE-ALIST* ;;; for a few types which are assumed to map into non :UNSPECIFIC generic base types ;;; if not otherwise specified by the host. ;;; Hosts of generic pathnames. ;;; Generic pathnames are defined to be BACKTRANSLATED with respect to logical hosts. ;;; Backtranslating means translating from physical (host device directory) to (currently) ;;; equivalent logical ones, if possible. ;;; Thus, one obtains SYS: SYS; from AI: LISPM;. This is consistant with the ;;; general idea of generic pathnames, which is to refer to "the object" with as ;;; high an abstraction as possible. When moving bands to different sites, this ;;; causes the right thing to happen as much as in any other scheme. A consequence ;;; of making generic pathnames be backtranslated is that ALL files on the ;;; translated from directories will have logical hosts in the generic pathnames. ;;; If random miscellaneous files are also stored in directories which are logically ;;; mapped, questionably intended results could be obtained in some cases. ;;; However, no great disasters will occur, and it should be kept in mind that ;;; relatively "clean" bands are shipped between sites, which should have only ;;; referenced system files. ;;; When computing a generic pathname, the :GENERIC-BASE-TYPE message is first ;;; sent to the actual host (if that happens to be available). Then the ;;; (host, directory) pair is backtranslated (possibly obtaining a logical host). ;;; Then, if the BASE-TYPE is still :UNSPECIFIC, another :GENERIC-BASE-TYPE message ;;; is tried. ;;; Names of generic pathnames. ;;; No conversion of NAME is ever done on generic pathnames. If you are using logical ;;; hosts (to attempt to improve portability) you should avoid complex file names ;;; for the same reason. ;(DEFUN FILE-S$NAMESTRING (OBJECT) ; "Convert OBJECT to a s$pathname; return a s$namestring specifying just name, type and version." ; (SEND (PATHNAME OBJECT) :STRING-FOR-DIRED)) ;(DEFUN DIRECTORY-S$NAMESTRING (OBJECT) ; "Convert OBJECT to a pathname; return a s$namestring specifying just device and directory." ; (SEND (S$PATHNAME OBJECT) :STRING-FOR-DIRECTORY)) ;(DEFUN HOST-S$NAMESTRING (OBJECT) ; "Convert OBJECT to a s$pathname; return a s$namestring with just OBJECT's host name and a colon." ; (STRING-APPEND (SEND (S$PATHNAME OBJECT) :HOST) ":")) ;(DEFUN ENOUGH-S$NAMESTRING (OBJECT &OPTIONAL (DEFAULTS *DEFAULT-S$PATHNAME-DEFAULTS*)) ; "Return enough s$namestring to produce whatever OBJECT produced ;when merged with DEFAULTS using MERGE-S$PATHNAMES. ;OBJECT is converted to a s$pathname, and that is made into a string ;from which components may be omitted if their values are the same as ;what would result from defaulting whatever is left with the specified defaults." ; (LET* ((S$PATHNAME (S$PATHNAME OBJECT)) ; (DEFHOST (DEFAULT-HOST DEFAULTS)) ; (DP (DEFAULT-S$PATHNAME DEFAULTS (S$PATHNAME-HOST S$PATHNAME))) ; (NEED-NAME (NOT (EQUAL (S$PATHNAME-RAW-NAME S$PATHNAME) (S$PATHNAME-RAW-NAME DP)))) ; (NEED-TYPE (NOT (EQUAL (S$PATHNAME-RAW-TYPE S$PATHNAME) (S$PATHNAME-RAW-TYPE DP)))) ; (NEED-VERSION (NEQ (S$PATHNAME-RAW-VERSION S$PATHNAME) (S$PATHNAME-RAW-VERSION DP))) ; (STRING ; (SEND ; (SEND S$PATHNAME :NEW-S$PATHNAME ; (IF (EQUAL (S$PATHNAME-RAW-DIRECTORY S$PATHNAME) (S$PATHNAME-RAW-DIRECTORY DP)) ; :DIRECTORY) ; NIL ; (IF (EQUAL (S$PATHNAME-RAW-DEVICE S$PATHNAME) (S$PATHNAME-RAW-DEVICE DP)) ; :DEVICE) ; NIL ; (IF (EQ (S$PATHNAME-VERSION S$PATHNAME) :NEWEST) ; :VERSION) ; :NEWEST) ; (IF (OR NEED-NAME NEED-TYPE NEED-VERSION) ; :STRING-FOR-PRINTING ; :STRING-FOR-DIRECTORY)))) ; (IF (OR NEED-NAME NEED-TYPE NEED-VERSION) ; (IF (EQ (S$PATHNAME-HOST S$PATHNAME) DEFHOST) ; (STRING-LEFT-TRIM #/SP (SUBSTRING-AFTER-CHAR #/: STRING)) ; STRING) ; (IF (EQ (S$PATHNAME-HOST S$PATHNAME) DEFHOST) ; STRING ; (STRING-APPEND (SEND (S$PATHNAME-HOST S$PATHNAME) :NAME-AS-FILE-COMPUTER) ; ": " STRING))))) ;(DEFFLAVOR S$PATHNAME-ERROR () (ERROR)) ;(DEFMETHOD (S$PATHNAME-ERROR :CASE :PROCEED-ASKING-USER :NEW-S$PATHNAME) ; (CONTINUATION READ-OBJECT-FUNCTION) ; (FUNCALL CONTINUATION :NEW-S$PATHNAME ; (FUNCALL READ-OBJECT-FUNCTION ; `(:S$PATHNAME :DEFAULTS (())) ; "s$pathname to use instead: "))) ;(COMPILE-FLAVOR-METHODS S$PATHNAME-ERROR)