summaryrefslogtreecommitdiff
path: root/lib/tracer.rb
blob: ef03fe09c9043aa66dd71192d763689922738f46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/local/bin/ruby
#
#   tracer.rb - 
#   	$Release Version: 0.2$
#   	$Revision: 1.6 $
#   	$Date: 1998/02/02 08:12:02 $
#   	by Keiju ISHITSUKA(Nippon Rational Inc.)
#
# --
#
#   
#

#
# tracer main class
#
class Tracer
  RCS_ID='-$Id: tracer.rb,v 1.6 1998/02/02 08:12:02 keiju Exp keiju $-'
  
  MY_FILE_NAME = caller(0)[0].scan(/^(.*):[0-9]+$/)[0]
  
  EVENT_SYMBOL = {
    "line" => "-",
    "call" => ">",
    "return" => "<",
    "class" => "C",
    "end" => "E"}
  
  def initialize
    @threads = Hash.new
    if defined? Thread.main
      @threads[Thread.main.id] = 0
    else
      @threads[Thread.current.id] = 0
    end

    @sources = Hash.new
  end
  
  def on
    if iterator?
      on
      begin
	yield
      ensure
	off
      end
    else
      set_trace_func proc{|event, file, line, id, binding|
	trace_func event, file, line, id, binding
      }
      print "Trace on\n"
    end
  end
  
  def off
    set_trace_func nil
    print "Trace off\n"
  end
  
  def get_line(file, line)
    unless list = @sources[file]
#      print file if $DEBUG
      begin
	f = open(file)
	begin 
	  @sources[file] = list = f.readlines
	ensure
	  f.close
	end
      rescue
	@sources[file] = list = []
      end
    end
    if l = list[line - 1]
      l
    else
      "-\n"
    end
  end
  
  def get_thread_no
    if no = @threads[Thread.current.id]
      no
    else
      @threads[Thread.current.id] = @threads.size
    end
  end
  
  def trace_func(event, file, line, id, binding)
    return if file == MY_FILE_NAME
    #printf "Th: %s\n", Thread.current.inspect
    
    Thread.critical = TRUE
    printf("#%d:%s:%d:%s: %s",
	   get_thread_no,
	   file,
	   line,
	   EVENT_SYMBOL[event],
	   get_line(file, line))
    Thread.critical = FALSE
  end

  Single = new
  def Tracer.on
    Single.on
  end
  
  def Tracer.off
    Single.off
  end
  
end

if caller(0).size == 1
  if $0 == Tracer::MY_FILE_NAME
    # direct call
    
    $0 = ARGV[0]
    ARGV.shift
    Tracer.on
    require $0
  else
    Tracer.on
  end
end