rgl 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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