protected void FormatObjectRecursed(Thread target, TargetObject obj, bool recursed) { try { if (DisplayFormat == DisplayFormat.Address) { if (obj.HasAddress) { Append(obj.GetAddress(target).ToString()); } else { Append("<cannot get address>"); } return; } else if (obj.HasAddress && obj.GetAddress(target).IsNull) { Append("null"); return; } else if (!recursed) { FormatObject(target, obj); return; } switch (obj.Kind) { case TargetObjectKind.Enum: FormatObject(target, obj); break; case TargetObjectKind.Fundamental: TargetFundamentalObject fobj = (TargetFundamentalObject)obj; object value = fobj.GetObject(target); Format(target, value); break; case TargetObjectKind.Nullable: FormatNullable(target, (TargetNullableObject)obj); break; default: PrintObject(target, obj); break; } } catch { Append("<cannot display object>"); } }
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; } }