
;;; 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 (<file-id> <access-pathname>).   
;;;	    <file-id> is a dotted pair (<TRUENAME> . <creation-time>)
;;;	    <access-pathname>  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 <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)
