(FILECREATED " 6-Jun-85 17:02:22" {ERIS}<LISPCORE>LIBRARY>MSHASH.;5 37839 changes to: (MACROS BOGUSVAL BOGUSVALP) (VARS MSHASHCOMS MSHFNS) (RECORDS HFTABLE) (FNS HFGETTABLE HFMAKETABLE HFMAPTABLE HFTESTTABLE HFEQMEMBTABLE HFSTORETABLE HFPUTTABLE HFADDTABLE HFSUBTABLE LOCALFNP MSKEY FORWARDTABLE MSVAL NEXTHASHKEY STOREHASHVALUE GETHASHTABLE ANALYZEFILES BUILDDB COPYDB FLUSHDB EQLST HFGETARGS MSFILECHECK MSFILES RESTOREDB SETDB UPDATECONTAINS UPDATEDB MSHASHWHENCLOSE) previous date: " 5-Jun-85 22:29:21" {ERIS}<LISPCORE>LIBRARY>MSHASH.;4) (* Copyright (c) 1985 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT MSHASHCOMS) (RPAQQ MSHASHCOMS [(VARS MSHFNS) [DECLARE: FIRST (P * (MAPCAR MSHFNS (FUNCTION (LAMBDA (X) (LIST (QUOTE MOVD?) (KWOTE (CADR X)) (KWOTE (CADDR X] (FNS * (MAPCAR MSHFNS (FUNCTION CAR))) (FNS LOCALFNP MSKEY FORWARDTABLE MSVAL NEXTHASHKEY STOREHASHVALUE GETHASHTABLE) (INITVARS MSHASHFILE MSREADONLYFLG NEXTHASHKEY MSFILETABLE (MSHASHSCRATCHSTRING (ALLOCSTRING 255))) (GLOBALVARS MSHASHFILE MSREADONLYFLG MSFILETABLE NEXTHASHKEY MSHASHSCRATCHSTRING MSHFNS) (GLOBALVARS MSDATABASELST MSDBEMPTY LOADDBFLG FILERDTBL) (DECLARE: DONTCOPY (RECORDS HFTABLE HashTextPtr) (* HashTextPtr is actually stolen from the new HASH) (MACROS BOGUSVAL BOGUSVALP)) (FILES (SYSLOAD FROM VALUEOF LISPUSERSDIRECTORIES) HASH) (LOCALVARS . T) (FNS ANALYZEFILES BUILDDB COPYDB FLUSHDB EQLST HFGETARGS MSFILECHECK MSFILES RESTOREDB SETDB UPDATECONTAINS UPDATEDB MSHASHWHENCLOSE) (COMS (* (ADDVARS (ANALYZEUSERFNS HFGETARGS]) (RPAQQ MSHFNS ((HFGETTABLE GETTABLE OLDHASHGETTABLE) (HFMAKETABLE MAKETABLE OLDHASHMAKETABLE) (HFMAPTABLE MAPTABLE OLDHASHMAPTABLE) (HFTESTTABLE TESTTABLE OLDHASHTESTTABLE) (HFEQMEMBTABLE EQMEMBTABLE OLDHASHEQMEMBTABLE) (HFSTORETABLE STORETABLE OLDHASHSTORETABLE) (HFPUTTABLE PUTTABLE OLDHASHPUTTABLE) (HFADDTABLE ADDTABLE OLDHASHADDTABLE) (HFSUBTABLE SUBTABLE OLDHASHSUBTABLE))) (DECLARE: FIRST (MOVD? (QUOTE GETTABLE) (QUOTE OLDHASHGETTABLE)) (MOVD? (QUOTE MAKETABLE) (QUOTE OLDHASHMAKETABLE)) (MOVD? (QUOTE MAPTABLE) (QUOTE OLDHASHMAPTABLE)) (MOVD? (QUOTE TESTTABLE) (QUOTE OLDHASHTESTTABLE)) (MOVD? (QUOTE EQMEMBTABLE) (QUOTE OLDHASHEQMEMBTABLE)) (MOVD? (QUOTE STORETABLE) (QUOTE OLDHASHSTORETABLE)) (MOVD? (QUOTE PUTTABLE) (QUOTE OLDHASHPUTTABLE)) (MOVD? (QUOTE ADDTABLE) (QUOTE OLDHASHADDTABLE)) (MOVD? (QUOTE SUBTABLE) (QUOTE OLDHASHSUBTABLE)) ) (DEFINEQ (HFGETTABLE [LAMBDA (KEY TABLE) (* cdl "13-May-85 08:07") (if (type? HFTABLE TABLE) then [PROG [FILEV FILE (LOCALV (OLDHASHGETTABLE KEY (fetch LOCALARRAY of TABLE] (if (OR (NULL LOCALV) (fetch INVFLG of TABLE)) then (if (SETQ FILEV (GETHASHFILE (MSKEY TABLE KEY) MSHASHFILE)) then (with HashTextPtr FILEV (SETFILEPTR (SETQ FILE (HASHFILENAME MSHASHFILE)) Start)) (SETQ FILEV (READ FILE FILERDTBL))) elseif (BOGUSVALP LOCALV) then (SETQ LOCALV NIL)) (RETURN (if (NULL (fetch INVFLG of TABLE)) then (OR LOCALV FILEV) else (SETQ TABLE (FORWARDTABLE TABLE)) (for X in (if (AND LOCALV FILEV) then (UNION LOCALV FILEV) else (OR LOCALV FILEV)) when (HFEQMEMBTABLE X KEY TABLE T) collect X] else (OLDHASHGETTABLE KEY TABLE]) (HFMAKETABLE [LAMBDA (N NAME INVFLG) (* cdl "12-May-85 12:47") (if MSHASHFILE then (create HFTABLE LOCALARRAY ←(OLDHASHMAKETABLE N) NAME ← NAME INVFLG ← INVFLG KEY ←(CONCAT [CHARACTER (COND [(LOOKUPHASHFILE (CONCAT (if INVFLG then "do!" else "by!") NAME) NEXTHASHKEY MSHASHFILE (if MSREADONLYFLG then 'RETRIEVE else '(RETRIEVE INSERT] ((NOT MSREADONLYFLG) (* key got written by LOOKUPHASHFILE) (NEXTHASHKEY)) (T (HELP "CAN'T SET UP READ-ONLY DATABASE FILE"] '!)) else (OLDHASHMAKETABLE N]) (HFMAPTABLE [LAMBDA (TABLE MFN) (* cdl "12-May-85 11:18") (DECLARE (SPECVARS TABLE MFN)) (if (type? HFTABLE TABLE) then [PROG (FILE TMP (HA (fetch LOCALARRAY of TABLE))) (* The function is named MFN so as not to conflict with the name of the fn argument in the old mapper.) [if (fetch INVFLG of TABLE) then [OLDHASHMAPTABLE HA (FUNCTION (LAMBDA (VAL ITEM) (if (SETQ VAL (HFGETTABLE ITEM TABLE)) then (APPLY* MFN VAL ITEM] else (OLDHASHMAPTABLE HA (FUNCTION (LAMBDA (VAL ITEM) (OR (BOGUSVALP VAL) (APPLY* MFN VAL ITEM] (if (SETQ TMP (GETHASHFILE (MSKEY TABLE '**ALLKEYS**) MSHASHFILE)) then (with HashTextPtr TMP (SETFILEPTR (SETQ FILE (HASHFILENAME MSHASHFILE)) Start)) (bind VAL for ITEM in (READ FILE FILERDTBL) do (if (AND (NOT (OLDHASHTESTTABLE ITEM HA)) (SETQ VAL (HFGETTABLE ITEM TABLE))) then (APPLY* MFN VAL ITEM] else (* Don't worry about bogus values) (OLDHASHMAPTABLE TABLE MFN]) (HFTESTTABLE [LAMBDA (KEY TABLE) (* cdl "12-May-85 11:02") (if (type? HFTABLE TABLE) then [PROG (LOCALV FILEV FORWARD FILE) (RETURN (if (OLDHASHTESTTABLE KEY (fetch LOCALARRAY of TABLE)) then [if (fetch INVFLG of TABLE) then (SETQ FORWARD (FORWARDTABLE TABLE)) (for X in (OLDHASHGETTABLE KEY (fetch LOCALARRAY of TABLE)) when (HFEQMEMBTABLE X KEY FORWARD T) do (RETURN T) finally (GO SCN2)) else (NOT (OLDHASHEQMEMBTABLE KEY (BOGUSVAL) (fetch LOCALARRAY of TABLE] elseif (NOT (fetch INVFLG of TABLE)) then (LOOKUPHASHFILE (MSKEY TABLE KEY) NIL MSHASHFILE NIL) else (GO SCAN))) SCAN(SETQ FORWARD (FORWARDTABLE TABLE)) SCN2(RETURN (if (SETQ FILEV (GETHASHFILE (MSKEY TABLE KEY) MSHASHFILE)) then (with HashTextPtr FILEV (SETFILEPTR (SETQ FILE (HASHFILENAME MSHASHFILE)) Start)) (if (for X in (READ FILE FILERDTBL) thereis (HFEQMEMBTABLE X KEY FORWARD T)) then T] else (OLDHASHTESTTABLE KEY TABLE]) (HFEQMEMBTABLE [LAMBDA (KEY VALUE TABLE FLG) (* cdl "12-May-85 11:02") (* Checks whether VALUE is a member of the TABLE entry defined by KEY. If so, value is the file position of VALUE in the entry if the entry is on the hashfile. If the entry is in the local database, the value will be non-NIL.) (if (type? HFTABLE TABLE) then (if (fetch INVFLG of TABLE) then (swap KEY VALUE) (SETQ TABLE (FORWARDTABLE TABLE))) (if (OLDHASHTESTTABLE KEY (fetch LOCALARRAY of TABLE)) then (OLDHASHEQMEMBTABLE KEY VALUE (fetch LOCALARRAY of TABLE)) elseif FLG then T elseif (SETQ KEY (GETHASHFILE (MSKEY TABLE KEY) MSHASHFILE)) then (with HashTextPtr KEY (FILEPOS (MSVAL VALUE) (HASHFILENAME MSHASHFILE) Start End)) T) else (OLDHASHEQMEMBTABLE KEY VALUE TABLE]) (HFSTORETABLE [LAMBDA (KEY TABLST VALUE) (* cdl "12-May-85 10:55") (if (type? HFTABLE (CADR TABLST)) then (OLDHASHPUTTABLE KEY (OR VALUE (BOGUSVAL)) (fetch LOCALARRAY of (CADR TABLST))) (if (CDDR TABLST) then (if (type? HFTABLE (CDDR TABLST)) then (bind (HA ←(fetch LOCALARRAY of (CDDR TABLST))) for V inside VALUE do (OLDHASHADDTABLE V KEY HA)) else (SHOULDNT))) else (OLDHASHSTORETABLE KEY TABLST VALUE]) (HFPUTTABLE [LAMBDA (KEY VALUE TABLE) (* cdl "12-May-85 11:02") (if (type? HFTABLE TABLE) then (OLDHASHPUTTABLE KEY (OR VALUE (BOGUSVAL)) (fetch LOCALARRAY of TABLE)) else (OLDHASHPUTTABLE KEY (OR VALUE (BOGUSVAL)) TABLE]) (HFADDTABLE [LAMBDA (KEY VALUE TABLE) (* cdl "12-May-85 11:03") (if (type? HFTABLE TABLE) then (SHOULDNT) else (OLDHASHADDTABLE KEY VALUE TABLE]) (HFSUBTABLE [LAMBDA (KEY VALUE TABLE) (* cdl "12-May-85 11:03") (if (type? HFTABLE TABLE) then (SHOULDNT) else (OLDHASHSUBTABLE KEY VALUE TABLE]) ) (DEFINEQ (LOCALFNP [LAMBDA (FN) (* cdl " 7-May-85 14:59") (* T if FN is KNOWN in the local database) (if [for TABLE in '(CALL REF NOBIND) thereis (AND (OLDHASHTESTTABLE FN (if [type? HFTABLE (SETQ TABLE (CADR (ASSOC TABLE MSDATABASELST] then (SETQ TABLE (fetch LOCALARRAY of TABLE)) else TABLE)) (NOT (OLDHASHEQMEMBTABLE FN (BOGUSVAL) TABLE] then T]) (MSKEY [LAMBDA (TABLE KEY) (* cdl " 7-May-85 12:34") (if (type? HFTABLE TABLE) then (RPLSTRING MSHASHSCRATCHSTRING 1 (fetch (HFTABLE KEY) of TABLE)) (RPLSTRING MSHASHSCRATCHSTRING 3 KEY) (SUBSTRING MSHASHSCRATCHSTRING 1 (IPLUS 2 (NCHARS KEY)) (CONSTANT (CONCAT))) else (SHOULDNT]) (FORWARDTABLE [LAMBDA (TABLE) (* cdl "12-May-85 11:07") (for X in MSDATABASELST when (EQ (CAR X) (fetch (HFTABLE NAME) of TABLE)) do (RETURN (CADR X)) finally (SELECTQ (fetch (HFTABLE NAME) of TABLE) (HELP]) (MSVAL [LAMBDA (VAL) (* cdl "12-May-85 11:08") (* Produces a string with all the escapes needed for searching with FILEPOS for PRIN2-pnames) (RPLSTRING MSHASHSCRATCHSTRING 1 " ") (bind C for I from 1 while (SETQ C (NTHCHAR VAL I T FILERDTBL)) do (RPLSTRING MSHASHSCRATCHSTRING (ADD1 I) C) finally (RPLSTRING MSHASHSCRATCHSTRING (ADD1 I) " ") (RETURN (SUBSTRING MSHASHSCRATCHSTRING 1 (ADD1 I) (CONSTANT (CONCAT]) (NEXTHASHKEY [LAMBDA NIL (* cdl " 7-May-85 17:10") (PROG1 NEXTHASHKEY (PUTHASHFILE 'NEXTHASHKEY (add NEXTHASHKEY 1) MSHASHFILE]) (STOREHASHVALUE [LAMBDA (KEY VALUE TABLE) (* cdl "13-May-85 08:11") (PROG (PTR FILE (HASHKEY (MSKEY TABLE KEY))) (if VALUE then (SETFILEPTR (SETQ FILE (HASHFILENAME MSHASHFILE)) -1) (SETQ PTR (create HashTextPtr Start ←(GETFILEPTR FILE))) (if (LISTP VALUE) then (PRIN3 "( " FILE) (for V on VALUE do (PRIN4 (CAR V) FILE FILERDTBL) (PRIN3 " " FILE) finally (if V then (PRIN3 ". " FILE) (PRIN4 V FILE FILERDTBL) (PRIN3 " " FILE))) (* Don't use SPACES to avoid line positioning) (PRIN3 ")" FILE) else (PRIN3 " " FILE) (* The leading space is for the EQMEMB predicate) (PRIN4 VALUE FILE FILERDTBL) (PRIN3 " " FILE)) (with HashTextPtr PTR (SETQ End (GETFILEPTR FILE))) (PUTHASHFILE HASHKEY PTR MSHASHFILE) else (PUTHASHFILE HASHKEY NIL MSHASHFILE))) VALUE]) (GETHASHTABLE [LAMBDA (KEY TABLE) (* cdl "12-May-85 11:08") (PROG (FILE PTR) (if (SETQ PTR (GETHASHFILE (MSKEY TABLE KEY) MSHASHFILE)) then (with HashTextPtr PTR (SETFILEPTR (SETQ FILE (HASHFILENAME MSHASHFILE)) Start)) (RETURN (READ FILE FILERDTBL]) ) (RPAQ? MSHASHFILE NIL) (RPAQ? MSREADONLYFLG NIL) (RPAQ? NEXTHASHKEY NIL) (RPAQ? MSFILETABLE NIL) (RPAQ? MSHASHSCRATCHSTRING (ALLOCSTRING 255)) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS MSHASHFILE MSREADONLYFLG MSFILETABLE NEXTHASHKEY MSHASHSCRATCHSTRING MSHFNS) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS MSDATABASELST MSDBEMPTY LOADDBFLG FILERDTBL) ) (DECLARE: DONTCOPY [DECLARE: EVAL@COMPILE (TYPERECORD HFTABLE (NAME LOCALARRAY KEY INVFLG)) (TYPERECORD HashTextPtr (Start . End)) ] (DECLARE: EVAL@COMPILE (PUTPROPS BOGUSVAL MACRO (NIL '**BOGUSVALUE**)) (PUTPROPS BOGUSVALP MACRO ((X) (EQ X '**BOGUSVALUE**))) ) ) (FILESLOAD (SYSLOAD FROM VALUEOF LISPUSERSDIRECTORIES) HASH) (DECLARE: DOEVAL@COMPILE DONTCOPY (LOCALVARS . T) ) (DEFINEQ (ANALYZEFILES [LAMBDA (FILES EVENIFVALID) (* cdl "12-May-85 11:27") (DECLARE (GLOBALVARS FILELST)) (* Reanalyzes functions on the files inside FILES, and enters the files' dates in the masterscope file-table. - Each file-specification can be a list of the form (file . fns), where fns=T => all, fns=NIL => none, and otherwise fns is a list of fns to be examined. A litatom file-specification is interpreted as (file . T). If n - if fns=T and EVENIFVALID=NIL, attempt to load a .DATABASE file.) (bind FILE N D FNS ALLFNS declare: (SPECVARS FILE FNS ALLFNS) for X inside FILES collect (if (LISTP X) then (SETQ FILE (CAR X)) (SETQ FNS (CDR X)) else (SETQ FILE X) (SETQ FNS T)) (SETQ N (NAMEFIELD FILE)) (if (CDR (LISTP FILES)) then (printout T T .P2 FILE T)) (if (NOT (MEMB N FILELST)) then (RESETVARS ((LOADDBFLG 'NO)) (SETQ FILE (LOADFROM FILE))) (* In case there's some spelling correction) (SETQ N (NAMEFIELD FILE))) (SETQ D (CAR (GETPROP N 'FILEDATES))) (if [OR EVENIFVALID (NEQ FNS T) (OR (NOT (GETD 'LOADDB)) (NOT (LOADDB (CDR D] then (SETQ ALLFNS (FILEFNSLST N)) (* RESETLST so temporary state is flushed, in particular, the file that masterscope opens.) (RESETLST (for F in (if (EQ FNS T) then ALLFNS else FNS) do (UPDATEFN F T))) (UPDATECONTAINS N ALLFNS) (STORETABLE N MSFILETABLE D)) (if (CDR (LISTP FILES)) then (printout T T)) (CDR D]) (BUILDDB [LAMBDA (NAME FILES #ENTRIES) (* gbn " 5-Jun-85 22:28") (* For creating a database and adding files to it. If NAME and FILES are both NIL, will make a new version of the current database) (OR NAME (AND MSHASHFILE (SETQ NAME (HASHFILENAME MSHASHFILE))) (ERROR "No database file name")) (if (NULL FILES) then (SETDB NAME) (SETQ FILES (MSFILES))) (SETDB NAME (QUOTE CREATE) #ENTRIES) (SETQ FILES (for F inside FILES collect (PACKFILENAME (QUOTE VERSION) NIL (QUOTE BODY) F))) (ANALYZEFILES FILES T) (SETDB NAME]) (COPYDB [LAMBDA (OLDFILE NEWFILE LEAVEOPEN) (* cdl "13-May-85 10:29") (* Copies the ms database on OLDFILE to NEWFILE, compressing out old space) [SETQ OLDFILE (INFILEP (if OLDFILE then (PACKFILENAME 'BODY OLDFILE 'EXTENSION 'HASHDATABASE) else (HASHFILENAME MSHASHFILE] [SETQ NEWFILE (OUTFILEP (if NEWFILE then (PACKFILENAME 'BODY NEWFILE 'EXTENSION 'HASHDATABASE) else (PACKFILENAME 'VERSION NIL 'BODY OLDFILE] (COPYHASHFILE OLDFILE NEWFILE (FUNCTION [LAMBDA (KEY VALUE OLDFILE NEWFILE) (* Old and new HASH incompatibility!) (if (NUMBERP KEY) then KEY elseif (type? HashTextPtr KEY) then (* old HASH) (SETFILEPTR (SETQ NEWFILE (HASHFILENAME OLDFILE)) -1) (SETQ OLDFILE (HASHFILENAME VALUE)) (with HashTextPtr KEY (SETQ VALUE (GETFILEPTR NEWFILE)) (COPYBYTES OLDFILE NEWFILE Start End) (SETQ Start VALUE) (SETQ End (GETFILEPTR NEWFILE))) KEY else VALUE]) NIL LEAVEOPEN]) (FLUSHDB [LAMBDA NIL (* cdl "12-May-85 11:09") (if (AND MSHASHFILE (NOT MSREADONLYFLG)) then (for X in MSDATABASELST bind LA KEYS REMKEYS TABLE FILEV FILE declare: (SPECVARS LA KEYS REMKEYS TABLE) do (if (type? HFTABLE (SETQ TABLE (CDDR X))) then (SETQ KEYS NIL) (SETQ REMKEYS NIL) [OLDHASHMAPTABLE (SETQ LA (fetch LOCALARRAY of TABLE)) (FUNCTION (LAMBDA (VAL ITEM) (if (STOREHASHVALUE ITEM (HFGETTABLE ITEM TABLE) TABLE) then (push KEYS ITEM) else (push REMKEYS ITEM)) (OLDHASHPUTTABLE ITEM NIL LA] (if (OR KEYS REMKEYS) then (STOREHASHVALUE '**ALLKEYS**(UNION KEYS (LDIFFERENCE (GETHASHTABLE '**ALLKEYS** TABLE) REMKEYS)) TABLE))) (if (type? HFTABLE (SETQ TABLE (CADR X))) then (SETQ KEYS NIL) (SETQ REMKEYS NIL) [OLDHASHMAPTABLE (SETQ LA (fetch LOCALARRAY of TABLE)) (FUNCTION (LAMBDA (VAL ITEM) (if (BOGUSVALP VAL) then (SETQ VAL NIL)) (if VAL then (push KEYS ITEM) else (push REMKEYS ITEM)) (if (NOT (EQLST VAL (GETHASHTABLE ITEM TABLE))) then (STOREHASHVALUE ITEM VAL TABLE)) (OLDHASHPUTTABLE ITEM NIL LA] (if (OR KEYS REMKEYS) then (SETQ KEYS (UNION (if (SETQ FILEV (GETHASHFILE (MSKEY TABLE '**ALLKEYS**) MSHASHFILE)) then (with HashTextPtr FILEV (SETFILEPTR (SETQ FILE (HASHFILENAME MSHASHFILE)) Start)) (LDIFFERENCE (SETQ FILEV (READ FILE FILERDTBL)) REMKEYS)) KEYS)) (if (EQLST FILEV KEYS) then (STOREHASHVALUE '**ALLKEYS** KEYS TABLE]) (EQLST [LAMBDA (L1 L2) (* cdl " 7-May-85 15:06") (if (AND (for X in L1 always (FMEMB X L2)) (for X in L2 always (FMEMB X L1))) then T]) (HFGETARGS [LAMBDA (NAME DEF DATA) (* cdl "12-May-85 11:24") (* An analyze userfn that collects the argument list for the ARG table) (DECLARE (GLOBALVARS MSHASHFILE) (SPECVARS DEF DATA)) [if MSHASHFILE then (* NLSETQ cause ARGLIST could cause an error) (NLSETQ (RPLACD (FASSOC 'ARG DATA) (OR (ARGLIST DEF) T] DATA]) (MSFILECHECK [LAMBDA (FILES) (* cdl " 7-May-85 14:45") (DECLARE (GLOBALVARS FILELST)) (* Returns alist containing the fullnames of files inside FILES which were known to the database and no longer exist (keyed under DELETED) or whose latest version is not known to the database (keyed under CHANGED). If FILES=T, checks the files known to the database. If FILES=NIL, uses filelst) [if (EQ FILES T) then (SETQ FILES (MSFILES)) elseif FILES then FILES else (SETQ FILES (SORT (for FILE in FILELST collect (CDAR (GETPROP FILE 'FILEDATES] (bind NF CHANGED DELETED for FL inside FILES do (if (SETQ NF (INFILEP (PACKFILENAME 'VERSION NIL 'BODY FL))) then (if [NEQ NF (CDR (GETTABLE (NAMEFIELD FL) (CADR MSFILETABLE] then (push CHANGED NF)) elseif [SETQ FL (CDR (GETTABLE (NAMEFIELD FL) (CADR MSFILETABLE] then (push DELETED FL)) (* The file disappeared if NF=NIL--return the previously known name) finally (RETURN (NCONC [if DELETED then (LIST (CONS 'DELETED (DREVERSE DELETED] (if CHANGED then (LIST (CONS 'CHANGED (DREVERSE CHANGED]) (MSFILES [LAMBDA NIL (* cdl " 7-May-85 15:07") (* Returns a list of the files known to the current ms database.) (PROG (VAL) (DECLARE (SPECVARS VAL)) [MAPTABLE (CADR MSFILETABLE) (FUNCTION (LAMBDA (DATE FILE) (push VAL (CDR DATE] (RETURN (SORT VAL]) (RESTOREDB [LAMBDA (FILE WRITEDATE OLDFILES) (* cdl "13-May-85 08:23") (* Re-opens a (new version of a) previously opened database file. Used as a status function for the mshashfile. OLDFILES is a list of fullnames of files that were on FILELST and known to the database when the sysout was made.) (* AFTERCLOSE FILE) (if [NULL (SETQ FILE (INFILEP (PACKFILENAME 'VERSION NIL 'BODY FILE] then (SETDB) NIL else (SETQ FILE (SETDB FILE 'RESTORE)) [if (NOT (IEQP WRITEDATE (GETFILEINFO FILE 'IWRITEDATE))) then (bind FLG NEWF for OLDF in OLDFILES unless (EQ [SETQ NEWF (CDR (GETTABLE (CAR OLDF) (CADR MSFILETABLE] (CDR OLDF)) do (* If NEWF=NIL, the file was removed from the database. Perhaps we should mark all its in-core functions as needing reanalysis) (if (NULL FLG) then (printout T T "***WARNING: The database has been updated. Information about files that you currently have loaded has changed:" T) (SETQ FLG T)) (if (CDR OLDF) then (printout T T .P2 (CDR OLDF) " has been ") (if NEWF then (printout T "replaced by " .P2 NEWF) else (printout T "deleted")) else (printout T T .P2 NEWF " has been added")) finally (if FLG then (printout T T T "You might want to LOADFROM or REANALYZE those files." T] T]) (SETDB [LAMBDA (FILE MODE #ENTRIES) (* gbn " 5-Jun-85 22:29") (* * Sets FILE to be the current masterscope hashfile, open for write if MODE is T or BOTH, new file if MODE=CREATE, restores old database if MODE=RESTORE. If FILE is NIL, closes any such file which is currently open. If FILE is T, simply changes the write-mode of the current file) (DECLARE (GLOBALVARS FILELST)) (* MSDBEMPTY is a masterscope variable) (PROG [CLOSEDFILE (RESTOREFLG (EQ MODE (QUOTE RESTORE] (if (AND MSHASHFILE (HASHFILEP MSHASHFILE)) then (if (NEQ MODE (QUOTE NOFLUSH)) then (FLUSHDB)) (SETQ CLOSEDFILE (CLOSEHASHFILE MSHASHFILE))) [if (EQ FILE T) then (* Reopen the old file with a new access mode) (if CLOSEDFILE then (SETQ MSHASHFILE (OPENHASHFILE CLOSEDFILE MODE))) elseif FILE then (SETQ FILE (PACKFILENAME (QUOTE BODY) FILE (QUOTE EXTENSION) (QUOTE HASHDATABASE))) (if RESTOREFLG then (* Don't want to wipe out old local database; use previous read mode.) (SETQ MODE (NOT MSREADONLYFLG)) else (%. ERASE)) (SETQ MSHASHFILE (if (EQ MODE (QUOTE CREATE)) then (SETQ MODE T) (SETQ MSDBEMPTY T) (CREATEHASHFILE FILE (QUOTE EXPR) NIL #ENTRIES) else (OPENHASHFILE FILE MODE))) (SETQ NEXTHASHKEY (OR (GETHASHFILE (QUOTE NEXTHASHKEY) MSHASHFILE) (CONSTANT (CHARCODE A] (if MSHASHFILE then [if (NULL CLOSEDFILE) then (* Set up the hashfile functions the first time a database is open. That way non-users don't pay.) (for X in MSHFNS do (MOVD (CAR X) (CADR X] (MSHASHWHENCLOSE MSHASHFILE) (SETQ MSREADONLYFLG (SELECTQ MODE ((INPUT NIL) T) NIL)) (if (AND (NEQ FILE T) (NOT RESTOREFLG)) then (if (NULL MSDATABASELST) then (%. WHO CALLS FUM)) (* Gets the database initialized, even though MSINIT isn't an entry.) ) (RETURN (HASHFILENAME MSHASHFILE)) elseif CLOSEDFILE then (%. ERASE) (* If we're closing up, need to make masterscope think the database went away, or it will still try to do lookups on random occasions, such as a record redeclaration) (RETURN CLOSEDFILE]) (UPDATECONTAINS [LAMBDA (FILE NEWFNS KEEPFLG) (* cdl " 7-May-85 15:14") (* Makes sure that the database is aware of which functions have disappeared, and who contains what. FILE is just the namefield. KEEPFLG is T then called from DUMPDB. We then are more cautious about destroying information about this function, cause it might have been moved to another file.) (PROG (UPDATEFNS OLDFNS (TBL (ASSOC 'CONTAINS MSDATABASELST))) (DECLARE (SPECVARS UPDATEFNS)) (SETQ OLDFNS (GETTABLE FILE (CADR TBL))) (if (AND (NOT KEEPFLG) (SETQ UPDATEFNS (LDIFFERENCE OLDFNS NEWFNS))) then (%. ERASE IN UPDATEFNS)) [for FN in OLDFNS unless (FMEMB FN NEWFNS) do (* Keep a single file, not a list, cause the analyzed definition is from only one file.) (for CONTAINER inside (GETTABLE FN (CDDR TBL)) do (STORETABLE CONTAINER TBL (REMOVE FN (GETTABLE CONTAINER (CADR TBL] (STORETABLE FILE TBL NEWFNS]) (UPDATEDB [LAMBDA (ADDFILES DELETEFILES ADDONLY NOGCFLG) (* cdl "12-May-85 13:02") (DECLARE (SPECVARS ADDFILES DELETEFILES ADDONLY NOGCFLG) (GLOBALVARS DWIMWAIT)) (* Copies the current masterscope hash-file into a scratch file, then information about files inside DELETEFILES (and erases function information for functions only on those files), then loads the .DATABASE files for the files in ADDFILES. The copy is so that this function will execute even though someone else is reading the current database. The database is copied to a scratch file, then renamed to be a newer version of the previous database, which is deleted. This allows others to use the old database while the copying is going on. If an earlier version of the scratch file exists, it means that someone else is currently updating (there version disappears when the complete successfully or logout), so we wait for them to finish.) (* Doesn't look for out-of-date files if ADDONLY. - If ADDFILES is a FIXP, it is the maximum number of files to be analyzed, as a precaution against running out of space when updating large databases. Repeated calls on UPDATEDB with a low ADDFILES should get through. - If NOGCFLG, the database is copied without compacting, which is considerably faster, though the resulting file is much larger. It may be fastest to do a number of updates with a small ADDFILES and NOGCFLG, then do a final one with compacting.) (if (NULL MSHASHFILE) then (ERROR "No current hash-database file")) (RESETLST (PROG (SCRATCH CHECKEDFILES DBFILES NFILES NADDFILES (NHF (LIST NIL)) (OLDMSN (HASHFILENAME MSHASHFILE))) [RESETSAVE (PROGN NHF) '(PROGN (CLOSEF? (CAR OLDVALUE)) (AND RESETSTATE (DELFILE (CAR OLDVALUE] [SETQ NHF (CAR (RPLACA NHF (CLOSEF (OPENFILE (SETQ SCRATCH (PACKFILENAME 'DIRECTORY (FILENAMEFIELD OLDMSN 'DIRECTORY) 'NAME 'NEWHASHDATABASE 'EXTENSION 'SCRATCH 'TEMPORARY 'S)) 'OUTPUT 'NEW] (* The CONS cell holds the name for resetsaves, but we don't need it below) (* PACKFILENAME produces version -1 for ;S on TOPS20) (if (EQ (SYSTEMTYPE) 'TOPS20) then (SETQ SCRATCH (PACKFILENAME 'VERSION NIL 'BODY SCRATCH))) [bind OLDV (RPT ← 1) until (EQ NHF (SETQ OLDV (FULLNAME SCRATCH 'OLDEST))) do (DISMISS 2000) (if RPT then (if (EQ RPT 5) then (printout T T (GETFILEINFO OLDV 'AUTHOR) " seems to be updating the database right now." T "I'm waiting for him to finish." T T) (SETQ RPT NIL) else (add RPT 1] (* If there is a version earlier than the one we got, someone else must have it, and we must wait until he gets rid of it (by deleting it)) (if (NULL ADDONLY) then (* Do this first, so user can break MSFILECHECK to modify things without having to wait for the copy to complete.) (SETQ CHECKEDFILES (MSFILECHECK T))) [RESETSAVE (SETDB) '(PROGN (SETDB (PACKFILENAME 'VERSION NIL 'BODY OLDVALUE] (* Leave this sysout with the latest version of the current database open--hopefully, the new one.) (if (FIXP ADDFILES) then (SETQ NFILES ADDFILES) (* Limit on number of files to analyze is coded in ADDFILES; necessary as an antidote to storage-full) (SETQ ADDFILES NIL)) (SETQ ADDFILES (NCONC (CDR (FASSOC 'CHANGED CHECKEDFILES)) (MKLIST ADDFILES))) (SETQ ADDFILES (for F in ADDFILES unless (bind (NAMEF ←(NAMEFIELD F)) for DF in DELETEFILES thereis (EQ NAMEF (NAMEFIELD DF))) collect F)) (SETQ NADDFILES (LENGTH ADDFILES)) (if (IGREATERP NADDFILES 0) then (printout T T NADDFILES " files to be updated:" 5 .PARA2 5 0 ADDFILES)) (if NOGCFLG then (COPYFILE OLDMSN NHF) (* File comes back closed, so re-open it to be consistent with the LEAVEOPEN logic.) (OPENHASHFILE NHF 'BOTH) else (COPYDB OLDMSN NHF T)) (* Must leave the new file open--otherwise, the user might lose access to it before he has started to load in the .DATABASE files) (SETDB NHF T) (for F inside DELETEFILES do (SETQ F (NAMEFIELD F)) (UPDATECONTAINS F) (STORETABLE F MSFILETABLE NIL)) (for F NAMEF in (CDR (FASSOC 'DELETED CHECKEDFILES)) eachtime (SETQ NAMEF (NAMEFIELD F)) when [AND (for DF inside DELETEFILES never (EQ NAMEF (NAMEFIELD DF))) (EQ 'Y (ASKUSER DWIMWAIT 'Y (LIST (PACKFILENAME 'VERSION NIL 'BODY F) "no longer exists. Shall I remove it from the database"] do (UPDATECONTAINS NAMEF) (STORETABLE NAMEF MSFILETABLE NIL)) (for F DBF in ADDFILES as I to (OR NFILES NADDFILES) do (printout T T T .P2 F T) (if (SETQ DBF (LOADDB (FINDFILE F))) then (push DBFILES DBF) else (ANALYZEFILES F T))) (SETDB) (* This closes the file, but other updaters are still locked out cause they go for a new version and then trip over our old one.) [COND ((SETQ NHF (RENAMEFILE NHF (PACKFILENAME 'VERSION NIL 'BODY OLDMSN))) (bind F (OLDV ←(FILENAMEFIELD OLDMSN 'VERSION)) (STEM ←(PACKFILENAME 'VERSION NIL 'BODY OLDMSN)) while (AND (SETQ F (FULLNAME STEM 'OLDEST)) (IGEQ OLDV (FILENAMEFIELD F 'VERSION)) (DELFILE F))) (* Success: We delete the old hash file and all the .DATABASE files we loaded, plus any earlier versions. DELFILE will return NIL if we don't have deletion rights.) (for DBF in DBFILES do (* Don't delete dbfiles newer than the one we just read) (bind F (OLDV ←(FILENAMEFIELD DBF 'VERSION)) (STEM ←(PACKFILENAME 'VERSION NIL 'BODY DBF)) while (AND (SETQ F (FULLNAME STEM 'OLDEST)) (IGEQ OLDV (FILENAMEFIELD F 'VERSION)) (DELFILE F] (* Now others can get in to read or update.) (if (AND NFILES (IGREATERP NADDFILES NFILES)) then (printout T T (IDIFFERENCE NADDFILES NFILES) " files still to be updated." T)) (RETURN NHF]) (MSHASHWHENCLOSE [LAMBDA (HASHFILE) (* cdl " 7-May-85 17:18") (DECLARE (GLOBALVARS FILELST)) (WHENCLOSE (HASHFILENAME HASHFILE) 'STATUS [FUNCTION (LAMBDA (FILE) (LIST 'RESTOREDB FILE (GETFILEINFO FILE 'IWRITEDATE) (for F in FILELST collect (* The CDR is NIL for files not in the database) (CONS F (CDR (HFGETTABLE F (CADR MSFILETABLE] 'CLOSEALL 'NO 'EOF (FUNCTION NILL) 'AFTER (FUNCTION (LAMBDA (F) (* after the hashfile is closed, reset the global name and file) (SETQ MSHASHFILE NIL]) ) (* (ADDVARS (ANALYZEUSERFNS HFGETARGS))) (PUTPROPS MSHASH COPYRIGHT ("Xerox Corporation" 1985)) (DECLARE: DONTCOPY (FILEMAP (NIL (2721 9953 (HFGETTABLE 2731 . 3857) (HFMAKETABLE 3859 . 4697) (HFMAPTABLE 4699 . 6131) ( HFTESTTABLE 6133 . 7535) (HFEQMEMBTABLE 7537 . 8562) (HFSTORETABLE 8564 . 9167) (HFPUTTABLE 9169 . 9501) (HFADDTABLE 9503 . 9726) (HFSUBTABLE 9728 . 9951)) (9954 13800 (LOCALFNP 9964 . 10555) (MSKEY 10557 . 10968) (FORWARDTABLE 10970 . 11320) (MSVAL 11322 . 12000) (NEXTHASHKEY 12002 . 12211) ( STOREHASHVALUE 12213 . 13403) (GETHASHTABLE 13405 . 13798)) (14589 37713 (ANALYZEFILES 14599 . 16555) (BUILDDB 16557 . 17290) (COPYDB 17292 . 18663) (FLUSHDB 18665 . 20835) (EQLST 20837 . 21080) ( HFGETARGS 21082 . 21654) (MSFILECHECK 21656 . 23144) (MSFILES 23146 . 23621) (RESTOREDB 23623 . 25409) (SETDB 25411 . 28331) (UPDATECONTAINS 28333 . 29545) (UPDATEDB 29547 . 36954) (MSHASHWHENCLOSE 36956 . 37711))))) STOP