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
@@ -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
+