protected override string Execute(ScriptingContext context, Expression expression, DisplayFormat format) { try { if (expression is TypeExpression) throw new ScriptingException ( "`{0}' is a type, not a variable.", expression.Name); object retval = expression.Evaluate (context); EmonicInterpreter.printData output = new EmonicInterpreter.printData(); output.type = ""; output.varValue = ""; output.varNames = ""; if (retval != null) { output.type = ((TargetObject)retval).TypeName; if (output.type == null) output.type = ""; switch (((TargetObject)retval).Kind) { case TargetObjectKind.Fundamental: // we send the value of the fundamental type TargetFundamentalObject tfo = retval as TargetFundamentalObject; if (tfo == null) { // element is "null" output.varValue = "<null>"; break; } output.varValue = tfo.GetObject(context.CurrentThread).ToString(); if (output.varValue == null) output.varValue = ""; break; case TargetObjectKind.Array: // we send back the number of array elements TargetArrayObject tao = retval as TargetArrayObject; if (tao == null) { // element is "null" output.varValue = "<null>"; break; } int lower = tao.GetLowerBound (context.CurrentThread, 0); int upper = tao.GetUpperBound (context.CurrentThread, 0); output.varNames = (upper-lower).ToString(); break; // same for struct and class case TargetObjectKind.Struct: case TargetObjectKind.Class: // we send back the member's names // NOTE! we also show static and constant fields TargetObject obj = retval as TargetObject; if (obj.HasAddress && obj.GetAddress(context.CurrentThread).IsNull) { output.varValue = "<null>"; break; } Mono.Debugger.Thread thread = context.CurrentThread; TargetClass tc = ((TargetClassObject)retval).Type.GetClass(thread); if (tc == null) break; TargetFieldInfo[] tfi = tc.GetFields(thread); if (tfi == null) break; output.varNames = ""; for (int i=0; i<tfi.Length; i++) { if (tfi[i].IsStatic) // do not show static fields, they're not accessible via the instance! continue; output.varNames += tfi[i].Name; output.varNames += " "; } output.varNames = output.varNames.Trim(); break; case TargetObjectKind.Object: case TargetObjectKind.Pointer: case TargetObjectKind.Unknown: case TargetObjectKind.Function: case TargetObjectKind.Alias: case TargetObjectKind.Enum: context.Print("ERROR: Print Command will return no values because of an implementation error"); break; } } string text = context.FormatObject (retval, format); context.Print (text); EmonicInterpreter.printOutput = output; EmonicInterpreter.printSem.Release(); return text; } catch { EmonicInterpreter.printData output = new EmonicInterpreter.printData(); output.type = ""; output.varValue = ""; output.varNames = ""; EmonicInterpreter.printOutput = output; EmonicInterpreter.printSem.Release(); throw; } }
public EmonicInterpreter.printData Print(string variableName) { if (!EmonicInterpreter.IsCurrentThreadStopped()) { // would block if current thread is not stopped! EmonicInterpreter.printData error = new EmonicInterpreter.printData(); error.type = error.varValue = error.varNames = ""; return error; } EmonicLineInterpreter.AddCmd("print "+variableName); EmonicInterpreter.printData pd = EmonicInterpreter.GetPrintOutput(); return pd; }
// copied that from PrintCommand class - we need that here because we need // to know if any exceptions in this method are raised protected override bool DoResolve(ScriptingContext context) { // whole method in a try-catch block - if any exceptions occur, we are able to generate // an invalid web service response and release the semaphore try { if (Argument.StartsWith ("/")) { int pos = Argument.IndexOfAny (new char[] { ' ', '\t' }); string fstring = Argument.Substring (1, pos-1); string arg = Argument.Substring (pos + 1); switch (fstring) { case "o": case "object": format = DisplayFormat.Object; break; case "a": case "address": format = DisplayFormat.Address; break; case "x": case "hex": format = DisplayFormat.HexaDecimal; break; case "default": format = DisplayFormat.Default; break; default: throw new ScriptingException ( "Unknown format: `{0}'", fstring); } expression = DoParseExpression (context, arg); } else expression = ParseExpression (context); if (expression == null) return false; expression = expression.Resolve (context); return expression != null; } catch { EmonicInterpreter.printData output = new EmonicInterpreter.printData(); output.type = ""; output.varValue = ""; output.varNames = ""; EmonicInterpreter.printOutput = output; EmonicInterpreter.printSem.Release(); throw; } }