(FILECREATED " 7-Jul-86 14:51:58" {QV}<NOTECARDS>1.3K>RHTPATCH061.;1 16584
changes to: (VARS RHTPATCH061COMS)
(FNS NC.ScavengerPhase1 NC.ForceDatabaseClose))
(* Copyright (c) 1986 by Xerox Corporation. All rights reserved.)
(PRETTYCOMPRINT RHTPATCH061COMS)
(RPAQQ RHTPATCH061COMS ((* * Fix to NCREPAIR)
(FNS NC.ScavengerPhase1)
(* * Fix to NCDATABASE)
(FNS NC.ForceDatabaseClose)))
(* * Fix to NCREPAIR)
(DEFINEQ
(NC.ScavengerPhase1
(LAMBDA (FileNameOrNoteFile ReadSubstancesFlg ScavengerInteractionWin RecheckBadCardsFlg)
(* rht: " 7-Jul-86 14:50")
(* * 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.)
(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)))
(RETURN NIL))
(AND (NULL (SETQ NoteFile
(NC.OpenDatabaseFile FileName NIL T NIL NIL NIL NIL T T NIL
NIL T)))
(NC.PrintMsg NIL NIL "Couldn't open " FileName "." (CHARACTER 13)
"Repair aborted."
(CHARACTER 13))
(RETURN NIL))
(NC.PrintMsg NIL NIL "Done."))
(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)) (* 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)
(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)
(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)))
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)))))
)
(* * Fix to NCDATABASE)
(DEFINEQ
(NC.ForceDatabaseClose
(LAMBDA (NoteFile Don'tMenuFlg) (* rht: " 7-Jul-86 14:51")
(* * Really close the database, i.e.. bypass the ADVISE on CLOSEF that prevents closing of the database.)
(* * rht 1/10/85: Note new kludgey call to \UPDATEOF recommended by Tayloe to avoid truncation problems.)
(* * rht 2/5/85: Added resetting of NC.UncachingNotCompleted here so it will happen after compact, repair, etc.)
(* * rht 7/9/85: Added resetting of NC.LinkLabelsDate.)
(* * rht 11/10/85: Updated to incorporate new NoteFile scheme.)
(* * kirk 31Dec85: added Don'tMenuFlg)
(* * rht 1/8/86: Now smashes old notefile object to remove cycles. Don't you love interlisp gc'er?)
(* * rht 5/1/86: Save Menu on notefile object when smashing.)
(* * rht 7/6/86: Only closes notefile's stream if there is an open one.)
(CLOSEF? (fetch (NoteFile Stream) of NoteFile)) (* Smash the cardcache and userdata fields of all card
objects for this notefile to remove circular links.)
(ADD.PROCESS (LIST (FUNCTION NC.CleanupCardObjects)
(fetch (NoteFile HashArray) of NoteFile)))
(replace (NoteFile Stream) of NoteFile with NIL) (* Smash the notefile object so we don't have cycles -
card -> notefile -> card.)
(create NoteFile smashing NoteFile UID ←(fetch (NoteFile UID) of NoteFile)
FullFileName ←(fetch (NoteFile FullFileName) of NoteFile)
Menu ←(fetch (NoteFile Menu) of NoteFile))
(* Usually we leave shell in notefiles hash array so
there's a record.)
(if Don'tMenuFlg
then (NC.RemoveNoteFile NoteFile))
NoteFile))
)
(PUTPROPS RHTPATCH061 COPYRIGHT ("Xerox Corporation" 1986))
(DECLARE: DONTCOPY
(FILEMAP (NIL (454 14518 (NC.ScavengerPhase1 464 . 14516)) (14549 16502 (NC.ForceDatabaseClose 14559
. 16500)))))
STOP