Class: FunctionGraph

Inherits:
RGL::DirectedAdjacencyGraph
  • Object
show all
Defined in:
lib/codegraph.rb

Direct Known Subclasses

EightFunctionGraph, SingleFunctionGraph

Constant Summary collapse

Params =

Theses Parameters are used by interactive representation and for the file generation function to_dot and to_type. They can only be given for the whole graph, not for a singel node. This could be done by extending the dot.rb file of the Ruby Graph Library

{'rankdir'     => 'LR',
'ranksep'     => '4.0',
'concentrate' => 'TRUE',
'label'       => '',
'fontsize'    => '12'}
@@home =
ENV['HOME']
@@codehomedir =
"#{@@home}/.codegraph"
@@filesDB =
@@codehomedir+'/filesDB.json'
@@funxDB =
@@codehomedir+'/funxDB.json'
@@matchBeforFuncName =
$options[:matchBefor].nil? ? '[^A-z0-9_]\s*': $options[:matchBefor]
@@matchAfterFuncName =
$options[:matchAfter].nil? ? '( *\(| |$)'   : $options[:matchAfter]
@@map =
Asciify::Mapping.new(:default)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeFunctionGraph

Returns a new instance of FunctionGraph.



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/codegraph.rb', line 43

def initialize
   super
   @debug   = false
   # the following attribute will hold the functionnames and their bodies
   @funx    = Hash.new
   @lock    = Mutex.new
   @filesDB = File.exist?(@@filesDB) ? JSON.parse(File.open(@@filesDB).read) : Hash.new
   @filesCk = @db.hash
   @funxDB  = File.exist?(@@funxDB) ? JSON.parse(File.open(@@funxDB).read) : Hash.new
   @funxCk  = @funxDB.hash

   @adds, @excludes = [],[]
end

Instance Attribute Details

#addsObject

Returns the value of attribute adds.



16
17
18
# File 'lib/codegraph.rb', line 16

def adds
  @adds
end

#debugObject

Returns the value of attribute debug.



16
17
18
# File 'lib/codegraph.rb', line 16

def debug
  @debug
end

#excludesObject

Returns the value of attribute excludes.



16
17
18
# File 'lib/codegraph.rb', line 16

def excludes
  @excludes
end

#funxObject

Returns the value of attribute funx.



16
17
18
# File 'lib/codegraph.rb', line 16

def funx
  @funx
end

Instance Method Details

#displayObject

Display the graph with an interactive viewer



209
210
211
212
# File 'lib/codegraph.rb', line 209

def display
   dotty(Params)
   system("rm graph.dot") if File.exist?("graph.dot")
end

#display_functionbody(name) ⇒ Object



176
177
178
# File 'lib/codegraph.rb', line 176

def display_functionbody(name)
  @funx[name]
end

#fill(filelist, exclude = []) ⇒ Object

fill the graph with all functions found in <filelist> while all functions from <exclude> aren’t recognized



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/codegraph.rb', line 130

def fill(filelist,exclude=[])
  threads = []
   # generate the necessary files and fill @funx
   genFiles(self,filelist,exclude)

   # scan functions for the function names
   names = @funx.keys
   @funx.each_pair {|name,body|
#        threads=[];threads << Thread.new(name,body,names) {|name,body,names|
       puts "Add func: #{name}" if @debug
       # Check if this body is in the funx DB
       bodyCk = Digest::SHA256.hexdigest(body)
       if @funxDB.has_key?(bodyCk) and @funxDB[name] == body
         edges = @funxDB[bodyCk]
         edges.each {|edge| add_edge(*edge)}
       else
         edges = []
         add_vertex(name)
         (names - [name] + @adds).each { |func|
           puts body if @debug and false
           puts func
           if/#@@matchBeforFuncName#{func}#@@matchAfterFuncName/.match(body)
             edge = ["#{name}","#{func}"]
             add_edge(*edge)
             edges << edge
           end
         }
#            @lock.synchronize { 
           @funxDB[bodyCk] = edges
           @funxDB[name]   = body
#            }
       end
#        }
   }
   threads.each {|t| t.join}
  updateFunxDB
end

#limit(depth) ⇒ Object



168
169
170
171
172
173
174
# File 'lib/codegraph.rb', line 168

def limit(depth)
  dv = RGL::DFSVisitor.new(self)
  dv.attach_distance_map
  self.depth_first_search(dv) {|u|
    self.remove_vertex(u) if dv.distance_to_root(u) > depth
  }
end

#to_dot(filename) ⇒ Object

Creates a simple dot file according to the above <Params>. Parameters for the nodes are not supported by rgl.



181
182
183
184
185
# File 'lib/codegraph.rb', line 181

def to_dot(filename)
   File.open(filename,"w") {|f|
      print_dotted_on(Params,f)
   }
end

#to_txtObject

Generates pairs of “func_A -> func_B” to stdout



188
189
190
191
192
# File 'lib/codegraph.rb', line 188

def to_txt
   each_edge do |left,right|
      print left,' -> ',right,"\n"
   end
end

#to_type(filename, type) ⇒ Object

This function generates a file of the given type using the dot utility. Supported Types are PS, PNG, JPG, DOT and SVG.



196
197
198
199
200
201
202
203
204
205
206
# File 'lib/codegraph.rb', line 196

def to_type(filename,type)
   if File.exist?(filename) 
      system("rm #{filename}")
   end
   if File.exist?(filename+"."+type) 
      system("rm #{filename}."+type)
   end
   to_dot(filename+".dot")
   system("dot -T#{type} -o #{filename} -Nshape=box #{filename}.dot")
   system("rm #{filename}.dot")
end