rdoc 2.4.1 → 2.4.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rdoc might be problematic. Click here for more details.
- data.tar.gz.sig +0 -0
- data/History.txt +25 -0
- data/Manifest.txt +2 -0
- data/Rakefile +1 -0
- data/lib/rdoc.rb +17 -24
- data/lib/rdoc/context.rb +1 -1
- data/lib/rdoc/generator/darkfish.rb +1 -1
- data/lib/rdoc/generator/template/darkfish/classpage.rhtml +1 -1
- data/lib/rdoc/markup/attribute_manager.rb +2 -2
- data/lib/rdoc/markup/to_html_crossref.rb +3 -1
- data/lib/rdoc/options.rb +126 -104
- data/lib/rdoc/parser/c.rb +1 -0
- data/lib/rdoc/parser/ruby.rb +62 -55
- data/lib/rdoc/rdoc.rb +253 -239
- data/lib/rdoc/ri/driver.rb +5 -5
- data/lib/rdoc/task.rb +276 -0
- data/lib/rdoc/top_level.rb +10 -0
- data/test/test_rdoc_markup_attribute_manager.rb +9 -0
- data/test/test_rdoc_markup_to_html.rb +1 -0
- data/test/test_rdoc_markup_to_html_crossref.rb +1 -0
- data/test/test_rdoc_parser_c.rb +28 -0
- data/test/test_rdoc_parser_ruby.rb +90 -2
- data/test/test_rdoc_task.rb +64 -0
- metadata +21 -7
- metadata.gz.sig +0 -0
data/lib/rdoc/parser/c.rb
CHANGED
@@ -614,6 +614,7 @@ class RDoc::Parser::C < RDoc::Parser
|
|
614
614
|
if find_body(class_name, meth_body, meth_obj, body) and meth_obj.document_self then
|
615
615
|
class_obj.add_method meth_obj
|
616
616
|
@stats.add_method meth_obj
|
617
|
+
meth_obj.visibility = :private if 'private_method' == type
|
617
618
|
end
|
618
619
|
end
|
619
620
|
end
|
data/lib/rdoc/parser/ruby.rb
CHANGED
@@ -1889,7 +1889,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1889
1889
|
end
|
1890
1890
|
|
1891
1891
|
def parse_class(container, single, tk, comment)
|
1892
|
-
container, name_t = get_class_or_module
|
1892
|
+
container, name_t = get_class_or_module container
|
1893
1893
|
|
1894
1894
|
case name_t
|
1895
1895
|
when TkCONSTANT
|
@@ -1921,9 +1921,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1921
1921
|
else
|
1922
1922
|
other = RDoc::TopLevel.find_class_named(name)
|
1923
1923
|
unless other
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1924
|
+
# other = @top_level.add_class(NormalClass, name, nil)
|
1925
|
+
# other.record_location(@top_level)
|
1926
|
+
# other.comment = comment
|
1927
1927
|
other = RDoc::NormalClass.new "Dummy", nil
|
1928
1928
|
end
|
1929
1929
|
|
@@ -1948,7 +1948,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1948
1948
|
return
|
1949
1949
|
end
|
1950
1950
|
|
1951
|
-
|
1952
1951
|
nest = 0
|
1953
1952
|
get_tkread
|
1954
1953
|
|
@@ -1960,25 +1959,27 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1960
1959
|
end
|
1961
1960
|
|
1962
1961
|
loop do
|
1963
|
-
|
1964
|
-
|
1962
|
+
case tk
|
1963
|
+
when TkSEMICOLON then
|
1964
|
+
break
|
1965
|
+
when TkLPAREN, TkfLPAREN, TkLBRACE, TkLBRACK, TkDO, TkIF, TkUNLESS,
|
1966
|
+
TkCASE then
|
1967
|
+
nest += 1
|
1968
|
+
when TkRPAREN, TkRBRACE, TkRBRACK, TkEND then
|
1969
|
+
nest -= 1
|
1970
|
+
when TkCOMMENT then
|
1971
|
+
if nest <= 0 && @scanner.lex_state == EXPR_END
|
1972
|
+
unget_tk tk
|
1965
1973
|
break
|
1966
|
-
when TkLPAREN, TkfLPAREN, TkLBRACE, TkLBRACK, TkDO
|
1967
|
-
nest += 1
|
1968
|
-
when TkRPAREN, TkRBRACE, TkRBRACK, TkEND
|
1969
|
-
nest -= 1
|
1970
|
-
when TkCOMMENT
|
1971
|
-
if nest <= 0 && @scanner.lex_state == EXPR_END
|
1972
|
-
unget_tk(tk)
|
1973
|
-
break
|
1974
|
-
end
|
1975
|
-
when TkNL
|
1976
|
-
if (nest <= 0) && ((@scanner.lex_state == EXPR_END) || (!@scanner.continue))
|
1977
|
-
unget_tk(tk)
|
1978
|
-
break
|
1979
|
-
end
|
1980
1974
|
end
|
1981
|
-
|
1975
|
+
when TkNL then
|
1976
|
+
if nest <= 0 &&
|
1977
|
+
(@scanner.lex_state == EXPR_END || !@scanner.continue) then
|
1978
|
+
unget_tk tk
|
1979
|
+
break
|
1980
|
+
end
|
1981
|
+
end
|
1982
|
+
tk = get_tk
|
1982
1983
|
end
|
1983
1984
|
|
1984
1985
|
res = get_tkread.tr("\n", " ").strip
|
@@ -1987,9 +1988,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1987
1988
|
con = RDoc::Constant.new name, res, comment
|
1988
1989
|
read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS
|
1989
1990
|
|
1990
|
-
if con.document_self
|
1991
|
-
container.add_constant(con)
|
1992
|
-
end
|
1991
|
+
container.add_constant con if con.document_self
|
1993
1992
|
end
|
1994
1993
|
|
1995
1994
|
##
|
@@ -2300,33 +2299,37 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
2300
2299
|
nest = 0
|
2301
2300
|
|
2302
2301
|
loop do
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2308
|
-
|
2309
|
-
|
2310
|
-
|
2302
|
+
case tk
|
2303
|
+
when TkSEMICOLON then
|
2304
|
+
break
|
2305
|
+
when TkLBRACE then
|
2306
|
+
nest += 1
|
2307
|
+
when TkRBRACE then
|
2308
|
+
# we might have a.each {|i| yield i }
|
2309
|
+
unget_tk(tk) if nest.zero?
|
2310
|
+
nest -= 1
|
2311
|
+
break if nest <= 0
|
2312
|
+
when TkLPAREN, TkfLPAREN then
|
2313
|
+
nest += 1
|
2314
|
+
when end_token then
|
2315
|
+
if end_token == TkRPAREN
|
2311
2316
|
nest -= 1
|
2312
|
-
break if nest <= 0
|
2313
|
-
|
2314
|
-
|
2315
|
-
when end_token
|
2316
|
-
if end_token == TkRPAREN
|
2317
|
-
nest -= 1
|
2318
|
-
break if @scanner.lex_state == EXPR_END and nest <= 0
|
2319
|
-
else
|
2320
|
-
break unless @scanner.continue
|
2321
|
-
end
|
2322
|
-
when method && method.block_params.nil? && TkCOMMENT
|
2323
|
-
unget_tk(tk)
|
2324
|
-
read_documentation_modifiers(method, modifiers)
|
2317
|
+
break if @scanner.lex_state == EXPR_END and nest <= 0
|
2318
|
+
else
|
2319
|
+
break unless @scanner.continue
|
2325
2320
|
end
|
2321
|
+
when method && method.block_params.nil? && TkCOMMENT then
|
2322
|
+
unget_tk tk
|
2323
|
+
read_documentation_modifiers method, modifiers
|
2324
|
+
@read.pop
|
2325
|
+
when TkCOMMENT then
|
2326
|
+
@read.pop
|
2327
|
+
end
|
2326
2328
|
tk = get_tk
|
2327
2329
|
end
|
2328
|
-
|
2329
|
-
res =
|
2330
|
+
|
2331
|
+
res = get_tkread.gsub(/\s+/, ' ').strip
|
2332
|
+
res = '' if res == ';'
|
2330
2333
|
res
|
2331
2334
|
end
|
2332
2335
|
|
@@ -2339,10 +2342,12 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
2339
2342
|
# and add this as the block_params for the method
|
2340
2343
|
|
2341
2344
|
def parse_method_parameters(method)
|
2342
|
-
res = parse_method_or_yield_parameters
|
2343
|
-
|
2345
|
+
res = parse_method_or_yield_parameters method
|
2346
|
+
|
2347
|
+
res = "(#{res})" unless res =~ /\A\(/
|
2344
2348
|
method.params = res unless method.params
|
2345
|
-
|
2349
|
+
|
2350
|
+
if method.block_params.nil? then
|
2346
2351
|
skip_tkspace(false)
|
2347
2352
|
read_documentation_modifiers method, RDoc::METHOD_MODIFIERS
|
2348
2353
|
end
|
@@ -2708,16 +2713,18 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
2708
2713
|
def read_directive(allowed)
|
2709
2714
|
tk = get_tk
|
2710
2715
|
result = nil
|
2711
|
-
|
2712
|
-
|
2716
|
+
|
2717
|
+
if TkCOMMENT === tk then
|
2718
|
+
if tk.text =~ /\s*:?(\w+):\s*(.*)/ then
|
2713
2719
|
directive = $1.downcase
|
2714
|
-
if allowed.include?
|
2720
|
+
if allowed.include? directive then
|
2715
2721
|
result = [directive, $2]
|
2716
2722
|
end
|
2717
2723
|
end
|
2718
2724
|
else
|
2719
|
-
unget_tk
|
2725
|
+
unget_tk tk
|
2720
2726
|
end
|
2727
|
+
|
2721
2728
|
result
|
2722
2729
|
end
|
2723
2730
|
|
data/lib/rdoc/rdoc.rb
CHANGED
@@ -18,329 +18,343 @@ require 'fileutils'
|
|
18
18
|
require 'time'
|
19
19
|
require 'thread'
|
20
20
|
|
21
|
-
|
21
|
+
##
|
22
|
+
# Encapsulate the production of rdoc documentation. Basically you can use this
|
23
|
+
# as you would invoke rdoc from the command line:
|
24
|
+
#
|
25
|
+
# rdoc = RDoc::RDoc.new
|
26
|
+
# rdoc.document(args)
|
27
|
+
#
|
28
|
+
# Where +args+ is an array of strings, each corresponding to an argument you'd
|
29
|
+
# give rdoc on the command line. See rdoc/rdoc.rb for details.
|
30
|
+
|
31
|
+
class RDoc::RDoc
|
22
32
|
|
23
33
|
##
|
24
|
-
#
|
25
|
-
# this as you would invoke rdoc from the command line:
|
26
|
-
#
|
27
|
-
# rdoc = RDoc::RDoc.new
|
28
|
-
# rdoc.document(args)
|
29
|
-
#
|
30
|
-
# Where +args+ is an array of strings, each corresponding to an argument
|
31
|
-
# you'd give rdoc on the command line. See rdoc/rdoc.rb for details.
|
34
|
+
# Generator instance used for creating output
|
32
35
|
|
33
|
-
|
36
|
+
attr_accessor :generator
|
34
37
|
|
35
|
-
|
36
|
-
|
38
|
+
##
|
39
|
+
# RDoc options
|
37
40
|
|
38
|
-
|
41
|
+
attr_reader :options
|
39
42
|
|
40
|
-
|
41
|
-
|
43
|
+
##
|
44
|
+
# Accessor for statistics. Available after each call to parse_files
|
42
45
|
|
43
|
-
|
46
|
+
attr_reader :stats
|
44
47
|
|
45
|
-
|
46
|
-
|
48
|
+
##
|
49
|
+
# This is the list of supported output generators
|
47
50
|
|
48
|
-
|
51
|
+
GENERATORS = {}
|
49
52
|
|
50
|
-
|
51
|
-
|
53
|
+
##
|
54
|
+
# Add +klass+ that can generate output after parsing
|
52
55
|
|
53
|
-
|
56
|
+
def self.add_generator(klass)
|
57
|
+
name = klass.name.sub(/^RDoc::Generator::/, '').downcase
|
58
|
+
GENERATORS[name] = klass
|
59
|
+
end
|
54
60
|
|
55
|
-
|
56
|
-
|
61
|
+
##
|
62
|
+
# Active RDoc::RDoc instance
|
57
63
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
64
|
+
def self.current
|
65
|
+
@current
|
66
|
+
end
|
62
67
|
|
63
|
-
|
64
|
-
|
68
|
+
##
|
69
|
+
# Sets the active RDoc::RDoc instance
|
65
70
|
|
66
|
-
|
67
|
-
|
68
|
-
|
71
|
+
def self.current=(rdoc)
|
72
|
+
@current = rdoc
|
73
|
+
end
|
69
74
|
|
70
|
-
|
71
|
-
|
75
|
+
def initialize
|
76
|
+
@generator = nil
|
77
|
+
@options = nil
|
78
|
+
@stats = nil
|
79
|
+
end
|
72
80
|
|
73
|
-
|
74
|
-
|
75
|
-
end
|
81
|
+
##
|
82
|
+
# Report an error message and exit
|
76
83
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
@stats = nil
|
81
|
-
end
|
84
|
+
def error(msg)
|
85
|
+
raise RDoc::Error, msg
|
86
|
+
end
|
82
87
|
|
83
|
-
|
84
|
-
|
88
|
+
##
|
89
|
+
# Turns RDoc from stdin into HTML
|
85
90
|
|
86
|
-
|
87
|
-
|
88
|
-
end
|
91
|
+
def handle_pipe
|
92
|
+
@html = RDoc::Markup::ToHtml.new
|
89
93
|
|
90
|
-
|
91
|
-
# Create an output dir if it doesn't exist. If it does exist, but doesn't
|
92
|
-
# contain the flag file <tt>created.rid</tt> then we refuse to use it, as
|
93
|
-
# we may clobber some manually generated documentation
|
94
|
+
out = @html.convert $stdin.read
|
94
95
|
|
95
|
-
|
96
|
-
|
96
|
+
$stdout.write out
|
97
|
+
end
|
97
98
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
99
|
+
##
|
100
|
+
# Create an output dir if it doesn't exist. If it does exist, but doesn't
|
101
|
+
# contain the flag file <tt>created.rid</tt> then we refuse to use it, as
|
102
|
+
# we may clobber some manually generated documentation
|
103
|
+
|
104
|
+
def setup_output_dir(op_dir, force)
|
105
|
+
flag_file = output_flag_file op_dir
|
106
|
+
|
107
|
+
if File.exist? op_dir then
|
108
|
+
unless File.directory? op_dir then
|
109
|
+
error "'#{op_dir}' exists, and is not a directory"
|
110
|
+
end
|
111
|
+
begin
|
112
|
+
created = File.read(flag_file)
|
113
|
+
rescue SystemCallError
|
114
|
+
error "\nDirectory #{op_dir} already exists, but it looks like it\n" +
|
115
|
+
"isn't an RDoc directory. Because RDoc doesn't want to risk\n" +
|
116
|
+
"destroying any of your existing files, you'll need to\n" +
|
117
|
+
"specify a different output directory name (using the\n" +
|
118
|
+
"--op <dir> option).\n\n"
|
113
119
|
else
|
114
|
-
|
120
|
+
last = (Time.parse(created) unless force rescue nil)
|
115
121
|
end
|
116
|
-
|
122
|
+
else
|
123
|
+
FileUtils.mkdir_p(op_dir)
|
117
124
|
end
|
125
|
+
last
|
126
|
+
end
|
118
127
|
|
119
|
-
|
120
|
-
|
128
|
+
##
|
129
|
+
# Update the flag file in an output directory.
|
121
130
|
|
122
|
-
|
123
|
-
|
124
|
-
|
131
|
+
def update_output_dir(op_dir, time)
|
132
|
+
File.open(output_flag_file(op_dir), "w") { |f| f.puts time.rfc2822 }
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# Return the path name of the flag file in an output directory.
|
137
|
+
|
138
|
+
def output_flag_file(op_dir)
|
139
|
+
File.join op_dir, "created.rid"
|
140
|
+
end
|
125
141
|
|
126
|
-
|
127
|
-
|
142
|
+
##
|
143
|
+
# The .document file contains a list of file and directory name patterns,
|
144
|
+
# representing candidates for documentation. It may also contain comments
|
145
|
+
# (starting with '#')
|
146
|
+
|
147
|
+
def parse_dot_doc_file(in_dir, filename, options)
|
148
|
+
# read and strip comments
|
149
|
+
patterns = File.read(filename).gsub(/#.*/, '')
|
150
|
+
|
151
|
+
result = []
|
128
152
|
|
129
|
-
|
130
|
-
File.join
|
153
|
+
patterns.split.each do |patt|
|
154
|
+
candidates = Dir.glob(File.join(in_dir, patt))
|
155
|
+
result.concat(normalized_file_list(options, candidates))
|
131
156
|
end
|
132
157
|
|
133
|
-
|
134
|
-
|
135
|
-
# representing candidates for documentation. It may also contain comments
|
136
|
-
# (starting with '#')
|
158
|
+
result
|
159
|
+
end
|
137
160
|
|
138
|
-
|
139
|
-
|
140
|
-
|
161
|
+
##
|
162
|
+
# Given a list of files and directories, create a list of all the Ruby
|
163
|
+
# files they contain.
|
164
|
+
#
|
165
|
+
# If +force_doc+ is true we always add the given files, if false, only
|
166
|
+
# add files that we guarantee we can parse. It is true when looking at
|
167
|
+
# files given on the command line, false when recursing through
|
168
|
+
# subdirectories.
|
169
|
+
#
|
170
|
+
# The effect of this is that if you want a file with a non-standard
|
171
|
+
# extension parsed, you must name it explicitly.
|
141
172
|
|
142
|
-
|
173
|
+
def normalized_file_list(options, relative_files, force_doc = false,
|
174
|
+
exclude_pattern = nil)
|
175
|
+
file_list = []
|
143
176
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
end
|
177
|
+
relative_files.each do |rel_file_name|
|
178
|
+
next if exclude_pattern && exclude_pattern =~ rel_file_name
|
179
|
+
stat = File.stat rel_file_name rescue next
|
148
180
|
|
149
|
-
|
150
|
-
|
181
|
+
case type = stat.ftype
|
182
|
+
when "file"
|
183
|
+
next if @last_created and stat.mtime < @last_created
|
151
184
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
#
|
161
|
-
# The effect of this is that if you want a file with a non-standard
|
162
|
-
# extension parsed, you must name it explicitly.
|
163
|
-
|
164
|
-
def normalized_file_list(options, relative_files, force_doc = false,
|
165
|
-
exclude_pattern = nil)
|
166
|
-
file_list = []
|
167
|
-
|
168
|
-
relative_files.each do |rel_file_name|
|
169
|
-
next if exclude_pattern && exclude_pattern =~ rel_file_name
|
170
|
-
stat = File.stat rel_file_name rescue next
|
171
|
-
|
172
|
-
case type = stat.ftype
|
173
|
-
when "file"
|
174
|
-
next if @last_created and stat.mtime < @last_created
|
175
|
-
|
176
|
-
if force_doc or ::RDoc::Parser.can_parse(rel_file_name) then
|
177
|
-
file_list << rel_file_name.sub(/^\.\//, '')
|
178
|
-
end
|
179
|
-
when "directory"
|
180
|
-
next if rel_file_name == "CVS" || rel_file_name == ".svn"
|
181
|
-
dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME)
|
182
|
-
if File.file?(dot_doc)
|
183
|
-
file_list.concat(parse_dot_doc_file(rel_file_name, dot_doc, options))
|
184
|
-
else
|
185
|
-
file_list.concat(list_files_in_directory(rel_file_name, options))
|
186
|
-
end
|
185
|
+
if force_doc or RDoc::Parser.can_parse(rel_file_name) then
|
186
|
+
file_list << rel_file_name.sub(/^\.\//, '')
|
187
|
+
end
|
188
|
+
when "directory"
|
189
|
+
next if rel_file_name == "CVS" || rel_file_name == ".svn"
|
190
|
+
dot_doc = File.join(rel_file_name, RDoc::DOT_DOC_FILENAME)
|
191
|
+
if File.file?(dot_doc)
|
192
|
+
file_list.concat(parse_dot_doc_file(rel_file_name, dot_doc, options))
|
187
193
|
else
|
188
|
-
|
194
|
+
file_list.concat(list_files_in_directory(rel_file_name, options))
|
189
195
|
end
|
196
|
+
else
|
197
|
+
raise RDoc::Error, "I can't deal with a #{type} #{rel_file_name}"
|
190
198
|
end
|
191
|
-
|
192
|
-
file_list
|
193
199
|
end
|
194
200
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
201
|
+
file_list
|
202
|
+
end
|
203
|
+
|
204
|
+
##
|
205
|
+
# Return a list of the files to be processed in a directory. We know that
|
206
|
+
# this directory doesn't have a .document file, so we're looking for real
|
207
|
+
# files. However we may well contain subdirectories which must be tested
|
208
|
+
# for .document files.
|
200
209
|
|
201
|
-
|
202
|
-
|
210
|
+
def list_files_in_directory(dir, options)
|
211
|
+
files = Dir.glob File.join(dir, "*")
|
203
212
|
|
204
|
-
|
205
|
-
|
213
|
+
normalized_file_list options, files, false, options.exclude
|
214
|
+
end
|
206
215
|
|
207
|
-
|
208
|
-
|
216
|
+
##
|
217
|
+
# Parse each file on the command line, recursively entering directories.
|
209
218
|
|
210
|
-
|
211
|
-
|
212
|
-
|
219
|
+
def parse_files(options)
|
220
|
+
files = options.files
|
221
|
+
files = ["."] if files.empty?
|
213
222
|
|
214
|
-
|
223
|
+
file_list = normalized_file_list(options, files, true, options.exclude)
|
215
224
|
|
216
|
-
|
225
|
+
return [] if file_list.empty?
|
217
226
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
227
|
+
jobs = SizedQueue.new(@options.threads * 3)
|
228
|
+
workers = []
|
229
|
+
file_info = []
|
230
|
+
file_info_lock = Mutex.new
|
222
231
|
|
223
|
-
|
224
|
-
|
225
|
-
|
232
|
+
Thread.abort_on_exception = true
|
233
|
+
@stats = RDoc::Stats.new(file_list.size, options.verbosity)
|
234
|
+
@stats.begin_adding @options.threads
|
226
235
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
236
|
+
# Create worker threads.
|
237
|
+
@options.threads.times do
|
238
|
+
thread = Thread.new do
|
239
|
+
while (filename = jobs.pop)
|
240
|
+
@stats.add_file(filename)
|
241
|
+
content = read_file_contents(filename)
|
242
|
+
top_level = RDoc::TopLevel.new filename
|
234
243
|
|
235
|
-
|
236
|
-
|
237
|
-
|
244
|
+
parser = RDoc::Parser.for(top_level, filename, content, options,
|
245
|
+
@stats)
|
246
|
+
result = parser.scan
|
238
247
|
|
239
|
-
|
240
|
-
|
241
|
-
end
|
248
|
+
file_info_lock.synchronize do
|
249
|
+
file_info << result
|
242
250
|
end
|
243
251
|
end
|
244
|
-
workers << thread
|
245
252
|
end
|
253
|
+
workers << thread
|
254
|
+
end
|
246
255
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
256
|
+
# Feed filenames to the parser worker threads...
|
257
|
+
file_list.each do |filename|
|
258
|
+
jobs << filename
|
259
|
+
end
|
260
|
+
workers.size.times do
|
261
|
+
jobs << nil
|
262
|
+
end
|
254
263
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
264
|
+
# ...and wait until they're done.
|
265
|
+
workers.each do |thread|
|
266
|
+
thread.join
|
267
|
+
end
|
259
268
|
|
260
|
-
|
269
|
+
@stats.done_adding
|
261
270
|
|
262
|
-
|
263
|
-
|
271
|
+
file_info
|
272
|
+
end
|
264
273
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
274
|
+
##
|
275
|
+
# Format up one or more files according to the given arguments.
|
276
|
+
#
|
277
|
+
# For simplicity, _argv_ is an array of strings, equivalent to the strings
|
278
|
+
# that would be passed on the command line. (This isn't a coincidence, as
|
279
|
+
# we _do_ pass in ARGV when running interactively). For a list of options,
|
280
|
+
# see rdoc/rdoc.rb. By default, output will be stored in a directory
|
281
|
+
# called +doc+ below the current directory, so make sure you're somewhere
|
282
|
+
# writable before invoking.
|
283
|
+
#
|
284
|
+
# Throws: RDoc::Error on error
|
276
285
|
|
277
|
-
|
278
|
-
|
286
|
+
def document(argv)
|
287
|
+
RDoc::TopLevel.reset
|
279
288
|
|
280
|
-
|
281
|
-
|
289
|
+
@options = RDoc::Options.new
|
290
|
+
@options.parse argv
|
282
291
|
|
283
|
-
|
292
|
+
if @options.pipe then
|
293
|
+
handle_pipe
|
294
|
+
exit
|
295
|
+
end
|
284
296
|
|
285
|
-
|
297
|
+
@last_created = setup_output_dir @options.op_dir, @options.force_update
|
286
298
|
|
287
|
-
|
299
|
+
start_time = Time.now
|
288
300
|
|
289
|
-
|
301
|
+
file_info = parse_files @options
|
290
302
|
|
291
|
-
|
292
|
-
$stderr.puts "\nNo newer files." unless @options.quiet
|
293
|
-
else
|
294
|
-
gen_klass = @options.generator
|
303
|
+
@options.title = "RDoc Documentation"
|
295
304
|
|
296
|
-
|
297
|
-
|
298
|
-
|
305
|
+
if file_info.empty?
|
306
|
+
$stderr.puts "\nNo newer files." unless @options.quiet
|
307
|
+
else
|
308
|
+
gen_klass = @options.generator
|
299
309
|
|
300
|
-
|
310
|
+
unless @options.quiet then
|
311
|
+
$stderr.puts "\nGenerating #{gen_klass.name.sub(/^.*::/, '')}..."
|
312
|
+
end
|
301
313
|
|
302
|
-
|
314
|
+
@generator = gen_klass.for @options
|
303
315
|
|
304
|
-
|
316
|
+
pwd = Dir.pwd
|
305
317
|
|
306
|
-
|
307
|
-
self.class.current = self
|
318
|
+
Dir.chdir @options.op_dir
|
308
319
|
|
309
|
-
|
310
|
-
|
311
|
-
update_output_dir ".", start_time
|
312
|
-
ensure
|
313
|
-
self.class.current = nil
|
314
|
-
Dir.chdir pwd
|
315
|
-
end
|
316
|
-
end
|
320
|
+
begin
|
321
|
+
self.class.current = self
|
317
322
|
|
318
|
-
|
319
|
-
|
320
|
-
|
323
|
+
RDoc::Diagram.new(file_info, @options).draw if @options.diagram
|
324
|
+
@generator.generate file_info
|
325
|
+
update_output_dir ".", start_time
|
326
|
+
ensure
|
327
|
+
self.class.current = nil
|
328
|
+
Dir.chdir pwd
|
321
329
|
end
|
322
330
|
end
|
323
331
|
|
324
|
-
|
332
|
+
unless @options.quiet or not @stats then
|
333
|
+
puts
|
334
|
+
@stats.print
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
private
|
325
339
|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
340
|
+
def read_file_contents(filename)
|
341
|
+
content = if RUBY_VERSION >= '1.9' then
|
342
|
+
File.open(filename, "r:ascii-8bit") { |f| f.read }
|
343
|
+
else
|
344
|
+
File.read filename
|
345
|
+
end
|
332
346
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
end
|
347
|
+
if defined? Encoding then
|
348
|
+
if /coding:\s*(\S+)/ =~ content[/\A(?:.*\n){0,2}/]
|
349
|
+
if enc = ::Encoding.find($1)
|
350
|
+
content.force_encoding(enc)
|
338
351
|
end
|
339
352
|
end
|
340
|
-
|
341
|
-
content
|
342
353
|
end
|
354
|
+
|
355
|
+
content
|
343
356
|
end
|
357
|
+
|
344
358
|
end
|
345
359
|
|
346
360
|
if Gem.respond_to? :find_files then
|