(FILECREATED " 6-Jul-86 18:48:44" {QV}<NOTECARDS>1.3K>RHTPATCH060.;2 20083  

      changes to:  (VARS RHTPATCH060COMS)
		   (FNS NC.CheckForNeededTruncation NC.OpenDatabaseFile NC.ForceDatabaseClose)

      previous date: " 6-Jul-86 18:40:56" {QV}<NOTECARDS>1.3K>RHTPATCH060.;1)


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

(PRETTYCOMPRINT RHTPATCH060COMS)

(RPAQQ RHTPATCH060COMS ((* * Change to NCDATABASE)
			  (FNS NC.CheckForNeededTruncation NC.ForceDatabaseClose NC.OpenDatabaseFile))
)
(* * Change to NCDATABASE)

(DEFINEQ

(NC.CheckForNeededTruncation
  (LAMBDA (NoteFile Access InterestedWindow)                 (* rht: " 6-Jul-86 18:48")

          (* * See if there was a crash or aborted close last time. That is, has the notefile got junk beyond the last 
	  checkpoint EOFPTR? If so, ask if user wants to save the extra junk in a file. In any case, truncate at the old 
	  point. If the version number is less than 2, change to a version 2 file and write the the new checkpoint pointer.)



          (* * rht 9/20/85: Now allows user to enter inspector rather than truncating -
	  uses a pop up menu.)



          (* * kirk 23Jan86 Changed to use NC.AskYesOrNo)



          (* * rht 7/6/86: Now cancels out of open if user clicks outside of menu.)


    (OR InterestedWindow (SETQ InterestedWindow (WFROMMENU (fetch (NoteFile Menu)
								    of NoteFile))))
    (WITH.MONITOR (NC.FetchMonitor NoteFile)
		  (PROG ((Stream (fetch (NoteFile Stream) of NoteFile))
			   (FullFileName (fetch (NoteFile FullFileName) of NoteFile))
			   (Version (fetch (NoteFile Version) of NoteFile))
			   LastChkptPtr EndPtr SaveFile SaveStream Ptr Menu InterestedWindowPos)
		          (COND
			    ((LESSP Version 2)             (* Pronounce this a version 2 file and write the new 
							     lastchkptr value.)
			      (NC.PutNoteFileVersion NoteFile 2)
			      (NC.PutCheckptPtr NoteFile (GETEOFPTR Stream))
			      (RETURN NIL)))
		          (SETQ LastChkptPtr (fetch (NoteFile CheckptPtr) of NoteFile))
		          (SETQ EndPtr (GETEOFPTR Stream))
		          (COND
			    ((LESSP LastChkptPtr EndPtr)
			      (NC.PrintMsg InterestedWindow T "Last " (IDIFFERENCE EndPtr 
										     LastChkptPtr)
					     " bytes of " FullFileName (CHARACTER 13)
					     
				       " were written since last checkpoint or successful close."
					     (CHARACTER 13))
			      (SETQ Menu (create MENU
						     ITEMS ←(QUOTE ((Cancel (QUOTE Abort)
									      
							   "Cancel this open notefile operation.")
								       (Inspect% &% Repair
									 (QUOTE Inspect% &% Repair)
									 
		      "Run the Inspect&Repair facility to integrate extra work since checkpoint.")
								       (Truncate% File (QUOTE
											 
										   Truncate% File)
										       
	       "Truncate the file, either throwing away or saving changes since last checkpoint.")))
						     MENUOUTLINESIZE ← 2
						     MENUFONT ←(FONTCREATE (QUOTE HELVETICA)
									     12
									     (QUOTE BOLD))))
			      (SELECTQ (MENU Menu (create POSITION
								XCOORD ←(fetch (POSITION XCOORD)
									   of (SETQ 
									      InterestedWindowPos
										  (WINDOWPOSITION
										    InterestedWindow))
										 )
								YCOORD ←(DIFFERENCE
								  (fetch (POSITION YCOORD)
								     of InterestedWindowPos)
								  (fetch (MENU IMAGEHEIGHT)
								     of Menu))))
					 (Cancel (RETURN (QUOTE ABORT)))
					 (Inspect% &% Repair (RETURN (QUOTE ABORTANDINSPECT)))
					 (NIL (RETURN (QUOTE ABORT)))
					 NIL)
			      (COND
				((NC.AskYesOrNo "Want to save info beyond checkpoint to a file? " 
						  "--"
						  "Yes" NIL InterestedWindow NIL T)
				  (COND
				    ((AND (SETQ SaveFile (NC.AskUser (CONCAT (CHARACTER
										       13)
										     
									 "File to save info in: ")
									   NIL NIL NIL 
									   InterestedWindow T))
					    (SETQ SaveStream (OPENSTREAM SaveFile (QUOTE OUTPUT)
									     NIL
									     (QUOTE ((TYPE BINARY)))
									     )))
				      (NC.PrintMsg InterestedWindow T "Saving extra info to " 
						     SaveFile " ...")
				      (COPYBYTES Stream SaveStream LastChkptPtr EndPtr)
				      (CLOSEF SaveStream)
				      (NC.PrintMsg InterestedWindow NIL "Done." (CHARACTER 13)))
				    (T (NC.PrintMsg InterestedWindow T "Can't open " SaveFile "."
						      (CHARACTER 13)
						      "Open aborted."
						      (CHARACTER 13))
				       (RETURN (QUOTE ABORT))))))
			      (COND
				((NC.AskYesOrNo (CONCAT "Are you sure you want to truncate "
							    (CHARACTER 13)
							    FullFileName "? ")
						  "--" "No" T InterestedWindow NIL T)
				  (NC.PrintMsg InterestedWindow T "Truncating file " FullFileName 
						 " ...")
				  (CLOSEF Stream)
				  (COND
				    ((NOT (SETFILEINFO FullFileName (QUOTE LENGTH)
							   LastChkptPtr))
				      (NC.PrintMsg InterestedWindow NIL "Couldn't truncate " 
						     FullFileName "." (CHARACTER 13)
						     "Open aborted."
						     (CHARACTER 13))
				      (RETURN (QUOTE ABORT))))
				  (NC.PrintMsg InterestedWindow T "Done." (CHARACTER 13))
				  (RETURN (OPENSTREAM FullFileName Access NIL
							  (QUOTE ((TYPE BINARY))))))
				(T (NC.PrintMsg InterestedWindow NIL (CHARACTER 13)
						  "Open aborted."
						  (CHARACTER 13))
				   (RETURN (QUOTE ABORT))))))))))

(NC.ForceDatabaseClose
  (LAMBDA (NoteFile Don'tMenuFlg)                            (* rht: " 6-Jul-86 18:34")

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


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile)))
         (AND (OPENP Stream)
		(CLOSEF Stream))                           (* 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)))

(NC.OpenDatabaseFile
  (LAMBDA (NoteFileOrFileName Access Don'tCacheTypesAndTitlesFlg QuietFlg Don'tCreateFlg 
			      Convertw/oConfirmFlg Don'tCreateArrayFlg Don'tTruncateFlg 
			      Don'tCreateInterfaceFlg Don'tGetSpecialCardsFlg InterestedWindow 
			      Don'tCheckOperationInProgressFlg MenuPosition)
                                                             (* rht: " 6-Jul-86 18:43")

          (* * Open an already existing NoteFile and return a NoteFile object)



          (* * rht 8/7/84: For nonexistent files, asks user whether to create unless Don'tCreateFlg is non-nil.)



          (* * rht 1/9/85: Checks NC.UncachingNotCompleted global var. If non-nil, then previous notefile died unnaturally, 
	  so we first clear junk off the IDs.)



          (* * rht 8/6/85: Added Don'tTruncateFlg, which, if on, prevents the check for truncation.)



          (* * fgh 10/16/85 Updated to use new cacheing scheme.)



          (* * kirk 10/29/85: Now does cacheing of types and titles as background process.)



          (* * fkr 11/8/85: Converted from Streams to NoteFile object.)



          (* * kirk 30Nov85 Added a check for correct version number.)



          (* * rht 12/6/85: Moved Kirk's above patch to NC.CheckForNeededConversion and modified somewhat.
	  Added check for plausible header.)



          (* * rht 1/8/86: Now reuses old notefile object if there is one for this filename.)



          (* * fgh 1/13/86: Fixed bug with returning File Name with embedded call to CreateDatabaseFile.
	  Now just calls OpenDatabaseFile recursively using result of CreateDatabaseFile.)



          (* * fgh 1/16/86 Folded the cacheing of the special cards into BuildHashArray instead of making it a separate 
	  function after the hash array is already read in.)



          (* * kirk 20Jan86 Added NC.AskYesOrNo and InterestedWindow for prompt)



          (* * fgh 5/2/86 Implemented before and after opening hooks using NC.OpenNoteFileFns global variable.)



          (* * fgh 6/8/86 Added code to insure that two files with SameUIDP would never be open at once.)



          (* * fgh 6/25/86 Added contention locks -- NC.ProtectedNoteFileOperation, Don'tCheckOperationInProgressFlg etc.)



          (* * fgh 6/27/86 Added MenuPsotion arg to pass to SetUpNoteFileInterface)



          (* * rht 7/6/86: Added InterestedWindow arg to call to NC.CheckForNeededTruncation.)


    (PROG (NoteFile FileName Name Stream NewStream Card CardTotal)
	    (OR Access (SETQ Access (QUOTE BOTH)))
	    (SETQ FileName (COND
		((type? NoteFile NoteFileOrFileName)
		  (SETQ NoteFile NoteFileOrFileName)
		  (fetch (NoteFile FullFileName) of NoteFileOrFileName))
		(T NoteFileOrFileName)))
	    (if (NOT (OR FileName (SETQ FileName (NC.DatabaseFileName 
								      "Name of NoteFile to open:"
										" -- " T NIL NIL 
										InterestedWindow))))
		then (RETURN NIL))                       (* Use existing notefile object if there is one for 
							     this file name.)
	    (OR (type? NoteFile NoteFile)
		  (SETQ NoteFile (OR (NC.NoteFileFromFileName FileName)
					 (create NoteFile))))

          (* * If there is no interested window, see if the menu window can be used.)


	    (if (AND (NULL InterestedWindow)
			 (fetch (NoteFile Menu) of NoteFile))
		then (SETQ InterestedWindow (WFROMMENU (fetch (NoteFile Menu) of NoteFile)))
		  )

          (* * If this is an open NoteFIle, just bring up its menu.)


	    (if (NC.NoteFileOpenP NoteFile)
		then (NC.SetUpNoteFileInterface NoteFile MenuPosition)
		       (RETURN NIL))

          (* * Check to make sure the file is not already open.)


	    (if (OPENP FileName)
		then                                       (* need a better check here to bring up or create 
							     notefile icon if needed)
		       (NC.PrintMsg InterestedWindow T FileName " is an already open file."
				      (CHARACTER 13))
		       (RETURN NIL))

          (* * Check to see if this NoteFile is busy doing something else)


	    (if (AND (NULL Don'tCheckOperationInProgressFlg)
			 (PROCESSP (NC.NoteFileProp NoteFile (QUOTE ProcessInProgress))))
		then (NC.PrintOperationInProgressMsg InterestedWindow (QUOTE Open% NoteFile)
							 (NC.NoteFileProp NoteFile (QUOTE 
									      OperationInProgress)))
		       (RETURN NIL))

          (* * Run rest of function with contention lock.)


	    (RETURN (NC.ProtectedNoteFileOperation
			NoteFile Open% NoteFile
			(PROG NIL
			        (if (NOT (SETQ Name (INFILEP FileName)))
				    then (COND
					     (Don'tCreateFlg (NC.PrintMsg InterestedWindow T 
									"Couldn't find NoteFile "
									    FileName "."
									    (CHARACTER 13))
							     (RETURN NIL))
					     ((NC.AskYesOrNo (CONCAT "Unable to find NoteFile " 
									 FileName "." (CHARACTER
									   13)
									 
						   "Want to create a new NoteFile by that name? ")
							       " -- " "Yes" T InterestedWindow)
					       (SETQ NoteFile (NC.CreateDatabaseFile FileName NIL 
									       "Opening NoteFile"
											 T))
					       (if (NOT (type? NoteFile NoteFile))
						   then (NC.PrintMsg InterestedWindow T 
								     "Unable to create Notefile "
									 FileName "." (CHARACTER
									   13))
							  (RETURN NIL)
						 else (RETURN (NC.OpenDatabaseFile NoteFile 
											 Access 
								      Don'tCacheTypesAndTitlesFlg 
											 QuietFlg 
										   Don'tCreateFlg 
									     Convertw/oConfirmFlg 
									      Don'tCreateArrayFlg 
										 Don'tTruncateFlg 
									  Don'tCreateInterfaceFlg 
									  Don'tGetSpecialCardsFlg 
										 InterestedWindow T)))
					       )
					     (T (RETURN NIL))))

          (* * Run through OpenNoteFileFns with param of BEFORE. Exit if any returns DON'T)


			        (if (for Function in NC.OpenNoteFileFns
					 thereis (OR (EQ Function (QUOTE DON'T))
							 (EQ (QUOTE DON'T)
							       (APPLY* Function Name NoteFile
									 (QUOTE BEFORE)))))
				    then (RETURN NIL))

          (* * Open the file)


			        (OR QuietFlg (NC.PrintMsg InterestedWindow T "Opening NoteFile " 
							      Name " . . ." (CHARACTER 13)))
			        (if (NULL (SETQ Stream
						(CAR (ERSETQ (OPENSTREAM Name Access
									       (QUOTE OLD)
									       (QUOTE
										 ((TYPE BINARY))))))))
				    then (NC.PrintMsg InterestedWindow T "Couldn't open " 
							  FileName "." (CHARACTER 13))
					   (RETURN NIL))
			        (replace (NoteFile Stream) of NoteFile with Stream)
			        (replace (NoteFile FullFileName) of NoteFile with (FULLNAME
											  Stream))
			        (NC.SetMonitor NoteFile (CREATE.MONITORLOCK (MKATOM
										  (CONCAT Name 
											  ":LOCK"))))
			        (NC.GetNoteFileHeader NoteFile)

          (* * Make sure there is no other open NF with this UID.)


			        (LET (NF)
				     (if (AND (SETQ NF (GETHASH (fetch (NoteFile UID)
									   of NoteFile)
									NC.NoteFilesHashArray))
						  (NEQ (fetch (NoteFile FullFileName)
							    of NoteFile)
							 (fetch (NoteFile FullFileName)
							    of NF))
						  (NC.NoteFileOpenP NF))
					 then (FLASHW PROMPTWINDOW)
						(NC.PrintMsg InterestedWindow T "Couldn't open " 
							       FileName (CHARACTER 13)
							       "because "
							       (fetch (NoteFile FullFileName)
								  of NF)
							       " is already open "
							       (CHARACTER 13)
							       "and has the same UID.")
						(if (STREAMP (fetch (NoteFile Stream)
								    of NoteFile))
						    then (CLOSEF? (fetch (NoteFile Stream)
									 of NoteFile)))
						(replace (NoteFile Stream) of NoteFile
						   with NIL)
						(RETURN NIL)))

          (* * See if notefile is out of date. If so, convert to current version.)


			        (if (NOT (NC.CheckForNeededConversion NoteFile 
									    Convertw/oConfirmFlg))
				    then (CLOSEF (fetch (NoteFile Stream) of NoteFile))
					   (NC.PrintMsg InterestedWindow T "Open cancelled.")
					   (RETURN NIL))   (* See if notefile header seems reasonable.
							     If not, bail out.)
			        (if (NOT (NC.PlausibleNoteFileHeaderP NoteFile))
				    then (NC.PrintMsg InterestedWindow NIL 
				       "Notefile has bad header.  Please see a NoteCards wizard."
							  (CHARACTER 13)
							  "Open cancelled.")
					   (RETURN NIL))
			        (COND
				  ((NULL Don'tTruncateFlg)
                                                             (* Can either bail out entirely or run inspector and 
							     then bail out.)
				    (SELECTQ (SETQ NewStream (NC.CheckForNeededTruncation
						   NoteFile Access InterestedWindow))
					       (ABORT (CLOSEF Stream)
						      (NC.PrintMsg InterestedWindow T 
								     "Open cancelled.")
						      (DISMISS 1500)
						      (NC.ClearMsg InterestedWindow T)
						      (RETURN NIL))
					       (ABORTANDINSPECT (CLOSEF Stream)
								(NC.ScavengerPhase1 Name)
								(RETURN NIL))
					       NIL)
				    (AND (STREAMP NewStream)
					   (replace (NoteFile Stream) of NoteFile with 
											NewStream))))

          (* * Stash the notefile in the global notefiles hash array.)


			        (NC.StoreNoteFile NoteFile)

          (* * Build the hash array and cache the special cards if necessary)


			        (OR Don'tCreateArrayFlg (NC.BuildHashArray NoteFile QuietFlg 
									  Don'tGetSpecialCardsFlg 
									       InterestedWindow
									       (CONCAT
										 "Opening NoteFile " 
										 Name (CHARACTER
										   13))))
			        (OR Don'tGetSpecialCardsFlg (NC.GetSpecialCards
					NoteFile QuietFlg InterestedWindow (CONCAT 
									      "Opening NoteFile "
										     Name
										     (CHARACTER
										       13))))

          (* * Make sure the NF can't be closed by CLOSEALL)


			        (WHENCLOSE (fetch (NoteFile Stream) of NoteFile)
					     (QUOTE CLOSEALL)
					     (QUOTE NO))
			        (COND
				  ((NULL Don'tCacheTypesAndTitlesFlg)
                                                             (* Cache all of the titles in this database)
				    (replace (NoteFile CachingProcess) of NoteFile
				       with (ADD.PROCESS (LIST (FUNCTION 
								       NC.CacheTypesAndTitles)
								     NoteFile)))))
			        (COND
				  ((NULL Don'tCreateInterfaceFlg)
                                                             (* Make an interface menu for this notefile.)
				    (NC.SetUpNoteFileInterface NoteFile MenuPosition)))
			        (AND (NULL QuietFlg)
				       (NC.PrintMsg InterestedWindow T "Opened " (FULLNAME Stream)
						      (CHARACTER 13))
				       (NC.ClearMsg InterestedWindow T))
			        (SETQ NC.LastNoteFileOpened NoteFile)

          (* * Run through OpenNoteFIleFns with param of AFTER. Stop if any returns DON'T)


			        (for Function in NC.OpenNoteFileFns
				   thereis (EQ (QUOTE DON'T)
						   (APPLY* Function Name NoteFile (QUOTE AFTER))))

          (* * return the opened NF)


			        (RETURN NoteFile)))))))
)
(PUTPROPS RHTPATCH060 COPYRIGHT ("Xerox Corporation" 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (561 20001 (NC.CheckForNeededTruncation 571 . 5834) (NC.ForceDatabaseClose 5836 . 7956) 
(NC.OpenDatabaseFile 7958 . 19999)))))
STOP