rgl 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. data/ChangeLog +74 -0
  2. data/Makefile +72 -0
  3. data/README +240 -0
  4. data/Rakefile +210 -0
  5. data/TAGS +209 -0
  6. data/examples/canvas.rb +103 -0
  7. data/examples/codegraph +238 -0
  8. data/examples/example.jpg +0 -0
  9. data/examples/examples.rb +112 -0
  10. data/examples/graph.dot +54 -0
  11. data/examples/graph.png +0 -0
  12. data/examples/module_graph.jpg +0 -0
  13. data/examples/north.rb +12 -0
  14. data/examples/north/Graph.log +128 -0
  15. data/examples/north/g.10.0.graphml +28 -0
  16. data/examples/north/g.10.1.graphml +28 -0
  17. data/examples/north/g.10.11.graphml +31 -0
  18. data/examples/north/g.10.12.graphml +27 -0
  19. data/examples/north/g.10.13.graphml +27 -0
  20. data/examples/north/g.10.14.graphml +27 -0
  21. data/examples/north/g.10.15.graphml +26 -0
  22. data/examples/north/g.10.16.graphml +26 -0
  23. data/examples/north/g.10.17.graphml +26 -0
  24. data/examples/north/g.10.19.graphml +37 -0
  25. data/examples/north/g.10.2.graphml +28 -0
  26. data/examples/north/g.10.20.graphml +38 -0
  27. data/examples/north/g.10.22.graphml +43 -0
  28. data/examples/north/g.10.24.graphml +30 -0
  29. data/examples/north/g.10.25.graphml +45 -0
  30. data/examples/north/g.10.27.graphml +38 -0
  31. data/examples/north/g.10.28.graphml +30 -0
  32. data/examples/north/g.10.29.graphml +38 -0
  33. data/examples/north/g.10.3.graphml +26 -0
  34. data/examples/north/g.10.30.graphml +34 -0
  35. data/examples/north/g.10.31.graphml +42 -0
  36. data/examples/north/g.10.34.graphml +42 -0
  37. data/examples/north/g.10.37.graphml +28 -0
  38. data/examples/north/g.10.38.graphml +38 -0
  39. data/examples/north/g.10.39.graphml +36 -0
  40. data/examples/north/g.10.4.graphml +26 -0
  41. data/examples/north/g.10.40.graphml +37 -0
  42. data/examples/north/g.10.41.graphml +37 -0
  43. data/examples/north/g.10.42.graphml +26 -0
  44. data/examples/north/g.10.45.graphml +28 -0
  45. data/examples/north/g.10.46.graphml +32 -0
  46. data/examples/north/g.10.5.graphml +31 -0
  47. data/examples/north/g.10.50.graphml +30 -0
  48. data/examples/north/g.10.56.graphml +29 -0
  49. data/examples/north/g.10.57.graphml +32 -0
  50. data/examples/north/g.10.58.graphml +32 -0
  51. data/examples/north/g.10.6.graphml +26 -0
  52. data/examples/north/g.10.60.graphml +32 -0
  53. data/examples/north/g.10.61.graphml +34 -0
  54. data/examples/north/g.10.62.graphml +34 -0
  55. data/examples/north/g.10.68.graphml +30 -0
  56. data/examples/north/g.10.69.graphml +32 -0
  57. data/examples/north/g.10.7.graphml +29 -0
  58. data/examples/north/g.10.70.graphml +26 -0
  59. data/examples/north/g.10.71.graphml +27 -0
  60. data/examples/north/g.10.72.graphml +28 -0
  61. data/examples/north/g.10.74.graphml +29 -0
  62. data/examples/north/g.10.75.graphml +29 -0
  63. data/examples/north/g.10.78.graphml +27 -0
  64. data/examples/north/g.10.79.graphml +34 -0
  65. data/examples/north/g.10.8.graphml +29 -0
  66. data/examples/north/g.10.80.graphml +34 -0
  67. data/examples/north/g.10.82.graphml +35 -0
  68. data/examples/north/g.10.83.graphml +32 -0
  69. data/examples/north/g.10.85.graphml +34 -0
  70. data/examples/north/g.10.86.graphml +34 -0
  71. data/examples/north/g.10.88.graphml +37 -0
  72. data/examples/north/g.10.89.graphml +29 -0
  73. data/examples/north/g.10.9.graphml +26 -0
  74. data/examples/north/g.10.90.graphml +32 -0
  75. data/examples/north/g.10.91.graphml +31 -0
  76. data/examples/north/g.10.92.graphml +26 -0
  77. data/examples/north/g.10.93.graphml +32 -0
  78. data/examples/north/g.10.94.graphml +34 -0
  79. data/examples/north/g.12.8.graphml +40 -0
  80. data/examples/north/g.14.9.graphml +36 -0
  81. data/examples/north2.rb +21 -0
  82. data/examples/rdep-rgl.rb +395 -0
  83. data/install.rb +49 -0
  84. data/lib/rgl/adjacency.rb +151 -0
  85. data/lib/rgl/base.rb +299 -0
  86. data/lib/rgl/connected_components.rb +125 -0
  87. data/lib/rgl/dot.rb +63 -0
  88. data/lib/rgl/graphxml.rb +52 -0
  89. data/lib/rgl/implicit.rb +151 -0
  90. data/lib/rgl/mutable.rb +54 -0
  91. data/lib/rgl/rdot.rb +264 -0
  92. data/lib/rgl/topsort.rb +61 -0
  93. data/lib/rgl/transitiv_closure.rb +34 -0
  94. data/lib/rgl/traversal.rb +296 -0
  95. data/tests/TestComponents.rb +67 -0
  96. data/tests/TestDirectedGraph.rb +100 -0
  97. data/tests/TestEdge.rb +33 -0
  98. data/tests/TestGraphXML.rb +57 -0
  99. data/tests/TestImplicit.rb +52 -0
  100. data/tests/TestTransitiveClosure.rb +29 -0
  101. data/tests/TestTraversal.rb +222 -0
  102. data/tests/TestUnDirectedGraph.rb +98 -0
  103. metadata +163 -0
data/TAGS ADDED
@@ -0,0 +1,209 @@
1
+
2
+ lib/rgl/adjacency.rb,956
3
+ module RGLRGL16,586
4
+ class DirectedAdjacencyGraphDirectedAdjacencyGraph17,597
5
+ def initialize(edgelist_class=Set)initialize33,1091
6
+ def each_vertex(&b)each_vertex39,1248
7
+ def each_adjacent(v, &b) # :nodoc:each_adjacent43,1305
8
+ def directed?; true; enddirected?49,1470
9
+ def has_vertex?(v); @vertice_dict.has_key?(v); endhas_vertex?53,1619
10
+ def has_edge? (u, v)has_edge?60,1799
11
+ def add_vertex(v)add_vertex67,1981
12
+ def add_edge (u,v)add_edge72,2080
13
+ def remove_vertex(v)remove_vertex79,2230
14
+ def remove_edge (u,v)remove_edge87,2422
15
+ def basic_add_edge(u,v)basic_add_edge93,2522
16
+ class AdjacencyGraph < DirectedAdjacencyGraphAdjacencyGraph101,2812
17
+ def directed?; false; enddirected?103,2885
18
+ def remove_edge (u,v)remove_edge106,2936
19
+ def basic_add_edge(u,v)basic_add_edge112,3044
20
+ module GraphGraph119,3143
21
+ def to_adjacencyto_adjacency122,3291
22
+ def reversereverse132,3639
23
+ def to_undirectedto_undirected144,4009
24
+
25
+ lib/rgl/base.rb,1907
26
+ module EnumerableEnumerable12,301
27
+ def inject(*argv)inject13,321
28
+ module EnumerableEnumerable41,700
29
+ def lengthlength48,892
30
+ module RGLRGL55,954
31
+ class NotDirectedError < RuntimeError; endNotDirectedError56,965
32
+ class NotUndirectedError < RuntimeError; endNotUndirectedError57,1010
33
+ class NoVertexError < IndexError; endNoVertexError59,1058
34
+ class NoEdgeError < IndexError; endNoEdgeError60,1098
35
+ module EdgeEdge65,1327
36
+ class DirectedEdgeDirectedEdge71,1651
37
+ def initialize (a,b)initialize80,1874
38
+ def eql?(edge)eql?86,2086
39
+ def reversereverse92,2216
40
+ def to_sto_s101,2504
41
+ def to_a; [source,target]; endto_a105,2589
42
+ class UnDirectedEdge < DirectedEdgeUnDirectedEdge115,2894
43
+ def eql?(edge)eql?116,2931
44
+ def hashhash120,3021
45
+ def to_s; "(#{source}=#{target})"; endto_s125,3113
46
+ module GraphGraph144,3938
47
+ def each_vertexeach_vertex151,4151
48
+ def each_adjacent (v)each_adjacent159,4401
49
+ def each_edge (&block)each_edge171,4882
50
+ def each(&block); each_vertex(&block); endeach184,5165
51
+ def directed?; false; enddirected?187,5264
52
+ def has_vertex?(v); include?(v); end # inherited from enumerablehas_vertex?192,5490
53
+ def empty?; num_vertices.zero?; endempty?197,5668
54
+ def vertices; to_a; endvertices200,5781
55
+ def edge_class; directed? ? DirectedEdge : UnDirectedEdge; endedge_class203,5871
56
+ def edgesedges207,6079
57
+ def adjacent_vertices (v)adjacent_vertices215,6239
58
+ def out_degree (v)out_degree223,6451
59
+ def size # Why not in Enumerable?size230,6560
60
+ def num_vertices; size; endnum_vertices236,6732
61
+ def num_edges; r = 0; each_edge {|u,v| r +=1}; r; endnum_edges239,6794
62
+ def to_sto_s242,6927
63
+ def each_edge_auxeach_edge_aux248,6973
64
+ module BidirectionalGraphBidirectionalGraph272,7816
65
+ def each_in_neighbor (v)each_in_neighbor279,8156
66
+ def in_degree (v)in_degree286,8359
67
+ def degree (v)degree294,8582
68
+
69
+ lib/rgl/connected_components.rb,497
70
+ module RGLRGL7,233
71
+ module GraphGraph8,244
72
+ def each_connected_componenteach_connected_component17,641
73
+ class TarjanSccVisitor < DFSVisitorTarjanSccVisitor34,1174
74
+ def initialize(g)initialize38,1314
75
+ def handle_examine_vertex(v)handle_examine_vertex48,1458
76
+ def handle_finish_vertex(v)handle_finish_vertex56,1606
77
+ def num_compnum_comp75,2151
78
+ def min_discover_time(u,v)min_discover_time81,2198
79
+ def strongly_connected_componentsstrongly_connected_components118,3687
80
+
81
+ lib/rgl/dot.rb,298
82
+ module RGLRGL10,239
83
+ module GraphGraph11,250
84
+ def to_dot_graph( params = {} )to_dot_graph15,428
85
+ def print_dotted_on (params = {}, s=$stdout)print_dotted_on35,1076
86
+ def dotty( params = {} )dotty41,1270
87
+ def write_to_graphic_file(fmt='png', dotfile="graph")write_to_graphic_file51,1530
88
+
89
+ lib/rgl/graphxml.rb,340
90
+ module RGLRGL15,594
91
+ module GraphXMLGraphXML22,893
92
+ class MutableGraphParserMutableGraphParser23,911
93
+ def initialize(graph)initialize26,992
94
+ def tag_start(name, attrs)tag_start30,1042
95
+ def MutableGraph.append_features(includingClass)append_features41,1229
96
+ def includingClass.from_graphxml (source)from_graphxml45,1350
97
+
98
+ lib/rgl/implicit.rb,681
99
+ module RGLRGL19,702
100
+ class ImplicitGraphImplicitGraph20,713
101
+ def initializeinitialize32,1102
102
+ def directed?; @directed; enddirected?40,1337
103
+ def each_vertex (&block) # :nodoc:each_vertex42,1370
104
+ def each_adjacent (v, &block) # :nodoc:each_adjacent46,1444
105
+ def each_edge (&block) # :nodoc:each_edge50,1527
106
+ def vertex_iterator (&block)vertex_iterator60,1811
107
+ def adjacent_iterator (&block)adjacent_iterator69,2127
108
+ def edge_iterator (&block)edge_iterator76,2367
109
+ module GraphGraph81,2433
110
+ def vertices_filtered_by (&filter)vertices_filtered_by105,3129
111
+ def edges_filtered_by (&filter)edges_filtered_by124,3675
112
+ def implicit_graphimplicit_graph141,4120
113
+
114
+ lib/rgl/mutable.rb,484
115
+ module RGLRGL3,20
116
+ module MutableGraphMutableGraph6,121
117
+ def add_vertex(v); raise NotImplementedError; endadd_vertex11,266
118
+ def add_edge(u, v); raise NotImplementedError; endadd_edge20,692
119
+ def add_vertices (*a)add_vertices23,790
120
+ def add_edges (*edges)add_edges30,1010
121
+ def remove_vertex(v); raise NotImplementedError; endremove_vertex39,1365
122
+ def remove_edge(u, v); raise NotImplementedError; endremove_edge46,1653
123
+ def remove_vertices (*a)remove_vertices50,1798
124
+
125
+ lib/rgl/rdot.rb,1615
126
+ module DOTDOT9,242
127
+ def change_tab( t )change_tab16,420
128
+ class DOTSimpleElementDOTSimpleElement81,1613
129
+ def initialize( params = {} )initialize84,1669
130
+ def to_sto_s88,1778
131
+ class DOTElement < DOTSimpleElementDOTElement94,1897
132
+ def initialize( params = {}, option_list = [] )initialize98,2005
133
+ def each_optioneach_option109,2419
134
+ def each_option_paireach_option_pair113,2497
135
+ class DOTPort < DOTSimpleElementDOTPort126,2856
136
+ def initialize( params = {} )initialize129,2931
137
+ def to_sto_s133,3068
138
+ class DOTNode < DOTElementDOTNode139,3200
139
+ def initialize( params = {}, option_list = NODE_OPTS )initialize142,3247
140
+ def each_porteach_port147,3424
141
+ def push ( thing )push155,3564
142
+ def poppop159,3637
143
+ def to_s( t = '' )to_s163,3689
144
+ class DOTSubgraph < DOTElementDOTSubgraph188,4604
145
+ def initialize( params = {}, option_list = GRAPH_OPTS )initialize192,4675
146
+ def each_nodeeach_node198,4887
147
+ def push( thing )push206,5034
148
+ def poppop210,5106
149
+ def to_s( t = '' )to_s214,5158
150
+ class DOTDigraph < DOTSubgraphDOTDigraph231,5663
151
+ def initialize( params = {}, option_list = GRAPH_OPTS )initialize232,5698
152
+ class DOTEdge < DOTElementDOTEdge239,5879
153
+ def initialize( params = {}, option_list = EDGE_OPTS )initialize241,5943
154
+ def edge_link; '--'; endedge_link247,6177
155
+ def to_s( t = '' )to_s248,6204
156
+ class DOTDirectedEdge < DOTEdgeDOTDirectedEdge258,6557
157
+ def edge_link; '->'; endedge_link259,6590
158
+
159
+ lib/rgl/topsort.rb,447
160
+ module RGLRGL3,25
161
+ class TopsortIteratorTopsortIterator14,503
162
+ def initialize(g)initialize16,550
163
+ def set_to_begin # :nodoc:set_to_begin21,602
164
+ def basic_forward # :nodoc:basic_forward36,924
165
+ def at_beginning?; true; end # :nodoc: FIXMEat_beginning?45,1091
166
+ def at_end?; @waiting.empty?; end # :nodoc:at_end?46,1138
167
+ module GraphGraph49,1190
168
+ def topsort_iteratortopsort_iterator51,1235
169
+ def acyclic?acyclic?57,1425
170
+
171
+ lib/rgl/transitiv_closure.rb,127
172
+ module RGLRGL9,334
173
+ module GraphGraph10,345
174
+ def transitive_closure_floyd_warshaltransitive_closure_floyd_warshal16,665
175
+
176
+ lib/rgl/traversal.rb,1708
177
+ module RGLRGL14,546
178
+ module GraphWrapper # :nodoc:GraphWrapper15,557
179
+ def initialize(graph); @graph = graph; endinitialize19,658
180
+ module GraphIteratorGraphIterator24,863
181
+ module GraphVisitorGraphVisitor59,2225
182
+ def initialize(graph)initialize64,2335
183
+ def resetreset70,2432
184
+ def finished_vertex? vfinished_vertex?75,2546
185
+ def attach_distance_map(map=Hash.new(0))attach_distance_map87,2937
186
+ def handle_tree_edge(u,v)handle_tree_edge90,3015
187
+ def distance_to_root(v)distance_to_root96,3141
188
+ def follow_edge?(u,v) # :nodoc:follow_edge?103,3261
189
+ def self.def_event_handler(m)def_event_handler108,3355
190
+ def handle_#{m}(#{params})handle_111,3446
191
+ def set_#{m}_event_handler(&b)set_114,3553
192
+ class BFSIteratorBFSIterator137,4373
193
+ def initialize(graph, start=graph.detect{|x| true})initialize143,4535
194
+ def at_beginning?; @color_map.size == 1; end # :nodoc:at_beginning?150,4727
195
+ def at_end?; @waiting.empty?; endat_end?153,4823
196
+ def set_to_beginset_to_begin156,4932
197
+ def basic_forward # :nodoc:basic_forward162,5098
198
+ def next_vertex () # :nodoc:next_vertex186,5696
199
+ module GraphGraph192,5804
200
+ def bfs_iterator (v=self.detect {|x| true})bfs_iterator194,5867
201
+ def bfs_search_tree_from(v)bfs_search_tree_from201,6151
202
+ class DFSIterator < BFSIteratorDFSIterator218,6699
203
+ def next_vertexnext_vertex219,6733
204
+ class DFSVisitorDFSVisitor235,7372
205
+ module GraphGraph241,7469
206
+ def dfs_iterator (v=self.detect {|x| true})dfs_iterator243,7532
207
+ def depth_first_search (vis = DFSVisitor.new(self),&b)depth_first_search250,7787
208
+ def depth_first_visit (u, vis = DFSVisitor.new(self), &b)depth_first_visit261,8079
209
+ def acyclic?acyclic?285,8775
@@ -0,0 +1,103 @@
1
+ # From c.l.r SNIP IT: bond TkCanvas with RubyGraphLibrary
2
+ # author: Phlip (see also
3
+ # http://www.rubygarden.org/ruby?RubyAlgorithmPackage/TkCanvasSample)
4
+ #
5
+ # put a GraphViz graph into a TkCanvas, and make nodes
6
+ # selectable. Illustrates a bug in GraphViz
7
+
8
+ require 'rgl/graphxml'
9
+ require 'rgl/adjacency'
10
+ require 'rgl/dot'
11
+ require 'tk'
12
+
13
+ include RGL
14
+ filename = ARGV[0]
15
+ puts 'Displaying ' + filename
16
+
17
+ # ruby canvas.rb north/g.10.8.graphml &
18
+ # ruby canvas.rb north/g.12.8.graphml &
19
+ # ruby canvas.rb north/g.14.9.graphml &
20
+
21
+ File.open(filename) { |file|
22
+ graph = DirectedAdjacencyGraph.from_graphxml(file)
23
+ graph.write_to_graphic_file('gif', filename)
24
+ graph.write_to_graphic_file('plain', filename)
25
+ root = TkRoot.new{title "Ex1"}
26
+
27
+ canvas = TkCanvas.new(root) {
28
+ width 400
29
+ height 600
30
+ }
31
+ canvas.pack()
32
+ ovals = []
33
+
34
+ TkcImage.new(canvas, 0, 0) {
35
+ anchor 'nw'
36
+
37
+ image TkPhotoImage.new() {
38
+ file filename + '.gif'
39
+ }
40
+ }
41
+
42
+ # read the 'plain' file, and for each node put an invisible
43
+ # oval over its image
44
+
45
+ File.open(filename + '.plain') { |f|
46
+ graphLine = f.readline()
47
+ graphStats = graphLine.split()
48
+ graphHeight = graphStats[3].to_f()
49
+ nodeLine = f.readline()
50
+ fields = nodeLine.split()
51
+
52
+ while fields[0] == 'node'
53
+ namer = fields[1]
54
+
55
+ # the following crud is because GraphViz has no system to
56
+ # emit a "plain" format in pixels that exactly match the
57
+ # locations of objects in dot's raster output
58
+
59
+ # furtherless, the current GraphViz seems to be centering
60
+ # the raster output but not the 'plain' output. Hence on
61
+ # g.10.8.graphml the X fudge factor must be 45. >sigh<
62
+
63
+ # YMMV, based on your system's opinion of the size of an inch
64
+
65
+ exx = fields[2].to_f * 96 - 20 # 45
66
+ why = (graphHeight - fields[3].to_f()) * 96 - 20
67
+ widt = fields[4].to_f() * 90
68
+ hite = fields[5].to_f() * 90
69
+
70
+ ov = TkcOval.new(canvas, exx, why,
71
+ exx + widt, why + hite) {
72
+ state 'hidden'
73
+ width 4
74
+ outline 'green'
75
+ tags namer
76
+ }
77
+ ovals.push(ov)
78
+ nodeLine = f.readline()
79
+ fields = nodeLine.split()
80
+ end
81
+ }
82
+ lastOval = ovals[0]
83
+
84
+ # at click time, search for an oval in range and display it
85
+
86
+ canvas.bind('Button-1') do |event|
87
+ x,y = canvas.canvasx(event.x), canvas.canvasy(event.y)
88
+
89
+ ovals.each { |r|
90
+ x1,y1,x2,y2 = r.coords()
91
+
92
+ if x >= x1 and x <= x2 and y >= y1 and y <= y2 then
93
+ lastOval.configure('state' => 'hidden')
94
+ lastOval = r
95
+ lastOval.configure('state' => 'normal')
96
+ break
97
+ end
98
+ }
99
+ end
100
+
101
+ Tk.mainloop
102
+ }
103
+
@@ -0,0 +1,238 @@
1
+ #!/usr/bin/env ruby
2
+ require 'ptools'
3
+ require 'rgl/adjacency'
4
+ require 'rgl/dot'
5
+ require 'rgl/rdot'
6
+
7
+ class FunctionGraph < RGL::DirectedAdjacencyGraph
8
+ attr_accessor :command
9
+ attr_accessor :funx
10
+ attr_accessor :lines
11
+ def initialize
12
+ super
13
+ @@lines = nil
14
+ @@funx = nil
15
+ end
16
+ def genFiles(graph, filelist, lang, exclude=[])
17
+ # test if the 'tobegenerated' files already exist
18
+ if (File.exist?('all.php') or File.exist?('php-funx'))
19
+ puts "Die Dateien 'all.php' oder 'php-funx' exitieren bereits."
20
+ puts "Bitte loeschen Sie sie manuel"
21
+ exit
22
+ end
23
+ # command to generate the necessary files
24
+ command = 'cat ' + filelist + ' | ruby -ne \' print unless /^#.*$/\' |
25
+ ruby -pe \'gsub(/#.*/," "); gsub(/".*"/,"")\' > all.php;
26
+ ctags -x --php-kinds=f all.php | sort -n -k 3 |
27
+ ruby -pe \'gsub(/ function /,"\t"); gsub(/all.php/,"\t")\' |
28
+ cut -f 1,2 |ruby -pe \'gsub(/ {2,}/,"")\' > php-funx'
29
+ system(command)
30
+ funchash = Hash.new
31
+ file = open('php-funx')
32
+ file.read.split(/\n/).each {|f|
33
+ thisfunc = f.split
34
+ funchash.store(thisfunc.last.to_i, thisfunc.first)
35
+ }
36
+ graph.lines = Array.new
37
+ graph.funx = Array.new
38
+ funchash.sort.each {|f|
39
+ next if exclude.include?(f.last)
40
+ graph.lines << f.first
41
+ graph.funx << f.last
42
+ }
43
+ $filesize = open('all.php').readlines.size
44
+ end
45
+
46
+ def fill(filelist,lang,exclude=[])
47
+ # generate the necessary files and return the size (in number of lines)
48
+ # of the file with all definitions
49
+ genFiles(self,filelist,lang,exclude)
50
+ # scan the first function
51
+ funcbody = File.middle('all.php', lines[0]+1, lines[1]-1).to_s
52
+ add_vertex(funx.first)
53
+ funx.each {|func|
54
+ if funcbody =~ /#{func} *\(/
55
+ add_func("#{funx.first}","#{func}")
56
+ end
57
+ }
58
+ # scan any other function except the last
59
+ (1...funx.size-1).each {|index|
60
+ add_vertex(funx[index])
61
+ funcbody = File.middle('all.php', lines[index]+1,lines[index+1]-1).to_s
62
+ funx.each {|func|
63
+ if funcbody =~ /#{func} *\(/
64
+ add_func("#{funx[index]}","#{func}")
65
+ end
66
+ }
67
+ }
68
+ # scan the last function
69
+ funcbody = File.middle('all.php', lines.last+1 , $filesize).to_s
70
+ add_vertex(funx.last)
71
+ funx.each {|func|
72
+ if funcbody =~ /#{func} *\(/
73
+ add_func("#{funx.last}","#{func}")
74
+ end
75
+ }
76
+ system('rm all.php php-funx')
77
+
78
+ # add fallow function's knodes
79
+ funx.each {|func|
80
+ if not has_vertex?(func)
81
+ add_edge("UNUSED CODE",func)
82
+ end
83
+ }
84
+ end
85
+ def to_ps(filename)
86
+ if File.exist?(filename)
87
+ system("rm #{filename}")
88
+ end
89
+ if File.exist?(filename+".dot")
90
+ system("rm #{filename}.dot")
91
+ end
92
+ # create dot file
93
+ params = Hash['rankdir' => 'LR',
94
+ 'ranksep' => '2.0',
95
+ 'concentrate' => 'TRUE',
96
+ 'fontsize' => '10']
97
+ File.open("#{filename}.dot","w") {|f|
98
+ print_dotted_on(params,f)
99
+ }
100
+ system("dot -Tps -o #{filename} -Nshape=box #{filename}.dot")
101
+ end
102
+ def add_func(f,g)
103
+ add_edge(f,g)
104
+ end
105
+ def display
106
+ params = Hash['rankdir' => 'LR',
107
+ 'ranksep' => '2.0',
108
+ 'concentrate' => 'TRUE',
109
+ 'label' => 'LCWA',
110
+ 'fontsize' => '12']
111
+ dotty(params)
112
+ end
113
+ private :genFiles
114
+ end
115
+
116
+ class SingleFunctionGraph < FunctionGraph
117
+ attr_accessor :func
118
+ def initialize(func)
119
+ @func = func
120
+ super()
121
+ end
122
+ def fill(filelist,lang,exclude=[])
123
+ genFiles(self,filelist,lang,exclude)
124
+ $scannedfunx = Array.new
125
+ scan(self, func)
126
+ system('rm all.php php-funx')
127
+ end
128
+ def scan(graph, f)
129
+ if ($scannedfunx.include?(f))
130
+ else
131
+ $scannedfunx << f
132
+ beginbody = graph.lines[graph.funx.index(f)]+1
133
+ if (graph.lines.size <= graph.funx.index(f)+1)
134
+ endbody = $filesize
135
+ else
136
+ endbody = graph.lines[graph.funx.index(f)+1]-1
137
+ end
138
+ fbody = File.middle('all.php', beginbody, endbody).to_s
139
+ graph.funx.each {|g|
140
+ if fbody =~ /#{g} *\(/
141
+ graph.add_func(f,g)
142
+ scan(graph,g)
143
+ end
144
+ }
145
+ end
146
+ end
147
+ private :scan
148
+ end
149
+
150
+ # main script #################################################################
151
+ require 'getoptlong'
152
+
153
+ def show_usage
154
+ puts <<-END
155
+ Usage: #{__FILE__}: --help guess what
156
+
157
+ --source, -s take every $IMPSRC/lcwa/web_interface/*inc.php file
158
+ to search in
159
+ --local, -l take every $(pwd)/*.inc.php file for scanning
160
+
161
+ --file-list, -F "<list>"
162
+ fill the graph with every function,
163
+ that has a definiton inside the given files
164
+
165
+ --function, -f <funcname>
166
+ take the given func as the root knode
167
+ --exclude, -x "<list>"
168
+ exclude a list of functions from the graph
169
+ --to-ps, -p <filename>
170
+ create a postscript file from the graph
171
+ END
172
+ end
173
+ # option setting ---------------------------------------------------------------
174
+ options = GetoptLong.new(
175
+ ['--help', '-h', GetoptLong::NO_ARGUMENT],
176
+ ['--local', '-l', GetoptLong::NO_ARGUMENT],
177
+ ['--source', '-s', GetoptLong::NO_ARGUMENT],
178
+ ['--function', '-f', GetoptLong::REQUIRED_ARGUMENT],
179
+ ['--file-list', '-F', GetoptLong::REQUIRED_ARGUMENT],
180
+ ['--to-ps', '-p', GetoptLong::REQUIRED_ARGUMENT],
181
+ ['--exclude', '-x', GetoptLong::REQUIRED_ARGUMENT]
182
+ )
183
+ options.ordering = GetoptLong::RETURN_IN_ORDER
184
+ # the default options ----------------------------------------------------------
185
+ filelist = ''
186
+ mode = 'multiple'
187
+ createPS = false
188
+ filename = ''
189
+ function = ''
190
+ exclude = Array.new
191
+ spaces = Array.new
192
+ # option parsing ---------------------------------------------------------------
193
+ options.each do |opt, arg|
194
+ case opt
195
+ when '--local'
196
+ filelist = './*inc.php'
197
+ spaces << filelist
198
+ when '--source'
199
+ filelist = '$IMPSRC/lcwa/web_interface/*inc.php'
200
+ spaces << filelist
201
+ when '--file-list'
202
+ filelist = arg
203
+ spaces << filelist
204
+ when '--function'
205
+ mode = 'single'
206
+ function = arg
207
+ when '--to-ps'
208
+ createPS = true
209
+ filename = arg
210
+ when '--exclude'
211
+ exclude = arg.split(/ /)
212
+ else
213
+ show_usage
214
+ exit
215
+ end
216
+ end
217
+ options.terminate
218
+ # script controlling ###########################################################
219
+ case mode
220
+ when 'single'
221
+ g = SingleFunctionGraph.new(function)
222
+ else
223
+ g = FunctionGraph.new
224
+ end
225
+ case spaces.size
226
+ when 1
227
+ g.fill(filelist,'php',exclude)
228
+ else
229
+ puts "Benutzen Sie entweder --local, --source oder --file-list <list>"
230
+ show_usage
231
+ exit
232
+ end
233
+ case createPS
234
+ when true
235
+ g.to_ps(filename)
236
+ else
237
+ g.display
238
+ end