rdoc 2.5.11 → 3.0

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.

Files changed (113) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.document +1 -0
  3. data/History.txt +95 -0
  4. data/Manifest.txt +13 -4
  5. data/README.txt +9 -3
  6. data/Rakefile +1 -1
  7. data/lib/rdoc.rb +15 -298
  8. data/lib/rdoc/alias.rb +65 -16
  9. data/lib/rdoc/any_method.rb +27 -150
  10. data/lib/rdoc/attr.rb +36 -115
  11. data/lib/rdoc/class_module.rb +236 -22
  12. data/lib/rdoc/code_object.rb +76 -31
  13. data/lib/rdoc/constant.rb +32 -4
  14. data/lib/rdoc/context.rb +494 -222
  15. data/lib/rdoc/encoding.rb +79 -0
  16. data/lib/rdoc/erbio.rb +37 -0
  17. data/lib/rdoc/gauntlet.rb +9 -5
  18. data/lib/rdoc/generator.rb +33 -1
  19. data/lib/rdoc/generator/darkfish.rb +284 -375
  20. data/lib/rdoc/generator/markup.rb +72 -36
  21. data/lib/rdoc/generator/ri.rb +4 -4
  22. data/lib/rdoc/generator/template/darkfish/classpage.rhtml +267 -274
  23. data/lib/rdoc/generator/template/darkfish/filepage.rhtml +91 -91
  24. data/lib/rdoc/generator/template/darkfish/index.rhtml +45 -45
  25. data/lib/rdoc/generator/template/darkfish/rdoc.css +298 -298
  26. data/lib/rdoc/include.rb +40 -1
  27. data/lib/rdoc/known_classes.rb +1 -0
  28. data/lib/rdoc/markup.rb +467 -2
  29. data/lib/rdoc/markup/attribute_manager.rb +24 -6
  30. data/lib/rdoc/markup/blank_line.rb +11 -3
  31. data/lib/rdoc/markup/document.rb +6 -0
  32. data/lib/rdoc/markup/formatter.rb +10 -0
  33. data/lib/rdoc/markup/formatter_test_case.rb +339 -3
  34. data/lib/rdoc/markup/heading.rb +3 -0
  35. data/lib/rdoc/markup/inline.rb +11 -1
  36. data/lib/rdoc/markup/list.rb +3 -0
  37. data/lib/rdoc/markup/list_item.rb +3 -0
  38. data/lib/rdoc/markup/paragraph.rb +3 -0
  39. data/lib/rdoc/markup/parser.rb +191 -237
  40. data/lib/rdoc/markup/{preprocess.rb → pre_process.rb} +50 -29
  41. data/lib/rdoc/markup/raw.rb +4 -0
  42. data/lib/rdoc/markup/rule.rb +3 -0
  43. data/lib/rdoc/markup/text_formatter_test_case.rb +116 -0
  44. data/lib/rdoc/markup/to_ansi.rb +14 -2
  45. data/lib/rdoc/markup/to_bs.rb +8 -2
  46. data/lib/rdoc/markup/to_html.rb +84 -91
  47. data/lib/rdoc/markup/to_html_crossref.rb +77 -26
  48. data/lib/rdoc/markup/to_rdoc.rb +94 -49
  49. data/lib/rdoc/markup/to_test.rb +9 -1
  50. data/lib/rdoc/markup/verbatim.rb +6 -3
  51. data/lib/rdoc/method_attr.rb +353 -0
  52. data/lib/rdoc/normal_class.rb +11 -2
  53. data/lib/rdoc/normal_module.rb +0 -5
  54. data/lib/rdoc/options.rb +373 -82
  55. data/lib/rdoc/parser.rb +59 -23
  56. data/lib/rdoc/parser/c.rb +224 -86
  57. data/lib/rdoc/parser/ruby.rb +219 -111
  58. data/lib/rdoc/parser/ruby_tools.rb +4 -1
  59. data/lib/rdoc/parser/simple.rb +9 -4
  60. data/lib/rdoc/rdoc.rb +68 -28
  61. data/lib/rdoc/require.rb +21 -0
  62. data/lib/rdoc/ri/driver.rb +20 -10
  63. data/lib/rdoc/ri/paths.rb +2 -2
  64. data/lib/rdoc/ri/store.rb +22 -5
  65. data/lib/rdoc/ruby_lex.rb +11 -12
  66. data/lib/rdoc/ruby_token.rb +2 -2
  67. data/lib/rdoc/single_class.rb +2 -1
  68. data/lib/rdoc/stats.rb +202 -162
  69. data/lib/rdoc/stats/normal.rb +51 -0
  70. data/lib/rdoc/stats/quiet.rb +59 -0
  71. data/lib/rdoc/stats/verbose.rb +45 -0
  72. data/lib/rdoc/text.rb +133 -4
  73. data/lib/rdoc/{tokenstream.rb → token_stream.rb} +0 -2
  74. data/lib/rdoc/top_level.rb +230 -39
  75. data/test/test_attribute_manager.rb +58 -7
  76. data/test/test_rdoc_alias.rb +13 -0
  77. data/test/test_rdoc_any_method.rb +43 -2
  78. data/test/test_rdoc_attr.rb +15 -8
  79. data/test/test_rdoc_class_module.rb +133 -0
  80. data/test/test_rdoc_code_object.rb +62 -5
  81. data/test/test_rdoc_context.rb +72 -26
  82. data/test/test_rdoc_encoding.rb +145 -0
  83. data/test/test_rdoc_generator_darkfish.rb +119 -0
  84. data/test/test_rdoc_generator_ri.rb +22 -2
  85. data/test/test_rdoc_include.rb +79 -0
  86. data/test/test_rdoc_markup_attribute_manager.rb +4 -4
  87. data/test/test_rdoc_markup_parser.rb +134 -95
  88. data/test/test_rdoc_markup_pre_process.rb +7 -2
  89. data/test/test_rdoc_markup_to_ansi.rb +43 -153
  90. data/test/test_rdoc_markup_to_bs.rb +42 -156
  91. data/test/test_rdoc_markup_to_html.rb +130 -58
  92. data/test/test_rdoc_markup_to_html_crossref.rb +10 -10
  93. data/test/test_rdoc_markup_to_rdoc.rb +40 -151
  94. data/test/test_rdoc_method_attr.rb +122 -0
  95. data/test/test_rdoc_normal_class.rb +1 -1
  96. data/test/test_rdoc_normal_module.rb +6 -1
  97. data/test/test_rdoc_options.rb +237 -12
  98. data/test/test_rdoc_parser.rb +3 -22
  99. data/test/test_rdoc_parser_c.rb +203 -2
  100. data/test/test_rdoc_parser_ruby.rb +403 -89
  101. data/test/test_rdoc_parser_simple.rb +25 -1
  102. data/test/test_rdoc_rdoc.rb +44 -32
  103. data/test/test_rdoc_ri_driver.rb +29 -24
  104. data/test/test_rdoc_ri_store.rb +46 -3
  105. data/test/test_rdoc_task.rb +1 -1
  106. data/test/test_rdoc_text.rb +102 -8
  107. data/test/test_rdoc_top_level.rb +13 -4
  108. data/test/xref_data.rb +8 -0
  109. data/test/xref_test_case.rb +6 -0
  110. metadata +29 -19
  111. metadata.gz.sig +0 -0
  112. data/lib/rdoc/parser/perl.rb +0 -165
  113. data/test/test_rdoc_parser_perl.rb +0 -73
@@ -1,6 +1,6 @@
1
1
  require 'rdoc'
2
2
  require 'rdoc/code_objects'
3
- require 'rdoc/markup/preprocess'
3
+ require 'rdoc/markup/pre_process'
4
4
  require 'rdoc/stats'
5
5
 
6
6
  ##
@@ -43,7 +43,15 @@ class RDoc::Parser
43
43
  @parsers = []
44
44
 
45
45
  class << self
46
+
47
+ ##
48
+ # A Hash that maps file exetensions regular expressions to parsers that
49
+ # will consume them.
50
+ #
51
+ # Use parse_files_matching to register a parser's file extensions.
52
+
46
53
  attr_reader :parsers
54
+
47
55
  end
48
56
 
49
57
  ##
@@ -62,34 +70,56 @@ class RDoc::Parser
62
70
  true
63
71
  end
64
72
 
65
- def self.set_encoding(string)
66
- if defined? Encoding then
67
- if /coding[=:]\s*([^\s;]+)/i =~ string[%r"\A(?:#!.*\n)?.*\n"]
68
- if enc = ::Encoding.find($1)
69
- string.force_encoding(enc)
70
- end
71
- end
72
- end
73
- end
74
-
75
73
  ##
76
74
  # Determines if the file is a "binary" file which basically means it has
77
75
  # content that an RDoc parser shouldn't try to consume.
78
76
 
79
77
  def self.binary?(file)
78
+ return false if file =~ /\.(rdoc|txt)$/
79
+
80
80
  s = File.read(file, 1024) or return false
81
- set_encoding(s)
82
-
83
- if s[0, 2] == Marshal.dump('')[0, 2] then
84
- true
85
- elsif file =~ /erb\.rb$/ then
86
- false
87
- elsif s.scan(/<%|%>/).length >= 4 || s.index("\x00") then
88
- true
89
- elsif 0.respond_to? :fdiv then
90
- s.count("^ -~\t\r\n").fdiv(s.size) > 0.3
91
- else # HACK 1.8.6
92
- (s.count("^ -~\t\r\n").to_f / s.size) > 0.3
81
+
82
+ have_encoding = s.respond_to? :encoding
83
+
84
+ if have_encoding then
85
+ return false if s.encoding != Encoding::ASCII_8BIT and s.valid_encoding?
86
+ end
87
+
88
+ return true if s[0, 2] == Marshal.dump('')[0, 2] or s.index("\x00")
89
+
90
+ if have_encoding then
91
+ s.force_encoding Encoding.default_external
92
+
93
+ not s.valid_encoding?
94
+ else
95
+ if 0.respond_to? :fdiv then
96
+ s.count("\x00-\x7F", "^ -~\t\r\n").fdiv(s.size) > 0.3
97
+ else # HACK 1.8.6
98
+ (s.count("\x00-\x7F", "^ -~\t\r\n").to_f / s.size) > 0.3
99
+ end
100
+ end
101
+ end
102
+
103
+ ##
104
+ # Processes common directives for CodeObjects for the C and Ruby parsers.
105
+ #
106
+ # Applies +directive+'s +value+ to +code_object+, if appropriate
107
+
108
+ def self.process_directive code_object, directive, value
109
+ case directive
110
+ when 'nodoc' then
111
+ code_object.document_self = nil # notify nodoc
112
+ code_object.document_children = value.downcase != 'all'
113
+ when 'doc' then
114
+ code_object.document_self = true
115
+ code_object.force_documentation = true
116
+ when 'yield', 'yields' then
117
+ # remove parameter &block
118
+ code_object.params.sub!(/,?\s*&\w+/, '') if code_object.params
119
+
120
+ code_object.block_params = value
121
+ when 'arg', 'args' then
122
+ code_object.params = value
93
123
  end
94
124
  end
95
125
 
@@ -154,6 +184,12 @@ class RDoc::Parser
154
184
  RDoc::Parser.parsers.unshift [regexp, self]
155
185
  end
156
186
 
187
+ ##
188
+ # Creates a new Parser storing +top_level+, +file_name+, +content+,
189
+ # +options+ and +stats+ in instance variables.
190
+ #
191
+ # Usually invoked by +super+
192
+
157
193
  def initialize(top_level, file_name, content, options, stats)
158
194
  @top_level = top_level
159
195
  @file_name = file_name
@@ -3,9 +3,9 @@ require 'rdoc/parser/ruby'
3
3
  require 'rdoc/known_classes'
4
4
 
5
5
  ##
6
- # We attempt to parse C extension files. Basically we look for
6
+ # RDoc::Parser::C attempts to parse C extension files. It looks for
7
7
  # the standard patterns that you find in extensions: <tt>rb_define_class,
8
- # rb_define_method</tt> and so on. We also try to find the corresponding
8
+ # rb_define_method</tt> and so on. It tries to find the corresponding
9
9
  # C source for the methods and extract comments, but if we fail
10
10
  # we don't worry too much.
11
11
  #
@@ -49,13 +49,26 @@ require 'rdoc/known_classes'
49
49
  #
50
50
  # The comment blocks may include special directives:
51
51
  #
52
- # [Document-class: <i>name</i>]
53
- # This comment block is documentation for the given class. Use this
54
- # when the <tt>Init_xxx</tt> method is not named after the class.
52
+ # [Document-class: +name+]
53
+ # Documentation for the named class.
55
54
  #
56
- # [Document-method: <i>name</i>]
57
- # This comment documents the named method. Use when RDoc cannot
58
- # automatically find the method from it's declaration
55
+ # [Document-module: +name+]
56
+ # Documentation for the named module.
57
+ #
58
+ # [Document-const: +name+]
59
+ # Documentation for the named +rb_define_const+.
60
+ #
61
+ # [Document-global: +name+]
62
+ # Documentation for the named +rb_define_global_const+
63
+ #
64
+ # [Document-variable: +name+]
65
+ # Documentation for the named +rb_define_variable+
66
+ #
67
+ # [Document-method: +name+]
68
+ # Documentation for the named method.
69
+ #
70
+ # [Document-attr: +name+]
71
+ # Documentation for the named attribute.
59
72
  #
60
73
  # [call-seq: <i>text up to an empty line</i>]
61
74
  # Because C source doesn't give descripive names to Ruby-level parameters,
@@ -124,6 +137,9 @@ class RDoc::Parser::C < RDoc::Parser
124
137
  @file_dir = File.dirname(@file_name)
125
138
  end
126
139
 
140
+ ##
141
+ # Scans #content for rb_define_alias
142
+
127
143
  def do_aliases
128
144
  @content.scan(/rb_define_alias\s*\(
129
145
  \s*(\w+),
@@ -145,6 +161,33 @@ class RDoc::Parser::C < RDoc::Parser
145
161
  end
146
162
  end
147
163
 
164
+ ##
165
+ # Scans #content for rb_attr and rb_define_attr
166
+
167
+ def do_attrs
168
+ @content.scan(/rb_attr\s*\(
169
+ \s*(\w+),
170
+ \s*([\w"()]+),
171
+ \s*([01]),
172
+ \s*([01]),
173
+ \s*\w+\);/xm) do |var_name, attr_name, read, write|
174
+ handle_attr var_name, attr_name, read, write
175
+ end
176
+
177
+ @content.scan(%r%rb_define_attr\(
178
+ \s*([\w\.]+),
179
+ \s*"([^"]+)",
180
+ \s*(\d+),
181
+ \s*(\d+)\s*\);
182
+ %xm) do |var_name, attr_name, read, write|
183
+ handle_attr var_name, attr_name, read, write
184
+ end
185
+ end
186
+
187
+ ##
188
+ # Scans #content for rb_define_module, rb_define_class, boot_defclass,
189
+ # rb_define_module_under, rb_define_class_under and rb_singleton_class
190
+
148
191
  def do_classes
149
192
  @content.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do
150
193
  |var_name, class_name|
@@ -191,12 +234,16 @@ class RDoc::Parser::C < RDoc::Parser
191
234
  end
192
235
  end
193
236
 
237
+ ##
238
+ # Scans #content for rb_define_variable, rb_define_readonly_variable,
239
+ # rb_define_const and rb_define_global_const
240
+
194
241
  def do_constants
195
242
  @content.scan(%r%\Wrb_define_
196
243
  ( variable |
197
244
  readonly_variable |
198
245
  const |
199
- global_const | )
246
+ global_const )
200
247
  \s*\(
201
248
  (?:\s*(\w+),)?
202
249
  \s*"(\w+)",
@@ -208,9 +255,7 @@ class RDoc::Parser::C < RDoc::Parser
208
255
  end
209
256
 
210
257
  ##
211
- # Look for includes of the form:
212
- #
213
- # rb_include_module(rb_cArray, rb_mEnumerable);
258
+ # Scans #content for rb_include_module
214
259
 
215
260
  def do_includes
216
261
  @content.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c,m|
@@ -221,6 +266,11 @@ class RDoc::Parser::C < RDoc::Parser
221
266
  end
222
267
  end
223
268
 
269
+ ##
270
+ # Scans #content for rb_define_method, rb_define_singleton_method,
271
+ # rb_define_module_function, rb_define_private_method,
272
+ # rb_define_global_function and define_filetest_function
273
+
224
274
  def do_methods
225
275
  @content.scan(%r%rb_define_
226
276
  (
@@ -234,8 +284,7 @@ class RDoc::Parser::C < RDoc::Parser
234
284
  \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
235
285
  \s*(-?\w+)\s*\)
236
286
  (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
237
- %xm) do
238
- |type, var_name, meth_name, meth_body, param_count, source_file|
287
+ %xm) do |type, var_name, meth_name, meth_body, param_count, source_file|
239
288
 
240
289
  # Ignore top-object and weird struct.c dynamic stuff
241
290
  next if var_name == "ruby_top_self"
@@ -248,18 +297,6 @@ class RDoc::Parser::C < RDoc::Parser
248
297
  source_file)
249
298
  end
250
299
 
251
- @content.scan(%r%rb_define_attr\(
252
- \s*([\w\.]+),
253
- \s*"([^"]+)",
254
- \s*(\d+),
255
- \s*(\d+)\s*\);
256
- %xm) do |var_name, attr_name, attr_reader, attr_writer|
257
- #var_name = "rb_cObject" if var_name == "rb_mKernel"
258
- handle_attr(var_name, attr_name,
259
- attr_reader.to_i != 0,
260
- attr_writer.to_i != 0)
261
- end
262
-
263
300
  @content.scan(%r%rb_define_global_function\s*\(
264
301
  \s*"([^"]+)",
265
302
  \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
@@ -280,23 +317,49 @@ class RDoc::Parser::C < RDoc::Parser
280
317
  end
281
318
  end
282
319
 
283
- def find_alias_comment(class_name, new_name, old_name)
284
- if content =~ %r%((?>/\*.*?\*/\s+))
285
- rb_define_alias\(\s*#{class_name}\s*,
286
- \s*"#{new_name}"\s*,
287
- \s*"#{old_name}"\s*\);%xm then
288
- $1
289
- else
290
- ''
291
- end
320
+ ##
321
+ # Finds the comment for an alias on +class_name+ from +new_name+ to
322
+ # +old_name+
323
+
324
+ def find_alias_comment class_name, new_name, old_name
325
+ content =~ %r%((?>/\*.*?\*/\s+))
326
+ rb_define_alias\(\s*#{Regexp.escape class_name}\s*,
327
+ \s*"#{Regexp.escape new_name}"\s*,
328
+ \s*"#{Regexp.escape old_name}"\s*\);%xm
329
+
330
+ $1 || ''
292
331
  end
293
332
 
294
- def find_attr_comment(attr_name)
333
+ ##
334
+ # Finds a comment for rb_define_attr, rb_attr or Document-attr.
335
+ #
336
+ # +var_name+ is the C class variable the attribute is defined on.
337
+ # +attr_name+ is the attribute's name.
338
+ #
339
+ # +read+ and +write+ are the read/write flags ('1' or '0'). Either both or
340
+ # neither must be provided.
341
+
342
+ def find_attr_comment var_name, attr_name, read = nil, write = nil
343
+ attr_name = Regexp.escape attr_name
344
+
345
+ rw = if read and write then
346
+ /\s*#{read}\s*,\s*#{write}\s*/xm
347
+ else
348
+ /.*?/m
349
+ end
350
+
295
351
  if @content =~ %r%((?>/\*.*?\*/\s+))
296
- rb_define_attr\((?:\s*(\w+),)?\s*
297
- "#{attr_name}"\s*,.*?\)\s*;%xmi
352
+ rb_define_attr\((?:\s*#{var_name},)?\s*
353
+ "#{attr_name}"\s*,
354
+ #{rw}\)\s*;%xm then
355
+ $1
356
+ elsif @content =~ %r%((?>/\*.*?\*/\s+))
357
+ rb_attr\(\s*#{var_name}\s*,
358
+ \s*#{attr_name}\s*,
359
+ #{rw},.*?\)\s*;%xm then
298
360
  $1
299
- elsif @content =~ %r%Document-attr:\s#{attr_name}\s*?\n((?>.*?\*/))%m
361
+ elsif @content =~ %r%Document-attr:\s#{attr_name}\s*?\n
362
+ ((?>.*?\*/))%xm then
300
363
  $1
301
364
  else
302
365
  ''
@@ -314,7 +377,6 @@ class RDoc::Parser::C < RDoc::Parser
314
377
  \s*(\([^)]*\))([^;]|$))%xm then
315
378
  comment = $1
316
379
  body_text = $2
317
- params = $3
318
380
 
319
381
  remove_private_comments comment if comment
320
382
 
@@ -353,24 +415,27 @@ class RDoc::Parser::C < RDoc::Parser
353
415
  meth_obj.comment = strip_stars(comment) + meth_obj.comment.to_s
354
416
  when %r%^\s*\#\s*define\s+#{meth_name}\s+(\w+)%m
355
417
  unless find_body(class_name, $1, meth_obj, body, true)
356
- warn "No definition for #{meth_name}" unless @options.quiet
418
+ warn "No definition for #{meth_name}" if @options.verbosity > 1
357
419
  return false
358
420
  end
359
- else
360
- # No body, but might still have an override comment
361
- comment = find_override_comment(class_name, meth_obj.name)
421
+ else # No body, but might still have an override comment
422
+ comment = find_override_comment class_name, meth_obj.name
362
423
 
363
424
  if comment
364
- find_modifiers(comment, meth_obj)
425
+ find_modifiers comment, meth_obj
365
426
  meth_obj.comment = strip_stars comment
366
427
  else
367
- warn "No definition for #{meth_name}" unless @options.quiet
428
+ warn "No definition for #{meth_name}" if @options.verbosity > 1
368
429
  return false
369
430
  end
370
431
  end
432
+
371
433
  true
372
434
  end
373
435
 
436
+ ##
437
+ # Finds a RDoc::NormalClass or RDoc::NormalModule for +raw_name+
438
+
374
439
  def find_class(raw_name, name)
375
440
  unless @classes[raw_name]
376
441
  if raw_name =~ /^rb_m/
@@ -419,7 +484,7 @@ class RDoc::Parser::C < RDoc::Parser
419
484
  (static\s+)?
420
485
  void\s+
421
486
  Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xmi then
422
- comment = $1
487
+ comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '')
423
488
  elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*?
424
489
  (?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm then
425
490
  comment = $1
@@ -456,30 +521,72 @@ class RDoc::Parser::C < RDoc::Parser
456
521
  end
457
522
 
458
523
  ##
459
- # If the comment block contains a section that looks like:
524
+ # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
460
525
  #
461
- # call-seq:
462
- # Array.new
463
- # Array.new(10)
526
+ # If <tt>:nodoc:</tt> is found, documentation on +meth_obj+ is suppressed.
464
527
  #
465
- # use it for the parameters.
528
+ # If <tt>:yields:</tt> is followed by an argument list it is used for the
529
+ # #block_params of +meth_obj+.
530
+ #
531
+ # If the comment block contains a <tt>call-seq:</tt> section like:
532
+ #
533
+ # call-seq:
534
+ # ARGF.readlines(sep=$/) -> array
535
+ # ARGF.readlines(limit) -> array
536
+ # ARGF.readlines(sep, limit) -> array
537
+ #
538
+ # ARGF.to_a(sep=$/) -> array
539
+ # ARGF.to_a(limit) -> array
540
+ # ARGF.to_a(sep, limit) -> array
541
+ #
542
+ # it is used for the parameters of +meth_obj+.
543
+
544
+ def find_modifiers comment, meth_obj
545
+ # we must handle situations like the above followed by an unindented first
546
+ # comment. The difficulty is to make sure not to match lines starting
547
+ # with ARGF at the same indent, but that are after the first description
548
+ # paragraph.
549
+
550
+ if comment =~ /call-seq:(.*?[^\s\*].*?)^\s*\*?\s*$/m then
551
+ all_start, all_stop = $~.offset(0)
552
+ seq_start, seq_stop = $~.offset(1)
553
+
554
+ # we get the following lines that start with the leading word at the
555
+ # same indent, even if they have blank lines before
556
+ if $1 =~ /(^\s*\*?\s*\n)+^(\s*\*?\s*\w+)/m then
557
+ leading = $2 # ' * ARGF' in the example above
558
+ re = %r%
559
+ \A(
560
+ (^\s*\*?\s*\n)+
561
+ (^#{Regexp.escape leading}.*?\n)+
562
+ )+
563
+ ^\s*\*?\s*$
564
+ %xm
565
+ if comment[seq_stop..-1] =~ re then
566
+ all_stop = seq_stop + $~.offset(0).last
567
+ seq_stop = seq_stop + $~.offset(1).last
568
+ end
569
+ end
466
570
 
467
- def find_modifiers(comment, meth_obj)
468
- if comment.sub!(/:nodoc:\s*^\s*\*?\s*$/m, '') or
469
- comment.sub!(/\A\/\*\s*:nodoc:\s*\*\/\Z/, '') then
470
- meth_obj.document_self = false
571
+ seq = comment[seq_start..seq_stop]
572
+ seq.gsub!(/^(\s*\*?\s*?)(\S|\n)/m, '\2')
573
+ comment.slice! all_start...all_stop
574
+ meth_obj.call_seq = seq
575
+ elsif comment.sub!(/\A\/\*\s*call-seq:(.*?)\*\/\Z/, '') then
576
+ meth_obj.call_seq = $1.strip
471
577
  end
472
578
 
473
- if comment.sub!(/call-seq:(.*?)^\s*\*?\s*$/m, '') or
474
- comment.sub!(/\A\/\*\s*call-seq:(.*?)\*\/\Z/, '') then
475
- seq = $1
476
- seq.gsub!(/^\s*\*\s*/, '')
477
- meth_obj.call_seq = seq
579
+ if comment.sub!(/\s*:(nodoc|doc|yields?|args?):\s*(.*)/, '') then
580
+ RDoc::Parser.process_directive meth_obj, $1, $2
478
581
  end
479
582
  end
480
583
 
584
+ ##
585
+ # Finds a <tt>Document-method</tt> override for +meth_name+ in +class_name+
586
+
481
587
  def find_override_comment(class_name, meth_name)
482
588
  name = Regexp.escape(meth_name)
589
+
483
590
  if @content =~ %r%Document-method:\s+#{class_name}(?:\.|::|#)#{name}\s*?\n((?>.*?\*/))%m then
484
591
  $1
485
592
  elsif @content =~ %r%Document-method:\s#{name}\s*?\n((?>.*?\*/))%m then
@@ -487,26 +594,38 @@ class RDoc::Parser::C < RDoc::Parser
487
594
  end
488
595
  end
489
596
 
490
- def handle_attr(var_name, attr_name, reader, writer)
597
+ ##
598
+ # Creates a new RDoc::Attr +attr_name+ on class +var_name+ that is either
599
+ # +read+, +write+ or both
600
+
601
+ def handle_attr(var_name, attr_name, read, write)
491
602
  rw = ''
492
- rw << 'R' if reader
493
- rw << 'W' if writer
603
+ rw << 'R' if '1' == read
604
+ rw << 'W' if '1' == write
494
605
 
495
606
  class_name = @known_classes[var_name]
496
607
 
497
608
  return unless class_name
498
609
 
499
- class_obj = find_class(var_name, class_name)
610
+ class_obj = find_class var_name, class_name
611
+
612
+ return unless class_obj
500
613
 
501
- if class_obj
502
- comment = find_attr_comment(attr_name)
503
- comment = strip_stars comment
504
- att = RDoc::Attr.new '', attr_name, rw, comment
505
- @stats.add_method att
506
- class_obj.add_attribute(att)
507
- end
614
+ comment = find_attr_comment var_name, attr_name
615
+ comment = strip_stars comment
616
+
617
+ name = attr_name.gsub(/rb_intern\("([^"]+)"\)/, '\1')
618
+
619
+ attr = RDoc::Attr.new '', name, rw, comment
620
+
621
+ class_obj.add_attribute attr
622
+ @stats.add_attribute attr
508
623
  end
509
624
 
625
+ ##
626
+ # Creates a new RDoc::NormalClass or RDoc::NormalModule based on +type+
627
+ # named +class_name+ in +parent+ which was assigned to the C +var_name+.
628
+
510
629
  def handle_class_module(var_name, type, class_name, parent, in_module)
511
630
  parent_name = @known_classes[parent] || parent
512
631
 
@@ -556,15 +675,14 @@ class RDoc::Parser::C < RDoc::Parser
556
675
  end
557
676
 
558
677
  ##
559
- # Adds constant comments. By providing some_value: at the start ofthe
560
- # comment you can override the C value of the comment to give a friendly
561
- # definition.
678
+ # Adds constants. By providing some_value: at the start of the comment you
679
+ # can override the C value of the comment to give a friendly definition.
562
680
  #
563
681
  # /* 300: The perfect score in bowling */
564
682
  # rb_define_const(cFoo, "PERFECT", INT2FIX(300);
565
683
  #
566
- # Will override +INT2FIX(300)+ with the value +300+ in the output RDoc.
567
- # Values may include quotes and escaped colons (\:).
684
+ # Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
685
+ # RDoc. Values may include quotes and escaped colons (\:).
568
686
 
569
687
  def handle_constants(type, var_name, const_name, definition)
570
688
  class_name = @known_classes[var_name]
@@ -625,6 +743,11 @@ class RDoc::Parser::C < RDoc::Parser
625
743
  body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
626
744
  end
627
745
 
746
+ ##
747
+ # Adds an RDoc::AnyMethod +meth_name+ defined on a class or module assigned
748
+ # to +var_name+. +type+ is the type of method definition function used.
749
+ # +singleton_method+ and +module_function+ create a singleton method.
750
+
628
751
  def handle_method(type, var_name, meth_name, meth_body, param_count,
629
752
  source_file = nil)
630
753
  singleton = false
@@ -640,9 +763,10 @@ class RDoc::Parser::C < RDoc::Parser
640
763
  class_obj = find_class var_name, class_name
641
764
 
642
765
  if class_obj then
643
- if meth_name == "initialize" then
644
- meth_name = "new"
766
+ if meth_name == 'initialize' then
767
+ meth_name = 'new'
645
768
  singleton = true
769
+ type = 'method' # force public
646
770
  end
647
771
 
648
772
  meth_obj = RDoc::AnyMethod.new '', meth_name
@@ -671,7 +795,8 @@ class RDoc::Parser::C < RDoc::Parser
671
795
  body = @content
672
796
  end
673
797
 
674
- if find_body(class_name, meth_body, meth_obj, body) and meth_obj.document_self then
798
+ if find_body(class_name, meth_body, meth_obj, body) and
799
+ meth_obj.document_self then
675
800
  class_obj.add_method meth_obj
676
801
  @stats.add_method meth_obj
677
802
  meth_obj.visibility = :private if 'private_method' == type
@@ -679,19 +804,27 @@ class RDoc::Parser::C < RDoc::Parser
679
804
  end
680
805
  end
681
806
 
807
+ ##
808
+ # Registers a singleton class +sclass_var+ as a singleton of +class_var+
809
+
682
810
  def handle_singleton sclass_var, class_var
683
811
  class_name = @known_classes[class_var]
684
812
 
685
813
  @singleton_classes[sclass_var] = class_name
686
814
  end
687
815
 
816
+ ##
817
+ # Normalizes tabs in +body+
818
+
688
819
  def handle_tab_width(body)
689
820
  if /\t/ =~ body
690
821
  tab_width = @options.tab_width
691
822
  body.split(/\n/).map do |line|
692
- 1 while line.gsub!(/\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)} && $~ #`
823
+ 1 while line.gsub!(/\t+/) do
824
+ ' ' * (tab_width * $&.length - $`.length % tab_width)
825
+ end && $~
693
826
  line
694
- end .join("\n")
827
+ end.join "\n"
695
828
  else
696
829
  body
697
830
  end
@@ -704,7 +837,7 @@ class RDoc::Parser::C < RDoc::Parser
704
837
  # * :title: My Awesome Project
705
838
  # */
706
839
  #
707
- # This routine modifies it's parameter
840
+ # This routine modifies its parameter
708
841
 
709
842
  def look_for_directives_in(context, comment)
710
843
  preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
@@ -715,13 +848,14 @@ class RDoc::Parser::C < RDoc::Parser
715
848
  @options.main_page = param
716
849
  ''
717
850
  when 'title' then
718
- @options.title = param
851
+ @options.default_title = param if @options.respond_to? :default_title=
719
852
  ''
720
853
  end
721
854
  end
722
855
 
723
856
  comment
724
857
  end
858
+
725
859
  ##
726
860
  # Removes lines that are commented out that might otherwise get picked up
727
861
  # when scanning for classes and methods
@@ -730,14 +864,17 @@ class RDoc::Parser::C < RDoc::Parser
730
864
  @content.gsub!(%r%//.*rb_define_%, '//')
731
865
  end
732
866
 
867
+ ##
868
+ # Removes private comments from +comment+
869
+
733
870
  def remove_private_comments(comment)
734
871
  comment.gsub!(/\/?\*--\n(.*?)\/?\*\+\+/m, '')
735
872
  comment.sub!(/\/?\*--\n.*/m, '')
736
873
  end
737
874
 
738
875
  ##
739
- # Extract the classes/modules and methods from a C file and return the
740
- # corresponding top-level object
876
+ # Extracts the classes, modules, methods, attributes, constants and aliases
877
+ # from a C file and returns an RDoc::TopLevel for this file
741
878
 
742
879
  def scan
743
880
  remove_commented_out_lines
@@ -746,6 +883,7 @@ class RDoc::Parser::C < RDoc::Parser
746
883
  do_methods
747
884
  do_includes
748
885
  do_aliases
886
+ do_attrs
749
887
  @top_level
750
888
  end
751
889