Package: DBGPReaderV2

DBGPReaderV2

nameinstructionbranchcomplexitylinemethod
DBGPReaderV2(String, int, String, Interpreter, String, CPUValue)
M: 18 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
canAssignValue(String, String)
M: 54 C: 0
0%
M: 18 C: 0
0%
M: 10 C: 0
0%
M: 14 C: 0
0%
M: 1 C: 0
0%
deref(Value)
M: 14 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
formatFunctionValue(FunctionValue)
M: 27 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
getChildCount(Value)
M: 137 C: 0
0%
M: 36 C: 0
0%
M: 19 C: 0
0%
M: 31 C: 0
0%
M: 1 C: 0
0%
getContextValues(DBGPContextType, int)
M: 301 C: 0
0%
M: 46 C: 0
0%
M: 25 C: 0
0%
M: 63 C: 0
0%
M: 1 C: 0
0%
getStackTrace(Throwable)
M: 20 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
isDebugVisible(Value)
M: 40 C: 0
0%
M: 24 C: 0
0%
M: 13 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
main(String[])
M: 845 C: 0
0%
M: 150 C: 0
0%
M: 76 C: 0
0%
M: 220 C: 0
0%
M: 1 C: 0
0%
makeDisplayId(Integer, Integer)
M: 21 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
makeProperty(String, String, String, String, Integer, Integer, boolean, Integer, Integer, Integer, String, StringBuilder)
M: 213 C: 0
0%
M: 14 C: 0
0%
M: 8 C: 0
0%
M: 28 C: 0
0%
M: 1 C: 0
0%
newThread(CPUValue)
M: 22 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
process(String)
M: 178 C: 0
0%
M: 30 C: 0
0%
M: 29 C: 0
0%
M: 75 C: 0
0%
M: 1 C: 0
0%
processClasses(DBGPCommand)
M: 72 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 15 C: 0
0%
M: 1 C: 0
0%
processEval(DBGPCommand)
M: 74 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 14 C: 0
0%
M: 1 C: 0
0%
processExec(DBGPCommand)
M: 101 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 23 C: 0
0%
M: 1 C: 0
0%
processExpr(DBGPCommand)
M: 81 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 20 C: 0
0%
M: 1 C: 0
0%
processLog(DBGPCommand)
M: 104 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 20 C: 0
0%
M: 1 C: 0
0%
processModules(DBGPCommand)
M: 72 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 15 C: 0
0%
M: 1 C: 0
0%
processOvertureCmd(DBGPCommand)
M: 103 C: 0
0%
M: 20 C: 0
0%
M: 18 C: 0
0%
M: 40 C: 0
0%
M: 1 C: 0
0%
processRun(DBGPCommand)
M: 370 C: 0
0%
M: 32 C: 0
0%
M: 17 C: 0
0%
M: 81 C: 0
0%
M: 1 C: 0
0%
processStack(DBGPCommand)
M: 50 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
processWriteCoverage(DBGPCommand)
M: 61 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 10 C: 0
0%
M: 1 C: 0
0%
propertyGet(DBGPCommand)
M: 170 C: 0
0%
M: 24 C: 0
0%
M: 13 C: 0
0%
M: 41 C: 0
0%
M: 1 C: 0
0%
propertyResponse(ILexNameToken, Value, DBGPContextType)
M: 43 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
propertyResponse(Integer, Integer)
M: 104 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 15 C: 0
0%
M: 1 C: 0
0%
propertyResponse(NameValuePairMap, DBGPContextType)
M: 43 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
propertyResponse(String, String, String, Value)
M: 11 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
propertyResponse(String, String, String, Value, Integer, Integer)
M: 175 C: 0
0%
M: 24 C: 0
0%
M: 13 C: 0
0%
M: 25 C: 0
0%
M: 1 C: 0
0%
propertyResponseChild(Value, Integer, Integer, Integer, Integer)
M: 570 C: 0
0%
M: 42 C: 0
0%
M: 22 C: 0
0%
M: 60 C: 0
0%
M: 1 C: 0
0%
propertySet(DBGPCommand)
M: 148 C: 0
0%
M: 14 C: 0
0%
M: 8 C: 0
0%
M: 32 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
statusResponse(DBGPStatus, DBGPReason)
M: 104 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 27 C: 0
0%
M: 1 C: 0
0%
writeCoverage(Interpreter, File)
M: 48 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 11 C: 0
0%
M: 1 C: 0
0%
xcmdOvertureResponse(DBGPXCmdOvertureCommandType, StringBuilder, StringBuilder)
M: 75 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 20 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: *
3: *        Copyright (c) 2010 Overture.
4: *
5: *        Author: Kenneth Lausdahl
6: *
7: *        This file is part of VDMJ.
8: *
9: *        VDMJ is free software: you can redistribute it and/or modify
10: *        it under the terms of the GNU General Public License as published by
11: *        the Free Software Foundation, either version 3 of the License, or
12: *        (at your option) any later version.
13: *
14: *        VDMJ is distributed in the hope that it will be useful,
15: *        but WITHOUT ANY WARRANTY; without even the implied warranty of
16: *        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: *        GNU General Public License for more details.
18: *
19: *        You should have received a copy of the GNU General Public License
20: *        along with VDMJ. If not, see <http://www.gnu.org/licenses/>.
21: *
22: ******************************************************************************/
23:
24: package org.overture.interpreter.debug;
25:
26: import java.io.ByteArrayOutputStream;
27: import java.io.File;
28: import java.io.FileNotFoundException;
29: import java.io.FileOutputStream;
30: import java.io.IOException;
31: import java.io.OutputStream;
32: import java.io.PrintWriter;
33: import java.io.Serializable;
34: import java.io.StringWriter;
35: import java.io.UnsupportedEncodingException;
36: import java.net.URI;
37: import java.net.URISyntaxException;
38: import java.util.Arrays;
39: import java.util.Hashtable;
40: import java.util.Iterator;
41: import java.util.List;
42: import java.util.Map;
43: import java.util.Map.Entry;
44: import java.util.Vector;
45:
46: import org.overture.ast.analysis.AnalysisException;
47: import org.overture.ast.definitions.AMutexSyncDefinition;
48: import org.overture.ast.definitions.APerSyncDefinition;
49: import org.overture.ast.definitions.PDefinition;
50: import org.overture.ast.definitions.SClassDefinition;
51: import org.overture.ast.expressions.AHistoryExp;
52: import org.overture.ast.expressions.PExp;
53: import org.overture.ast.factory.AstFactory;
54: import org.overture.ast.intf.lex.ILexNameToken;
55: import org.overture.ast.lex.Dialect;
56: import org.overture.ast.lex.LexNameList;
57: import org.overture.ast.lex.LexNameToken;
58: import org.overture.ast.lex.LexToken;
59: import org.overture.ast.lex.VDMToken;
60: import org.overture.ast.modules.AModuleModules;
61: import org.overture.ast.util.definitions.ClassList;
62: import org.overture.config.Release;
63: import org.overture.config.Settings;
64: import org.overture.interpreter.VDMJ;
65: import org.overture.interpreter.VDMPP;
66: import org.overture.interpreter.VDMRT;
67: import org.overture.interpreter.VDMSL;
68: import org.overture.interpreter.debug.DBGPExecProcesser.DBGPExecResult;
69: import org.overture.interpreter.messages.Console;
70: import org.overture.interpreter.messages.rtlog.RTLogger;
71: import org.overture.interpreter.messages.rtlog.RTTextLogger;
72: import org.overture.interpreter.messages.rtlog.nextgen.NextGenRTLogger;
73: import org.overture.interpreter.runtime.ClassContext;
74: import org.overture.interpreter.runtime.ClassInterpreter;
75: import org.overture.interpreter.runtime.Context;
76: import org.overture.interpreter.runtime.ContextException;
77: import org.overture.interpreter.runtime.Interpreter;
78: import org.overture.interpreter.runtime.ModuleInterpreter;
79: import org.overture.interpreter.runtime.ObjectContext;
80: import org.overture.interpreter.runtime.RuntimeValidator;
81: import org.overture.interpreter.runtime.SourceFile;
82: import org.overture.interpreter.runtime.StateContext;
83: import org.overture.interpreter.runtime.VdmRuntime;
84: import org.overture.interpreter.scheduler.BasicSchedulableThread;
85: import org.overture.interpreter.scheduler.ISchedulableThread;
86: import org.overture.interpreter.traces.TraceReductionType;
87: import org.overture.interpreter.util.ExitStatus;
88: import org.overture.interpreter.values.BooleanValue;
89: import org.overture.interpreter.values.CPUValue;
90: import org.overture.interpreter.values.CharacterValue;
91: import org.overture.interpreter.values.FieldValue;
92: import org.overture.interpreter.values.FunctionValue;
93: import org.overture.interpreter.values.MapValue;
94: import org.overture.interpreter.values.NameValuePair;
95: import org.overture.interpreter.values.NameValuePairMap;
96: import org.overture.interpreter.values.NilValue;
97: import org.overture.interpreter.values.NumericValue;
98: import org.overture.interpreter.values.ObjectValue;
99: import org.overture.interpreter.values.RecordValue;
100: import org.overture.interpreter.values.ReferenceValue;
101: import org.overture.interpreter.values.SeqValue;
102: import org.overture.interpreter.values.SetValue;
103: import org.overture.interpreter.values.TokenValue;
104: import org.overture.interpreter.values.TransactionValue;
105: import org.overture.interpreter.values.TupleValue;
106: import org.overture.interpreter.values.UpdatableValue;
107: import org.overture.interpreter.values.Value;
108: import org.overture.parser.config.Properties;
109: import org.overture.parser.lex.LexException;
110: import org.overture.parser.lex.LexTokenReader;
111: import org.overture.util.Base64;
112:
113: /**
114: * Extended DBGPReader adding support for:
115: * <ul>
116: * <li>In-depth variable inspection.
117: * <li>Overture command for writing covtbl files after execution.
118: * <li>Overture response. Used to check status after issuing an xcmd Overture
119: * </ul>
120: *
121: * @author kela
122: */
123: public class DBGPReaderV2 extends DBGPReader implements Serializable
124: {
125:         private static final long serialVersionUID = 1L;
126:
127:         private static final int SHORT_STRING_MAX = 200;
128:
129:         /**
130:          * Map containing Values accessible from the client by a key. Should be emptied at resume
131:          */
132:         private Map<Integer, Value> debugValueMap = new Hashtable<Integer, Value>();
133:         /**
134:          * Debug key counter for the client
135:          */
136:         private Integer debugValueKeyCounter = 0;
137:         /**
138:          * Indicating if the debugger is running in a trace mode
139:          */
140:         private static Boolean traceExpression = false;
141:
142:         @SuppressWarnings("unchecked")
143:         public static void main(String[] args)
144:         {
145:                 Settings.usingDBGP = true;
146:                 Settings.baseDir = new File(".").getParentFile();
147:
148:                 String host = null;
149:                 int port = -1;
150:                 String ideKey = null;
151:                 Settings.dialect = null;
152:                 String expression = null;
153:                 List<File> files = new Vector<File>();
154:                 List<String> largs = Arrays.asList(args);
155:                 VDMJ controller = null;
156:                 boolean warnings = true;
157:                 boolean quiet = false;
158:                 String logfile = null;
159:                 String logTimeInvfile = null;
160:                 boolean expBase64 = false;
161:                 File coverage = null;
162:                 String defaultName = null;
163:                 String remoteName = null;
164:                 Class<RemoteControl> remoteClass = null;
165:
166:                 Properties.init(); // Read properties file, if any
167:
168:                 Properties.parser_tabstop = 1;// required to match locations with the editor representation
169:
170:•                for (Iterator<String> i = largs.iterator(); i.hasNext();)
171:                 {
172:                         String arg = i.next();
173:
174:•                        if (arg.equals("-vdmsl"))
175:                         {
176:                                 controller = new VDMSL();
177:•                        } else if (arg.equals("-vdmpp"))
178:                         {
179:                                 controller = new VDMPP();
180:•                        } else if (arg.equals("-vdmrt"))
181:                         {
182:                                 controller = new VDMRT();
183:•                        } else if (arg.equals("-h"))
184:                         {
185:•                                if (i.hasNext())
186:                                 {
187:                                         host = i.next();
188:                                 } else
189:                                 {
190:                                         usage("-h option requires a hostname");
191:                                 }
192:•                        } else if (arg.equals("-p"))
193:                         {
194:                                 try
195:                                 {
196:                                         port = Integer.parseInt(i.next());
197:                                 } catch (Exception e)
198:                                 {
199:                                         usage("-p option requires a port");
200:                                 }
201:•                        } else if (arg.equals("-k"))
202:                         {
203:•                                if (i.hasNext())
204:                                 {
205:                                         ideKey = i.next();
206:                                 } else
207:                                 {
208:                                         usage("-k option requires a key");
209:                                 }
210:•                        } else if (arg.equals("-e"))
211:                         {
212:•                                if (i.hasNext())
213:                                 {
214:                                         expression = i.next();
215:                                 } else
216:                                 {
217:                                         usage("-e option requires an expression");
218:                                 }
219:•                        } else if (arg.equals("-e64"))
220:                         {
221:•                                if (i.hasNext())
222:                                 {
223:                                         expression = i.next();
224:                                         expBase64 = true;
225:                                 } else
226:                                 {
227:                                         usage("-e64 option requires an expression");
228:                                 }
229:•                        } else if (arg.equals("-c"))
230:                         {
231:•                                if (i.hasNext())
232:                                 {
233:•                                        if (controller == null)
234:                                         {
235:                                                 usage("-c must come after <-vdmpp|-vdmsl|-vdmrt>");
236:                                         }
237:
238:                                         controller.setCharset(validateCharset(i.next()));
239:                                 } else
240:                                 {
241:                                         usage("-c option requires a charset name");
242:                                 }
243:•                        } else if (arg.equals("-r"))
244:                         {
245:•                                if (i.hasNext())
246:                                 {
247:                                         Settings.release = Release.lookup(i.next());
248:
249:•                                        if (Settings.release == null)
250:                                         {
251:                                                 usage("-r option must be " + Release.list());
252:                                         }
253:                                 } else
254:                                 {
255:                                         usage("-r option requires a VDM release");
256:                                 }
257:•                        } else if (arg.equals("-pre"))
258:                         {
259:                                 Settings.prechecks = false;
260:•                        } else if (arg.equals("-post"))
261:                         {
262:                                 Settings.postchecks = false;
263:•                        } else if (arg.equals("-inv"))
264:                         {
265:                                 Settings.invchecks = false;
266:•                        } else if (arg.equals("-dtc"))
267:                         {
268:                                 // NB. Turn off both when no DTC
269:                                 Settings.invchecks = false;
270:                                 Settings.dynamictypechecks = false;
271:•                        } else if (arg.equals("-measures"))
272:                         {
273:                                 Settings.measureChecks = false;
274:•                        } else if (arg.equals("-strict"))
275:                         {
276:                                 Settings.strict = true;
277:•                        } else if (arg.equals("-log"))
278:                         {
279:•                                if (i.hasNext())
280:                                 {
281:                                         try
282:                                         {
283:                                                 logfile = new URI(i.next()).getPath();
284:                                         } catch (URISyntaxException e)
285:                                         {
286:                                                 usage(e.getMessage() + ": " + arg);
287:                                         } catch (IllegalArgumentException e)
288:                                         {
289:                                                 usage(e.getMessage() + ": " + arg);
290:                                         }
291:                                 } else
292:                                 {
293:                                         usage("-log option requires a filename");
294:                                 }
295:•                        } else if (arg.equals("-timeinv"))
296:                         {
297:•                                if (i.hasNext())
298:                                 {
299:                                         try
300:                                         {
301:                                                 logTimeInvfile = new URI(i.next()).getPath();
302:                                         } catch (URISyntaxException e)
303:                                         {
304:                                                 usage(e.getMessage() + ": " + arg);
305:                                         } catch (IllegalArgumentException e)
306:                                         {
307:                                                 usage(e.getMessage() + ": " + arg);
308:                                         }
309:                                 } else
310:                                 {
311:                                         usage("-timeinv option requires a filename");
312:                                 }
313:•                        } else if (arg.equals("-w"))
314:                         {
315:                                 warnings = false;
316:•                        } else if (arg.equals("-q"))
317:                         {
318:                                 quiet = true;
319:•                        } else if (arg.equals("-coverage"))
320:                         {
321:•                                if (i.hasNext())
322:                                 {
323:                                         try
324:                                         {
325:                                                 coverage = new File(new URI(i.next()));
326:
327:•                                                if (!coverage.isDirectory())
328:                                                 {
329:                                                         usage("Coverage location is not a directory");
330:                                                 }
331:                                         } catch (URISyntaxException e)
332:                                         {
333:                                                 usage(e.getMessage() + ": " + arg);
334:                                         } catch (IllegalArgumentException e)
335:                                         {
336:                                                 usage(e.getMessage() + ": " + arg);
337:                                         }
338:                                 } else
339:                                 {
340:                                         usage("-coverage option requires a directory name");
341:                                 }
342:•                        } else if (arg.equals("-default64"))
343:                         {
344:•                                if (i.hasNext())
345:                                 {
346:                                         defaultName = i.next();
347:                                 } else
348:                                 {
349:                                         usage("-default64 option requires a name");
350:                                 }
351:•                        } else if (arg.equals("-remote"))
352:                         {
353:•                                if (i.hasNext())
354:                                 {
355:                                         remoteName = i.next();
356:                                 } else
357:                                 {
358:                                         usage("-remote option requires a Java classname");
359:                                 }
360:•                        } else if (arg.equals("-t"))
361:                         {
362:                                 traceExpression = true;
363:•                        } else if (arg.equals("-consoleName"))
364:                         {
365:•                                if (i.hasNext())
366:                                 {
367:                                         LexTokenReader.consoleFileName = i.next();
368:                                 } else
369:                                 {
370:                                         usage("-consoleName option requires a console name");
371:                                 }
372:•                        } else if (arg.equals("-baseDir"))
373:                         {
374:•                                if (i.hasNext())
375:                                 {
376:                                         try
377:                                         {
378:                                                 Settings.baseDir = new File(new URI(i.next()));
379:                                         } catch (URISyntaxException e)
380:                                         {
381:                                                 usage(e.getMessage() + ": " + arg);
382:                                         } catch (IllegalArgumentException e)
383:                                         {
384:                                                 usage(e.getMessage() + ": " + arg);
385:                                         }
386:                                 } else
387:                                 {
388:                                         usage("-baseDir option requires a folder name");
389:                                 }
390:•                        } else if (arg.startsWith("-"))
391:                         {
392:                                 usage("Unknown option " + arg);
393:                         } else
394:                         {
395:                                 try
396:                                 {
397:                                         File dir = new File(new URI(arg));
398:
399:•                                        if (dir.isDirectory())
400:                                         {
401:•                                                for (File file : dir.listFiles(Settings.dialect.getFilter()))
402:                                                 {
403:•                                                        if (file.isFile())
404:                                                         {
405:                                                                 files.add(file);
406:                                                         }
407:                                                 }
408:                                         } else
409:                                         {
410:                                                 files.add(dir);
411:                                         }
412:                                 } catch (URISyntaxException e)
413:                                 {
414:                                         usage(e.getMessage() + ": " + arg);
415:                                 } catch (IllegalArgumentException e)
416:                                 {
417:                                         usage(e.getMessage() + ": " + arg);
418:                                 }
419:                         }
420:                 }
421:
422:•                if (host == null)
423:                 {
424:                         usage("Missing mandatory host URL");
425:                 }
426:
427:•                if (port == -1)
428:                 {
429:                         usage("Missing mandatory port number");
430:                 }
431:
432:•                if (ideKey == null)
433:                 {
434:                         usage("Missing mandatory IDE key");
435:                 }
436:
437:•                if (expression == null)
438:                 {
439:                         usage("Missing mandatory expression");
440:                 }
441:
442:•                if (Settings.dialect == null)
443:                 {
444:                         usage("Missing mandatory dialect");
445:                 }
446:
447:•                if (files.isEmpty())
448:                 {
449:                         usage("Missing mandatory specification files");
450:                 }
451:
452:•                if (host == null || port == -1 || controller == null || ideKey == null
453:                                 || expression == null || Settings.dialect == null
454:•                                || files.isEmpty())
455:                 {
456:                         usage("Missing mandatory arguments");
457:                 }
458:
459:•                if (Settings.dialect != Dialect.VDM_RT && logfile != null)
460:                 {
461:                         usage("-log can only be used with -vdmrt");
462:                 }
463:•                if (Settings.dialect != Dialect.VDM_RT && logTimeInvfile != null)
464:                 {
465:                         usage("-timeinv can only be used with -vdmrt");
466:                 }
467:
468:•                if (expBase64)
469:                 {
470:                         try
471:                         {
472:                                 byte[] bytes = Base64.decode(expression);
473:                                 expression = new String(bytes, VDMJ.filecharset);
474:                         } catch (Exception e)
475:                         {
476:                                 usage("Malformed -e64 base64 expression");
477:                         }
478:                 }
479:
480:•                if (defaultName != null)
481:                 {
482:                         try
483:                         {
484:                                 byte[] bytes = Base64.decode(defaultName);
485:                                 defaultName = new String(bytes, VDMJ.filecharset);
486:                         } catch (Exception e)
487:                         {
488:                                 usage("Malformed -default64 base64 name");
489:                         }
490:                 }
491:
492:•                if (remoteName != null)
493:                 {
494:                         try
495:                         {
496:                                 Class<?> cls = ClassLoader.getSystemClassLoader().loadClass(remoteName);
497:                                 remoteClass = (Class<RemoteControl>) cls;
498:                         } catch (ClassNotFoundException e)
499:                         {
500:                                 usage("Cannot locate " + remoteName + " on the CLASSPATH");
501:                         }
502:                 }
503:
504:                 controller.setWarnings(warnings);
505:                 controller.setQuiet(quiet);
506:
507:•                if (controller.parse(files) == ExitStatus.EXIT_OK)
508:                 {
509:•                        if (controller.typeCheck() == ExitStatus.EXIT_OK)
510:                         {
511:                                 try
512:                                 {
513:•                                        if (logfile != null)
514:                                         {
515:                                                 RTLogger.setLogfile(RTTextLogger.class, new File(logfile));
516:                                                 RTLogger.setLogfile(NextGenRTLogger.class, new File(logfile));
517:                                         }
518:
519:•                                        if (logTimeInvfile != null)
520:                                         {
521:                                                 Settings.timingInvChecks = true;
522:                                                 PrintWriter p = new PrintWriter(new FileOutputStream(logTimeInvfile, false));
523:                                                 RuntimeValidator.setLogFile(p);
524:                                         }
525:
526:                                         Interpreter i = controller.getInterpreter();
527:
528:•                                        if (defaultName != null)
529:                                         {
530:                                                 i.setDefaultName(defaultName);
531:                                         }
532:
533:•                                        RemoteControl remote = remoteClass == null ? null
534:                                                         : remoteClass.newInstance();
535:
536:                                         new DBGPReaderV2(host, port, ideKey, i, expression, null).startup(remote);
537:
538:•                                        if (coverage != null)
539:                                         {
540:                                                 writeCoverage(i, coverage);
541:                                         }
542:
543:                                         RTLogger.dump(true);
544:                                         System.exit(0);
545:                                 } catch (ContextException e)
546:                                 {
547:                                         System.err.println("Initialization: " + e);
548:                                         
549:•                                        if (e.isStackOverflow())
550:                                         {
551:                                                 e.ctxt.printStackFrames(Console.out);
552:                                         }
553:                                         else
554:                                         {
555:                                                 e.ctxt.printStackTrace(Console.out, true);
556:                                         }
557:                                         
558:                                         RTLogger.dump(true);
559:                                         System.exit(3);
560:                                 } catch (Exception e)
561:                                 {
562:                                         System.err.println("Initialization: " + e);
563:                                         e.printStackTrace();
564:                                         RTLogger.dump(true);
565:                                         System.exit(3);
566:                                 }
567:                         } else
568:                         {
569:                                 System.exit(2);
570:                         }
571:                 } else
572:                 {
573:                         System.exit(1);
574:                 }
575:         }
576:
577:         public DBGPReaderV2(String host, int port, String ideKey,
578:                         Interpreter interpreter, String expression, CPUValue cpu)
579:         {
580:                 super(host, port, ideKey, interpreter, expression, cpu);
581:         }
582:
583:         /**
584:          * Overrides to use DBGPReaderV2 debug reader
585:          */
586:         @Override
587:         public DBGPReaderV2 newThread(CPUValue _cpu)
588:         {
589:                 DBGPReaderV2 r = new DBGPReaderV2(host, port, ideKey, interpreter, null, _cpu);
590:                 r.command = DBGPCommandType.UNKNOWN;
591:                 r.transaction = "?";
592:                 return r;
593:         }
594:
595:         @Override
596:         protected boolean process(String line)
597:         {
598:                 boolean carryOn = true;
599:
600:                 try
601:                 {
602:                         command = DBGPCommandType.UNKNOWN;
603:                         transaction = "?";
604:
605:                         String[] parts = line.split("\\s+");
606:                         DBGPCommand c = parse(parts);
607:
608:•                        switch (c.type)
609:                         {
610:                                 case STATUS:
611:                                         processStatus(c);
612:                                         break;
613:
614:                                 case FEATURE_GET:
615:                                         processFeatureGet(c);
616:                                         break;
617:
618:                                 case FEATURE_SET:
619:                                         processFeatureSet(c);
620:                                         break;
621:
622:                                 case RUN:
623:                                         carryOn = processRun(c);
624:                                         break;
625:
626:                                 case EVAL:
627:                                         carryOn = processEval(c);
628:                                         break;
629:
630:                                 case EXPR:
631:                                         carryOn = processExpr(c);
632:                                         break;
633:
634:                                 case EXEC:
635:                                         carryOn = processExec(c);
636:                                         break;
637:
638:                                 case STEP_INTO:
639:                                         processStepInto(c);
640:                                         carryOn = false;
641:                                         break;
642:
643:                                 case STEP_OVER:
644:                                         processStepOver(c);
645:                                         carryOn = false;
646:                                         break;
647:
648:                                 case STEP_OUT:
649:                                         processStepOut(c);
650:                                         carryOn = false;
651:                                         break;
652:
653:                                 case STOP:
654:                                         processStop(c);
655:                                         carryOn = false;
656:                                         break;
657:
658:                                 case BREAKPOINT_GET:
659:                                         breakpointGet(c);
660:                                         break;
661:
662:                                 case BREAKPOINT_SET:
663:                                         breakpointSet(c);
664:                                         break;
665:
666:                                 case BREAKPOINT_UPDATE:
667:                                         breakpointUpdate(c);
668:                                         break;
669:
670:                                 case BREAKPOINT_REMOVE:
671:                                         breakpointRemove(c);
672:                                         break;
673:
674:                                 case BREAKPOINT_LIST:
675:                                         breakpointList(c);
676:                                         break;
677:
678:                                 case STACK_DEPTH:
679:                                         stackDepth(c);
680:                                         break;
681:
682:                                 case STACK_GET:
683:                                         stackGet(c);
684:                                         break;
685:
686:                                 case CONTEXT_NAMES:
687:                                         contextNames(c);
688:                                         break;
689:
690:                                 case CONTEXT_GET:
691:                                         contextGet(c);
692:                                         break;
693:
694:                                 case PROPERTY_GET:
695:                                         propertyGet(c);
696:                                         break;
697:
698:                                 case SOURCE:
699:                                         processSource(c);
700:                                         break;
701:
702:                                 case STDOUT:
703:                                         processStdout(c);
704:                                         break;
705:
706:                                 case STDERR:
707:                                         processStderr(c);
708:                                         break;
709:
710:                                 case DETACH:
711:                                         carryOn = false;
712:                                         break;
713:
714:                                 case XCMD_OVERTURE_CMD:
715:                                         processOvertureCmd(c);
716:                                         break;
717:
718:                                 case PROPERTY_SET:
719:                                         propertySet(c);
720:                                         break;
721:                                 default:
722:                                         errorResponse(DBGPErrorCode.NOT_AVAILABLE, c.type.value);
723:                         }
724:                 } catch (DBGPException e)
725:                 {
726:                         errorResponse(e.code, e.reason);
727:                 } catch (StackOverflowError e)
728:                 {
729:                         invocationError(e);
730:                 } catch (Throwable e)
731:                 {
732:                         e.printStackTrace();
733:                         String msg = e.getMessage();
734:•                        errorResponse(DBGPErrorCode.INTERNAL_ERROR, msg != null ? msg : e.toString());
735:                 }
736:
737:                 return carryOn;
738:         }
739:
740:         private void propertySet(DBGPCommand c) throws DBGPException, IOException
741:         {
742:
743:                 checkArgs(c, 4, false);
744:                 DBGPOption option = c.getOption(DBGPOptionType.K);
745:
746:•                if (option == null)
747:                 {
748:                         throw new DBGPException(DBGPErrorCode.INVALID_OPTIONS, c.toString());
749:                 }
750:
751:                 boolean success = false;
752:                 Integer key = Integer.parseInt(option.value);
753:
754:                 Value vOriginal = null;
755:                 UpdatableValue uv = null;
756:                 try
757:                 {
758:•                        if (!debugValueMap.containsKey(key))
759:                         {
760:                                 throw new DBGPException(DBGPErrorCode.CANT_GET_PROPERTY, "Key = "
761:                                                 + key);
762:                         }
763:                         Value v = debugValueMap.get(key);
764:                         vOriginal = v.deepCopy();// inexpensive only support of simple types
765:
766:•                        if (v instanceof UpdatableValue)
767:                         {
768:                                 uv = (UpdatableValue) v;
769:
770:                                 // TODO BUG: Here is a problem if the evaluate is suspended in a
771:                                 // property_set by the scheduler
772:                                 Value newval = interpreter.evaluate(c.data, interpreter.initialContext);
773:
774:•                                if (newval != null && canAssignValue(newval.kind(), uv.kind()))
775:                                 {
776:                                         uv.set(breakpoint.location, newval, breakContext);
777:                                         success = true;
778:                                 }
779:                         }
780:                 } catch (ContextException e)
781:                 {
782:                         success = false;
783:                         // aboard value update and put back the original value
784:                         try
785:                         {
786:•                                if (uv != null)
787:                                 {
788:                                         uv.set(breakpoint.location, vOriginal, breakContext);
789:                                 }
790:                         } catch (Exception ex)
791:                         {
792:                                 // this is fatal we cannot continue interpretation
793:                                 throw new DBGPException(DBGPErrorCode.INTERNAL_ERROR, ex.toString());
794:                         }
795:                 }
796:
797:                 catch (Exception e)
798:                 {
799:                         throw new DBGPException(DBGPErrorCode.INTERNAL_ERROR, e.toString());
800:                 }
801:
802:                 StringBuilder hdr = new StringBuilder();
803:
804:•                hdr.append("success=\"" + (success ? "1" : "0") + "\"");
805:
806:                 response(hdr, null);
807:
808:         }
809:
810:         private boolean canAssignValue(String newKind, String source)
811:         {
812:
813:•                if (newKind.equals(source))
814:                 {
815:                         return true;
816:                 }
817:
818:                 final String TYPE_REAL = "real";
819:                 final String TYPE_NAT = "nat";
820:                 final String TYPE_INT = "int";
821:
822:•                if (newKind.contains(TYPE_NAT) && source.equals(TYPE_NAT))
823:                 {
824:                         return true;
825:                 }
826:•                if (newKind.contains(TYPE_NAT) && source.equals(TYPE_REAL))
827:                 {
828:                         return true;
829:                 }
830:
831:•                if (newKind.contains(TYPE_NAT) && source.equals(TYPE_INT))
832:                 {
833:                         return true;
834:                 }
835:•                if (newKind.contains(TYPE_INT) && source.equals(TYPE_REAL))
836:                 {
837:                         return true;
838:                 }
839:                 return false;
840:         }
841:
842:         /**
843:          * Send a xcmd Overture Response
844:          *
845:          * @param overtureCmd
846:          * The overture command which this is a response to
847:          * @param hdr
848:          * The header
849:          * @param body
850:          * The body
851:          * @throws IOException
852:          */
853:         private void xcmdOvertureResponse(DBGPXCmdOvertureCommandType overtureCmd,
854:                         StringBuilder hdr, StringBuilder body) throws IOException
855:         {
856:                 StringBuilder sb = new StringBuilder();
857:
858:                 sb.append("<xcmd_overture_response command=\"");
859:                 sb.append(command);
860:                 sb.append("\"");
861:
862:                 sb.append(" overtureCmd=\"");
863:                 sb.append(overtureCmd);
864:                 sb.append("\"");
865:
866:•                if (hdr != null)
867:                 {
868:                         sb.append(" ");
869:                         sb.append(hdr);
870:                 }
871:
872:                 sb.append(" transaction_id=\"");
873:                 sb.append(transaction);
874:                 sb.append("\"");
875:
876:•                if (body != null)
877:                 {
878:                         sb.append(">");
879:                         sb.append(body);
880:                         sb.append("</xcmd_overture_response>\n");
881:                 } else
882:                 {
883:                         sb.append("/>\n");
884:                 }
885:
886:                 write(sb);
887:         }
888:
889:         @Override
890:         protected void statusResponse(DBGPStatus s, DBGPReason reason)
891:                         throws IOException
892:         {
893:•                if (s == DBGPStatus.STOPPED)
894:                 {
895:                         stopped = true;
896:                 }
897:
898:                 StringBuilder sb = new StringBuilder();
899:
900:                 status = s;
901:                 statusReason = reason;
902:
903:                 sb.append("status=\"");
904:                 sb.append(status);
905:                 sb.append("\"");
906:                 sb.append(" reason=\"");
907:                 sb.append(statusReason);
908:                 sb.append("\"");
909:
910:                 StringBuilder body = new StringBuilder();
911:                 body.append("<internal ");
912:
913:                 ISchedulableThread th = BasicSchedulableThread.getThread(Thread.currentThread());
914:
915:•                if (th != null)
916:                 {
917:                         body.append("threadId=\"");
918:                         body.append(th.getId());
919:                         body.append("\" ");
920:
921:                         body.append("threadName=\"");
922:                         body.append(th.getName());
923:                         body.append("\" ");
924:
925:                         body.append("threadState=\"");
926:                         body.append(th.getRunState().toString());
927:                         body.append("\" ");
928:
929:                 }
930:
931:                 body.append("/>");
932:
933:                 response(sb, body);
934:         }
935:
936:         /**
937:          * Overrides super class by filtering all entries against isDebugVisible
938:          */
939:         @Override
940:         protected StringBuilder propertyResponse(NameValuePairMap vars,
941:                         DBGPContextType context) throws UnsupportedEncodingException
942:         {
943:                 StringBuilder sb = new StringBuilder();
944:
945:•                for (Entry<ILexNameToken, Value> e : vars.entrySet())
946:                 {
947:•                        if (!e.getKey().getName().equals("self"))
948:                         { // This test makes the self not appear
949:
950:•                                if (isDebugVisible(e.getValue()))
951:                                 {
952:                                         sb.append(propertyResponse(e.getKey(), e.getValue(), context));
953:                                 }
954:                         }
955:                 }
956:
957:                 return sb;
958:         }
959:
960:         @Override
961:         protected StringBuilder propertyResponse(ILexNameToken name, Value value,
962:                         DBGPContextType context) throws UnsupportedEncodingException
963:         {
964:•                String nameString = context == DBGPContextType.GLOBAL ? name.getModule()
965:                                 + "`" + name.getName()
966:•                                : name.getOld() ? name.getName() + "~" : name.getName();
967:                 return propertyResponse(nameString, name.getExplicit(true).toString(), name.getModule(), value);
968:         }
969:
970:         private StringBuilder propertyResponse(String name, String fullname,
971:                         String clazz, Value value) throws UnsupportedEncodingException
972:         {
973:                 return propertyResponse(name, fullname, clazz, value, 3, 0);
974:         }
975:
976:         private StringBuilder propertyResponse(String name, String fullname,
977:                         String clazz, Value value, Integer depth, Integer currentDepth)
978:                         throws UnsupportedEncodingException
979:         {
980:                 StringBuilder sb = new StringBuilder();
981:                 currentDepth++;
982:
983:                 Integer numChildren = getChildCount(value);
984:
985:                 Integer page = 0;
986:                 Integer pageSize = Integer.parseInt(features.getProperty(DBGPFeatures.MAX_CHILDREN));
987:
988:                 Integer key = null;
989:                 String data = null;
990:                 StringBuilder nestedChildren = null;
991:
992:                 // store property for retrieval of additional pages or value editing
993:•                if (numChildren > pageSize || depth == currentDepth
994:                                 || value instanceof UpdatableValue
995:                                 || value instanceof ObjectValue)
996:                 {
997:                         debugValueKeyCounter++;
998:                         debugValueMap.put(debugValueKeyCounter, value);
999:                         key = debugValueKeyCounter;
1000:                 }
1001:
1002:•                if (numChildren > pageSize || depth == currentDepth)
1003:                 {
1004:                         name += " (ref=" + debugValueKeyCounter + ")";
1005:                 }
1006:
1007:•                if (numChildren > 0)
1008:                 {
1009:                         data = value.toShortString(SHORT_STRING_MAX);
1010:                 } else
1011:                 {
1012:                         data = value.toString();
1013:                 }
1014:
1015:                 Value valDeref = value.deref();
1016:•                if (valDeref instanceof FunctionValue)
1017:                 {
1018:                         data = formatFunctionValue((FunctionValue) valDeref);
1019:                 }
1020:
1021:•                if (currentDepth < depth && numChildren > 0)
1022:                 {
1023:                         // max depth not reached. Fetch children of page size
1024:                         sb.append(propertyResponseChild(value, depth, currentDepth, pageSize, 0));
1025:                         nestedChildren = propertyResponseChild(value, depth, currentDepth, pageSize, 0);
1026:                 }
1027:
1028:•                boolean constant = numChildren > 0
1029:                                 || !(value instanceof UpdatableValue);
1030:
1031:                 return makeProperty(name, fullname, value.kind(), clazz, page, pageSize, constant, data.length(), key, numChildren, data, nestedChildren);
1032:         }
1033:
1034:         private String formatFunctionValue(FunctionValue value)
1035:         {
1036:                 StringBuilder sb = new StringBuilder();
1037:                 sb.append(value.name + ": " + value.toString() + " & " + value.body);
1038:                 return sb.toString();
1039:         }
1040:
1041:         /**
1042:          * @param size
1043:          * Unused.
1044:          */
1045:         private StringBuilder makeProperty(String name, String fullName,
1046:                         String type, String clazz, Integer page, Integer pageSize,
1047:                         boolean constant, Integer size, Integer key, Integer numChildren,
1048:                         String data, StringBuilder nestedProperties)
1049:                         throws UnsupportedEncodingException
1050:         {
1051:                 StringBuilder sb = new StringBuilder();
1052:                 Integer children = 0;
1053:
1054:•                if (numChildren > 0)
1055:                 {
1056:                         children = 1;
1057:                 }
1058:                 sb.append("<property");
1059:                 sb.append(" name=\"" + quote(name) + "\"");
1060:                 sb.append(" fullname=\"" + quote(fullName) + "\"");
1061:                 sb.append(" type=\"" + quote(type) + "\"");
1062:                 sb.append(" classname=\"" + clazz + "\"");
1063:•                if (numChildren > 0)
1064:                 {
1065:                         sb.append(" page=\"" + page + "\"");
1066:                         sb.append(" pagesize=\"" + pageSize + "\"");
1067:                 }
1068:
1069:•                sb.append(" constant=\"" + (constant ? "1" : "0") + "\"");
1070:                 sb.append(" children=\"" + children + "\"");
1071:
1072:                 StringBuffer encodedData = Base64.encode(data.getBytes("UTF-8"));
1073:
1074:                 sb.append(" size=\"" + encodedData.length() + "\"");
1075:•                if (key != null)
1076:                 {
1077:                         sb.append(" key=\"" + key + "\"");
1078:                 }
1079:                 sb.append(" encoding=\"base64\"");
1080:•                if (numChildren > 0)
1081:                 {
1082:                         sb.append(" numchildren=\"" + numChildren + "\"");
1083:                 }
1084:                 sb.append("><![CDATA[");
1085:                 sb.append(encodedData);
1086:                 sb.append("]]>");
1087:
1088:•                if (nestedProperties != null && nestedProperties.length() > 0)
1089:                 {
1090:                         sb.append(nestedProperties.toString());
1091:                 }
1092:
1093:                 sb.append("</property>");
1094:
1095:                 return sb;
1096:         }
1097:
1098:         /**
1099:          * Calculates if a value has children and returns the child count
1100:          *
1101:          * @param value
1102:          * The value to determine child count for
1103:          * @return number of children
1104:          */
1105:         private Integer getChildCount(Value value)
1106:         {
1107:                 // all types listed here are directly toString() in the debugger
1108:•                if (value instanceof NumericValue || value instanceof CharacterValue
1109:                                 || value instanceof NilValue || value instanceof TokenValue)
1110:                 {
1111:                         return 0;
1112:•                } else if (value instanceof SetValue)
1113:                 {
1114:                         return ((SetValue) value).values.size();
1115:•                } else if (value instanceof SeqValue)
1116:                 {
1117:                         boolean isString = true;
1118:•                        for (Value v : ((SeqValue) value).values)
1119:                         {
1120:•                                if (!(deref(v) instanceof CharacterValue))
1121:                                 {
1122:                                         isString = false;
1123:                                 }
1124:                         }
1125:
1126:•                        if (isString)
1127:                         {
1128:                                 return 0; // tread as simple value
1129:                         } else
1130:                         {
1131:                                 return ((SeqValue) value).values.size();
1132:                         }
1133:
1134:•                } else if (value instanceof MapValue)
1135:                 {
1136:                         return ((MapValue) value).values.size();
1137:•                } else if (value instanceof ObjectValue)
1138:                 {
1139:                         int count = 0;
1140:•                        for (NameValuePair v : ((ObjectValue) value).members.asList())
1141:                         {
1142:•                                if (isDebugVisible(v.value))
1143:                                 {
1144:                                         count++;
1145:                                 }
1146:                         }
1147:                         return count;
1148:
1149:•                } else if (value instanceof UpdatableValue
1150:                                 || value instanceof TransactionValue
1151:                                 || value instanceof ReferenceValue)
1152:                 {
1153:                         return getChildCount(deref(value));
1154:•                } else if (value instanceof RecordValue)
1155:                 {
1156:                         RecordValue rVal = (RecordValue) value;
1157:                         return rVal.fieldmap.size();
1158:•                } else if (value instanceof TupleValue)
1159:                 {
1160:                         TupleValue tVal = (TupleValue) value;
1161:                         return tVal.values.size();
1162:                 }
1163:
1164:                 return 0;
1165:         }
1166:
1167:         /**
1168:          * Creates a string with property responses for all requested children of the parsed value, intended to be used as
1169:          * the body of the value parsed
1170:          *
1171:          * @param value
1172:          * The value which children should be fetched
1173:          * @param depth
1174:          * The max depth
1175:          * @param currentDepth
1176:          * The current depth (The method recurses over children if needed)
1177:          * @param pageSize
1178:          * The page size used when returning children
1179:          * @param page
1180:          * The current page
1181:          * @return A string with property responses for all requested children
1182:          * @throws UnsupportedEncodingException
1183:          */
1184:         private StringBuilder propertyResponseChild(Value value, Integer depth,
1185:                         Integer currentDepth, Integer pageSize, Integer page)
1186:                         throws UnsupportedEncodingException
1187:         {
1188:                 StringBuilder s = new StringBuilder();
1189:•                if (value instanceof SeqValue)
1190:                 {
1191:                         SeqValue sVal = (SeqValue) value;
1192:•                        for (Integer i = page * pageSize; i < sVal.values.size()
1193:•                                        && i < page + 1 * pageSize; i++)
1194:                         {
1195:                                 Value element = sVal.values.get(i);
1196:                                 Integer vdmIndex = i + 1;
1197:                                 s.append(propertyResponse("Element["
1198:                                                 + makeDisplayId(sVal.values.size(), vdmIndex) + "]", vdmIndex.toString(), "-", element, depth, currentDepth));
1199:
1200:                         }
1201:•                } else if (value instanceof SetValue)
1202:                 {
1203:                         SetValue sVal = (SetValue) value;
1204:•                        for (Integer i = page * pageSize; i < sVal.values.size()
1205:•                                        && i < (page + 1) * pageSize + 1; i++)
1206:                         {
1207:                                 Value element = sVal.values.get(i);
1208:                                 Integer vdmIndex = i + 1;
1209:                                 s.append(propertyResponse("Element "
1210:                                                 + makeDisplayId(sVal.values.size(), vdmIndex), vdmIndex.toString(), "-", element, depth, currentDepth));
1211:
1212:                         }
1213:•                } else if (value instanceof ObjectValue)
1214:                 {
1215:                         ObjectValue oVal = (ObjectValue) value;
1216:                         currentDepth++;
1217:•                        for (ILexNameToken key : oVal.members.keySet())
1218:                         {
1219:                                 Value val = oVal.members.get(key);
1220:•                                if (isDebugVisible(val))
1221:                                 {
1222:                                         s.append(propertyResponse(key.getName(), key.getExplicit(true).toString(), key.getModule(), val, depth, currentDepth));
1223:                                 }
1224:                         }
1225:•                } else if (value instanceof UpdatableValue)
1226:                 {
1227:                         return propertyResponseChild(((UpdatableValue) value).deref(), depth, currentDepth, pageSize, page);
1228:
1229:•                } else if (value instanceof TransactionValue)
1230:                 {
1231:                         return propertyResponseChild(((TransactionValue) value).deref(), depth, currentDepth, pageSize, page);
1232:
1233:•                } else if (value instanceof ReferenceValue)
1234:                 {
1235:                         return propertyResponseChild(((ReferenceValue) value).deref(), depth, currentDepth, pageSize, page);
1236:
1237:•                } else if (value instanceof MapValue)
1238:                 {
1239:                         MapValue mVal = (MapValue) value;
1240:                         Value[] keys = mVal.values.keySet().toArray(new Value[mVal.values.keySet().size()]);
1241:•                        for (Integer i = page * pageSize; i < keys.length
1242:•                                        && i < (page + 1) * pageSize + 1; i++)
1243:                         {
1244:                                 Value dom = keys[i];
1245:                                 Value rng = mVal.values.get(dom);
1246:                                 Integer vdmIndex = i + 1;
1247:
1248:                                 StringBuilder entries = new StringBuilder();
1249:                                 entries.append(propertyResponse("dom", vdmIndex.toString(), "-", dom, depth, currentDepth));
1250:                                 entries.append(propertyResponse("rng", vdmIndex.toString(), "-", rng, depth, currentDepth));
1251:                                 s.append(makeProperty("Maplet "
1252:                                                 + makeDisplayId(mVal.values.keySet().size(), vdmIndex), vdmIndex.toString(), value.kind(), "", page, pageSize, true, 2, null, 2, "{"
1253:                                                 + dom + " |-> " + rng + "}", entries));
1254:                         }
1255:•                } else if (value instanceof RecordValue)
1256:                 {
1257:                         RecordValue rVal = (RecordValue) value;
1258:•                        for (Integer i = page * pageSize; i < rVal.fieldmap.size()
1259:•                                        && i < (page + 1) * pageSize + 1; i++)
1260:                         {
1261:                                 FieldValue field = rVal.fieldmap.get(i);
1262:                                 Integer vdmIndex = i + 1;
1263:                                 s.append(propertyResponse(field.name, vdmIndex.toString(), "-", field.value, depth, currentDepth));
1264:
1265:                         }
1266:•                } else if (value instanceof TupleValue)
1267:                 {
1268:                         TupleValue tVal = (TupleValue) value;
1269:•                        for (Integer i = page * pageSize; i < tVal.values.size()
1270:•                                        && i < (page + 1) * pageSize + 1; i++)
1271:                         {
1272:                                 Value v = tVal.values.get(i);
1273:                                 Integer vdmIndex = i + 1;
1274:                                 s.append(propertyResponse("#"
1275:                                                 + makeDisplayId(tVal.values.size(), vdmIndex), vdmIndex.toString(), "-", v, depth, currentDepth));
1276:
1277:                         }
1278:                 }
1279:
1280:                 return s;
1281:         }
1282:
1283:         private String makeDisplayId(Integer size, Integer vdmIndex)
1284:         {
1285:                 StringBuffer id = new StringBuffer(vdmIndex.toString());
1286:•                while (size.toString().length() > id.length())
1287:                 {
1288:                         id.insert(0, "0");
1289:                 }
1290:                 return id.toString();
1291:         }
1292:
1293:         /**
1294:          * Deref Value of Reference and Updatable Value types
1295:          *
1296:          * @param value
1297:          * The value to deref
1298:          * @return The internal value of the parameter
1299:          */
1300:         private Value deref(Value value)
1301:         {
1302:•                if (value instanceof ReferenceValue || value instanceof UpdatableValue
1303:                                 || value instanceof TransactionValue)
1304:                 {
1305:                         return value.deref();
1306:                 } else
1307:                 {
1308:                         return value;
1309:                 }
1310:         }
1311:
1312:         /**
1313:          * Determines if a value should be shown in the debug client
1314:          *
1315:          * @param v
1316:          * The value to check
1317:          * @return True if the value is allowed to be displayed in the client
1318:          */
1319:         private boolean isDebugVisible(Value v)
1320:         {
1321:•                return v instanceof ReferenceValue || v instanceof NumericValue
1322:                                 || v instanceof CharacterValue || v instanceof BooleanValue
1323:                                 || v instanceof SetValue || v instanceof SeqValue
1324:                                 || v instanceof MapValue || v instanceof TokenValue
1325:                                 || v instanceof RecordValue || v instanceof ObjectValue
1326:                                 || v instanceof NilValue || v instanceof FunctionValue;
1327:         }
1328:
1329:         /**
1330:          * Overridden to enable trace handling
1331:          */
1332:         @Override
1333:         protected boolean processRun(DBGPCommand c) throws DBGPException
1334:         {
1335:                 checkArgs(c, 1, false);
1336:
1337:•                if (status == DBGPStatus.BREAK || status == DBGPStatus.STOPPING)
1338:                 {
1339:•                        if (breakContext != null)
1340:                         {
1341:                                 breakContext.threadState.setBreaks(null, null, null);
1342:                                 status = DBGPStatus.RUNNING;
1343:                                 statusReason = DBGPReason.OK;
1344:                                 return false; // run means continue
1345:                         } else
1346:                         {
1347:                                 throw new DBGPException(DBGPErrorCode.NOT_AVAILABLE, c.toString());
1348:                         }
1349:                 }
1350:
1351:•                if (status == DBGPStatus.STARTING && expression == null)
1352:                 {
1353:                         status = DBGPStatus.RUNNING;
1354:                         statusReason = DBGPReason.OK;
1355:                         return false; // a run for a new thread, means continue
1356:                 }
1357:
1358:•                if (status != DBGPStatus.STARTING)
1359:                 {
1360:                         throw new DBGPException(DBGPErrorCode.NOT_AVAILABLE, c.toString());
1361:                 }
1362:
1363:•                if (c.data != null) // data is in "expression"
1364:                 {
1365:                         throw new DBGPException(DBGPErrorCode.INVALID_OPTIONS, c.toString());
1366:                 }
1367:
1368:•                if (remoteControl != null)
1369:                 {
1370:                         try
1371:                         {
1372:                                 status = DBGPStatus.RUNNING;
1373:                                 statusReason = DBGPReason.OK;
1374:                                 final RemoteInterpreter remoteInterpreter = new RemoteInterpreter(interpreter, this);
1375:                                 Thread remoteThread = new Thread(new Runnable()
1376:                                 {
1377:
1378:                                         public void run()
1379:                                         {
1380:                                                 try
1381:                                                 {
1382:                                                         remoteControl.run(remoteInterpreter);
1383:                                                 } catch (Exception e)
1384:                                                 {
1385:                                                         status = DBGPStatus.STOPPED;
1386:                                                         statusReason = DBGPReason.ERROR;
1387:                                                         errorResponse(DBGPErrorCode.INTERNAL_ERROR, e.getMessage());
1388:                                                 }
1389:                                         }
1390:                                 });
1391:                                 remoteThread.setName("RemoteControl runner");
1392:                                 remoteThread.setDaemon(true);
1393:                                 remoteThread.start();
1394:                                 remoteInterpreter.processRemoteCalls();
1395:                                 stdout("Remote control completed");
1396:                                 statusResponse(DBGPStatus.STOPPED, DBGPReason.OK);
1397:                                 run();
1398:
1399:                         } catch (Exception e)
1400:                         {
1401:                                 status = DBGPStatus.STOPPED;
1402:                                 statusReason = DBGPReason.ERROR;
1403:                                 errorResponse(DBGPErrorCode.INTERNAL_ERROR, e.getMessage());
1404:                         }
1405:
1406:                         return false; // Do not continue after remote session
1407:                 } else
1408:                 {
1409:                         try
1410:                         {
1411:                                 status = DBGPStatus.RUNNING;
1412:                                 statusReason = DBGPReason.OK;
1413:•                                if (!traceExpression)
1414:                                 {
1415:                                  long before = System.currentTimeMillis();
1416:•                                        if (expression.equals("###CONSOLE###"))
1417:                                         {
1418:                                                 run();
1419:                                         } else
1420:                                         {
1421:                                                 theAnswer = interpreter.execute(expression, this);
1422:                                         }
1423:                                         stdout("\n" + expression + " = " + theAnswer.toString() + "\n");
1424:                                  long after = System.currentTimeMillis();
1425:                                  stdout("Executed in " + (double)(after-before)/1000 + " secs. ");
1426:                                 } else
1427:                                 {
1428:                                         String[] parts = expression.split("\\s+");
1429:                                         int testNo = 0;
1430:                                         float reduction = 1.0F;
1431:                                         TraceReductionType reductionType = TraceReductionType.NONE;
1432:                                         long seed = 999;
1433:                                         // Test`T1 4 {subset,reduction,seed}
1434:•                                        if (parts.length >= 2 && !parts[1].startsWith("{"))
1435:                                         {
1436:                                                 try
1437:                                                 {
1438:                                                         testNo = Integer.parseInt(parts[1]);
1439:                                                 } catch (NumberFormatException e)
1440:                                                 {
1441:                                                         errorResponse(DBGPErrorCode.INTERNAL_ERROR, parts[0]
1442:                                                                         + " <name> [test number]");
1443:                                                         return true;
1444:                                                 }
1445:                                         }
1446:•                                        if (parts.length >= 2
1447:•                                                        && parts[parts.length - 1].length() > 7
1448:•                                                        && parts[parts.length - 1].startsWith("{"))
1449:                                         {
1450:                                                 try
1451:                                                 {
1452:                                                         String settings = parts[parts.length - 1];
1453:                                                         String[] tmp = settings.substring(1, settings.length() - 1).split(",");
1454:•                                                        if (tmp.length == 3)
1455:                                                         {
1456:                                                                 reduction = Float.parseFloat(tmp[0]);
1457:                                                                 reductionType = TraceReductionType.valueOf(tmp[1]);
1458:                                                                 seed = Long.parseLong(tmp[2]);
1459:                                                         }
1460:                                                 } catch (NumberFormatException e)
1461:                                                 {
1462:                                                         errorResponse(DBGPErrorCode.INTERNAL_ERROR, parts[0]
1463:                                                                         + " <name> [test number]");
1464:                                                         return true;
1465:                                                 }
1466:                                         }
1467:
1468:                                         String traceExpression1 = parts[0];
1469:
1470:                                         interpreter.runtrace(traceExpression1, testNo, true, reduction, reductionType, seed);
1471:                                         stdout("\n" + expression + " = " + "Trace completed\n");
1472:                                 }
1473:
1474:                                 statusResponse(DBGPStatus.STOPPED, DBGPReason.OK);
1475:
1476:                         } catch (ContextException e)
1477:                         {
1478:                                 dyingThread(e);
1479:                         } catch (Exception e)
1480:                         {
1481:                                 status = DBGPStatus.STOPPED;
1482:                                 statusReason = DBGPReason.ERROR;
1483:                                 errorResponse(DBGPErrorCode.EVALUATION_ERROR, e.getMessage());
1484:                         }
1485:
1486:                         return true;
1487:                 }
1488:         }
1489:
1490:         @Override
1491:         protected boolean processEval(DBGPCommand c) throws DBGPException
1492:         {
1493:                 checkArgs(c, 1, true);
1494:
1495:•                if (status != DBGPStatus.BREAK && status != DBGPStatus.STOPPING
1496:                                 || breakpoint == null)
1497:                 {
1498:                         throw new DBGPException(DBGPErrorCode.NOT_AVAILABLE, c.toString());
1499:                 }
1500:
1501:                 breaksSuspended = true;
1502:
1503:                 try
1504:                 {
1505:                         String exp = c.data; // Already base64 decoded by the parser
1506:                         interpreter.setDefaultName(breakpoint.location.getModule());
1507:                         theAnswer = interpreter.evaluate(exp, breakContext);
1508:                         StringBuilder property = propertyResponse(exp, exp, interpreter.getDefaultName(), theAnswer);
1509:                         StringBuilder hdr = new StringBuilder("success=\"1\"");
1510:                         response(hdr, property);
1511:                 } catch (Exception e)
1512:                 {
1513:                         errorResponse(DBGPErrorCode.EVALUATION_ERROR, e.getMessage());
1514:                 } finally
1515:                 {
1516:                         breaksSuspended = false;
1517:                 }
1518:
1519:                 return true;
1520:         }
1521:
1522:         @Override
1523:         protected boolean processExpr(DBGPCommand c) throws DBGPException
1524:         {
1525:                 checkArgs(c, 1, true);
1526:
1527:•                if (status == DBGPStatus.BREAK || status == DBGPStatus.STOPPING)
1528:                 {
1529:                         throw new DBGPException(DBGPErrorCode.NOT_AVAILABLE, c.toString());
1530:                 }
1531:
1532:                 try
1533:                 {
1534:                         status = DBGPStatus.RUNNING;
1535:                         statusReason = DBGPReason.OK;
1536:                         String exp = c.data; // Already base64 decoded by the parser
1537:                         theAnswer = interpreter.execute(exp, this);
1538:                         StringBuilder property = propertyResponse(exp, exp, interpreter.getDefaultName(), theAnswer);
1539:                         StringBuilder hdr = new StringBuilder("success=\"1\"");
1540:                         status = DBGPStatus.STOPPED;
1541:                         statusReason = DBGPReason.OK;
1542:                         response(hdr, property);
1543:                 } catch (ContextException e)
1544:                 {
1545:                         dyingThread(e);
1546:                 } catch (Exception e)
1547:                 {
1548:                         status = DBGPStatus.STOPPED;
1549:                         statusReason = DBGPReason.ERROR;
1550:                         errorResponse(DBGPErrorCode.EVALUATION_ERROR, e.getMessage());
1551:                 }
1552:
1553:                 return true;
1554:         }
1555:
1556:         protected boolean processExec(DBGPCommand c) throws DBGPException
1557:         {
1558:                 checkArgs(c, 1, true);
1559:                 // TODO
1560:                 // if (status == DBGPStatus.BREAK || status == DBGPStatus.STOPPING) {
1561:                 // throw new DBGPException(DBGPErrorCode.NOT_AVAILABLE, c.toString());
1562:                 // }
1563:
1564:                 try
1565:                 {
1566:                         status = DBGPStatus.RUNNING;
1567:                         statusReason = DBGPReason.OK;
1568:                         String exp = c.data; // Already base64 decoded by the parser
1569:
1570:                         DBGPReader dbgpReaderThread = newThread(null);
1571:                         DBGPExecResult result = DBGPExecProcesser.process(dbgpReaderThread, interpreter, exp);
1572:                         dbgpReaderThread.complete(DBGPReason.OK, null);
1573:                         StringBuilder property = makeProperty("", "", "", "", 0, 0, true, result.result.length(), -1, 0, result.result, new StringBuilder());
1574:                         theAnswer = new CharacterValue('l');
1575:                         StringBuilder hdr = new StringBuilder("success=\"1\"");
1576:                         status = DBGPStatus.STOPPED;
1577:                         statusReason = DBGPReason.OK;
1578:                         response(hdr, property);
1579:•                        if (result.quit)
1580:                         {
1581:                                 this.complete(DBGPReason.OK, null);
1582:                         }
1583:                 } catch (ContextException e)
1584:                 {
1585:                         dyingThread(e);
1586:                 } catch (Exception e)
1587:                 {
1588:                         status = DBGPStatus.STOPPED;
1589:                         statusReason = DBGPReason.ERROR;
1590:                         errorResponse(DBGPErrorCode.EVALUATION_ERROR, e.getMessage());
1591:                 }
1592:
1593:                 return true;
1594:         }
1595:
1596:         @Override
1597:         protected NameValuePairMap getContextValues(DBGPContextType context,
1598:                         int depth)
1599:         {
1600:                 NameValuePairMap vars = new NameValuePairMap();
1601:
1602:•                switch (context)
1603:                 {
1604:                         case LOCAL:
1605:•                                if (depth == 0)
1606:                                 {
1607:                                         vars.putAll(breakContext.getVisibleVariables());
1608:                                 } else
1609:                                 {
1610:                                         Context frame = breakContext.getFrame(depth - 1).outer;
1611:
1612:•                                        if (frame != null)
1613:                                         {
1614:                                                 vars.putAll(frame.getVisibleVariables());
1615:                                         }
1616:                                 }
1617:
1618:•                                if (breakContext instanceof ObjectContext)
1619:                                 {
1620:                                         ObjectContext octxt = (ObjectContext) breakContext;
1621:                                         int line = breakpoint.location.getStartLine();
1622:•                                        String opname = breakContext.guardOp == null ? ""
1623:                                                         : breakContext.guardOp.name.getName();
1624:
1625:•                                        for (PDefinition d : octxt.self.type.getClassdef().getDefinitions())
1626:                                         {
1627:•                                                if (d instanceof APerSyncDefinition)
1628:                                                 {
1629:                                                         APerSyncDefinition pdef = (APerSyncDefinition) d;
1630:
1631:•                                                        if (pdef.getOpname().getName().equals(opname)
1632:•                                                                        || pdef.getLocation().getStartLine() == line
1633:•                                                                        || octxt.assistantFactory.createPExpAssistant().findExpression(pdef.getGuard(), line) != null)
1634:                                                         {
1635:•                                                                for (PExp sub : octxt.assistantFactory.createPExpAssistant().getSubExpressions(pdef.getGuard()))
1636:                                                                 {
1637:•                                                                        if (sub instanceof AHistoryExp)
1638:                                                                         {
1639:                                                                                 AHistoryExp hexp = (AHistoryExp) sub;
1640:
1641:                                                                                 try
1642:                                                                                 {
1643:                                                                                         Value v = hexp.apply(VdmRuntime.getExpressionEvaluator(), octxt);
1644:                                                                                         LexNameToken name = new LexNameToken(octxt.self.type.getName().getModule(), hexp.toString(), hexp.getLocation());
1645:                                                                                         vars.put(name, v);
1646:                                                                                 } catch (Throwable e)
1647:                                                                                 {
1648:                                                                                         // Ignore
1649:                                                                                 }
1650:
1651:                                                                         }
1652:                                                                 }
1653:
1654:                                                                 break;
1655:                                                         }
1656:•                                                } else if (d instanceof AMutexSyncDefinition)
1657:                                                 {
1658:                                                         AMutexSyncDefinition mdef = (AMutexSyncDefinition) d;
1659:
1660:•                                                        for (ILexNameToken mop : mdef.getOperations())
1661:                                                         {
1662:•                                                                if (mop.getName().equals(opname))
1663:                                                                 {
1664:•                                                                        for (ILexNameToken op : mdef.getOperations())
1665:                                                                         {
1666:                                                                                 LexNameList ops = new LexNameList(op);
1667:                                                                                 PExp hexp = AstFactory.newAHistoryExp(mdef.getLocation(), new LexToken(null, VDMToken.ACTIVE), ops);
1668:
1669:                                                                                 try
1670:                                                                                 {
1671:                                                                                         Value v = hexp.apply(VdmRuntime.getExpressionEvaluator(), octxt);
1672:                                                                                         LexNameToken name = new LexNameToken(octxt.self.type.getName().getModule(), hexp.toString(), mdef.getLocation());
1673:                                                                                         vars.put(name, v);
1674:                                                                                 } catch (Throwable e)
1675:                                                                                 {
1676:                                                                                         // Ignore
1677:                                                                                 }
1678:
1679:                                                                         }
1680:
1681:                                                                         break;
1682:                                                                 }
1683:                                                         }
1684:                                                 }
1685:                                         }
1686:                                 }
1687:                                 break;
1688:
1689:                         case CLASS: // Includes modules
1690:                                 Context root = breakContext.getFrame(depth);
1691:
1692:•                                if (root instanceof ObjectContext)
1693:                                 {
1694:                                         // Filter Values based in isDebugVisible instead of
1695:                                         // vars.putAll(octxt.self.members)
1696:                                         ObjectContext octxt = (ObjectContext) root;
1697:•                                        for (ILexNameToken key : octxt.self.members.keySet())
1698:                                         {
1699:                                                 Value v = octxt.self.members.get(key);
1700:•                                                if (isDebugVisible(v))
1701:                                                 {
1702:                                                         vars.put(key, v);
1703:                                                 }
1704:                                         }
1705:•                                } else if (root instanceof ClassContext)
1706:                                 {
1707:                                         ClassContext cctxt = (ClassContext) root;
1708:                                         vars.putAll(cctxt.assistantFactory.createSClassDefinitionAssistant().getStatics(cctxt.classdef));
1709:•                                } else if (root instanceof StateContext)
1710:                                 {
1711:                                         StateContext sctxt = (StateContext) root;
1712:
1713:•                                        if (sctxt.stateCtxt != null)
1714:                                         {
1715:                                                 vars.putAll(sctxt.stateCtxt);
1716:                                         }
1717:                                 }
1718:                                 break;
1719:
1720:                         case GLOBAL:
1721:                                 vars.putAll(interpreter.initialContext);
1722:                                 break;
1723:                 }
1724:
1725:                 return vars;
1726:         }
1727:
1728:         @Override
1729:         protected void propertyGet(DBGPCommand c) throws DBGPException, IOException
1730:         {
1731:•                if (c.data != null || c.options.size() > 5)// new parameter
1732:                 {
1733:                         throw new DBGPException(DBGPErrorCode.INVALID_OPTIONS, c.toString());
1734:                 }
1735:
1736:•                if (status != DBGPStatus.BREAK && status != DBGPStatus.STOPPING)
1737:                 {
1738:                         throw new DBGPException(DBGPErrorCode.NOT_AVAILABLE, c.toString());
1739:                 }
1740:
1741:                 DBGPOption option = c.getOption(DBGPOptionType.C);
1742:                 int type = 0;
1743:
1744:•                if (option != null)
1745:                 {
1746:                         type = Integer.parseInt(option.value);
1747:                 }
1748:
1749:                 DBGPContextType context = DBGPContextType.lookup(type);
1750:
1751:                 option = c.getOption(DBGPOptionType.D);
1752:                 int depth = -1;
1753:
1754:•                if (option != null)
1755:                 {
1756:                         depth = Integer.parseInt(option.value);
1757:                 }
1758:                 //
1759:
1760:                 option = c.getOption(DBGPOptionType.P);
1761:                 int page = 0;
1762:•                if (option != null)
1763:                 {
1764:                         page = Integer.parseInt(option.value);
1765:                 }
1766:
1767:                 option = c.getOption(DBGPOptionType.K);
1768:                 Integer key;
1769:•                if (option != null)
1770:                 {
1771:                         key = Integer.parseInt(option.value);
1772:•                        if (debugValueMap.containsKey(key))
1773:                         {
1774:                                 response(null, propertyResponse(key, page));
1775:                                 return;
1776:                         }
1777:                 }
1778:                 //
1779:
1780:                 option = c.getOption(DBGPOptionType.N);
1781:
1782:•                if (option == null)
1783:                 {
1784:                         throw new DBGPException(DBGPErrorCode.CANT_GET_PROPERTY, c.toString());
1785:                 }
1786:
1787:                 LexTokenReader ltr = new LexTokenReader(option.value, Dialect.VDM_PP);
1788:                 LexToken token = null;
1789:
1790:                 try
1791:                 {
1792:                         token = ltr.nextToken();
1793:                 } catch (LexException e)
1794:                 {
1795:                         throw new DBGPException(DBGPErrorCode.CANT_GET_PROPERTY, option.value);
1796:                 } finally
1797:                 {
1798:                         ltr.close();
1799:                 }
1800:
1801:•                if (token.isNot(VDMToken.NAME))
1802:                 {
1803:                         throw new DBGPException(DBGPErrorCode.CANT_GET_PROPERTY, token.toString());
1804:                 }
1805:
1806:                 NameValuePairMap vars = getContextValues(context, depth);
1807:                 LexNameToken longname = (LexNameToken) token;
1808:                 Value value = vars.get(longname);
1809:
1810:•                if (value == null)
1811:                 {
1812:                         throw new DBGPException(DBGPErrorCode.CANT_GET_PROPERTY, longname.toString());
1813:                 }
1814:
1815:                 response(null, propertyResponse(longname, value, context));
1816:         }
1817:
1818:         private StringBuilder propertyResponse(Integer key, Integer page)
1819:                         throws UnsupportedEncodingException
1820:         {
1821:                 Value value = debugValueMap.get(key);
1822:                 StringBuilder sb = new StringBuilder();
1823:                 Integer numChildren = getChildCount(value);
1824:
1825:                 Integer pageSize = Integer.parseInt(features.getProperty(DBGPFeatures.MAX_CHILDREN));
1826:                 String data = null;
1827:                 StringBuilder nestedChildren = null;
1828:                 String name = "(ref=" + key + ")";
1829:
1830:•                if (numChildren > 0)
1831:                 {
1832:                         data = value.kind().toString();
1833:                 } else
1834:                 {
1835:                         data = value.toString();
1836:                 }
1837:                 Integer defaultPageSize = Integer.parseInt(features.getProperty(DBGPFeatures.MAX_CHILDREN));
1838:                 sb.append(propertyResponseChild(value, 1, 0, defaultPageSize, page));
1839:                 nestedChildren = propertyResponseChild(value, 1, 0, defaultPageSize, page);
1840:
1841:•                boolean constant = numChildren > 0
1842:                                 || !(value instanceof UpdatableValue);
1843:
1844:                 return makeProperty(name, name, value.kind(), "", page, pageSize, constant, data.length(), key, numChildren, data, nestedChildren);
1845:         }
1846:
1847:         @Override
1848:         protected void processOvertureCmd(DBGPCommand c) throws DBGPException,
1849:                         IOException, URISyntaxException, AnalysisException
1850:         {
1851:                 checkArgs(c, 2, false);
1852:                 DBGPOption option = c.getOption(DBGPOptionType.C);
1853:
1854:•                if (option == null)
1855:                 {
1856:                         throw new DBGPException(DBGPErrorCode.INVALID_OPTIONS, c.toString());
1857:                 }
1858:•                if (option.value.startsWith(DBGPXCmdOvertureCommandType.LATEX.toString()))
1859:                 {
1860:                         processLatex(c);
1861:                 } else
1862:                 {
1863:                         DBGPXCmdOvertureCommandType xcmd = DBGPXCmdOvertureCommandType.lookup(option.value);
1864:
1865:•                        switch (xcmd)
1866:                         {
1867:                                 case INIT:
1868:                                         processInit(c);
1869:                                         break;
1870:                                 case CREATE:
1871:                                         processCreate(c);
1872:                                         break;
1873:                                 case CURRENT_LINE:
1874:                                         processCurrentLine(c);
1875:                                         break;
1876:                                 case SOURCE:
1877:                                         processCurrentSource(c);
1878:                                         break;
1879:                                 case COVERAGE:
1880:                                         processCoverage(c);
1881:                                         break;
1882:                                 case WRITE_COMPLETE_COVERAGE:
1883:                                         processWriteCoverage(c);
1884:                                         break;
1885:                                 case POG:
1886:                                         processPOG(c);
1887:                                         break;
1888:                                 case STACK:
1889:                                         processStack(c);
1890:                                         break;
1891:                                 case TRACE:
1892:                                         processTrace(c);
1893:                                         break;
1894:                                 case LIST:
1895:                                         processList();
1896:                                         break;
1897:                                 case FILES:
1898:                                         processFiles();
1899:                                         break;
1900:                                 case CLASSES:
1901:                                         processClasses(c);
1902:                                         break;
1903:                                 case MODULES:
1904:                                         processModules(c);
1905:                                         break;
1906:                                 case DEFAULT:
1907:                                         processDefault(c);
1908:                                         break;
1909:                                 case LOG:
1910:                                         processLog(c);
1911:                                         break;
1912:                                 default:
1913:                                         throw new DBGPException(DBGPErrorCode.INVALID_OPTIONS, c.toString());
1914:
1915:                         }
1916:                 }
1917:         }
1918:
1919:         private void processClasses(DBGPCommand c) throws IOException,
1920:                         DBGPException
1921:         {
1922:•                if (!(interpreter instanceof ClassInterpreter))
1923:                 {
1924:                         throw new DBGPException(DBGPErrorCode.INTERNAL_ERROR, c.toString());
1925:                 }
1926:
1927:                 ClassInterpreter cinterpreter = (ClassInterpreter) interpreter;
1928:                 String def = cinterpreter.getDefaultName();
1929:                 ClassList classes = cinterpreter.getClasses();
1930:                 OutputStream out = new ByteArrayOutputStream();
1931:                 PrintWriter pw = new PrintWriter(out);
1932:
1933:•                for (SClassDefinition cls : classes)
1934:                 {
1935:•                        if (cls.getName().getName().equals(def))
1936:                         {
1937:                                 pw.println(cls.getName().getName() + " (default)");
1938:                         } else
1939:                         {
1940:                                 pw.println(cls.getName().getName());
1941:                         }
1942:                 }
1943:
1944:                 pw.close();
1945:                 cdataResponse(out.toString());
1946:         }
1947:
1948:         private void processModules(DBGPCommand c) throws DBGPException,
1949:                         IOException
1950:         {
1951:•                if (!(interpreter instanceof ModuleInterpreter))
1952:                 {
1953:                         throw new DBGPException(DBGPErrorCode.INTERNAL_ERROR, c.toString());
1954:                 }
1955:
1956:                 ModuleInterpreter minterpreter = (ModuleInterpreter) interpreter;
1957:                 String def = minterpreter.getDefaultName();
1958:                 List<AModuleModules> modules = minterpreter.getModules();
1959:                 OutputStream out = new ByteArrayOutputStream();
1960:                 PrintWriter pw = new PrintWriter(out);
1961:
1962:•                for (AModuleModules m : modules)
1963:                 {
1964:•                        if (m.getName().getName().equals(def))
1965:                         {
1966:                                 pw.println(m.getName().getName() + " (default)");
1967:                         } else
1968:                         {
1969:                                 pw.println(m.getName().getName());
1970:                         }
1971:                 }
1972:
1973:                 pw.close();
1974:                 cdataResponse(out.toString());
1975:         }
1976:
1977:         /**
1978:          * Overrides processLog to support URI file format and xcmdOvertureResponse as reply
1979:          */
1980:         @Override
1981:         protected void processLog(DBGPCommand c) throws IOException
1982:         {
1983:                 StringBuilder out = new StringBuilder();
1984:
1985:                 try
1986:                 {
1987:•                        if (c.data == null)
1988:                         {
1989:•                                if (RTLogger.getLogSize() > 0)
1990:                                 {
1991:                                         out.append("Flushing " + RTLogger.getLogSize()
1992:                                                         + " RT events\n");
1993:                                 }
1994:
1995:                                 RTLogger.setLogfile(RTTextLogger.class, null);
1996:                                 RTLogger.setLogfile(NextGenRTLogger.class, (File) null);
1997:                                 out.append("RT events now logged to the console");
1998:•                        } else if (c.data.equals("off"))
1999:                         {
2000:                                 RTLogger.enable(false);
2001:                                 out.append("RT event logging disabled");
2002:                         } else
2003:                         {
2004:                                 File file = new File(new URI(c.data));
2005:                                 RTLogger.setLogfile(RTTextLogger.class, file);
2006:                                 out.append("RT events now logged to " + c.data);
2007:                         }
2008:                 } catch (FileNotFoundException e)
2009:                 {
2010:                         out.append("Cannot create RT event log: " + e.getMessage());
2011:                 } catch (URISyntaxException e)
2012:                 {
2013:                         out.append("Cannot decode log file from URI: " + e.getMessage());
2014:                 }
2015:
2016:                 xcmdOvertureResponse(DBGPXCmdOvertureCommandType.LOG, null, out);
2017:         }
2018:
2019:         @Override
2020:         protected void processStack(DBGPCommand c) throws IOException,
2021:                         DBGPException
2022:         {
2023:•                if (status != DBGPStatus.BREAK && status != DBGPStatus.STOPPING
2024:                                 || breakpoint == null)
2025:                 {
2026:                         throw new DBGPException(DBGPErrorCode.NOT_AVAILABLE, c.toString());
2027:                 }
2028:
2029:                 OutputStream out = new ByteArrayOutputStream();
2030:                 PrintWriter pw = new PrintWriter(out);
2031:                 pw.println("Stopped at " + breakpoint);
2032:                 breakContext.printStackTrace(pw, true);
2033:                 pw.close();
2034:                 cdataResponse(out.toString());
2035:         }
2036:
2037:         private void processWriteCoverage(DBGPCommand c) throws DBGPException,
2038:                         IOException, URISyntaxException
2039:         {
2040:                 // if (status == DBGPStatus.BREAK) {
2041:                 // throw new DBGPException(DBGPErrorCode.NOT_AVAILABLE, c.toString());
2042:                 // }
2043:
2044:                 File file = new File(new URI(c.data));
2045:
2046:•                if (file == null || file.getName().length() == 0)
2047:                 {
2048:                         cdataResponse(file + ": folder not found");
2049:                 } else
2050:                 {
2051:                         file.mkdirs();
2052:                         writeCoverage(interpreter, file);
2053:                         StringBuilder hdr = new StringBuilder("success=\"1\"");
2054:                         StringBuilder sb = new StringBuilder();
2055:                         sb.append("Coverage written to: " + file.toURI().toASCIIString());
2056:                         xcmdOvertureResponse(DBGPXCmdOvertureCommandType.WRITE_COMPLETE_COVERAGE, hdr, sb);
2057:                 }
2058:         }
2059:
2060:         public static void writeCoverage(Interpreter interpreter, File coverage)
2061:                         throws IOException
2062:         {
2063:
2064:                 Properties.init(); // Read properties file, if any
2065:
2066:•                for (File f : interpreter.getSourceFiles())
2067:                 {
2068:
2069:                         SourceFile source = interpreter.getSourceFile(f);
2070:
2071:                         File data = new File(coverage.getPath() + File.separator
2072:                                         + f.getName() + ".covtbl");
2073:                         PrintWriter pw = new PrintWriter(data);
2074:                         source.writeCoverage(pw);
2075:                         pw.close();
2076:
2077:                 }
2078:
2079:                 Properties.parser_tabstop = 1;// required to match locations with the editor representation
2080:         }
2081:
2082:         public static String getStackTrace(Throwable t)
2083:         {
2084:                 StringWriter sw = new StringWriter();
2085:                 PrintWriter pw = new PrintWriter(sw, true);
2086:                 t.printStackTrace(pw);
2087:                 pw.flush();
2088:                 sw.flush();
2089:                 return sw.toString();
2090:         }
2091:
2092: }