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
@@ -0,0 +1,31 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- This file was written by the internal XML-Handler of Y-Files.-->
3
+ <!DOCTYPE graphml SYSTEM "http://www.graphdrawing.org/dtds/graphml.dtd">
4
+ <graphml>
5
+ <graph id="G">
6
+ <node id="n0"/>
7
+ <node id="n1"/>
8
+ <node id="n2"/>
9
+ <node id="n3"/>
10
+ <node id="n4"/>
11
+ <node id="n5"/>
12
+ <node id="n6"/>
13
+ <node id="n7"/>
14
+ <node id="n8"/>
15
+ <node id="n9"/>
16
+ <edge id="e0" source="n0" target="n1"/>
17
+ <edge id="e1" source="n1" target="n2"/>
18
+ <edge id="e2" source="n1" target="n3"/>
19
+ <edge id="e3" source="n1" target="n4"/>
20
+ <edge id="e4" source="n1" target="n5"/>
21
+ <edge id="e5" source="n1" target="n6"/>
22
+ <edge id="e6" source="n1" target="n7"/>
23
+ <edge id="e7" source="n1" target="n8"/>
24
+ <edge id="e8" source="n1" target="n9"/>
25
+ <edge id="e9" source="n3" target="n4"/>
26
+ <edge id="e10" source="n4" target="n5"/>
27
+ <edge id="e11" source="n5" target="n6"/>
28
+ <edge id="e12" source="n6" target="n7"/>
29
+ <edge id="e13" source="n7" target="n8"/>
30
+ </graph>
31
+ </graphml>
@@ -0,0 +1,26 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- This file was written by the internal XML-Handler of Y-Files.-->
3
+ <!DOCTYPE graphml SYSTEM "http://www.graphdrawing.org/dtds/graphml.dtd">
4
+ <graphml>
5
+ <graph id="G">
6
+ <node id="n0"/>
7
+ <node id="n1"/>
8
+ <node id="n2"/>
9
+ <node id="n3"/>
10
+ <node id="n4"/>
11
+ <node id="n5"/>
12
+ <node id="n6"/>
13
+ <node id="n7"/>
14
+ <node id="n8"/>
15
+ <node id="n9"/>
16
+ <edge id="e0" source="n0" target="n1"/>
17
+ <edge id="e1" source="n1" target="n2"/>
18
+ <edge id="e2" source="n3" target="n2"/>
19
+ <edge id="e3" source="n4" target="n2"/>
20
+ <edge id="e4" source="n6" target="n2"/>
21
+ <edge id="e5" source="n5" target="n6"/>
22
+ <edge id="e6" source="n7" target="n2"/>
23
+ <edge id="e7" source="n8" target="n2"/>
24
+ <edge id="e8" source="n9" target="n2"/>
25
+ </graph>
26
+ </graphml>
@@ -0,0 +1,32 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- This file was written by the internal XML-Handler of Y-Files.-->
3
+ <!DOCTYPE graphml SYSTEM "http://www.graphdrawing.org/dtds/graphml.dtd">
4
+ <graphml>
5
+ <graph id="G">
6
+ <node id="n0"/>
7
+ <node id="n1"/>
8
+ <node id="n2"/>
9
+ <node id="n3"/>
10
+ <node id="n4"/>
11
+ <node id="n5"/>
12
+ <node id="n6"/>
13
+ <node id="n7"/>
14
+ <node id="n8"/>
15
+ <node id="n9"/>
16
+ <edge id="e0" source="n0" target="n2"/>
17
+ <edge id="e1" source="n0" target="n3"/>
18
+ <edge id="e2" source="n0" target="n4"/>
19
+ <edge id="e3" source="n0" target="n5"/>
20
+ <edge id="e4" source="n0" target="n6"/>
21
+ <edge id="e5" source="n0" target="n7"/>
22
+ <edge id="e6" source="n0" target="n8"/>
23
+ <edge id="e7" source="n0" target="n9"/>
24
+ <edge id="e8" source="n3" target="n9"/>
25
+ <edge id="e9" source="n4" target="n9"/>
26
+ <edge id="e10" source="n5" target="n9"/>
27
+ <edge id="e11" source="n6" target="n9"/>
28
+ <edge id="e12" source="n7" target="n9"/>
29
+ <edge id="e13" source="n8" target="n9"/>
30
+ <edge id="e14" source="n1" target="n0"/>
31
+ </graph>
32
+ </graphml>
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- This file was written by the internal XML-Handler of Y-Files.-->
3
+ <!DOCTYPE graphml SYSTEM "http://www.graphdrawing.org/dtds/graphml.dtd">
4
+ <graphml>
5
+ <graph id="G">
6
+ <node id="n0"/>
7
+ <node id="n1"/>
8
+ <node id="n2"/>
9
+ <node id="n3"/>
10
+ <node id="n4"/>
11
+ <node id="n5"/>
12
+ <node id="n6"/>
13
+ <node id="n7"/>
14
+ <node id="n8"/>
15
+ <node id="n9"/>
16
+ <edge id="e0" source="n0" target="n1"/>
17
+ <edge id="e1" source="n0" target="n2"/>
18
+ <edge id="e2" source="n1" target="n3"/>
19
+ <edge id="e3" source="n1" target="n4"/>
20
+ <edge id="e4" source="n1" target="n5"/>
21
+ <edge id="e5" source="n1" target="n6"/>
22
+ <edge id="e6" source="n3" target="n8"/>
23
+ <edge id="e7" source="n3" target="n9"/>
24
+ <edge id="e8" source="n4" target="n8"/>
25
+ <edge id="e9" source="n6" target="n4"/>
26
+ <edge id="e10" source="n6" target="n5"/>
27
+ <edge id="e11" source="n6" target="n7"/>
28
+ <edge id="e12" source="n5" target="n9"/>
29
+ <edge id="e13" source="n2" target="n3"/>
30
+ <edge id="e14" source="n2" target="n5"/>
31
+ <edge id="e15" source="n2" target="n7"/>
32
+ <edge id="e16" source="n7" target="n8"/>
33
+ </graph>
34
+ </graphml>
@@ -0,0 +1,40 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- This file was written by the internal XML-Handler of Y-Files.-->
3
+ <!DOCTYPE graphml SYSTEM "http://www.graphdrawing.org/dtds/graphml.dtd">
4
+ <graphml>
5
+ <graph id="G">
6
+ <node id="n0"/>
7
+ <node id="n1"/>
8
+ <node id="n2"/>
9
+ <node id="n3"/>
10
+ <node id="n4"/>
11
+ <node id="n5"/>
12
+ <node id="n6"/>
13
+ <node id="n7"/>
14
+ <node id="n8"/>
15
+ <node id="n9"/>
16
+ <node id="n10"/>
17
+ <node id="n11"/>
18
+ <edge id="e0" source="n0" target="n1"/>
19
+ <edge id="e1" source="n0" target="n2"/>
20
+ <edge id="e2" source="n0" target="n3"/>
21
+ <edge id="e3" source="n0" target="n4"/>
22
+ <edge id="e4" source="n0" target="n5"/>
23
+ <edge id="e5" source="n1" target="n5"/>
24
+ <edge id="e6" source="n4" target="n5"/>
25
+ <edge id="e7" source="n11" target="n0"/>
26
+ <edge id="e8" source="n11" target="n1"/>
27
+ <edge id="e9" source="n11" target="n2"/>
28
+ <edge id="e10" source="n11" target="n4"/>
29
+ <edge id="e11" source="n2" target="n3"/>
30
+ <edge id="e12" source="n6" target="n7"/>
31
+ <edge id="e13" source="n6" target="n8"/>
32
+ <edge id="e14" source="n6" target="n9"/>
33
+ <edge id="e15" source="n6" target="n10"/>
34
+ <edge id="e16" source="n6" target="n11"/>
35
+ <edge id="e17" source="n7" target="n9"/>
36
+ <edge id="e18" source="n7" target="n10"/>
37
+ <edge id="e19" source="n8" target="n9"/>
38
+ <edge id="e20" source="n8" target="n10"/>
39
+ </graph>
40
+ </graphml>
@@ -0,0 +1,36 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- This file was written by the internal XML-Handler of Y-Files.-->
3
+ <!DOCTYPE graphml SYSTEM "http://www.graphdrawing.org/dtds/graphml.dtd">
4
+ <graphml>
5
+ <graph id="G">
6
+ <node id="n0"/>
7
+ <node id="n1"/>
8
+ <node id="n2"/>
9
+ <node id="n3"/>
10
+ <node id="n4"/>
11
+ <node id="n5"/>
12
+ <node id="n6"/>
13
+ <node id="n7"/>
14
+ <node id="n8"/>
15
+ <node id="n9"/>
16
+ <node id="n10"/>
17
+ <node id="n11"/>
18
+ <node id="n12"/>
19
+ <node id="n13"/>
20
+ <edge id="e0" source="n0" target="n1"/>
21
+ <edge id="e1" source="n0" target="n2"/>
22
+ <edge id="e2" source="n0" target="n3"/>
23
+ <edge id="e3" source="n0" target="n4"/>
24
+ <edge id="e4" source="n0" target="n5"/>
25
+ <edge id="e5" source="n0" target="n6"/>
26
+ <edge id="e6" source="n0" target="n7"/>
27
+ <edge id="e7" source="n0" target="n8"/>
28
+ <edge id="e8" source="n0" target="n9"/>
29
+ <edge id="e9" source="n0" target="n10"/>
30
+ <edge id="e10" source="n2" target="n11"/>
31
+ <edge id="e11" source="n2" target="n12"/>
32
+ <edge id="e12" source="n3" target="n11"/>
33
+ <edge id="e13" source="n3" target="n12"/>
34
+ <edge id="e14" source="n9" target="n13"/>
35
+ </graph>
36
+ </graphml>
@@ -0,0 +1,21 @@
1
+ require 'rgl/graphxml'
2
+ require 'rgl/adjacency'
3
+ require 'rgl/dot'
4
+
5
+ include RGL
6
+ name,nnodes,nedges = '','',''
7
+ IO.foreach('north/Graph.log') {
8
+ |line|
9
+ if /name:\s*(.*)\sformat: graphml\s+nodes: (\d+)\s+edges: (\d+)/ =~ line
10
+ name,nnodes,nedges = $1,$2.to_i,$3.to_i
11
+ end
12
+ if name && /directed: (.*)\s+acyclic: (.*)\s+.*connected: (.*)\s+biconnected: (.*)\s+/ =~ line
13
+ directed, acyclic, connected, biconnected = $1,$2,$3,$4
14
+ puts [name,nnodes,nedges].join('-|-')
15
+ File.open('north/' + name + '.graphml') {
16
+ |file|
17
+ graph = DirectedAdjacencyGraph.from_graphxml(file)
18
+ puts "#{graph.num_vertices} = #{nnodes}"
19
+ }
20
+ end
21
+ }
@@ -0,0 +1,395 @@
1
+ #
2
+ # $Id: rdep-rgl.rb,v 1.1 2002/11/13 23:30:25 monora Exp $
3
+ #
4
+ # Simple extensions of Hal Fultons tool to show dependencies between ruby
5
+ # source files (see http://hypermetrics.com/rubyhacker/code/rdep/). The basic
6
+ # extensions can be found at the end of the function find_files.
7
+ #
8
+ # Source: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/rgl/rgl/examples/rdep-rgl.rb
9
+ #
10
+ # Additionaly rdep-rgl.rb generates a graphics file named
11
+ # File.basename(ARGV[0]) + ".png".
12
+ #
13
+ # Requires RGL (http://rgl.sourceforge.net) and Graphviz
14
+ # (www.research.att.com/sw/tools/graphviz/download.html).
15
+ #
16
+ # ruby rdep-rgl.rb j:/ruby/lib/ruby/site_ruby/1.6/rdoc/rdoc.rb
17
+ #
18
+ # produces the following graph: link:rdoc.rb.png
19
+ #
20
+ require 'rgl/adjacency'
21
+ require 'rgl/dot'
22
+
23
+ =begin
24
+
25
+ rdep - The Ruby Dependency Tool
26
+ Version 1.4
27
+
28
+ Hal E. Fulton
29
+ 2 November 2002
30
+ Ruby's license
31
+
32
+ Purpose
33
+
34
+ Determine the library files on which a specified Ruby file is dependent
35
+ (and their location and availability).
36
+
37
+ Usage notes
38
+
39
+ Usage: ruby rdep.rb sourcefile
40
+
41
+ The sourcefile may or may not have a .rb extension.
42
+
43
+ The directories in the $: array (which includes the RUBYLIB environment
44
+ variable) are searched first. File extensions are currently searched for
45
+ in this order: no extension, .rb, .o, .so, .dll (this may not be correct).
46
+
47
+ If there are no detected dependencies, the program will give the
48
+ message, "No dependencies found."
49
+
50
+ If the program finds [auto]load and require statements that it can
51
+ understand, it searches for the specified files. Any recognized Ruby
52
+ source files (*.rb) are processed recursively in the same way. No attempt
53
+ is made to open the files that appear to be binary.
54
+
55
+ The program will print up to four lists (any or all may be omitted):
56
+ 1. A list of files it found by going through RUBYLIB.;
57
+ 2. A list of files found under the searchroot (or under '.');
58
+ 3. A list of directories under searchroot which should perhaps be
59
+ added to RUBYLIB; and
60
+ 4. A list of files (without extensions) which could not be found.
61
+
62
+ If there were unparseable [auto]load or require statements, a warning
63
+ will be issued.
64
+
65
+ Between lists 3 and 4, the program will give an opinion about the overall
66
+ situation. The worst case is that files were not found; the uncertain
67
+ case is when there were unparseable statements; and the best case is
68
+ when all files could be found (lists 1 and 2).
69
+
70
+ Exit codes
71
+
72
+ 0 - Usage or successful execution
73
+ 1 - Nonexistent sourcefile specified
74
+ 2 - Improper sourcefile (pipe, special file, ...)
75
+ 3 - Some kind of problem reading a file
76
+
77
+ Limitations
78
+
79
+ Requires Ruby 1.6.0 or higher
80
+ No recursion on binaries
81
+ Can't look at dynamically built names
82
+ Can't detect "tested" requires (e.g.: flag = require "foo.rb")
83
+ [auto]load/require can be preceded only by whitespace on the line
84
+ Only recognizes simple strings ("file" or 'file')
85
+ Does not recognized named constants (e.g.: require MyFile)
86
+ Assumes every directory entry is either a file or subdirectory
87
+ Does not handle the Windows variable RUBYLIB_PREFIX
88
+ May be SLOW if a directory structure is deep (especially
89
+ on Windows with 1.6.x)
90
+
91
+ Known bugs:
92
+
93
+ Logic may be incorrect in terms of search order, file extensions, etc.
94
+ Injected a bug in 1.3: In rare cases will recurse until stack overflow
95
+
96
+ Revision history
97
+
98
+ Version 1.0 - 13 October 2000 - Initial release
99
+ Version 1.1 - 10 July 2001 - Bug fixes
100
+ Version 1.2 - 15 August 2002 - Works correctly on Win98
101
+ Version 1.3 - 21 October 2002 - Removed globals; removed search root;
102
+ added $: instead of RUBYLIB; etc.
103
+ Version 1.4 - 2 November 2002 - Fixed autoload recursion bug
104
+
105
+ To-do list
106
+
107
+ Possibly change extension search order?
108
+ Possibly add extensions to list?
109
+ Are explicit extensions allowed other than .rb?
110
+ Is a null extension really legal?
111
+ Additional tests/safeguards? (file permissions, non-empty files,...)
112
+ Change inconsistent expansion of tilde, dot, etc.?
113
+ Make it smarter somehow??
114
+
115
+ =end
116
+
117
+ #
118
+ # File.doc_skip - iterator to skip embedded docs in Ruby input file
119
+ #
120
+
121
+ class File
122
+
123
+ def doc_skip
124
+ loop do
125
+ str = gets
126
+ break if not str
127
+ if str =~ /^=begin([ \t]|$)/
128
+ loop do
129
+ str = gets
130
+ break if not str
131
+ break if str =~ /^=end([ \t]|$)/
132
+ end
133
+ else
134
+ yield str
135
+ end
136
+ end
137
+ end
138
+
139
+ end
140
+
141
+ class Dependency
142
+ attr_reader :graph
143
+
144
+ #
145
+ # unquote - Find the value of a string. Called from scan.
146
+ #
147
+
148
+ def unquote(str)
149
+ # Still more kludgy code.
150
+ return nil if str == nil
151
+ if [?', ?"].include? str[0] # ' Unconfuse gvim
152
+ str = str[1..-2]
153
+ else
154
+ ""
155
+ end
156
+ end
157
+
158
+ #
159
+ # scan - Scans a line and returns the filename from a load or require
160
+ # statement. Returns null string if there was a parsing problem.
161
+ # Returns nil if this is not a load or require.
162
+ #
163
+
164
+ def scan(line)
165
+ line.strip!
166
+ if line =~ /^load/ or line =~ /^auto/ or line =~ /^require/
167
+ @has_dep = true # At least one dependency found.
168
+ # Kludge!!
169
+ junk = %w[ require load autoload ( ) , ] + [""]
170
+ temp = line.split(/[ \t\(\),]/) - junk
171
+ if temp[2] and temp[2][0].chr =~ /[#;]/ # Comments, semi...
172
+ temp = temp[0..1]
173
+ end
174
+ if temp[-1] =~ /\#\{/ # #{} means trouble
175
+ str = ""
176
+ else
177
+ str = unquote(temp[-1]) # May return nil.
178
+ end
179
+ str
180
+ else
181
+ nil
182
+ end
183
+ end
184
+
185
+ #
186
+ # find_files - The heart of the program. Search for files using $:
187
+ #
188
+
189
+ def find_files(source)
190
+ # loadable - This file or some variant can be found in one of the
191
+ # directories in $:
192
+ loadable = false
193
+
194
+ files = [] # Save a list of load/require files.
195
+ found = [] # Save a list of files found (.rb only for now)
196
+
197
+ # Open the file, strip embedded docs, and look for load/require statements.
198
+
199
+ begin
200
+ File.open(source).doc_skip {|line| files << scan(line)}
201
+ rescue => err
202
+ puts "Problem processing file #{source}: #{err}"
203
+ caller.each {|x| puts " #{x}"}
204
+ exit 3
205
+ end
206
+
207
+ # If no dependencies, don't bother searching!
208
+ if ! @has_dep
209
+ puts "No dependencies found."
210
+ exit 0
211
+ end
212
+
213
+ files.compact!
214
+ catch(:skip) do
215
+ for file in files
216
+
217
+ if file == "" # Warning
218
+ @warnfiles << source
219
+ next
220
+ end
221
+
222
+ throw :skip if (@inpath.include? file) || (@cantfind.include? file)
223
+
224
+ if file =~ /\.rb$/ then # Don't add suffix to *.rb
225
+ suffixes = [""] # Hmm... .rbw?? Probably not needed.
226
+ else
227
+ suffixes = @suffixes # Use any suffix (extension)
228
+ end
229
+
230
+ # Look through search path (@search_path)
231
+
232
+ for dir in @search_path
233
+
234
+ for suf in suffixes
235
+ filename = dir + file + suf
236
+ loadable = test ?e, filename
237
+ break if loadable
238
+ end
239
+
240
+ if loadable
241
+ @inpath << filename # Files we found in RUBYLIB
242
+ # Add to 'found' if it's a source file (so we can recurse)
243
+ found << filename if filename =~ /\.rb$/
244
+ break
245
+ end
246
+
247
+ end
248
+
249
+ @cantfind << file if !loadable
250
+ end
251
+ end
252
+
253
+ found.uniq!
254
+ found.compact!
255
+
256
+ @graph.add_vertex(source)
257
+
258
+ list = found
259
+ found.each {
260
+ |x|
261
+ @graph.add_edge(source,x)
262
+ list += find_files(x)
263
+ }
264
+
265
+ list
266
+ end
267
+
268
+ #
269
+ # print_list - Print a header message followed by a list of files
270
+ # or directories.
271
+ #
272
+
273
+ def print_list(header, list)
274
+ return if list.empty?
275
+ puts header + "\n\n" # Extra newlines
276
+ list.each {|x| puts " #{x}"}
277
+ puts "\n" # Extra newline
278
+ end
279
+
280
+ SEP = File::Separator
281
+ DIRSEP = if SEP=="/" then ":" else ";" end
282
+
283
+ def execute
284
+ @has_dep = false
285
+ @warnfiles = []
286
+ @newdirs = []
287
+ @inpath = []
288
+ @cantfind = []
289
+ @suffixes = [""] + %w[ .rb .o .so .dll ]
290
+ @rdirs = []
291
+ @global_found = []
292
+ @graph = RGL::DirectedAdjacencyGraph.new
293
+
294
+ # No parameters? Usage message
295
+
296
+ if not ARGV[0]
297
+ puts "Usage: ruby rdep.rb sourcefile [searchroot]"
298
+ exit 0
299
+ end
300
+
301
+ # Does sourcefile exist?
302
+
303
+ if ! test ?e, ARGV[0]
304
+ puts "#{ARGV[0]} does not exist."
305
+ exit 1
306
+ end
307
+
308
+ # Is sourcefile a "real" file?
309
+
310
+ if ! test ?f, ARGV[0]
311
+ puts "#{ARGV[0]} is not a regular file."
312
+ exit 2
313
+ end
314
+
315
+ # Be sure to search under the dir where the
316
+ # program lives...
317
+
318
+ @proghome = File.dirname(File.expand_path(ARGV[0]))
319
+ if @proghome != File.expand_path(".")
320
+ $: << @proghome
321
+ end
322
+
323
+ # Get list of dirs in $:
324
+
325
+ @search_path = $:
326
+ @search_path.collect! {|x| x[-1] == SEP ? x : x + SEP }
327
+
328
+ # All real work happens here -- big recursive find
329
+
330
+ find_files(ARGV[0])
331
+
332
+ @warnfiles.uniq!
333
+ @cantfind.uniq!
334
+ @newdirs.uniq!
335
+ @inpath.map! {|x| File.expand_path(x)}
336
+ @inpath.uniq!
337
+
338
+ #
339
+ # Now, what are all the results? Report to user.
340
+ #
341
+
342
+ if @inpath[0]
343
+ print_list("Found in search path:", @inpath)
344
+ if ! @cantfind.empty? && @warnfiles.empty?
345
+ puts "This will probably be sufficient.\n"
346
+ end
347
+ end
348
+
349
+ # Did we use any dirs under the "home"?
350
+
351
+ homedirs = @inpath.find_all {|x| x =~ Regexp.new("^"+@proghome)}
352
+ if homedirs[0] # not empty
353
+ homedirs.map! {|x| File.dirname(x) }.uniq!
354
+ puts "Consider adding these directories to RUBYPATH:\n\n"
355
+ homedirs.each {|x| puts " #{x}" }
356
+ puts
357
+ if @warnfiles[0] and homedirs == [] # There are unparseable statements.
358
+ puts "This will probably NOT be sufficient. See below.\n\n"
359
+ end
360
+ end
361
+
362
+ # What's our opinion?
363
+
364
+ if @cantfind[0] # There are unknown files.
365
+ puts "This will probably NOT be sufficient. See below.\n\n"
366
+ elsif @warnfiles[0] and homedirs == [] # There are unparseable statements.
367
+ puts "Files may still be missing. See below.\n\n"
368
+ else # We think everything is OK.
369
+ puts "This will probably be sufficient."
370
+ end
371
+
372
+ # Report unknown files
373
+ print_list("Not located anywhere:", @cantfind)
374
+
375
+ # Print warning about load/require strings we couldn't understand
376
+ print_list("Warning: Unparseable usages of 'load' or 'require' in:",
377
+ @warnfiles)
378
+ end
379
+
380
+ end
381
+
382
+ d = Dependency.new
383
+ d.execute
384
+ begin
385
+ d.graph.write_to_graphic_file('png',
386
+ File.basename(ARGV[0]),
387
+ 'label'=>"Dependencies of #{ARGV[0]}")
388
+ rescue ArgumentError
389
+ d.graph.write_to_graphic_file('png',
390
+ File.basename(ARGV[0]))
391
+ end
392
+
393
+
394
+ exit 0
395
+