* transcode.c (trans_open_i): check the result of rb_transcoding_open.
[ruby-svn.git] / lib / tracer.rb
blob1fdc6089602642e66d36e9d92fba6ed302f232ec
2 #   tracer.rb - 
3 #       $Release Version: 0.2$
4 #       $Revision: 1.8 $
5 #       by Keiju ISHITSUKA(Nippon Rational Inc.)
7 # --
9 #   
13 # tracer main class
15 class Tracer
16   @RCS_ID='-$Id: tracer.rb,v 1.8 1998/05/19 03:42:49 keiju Exp keiju $-'
18   @stdout = STDOUT
19   @verbose = false
20   class << self
21     attr_accessor :verbose
22     alias verbose? verbose
23     attr_accessor :stdout
24   end
25   
26   EVENT_SYMBOL = {
27     "line" => "-",
28     "call" => ">",
29     "return" => "<",
30     "class" => "C",
31     "end" => "E",
32     "c-call" => ">",
33     "c-return" => "<",
34   }
35   
36   def initialize
37     @threads = Hash.new
38     if defined? Thread.main
39       @threads[Thread.main.object_id] = 0
40     else
41       @threads[Thread.current.object_id] = 0
42     end
44     @get_line_procs = {}
46     @filters = []
47   end
48   
49   def stdout
50     Tracer.stdout
51   end
53   def on
54     if block_given?
55       on
56       begin
57         yield
58       ensure
59         off
60       end
61     else
62       set_trace_func method(:trace_func).to_proc
63       stdout.print "Trace on\n" if Tracer.verbose?
64     end
65   end
66   
67   def off
68     set_trace_func nil
69     stdout.print "Trace off\n" if Tracer.verbose?
70   end
72   def add_filter(p = proc)
73     @filters.push p
74   end
76   def set_get_line_procs(file, p = proc)
77     @get_line_procs[file] = p
78   end
79   
80   def get_line(file, line)
81     if p = @get_line_procs[file]
82       return p.call(line)
83     end
85     unless list = SCRIPT_LINES__[file]
86       begin
87         f = open(file)
88         begin 
89           SCRIPT_LINES__[file] = list = f.readlines
90         ensure
91           f.close
92         end
93       rescue
94         SCRIPT_LINES__[file] = list = []
95       end
96     end
98     if l = list[line - 1]
99       l
100     else
101       "-\n"
102     end
103   end
104   
105   def get_thread_no
106     if no = @threads[Thread.current.object_id]
107       no
108     else
109       @threads[Thread.current.object_id] = @threads.size
110     end
111   end
112   
113   def trace_func(event, file, line, id, binding, klass, *)
114     return if file == __FILE__
115     
116     for p in @filters
117       return unless p.call event, file, line, id, binding, klass
118     end
119     
120     # saved_crit = Thread.critical
121     # Thread.critical = true
122     stdout.printf("#%d:%s:%d:%s:%s: %s",
123       get_thread_no,
124       file,
125       line,
126       klass || '',
127       EVENT_SYMBOL[event],
128       get_line(file, line))
129     # Thread.critical = saved_crit
130   end
132   Single = new
133   def Tracer.on
134     if block_given?
135       Single.on{yield}
136     else
137       Single.on
138     end
139   end
140   
141   def Tracer.off
142     Single.off
143   end
144   
145   def Tracer.set_get_line_procs(file_name, p = proc)
146     Single.set_get_line_procs(file_name, p)
147   end
149   def Tracer.add_filter(p = proc)
150     Single.add_filter(p)
151   end
152   
155 SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
157 if $0 == __FILE__
158   # direct call
159     
160   $0 = ARGV[0]
161   ARGV.shift
162   Tracer.on
163   require $0
164 elsif caller(0).size == 1
165   Tracer.on