'From Cuis 2.0 of 24 February 2010 [latest update: #440] on 26 February 2010 at 12:09:28 pm'!

!FileDirectory class methodsFor: 'name utilities' stamp: 'jmv 2/26/2010 10:56'!
sourceSuffix
"if 'sources' is not suitable, override this message to return something that is ok"
	^'sources'! !

!FileDirectory class methodsFor: 'system start up' stamp: 'jmv 2/26/2010 11:56'!
openSources: sourcesName andChanges: changesName forImage: imageName 
	"Open the changes and sources files and install them in SourceFiles. Inform the user of problems regarding write permissions or CR/CRLF mixups."
	"Note: SourcesName and imageName are full paths; changesName is a  
	local name."
	| sources changes msg wmsg |
	msg _ 'Squeak cannot locate &fileRef.

Please check that the file is named properly and is in the
same directory as this image.  
Further explanation can found
in the startup window, ''How Squeak Finds Source Code''.'.
	wmsg _ 'Squeak cannot write to &fileRef.

Please check that you have write permission for this file.

You won''t be able to save this image correctly until you fix this.'.

	"Do not open source files if internalized (i.e. notNil)"
	sources _ (SourceFiles at: 1) ifNil: [ self openSources: sourcesName forImage: imageName ].
	changes _ (SourceFiles at: 2) ifNil: [ self openChanges: changesName forImage: imageName ].

	(sources isNil and: [ Preferences valueOfFlag: #warnIfNoSourcesFile ])
		ifTrue: [
			Smalltalk platformName = 'Mac OS'
				ifTrue: [
					msg _ msg , String cr, 'Make sure the sources file is not an Alias.'].
			self inform: (msg copyReplaceAll: '&fileRef' with: 'the sources file named ' , sourcesName)].

	(changes isNil and: [ Preferences valueOfFlag: #warnIfNoChangesFile ])
		ifTrue: [self inform: (msg copyReplaceAll: '&fileRef' with: 'the changes file named ' , changesName)].

	((Preferences valueOfFlag: #warnIfNoChangesFile) and: [changes notNil])
		ifTrue: [
			changes isReadOnly
				ifTrue: [
					self inform: (wmsg copyReplaceAll: '&fileRef' with: 'the changes file named ' , changesName)].

			((changes next: 200)
					includesSubString: String crlf)
				ifTrue: [
					self inform: 'The changes file named ' , changesName , '
has been injured by an unpacking utility.  Crs were changed to CrLfs.
Please set the preferences in your decompressing program to 
"do not convert text files" and unpack the system again.']].

	SourceFiles _ Array with: sources with: changes! !


!Stream methodsFor: 'accessing' stamp: 'jmv 2/26/2010 11:31'!
basicNext

	^ self next! !

!Stream methodsFor: 'testing' stamp: 'jmv 2/26/2010 11:13'!
isReadOnly
	"To be redefined in subclasses that can't do #nextPut:"
	^ false! !

!Stream methodsFor: 'FileStream compatibility' stamp: 'jmv 2/26/2010 11:26'!
close
	"Only some specific kinds of Streams such as FileStream need this"! !

!Stream methodsFor: 'FileStream compatibility' stamp: 'jmv 2/26/2010 11:27'!
readOnlyCopy
	"Only some specific kinds of Streams such as FileStream need this
	This is needed, for example, for #internalizeSources"
	^self! !


!ReadStream methodsFor: 'testing' stamp: 'jmv 2/26/2010 11:13'!
isReadOnly
	^ true! !


!SystemDictionary methodsFor: 'housekeeping' stamp: 'jmv 2/26/2010 11:00'!
condenseSources	
	"Move all the changes onto a compacted sources file."
	"Smalltalk condenseSources"

	| f classCount dir newVersionString newSourcesName |
	dir _ FileDirectory default.
	newVersionString _ FillInTheBlank request: 'Please designate the version
for the new source code file...' initialAnswer: SourceFileVersionString.
	newVersionString ifNil: [^ self].
	newVersionString = SourceFileVersionString ifTrue:
		[^ self error: 'The new source file must not be the same as the old.'].
	SourceFileVersionString _ newVersionString.

	"Write all sources with fileIndex 1"
	newSourcesName _ self newSourcesName.
	f _ FileStream newFileNamed: newSourcesName.
	f timeStamp.
'Condensing Sources File...'
	displayProgressAt: Sensor cursorPoint
	from: 0 to: Smalltalk classNames size
	during:
		[:bar | classCount _ 0.
		Smalltalk allClassesDo:
			[:class | bar value: (classCount _ classCount + 1).
			class fileOutOn: f moveSource: true toFile: 1]].
	f close.

	"Make a new empty changes file"
	self closeSourceFiles.
	dir rename: self localChangesName
		toBe: self localChangesName , '.old'.
	(FileStream newFileNamed: self localChangesName)
		timeStamp; close.
	LastQuitLogPosition _ 0.

	self setMacFileInfoOn: self localChangesName.
	self setMacFileInfoOn: newSourcesName.
	self openSourceFiles.
	self inform: 'Source files have been rewritten!!
 
Check that all is well, and then save/quit.
 
Otherwise, remove new sources/changes,
replace them with the former ones, and
exit without saving the image.
 '! !

!SystemDictionary methodsFor: 'image, changes name' stamp: 'jmv 2/26/2010 10:04'!
currentSourcesName
	"Answer the full path to the version-stable source code currently in use"
	^(SourceFiles at: 1) name! !

!SystemDictionary methodsFor: 'image, changes name' stamp: 'jmv 2/26/2010 10:56'!
defaultSourcesName
	"Answer the default full path to the version-stable source code"
	^ self vmPath , SourceFileVersionString , FileDirectory dot , FileDirectory sourceSuffix! !

!SystemDictionary methodsFor: 'image, changes name' stamp: 'jmv 2/26/2010 10:31'!
localChangesName
	"Answer the local name for the changes file corresponding to the image file name."
	"Smalltalk changesName"

	| imName |
	imName _ FileDirectory baseNameFor:
		(FileDirectory localNameFor: self imageName).
	^ imName, FileDirectory dot, FileDirectory changeSuffix! !

!SystemDictionary methodsFor: 'image, changes name' stamp: 'jmv 2/26/2010 11:00'!
newSourcesName
	"Answer the full path to a new version of the version-stable source code, just to be created
	Default location is the default directory"
	| newName |
	newName _ FileDirectory baseNameFor: (FileDirectory default fullNameFor: SourceFileVersionString).
	^newName , FileDirectory dot, FileDirectory sourceSuffix! !

!SystemDictionary methodsFor: 'snapshot and quit' stamp: 'jmv 2/26/2010 10:33'!
saveChangesInFileNamed: aString
	FileDirectory default 
		copyFileWithoutOverwriteConfirmationNamed: self localChangesName 
		toFileNamed: aString.
	self	setMacFileInfoOn: aString.! !

!SystemDictionary methodsFor: 'sources, change log' stamp: 'jmv 2/26/2010 10:34'!
externalizeSources   
	"Write the sources and changes streams onto external files."
 	"Smalltalk externalizeSources"

	| sourcesName changesName aFile |
	sourcesName _ self defaultSourcesName.
	(FileDirectory default fileExists: sourcesName)
		ifTrue: [^ self inform:
'Sorry, you must first move or remove the
file named ', sourcesName].
	changesName _ self localChangesName.
	(FileDirectory default fileExists: changesName)
		ifTrue: [^ self inform:
'Sorry, you must first move or remove the
file named ', changesName].

	aFile _  FileStream newFileNamed: sourcesName.
	aFile nextPutAll: SourceFiles first originalContents.
	aFile close.
	self setMacFileInfoOn: sourcesName.
	SourceFiles at: 1 put: (FileStream readOnlyFileNamed: sourcesName).

	aFile _ FileStream newFileNamed: self localChangesName.
	aFile nextPutAll: SourceFiles last contents.
	aFile close.
	"On Mac, set the file type and creator (noop on other platforms)"
	FileDirectory default
		setMacFileNamed: self localChangesName
		type: 'STch'
		creator: 'FAST'.
	SourceFiles at: 2 put: (FileStream oldFileNamed: changesName).

	self inform: 'Sources successfully externalized'.
! !

!SystemDictionary methodsFor: 'sources, change log' stamp: 'jmv 2/26/2010 10:33'!
internalizeChangeLog    
		"Smalltalk internalizeChangeLog"
	"Bring the changes file into a memory-resident filestream, for faster access and freedom from external file system.  1/31/96 sw"

	| reply aName aFile |
	reply _ self confirm:  'CAUTION -- do not undertake this lightly!!
If you have backed up your system and
are prepared to face the consequences of
the requested internalization of sources,
hit Yes.  If you have any doubts, hit No
to back out with no harm done.'.

	(reply ==  true) ifFalse:
		[^ self inform: 'Okay - abandoned'].

	aName _ self localChangesName.
	(aFile _ SourceFiles last) == nil ifTrue:
		[(FileDirectory default fileExists: aName)
			ifFalse: [^ self halt: 'Cannot locate ', aName, ' so cannot proceed.'].
		aFile _ FileStream readOnlyFileNamed: aName].
	SourceFiles at: 2 put: (ReadWriteStream with: aFile contentsOfEntireFile).

	self inform: 'Okay, changes file internalized'! !

!SystemDictionary methodsFor: 'sources, change log' stamp: 'jmv 2/26/2010 11:32'!
internalizeSources
		"Smalltalk internalizeSources"
	"Bring the sources and changes files into memory-resident filestreams, for faster access and freedom from file-system interface.  1/29/96 sw"

	| reply aName aFile |
	reply _ self confirm:  'CAUTION -- do not undertake this lightly!!
If you have backed up your system and
are prepared to face the consequences of
the requested internalization of sources,
hit Yes.  If you have any doubts, hit No
to back out with no harm done.'.

	(reply ==  true) ifFalse:
		[^ self inform: 'Okay - abandoned'].

	aName _ self currentSourcesName.
	(aFile _ SourceFiles first) ifNil: [
		(FileDirectory default fileExists: aName)
			ifFalse: [^ self halt: 'Cannot locate ', aName, ' so cannot proceed.'].
		aFile _ FileStream readOnlyFileNamed: aName].
	SourceFiles at: 1 put: (ReadWriteStream with: aFile contentsOfEntireFile).

	aName _ self localChangesName.
	(aFile _ SourceFiles last) ifNil: [
		(FileDirectory default fileExists: aName)
			ifFalse: [^ self halt: 'Cannot locate ', aName, ' so cannot proceed.'].
		aFile _ FileStream readOnlyFileNamed: aName].
	SourceFiles at: 2 put: (ReadWriteStream with: aFile contentsOfEntireFile).

	self inform: 'Okay, sources internalized'! !

!SystemDictionary methodsFor: 'sources, change log' stamp: 'jmv 2/26/2010 12:09'!
openSourceFiles
	self imageName = LastImageName ifFalse: [
		"Reset the author initials to blank when the image gets moved"
		LastImageName _ self imageName.
		Utilities setAuthorInitials: ''].
	"Warning: Do open the source files only if nil.
	If not nil, it is because they are internalized and the files should not be opened"
	FileDirectory
		openSources: self defaultSourcesName
		andChanges: self localChangesName
		forImage: LastImageName.
	StandardSourceFileArray install! !

Utilities class removeSelector: #fixUpProblemsWithAllCategory!
SystemDictionary removeSelector: #changesName!
SystemDictionary removeSelector: #sourcesName!
