VDBStartup.st
changeset 107 d98c11f9a7f5
parent 83 101ff2210613
child 116 d0d6da74ead3
equal deleted inserted replaced
106:2a95c11eb590 107:d98c11f9a7f5
       
     1 "
       
     2 jv:vdb - Visual / VM Debugger
       
     3 Copyright (C) 2015-now Jan Vrany
       
     4 
       
     5 This software is licensed under 'Creative Commons Attribution-NonCommercial 4.0 International License'
       
     6 
       
     7 You may find a full license text in LICENSE.txt or at http://creativecommons.org/licenses/by-nc/4.0/
       
     8 "
       
     9 "{ Package: 'jv:vdb/application' }"
       
    10 
       
    11 "{ NameSpace: Smalltalk }"
       
    12 
       
    13 StandaloneStartup subclass:#VDBStartup
       
    14 	instanceVariableNames:''
       
    15 	classVariableNames:''
       
    16 	poolDictionaries:''
       
    17 	category:'VDB-UI'
       
    18 !
       
    19 
       
    20 !VDBStartup class methodsFor:'documentation'!
       
    21 
       
    22 copyright
       
    23 "
       
    24 jv:vdb - Visual / VM Debugger
       
    25 Copyright (C) 2015-now Jan Vrany
       
    26 
       
    27 This software is licensed under 'Creative Commons Attribution-NonCommercial 4.0 International License'
       
    28 
       
    29 You may find a full license text in LICENSE.txt or at http://creativecommons.org/licenses/by-nc/4.0/
       
    30 "
       
    31 ! !
       
    32 
       
    33 !VDBStartup class methodsFor:'constants & defaults'!
       
    34 
       
    35 applicationRegistryPath
       
    36     "the key under which this application stores its process ID in the registry
       
    37      as a collection of path-components.
       
    38      i.e. if #('foo' 'bar' 'baz') is returned here, the current applications ID will be stored
       
    39      in HKEY_CURRENT_USER\Software\foo\bar\baz\CurrentID.
       
    40      (would also be used as a relative path for a temporary lock file under unix).
       
    41      Used to detect if another instance of this application is already running."
       
    42 
       
    43     ^ #('vdb')
       
    44 
       
    45     "Modified: / 21-09-2014 / 01:29:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    46 !
       
    47 
       
    48 applicationUUID
       
    49     "answer an application-specific unique uuid.
       
    50      This is used as the name of some exclusive OS-resource, which is used to find out,
       
    51      if another instance of this application is already running.
       
    52      Under win32, a mutex is used; under unix, an exclusive file in the tempDir could be used.
       
    53      If redefined, please return a real UUID (i.e. UUID fromString:'.....') and not a string or
       
    54      similar possibly conflicting identifier.
       
    55      You can paste a fresh worldwide unique id via the editor's more-misc-paste UUID menuFunction."
       
    56 
       
    57     ^ UUID fromString:'57b09330-4126-11e4-a80f-606720e43e2c'
       
    58 
       
    59     "Modified: / 21-09-2014 / 01:29:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    60 ! !
       
    61 
       
    62 !VDBStartup class methodsFor:'defaults'!
       
    63 
       
    64 allowDebugOption
       
    65     "enable/disable the --debug startup option.
       
    66      Can be redefined in subclasses to enable it"
       
    67 
       
    68     ^ true
       
    69 
       
    70     "Created: / 08-09-2014 / 19:30:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    71 ! !
       
    72 
       
    73 !VDBStartup class methodsFor:'private'!
       
    74 
       
    75 loadPreferenceFile: file
       
    76 
       
    77     "Created: / 07-06-2017 / 09:49:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    78 ! !
       
    79 
       
    80 !VDBStartup class methodsFor:'queries'!
       
    81 
       
    82 applicationName
       
    83     ^ 'vdb'
       
    84 
       
    85     "Created: / 06-06-2017 / 22:50:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    86 ! !
       
    87 
       
    88 !VDBStartup class methodsFor:'startup'!
       
    89 
       
    90 main:argv
       
    91     "Application entry point. `argv` is the array of command arguments (as Array of Strings)"
       
    92 
       
    93     | optparser positional settingsFile settingsSuppressed replay 
       
    94       programExecutable programArgs programPid attach 
       
    95       debugger debuggerApp |
       
    96 
       
    97     settingsSuppressed := false.
       
    98     replay := false.
       
    99     attach := false.
       
   100 
       
   101     "/ Parse options...
       
   102     optparser := CmdLineParser new
       
   103                     ignoreUnknownOptions: true;
       
   104                     on: #('--help') do:[
       
   105                         self usage
       
   106                     ];
       
   107                     on: #('--preferences') do:[:filename |
       
   108                         | file |
       
   109 
       
   110                         file := filename asFilename.
       
   111                         file isReadable ifFalse:[
       
   112                             self error: 'preference file does not exists or not readable: ' , filename.
       
   113                         ].
       
   114                         file isRegularFile ifFalse:[
       
   115                             self error: 'preference file is not a regular file: ' , filename.
       
   116                         ].
       
   117                         settingsFile := file.
       
   118                     ];
       
   119                     on: #('--no-preferences') do:[
       
   120                         settingsSuppressed := true
       
   121                     ];
       
   122                     on: #('--replay') do:[
       
   123                         replay := true
       
   124                     ];
       
   125                     yourself.
       
   126     [
       
   127         positional := optparser parse:argv.
       
   128     ] on: CmdLineOptionError do:[:ex |
       
   129         self error: ex description.
       
   130     ].
       
   131 
       
   132 
       
   133     "/ Now validate and process options
       
   134     settingsSuppressed ifFalse:[
       
   135         | settings |
       
   136 
       
   137         settingsFile notNil ifTrue:[
       
   138             settingsFile exists ifFalse:[
       
   139                 self error: 'preference file does not exist: ', settingsFile pathName
       
   140             ].
       
   141             settingsFile isDirectory ifTrue:[
       
   142                 self error: 'preference file is not a regular file: ', settingsFile pathName
       
   143             ].
       
   144             settingsFile isReadable ifFalse:[
       
   145                 self error: 'preference file is not a readable (check permissions): ', settingsFile pathName
       
   146             ].
       
   147             settings := UserPreferences loadSettingsFrom: settingsFile.
       
   148         ] ifFalse:[
       
   149             settings := UserPreferences loadSettings.
       
   150         ].
       
   151         UserPreferences setCurrent: settings.
       
   152     ].
       
   153 
       
   154     replay ifTrue:[ 
       
   155         OperatingSystem isLinuxLike ifFalse:[ 
       
   156             self error: 'replay not supported on this platform'.
       
   157         ].
       
   158         RR available ifFalse:[ 
       
   159             self error: 'cannot replay because rr not available'
       
   160         ].
       
   161     ].
       
   162 
       
   163     "/ Parse positional arguments - there are two forms:
       
   164     "/
       
   165     "/   vdb [OPTIONS] [PROGRAM [ARGS]]
       
   166     "/   vdb [OPTIONS] [PID]
       
   167     "/
       
   168     "/ [OPTIONS] have already been processed, the rest is in `positional`
       
   169     "/ variable
       
   170 
       
   171     positional notEmpty ifTrue:[
       
   172         programExecutable := positional first.
       
   173         programExecutable asFilename exists ifFalse:[
       
   174             "Try to find the executable in PATH..."
       
   175 
       
   176             | path |
       
   177 
       
   178             path := OperatingSystem pathOfCommand: programExecutable.
       
   179             path notNil ifTrue:[
       
   180                 programExecutable := path.
       
   181             ].
       
   182         ].
       
   183         programPid := Integer fromString: positional first onError: [ nil ].
       
   184         programArgs := positional copyFrom: 2.
       
   185 
       
   186         replay ifTrue:[ 
       
   187             programArgs notEmptyOrNil ifTrue:[ 
       
   188                 self error: 'cannot specify program args when replaying'.
       
   189             ].
       
   190         ] ifFalse:[
       
   191             "/ If * programExecutable does not exists
       
   192             "/    * AND programPid is not nil (i.e., first positional argument can be converted to an integer)
       
   193             "/    * AND programArguments are empty
       
   194             "/ then interpret positional argument as PID and attach to it.
       
   195             "/ Otherwise, interpret positional arguments
       
   196             (programExecutable asFilename exists not and: [ programPid notNil and: [ programArgs isEmpty ]]) ifTrue:[
       
   197                 attach := true.
       
   198             ] ifFalse:[
       
   199                 programExecutable asFilename exists ifFalse:[
       
   200                     self error: 'cannot find program executable: ', programExecutable.
       
   201                 ].
       
   202             ].
       
   203         ].
       
   204     ].
       
   205 
       
   206     Debugger := DebugView ? MiniDebugger.
       
   207     Inspector := InspectorView ? MiniInspector.
       
   208 
       
   209     debugger := GDBDebugger new.
       
   210     attach ifTrue:[
       
   211         debugger attach: programPid
       
   212     ] ifFalse:[
       
   213         programExecutable notNil ifTrue:[
       
   214             debugger executable: programExecutable arguments: programArgs.
       
   215         ].
       
   216     ].
       
   217     Smalltalk openDisplay.
       
   218     debuggerApp := VDBDebuggerApplication new.
       
   219     debuggerApp debugger: debugger.
       
   220     debuggerApp open.
       
   221     replay ifTrue:[ 
       
   222         debuggerApp doAttachToRR
       
   223     ]. 
       
   224 
       
   225     "
       
   226         VDBStartup main: #()
       
   227         VDBStartup main: #('ls')
       
   228         VDBStartup main: #('/bin/ls' '/tmp')
       
   229     "
       
   230 
       
   231     "Modified: / 29-07-2018 / 08:51:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   232 !
       
   233 
       
   234 usage
       
   235     Stdout nextPutAll:'usage: '; nextPutAll: self applicationName; nextPutAll: ' [OPTIONS] [PROGRAM [ARGS]] '; cr.
       
   236     Stdout nextPutAll:'       '; nextPutAll: self applicationName; nextPutAll: ' [OPTIONS] [PID]'; cr.
       
   237                                                                           "|"
       
   238     Stdout nextPutLine:'
       
   239 options:
       
   240  --replay ..................... replay last rr record
       
   241  --preference FILE ............ read user settings from FILE
       
   242  --no-preferences ............. do not read user settings at all
       
   243  --help ....................... output this message
       
   244 '.
       
   245 
       
   246     Smalltalk exitIfStandalone: 0.
       
   247 
       
   248     "Modified: / 29-07-2018 / 08:55:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   249 ! !
       
   250 
       
   251 !VDBStartup class methodsFor:'documentation'!
       
   252 
       
   253 version_HG
       
   254 
       
   255     ^ '$Changeset: <not expanded> $'
       
   256 ! !
       
   257