1 package kawa.standard; 2 import gnu.mapping.*; 3 import java.io.PrintWriter ; 4 import gnu.math.IntNum; 5 import gnu.kawa.functions.ObjectFormat; 6 7 8 9 public class TracedProcedure extends ProcedureN 10 { 11 public Procedure proc; 12 boolean enabled; 13 14 static int indentationStep = 2; 15 static Symbol curIndentSym = Symbol.makeUninterned("current-indentation"); 16 17 public TracedProcedure (Procedure proc, boolean enable) 18 { 19 this.proc = proc; 20 this.enabled = enable; 21 String name = proc.getName(); 22 if (name != null) 23 setName(name); 24 } 25 26 static void put(Object value, PrintWriter out) 27 { 28 try 29 { 30 if (! ObjectFormat.format(value, out, 50, true)) 31 out.print("..."); 32 } 33 catch (java.io.IOException ex) 34 { 35 out.print("<caught "); 36 out.print(ex); 37 out.print('>'); 38 } 39 } 40 41 static void indent(int i, PrintWriter out) 42 { 43 while (--i >= 0) 44 out.print(' '); 45 } 46 47 public Object applyN(Object [] args) throws Throwable 48 { 49 if (enabled) 50 { 51 Environment env = Environment.getCurrent(); 52 Location curIndentLoc = env.getLocation(curIndentSym); 53 Object oldIndent = curIndentLoc.get(null); 54 int curIndent; 55 if (! (oldIndent instanceof IntNum)) 56 { 57 curIndent = 0; 58 curIndentLoc.set(IntNum.zero()); 59 } 60 else 61 curIndent = ((IntNum) oldIndent).intValue(); 62 PrintWriter out = OutPort.errDefault(); 63 String name = getName(); 64 if (name == null) 65 name = "??"; 66 67 indent(curIndent, out); 69 out.print("call to "); 70 out.print(name); 71 int len = args.length; 72 out.print(" ("); 73 for (int i = 0; i < len; i++) 74 { 75 if (i > 0) 76 out.print(' '); 77 put(args[i], out); 78 } 79 out.println(")"); 80 81 CallContext context = CallContext.getInstance(); 83 IntNum newIndentation = IntNum.make(curIndent+indentationStep); 84 Object result; 85 Object save = curIndentLoc.setWithSave(newIndentation, context); 86 try 87 { 88 result = proc.applyN(args); 89 } 90 catch (RuntimeException e) 91 { 92 indent(curIndent, out); 93 out.println("procedure " + name + " throws exception " + e); 94 throw e; 95 } 96 finally 97 { 98 curIndentLoc.setRestore(save, context); 99 } 100 101 indent(curIndent, out); 103 out.print("return from "); 104 out.print(name); 105 out.print(" => "); 106 put(result, out); 107 out.println(); 108 return result; 109 } 110 return proc.applyN(args); 111 } 112 113 public static Procedure doTrace(Procedure proc, boolean enable) 114 { 115 if (proc instanceof TracedProcedure) 116 { 117 ((TracedProcedure) proc).enabled = enable; 118 return proc; 119 } 120 else 121 return new TracedProcedure(proc, enable); 122 } 123 124 public void print(java.io.PrintWriter ps) 125 { 126 ps.print ("#<procedure "); 127 String n = getName(); 128 if (n == null) 129 ps.print ("<unnamed>"); 130 else 131 ps.print (n); 132 ps.print(enabled? ", traced>" : ">"); 133 } 134 } 135 | Popular Tags |