KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > kawa > standard > TracedProcedure


1 package kawa.standard;
2 import gnu.mapping.*;
3 import java.io.PrintWriter JavaDoc;
4 import gnu.math.IntNum;
5 import gnu.kawa.functions.ObjectFormat;
6
7 /** A TracedProcedure is a Procedure wrapper that writes trace output. */
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 JavaDoc name = proc.getName();
22     if (name != null)
23       setName(name);
24   }
25
26   static void put(Object JavaDoc value, PrintWriter JavaDoc out)
27   {
28     try
29       {
30     if (! ObjectFormat.format(value, out, 50, true))
31       out.print("...");
32       }
33     catch (java.io.IOException JavaDoc ex)
34       {
35     out.print("<caught ");
36     out.print(ex);
37     out.print('>');
38       }
39   }
40
41   static void indent(int i, PrintWriter JavaDoc out)
42   {
43     while (--i >= 0)
44       out.print(' ');
45   }
46
47   public Object JavaDoc applyN(Object JavaDoc[] args) throws Throwable JavaDoc
48   {
49     if (enabled)
50       {
51     Environment env = Environment.getCurrent();
52     Location curIndentLoc = env.getLocation(curIndentSym);
53     Object JavaDoc 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 JavaDoc out = OutPort.errDefault();
63     String JavaDoc name = getName();
64     if (name == null)
65       name = "??";
66
67         // Print the call arguments (indented).
68
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         // Now do the actual call, but with the indentation incremented.
82
CallContext context = CallContext.getInstance();
83         IntNum newIndentation = IntNum.make(curIndent+indentationStep);
84     Object JavaDoc result;
85     Object JavaDoc save = curIndentLoc.setWithSave(newIndentation, context);
86         try
87           {
88             result = proc.applyN(args);
89           }
90         catch (RuntimeException JavaDoc 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         // Print the result (indented).
102
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 JavaDoc ps)
125   {
126     ps.print ("#<procedure ");
127     String JavaDoc 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