(FILECREATED "17-Jul-86 12:13:25" {QV}<NOTECARDS>1.3K>RHTPATCH078.;1 42056 changes to: (VARS RHTPATCH078COMS)) (* Copyright (c) 1986 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT RHTPATCH078COMS) (RPAQQ RHTPATCH078COMS ((* * Changes to NCINTERFACE) (FNS NC.FileBrowserInspect&Repair NC.DoNoteFileOp) (* * Change to NCREPAIR) (FNS NC.InspectAndRepairNoteFile NC.ScavengerPhase1 NC.ScavengeDatabaseFile NC.GetScavengerInfo NC.BuildBadCardsList))) (* * Changes to NCINTERFACE) (DEFINEQ (NC.FileBrowserInspect&Repair (LAMBDA (Browser Key Item Menu ReadSubstancesFlg) (* rht: "17-Jul-86 11:50") (* * Function called from file browser menu for notefile inspect&repair.) (* * rht 7/1/86: Now passes InterestedWindow arg to NC.ScavengerPhase1.) (* * rht 7/17/86: Now calls NC.InspectAndRepairNoteFile instead of NC.ScavengerPhase1.) (for FileObject in (FB.SELECTEDFILES Browser) do (NC.InspectAndRepairNoteFile (MKATOM (FB.FETCHFILENAME FileObject)) ReadSubstancesFlg (fetch (FILEBROWSER PROMPTWINDOW) of Browser))))) (NC.DoNoteFileOp (LAMBDA (Op) (* rht: "17-Jul-86 11:54") (* * Do a NoteFile op chosen from NC icon menu) (* * rht 7/2/86: Now calls NC.AbortSession with NC.NoteCardsIconWindow arg.) (* * rht 7/5/86: Added Read-only% Open entry.) (* * rht 7/17/86: Now calls NC.InspectAndRepairNoteFile instead of NC.ScavengerPhase1.) (SELECTQ Op (Open% NoteFile (LET ((NoteFile (NC.ListOfNoteFilesMenu T NIL NC.NoteCardsIconWindow (QUOTE Open% NoteFile)))) (if (NULL NoteFile) then NIL else (if (EQ NoteFile (QUOTE NEW)) then (SETQ NoteFile NIL)) (NC.OpenDatabaseFile NoteFile NIL NIL NIL NIL NIL NIL NIL NIL NIL NC.NoteCardsIconWindow)))) (Read-only% Open (LET ((NoteFile (NC.ListOfNoteFilesMenu T NIL NC.NoteCardsIconWindow (QUOTE Open% NoteFile)))) (if (NULL NoteFile) then NIL else (if (EQ NoteFile (QUOTE NEW)) then (SETQ NoteFile NIL)) (NC.OpenDatabaseFile NoteFile (QUOTE INPUT) NIL NIL NIL NIL NIL NIL NIL NIL NC.NoteCardsIconWindow)))) (Checkpoint% NoteFile (LET ((NoteFile (NC.ListOfNoteFilesMenu NIL T NC.NoteCardsIconWindow (QUOTE Checkpoint% NoteFile)))) (if NoteFile then (NC.CheckpointDatabase NoteFile NIL NIL NIL NIL NC.NoteCardsIconWindow)))) (Close% NoteFile (LET ((NoteFile (NC.ListOfNoteFilesMenu NIL T NC.NoteCardsIconWindow (QUOTE Close% NoteFile)))) (if NoteFile then (NC.CloseDatabaseFile NoteFile NC.NoteCardsIconWindow)))) (Abort% NoteFile (LET ((NoteFile (NC.ListOfNoteFilesMenu NIL T NC.NoteCardsIconWindow (QUOTE Abort% NoteFile)))) (if NoteFile then (NC.AbortSession NoteFile NC.NoteCardsIconWindow)))) (Compact% NoteFile (LET ((NoteFile (NC.ListOfNoteFilesMenu T NIL NC.NoteCardsIconWindow (QUOTE Compact% NoteFile)))) (if (NULL NoteFile) then NIL else (if (EQ NoteFile (QUOTE NEW)) then (SETQ NoteFile NIL)) (NC.CompactNoteFile NoteFile NIL NIL NC.NoteCardsIconWindow)))) (Compact% In% Place (LET ((NoteFile (NC.ListOfNoteFilesMenu T NIL NC.NoteCardsIconWindow (QUOTE Compact% NoteFile)))) (if (NULL NoteFile) then NIL else (if (EQ NoteFile (QUOTE NEW)) then (SETQ NoteFile NIL)) (NC.CompactNoteFile NoteFile NIL T NC.NoteCardsIconWindow)))) (Inspect&Repair% NoteFile (LET ((NoteFile (NC.ListOfNoteFilesMenu T NIL NC.NoteCardsIconWindow (QUOTE Inspect&Repair% NoteFile)))) (if (NULL NoteFile) then NIL else (if (EQ NoteFile (QUOTE NEW)) then (SETQ NoteFile NIL)) (NC.InspectAndRepairNoteFile NoteFile NIL NC.NoteCardsIconWindow)))) (Read% Substances (LET ((NoteFile (NC.ListOfNoteFilesMenu T NIL NC.NoteCardsIconWindow (QUOTE Inspect&Repair% NoteFile)))) (if (NULL NoteFile) then NIL else (if (EQ NoteFile (QUOTE NEW)) then (SETQ NoteFile NIL)) (NC.InspectAndRepairNoteFile NoteFile T NC.NoteCardsIconWindow)))) (Copy% NoteFile (LET ((NoteFile (NC.ListOfNoteFilesMenu T (QUOTE CLOSED) NC.NoteCardsIconWindow (QUOTE Copy% NoteFile)))) (if (NULL NoteFile) then NIL else (if (EQ NoteFile (QUOTE NEW)) then (SETQ NoteFile NIL)) (NC.CopyNoteFile NoteFile NIL NC.NoteCardsIconWindow))) ) (Rename% NoteFile (LET ((NoteFile (NC.ListOfNoteFilesMenu T (QUOTE CLOSED) (QUOTE Rename% NoteFile)) )) (if (NULL NoteFile) then NIL else (if (EQ NoteFile (QUOTE NEW)) then (SETQ NoteFile NIL)) (NC.RenameNoteFile NoteFile NIL NC.NoteCardsIconWindow)))) (Delete% NoteFile (LET ((NoteFile (NC.ListOfNoteFilesMenu T (QUOTE CLOSED) (QUOTE Delete% NoteFile)) )) (if (NULL NoteFile) then NIL else (if (EQ NoteFile (QUOTE NEW)) then (SETQ NoteFile NIL)) (NC.DeleteDatabaseFile NoteFile NC.NoteCardsIconWindow)))) (Create% NoteFile (NC.CreateDatabaseFile NIL NIL NIL NIL NIL NIL NC.NoteCardsIconWindow)) NIL))) ) (* * Change to NCREPAIR) (DEFINEQ (NC.InspectAndRepairNoteFile (LAMBDA (NoteFileOrFileName ReadSubstancesFlg InterestedWindow) (* rht: "17-Jul-86 11:58") (* * Check to be sure file is closed before calling real inspect and repair.) (* * rht 7/16/86: Added InterestedWindow arg. Removed call to NC.OpenDatabaseFile.) (* * rht 7/17/86: Now works with file name args as well as notefile args. Took out reopen'ing of notefile, because you don't know how it was originally opened.) (if (OR (NC.NoteFileOpenP NoteFileOrFileName) (OPENP NoteFileOrFileName)) then (NC.CloseDatabaseFile NoteFileOrFileName InterestedWindow)) (NC.ScavengerPhase1 NoteFileOrFileName ReadSubstancesFlg NIL NIL InterestedWindow))) (NC.ScavengerPhase1 (LAMBDA (FileNameOrNoteFile ReadSubstancesFlg ScavengerInteractionWin RecheckBadCardsFlg InterestedWindow) (* rht: "17-Jul-86 12:08") (* * This is the first phase of the scavenger. Runs over entire data portion of the notefile, accumulating pointers to healthy parts of cards. Then runs over index array asking user what to do with bad or outdated pointers. If ReadSubstancesFlg is non-nil then it'll do robust gets of the substances. This slows things down, but makes checking more comprehensive.) (* * rht 12/7/85: Updated to handle new notefile and card object formats.) (* * rht 3/22/86: No longer hangs bad cards off proplist of Reason atoms. Uses local var ReasonsHashArray instead. NC.ScavengerPhase1 no longer hanging on completion of phase 3) (* * rht 7/7/86: Now passes non-nil Don'tCheckOperationInProgress flg to NC.OpenDatabaseFile.) (* * rht 7/16/86: Added InterestedWindow arg.) (PROG (FileName NoteFile UnknownCardTypesList ReasonsList ReasonsHashArray CardsToDelete Menu MenuItems LinkLabelsNews CardTotal BadNewsList BadBoxes ExtraBadNews FirstTimeFlg InspectorPendingEvent NoteFileMenu NoteFileOpsMenuItem CanDoPhase3Flg NoteFileStream) (* * First, take care of opening notefile if needed.) (if (AND (type? NoteFile FileNameOrNoteFile) (SETQ NoteFileStream (fetch (NoteFile Stream) of FileNameOrNoteFile)) (OPENP NoteFileStream)) then (* This notefile is already open For when we do recursive call.) (SETQ NoteFile FileNameOrNoteFile) else (* Get file name and open the file if conditions are okay.) (SETQ FileName FileNameOrNoteFile) (AND (NULL FileName) (NULL (SETQ FileName (NC.DatabaseFileName "What is the name of the NoteFile to Inspect&Repair? " NIL T NIL NIL InterestedWindow))) (RETURN NIL)) (AND (NULL (SETQ NoteFile (NC.OpenDatabaseFile FileName NIL T NIL NIL NIL NIL T T NIL InterestedWindow T))) (NC.PrintMsg InterestedWindow NIL "Couldn't open " FileName "." (CHARACTER 13) "Repair aborted.") (RETURN NIL)) (NC.ClearMsg InterestedWindow T)) (SETQ CardTotal (SUB1 (fetch (NoteFile NextIndexNum) of NoteFile))) (* Build a window for talking to the user if one wasn't passed in.) (if (WINDOWP ScavengerInteractionWin) then (CLEARW ScavengerInteractionWin) else (SETQ ScavengerInteractionWin (CREATEW NC.ScavengerInteractionWinRegion "Inspect&Repair Interaction Window" NIL T)) (* This flg indicates that we're in the first call to the scavenger.) (SETQ FirstTimeFlg T) (WINDOWADDPROP ScavengerInteractionWin (QUOTE CLOSEFN) (FUNCTION NC.MessageWinCloseFn) T)) (* Stash InterestedWindow for calls to phase 3 under menu whenselected fn.) (OR (WINDOWPROP ScavengerInteractionWin (QUOTE INTERESTEDWINDOW)) (WINDOWPROP ScavengerInteractionWin (QUOTE INTERESTEDWINDOW) InterestedWindow)) (* Get all relevant info about the data area of the notefile onto the cards' prop lists.) (if (OR (NOT FirstTimeFlg) (EQ (NC.GetScavengerInfo NoteFile ReadSubstancesFlg ScavengerInteractionWin InterestedWindow) (QUOTE SUCCESS))) then (WINDOWPROP ScavengerInteractionWin (QUOTE NOTEFILE) NoteFile) (WINDOWPROP ScavengerInteractionWin (QUOTE CARDTOTAL) CardTotal) else (* Something's wrong. Couldn't get scavenger info. Bail out.) (NC.ScavengerCleanup ScavengerInteractionWin InterestedWindow) (CLOSEW ScavengerInteractionWin) (RETURN NIL)) (* * Check the list of card types that are undefined to see if user has loaded a definition since the last time we checked. If he has, then go try to read the substance card parts for those newly defined card types.) (NC.CheckUnknownCardTypes NoteFile ReadSubstancesFlg ScavengerInteractionWin) (* * Next step is to run down the in-core index and find those cards having pointers to bad items in the data area. We also need to look for undefined card types and for pointers past the checkpoint pointer. However, we can reuse old bad news list if nothing has changed.) (if (OR FirstTimeFlg RecheckBadCardsFlg (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDCHECKPOINT))) then (WINDOWPROP ScavengerInteractionWin (QUOTE ORIGINALBADNEWSLIST) (SETQ BadNewsList (NC.BuildBadCardsList NoteFile ScavengerInteractionWin FirstTimeFlg InterestedWindow))) else (SETQ BadNewsList (WINDOWPROP ScavengerInteractionWin (QUOTE ORIGINALBADNEWSLIST)))) (* * Okay, now all the troublesome IDs and the reasons for their troubles are recorded in BadNewsList. We next need to get directives from the user as to what to do for each problem card.) (NC.RepositionWindowIfNeeded ScavengerInteractionWin) (* If there's bad news for link labels then take off list and store in a local var.) (if (SETQ LinkLabelsNews (for BadCardEntry in BadNewsList bind (LinkLabelsCard ←(fetch (NoteFile LinkLabelsCard) of NoteFile)) eachtime (BLOCK) when (NC.SameCardP LinkLabelsCard (CAR BadCardEntry)) do (RETURN BadCardEntry))) then (SETQ BadNewsList (DREMOVE LinkLabelsNews BadNewsList))) (* Accumulate general statistics on the problems.) (SETQ ReasonsHashArray (HASHARRAY 100)) (for BadNews in BadNewsList bind Card Type eachtime (BLOCK) unless (FMEMB (CADR BadNews) (QUOTE (DELETED FREE))) do (SETQ Card (CAR BadNews)) (for Reason in (CDDDR BadNews) eachtime (BLOCK) do (PUTHASH Reason (CONS Card (GETHASH Reason ReasonsHashArray)) ReasonsHashArray) (if (NOT (FMEMB Reason ReasonsList)) then (SETQ ReasonsList (CONS Reason ReasonsList))) (if (EQ Reason (QUOTE UNKNOWNCARDTYPE)) then (* Accumulate the list of unknown card types for nondeleted cards.) (if (NOT (FMEMB (SETQ Type ( NC.FetchTypeFromScavengerInfo Card)) UnknownCardTypesList)) then (push UnknownCardTypesList Type))))) (* Build the menu entries that we know will be present regardless of which cards are bad.) (SETQ MenuItems (QUOTE ((Abort (QUOTE Abort) "Quit this Inspect&Repair operation.") (Recheck% Bad% Cards (QUOTE Recheck% Bad% Cards) "Recompute bad cards list. Useful if you've just loaded some card type definitions.") (Inspect% Cards (QUOTE Inspect% Cards) "Bring up the cards inspector menu." (SUBITEMS (Include% Deleted% Cards (QUOTE Include% Deleted% Cards) "Throw in deleted cards as well."))))) ) (* Print a message if news on link labels is worse than just past checkpoint.) (if (AND LinkLabelsNews (NOT (EQUAL (CDDDR LinkLabelsNews) (QUOTE (MAINDATAPASTCHKPT))))) then (push ExtraBadNews LinkLabelsNews) (NC.PrintMsg ScavengerInteractionWin NIL "The link types are bad." (CHARACTER 13) "If you don't back them up to a previous version, then phase 3 of Inspect&Repair will rebuild them." (CHARACTER 13)) (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE) T)) (* Collect any fileboxes that have bad substances.) (if (SETQ BadBoxes (LET (Boxes) (SETQ BadNewsList (for News in BadNewsList bind Box eachtime (BLOCK) unless (if (AND (EQ ( NC.FetchTypeFromScavengerInfo (SETQ Box (CAR News))) (QUOTE FileBox)) (FMEMB (QUOTE BADMAINDATA) (CDDDR News))) then (push Boxes Box) (* If nothing else is wrong with those boxes, then take off bad news list.) (EQ (LENGTH (CDDDR News)) 1) else NIL) collect News)) Boxes)) then (NC.PrintMsg ScavengerInteractionWin NIL "Fileboxes " (for Box in BadBoxes collect ( NC.FetchTitleFromScavengerInfo Box)) " have bad substance(s)." (CHARACTER 13) "If you don't delete them or back up to a previous version, then phase 3 of Inspect&Repair will rebuild their contents." (CHARACTER 13)) (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE) T)) (* Print out totals of active and deleted cards.) (LET ((ActivesTotal 0) (DeletedsTotal 0)) (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card) (SELECTQ (NC.FetchStatus Card) (ACTIVE (SETQ ActivesTotal (ADD1 ActivesTotal))) (DELETED (SETQ DeletedsTotal (ADD1 DeletedsTotal))) NIL)))) (NC.PrintMsg ScavengerInteractionWin NIL "Out of " CardTotal " cards:" (CHARACTER 13) "there are " ActivesTotal " active cards and " DeletedsTotal " deleted cards." (CHARACTER 13))) (if ReasonsList then (* Print out messages for bad cards.) (NC.PrintMsg ScavengerInteractionWin NIL "Of the non-deleted ones," (CHARACTER 13)) (for Reason in ReasonsList eachtime (BLOCK) do (NC.PrintMsg ScavengerInteractionWin NIL (LENGTH (GETHASH Reason ReasonsHashArray)) " have " (GETPROP Reason (QUOTE ReasonString)) (CHARACTER 13)) (if (EQ Reason (QUOTE UNKNOWNCARDTYPE)) then (NC.PrintMsg ScavengerInteractionWin NIL "The unknown types are: " UnknownCardTypesList "." (CHARACTER 13)))) else (NC.PrintMsg ScavengerInteractionWin NIL "All non-deleted cards look okay." (CHARACTER 13))) (* Only allow continuation to phase 3 of repair, links rebuilding, if there's no bad news that can't be fixed. We can fix bad proplist, titles or links. We can also fix even bad substances if they're for fileboxes.) (if (for News in BadNewsList eachtime (BLOCK) unless (FMEMB (CADR News) (QUOTE (DELETED FREE))) unless (EQ (NC.FetchTypeFromScavengerInfo (CAR News)) (QUOTE FileBox)) never (INTERSECTION (CDDDR News) (QUOTE (BADMAINDATA UNKNOWNCARDTYPE)))) then (* Add the appropriate menu items.) (if (NOT (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE))) then (SETQ MenuItems (CONS (QUOTE (End% Inspect&Repair (QUOTE End% Inspect&Repair) "This exits Inspect&Repair normally, closing the notefile.")) MenuItems))) (SETQ CanDoPhase3Flg T) (SETQ MenuItems (CONS (QUOTE (Continue% Repair (QUOTE Continue% Repair) "Complete Inspect&Repair by rebuilding the links.")) MenuItems))) (* Make sure a checkpoint will happen before continuing to phase 3 if there are any card parts beyond the checkpt pointer.) (if (INTERSECTION ReasonsList (QUOTE (MAINDATAPASTCHKPT LINKSPASTCHKPT TITLEPASTCHKPT PROPLISTPASTCHKPT))) then (AND CanDoPhase3Flg (NC.PrintMsg ScavengerInteractionWin NIL "'Continue Repair' will integrate any card part versions beyond chkpt pointer." (CHARACTER 13))) (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDCHECKPOINT) T)) (* Ugliness! Have to cache all these vars on window so that attached menu's whenselectedfn will be able to grab them.) (WINDOWPROP ScavengerInteractionWin (QUOTE BADNEWSLIST) BadNewsList) (WINDOWPROP ScavengerInteractionWin (QUOTE EXTRABADNEWS) ExtraBadNews) (WINDOWPROP ScavengerInteractionWin (QUOTE LINKSLABELSNEWS) LinkLabelsNews) (WINDOWPROP ScavengerInteractionWin (QUOTE BADBOXES) BadBoxes) (ATTACHMENU (create MENU ITEMS ← MenuItems WHENSELECTEDFN ←(FUNCTION NC.MessageWinAttachedMenuWhenSelectedFn) MENUFONT ← NC.ScavengerAttachedMenuFont) ScavengerInteractionWin (QUOTE RIGHT) (QUOTE TOP))))) (NC.ScavengeDatabaseFile (LAMBDA (NoteFileOrFileName BadLinkLabelsFlg ListOfBoxesToReconstruct ListOfCardsNeedingGlobalLinksReconstructed InterestedWindow) (* rht: "17-Jul-86 12:11") (* Scavenge the database FileName. Essentially throw away all of the information about From and ToLinks and recreate them by retrieving the link information from the substance of each card and from the list of global links from the card.) (* * rht 8/9/84: Now calls NC.OpenDatabaseFile to do the file open.) (* * rht 7/17/85: Changed so can take a stream argument. Also handles link labels. If BadLinkLabelsFlg is non-nil, then don't try to read current link labels. Just rebuild them from what's out there. Otherwise, only rebuild if find new any new ones.) (* * fgh 22-Jul-85 Takes a list of bad file box cards and reconstructs the file boxes from the From pointer lists of all the cards in the NoteFile.) (* * fgh 30-Jul-85 Takes a list of cards with bad global links and reconstructs the global links list from the From pointer lists of all the cards in the NoteFile.) (* * rht 11/23/85: Updated to handle new notefile and card object formats.) (* * rht 12/1/85: Now calls NC.GetMainCardData and NC.GetLinks instead of NC.GetNoteCard.) (* * rht 12/19/85: Massive overhaul for sake of speed. Should be wizzier now.) (* * fgh 2/4/86 Now works on open NFs. No need to error check since this function should always be called from earlier phases of the inspect & repaier.) (* * fgh 5/21/86 Fixed bug in handling of global links.) (* * rht 7/16/86: Added InterestedWindow arg.) (* * rht 7/16/86: Now calls NC.PutLinks passing UseOldDatesFlg.) (PROG (NoteFile FileName CardTotal NoteCardNumber OldLinkLabels DiscoveredLinkLabels ReconstructLinks ReconstructGlobalLinks ToBeFiledCards) (* * First, take care of checking stream's validity, etc.) (SETQ FileName (if (type? NoteFile NoteFileOrFileName) then (SETQ NoteFile NoteFileOrFileName) (fetch (NoteFile FullFileName) of NoteFileOrFileName) else NoteFileOrFileName)) (* Try to open notefile.) (if (NULL (OPENP FileName)) then (if (NULL (SETQ NoteFile (NC.OpenDatabaseFile FileName NIL T NIL NIL NIL NIL T T NIL InterestedWindow))) then (NC.PrintMsg InterestedWindow NIL "Couldn't open " FileName "." (CHARACTER 13) "Repair aborted.") (RETURN NIL))) (* * If link labels aren't screwed up, then read them in.) (OR BadLinkLabelsFlg (SETQ OldLinkLabels (NC.RetrieveLinkLabels NoteFile T))) (* * Mark every card that needs its global links or substance reconstructed so we don't have to search the lists so much.) (for Card in ListOfCardsNeedingGlobalLinksReconstructed do (NC.SetUserDataProp Card (QUOTE NeedsGlobalLinksReconstructedFlg) T)) (for Box in ListOfBoxesToReconstruct do (NC.SetUserDataProp Box (QUOTE NeedsReconstructingFlg) T)) (* Read through all NoteCard substances to find actual pointers. Use this to create the To Links list. The list collection function checks to make sure each link is valid.) (SETQ CardTotal (SUB1 (fetch (NoteFile NextIndexNum) NoteFile))) (NC.PrintMsg InterestedWindow T "Rebuilding notefile links." (CHARACTER 13) "Collecting Links for item " 1 " out of " CardTotal ".") (SETQ NoteCardNumber 0) (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card) (SETQ NoteCardNumber (ADD1 NoteCardNumber)) (AND (ZEROP (REMAINDER NoteCardNumber 10)) (NC.PrintMsg InterestedWindow T "Rebuilding notefile links." (CHARACTER 13) "Collecting Links for item " NoteCardNumber " out of " CardTotal ".")) (if (NC.FetchUserDataProp Card (QUOTE NeedsReconstructingFlg)) then (* Card substance and links will be reconstructed so no need to try to read substance.) (NC.GetLinks Card) (if (NOT (NC.FetchUserDataProp Card (QUOTE NeedsGlobalLinksReconstructedFlg))) then (NC.SetUserDataProp Card (QUOTE ScavengerToLinks) (NC.FetchGlobalLinks Card)) (NC.SetUserDataProp Card (QUOTE ScavengerGlobalLinks) (NC.FetchGlobalLinks Card))) (NC.DeactivateCard Card T) else (NC.GetMainCardData Card) (NC.GetLinks Card) (NC.ActivateCard Card) (if (EQ (NC.FetchStatus Card) (QUOTE ACTIVE)) then (* Collect links having active destinations. Delete the others.) (NC.SetUserDataProp Card (QUOTE ScavengerToLinks) (NCONC (for Link in (CAR (NC.CollectReferences Card)) eachtime (BLOCK) when (if (EQ (NC.FetchStatus (fetch (Link DestinationCard) of Link)) (QUOTE ACTIVE)) else (NC.DelReferencesToCard Card Link) NIL) collect Link) (if (NC.FetchUserDataProp Card (QUOTE NeedsGlobalLinksReconstructedFlg)) else (NC.SetUserDataProp Card (QUOTE ScavengerGlobalLinks) (NC.FetchGlobalLinks Card)) (NC.FetchGlobalLinks Card)))) (if (NC.FetchUserDataProp Card (QUOTE NeedsGlobalLinksReconstructedFlg)) else (NC.SetUserDataProp Card (QUOTE ScavengerGlobalLinks) (NC.FetchGlobalLinks Card))) (* If there are file boxes to be reconstructed, then look thru the From links to see if this card was filed in one of the to-be-reconstructed boxes) (AND ListOfBoxesToReconstruct (for Link in (NC.FetchFromLinks Card) eachtime (BLOCK) when (AND (NC.ChildLinkP Link) (NC.FetchUserDataProp (fetch (Link SourceCard) of Link) (QUOTE NeedsReconstructingFlg))) do (push ReconstructLinks Link))) (* If there are global links to be reconstructed, then look thru the From links to see if this card had a global link from a card whose global links need reconstructing.) (AND ListOfCardsNeedingGlobalLinksReconstructed (for Link in (NC.FetchFromLinks Card) eachtime (BLOCK) when (AND (NC.GlobalLinkP Link) (NC.FetchUserDataProp (fetch (Link SourceCard) of Link) (QUOTE NeedsGlobalLinksReconstructedFlg))) do (push ReconstructGlobalLinks Link))) (NC.DeactivateCard Card T)))))) (* * Reconstruct any cards as requested) (for BoxToReconstruct in ListOfBoxesToReconstruct eachtime (BLOCK) do (* Make a new file box using the given card.) (NC.MakeNoteCard (QUOTE FileBox) NoteFile "Untitled: Reconstructed during repair" T NIL BoxToReconstruct) (* File cards whose from links indicate that they used to be filed in this file box. Also add these new links to collected ToLinks.) (NC.SetUserDataProp BoxToReconstruct (QUOTE ScavengerToLinks) (APPEND (NC.FetchUserDataProp BoxToReconstruct (QUOTE ScavengerToLinks) ) (for Link in ReconstructLinks eachtime (BLOCK) when (NC.SameCardP BoxToReconstruct (fetch (Link SourceCard) of Link)) collect (NC.MakeChildLink (fetch (Link DestinationCard) of Link) BoxToReconstruct NIL)))) (* Put the card away) (NC.PutMainCardData BoxToReconstruct) (NC.DeactivateCard BoxToReconstruct T)) (* * Reconstruct any global link lists as required) (for Link in ReconstructGlobalLinks bind ThisCardsToLinks ThisCardsGlobalLinks SourceCard eachtime (BLOCK) do (SETQ SourceCard (fetch (Link SourceCard) of Link)) (* Add it to the GlobalLinks list for its source card unless it's already there.) (if (for GlobalLink in (SETQ ThisCardsGlobalLinks (NC.FetchUserDataProp SourceCard (QUOTE ScavengerGlobalLinks))) eachtime (BLOCK) never (NC.SameLinkP Link GlobalLink)) then (NC.SetUserDataProp SourceCard (QUOTE ScavengerGlobalLinks) (CONS Link ThisCardsGlobalLinks))) (* Add it to the source card's ToLinks list unless it's already there) (if (for ToLink in (SETQ ThisCardsToLinks (NC.FetchUserDataProp SourceCard (QUOTE ScavengerToLinks))) eachtime (BLOCK) never (NC.SameLinkP Link ToLink)) then (NC.SetUserDataProp SourceCard (QUOTE ScavengerToLinks) (CONS Link ThisCardsToLinks)))) (* * Compute the From Links list by "inverting" the To Links list) (NC.PrintMsg InterestedWindow T "Repairing NoteFile." (CHARACTER 13) "Inverting links for item " 1 " out of " CardTotal ".") (SETQ NoteCardNumber 0) (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card) (SETQ NoteCardNumber (ADD1 NoteCardNumber)) (AND (ZEROP (REMAINDER NoteCardNumber 100)) (NC.PrintMsg InterestedWindow T "Repairing NoteFile." (CHARACTER 13) "Inverting links for item " NoteCardNumber " out of " CardTotal ".")) (if (EQ (NC.FetchStatus Card) (QUOTE ACTIVE)) then (for Link in (NC.FetchUserDataProp Card (QUOTE ScavengerToLinks) ) bind DestinationCard LinkLabel eachtime (BLOCK) do (* Add this ToLink as a FromLink for the link's destination card.) (NC.SetUserDataProp (SETQ DestinationCard (fetch (Link DestinationCard) of Link)) (QUOTE ScavengerFromLinks) (CONS Link ( NC.FetchUserDataProp DestinationCard (QUOTE ScavengerFromLinks)))) (* Accumulate the link labels into a list.) (if (NOT (FMEMB (SETQ LinkLabel (fetch (Link Label) of Link)) DiscoveredLinkLabels)) then (push DiscoveredLinkLabels LinkLabel))) )))) (* * Reset all of the To and From Links lists in the database) (NC.PrintMsg InterestedWindow T "Repairing NoteFile." (CHARACTER 13) "Rewriting links for item " 1 " out of " CardTotal ".") (SETQ NoteCardNumber 0) (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card) (SETQ NoteCardNumber (ADD1 NoteCardNumber)) (AND (ZEROP (REMAINDER NoteCardNumber 10)) (NC.PrintMsg InterestedWindow T "Repairing NoteFile." (CHARACTER 13) "Rewriting links for item " NoteCardNumber " out of " CardTotal ".")) (if (EQ (NC.FetchStatus Card) (QUOTE ACTIVE)) then (NC.SetGlobalLinks Card (NC.FetchUserDataProp Card (QUOTE ScavengerGlobalLinks))) (NC.SetToLinks Card (NC.FetchUserDataProp Card (QUOTE ScavengerToLinks))) (NC.SetFromLinks Card (NC.FetchUserDataProp Card (QUOTE ScavengerFromLinks))) (* Check whether this card isn't filed anywhere.) (if (AND (NOT (NC.UndeletableCardP Card)) (for Link in (NC.FetchFromLinks Card) eachtime (BLOCK) never ( NC.ChildLinkP Link))) then (push ToBeFiledCards Card)) (NC.PutLinks Card T)) (* Clean any junk off the card.) (NC.DeactivateCard Card T) (NC.SetUserDataPropList Card NIL)))) (* * File any unfiled cards in the ToBeFiled box.) (if ToBeFiledCards then (NC.PrintMsg InterestedWindow T "Filing " (LENGTH ToBeFiledCards) " cards in ToBeFiled box ...") (NCP.FileCards ToBeFiledCards (fetch (NoteFile ToBeFiledCard) of NoteFile))) (* Rewrite link labels if we've found any new ones.) (if (LDIFFERENCE DiscoveredLinkLabels OldLinkLabels) then (NC.StoreLinkLabels NoteFile (UNION DiscoveredLinkLabels OldLinkLabels))) (* Clean up and get out.) (NC.CheckpointDatabase NoteFile T) (NC.ForceDatabaseClose NoteFile) (NC.PrintMsg InterestedWindow T "Repair Completed for " (FULLNAME FileName) ".") (if ToBeFiledCards then (NC.PrintMsg InterestedWindow NIL "Filed " (LENGTH ToBeFiledCards) " cards in ToBeFiled box."))))) (NC.GetScavengerInfo (LAMBDA (NoteFile ReadSubstancesFlg MessageWin InterestedWindow) (* rht: "17-Jul-86 12:07") (* * Return an array containing pointers to all valid versions of notecard parts, i.e. substances, titles, links, and proplists. If ReadSubstancesFlg is non-nil, then read substances when checking rather than just checking that start and end substance pointers make sense.) (* * rht 9/17/85: Now keeps track of largest ID seen and caches on MessageWin's WINDOWPROP.) (* * rht 12/1/85: Updated to handle new notefile and card format. Ripped out MaxIDNum stuff.) (* * rht 7/16/86: Added InterestedWindow arg.) (LET ((Stream (fetch (NoteFile Stream) of NoteFile)) EndPtr CurPtr BadCardTypesList) (SETQ EndPtr (GETEOFPTR Stream)) (* Initialize bad card types list to nil. NC.RobustReadCardPart will add to it as it finds unknown card types.) (WINDOWPROP MessageWin (QUOTE BADCARDTYPESLIST) NIL) (NC.PrintMsg InterestedWindow T "Processing data area of notefile ..." (CHARACTER 13) "Searching for start of data area ...") (* Find start of data area) (SETQ CurPtr (NC.SearchFor### Stream 0)) (* Walk, don't run, through the data area trying to find good card parts.) (if (for bind (LastPtrHighBits ← 0) CurPtrHighBits Card eachtime (BLOCK) while (AND CurPtr (LESSP CurPtr EndPtr)) do (* Print a message every 8K or so bytes.) (if (GREATERP (SETQ CurPtrHighBits (LRSH CurPtr 13)) LastPtrHighBits) then (NC.PrintMsg InterestedWindow T "Processing data area of notefile ..." (CHARACTER 13) "Byte number: " (QUOTIENT CurPtr 1000) "K out of " (QUOTIENT EndPtr 1000) "K.") (SETQ LastPtrHighBits CurPtrHighBits)) (* Try to read a card part. If returns nil, then search for next # marker and try again.) (if (SETQ Card (NC.RobustReadCardPart NoteFile ReadSubstancesFlg MessageWin EndPtr)) then (SETQ CurPtr (GETFILEPTR Stream)) else (SETQ CurPtr (NC.SearchFor### Stream (PLUS 4 CurPtr)))) finally (RETURN (QUOTE SUCCESS))) then (NC.ClearMsg InterestedWindow T) (QUOTE SUCCESS))))) (NC.BuildBadCardsList (LAMBDA (NoteFile MessageWin FirstTimeFlg InterestedWindow) (* rht: "17-Jul-86 12:11") (* * Returns a list of all IDs with illegal index pointers, i.e. pointers not to valid data areas recorded in ScavengerArray. Also record those IDs with pointers beyond checkpoint ptr.) (* * rht 9/17/85: Now takes MessageWin argument so can extract the MaxIDNum off its props.) (* * rht 12/7/85: Modified to reflect new card and notefile object formats.) (* * fgh 2/4/86 Fixed minor bug where UNKNOWNCARDTYPE apeeared in a singleton list.) (* * rht 7/16/86: Added InterestedWindow arg.) (LET ((CardTotal (SUB1 (fetch (NoteFile NextIndexNum) of NoteFile))) (CheckptPtr (fetch (NoteFile CheckptPtr) of NoteFile)) (Num 0) Results) (NC.PrintMsg InterestedWindow T "Building bad cards list ..." (CHARACTER 13) "Processing item number " 1 " out of " CardTotal ".") (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card) (LET (Problems) (SETQ Num (ADD1 Num)) (if (ZEROP (IREMAINDER Num 100)) then (NC.PrintMsg InterestedWindow T "Building bad cards list ..." (CHARACTER 13) "Processing item number " Num " out of " CardTotal ".")) (* If card is not worthless, has reasonable status, and at least one problem, then make a bad card entry for it.) (if (AND (NOT (NC.WorthlessCardP Card)) (FMEMB (NC.FetchStatus Card) (QUOTE (ACTIVE DELETED SPECIAL BADPOINTER NIL))) (SETQ Problems (LET ((IndexLocsProblems (NC.CheckIndexLocs Card MessageWin CheckptPtr FirstTimeFlg)) (Type (NC.FetchTypeFromScavengerInfo Card))) (if (AND Type (NOT (NCP.ValidCardType Type))) then (CONS (QUOTE UNKNOWNCARDTYPE) IndexLocsProblems) else IndexLocsProblems)))) then (push Results (BQUOTE (, Card , (NC.FetchStatus Card) , (NC.EncodeCardProblems Problems) ,@ Problems)))))))) (NC.ClearMsg InterestedWindow T) Results))) ) (PUTPROPS RHTPATCH078 COPYRIGHT ("Xerox Corporation" 1986)) (DECLARE: DONTCOPY (FILEMAP (NIL (544 6489 (NC.FileBrowserInspect&Repair 554 . 1264) (NC.DoNoteFileOp 1266 . 6487)) (6521 41974 (NC.InspectAndRepairNoteFile 6531 . 7366) (NC.ScavengerPhase1 7368 . 21861) ( NC.ScavengeDatabaseFile 21863 . 36577) (NC.GetScavengerInfo 36579 . 39382) (NC.BuildBadCardsList 39384 . 41972))))) STOP