(FILECREATED " 1-Dec-85 23:45:04" {QV}<NOTECARDS>1.3K>RHTPATCH011.;1 38243  

      changes to:  (VARS RHTPATCH011COMS)
		   (RECORDS ScavengerInfo)
		   (FNS NC.FetchScavengerInfo NC.SetScavengerInfo NC.SetScavengerTitleInfo 
			NC.SetScavengerMainDataInfo NC.SetScavengerLinksInfo 
			NC.SetScavengerPropListInfo NC.FetchScavengerTitleInfo 
			NC.FetchScavengerMainDataInfo NC.FetchScavengerLinksInfo 
			NC.FetchScavengerPropListInfo NC.RobustReadUID NC.SearchFor### 
			NC.GetScavengerInfo))


(* Copyright (c) 1985 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT RHTPATCH011COMS)

(RPAQQ RHTPATCH011COMS ((* * This contains lots of things to do to NCREPAIR.)
			  (* * First, remove the date crud at the top of NCREPAIR.)
			  (* * Next, remove the following global vars from the GLOBALVARS list: 
			     NC.LinkLabelsID NC.ScavengerArrayLinkLabelsOffset 
			     NC.ClippedIdentifierAtoms PSA.Database NC.IndexArrayLinkLabelsOffset 
			     NC.TopLevelCards NC.NextNOBINDLoc)
			  (* * In the VARS, remove definitions for NC.ScavengerArrayLinkLabelsOffset 
			     NC.IndexArrayLinkLabelsOffset.)
			  (* * Change the comment "Old scavenger stuff." to 
			     "Phase 3 scavenger stuff.")
			  (* * In the first list of FNS, remove the following: NC.GetOldData 
			     NC.FindOldData NC.FindOldLinks NC.ReinstateNthInstance)
			  (* * In the list labeled "Functions for building the scavenger array ..." 
			     remove NC.ScavengerArrayOffsetFromID.)
			  (* * Here are new functions and records for NCREPAIR belonging with the 
			     group labeled "Functions for accessing the scavenger array." And change 
			     that comment to "Functions for accessing scavenger info for a card.")
			  (FNS NC.FetchScavengerInfo NC.SetScavengerInfo NC.SetScavengerTitleInfo 
			       NC.SetScavengerMainDataInfo NC.SetScavengerLinksInfo 
			       NC.SetScavengerPropListInfo NC.FetchScavengerTitleInfo 
			       NC.FetchScavengerMainDataInfo NC.FetchScavengerLinksInfo 
			       NC.FetchScavengerPropListInfo)
			  (RECORDS ScavengerInfo)
			  (* * Replace NC.RobustReadID with the following.)
			  (FNS NC.RobustReadUID)
			  (* * Replace NC.SearchFor###OrNOBIND with the following.)
			  (FNS NC.SearchFor###)
			  (* * Replace NC.BuildScavengerArray with the following.)
			  (FNS NC.GetScavengerInfo)
			  (* * Here are a bunch of redefined functions from NCREPAIR.)
			  (FNS NC.ScavengeDatabaseFile NC.RobustReadCardPart 
			       NC.CheckForValidSubstance NC.AtEndOfItemP NC.RobustReadItemIdentifier 
			       NC.RobustReadString NC.RobustReadList NC.RobustReadLinks 
			       NC.RobustReadAtom NC.RobustReadRegion NC.RobustGetSubstance 
			       NC.RobustReadDate)))
(* * This contains lots of things to do to NCREPAIR.)

(* * First, remove the date crud at the top of NCREPAIR.)

(* * Next, remove the following global vars from the GLOBALVARS list: NC.LinkLabelsID 
NC.ScavengerArrayLinkLabelsOffset NC.ClippedIdentifierAtoms PSA.Database 
NC.IndexArrayLinkLabelsOffset NC.TopLevelCards NC.NextNOBINDLoc)

(* * In the VARS, remove definitions for NC.ScavengerArrayLinkLabelsOffset 
NC.IndexArrayLinkLabelsOffset.)

(* * Change the comment "Old scavenger stuff." to "Phase 3 scavenger stuff.")

(* * In the first list of FNS, remove the following: NC.GetOldData NC.FindOldData 
NC.FindOldLinks NC.ReinstateNthInstance)

(* * In the list labeled "Functions for building the scavenger array ..." remove 
NC.ScavengerArrayOffsetFromID.)

(* * Here are new functions and records for NCREPAIR belonging with the group labeled 
"Functions for accessing the scavenger array." And change that comment to 
"Functions for accessing scavenger info for a card.")

(DEFINEQ

(NC.FetchScavengerInfo
  (LAMBDA (Card)                                             (* rht: " 1-Dec-85 21:24")

          (* * Get the scavenger info record for this card.)


    (NC.FetchUserDataProp Card (QUOTE SCAVENGERINFO))))

(NC.SetScavengerInfo
  (LAMBDA (Card NewScavengerInfo)                            (* rht: " 1-Dec-85 21:25")

          (* * Set the scavenger info record for this card.)


    (NC.SetUserDataProp Card (QUOTE SCAVENGERINFO)
			  NewScavengerInfo)))

(NC.SetScavengerTitleInfo
  (LAMBDA (Card TitleInfo)                                   (* rht: " 1-Dec-85 21:41")

          (* * Set the title part of the scavenger info record for Card.)


    (LET ((ScavengerInfo (NC.FetchScavengerInfo Card)))
         (if (NOT (type? ScavengerInfo ScavengerInfo))
	     then (NC.SetScavengerInfo Card (SETQ ScavengerInfo (create ScavengerInfo))))
         (replace (ScavengerInfo TitleInfo) of ScavengerInfo with TitleInfo))))

(NC.SetScavengerMainDataInfo
  (LAMBDA (Card MainDataInfo)                                (* rht: " 1-Dec-85 21:41")

          (* * Set the main data part of the scavenger info record for Card.)


    (LET ((ScavengerInfo (NC.FetchScavengerInfo Card)))
         (if (NOT (type? ScavengerInfo ScavengerInfo))
	     then (NC.SetScavengerInfo Card (SETQ ScavengerInfo (create ScavengerInfo))))
         (replace (ScavengerInfo MainDataInfo) of ScavengerInfo with MainDataInfo))))

(NC.SetScavengerLinksInfo
  (LAMBDA (Card LinksInfo)                                   (* rht: " 1-Dec-85 21:41")

          (* * Set the links part of the scavenger info record for Card.)


    (LET ((ScavengerInfo (NC.FetchScavengerInfo Card)))
         (if (NOT (type? ScavengerInfo ScavengerInfo))
	     then (NC.SetScavengerInfo Card (SETQ ScavengerInfo (create ScavengerInfo))))
         (replace (ScavengerInfo LinksInfo) of ScavengerInfo with LinksInfo))))

(NC.SetScavengerPropListInfo
  (LAMBDA (Card PropListInfo)                                (* rht: " 1-Dec-85 21:41")

          (* * Set the prop list part of the scavenger info record for Card.)


    (LET ((ScavengerInfo (NC.FetchScavengerInfo Card)))
         (if (NOT (type? ScavengerInfo ScavengerInfo))
	     then (NC.SetScavengerInfo Card (SETQ ScavengerInfo (create ScavengerInfo))))
         (replace (ScavengerInfo PropListInfo) of ScavengerInfo with PropListInfo))))

(NC.FetchScavengerTitleInfo
  (LAMBDA (Card)                                             (* rht: " 1-Dec-85 21:41")

          (* * Get the title part of the scavenger info record for Card.)


    (LET ((ScavengerInfo (NC.FetchScavengerInfo Card)))
         (if (type? ScavengerInfo ScavengerInfo)
	     then (fetch (ScavengerInfo TitleInfo) of ScavengerInfo)
	   else NIL))))

(NC.FetchScavengerMainDataInfo
  (LAMBDA (Card)                                             (* rht: " 1-Dec-85 21:48")

          (* * Get the main data part of the scavenger info record for Card.)


    (LET ((ScavengerInfo (NC.FetchScavengerInfo Card)))
         (if (type? ScavengerInfo ScavengerInfo)
	     then (fetch (ScavengerInfo MainDataInfo) of ScavengerInfo)
	   else NIL))))

(NC.FetchScavengerLinksInfo
  (LAMBDA (Card)                                             (* rht: " 1-Dec-85 21:48")

          (* * Get the links part of the scavenger info record for Card.)


    (LET ((ScavengerInfo (NC.FetchScavengerInfo Card)))
         (if (type? ScavengerInfo ScavengerInfo)
	     then (fetch (ScavengerInfo LinksInfo) of ScavengerInfo)
	   else NIL))))

(NC.FetchScavengerPropListInfo
  (LAMBDA (Card)                                             (* rht: " 1-Dec-85 21:49")

          (* * Get the prop list part of the scavenger info record for Card.)


    (LET ((ScavengerInfo (NC.FetchScavengerInfo Card)))
         (if (type? ScavengerInfo ScavengerInfo)
	     then (fetch (ScavengerInfo PropListInfo) of ScavengerInfo)
	   else NIL))))
)
[DECLARE: EVAL@COMPILE 

(DATATYPE ScavengerInfo (MainDataInfo LinksInfo TitleInfo PropListInfo))
]
(/DECLAREDATATYPE (QUOTE ScavengerInfo)
		  (QUOTE (POINTER POINTER POINTER POINTER))
		  (QUOTE ((ScavengerInfo 0 POINTER)
			  (ScavengerInfo 2 POINTER)
			  (ScavengerInfo 4 POINTER)
			  (ScavengerInfo 6 POINTER)))
		  (QUOTE 8))
(* * Replace NC.RobustReadID with the following.)

(DEFINEQ

(NC.RobustReadUID
  (LAMBDA (Stream)                                           (* rht: " 1-Dec-85 23:03")

          (* * Try to read a Notecards ID from Stream. Return NIL if it's not a valid ID.)



          (* * rht 12/1/85: Updated to handle new card format.)


    (LET ((OldPtr (GETFILEPTR Stream))
	  (Val (CAR (RESETVAR HELPFLAG NIL (NLSETQ (NC.ReadUID Stream))))))
         (if (type? UID Val)
	     then Val
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))
)
(* * Replace NC.SearchFor###OrNOBIND with the following.)

(DEFINEQ

(NC.SearchFor###
  (LAMBDA (Stream Ptr)                                       (* rht: " 1-Dec-85 23:33")

          (* * Move the file ptr to next occurrence of either # or NOBIND. The latter is for the stupid case of NOBIND 
	  instead of titles identifier. The choice of FFILEPOS rather than FILEPOS for the NOBIND search is based on 
	  empirical evidence from TIMEALL.)



          (* * rht 12/1/85: Now positions file 3 bytes in front of ###, to account for new length bytes.
	  Now doesn't fool with NOBIND litatoms.)


    (LET (NewPtr)
         (AND (SETQ NewPtr (FILEPOS (QUOTE ###)
					  Stream Ptr))
		(SETFILEPTR Stream (DIFFERENCE NewPtr 3))))))
)
(* * Replace NC.BuildScavengerArray with the following.)

(DEFINEQ

(NC.GetScavengerInfo
  (LAMBDA (NoteFile ReadSubstancesFlg MessageWin)            (* rht: " 1-Dec-85 23:41")

          (* * 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.)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
	  EndPtr CurPtr BadCardTypesList (MaxIDNum 0))
         (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 NIL T "Processing data area of notefile ..." (CHARACTER 13)
			"Searching for start of data area ..."
			(CHARACTER 13))                    (* 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 NIL T "Processing data area of notefile ..."
						 (CHARACTER 13)
						 "Byte number: "
						 (QUOTIENT CurPtr 1000)
						 "K out of "
						 (QUOTIENT EndPtr 1000)
						 "K."
						 (CHARACTER 13))
				  (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 (ADD1 CurPtr))))
		  finally (RETURN (QUOTE SUCCESS)))
	     then (NC.PrintMsg NIL NIL "Done." (CHARACTER 13))
		    (QUOTE SUCCESS)))))
)
(* * Here are a bunch of redefined functions from NCREPAIR.)

(DEFINEQ

(NC.ScavengeDatabaseFile
  (LAMBDA (NoteFileOrFileName BadLinkLabelsFlg ListOfCardsToReconstruct 
			      ListOfGlobalLinksToReconstruct)
                                                             (* rht: " 1-Dec-85 20:58")

          (* 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.)


    (PROG ((ListOfValidCards (LIST (QUOTE **Header**)))
	     (NoteCardNumber 0)
	     NoteFile FileName OldLinkLabels DiscoveredLinkLabels FromLinks ToLinks Stream 
	     HashArraySize Status ID Links Entry FullName CardTotal GlobalLinks ActiveCardsList 
	     ReconstructLinks ReconstructGlobalLinks ThisCardsToLinks ThisCardsGlobalLinks 
	     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))
	    (if (OPENP FileName)
		then (NC.PrintMsg NIL T FileName " is an already open file." (CHARACTER 13))
		       (RETURN NIL))                       (* Try to open notefile.)
	    (if (NULL (SETQ NoteFile (NC.OpenDatabaseFile FileName NIL T NIL NIL NIL NIL NIL 
								  T)))
		then (NC.PrintMsg NIL NIL "Couldn't open " FileName "." (CHARACTER 13)
				      "Repair aborted."
				      (CHARACTER 13))
		       (RETURN NIL))

          (* * If link labels aren't screwed up, then read them in.)


	    (OR BadLinkLabelsFlg (SETQ OldLinkLabels (NC.RetrieveLinkLabels NoteFile 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 HashArraySize (fetch (NoteFile HashArraySize)
					   NoteFile))
	    (NC.PrintMsg NIL T "Rebuilding notefile links." (CHARACTER 13)
			   "Collecting Links for item " 1 " out of " HashArraySize "." (CHARACTER
			     13))
	    (NC.MapCards NoteFile
			   (FUNCTION (LAMBDA (Card)
			       (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			       (AND (ZEROP (REMAINDER HashArraySize NoteCardNumber))
				      (NC.PrintMsg NIL T "Rebuilding notefile links." (CHARACTER
						       13)
						     "Collecting Links for item " NoteCardNumber 
						     " out of "
						     HashArraySize "." (CHARACTER 13)))
			       (COND
				 ((for CardToReconstruct in ListOfCardsToReconstruct
				     never (NC.SameCardP Card CardToReconstruct))
				   (NC.GetMainCardData Card)
				   (NC.GetLinks Card)
				   (SETQ Status (NC.FetchStatus Card))
				   (COND
				     ((EQ Status (QUOTE ACTIVE))
				       (push ActiveCardsList Card)
				       (AND (for ValidCard in ListOfValidCards
						 never (NC.SameCardP Card ValidCard))
					      (push ListOfValidCards Card))
				       (SETQ Links (NC.CollectAndCheckLinks Card NoteFile 
										ListOfValidCards))
				       (push ToLinks (CONS Card Links))
				       (push GlobalLinks (CONS Card (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 ListOfCardsToReconstruct
					      (for Link in (NC.FetchFromLinks Card)
						 eachtime (BLOCK)
						 when (for CardToReconstruct in 
									 ListOfCardsToReconstruct
							   bind (SourceCard ←(fetch (Link 
										       SourceCard)
										  of Link))
							   thereis (NC.SameCardP SourceCard 
										CardToReconstruct))
						 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 to a card whose global links need reconstructing.)


				       (AND ListOfGlobalLinksToReconstruct
					      (for Link in (NC.FetchFromLinks Card)
						 eachtime (BLOCK)
						 when (AND (NC.GlobalLinkP Link)
							       (for CardToReconstruct in 
								   ListOfGlobalLinksToReconstruct
								  bind (SourceCard
									   ←(fetch (Link SourceCard)
									       of Link))
								  thereis (NC.SameCardP 
										       SourceCard 
										CardToReconstruct)))
						 do (push ReconstructGlobalLinks Link)))
				       (NC.DeactivateCard Card T))))
				 (T (NC.GetLinks Card)
				    (push GlobalLinks (CONS Card (NC.FetchGlobalLinks Card)))
				    (push ToLinks (CONS Card (NC.FetchGlobalLinks Card)))
				    (NC.DeactivateCard Card T))))))

          (* * Reconstruct any cards as requested)


	    (for CardToReconstruct in ListOfCardsToReconstruct eachtime (BLOCK)
	       do                                          (* Make a new file box using the given card.)
		    (NC.MakeNoteCard (QUOTE FileBox)
				       NoteFile "Untitled: Reconstructed during repair" T NIL 
				       CardToReconstruct)    (* File cards whose from links indicate that they used
							     to be filed in this file box)
		    (SETQ Links (for Link in ReconstructLinks bind DestCard eachtime
										     (BLOCK)
				     when (AND (NC.SameCardP CardToReconstruct
								   (fetch (Link SourceCard)
								      of Link))
						   (OR (NC.ContentsLinkP Link)
							 (NC.SubContentsLinkP Link)))
				     collect (NC.FileBoxCollectChildren
						 (NC.FetchSubstance CardToReconstruct)
						 CardToReconstruct
						 (LIST (SETQ DestCard (fetch (Link 
										  DestinationCard)
									     of Link)))
						 T)

          (* * rht 9/20/85: Have to find link just created in the ToLinks of filebox, so we can be sure that LinkID matches.
	  This is ugly to have to do this search every time!)


					       (create Link
						  copying (for CardLink in (NCP.GetLinks
										   CardToReconstruct)
							       eachtime (BLOCK)
							       when (NC.SameCardP
									DestCard
									(fetch (Link 
										  DestinationCard)
									   of CardLink))
							       do (RETURN CardLink)))))
                                                             (* Add the new links to the collected links list)
		    (COND
		      ((SETQ ThisCardsToLinks (for CardLinkPair in ToLinks eachtime (BLOCK)
						   when (NC.SameCardP (CAR CardLinkPair)
									  CardToReconstruct)
						   do (RETURN CardLinkPair)))
			(NCONC ThisCardsToLinks Links))
		      (T (push ToLinks (CONS CardToReconstruct Links))))
		    (push ActiveCardsList CardToReconstruct) 
                                                             (* Put the card away)
		    (NC.PutMainCardData CardToReconstruct)
		    (NC.DeactivateCard CardToReconstruct T))

          (* * Reconstruct any global link lists as required)


	    (for Link in ReconstructGlobalLinks eachtime (BLOCK)
	       do                                          (* Add it to the GlobalLinks list)
		    (COND
		      ((SETQ ThisCardsGlobalLinks (for CardAndGlobalLink in GlobalLinks
						       when (NC.SameCardP (fetch (Link 
										       SourceCard)
										 of Link)
									      (CAR 
										CardAndGlobalLink))
						       do (RETURN CardAndGlobalLink)))
			(COND
			  ((for GlobalLink in ThisCardsGlobalLinks eachtime (BLOCK)
			      never (NC.SameLinkP Link GlobalLink))
			    (COND
			      ((CADR ThisCardsGlobalLinks)
                                                             (* were there global links before?)
				(NCONC1 ThisCardsGlobalLinks Link))
			      (T (RPLACD ThisCardsGlobalLinks (LIST Link)))))))
		      (T (push GlobalLinks (CONS (fetch (Link SourceCard) of Link)
						     (LIST Link)))))
                                                             (* Add it to the ToLinks list if its not already 
							     there)
		    (COND
		      ((SETQ ThisCardsToLinks (for CardAndLinks in ToLinks
						   when (NC.SameCardP (fetch (Link SourceCard)
									     of Link)
									  (CAR CardAndLinks))
						   do (RETURN CardAndLinks)))
			(COND
			  ((for ToLink in ThisCardsToLinks eachtime (BLOCK)
			      never (NC.SameLinkP Link ToLink))
			    (COND
			      ((CADR ThisCardsToLinks)
				(NCONC1 ThisCardsToLinks Link))
			      (T (RPLACD ThisCardsToLinks (LIST Link)))))))
		      (T (SETQ ToLinks (CONS (CONS (fetch (Link SourceCard) of Link)
							 (LIST Link))
						 ToLinks)))))

          (* * Compute the From Links list by "inverting" the To Links list)


	    (NC.PrintMsg NIL T "Processing Links ... ")
	    (for Item in ToLinks eachtime (BLOCK)
	       do (for Link in (CDR Item) bind LinkLabel eachtime (BLOCK)
		       do (SETQ Entry (for CardAndLinks in FromLinks
					     when (NC.SameCardP (fetch (Link DestinationCard)
								       of Link)
								    (CAR CardAndLinks))
					     do (RETURN CardAndLinks)))
			    (COND
			      (Entry (NCONC1 Entry Link))
			      (T (push FromLinks (LIST (fetch (Link DestinationCard)
							      of Link)
							   Link))))
                                                             (* Accumulate the link labels into a list.)
			    (COND
			      ((NOT (FMEMB (SETQ LinkLabel (fetch (Link Label) of Link))
					       DiscoveredLinkLabels))
				(push DiscoveredLinkLabels LinkLabel)))))
                                                             (* Reset all of the To and From Links lists in the 
							     database)
	    (NC.PrintMsg NIL T "Repairing NoteFile." (CHARACTER 13)
			   "Rewriting links for item " 1 " out of " HashArraySize "." (CHARACTER
			     13))
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
			       (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			       (AND (ZEROP (REMAINDER NoteCardNumber 10))
				      (NC.PrintMsg NIL T "Repairing NoteFile." (CHARACTER 13)
						     "Rewriting links for item " NoteCardNumber 
						     " out of "
						     HashArraySize "." (CHARACTER 13)))
			       (COND
				 ((for ActiveCard in ActiveCardsList thereis (NC.SameCardP
										     ActiveCard Card))
				   (NC.SetGlobalLinks Card (CDR (for CardAndLinks in 
										      GlobalLinks
								       when (NC.SameCardP
										Card
										(CAR CardAndLinks))
								       do (RETURN CardAndLinks))))
				   (NC.SetToLinks Card (CDR (for CardAndLinks in ToLinks
								   when (NC.SameCardP
									    Card
									    (CAR CardAndLinks))
								   do (RETURN CardAndLinks))))
				   (NC.SetFromLinks Card (CDR (for CardAndLinks in FromLinks
								     when (NC.SameCardP
									      Card
									      (CAR CardAndLinks))
								     do (RETURN CardAndLinks))))
				   (if (AND (for TopLevelCard in (NC.FetchTopLevelCards
									   NoteFile)
						   never (NC.SameCardP Card TopLevelCard))
						(NOT (NC.SameCardP Card (fetch (NoteFile 
										   LinkLabelsCard)
									       of NoteFile)))
						(for Link in (NC.FetchFromLinks Card)
						   eachtime (BLOCK) never (NC.ChildLinkP
										  Link)))
				       then (push ToBeFiledCards Card))
				   (NC.PutLinks Card)
				   (NC.DeactivateCard Card T))))))
                                                             (* File any unfiled cards in the ToBeFiled box.)
	    (if ToBeFiledCards
		then (NC.PrintMsg NIL T "Filing " (LENGTH ToBeFiledCards)
				      " cards in ToBeFiled box."
				      (CHARACTER 13))
		       (NCP.FileCards ToBeFiledCards (fetch (NoteFile ToBeFiledCard)
							  of NoteFile)))
                                                             (* Rewrite link labels if we've found any new ones.)
	    (COND
	      ((LDIFFERENCE DiscoveredLinkLabels OldLinkLabels)
		(NC.StoreLinkLabels NoteFile (UNION DiscoveredLinkLabels OldLinkLabels))))
	    (NC.CheckpointDatabase NoteFile T)
	    (NC.ForceDatabaseClose NoteFile)
	    (NC.PrintMsg NIL T "Repair Completed for " (FULLNAME FileName)
			   "."
			   (CHARACTER 13))
	    (if ToBeFiledCards
		then (NC.PrintMsg NIL NIL "Filed cards " (for Card in ToBeFiledCards
								collect (NC.FetchTitle Card))
				      " in ToBeFiled box.")))))

(NC.RobustReadCardPart
  (LAMBDA (NoteFile ReadSubstancesFlg MessageWin EndPtr)     (* rht: " 1-Dec-85 23:23")

          (* * Assume stream is positioned at start of a card part. Try to read one and modify scavenger array according to 
	  what we find.)



          (* * rht 9/17/85: Now returns ID rather than litatom SUCCESS is wins.)



          (* * rht 12/1/85: Updated to handle new notefile and card object formats.)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
	  IdentifierAndVersionNum IdentifierAtom Date UID Card Title ToLinks FromLinks GlobalLinks 
	  PropList Type SubstanceLength)
         (OR EndPtr (SETQ EndPtr (GETEOFPTR Stream)))
         (SETQ CurPtr (GETFILEPTR Stream))
         (if (AND (SETQ IdentifierAndVersionNum (NC.RobustReadItemIdentifier Stream))
		      (if (GEQ (CDR IdentifierAndVersionNum)
				   1)
			  then (SETQ Date (NC.RobustReadDate Stream))
			else T)
		      (SETQ UID (NC.RobustReadUID Stream))
		      (SETQ Card (NC.CardFromUID UID NoteFile)))
	     then (SETQ Date (CAR Date))
		    (SETQ IdentifierAtom (CAR IdentifierAndVersionNum))
		    (if (COND
			    ((EQ IdentifierAtom NC.TitlesIdentifier)
                                                             (* Hoping to get a healthy title.)
			      (if (AND (SETQ Title (NC.RobustReadString Stream))
					   (NC.AtEndOfItemP Stream EndPtr))
				  then (NC.SetScavengerTitleInfo Card
								     (CONS (LIST CurPtr Date 
										     Title)
									     (
								       NC.FetchScavengerTitleInfo
									       Card)))))
			    ((EQ IdentifierAtom NC.PropsIdentifier)
                                                             (* Hoping to get a healthy prop list.)
			      (if (AND (SETQ PropList (NC.RobustReadList Stream))
					   (NC.AtEndOfItemP Stream))
				  then (NC.SetScavengerPropListInfo
					   Card
					   (CONS (LIST CurPtr Date (LENGTH (CAR PropList)))
						   (NC.FetchScavengerPropListInfo Card)))))
			    ((EQ IdentifierAtom NC.LinksIdentifier)
                                                             (* Hoping to get healthy links.
							     Try to read three lists: ToLinks, FromLinks, and 
							     Global links.)
			      (if (AND (SETQ ToLinks (NC.RobustReadLinks Stream NoteFile))
					   (SETQ FromLinks (NC.RobustReadLinks Stream NoteFile))
					   (SETQ GlobalLinks (NC.RobustReadLinks Stream NoteFile))
					   (NC.AtEndOfItemP Stream EndPtr))
				  then (NC.SetScavengerLinksInfo
					   Card
					   (CONS (LIST CurPtr Date (LIST (LENGTH
										 (CAR ToLinks))
									       (LENGTH
										 (CAR FromLinks))
									       (LENGTH
										 (CAR GlobalLinks)))
							   )
						   (NC.FetchScavengerLinksInfo Card)))))
			    ((EQ IdentifierAtom NC.ItemIdentifier)
                                                             (* Hoping to get healthy substance.)
			      (if (AND (SETQ Type (CAR (NC.RobustReadAtom Stream)))
					   (NC.RobustReadRegion Stream EndPtr)
					   (SETQ SubstanceLength (NC.CheckForValidSubstance
					       Stream EndPtr Card Type ReadSubstancesFlg))
					   (NC.AtEndOfItemP Stream))
				  then (if (NOT (NCP.ValidCardType Type))
					     then          (* Code for this card part type has not been loaded.)
						    (WINDOWADDPROP MessageWin (QUOTE 
									     UNKNOWNCARDTYPESLIST)
								     Type)
                                                             (* Save the pointer to the substance card part on the 
							     unknown type's proplist.)
						    (ADDPROP Type (QUOTE SUBSTANCEPTRS)
							       CurPtr))
					 (NC.SetScavengerMainDataInfo
					   Card
					   (CONS (LIST CurPtr Date Type (OR SubstanceLength
										  (QUOTE 
										  UNKNOWNCARDTYPE)))
						   (NC.FetchScavengerMainDataInfo Card))))))
			then Card)))))

(NC.CheckForValidSubstance
  (LAMBDA (Stream EofPtr Card CardType ReadSubstanceFlg)     (* rht: " 1-Dec-85 23:21")

          (* * Check whether we've got a valid substance at current pos in Stream. Check for a valid StartPtr and EndPtr.
	  If ReadSubstanceFlg is non-nil, then do robust get of the substance. Return length of substance or nil.)



          (* * rht 12/1/85: Updated to handle new notefile format in MainCardData card part.)


    (LET ((OldPtr (GETFILEPTR Stream))
	  Length EndPtr)
         (OR EofPtr (SETQ EofPtr (GETEOFPTR Stream)))
         (if (AND (LESSP OldPtr (DIFFERENCE EofPtr 3))
		      (SETQ Length (NC.ReadPtr Stream 3))
		      (LEQ (SETQ EndPtr (PLUS Length (GETFILEPTR Stream)))
			     EofPtr)
		      (OR (NOT ReadSubstanceFlg)
			    (NOT (NCP.ValidCardType CardType))
			    (NC.RobustGetSubstance Card CardType Length))
		      (SETFILEPTR Stream EndPtr)
		      Length)
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))

(NC.AtEndOfItemP
  (LAMBDA (Stream EofPtr)                                    (* rht: " 1-Dec-85 22:55")

          (* * Return T if at the end of an item. That means either we're at the end of the file, or there's a # at the 
	  current location.)



          (* * rht 12/1/85: Updated to handle new notefile and card object formats. Ripped out the kludgy check for NOBIND 
	  litatom. Also now handles the 3 byte length info at start of every card part header.)


    (LET ((OldPtr (GETFILEPTR Stream))
	  HashPtr)
         (OR EofPtr (SETQ EofPtr (GETEOFPTR Stream)))
                                                             (* Skip past the card part length.)
         (SETFILEPTR Stream (SETQ HashPtr (PLUS 3 OldPtr)))
         (if (OR (GEQ HashPtr EofPtr)
		     (EQ (READC Stream)
			   (QUOTE #)))
	     then (SETFILEPTR Stream OldPtr)
		    T
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))

(NC.RobustReadItemIdentifier
  (LAMBDA (Stream)                                           (* rht: " 1-Dec-85 22:24")

          (* * Look for an item identifier at the current position in Stream. If successful, return the part/item type.)



          (* * rht 12/1/85: Ripped out kludgy NOBIND litatom test.)


    (LET ((OldPtr (GETFILEPTR Stream))
	  Atom VersionNumber)
         (SETQ Atom (CAR (NC.RobustRead Stream)))
         (if (AND (FMEMB Atom NC.IdentifierAtoms)
		      (NC.RobustReadChar Stream)
		      (NUMBERP (SETQ VersionNumber (CAR (NC.RobustReadByte Stream)))))
	     then (CONS Atom VersionNumber)
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))

(NC.RobustReadString
  (LAMBDA (Stream)                                           (* rht: " 1-Dec-85 22:57")

          (* * Try to read a string from Stream. Return NIL if not.)


    (LET (Val (OldPtr (GETFILEPTR Stream)))
         (if (STRINGP (SETQ Val (CAR (NC.RobustRead Stream))))
	     then                                          (* Skip CR.)
		    (NC.RobustReadChar Stream)
		    Val
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))

(NC.RobustReadList
  (LAMBDA (Stream)                                           (* rht: " 1-Dec-85 22:57")

          (* * Try to read a list from Stream. Returns a list of one element, the list read, if successful.
	  NIL otherwise.)


    (LET (Val (OldPtr (GETFILEPTR Stream)))
         (if (AND (SETQ Val (NC.RobustRead Stream))
		      (OR (NULL (CAR Val))
			    (LISTP (CAR Val))))
	     then                                          (* Skip CR at end.)
		    (NC.RobustReadChar Stream)
		    Val
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))

(NC.RobustReadLinks
  (LAMBDA (Stream NoteFile)                                  (* rht: " 1-Dec-85 23:04")

          (* * Try to read a list of links from Stream. Return list of one element, the list read, if successful, NIL 
	  otherwise.)


    (LET ((OldPtr (GETFILEPTR Stream))
	  (List (CAR (RESETVAR HELPFLAG NIL (NLSETQ (NC.ReadListOfLinks NoteFile))))))
         (if List
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))

(NC.RobustReadAtom
  (LAMBDA (Stream)                                           (* rht: " 1-Dec-85 23:05")

          (* * Returns a list of one element, the atom found. If unsuccessful read, then return nil.)


    (LET ((OldPtr (GETFILEPTR Stream))
	  (Val (NC.RobustRead Stream)))
         (if (AND Val (ATOM (CAR Val)))
	     then                                          (* Skip CR.)
		    (NC.RobustReadChar Stream)
		    Val
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))

(NC.RobustReadRegion
  (LAMBDA (Stream EofPtr)                                    (* rht: " 1-Dec-85 23:07")

          (* * Try to read a notecards region. Return region or nil.)


    (LET ((OldPtr (GETFILEPTR Stream)))
         (OR EofPtr (SETQ EofPtr (GETEOFPTR Stream)))
         (if (AND (LESSP OldPtr (DIFFERENCE EofPtr 8))
		      (for i from 1 to 4 bind Num collect (if (GEQ (SETQ Num
										   (NC.GetPtr Stream 
											      2))
										 0)
									then Num
								      else (RETURN NIL))))
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))

(NC.RobustGetSubstance
  (LAMBDA (Card CardType Length)                             (* rht: " 1-Dec-85 23:21")

          (* * Try to get substance robustly. RESETVAR prevents breaks. Returns either substance or nil if unsuccessful.)



          (* * rht 12/1/85: Updated to use card and notefile format.)


    (RESETVAR HELPFLAG NIL (NLSETQ (APPLY* (NC.GetSubstanceFn CardType)
						 Card Length)))))

(NC.RobustReadDate
  (LAMBDA (Stream)                                           (* rht: " 1-Dec-85 22:32")

          (* * Try to read a date string or the litatom NIL. Return a list containing the date or NIL indicating failure.)



          (* * rht 12/1/85: Now skips past CR if successful.)


    (LET ((OldPtr (GETFILEPTR Stream))
	  Val)
         (if (OR (NULL (SETQ Val (CAR (NC.RobustRead Stream))))
		     (AND (STRINGP Val)
			    (EQ (NCHARS Val)
				  NC.DateStringLength)))
	     then                                          (* Skip CR.)
		    (NC.RobustReadChar Stream)
		    (LIST Val)
	   else (SETFILEPTR Stream OldPtr)
		  NIL))))
)
(PUTPROPS RHTPATCH011 COPYRIGHT ("Xerox Corporation" 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (3732 8070 (NC.FetchScavengerInfo 3742 . 3992) (NC.SetScavengerInfo 3994 . 4262) (
NC.SetScavengerTitleInfo 4264 . 4784) (NC.SetScavengerMainDataInfo 4786 . 5319) (
NC.SetScavengerLinksInfo 5321 . 5841) (NC.SetScavengerPropListInfo 5843 . 6376) (
NC.FetchScavengerTitleInfo 6378 . 6794) (NC.FetchScavengerMainDataInfo 6796 . 7222) (
NC.FetchScavengerLinksInfo 7224 . 7640) (NC.FetchScavengerPropListInfo 7642 . 8068)) (8465 8999 (
NC.RobustReadUID 8475 . 8997)) (9064 9788 (NC.SearchFor### 9074 . 9786)) (9852 12535 (
NC.GetScavengerInfo 9862 . 12533)) (12603 38161 (NC.ScavengeDatabaseFile 12613 . 27122) (
NC.RobustReadCardPart 27124 . 31364) (NC.CheckForValidSubstance 31366 . 32430) (NC.AtEndOfItemP 32432
 . 33432) (NC.RobustReadItemIdentifier 33434 . 34180) (NC.RobustReadString 34182 . 34681) (
NC.RobustReadList 34683 . 35310) (NC.RobustReadLinks 35312 . 35789) (NC.RobustReadAtom 35791 . 36326) 
(NC.RobustReadRegion 36328 . 36985) (NC.RobustGetSubstance 36987 . 37423) (NC.RobustReadDate 37425 . 
38159)))))
STOP