Marcel Taeumel uploaded a new version of Graphics to project The Trunk:
http://source.squeak.org/trunk/Graphics-mt.538.mcz
==================== Summary ====================
Name: Graphics-mt.538
Author: mt
Time: 23 January 2023, 1:21:45.37588 pm
UUID: 0d6f4808-2e2e-494c-9b2c-92f7d0c7a0eb
Ancestors: Graphics-mt.537
Fix issue of leaking file handles in our new GIFReadWriter. I will backport this to 6.0.
Document the misnomer that should not be changed at this point. I think.
=============== Diff against Graphics-mt.537 ===============
Item was changed:
----- Method: GIFReadWriter class>>formsFromFileNamed: (in category 'image reading/writing') -----
+ formsFromFileNamed: aFilePath
+
+ ^ self formsFromStream: (FileStream readOnlyFileNamed: aFilePath)!
- formsFromFileNamed: aFile
- ^ (self on: aFile asDirectoryEntry readStream binary)
- readHeader;
- readBody;
- yourself!
Item was changed:
----- Method: GIFReadWriter class>>formsFromStream: (in category 'image reading/writing') -----
formsFromStream: aBinaryStream
+
+ | result |
+ self flag: #misnomer. "mt: This message does NOT return a collection of forms."
+ result := (self on: aBinaryStream)
- ^ (self on: aBinaryStream)
readHeader;
readBody;
+ yourself.
+
+ self flag: #workaround. "mt: Avoid leaking open file handles."
+ result close.
+
+ ^ result!
- yourself!
There is a pdf of Squeak By Example 5.3, but I can't find a printed and bound edition. There is a copy of the old 2007 or 2011 edition of the book for sale on Amazon, but not the updated one for 5.3.
Can I upload the SBE 5.3 pdf to lulu.com and have color printed and bound book created so I can purchase it for myself? I don't want to break any copyright laws. Even though the pdf is freely available, I don't know if having it printed is permitted.
Thank you.
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.1384.mcz
==================== Summary ====================
Name: System-mt.1384
Author: mt
Time: 20 January 2023, 3:48:54.016382 pm
UUID: 85b1fd2e-0162-b54c-b735-f046350d97ad
Ancestors: System-mt.1383
Move (1) recursive-error detection and (2) stack-to-file logging from Debugger class to ToolSet/Project so that custom (process) debugging tools cannot omit to include these features.
Note that, by now, most of the actual "debugging logic" is simply contained in
- Context and Process (for code simulation, i.e., step into etc.)
- Project and subclasses (for GUI/system responsiveness protection, i.e., recursive error detection, project fallback, emergency evaluator, ...)
It's now easier to write a custom debugger, install it through a custom toolset, and then use it for the next unhandled error.
=============== Diff against System-mt.1383 ===============
Item was changed:
----- Method: Process>>debug (in category '*System-debugging') -----
debug
"See the comment in #debugWithTitle:full:contents:."
+ ^ self debugWithTitle: 'Debugger' translated!
- ^ self debugWithTitle: nil!
Item was added:
+ ----- Method: Project>>debugProcess:inDialog: (in category 'scheduling & debugging') -----
+ debugProcess: aProcess inDialog: aMessageText
+ "Inform the user about a debugging incident where no interactive debugger is available. Give a choice between #terminate and #inspect. Suspend the process anway."
+
+ self addDeferredUIMessage: [
+ (self uiManager confirm: aMessageText, '\\Terminate process?' translated withCRs)
+ ifTrue: [aProcess terminateAggressively]
+ ifFalse: [aProcess inspect]].
+
+ self suspendProcessSafely: aProcess.
+
+ ^ nil "There is no debugger tool to answer."!
Item was added:
+ ----- Method: Project>>guardRecursiveError:during: (in category 'scheduling & debugging') -----
+ guardRecursiveError: errorMessage during: workBlock
+
+ "If the active process re-enters this method again, something went wrong with invoking the debugger."
+ Processor activeProcess hasRecursiveError
+ ifTrue: [
+ Processor activeProcess clearErrorRecursionFlag.
+ ToolSet handleRecursiveError: errorMessage].
+
+ "If project-specific debuggers mess up, we have to flag that recursion here."
+ Processor activeProcess setErrorRecursionFlag.
+ ^ workBlock ensure: [Processor activeProcess clearErrorRecursionFlag]!
Item was changed:
----- Method: SmalltalkImage>>logError:inContext:to: (in category 'miscellaneous') -----
logError: errMsg inContext: aContext to: aFilename
"Log the error message and a stack trace to the given file."
+ FileStream forceNewFileNamed: aFilename do: [:stream |
+ stream nextPutAll: (errMsg ifNil: ['(unspecified error)']); cr.
+ aContext errorReportOn: stream].!
- | ff |
- FileDirectory default deleteFileNamed: aFilename ifAbsent: [].
- (ff := FileStream fileNamed: aFilename) ifNil: [^ self "avoid recursive errors"].
-
- ff nextPutAll: errMsg; cr.
- aContext errorReportOn: ff.
- ff close.!
Item was added:
+ ----- Method: SmalltalkImage>>tryLogSqueakError:inContext: (in category 'miscellaneous') -----
+ tryLogSqueakError: errorMessage inContext: aContext
+ "Log error message and stack trace in file. Can be disabled via preference. Guard errors to avoid recursive error."
+
+ Preferences logDebuggerStackToFile ifFalse: [^ false].
+
+ [Smalltalk logSqueakError: errorMessage inContext: aContext]
+ on: Error do: [:ex |
+ Preferences disable: #logDebuggerStackToFile.
+ ToolSet debugException: ex.
+ ^ false].
+
+ ^ true!
Item was changed:
----- Method: ToolSet class>>debugProcess:context:label:contents:fullView: (in category 'debugging') -----
debugProcess: aProcess context: aContext label: aString contents: contents fullView: aBool
+ "Open a debugger on the given process, which might be active, suspended, or terminated. You can also use the convenience protocol for debugging on Process and ProcessorScheduler.
+
+ NOTE that you SHOULD NOT pass 'Processor activeProcess' directly to this method to avoid mixing code simulation with genuine code execution. Always use the indirection via ProcessorScheduler >>#debug... See also the comment in Process >> #debugWithTitle:full:contents:."
- "Open a debugger on the given process, which might be active, suspended, or terminated. You can also use the convenience protocol for debugging on Process and ProcessorScheduler. NOTE that you should not pass Processor activeProcess directly to this method. Always use the indirection via ProcessorScheduler >>#debug... See also the comment in Process >> #debugWithTitle:full:contents:."
+ "First, guard this incident to detect and handle recursive errors."
+ ^ Project current guardRecursiveError: aString during: [
+
+ "In any case, log the debugging incident into an external file."
+ Smalltalk tryLogSqueakError: aString inContext: aContext.
+
+ self default
+ ifNotNil: [:toolSet |
+ "Let the current tool set decide about the best tool for the job."
+ toolSet
+ debugProcess: aProcess context: aContext
+ label: aString contents: contents
+ fullView: aBool]
+ ifNil: [
+ "There is no tool set!! :-O ... Inform the user in a simple dialog."
+ Project current
+ debugProcess: aProcess
+ inDialog: ('No debugger available for process:\\ Name: {1}\ Hash: {2}\ Context: {3}\ Title: {4}\ Message: {5}' translated withCRs
+ format: {aProcess name. aProcess hash. aContext. aString. contents})] ]!
- ^ self default
- ifNil: [(self confirm: 'Debugger request -- proceed?' translated) ifFalse: [Processor terminateActive]]
- ifNotNil: [:ts | ts debugProcess: aProcess context: aContext label: aString contents: contents fullView: aBool]!
Marcel Taeumel uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-mt.1186.mcz
==================== Summary ====================
Name: Tools-mt.1186
Author: mt
Time: 20 January 2023, 6:50:26.795382 pm
UUID: 19c7a120-92c1-fd49-a0fd-96a76f3285c1
Ancestors: Tools-mt.1185
Complements System-mt.1385
=============== Diff against Tools-mt.1185 ===============
Item was added:
+ ----- Method: Debugger>>initialExtentKey (in category 'initialize-release') -----
+ initialExtentKey
+
+ ^ { self class name . self isNotifier }!
Item was changed:
----- Method: Debugger>>openFullFromNotifier: (in category 'initialize-release') -----
openFullFromNotifier: topView
"Create a full debugger to replace the given view."
+ RealEstateAgent rememberExtentFor: self.
self initializeFull.
topView model: nil. "so close won't release me."
self breakDependents.
^ ToolBuilder default
close: topView;
open: self label: topView label "Keep the label."!
Item was changed:
----- Method: Inspector>>replaceInspectorWithExplorer (in category 'toolbuilder') -----
replaceInspectorWithExplorer
"Switch to an explorer tool. If there are custom fields, the user can choose to not discard them, which will just spawn a new explorer tool besides this inspector."
| window currentBounds |
self flag: #todo. "ct: In the long term, we should try to communicate specific selectors (here: #expression) along the observer pattern for requests such as #acceptChanges or #wantToChange instead of exploiting contentsTyped etc."
(self okToDiscardCustomFields and: [contentsTyped notNil ==> [self confirm:
'Changes have not been saved.
Is it OK to cancel those changes?' translated orCancel: [^ self]]])
ifFalse: [^ self object explore].
self customFields removeAll.
self changed: #contents. "Reset value pane contents before accepting all contents"
self changed: #acceptChanges. "We copy the current state anyway. See below."
+ RealEstateAgent rememberExtentFor: self.
currentBounds := ToolBuilder default class getBoundsForWindow: self containingWindow.
"Close first because MVC fiddles around with processes."
self changed: #close.
window := ToolSet explore: self object.
"---- In MVC, the lines after this will not be executed ---"
window model setExpression: self expression.
ToolBuilder default class setBoundsForWindow: window to: currentBounds.!
Item was added:
+ ----- Method: MessageSet>>initialExtentKey (in category 'initialize-release') -----
+ initialExtentKey
+
+ ^ { self class name . windowLabel hash}!
Item was changed:
----- Method: ObjectExplorer>>inspectObject (in category 'toolbuilder') -----
inspectObject
"Switch to an inspector tool."
| window currentBounds |
+ RealEstateAgent rememberExtentFor: self.
currentBounds := ToolBuilder findDefault getBoundsForWindow: self containingWindow.
"Close first because MVC fiddles around with processes."
self changed: #close.
window := ToolSet inspect: self rootObject.
"---- In MVC, the lines after this will not be executed ---"
window model setExpression: self expression.
ToolBuilder findDefault setBoundsForWindow: window to: currentBounds.!
Marcel Taeumel uploaded a new version of ST80 to project The Trunk:
http://source.squeak.org/trunk/ST80-mt.289.mcz
==================== Summary ====================
Name: ST80-mt.289
Author: mt
Time: 20 January 2023, 6:49:19.776382 pm
UUID: 9be26961-243c-2649-bb65-e850b7ce8afc
Ancestors: ST80-mt.288
Complements System-mt.1385
=============== Diff against ST80-mt.288 ===============
Item was added:
+ ----- Method: StandardSystemView>>extent (in category 'framing compatibility') -----
+ extent
+
+ ^ self viewport extent!
Item was changed:
+ ----- Method: StandardSystemView>>initialExtent (in category 'framing compatibility') -----
- ----- Method: StandardSystemView>>initialExtent (in category 'framing') -----
initialExtent
"Answer the desired extent for the receiver when it is first opened on the screen. "
^ model initialExtent min: maximumSize max: minimumSize!
Item was changed:
----- Method: StandardSystemView>>release (in category 'initialize-release') -----
release
+ RealEstateAgent rememberExtentFor: model.
model windowIsClosing; release.
self isCollapsed ifTrue: [savedSubViews do: [:v | v release]].
super release.
!