(DEFINE-FILE-INFO READTABLE "XCL" PACKAGE "XCL")(il:filecreated " 2-Nov-87 15:12:49" il:|{POGO:AISNORTH:XEROX}<CUTTING>LISP>NEW-WHERE-IS.;4| 18589        il:|changes| il:|to:|  (il:functions get-where-is-entries del-where-is-database)      il:|previous| il:|date:| "26-Oct-87 12:42:24" il:|{POGO:AISNORTH:XEROX}<CUTTING>LISP>NEW-WHERE-IS.;3|); Copyright (c) 1987 by Xerox Corporation.  All rights reserved.(il:prettycomprint il:new-where-iscoms)(il:rpaqq il:new-where-iscoms ((il:prop (il:makefile-environment il:filetype)                                      il:new-where-is)                               (il:p (provide "WHERE-IS")                                     (require "HASH-FILE" "HASH-FILE.DFASL")                                     (require "CASH-FILE" "CASH-FILE.DFASL")                                     (case il:makesysname (:lyric (il:filesload (il:sysload)                                                                         il:filepkg-patch))))                               (il:coms                                  (il:* il:|;;| "run time code")                                      (il:functions hash-file-where-is hash-file-types-of                                              get-where-is-entries add-where-is-databases                                              add-where-is-database del-where-is-database                                              same-where-is-database close-where-is-files)                                      (il:addvars (il:aroundexitfns close-where-is-files))                                      (il:variables *where-is-cash-files* *where-is-cash-size*))                               (il:coms                                  (il:* il:|;;| "notice time code")                                      (il:functions where-is-notice where-is-notice-internal                                              where-is-files where-is-default-define-types                                              where-is-namestring where-is-read-coms                                              where-is-set-write-date where-is-get-write-date)                                      (il:variables *where-is-hash-file-size*                                              *where-is-ignore-define-types*)                                      (il:prop il:argnames where-is-notice))))(il:putprops il:new-where-is il:makefile-environment (:readtable "XCL" :package "XCL"))(il:putprops il:new-where-is il:filetype :compile-file)(provide "WHERE-IS")(require "HASH-FILE" "HASH-FILE.DFASL")(require "CASH-FILE" "CASH-FILE.DFASL")(case il:makesysname (:lyric (il:filesload (il:sysload)                                    il:filepkg-patch)))(il:* il:|;;| "run time code")(defun hash-file-where-is (name type)                                  (il:* il:|;;| "return a list of file names containing NAME of TYPE ") (remove-duplicates (mapcan #'(lambda (entry)                                     (cdr (assoc type entry))) (get-where-is-entries name))        :test        'string=))(defun hash-file-types-of (name &optional (possible-types (where-is-default-define-types)))   (let ((entries (get-where-is-entries name))         (types nil))        (dolist (type possible-types)               (dolist (entry entries)                      (when (assoc type entry)                            (push type types)                            (return))))        (remove-duplicates types)))(defun get-where-is-entries (name)                                  (il:* il:|;;|                                  "return a list of all entries for name in *WHERE-IS-CASH-FILES*") (maplist #'(lambda (tail)                   (let ((database (car tail)))                        (proceed-case (cash-file:get-cash-file name (if (cash-file:cash-file-p                                                                                database)                                                                        database                                                                        (setf (car tail)                                                                              (                                                                             cash-file:open-cash-file                                                                               database                                                                                *where-is-cash-size*))                                                                        ))                               (nil nil :report "Delete from the databases known to WHERE-IS?"                                    (del-where-is-database database)                                    nil)))) *where-is-cash-files*))(defun add-where-is-databases (&rest pathnames)                                                "add each PATHNAME to the databases known to WHERE-IS"   (mapcar #'add-where-is-database pathnames))(defun add-where-is-database (pathname) "add PATHNAME to the databases known to WHERE-IS"   (let ((new-pathname (pathname pathname)))        (il:* il:|;;| "first delete & close the old one (if any)")        (del-where-is-database new-pathname)        (il:* il:|;;| "now add the new one")        (push new-pathname *where-is-cash-files*)        new-pathname))(defun del-where-is-database (database) (let ((found (find-if #'(lambda (element)                                                                       (same-where-is-database                                                                               database element))                                                             *where-is-cash-files*)))                                             (when found (setq *where-is-cash-files*                                                               (delete found *where-is-cash-files*                                                                       :test 'eq))                                                   (if (cash-file:cash-file-p found)                                                       (hash-file:close-hash-file (                                                                        cash-file:cash-file-hash-file                                                                                   found))                                                       found))))(defun same-where-is-database (x y) (flet ((coerce-to-pathame (cash-file-or-file-name)                                                  (pathname (if (cash-file:cash-file-p                                                                        cash-file-or-file-name)                                                                (hash-file::hash-file-stream                                                                 (cash-file:cash-file-hash-file                                                                  cash-file-or-file-name))                                                                cash-file-or-file-name))))                                          (let ((pathname-x (coerce-to-pathame x))                                                (pathname-y (coerce-to-pathame y)))                                 (il:* il:|;;| "do a case & version insensitive comparison")                                               (and (equalp (pathname-host pathname-x)                                                           (pathname-host pathname-y))                                                    (equalp (pathname-device pathname-x)                                                           (pathname-device pathname-y))                                                    (equalp (pathname-directory pathname-x)                                                           (pathname-directory pathname-y))                                                    (equalp (pathname-name pathname-x)                                                           (pathname-name pathname-y))                                                    (equalp (pathname-type pathname-x)                                                           (pathname-type pathname-y))))))(defun close-where-is-files (event) (case event                                          ((nil il:beforelogout il:beforesysout il:beforemakesys)                                           (il:nlsetq (mapc #'(lambda (cash-file:cash-file)                                                                     (if (cash-file:cash-file-p                                                                          cash-file:cash-file)                                                                         (hash-file:close-hash-file                                                                          (                                                                        cash-file:cash-file-hash-file                                                                           cash-file:cash-file))))                                                             *where-is-cash-files*)))))(il:addtovar il:aroundexitfns close-where-is-files)(defvar *where-is-cash-files* nil "list of pathnames or CASH-FILEs")(defvar *where-is-cash-size* 100 "size of the CACHE-FILE cache to use")(il:* il:|;;| "notice time code")(defun where-is-notice (database-file &key (files "*.;")                              (new nil)                              (define-types (where-is-default-define-types))                              (hash-file-size *where-is-hash-file-size*)                              (quiet nil)                              (temp-file nil))   (let* ((file (if temp-file (if new temp-file (il:copyfile database-file temp-file))                    database-file))          (hash-file:hash-file (if new (hash-file:make-hash-file file hash-file-size)                                   (hash-file:open-hash-file file :direction :io)))          (hash-file::*delete-old-version-on-rehash* t))         (unwind-protect          (dolist (pathname (where-is-files files))                 (unless quiet (format t ";;; ~A ." (namestring pathname)))                 (let ((namestring (where-is-namestring pathname)))                      (if (and (not new)                               (let ((old-write-date (where-is-get-write-date namestring                                                             hash-file:hash-file)))                                    (and old-write-date (= (file-write-date pathname)                                                           old-write-date))))                          (unless quiet (format t " up to date.~%"))                          (multiple-value-bind                           (file-vars values)                           (where-is-read-coms pathname)                           (when file-vars                                  (il:* il:|;;| "bind the filevars s.t. IL:INFILECOMS? will find them")                                 (progv file-vars values (unless quiet (princ "."))                                        (dolist (type define-types)                                               (let ((names (il:infilecoms? nil type (first file-vars                                                                                            ))))                                                    (when (consp names)                                 (il:* il:|;;| "IL:INFILECOMS? sometimes returns T.")                                                          (dolist (name names)                                                                 (where-is-notice-internal name type                                                                         namestring                                                                         hash-file:hash-file))))))                                 (where-is-set-write-date namestring pathname hash-file:hash-file)                                 (unless quiet (princ ". done.")                                        (terpri)))))))          (hash-file:close-hash-file hash-file:hash-file))         (let ((pathname (pathname (hash-file::hash-file-stream hash-file:hash-file))))              (cond                 (temp-file (unless quiet (format t ";;; Renaming ~A ... " (namestring pathname)))                        (multiple-value-bind (merged true-name real-true-name)                               (rename-file pathname database-file)                               (unless quiet (format t "~A~%" (namestring real-true-name)))                               real-true-name))                 (t pathname)))))(defun where-is-notice-internal (name type file-name hash-file:hash-file)                                  (il:* il:|;;|                                  "note that NAME is defined as TYPE on FILE-NAME in HASH-FILE ")  (il:* il:|;;| "we keep an ALIST for each name, indexed by type") (let* ((alist (hash-file:get-hash-file name hash-file:hash-file))        (old-entry (assoc type alist :test 'equal))        (old-files (cdr old-entry)))       (unless (member file-name old-files)              (il:* il:|;;| "this optimization helps a lot when re-noticing a file ")              (setf (hash-file:get-hash-file name hash-file:hash-file)                    (cons (cons type (cons file-name old-files))                          (delete old-entry alist :test 'eq :count 1))))))(defun where-is-files (files)                               (il:* il:|;;| "expand the FILES argument to WHERE-IS-NOTICE")  (il:* il:|;;| "allow: non-LIST, file names & file patterns") (mapcan #'(lambda (pattern)                  (let ((pathname (probe-file pattern)))                       (if pathname (list pathname)                           (case il:makesysname (:lyric                                  (il:* il:|;;| "CL:DIRECTORY is broken in Lyric")                                                       (il:directory pattern))                                 (otherwise (directory pattern)))))) (if (listp files)                                                                         files                                                                         (list files))))(defun where-is-default-define-types nil (mapcan #'(lambda (type)                                 (il:* il:|;;|                                  "ignore aliases and types on *WHERE-IS-IGNORE-DEFINE-TYPES*")                                                          (unless (or (consp type)                                                                      (member type                                                                        *where-is-ignore-define-types*                                                                             ))                                                                 (list type))) il:filepkgtypes))(defun where-is-namestring (pathname)                                  (il:* il:|;;|                            "return a namestring for PATHNAME containing only the NAME & TYPE fields ") (namestring (make-pathname :host nil :name (pathname-name pathname)                    :type                    (if (equal (pathname-type pathname)                               "")                        nil                        (pathname-type pathname)))))(defun where-is-read-coms (pathname) (il:* il:|;;;| "returns as first value a list of the filevars on PATHNAME, as second value a list of the values for these filevars.") (il:resetlst         (il:* il:|;;| "make sure all IL:LOADVARS get undone")        (il:resetsave (il:resetundo))        (do ((il:load-verbose-stream 'nil)             (all-file-vars)             (queue (list (il:filecoms (string-upcase (pathname-name pathname))))                    (cond                       ((consp (il:nlsetq (il:loadvars queue pathname nil)))                        (mapcan #'(lambda (file-var)                                         (if (boundp file-var)                                             (let ((file-vars (il:infilecoms? nil 'il:filevars                                                                      file-var)))                                                  (push file-var all-file-vars)                                                  (when (consp file-vars)                                                        file-vars))                                             (prog1 nil (warn "Couldn't find ~S on ~A." file-var                                                              (namestring pathname))))) queue))                       (t (warn "Error attempting to LOADVARS ~S from ~A." queue (namestring pathname                                                                                        ))                          'nil))))            ((null queue)             (setq all-file-vars (nreverse all-file-vars))             (values all-file-vars (mapcar #'symbol-value all-file-vars)))            (declare (special il:load-verbose-stream))            (dolist (file-var queue)                   (if (member file-var all-file-vars :test 'eq)                       (il:* il:|;;| "don't want to load any twice")                       (setf queue (delete file-var queue :test 'eq)))))))(defun where-is-set-write-date (namestring pathname hash-file:hash-file)                                  (il:* il:|;;| "store the write date as a bogus entry on the file") (where-is-notice-internal namestring 'si::write-date (file-write-date pathname)        hash-file:hash-file))(defun where-is-get-write-date (namestring hash-file:hash-file)                                  (il:* il:|;;|                                  "retrieve write date stored for NAMESTRING in HASH-FILE:HASH-FILE") (cadr (assoc 'si::write-date (hash-file:get-hash-file namestring hash-file:hash-file))))(defvar *where-is-hash-file-size* 10000 "initial size to create WHERE-IS hash files")(defvar *where-is-ignore-define-types* '(il:files il:expressions il:filevars il:alists) )(il:putprops where-is-notice il:argnames (il:database-file &key il:files il:new il:define-types                                                 il:hash-file-size il:quiet il:temp-file))(il:putprops il:new-where-is il:copyright ("Xerox Corporation" 1987))(il:declare\: il:dontcopy  (il:filemap (nil)))il:stop