application/VDBStartup.st
changeset 43 c98aa29401f7
parent 37 f417fe8685c5
child 47 25d82943a3cf
--- a/application/VDBStartup.st	Fri Jun 02 07:42:04 2017 +0100
+++ b/application/VDBStartup.st	Thu Jun 08 14:16:29 2017 +0100
@@ -50,23 +50,145 @@
     "Created: / 08-09-2014 / 19:30:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+!VDBStartup class methodsFor:'private'!
+
+loadPreferenceFile: file
+
+    "Created: / 07-06-2017 / 09:49:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VDBStartup class methodsFor:'queries'!
+
+applicationName
+    ^ 'vdb'
+
+    "Created: / 06-06-2017 / 22:50:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !VDBStartup class methodsFor:'startup'!
 
 main:argv
-    | gdb |
+    "Application entry point. `argv` is the array of command arguments (as Array of Strings)"
+
+    | optparser positional settingsFile settingsSuppressed programExecutable programArgs programPid attach debugger |
+
+    settingsSuppressed := false.
+
+    "/ Parse options...
+    optparser := CmdLineParser new
+                    ignoreUnknownOptions: true;
+                    on: #('--help') do:[ 
+                        self usage 
+                    ];
+                    on: #('--preferences') do:[:filename | 
+                        | file |
+
+                        file := filename asFilename.
+                        file isReadable ifFalse:[ 
+                            self error: 'preference file does not exists or not readable: ' , filename.
+                        ].
+                        file isRegularFile ifFalse:[ 
+                            self error: 'preference file is not a regular file: ' , filename.
+                        ].
+                        settingsFile := Array with: file 
+                    ];
+                    on: #('--no-preferences') do:[ 
+                        settingsSuppressed := #() 
+                    ];
+                    yourself.
+    [
+        positional := optparser parse:argv.
+    ] on: CmdLineOptionError do:[:ex |
+        self error: ex description.
+    ].
+
+    "/ Parse positional arguments - there are two forms:
+    "/
+    "/   vdb [OPTIONS] PROGRAM [ARGS] 
+    "/   vdb [OPTIONS] PID
+    "/ 
+    "/ [OPTIONS] have already been processed, the rest is in `positional`
+    "/ variable
 
+    positional isEmpty ifTrue:[ 
+        self error: 'no executable (or PID to attach) given'
+    ].
+    programExecutable := positional first.
+    programExecutable asFilename exists ifFalse:[ 
+        programExecutable := OperatingSystem pathOfCommand: programExecutable.
+    ].
+    programPid := Integer fromString: positional first onError: [ nil ].
+    programArgs := positional copyFrom: 2.
+
+    "/ Now validate and process options
+    settingsSuppressed ifFalse:[ 
+        | settings |
+
+        settingsFile notNil ifTrue:[ 
+            settingsFile exists ifFalse:[
+                self error: 'preference file does not exist: ', settingsFile pathName
+            ].
+            settingsFile isDirectory ifTrue:[
+                self error: 'preference file is not a regular file: ', settingsFile pathName
+            ].
+            settingsFile isReadable ifFalse:[
+                self error: 'preference file is not a readable (check permissions): ', settingsFile pathName
+            ].    
+            settings := UserPreferences loadSettingsFrom: settingsFile.  
+        ] ifFalse:[ 
+            settings := UserPreferences loadSettings.
+        ].
+        UserPreferences setCurrent: settings.
+    ].
+
+    "/ If * programExecutable does not exists 
+    "/    * AND programPid is not nil (i.e., first positional argument can be converted to an integer)
+    "/    * AND programArguments are empty 
+    "/ then interpret positional argument as PID and attach to it.
+    "/ Otherwise, interpret positional arguments
+    (programExecutable asFilename exists not and: [ programPid notNil and: [ programArgs isEmpty ]]) ifTrue:[ 
+        attach := true.
+    ] ifFalse:[ 
+        attach := false.
+        programExecutable asFilename exists ifFalse:[ 
+            self error: 'cannot find program executable: ', programExecutable.
+        ].
+    ].
+    Debugger := DebugView ? MiniDebugger.
+    Inspector := InspectorView ? MiniInspector. 
+
+    debugger := GDBDebugger new.
+    attach ifTrue:[ 
+        debugger attach: programPid
+    ] ifFalse:[ 
+        debugger executable: programExecutable arguments: programArgs.
+    ].
     Smalltalk openDisplay.
-    gdb := GDBDebugger new.
-    VDBDebuggerApplication openFor: gdb.
+    VDBDebuggerApplication openFor: debugger.
+
 
-    "Modified: / 21-09-2014 / 01:31:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "
+        VDBStartup main: #('ls')
+        VDBStartup main: #('/bin/ls' '/tmp')               
+    "
+
+    "Modified: / 08-06-2017 / 13:09:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 usage
-    Stderr nextPutLine:'usage: ',self applicationName,' [options...]'.
-    Stderr nextPutLine:'  -h .................. output this message'.
+    Stdout nextPutAll:'usage: '; nextPutAll: self applicationName; nextPutAll: ' [OPTIONS] PROGRAM [ARGS] '; cr.
+    Stdout nextPutAll:'       '; nextPutAll: self applicationName; nextPutAll: ' [OPTIONS] PID'; cr.
+                                                                          "|"
+    Stdout nextPutLine:'                                             
+options:
+ --settings FILE .............. read user settings from FILE
+ --no-settings ................ do not read user settings at all
+ --help ....................... output this message
+'.
 
-    Smalltalk isStandAloneApp ifTrue:[ Smalltalk exit:1 ].
+    Smalltalk exitIfStandalone: 0.
+
+    "Modified: / 07-06-2017 / 09:04:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !VDBStartup class methodsFor:'documentation'!