Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/REPLRemoteCommand.java @ 21568:3b8bbf51d320
Truffle/Debugging: add the Truffle DebugEngine and supporting code, as well as add a crude command-line debugging tool used mainly to test the DebugEngine. Migrate the small tols out of project com.oracle.truffle.api into the new project com.oracle.truffle.tools.
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Tue, 26 May 2015 16:38:13 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
21470:1bbef57f9a38 | 21568:3b8bbf51d320 |
---|---|
1 /* | |
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. Oracle designates this | |
8 * particular file as subject to the "Classpath" exception as provided | |
9 * by Oracle in the LICENSE file that accompanied this code. | |
10 * | |
11 * This code is distributed in the hope that it will be useful, but WITHOUT | |
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 * version 2 for more details (a copy is included in the LICENSE file that | |
15 * accompanied this code). | |
16 * | |
17 * You should have received a copy of the GNU General Public License version | |
18 * 2 along with this work; if not, write to the Free Software Foundation, | |
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
20 * | |
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
22 * or visit www.oracle.com if you need additional information or have any | |
23 * questions. | |
24 */ | |
25 package com.oracle.truffle.tools.debug.shell.client; | |
26 | |
27 import java.io.*; | |
28 import java.util.*; | |
29 | |
30 import com.oracle.truffle.api.source.*; | |
31 import com.oracle.truffle.tools.debug.shell.*; | |
32 | |
33 // TODO (mlvdv) write a real command line parser | |
34 public abstract class REPLRemoteCommand extends REPLCommand { | |
35 | |
36 public REPLRemoteCommand(String command, String abbreviation, String description) { | |
37 super(command, abbreviation, description); | |
38 } | |
39 | |
40 protected abstract REPLMessage createRequest(REPLClientContext context, String[] args); | |
41 | |
42 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
43 REPLMessage firstReply = replies[0]; | |
44 | |
45 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { | |
46 final String result = firstReply.get(REPLMessage.DISPLAY_MSG); | |
47 context.displayFailReply(result != null ? result : firstReply.toString()); | |
48 } else { | |
49 final String result = firstReply.get(REPLMessage.DISPLAY_MSG); | |
50 context.displayReply(result != null ? result : firstReply.toString()); | |
51 } | |
52 | |
53 for (int i = 1; i < replies.length; i++) { | |
54 REPLMessage reply = replies[i]; | |
55 final String result = reply.get(REPLMessage.DISPLAY_MSG); | |
56 context.displayInfo(result != null ? result : reply.toString()); | |
57 } | |
58 } | |
59 | |
60 public static final REPLRemoteCommand BREAK_AT_LINE_CMD = new REPLRemoteCommand("break-at-line", "break", "Set a breakpoint") { | |
61 | |
62 private final String[] help = {"break <n> [ignore=<n>] : set breakpoint at line <n> in current file", "break <filename>:<n> [ignore=<n>] : set breakpoint at line <n> in <filename>", | |
63 " optionally ignore first <n> hits (default 0)"}; | |
64 | |
65 @Override | |
66 public String[] getHelp() { | |
67 return help; | |
68 } | |
69 | |
70 @Override | |
71 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
72 try { | |
73 final REPLineLocation lineLocation = REPLineLocation.parse(context, args); | |
74 final REPLMessage requestMessage = lineLocation.createMessage(REPLMessage.BREAK_AT_LINE); | |
75 int ignoreCount = 0; | |
76 if (args.length > 2) { | |
77 final String ignoreText = args[2]; | |
78 if (ignoreText.equals("ignore")) { | |
79 throw new IllegalArgumentException("No ignore count specified"); | |
80 } | |
81 final String[] split = ignoreText.split("="); | |
82 if (split.length == 2 && split[0].equals("ignore")) { | |
83 try { | |
84 ignoreCount = Integer.parseInt(split[1]); | |
85 if (ignoreCount < 0) { | |
86 throw new IllegalArgumentException("Illegal ignore count: " + split[1]); | |
87 } | |
88 } catch (NumberFormatException e) { | |
89 throw new IllegalArgumentException("No ignore count specified"); | |
90 } | |
91 } else { | |
92 throw new IllegalArgumentException("Unrecognized argument \"" + ignoreText + "\""); | |
93 } | |
94 } | |
95 requestMessage.put(REPLMessage.BREAKPOINT_IGNORE_COUNT, Integer.toString(ignoreCount)); | |
96 return requestMessage; | |
97 } catch (IllegalArgumentException ex) { | |
98 context.displayFailReply(ex.getMessage()); | |
99 } | |
100 return null; | |
101 } | |
102 | |
103 @Override | |
104 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
105 REPLMessage firstReply = replies[0]; | |
106 | |
107 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { | |
108 final String number = firstReply.get(REPLMessage.BREAKPOINT_ID); | |
109 final String fileName = firstReply.get(REPLMessage.SOURCE_NAME); | |
110 final String lineNumber = firstReply.get(REPLMessage.LINE_NUMBER); | |
111 firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + number + " set at " + fileName + ":" + lineNumber); | |
112 } | |
113 super.processReply(context, replies); | |
114 } | |
115 }; | |
116 | |
117 public static final REPLRemoteCommand BREAK_AT_LINE_ONCE_CMD = new REPLRemoteCommand("break-at-line-once", "break1", "Set a one-shot breakpoint") { | |
118 | |
119 private final String[] help = {"break <n>: set one-shot breakpoint at line <n> in current file", "break <filename>:<n>: set one-shot breakpoint at line <n> in current file"}; | |
120 | |
121 @Override | |
122 public String[] getHelp() { | |
123 return help; | |
124 } | |
125 | |
126 @Override | |
127 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
128 try { | |
129 return REPLineLocation.parse(context, args).createMessage(REPLMessage.BREAK_AT_LINE_ONCE); | |
130 } catch (IllegalArgumentException ex) { | |
131 context.displayFailReply(ex.getMessage()); | |
132 } | |
133 return null; | |
134 } | |
135 | |
136 @Override | |
137 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
138 REPLMessage firstReply = replies[0]; | |
139 | |
140 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { | |
141 final String fileName = firstReply.get(REPLMessage.SOURCE_NAME); | |
142 final String lineNumber = firstReply.get(REPLMessage.LINE_NUMBER); | |
143 firstReply.put(REPLMessage.DISPLAY_MSG, "one-shot breakpoint set at " + fileName + ":" + lineNumber); | |
144 } | |
145 super.processReply(context, replies); | |
146 } | |
147 }; | |
148 | |
149 public static final REPLRemoteCommand BREAK_AT_THROW_CMD = new REPLRemoteCommand("break-at-throw", "breakthrow", "Break at any throw") { | |
150 | |
151 private final String[] help = {"break-at-throw: set breakpoint on any throw"}; | |
152 | |
153 @Override | |
154 public String[] getHelp() { | |
155 return help; | |
156 } | |
157 | |
158 @Override | |
159 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
160 final REPLMessage request = new REPLMessage(); | |
161 request.put(REPLMessage.OP, REPLMessage.BREAK_AT_THROW); | |
162 return request; | |
163 } | |
164 | |
165 @Override | |
166 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
167 REPLMessage firstReply = replies[0]; | |
168 | |
169 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { | |
170 firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint at any throw set"); | |
171 } | |
172 super.processReply(context, replies); | |
173 } | |
174 }; | |
175 | |
176 public static final REPLRemoteCommand BREAK_AT_THROW_ONCE_CMD = new REPLRemoteCommand("break-at-throw-once", "break1throw", "Break once at any throw") { | |
177 | |
178 private final String[] help = {"break-at-throw: set one-short breakpoint on any throw"}; | |
179 | |
180 @Override | |
181 public String[] getHelp() { | |
182 return help; | |
183 } | |
184 | |
185 @Override | |
186 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
187 final REPLMessage request = new REPLMessage(); | |
188 request.put(REPLMessage.OP, REPLMessage.BREAK_AT_THROW_ONCE); | |
189 return request; | |
190 } | |
191 | |
192 @Override | |
193 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
194 REPLMessage firstReply = replies[0]; | |
195 | |
196 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { | |
197 firstReply.put(REPLMessage.DISPLAY_MSG, "one-shot breakpoint at any throw set"); | |
198 } | |
199 super.processReply(context, replies); | |
200 } | |
201 }; | |
202 | |
203 public static final REPLRemoteCommand CLEAR_BREAK_CMD = new REPLRemoteCommand("clear", null, "Clear a breakpoint") { | |
204 | |
205 private final String[] help = {"clear <n>: clear breakpoint number <n>"}; | |
206 | |
207 @Override | |
208 public String[] getHelp() { | |
209 return help; | |
210 } | |
211 | |
212 @Override | |
213 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
214 if (args.length == 1) { | |
215 context.displayFailReply("breakpoint number not speciified: \"break <n>\""); | |
216 } else if (args.length > 2) { | |
217 context.displayFailReply("breakpoint number not understood: \"break <n>\""); | |
218 } else { | |
219 try { | |
220 final int breakpointNumber = Integer.parseInt(args[1]); | |
221 final REPLMessage request = new REPLMessage(); | |
222 request.put(REPLMessage.OP, REPLMessage.CLEAR_BREAK); | |
223 request.put(REPLMessage.BREAKPOINT_ID, Integer.toString(breakpointNumber)); | |
224 return request; | |
225 } catch (IllegalArgumentException ex) { | |
226 context.displayFailReply(ex.getMessage()); | |
227 } | |
228 } | |
229 return null; | |
230 } | |
231 | |
232 @Override | |
233 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
234 REPLMessage firstReply = replies[0]; | |
235 | |
236 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { | |
237 final int breakpointNumber = firstReply.getIntValue(REPLMessage.BREAKPOINT_ID); | |
238 firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + breakpointNumber + " cleared"); | |
239 } | |
240 super.processReply(context, replies); | |
241 } | |
242 }; | |
243 | |
244 public static final REPLRemoteCommand CONDITION_BREAK_CMD = new REPLRemoteCommand("cond", null, "Set new condition on a breakpoint") { | |
245 | |
246 private final String[] help = {"cond <n> [expr]: sets new condition on breakpoint number <n>; make unconditional if no [expr]"}; | |
247 | |
248 @Override | |
249 public String[] getHelp() { | |
250 return help; | |
251 } | |
252 | |
253 @Override | |
254 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
255 if (args.length == 1) { | |
256 context.displayFailReply("breakpoint number not speciified: \"cond <n>\""); | |
257 } else { | |
258 try { | |
259 final int breakpointNumber = Integer.parseInt(args[1]); | |
260 final REPLMessage request = new REPLMessage(); | |
261 request.put(REPLMessage.BREAKPOINT_ID, Integer.toString(breakpointNumber)); | |
262 if (args.length == 2) { | |
263 request.put(REPLMessage.OP, REPLMessage.UNSET_BREAK_CONDITION); | |
264 } else { | |
265 final StringBuilder exprBuilder = new StringBuilder(); | |
266 for (int i = 2; i < args.length; i++) { | |
267 exprBuilder.append(args[i]).append(" "); | |
268 } | |
269 request.put(REPLMessage.BREAKPOINT_CONDITION, exprBuilder.toString().trim()); | |
270 request.put(REPLMessage.OP, REPLMessage.SET_BREAK_CONDITION); | |
271 } | |
272 return request; | |
273 } catch (IllegalArgumentException ex) { | |
274 context.displayFailReply(ex.getMessage()); | |
275 } | |
276 } | |
277 return null; | |
278 } | |
279 | |
280 @Override | |
281 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
282 REPLMessage firstReply = replies[0]; | |
283 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { | |
284 final int breakpointNumber = firstReply.getIntValue(REPLMessage.BREAKPOINT_ID); | |
285 final String condition = firstReply.get(REPLMessage.BREAKPOINT_CONDITION); | |
286 if (condition == null) { | |
287 firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + breakpointNumber + " condition cleared"); | |
288 } else { | |
289 firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + breakpointNumber + " condition=\"" + condition + "\""); | |
290 } | |
291 } | |
292 super.processReply(context, replies); | |
293 } | |
294 }; | |
295 | |
296 public static final REPLRemoteCommand CONTINUE_CMD = new REPLRemoteCommand("continue", "c", "Continue execution") { | |
297 | |
298 @Override | |
299 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
300 if (context.level() == 0) { | |
301 context.displayFailReply("no active execution"); | |
302 return null; | |
303 } | |
304 final REPLMessage request = new REPLMessage(); | |
305 request.put(REPLMessage.OP, REPLMessage.CONTINUE); | |
306 return request; | |
307 } | |
308 | |
309 @Override | |
310 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
311 | |
312 throw new REPLContinueException(); | |
313 | |
314 } | |
315 }; | |
316 | |
317 public static final REPLRemoteCommand DELETE_CMD = new REPLRemoteCommand("delete", "d", "Delete all breakpoints") { | |
318 | |
319 @Override | |
320 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
321 final REPLMessage request = new REPLMessage(); | |
322 request.put(REPLMessage.OP, REPLMessage.DELETE_BREAK); | |
323 return request; | |
324 } | |
325 }; | |
326 | |
327 public static final REPLRemoteCommand DISABLE_CMD = new REPLRemoteCommand("disable", null, "Disable a breakpoint") { | |
328 | |
329 private final String[] help = {"disable <n>: disable breakpoint number <n>"}; | |
330 | |
331 @Override | |
332 public String[] getHelp() { | |
333 return help; | |
334 } | |
335 | |
336 @Override | |
337 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
338 if (args.length == 1) { | |
339 context.displayFailReply("breakpoint number not speciified: \"disable <n>\""); | |
340 } else if (args.length > 2) { | |
341 context.displayFailReply("breakpoint number not understood: \"disable <n>\""); | |
342 } else { | |
343 try { | |
344 final int breakpointNumber = Integer.parseInt(args[1]); | |
345 final REPLMessage request = new REPLMessage(); | |
346 request.put(REPLMessage.OP, REPLMessage.DISABLE_BREAK); | |
347 request.put(REPLMessage.BREAKPOINT_ID, Integer.toString(breakpointNumber)); | |
348 return request; | |
349 } catch (IllegalArgumentException ex) { | |
350 context.displayFailReply(ex.getMessage()); | |
351 } | |
352 } | |
353 return null; | |
354 } | |
355 | |
356 @Override | |
357 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
358 REPLMessage firstReply = replies[0]; | |
359 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { | |
360 final int breakpointNumber = firstReply.getIntValue(REPLMessage.BREAKPOINT_ID); | |
361 firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + breakpointNumber + " disabled"); | |
362 } | |
363 super.processReply(context, replies); | |
364 } | |
365 }; | |
366 | |
367 public static final REPLRemoteCommand DOWN_CMD = new REPLRemoteCommand("down", null, "Move down a stack frame") { | |
368 | |
369 @Override | |
370 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
371 if (context.level() == 0) { | |
372 context.displayFailReply("no active execution"); | |
373 return null; | |
374 } | |
375 final List<REPLFrame> frames = context.frames(); | |
376 final int newFrameSelection = context.getSelectedFrameNumber() + 1; | |
377 if (newFrameSelection > frames.size() - 1) { | |
378 context.displayFailReply("at bottom of stack"); | |
379 return null; | |
380 } | |
381 context.selectFrameNumber(newFrameSelection); | |
382 return FRAME_CMD.createRequest(context, Arrays.copyOfRange(args, 0, 0)); | |
383 } | |
384 | |
385 @Override | |
386 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
387 REPLMessage firstReply = replies[0]; | |
388 | |
389 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { | |
390 final String result = firstReply.get(REPLMessage.DISPLAY_MSG); | |
391 context.displayFailReply(result != null ? result : firstReply.toString()); | |
392 } else { | |
393 context.displayStack(); | |
394 } | |
395 } | |
396 }; | |
397 | |
398 public static final REPLRemoteCommand ENABLE_CMD = new REPLRemoteCommand("enable", null, "Enable a breakpoint") { | |
399 | |
400 private final String[] help = {"enable <n>: enable breakpoint number <n>"}; | |
401 | |
402 @Override | |
403 public String[] getHelp() { | |
404 return help; | |
405 } | |
406 | |
407 @Override | |
408 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
409 if (args.length == 1) { | |
410 context.displayFailReply("breakpoint number not speciified: \"enable <n>\""); | |
411 } else if (args.length > 2) { | |
412 context.displayFailReply("breakpoint number not understood: \"enable <n>\""); | |
413 } else { | |
414 try { | |
415 final int breakpointNumber = Integer.parseInt(args[1]); | |
416 final REPLMessage request = new REPLMessage(); | |
417 request.put(REPLMessage.OP, REPLMessage.ENABLE_BREAK); | |
418 request.put(REPLMessage.BREAKPOINT_ID, Integer.toString(breakpointNumber)); | |
419 return request; | |
420 } catch (IllegalArgumentException ex) { | |
421 context.displayFailReply(ex.getMessage()); | |
422 } | |
423 } | |
424 return null; | |
425 } | |
426 | |
427 @Override | |
428 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
429 REPLMessage firstReply = replies[0]; | |
430 | |
431 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { | |
432 final int breakpointNumber = firstReply.getIntValue(REPLMessage.BREAKPOINT_ID); | |
433 firstReply.put(REPLMessage.DISPLAY_MSG, "breakpoint " + breakpointNumber + " enabled"); | |
434 } | |
435 super.processReply(context, replies); | |
436 } | |
437 }; | |
438 | |
439 public static final REPLRemoteCommand FRAME_CMD = new REPLRemoteCommand("frame", null, "Display a stack frame") { | |
440 | |
441 private final String[] help = {"frame : display currently selected frame", "frame <n> : display frame <n>"}; | |
442 | |
443 @Override | |
444 public String[] getHelp() { | |
445 return help; | |
446 } | |
447 | |
448 @Override | |
449 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
450 if (context.level() == 0) { | |
451 context.displayFailReply("no active execution"); | |
452 return null; | |
453 } | |
454 final REPLMessage request = new REPLMessage(); | |
455 request.put(REPLMessage.OP, REPLMessage.FRAME); | |
456 | |
457 int frameNumber = context.getSelectedFrameNumber(); | |
458 if (args.length > 1) { | |
459 if (args.length == 2) { | |
460 try { | |
461 frameNumber = Integer.parseInt(args[1]); | |
462 } catch (NumberFormatException e) { | |
463 throw new IllegalArgumentException("Unrecognized argument \"" + args[1] + "\""); | |
464 } | |
465 } else { | |
466 throw new IllegalArgumentException("Unrecognized argument \"" + args[2] + "\""); | |
467 } | |
468 } | |
469 request.put(REPLMessage.FRAME_NUMBER, Integer.toString(frameNumber)); | |
470 return request; | |
471 } | |
472 | |
473 @Override | |
474 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
475 if (replies[0].get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { | |
476 context.displayFailReply(replies[0].get(REPLMessage.DISPLAY_MSG)); | |
477 } else { | |
478 Integer frameNumber = replies[0].getIntValue(REPLMessage.FRAME_NUMBER); | |
479 context.selectFrameNumber(frameNumber); | |
480 context.displayReply("Frame " + frameNumber + ":"); | |
481 for (REPLMessage message : replies) { | |
482 for (String line : message.get(REPLMessage.DISPLAY_MSG).split("\n")) { | |
483 context.displayInfo(line); | |
484 } | |
485 } | |
486 } | |
487 } | |
488 }; | |
489 | |
490 public static final REPLRemoteCommand KILL_CMD = new REPLRemoteCommand("kill", null, "Stop program execution") { | |
491 | |
492 @Override | |
493 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
494 if (context.level() == 0) { | |
495 context.displayFailReply("no active execution"); | |
496 return null; | |
497 } | |
498 final REPLMessage request = new REPLMessage(); | |
499 request.put(REPLMessage.OP, "kill"); | |
500 return request; | |
501 } | |
502 | |
503 @Override | |
504 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
505 if (replies[0].get(REPLMessage.STATUS).equals(REPLMessage.SUCCEEDED)) { | |
506 context.displayReply(replies[0].get(REPLMessage.DISPLAY_MSG)); | |
507 } else { | |
508 context.displayFailReply(replies[0].get(REPLMessage.DISPLAY_MSG)); | |
509 } | |
510 } | |
511 }; | |
512 | |
513 public static final REPLRemoteCommand LOAD_RUN_CMD = new REPLRemoteCommand("load-run", "loadr", "Load and run a source") { | |
514 | |
515 @Override | |
516 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
517 Source runSource = null; | |
518 if (args.length == 1) { | |
519 runSource = context.getSelectedSource(); | |
520 if (runSource == null) { | |
521 context.displayFailReply("No file selected"); | |
522 return null; | |
523 } | |
524 } else { | |
525 try { | |
526 runSource = Source.fromFileName(args[1]); | |
527 } catch (IOException e) { | |
528 context.displayFailReply("Can't find file: " + args[1]); | |
529 return null; | |
530 } | |
531 } | |
532 final REPLMessage request = new REPLMessage(); | |
533 request.put(REPLMessage.OP, REPLMessage.LOAD_RUN); | |
534 request.put(REPLMessage.SOURCE_NAME, runSource.getPath()); | |
535 return request; | |
536 } | |
537 }; | |
538 | |
539 public static final REPLRemoteCommand LOAD_STEP_CMD = new REPLRemoteCommand("load-step", "loads", "Load and step into a source") { | |
540 | |
541 @Override | |
542 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
543 Source runSource = null; | |
544 if (args.length == 1) { | |
545 runSource = context.getSelectedSource(); | |
546 if (runSource == null) { | |
547 context.displayFailReply("No file selected"); | |
548 return null; | |
549 } | |
550 } else { | |
551 try { | |
552 runSource = Source.fromFileName(args[1]); | |
553 } catch (IOException e) { | |
554 context.displayFailReply("Can't find file: " + args[1]); | |
555 return null; | |
556 } | |
557 } | |
558 final REPLMessage request = new REPLMessage(); | |
559 request.put(REPLMessage.OP, REPLMessage.LOAD_STEP); | |
560 request.put(REPLMessage.SOURCE_NAME, runSource.getPath()); | |
561 return request; | |
562 } | |
563 }; | |
564 | |
565 public static final REPLRemoteCommand STEP_INTO_CMD = new REPLRemoteCommand("step", "s", "(StepInto) next statement, going into functions.") { | |
566 | |
567 @Override | |
568 public String[] getHelp() { | |
569 return new String[]{"step into: step to next statement (into calls)", "step <n>: step to nth next statement (into calls)"}; | |
570 } | |
571 | |
572 @Override | |
573 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
574 if (context.level() == 0) { | |
575 context.displayFailReply("no active execution"); | |
576 return null; | |
577 } | |
578 final REPLMessage request = new REPLMessage(); | |
579 request.put(REPLMessage.OP, REPLMessage.STEP_INTO); | |
580 | |
581 if (args.length >= 2) { | |
582 final String nText = args[1]; | |
583 try { | |
584 final int nSteps = Integer.parseInt(nText); | |
585 if (nSteps > 0) { | |
586 request.put(REPLMessage.REPEAT, Integer.toString(nSteps)); | |
587 } else { | |
588 return null; | |
589 } | |
590 } catch (NumberFormatException e) { | |
591 context.displayFailReply("Step into count \"" + nText + "\" not recognized"); | |
592 return null; | |
593 } | |
594 } | |
595 return request; | |
596 } | |
597 | |
598 @Override | |
599 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
600 | |
601 throw new REPLContinueException(); | |
602 } | |
603 }; | |
604 | |
605 public static final REPLRemoteCommand STEP_OUT_CMD = new REPLRemoteCommand("finish", null, "(StepOut) continue to end of function") { | |
606 | |
607 @Override | |
608 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
609 if (context.level() == 0) { | |
610 context.displayFailReply("no active execution"); | |
611 return null; | |
612 } | |
613 final REPLMessage request = new REPLMessage(); | |
614 request.put(REPLMessage.OP, REPLMessage.STEP_OUT); | |
615 | |
616 return request; | |
617 } | |
618 | |
619 @Override | |
620 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
621 | |
622 throw new REPLContinueException(); | |
623 } | |
624 }; | |
625 | |
626 public static final REPLRemoteCommand STEP_OVER_CMD = new REPLRemoteCommand("next", "n", "(StepOver) execute next line of code, not into functions.") { | |
627 | |
628 @Override | |
629 public String[] getHelp() { | |
630 return new String[]{"next: (StepOver) execute next line of code, not into functions.", "next <n>: (StepOver) execute to nth next statement (not counting into functions)"}; | |
631 } | |
632 | |
633 @Override | |
634 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
635 if (context.level() == 0) { | |
636 context.displayFailReply("no active execution"); | |
637 return null; | |
638 } | |
639 final REPLMessage request = new REPLMessage(); | |
640 request.put(REPLMessage.OP, REPLMessage.STEP_OVER); | |
641 | |
642 if (args.length >= 2) { | |
643 final String nText = args[1]; | |
644 try { | |
645 final int nSteps = Integer.parseInt(nText); | |
646 if (nSteps > 0) { | |
647 request.put(REPLMessage.REPEAT, Integer.toString(nSteps)); | |
648 } else { | |
649 return null; | |
650 } | |
651 } catch (NumberFormatException e) { | |
652 context.displayFailReply("Next count \"" + nText + "\" not recognized"); | |
653 return null; | |
654 } | |
655 } | |
656 return request; | |
657 } | |
658 | |
659 @Override | |
660 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
661 | |
662 throw new REPLContinueException(); | |
663 } | |
664 }; | |
665 | |
666 public static final REPLRemoteCommand UP_CMD = new REPLRemoteCommand("up", null, "Move up a stack frame") { | |
667 | |
668 @Override | |
669 public REPLMessage createRequest(REPLClientContext context, String[] args) { | |
670 if (context.level() == 0) { | |
671 context.displayFailReply("no active execution"); | |
672 return null; | |
673 } | |
674 final int newFrameSelection = context.getSelectedFrameNumber() - 1; | |
675 if (newFrameSelection < 0) { | |
676 context.displayFailReply("at top of stack"); | |
677 return null; | |
678 } | |
679 context.selectFrameNumber(newFrameSelection); | |
680 return FRAME_CMD.createRequest(context, Arrays.copyOfRange(args, 0, 0)); | |
681 } | |
682 | |
683 @Override | |
684 void processReply(REPLClientContext context, REPLMessage[] replies) { | |
685 REPLMessage firstReply = replies[0]; | |
686 | |
687 if (firstReply.get(REPLMessage.STATUS).equals(REPLMessage.FAILED)) { | |
688 final String result = firstReply.get(REPLMessage.DISPLAY_MSG); | |
689 context.displayFailReply(result != null ? result : firstReply.toString()); | |
690 } else { | |
691 context.displayStack(); | |
692 } | |
693 } | |
694 }; | |
695 | |
696 } |