|
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 |