;;; -*- Mode: LISP; Package: FILE-SYSTEM; Base: 10; Patch-File: Yes;-*- ;;; (1) Compile and load this patch on your Symbolics machine. ;;; (2) using tv:edit-namespace-object add a USER PROPERTY ;;; called :LMI-LAMBDA-P on all your LMI machines. ;;; ;;; Or, if you want, modify the definition of LMI-LAMBDA-P to use ;;; the naming heuristic, which will work on default customer lambda sites ;;; because machines are named "LAMBDA-A" "LAMBDA-B" etc... (DEFUN LMI-LAMBDA-NAME-P (STRING) (OR (STRING-SEARCH "LAMBDA" STRING) (STRING-SEARCH "EXPLORER" STRING))) ;;; NOTES: MOST OF THIS CODE IS LIFTED DIRECTLY FROM THE LMI-LAMBDA SYSTEM ;;; CODE FOR PARSING ITS OWN PATHNAMES. AS SUCH, THE FOLLOWING IS TECHICALLY ;;; APPLICABLE: ;;; Copyright LISP Machine, Inc. 1984 ;;; See filename "Copyright.Text" for ;;; licensing and release information. ;;; (DEFMETHOD (lispm-host :pathname-flavor) () (COND ((SEND SELF :USER-GET :LMI-LAMBDA-P) 'LMI-LAMBDA-PATHNAME) ((LMI-LAMBDA-NAME-P (STRING (SEND SELF :NAME))) 'LMI-LAMBDA-PATHNAME) ('ELSE 'LMFS-PATHNAME))) (SETQ *USE-FULL-PARSER* t) ; NEEDED BECAUSE LMI-LAMBDA QFILE-ACCESS SENDS 1985 INSTEAD OF 85. (DEFFLAVOR LMI-lambda-pathname () (lmfs-pathname)) (DEFMETHOD (LMI-lambda-pathname :valid-directory-p) (dirname) (TYPECASE dirname (:string t) (:symbol (MEMQ dirname '(nil :wild :root))) (:list (AND (OR (NEQ (CAR dirname) :wild-inferiors) (NOT (SEND self :root-always-explicit-p))) (SEND self :valid-subdirectory-p dirname 0))))) (DEFUN-METHOD LMI-lambda-type-string LMI-lambda-pathname () (string-or-wild type)) (DEFUN-METHOD LMI-lambda-version-string LMI-lambda-pathname () (SELECTQ version (nil nil) (:newest ">") (:oldest "<") (:wild "*") (otherwise version))) (DEFUN-METHOD LMI-lambda-directory-string LMI-lambda-pathname () (COND ((LISTP directory) (LET ((temp-directory (REMQ :relative directory))) (FORMAT nil "~a~{.~a~}" (FIRST temp-directory) (CDR temp-directory)))) (t (string-or-wild directory)))) (DEFMETHOD (LMI-lambda-pathname :character-needs-quoting-p) (ch) ch nil) (DEFMETHOD (LMI-lambda-pathname :string-for-directory) () (LET ((default-cons-area pathname-area)) (FORMAT nil "~A;" (LMI-lambda-directory-string)))) (DEFMETHOD (LMI-lambda-pathname :string-for-dired) () (LET ((nam (string-or-wild name)) (typ (LMI-lambda-type-string)) (ver (LMI-lambda-version-string)) (default-cons-area pathname-area)) (FORMAT nil "~:[~A~;~*~]~:[.~A~;~*~]~:[#~D~;~*~]" (NULL nam) nam (NULL typ) typ (NULL ver) ver))) (DEFMETHOD (LMI-lambda-pathname :string-for-editor) () (LET ((dir (LMI-lambda-directory-string)) (nam (string-or-wild name)) (typ (LMI-lambda-type-string)) (ver (LMI-lambda-version-string)) (default-cons-area pathname-area)) (FORMAT nil "~:[~A~;~*~]~:[.~A~;~*~]~:[#~D~;~*~] ~:[~A;~;~*~] ~a:" (NULL nam) nam (NULL typ) typ (NULL ver) ver (NULL directory) dir (FUNCALL host :name-as-file-computer)))) (DEFMETHOD (LMI-lambda-pathname :string-for-host) () (LET ((dir (IF (MEMQ directory '(:wild :root)) "~" (LMI-lambda-directory-string))) (nam (string-or-wild name)) (typ (LMI-lambda-type-string)) (ver (LMI-lambda-version-string)) (default-cons-area pathname-area)) (FORMAT nil "~A:~:[~A;~;~*~]~:[~A~;~*~]~:[.~A~;~*~]~:[/#~D~;~*~]" (FUNCALL host :name-as-file-computer) (NULL directory) dir (NULL nam) nam (NULL typ) typ (NULL ver) ver))) (DEFMETHOD (LMI-lambda-pathname :string-for-printing) () (LET ((dir (LMI-lambda-directory-string)) (nam (string-or-wild name)) (typ (LMI-lambda-type-string)) (ver (LMI-lambda-version-string)) (default-cons-area pathname-area)) (FORMAT nil "~A:~:[~A;~;~*~]~:[~A~;~*~]~:[.~A~;~*~]~:[/#~D~;~*~]" (FUNCALL host :name-as-file-computer) (NULL directory) dir (NULL nam) nam (NULL typ) typ (NULL ver) ver))) (DEFMETHOD (LMI-lambda-pathname :parse-namestring) (IGNORE namestring &optional (start 0) end) (LMI-lambda-parse-namestring namestring start end)) (DEFWHOPPER (LMI-lambda-pathname :new-pathname) (&rest args) (LET* ((new-pathname (LEXPR-CONTINUE-WHOPPER args)) (directory-list (SEND new-pathname :directory))) (WHEN (AND (LISTP directory-list) (MEMQ :relative directory-list)) (SETQ new-pathname (SEND new-pathname :new-pathname :directory (REMQ :relative directory-list)))) new-pathname)) (COMPILE-FLAVOR-METHODS LMI-lambda-pathname) (DEFUN LMI-lambda-parse-namestring (STRING &optional (start 0) end &aux char state tem tem1 field-start (device "dsk") directory name type version) (OR end (SETQ end (ARRAY-ACTIVE-LENGTH string))) (DO ((index start (1+ index))) (nil) (IF (>= index end) (SETQ char 'done) (SETQ char (AREF string index))) (COND ((AND (NOT (MEMQ char '(#\sp #\tab #/. #/: #/; #/# done))) (OR (NOT (MEMQ char '(#/< #/>))) (MEMQ state '(version double-dotted)))) (AND (%STORE-CONDITIONAL (LOCF state) nil t) (SETQ field-start index)) (COND ((OR (EQ char #//) (EQ char #\circle-plus)) (SETQ index (1+ index)) (OR (< index end) (LMI-lambda-char-error string 'done)) (SETQ char (AREF string index)) (AND (>= char #o200) (NOT (= char #\tab)) (LMI-lambda-char-error string char))))) ((EQ char #\<) (COND ((NULL state)) ;Extraneous whitespace. ((EQ state t) (SETQ name (LMI-lambda-field string field-start index))) ((EQ state 'dotted) (AND tem (SETQ name tem)) (SETQ type (LMI-lambda-field string field-start index))) ((EQ state 'double-dotted) (AND tem (SETQ name tem)) (AND tem1 (SETQ type tem1)) (SETQ version (LMI-lambda-field string field-start index t))) (t (LMI-lambda-char-error string char))) (SETQ state 'DIRECTORY directory nil) (GO new-field)) ((MEMQ char '(#\sp #\tab done)) (COND ((NULL state)) ;Extraneous whitespace. ((EQ state t) (SETQ name (LMI-lambda-field string field-start index) state nil)) ((EQ state 'dotted) (AND tem (SETQ name tem)) (SETQ type (LMI-lambda-field string field-start index) state nil)) ((EQ state 'double-dotted) (AND tem (SETQ name tem)) (AND tem1 (SETQ type tem1)) (SETQ version (LMI-lambda-field string field-start index t) state nil) (COND ((EQ version 0) (SETQ version :newest)) ((EQ version -2) (SETQ version :oldest)))) ((EQ state 'version) (SETQ version (LMI-lambda-field string field-start index t) state nil)) (t (LMI-lambda-char-error string char)))) ((EQ char #/.) (COND ((NULL state) ;Could only be :UNSPECIFIC name (SETQ tem nil state 'dotted)) ((EQ state t) ;Could either be directory or name (SETQ state 'dotted tem (LMI-lambda-field string field-start index))) ((EQ state 'dotted) (OR tem (LMI-lambda-char-error string #/.)) (SETQ tem1 (LMI-lambda-field string field-start index) state 'double-dotted)) ((EQ state 'double-dotted) (OR tem (LMI-lambda-char-error string #/.)) (SETQ state 'DIRECTORY directory (LIST* tem tem1 (LMI-lambda-field string field-start index) nil))) ((EQ state 'DIRECTORY) (SETQ directory (NCONC directory (NCONS (LMI-lambda-field string field-start index))))) ((EQ state 'version) (SETQ version (LMI-lambda-field string field-start index t) state 'dotted)) (t (LMI-lambda-char-error string char))) (GO new-field)) ((EQ char #/#) (COND ((NULL state) (SETQ state 'version)) ((EQ state t) (SETQ name (LMI-lambda-field string field-start index) state 'version)) ((EQ state 'dotted) (AND tem (SETQ name tem)) (SETQ type (LMI-lambda-field string field-start index) state 'version)) (t (LMI-lambda-char-error string char))) (GO new-field)) ((OR (EQ char #/;) (EQ char #/>)) (COND ((EQ state t) (SETQ directory (LMI-lambda-field string field-start index)) (IF (STRING-EQUAL directory "~") (SETQ directory :root))) ((EQ state 'dotted) (OR tem (LMI-lambda-char-error string char)) (SETQ directory (LIST tem (LMI-lambda-field string field-start index)))) ((EQ state 'double-dotted) (OR (AND tem tem1) (LMI-lambda-char-error string char)) (SETQ directory (LIST tem tem1 (LMI-lambda-field string field-start index)))) ((EQ state 'DIRECTORY) (LET ((field (LMI-lambda-field string field-start index))) (IF (AND (NULL directory) (EQ field :unspecific)) (SETQ directory :root) (SETQ directory (NCONC directory (LIST field)))))) (t (LMI-lambda-char-error string char))) (SETQ state nil)) ((EQ state t) (SETQ device ;(FUNCALL-SELF :PARSE-DEVICE-SPEC ; (LMI-LAMBDA-FIELD STRING FIELD-START INDEX)) :unspecific state nil)) (t (LMI-lambda-char-error string char))) (GO skip) new-field (SETQ field-start (1+ index)) skip (AND (EQ char 'done) (RETURN (VALUES device directory name type version))))) (DEFPROP LMI-lambda-char-error t :error-reporter) (DEFUN LMI-lambda-char-error (STRING char) (IF (EQ char 'done) (FERROR :pathname-parse-error "Unexpected end of string while parsing ~s." string) (FERROR :pathname-parse-error "Unexpected character (~:C) while parsing ~s." char string))) (DEFUN LMI-lambda-field (STRING &optional (start 0) end version-p device-p &aux size arr char) device-p (OR end (SETQ end (ARRAY-ACTIVE-LENGTH string))) (SETQ size (- end start)) (IF (ZEROP size) :unspecific (SETQ arr (MAKE-ARRAY size :type 'art-string)) (DO ((i start (1+ i)) (si 0)) ((>= i end) (OR (= si size) (SETQ arr (ADJUST-ARRAY-SIZE arr si)))) (COND ((NOT (MEMQ (SETQ char (AREF string i)) '(#// #\circle-plus))) (AND (>= char #o200) (NOT (= char #\tab)) (LMI-lambda-char-error string char)) (ASET (CHAR-UPCASE char) arr si) (SETQ si (1+ si))))) (COND ((STRING-EQUAL arr "*") :wild) ((NOT version-p) arr) ((numeric-p arr nil t)) ((CDR (ASSOC arr '((">" . :newest) ("<" . :oldest))))) (t (FERROR :pathname-parse-error "Invalid version spec ~S in ~s" arr string)))))