super-quick-rb 0.0.1

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 (218) hide show
  1. checksums.yaml +7 -0
  2. data/rdoc-8.0.0/CONTRIBUTING.md +195 -0
  3. data/rdoc-8.0.0/CVE-2013-0256.rdoc +49 -0
  4. data/rdoc-8.0.0/History.rdoc +1668 -0
  5. data/rdoc-8.0.0/LEGAL.rdoc +56 -0
  6. data/rdoc-8.0.0/LICENSE.rdoc +63 -0
  7. data/rdoc-8.0.0/README.md +236 -0
  8. data/rdoc-8.0.0/RI.md +842 -0
  9. data/rdoc-8.0.0/TODO.rdoc +60 -0
  10. data/rdoc-8.0.0/doc/markup_reference/markdown.md +659 -0
  11. data/rdoc-8.0.0/doc/markup_reference/rdoc.rdoc +1169 -0
  12. data/rdoc-8.0.0/exe/rdoc +43 -0
  13. data/rdoc-8.0.0/exe/ri +12 -0
  14. data/rdoc-8.0.0/lib/rdoc/code_object/alias.rb +98 -0
  15. data/rdoc-8.0.0/lib/rdoc/code_object/any_method.rb +387 -0
  16. data/rdoc-8.0.0/lib/rdoc/code_object/attr.rb +178 -0
  17. data/rdoc-8.0.0/lib/rdoc/code_object/class_module.rb +969 -0
  18. data/rdoc-8.0.0/lib/rdoc/code_object/constant.rb +221 -0
  19. data/rdoc-8.0.0/lib/rdoc/code_object/context/section.rb +182 -0
  20. data/rdoc-8.0.0/lib/rdoc/code_object/context.rb +1238 -0
  21. data/rdoc-8.0.0/lib/rdoc/code_object/extend.rb +9 -0
  22. data/rdoc-8.0.0/lib/rdoc/code_object/include.rb +9 -0
  23. data/rdoc-8.0.0/lib/rdoc/code_object/method_attr.rb +417 -0
  24. data/rdoc-8.0.0/lib/rdoc/code_object/mixin.rb +123 -0
  25. data/rdoc-8.0.0/lib/rdoc/code_object/normal_class.rb +92 -0
  26. data/rdoc-8.0.0/lib/rdoc/code_object/normal_module.rb +73 -0
  27. data/rdoc-8.0.0/lib/rdoc/code_object/require.rb +51 -0
  28. data/rdoc-8.0.0/lib/rdoc/code_object/single_class.rb +30 -0
  29. data/rdoc-8.0.0/lib/rdoc/code_object/top_level.rb +286 -0
  30. data/rdoc-8.0.0/lib/rdoc/code_object.rb +393 -0
  31. data/rdoc-8.0.0/lib/rdoc/code_objects.rb +5 -0
  32. data/rdoc-8.0.0/lib/rdoc/comment.rb +353 -0
  33. data/rdoc-8.0.0/lib/rdoc/cross_reference.rb +215 -0
  34. data/rdoc-8.0.0/lib/rdoc/encoding.rb +120 -0
  35. data/rdoc-8.0.0/lib/rdoc/erb_partial.rb +18 -0
  36. data/rdoc-8.0.0/lib/rdoc/erbio.rb +37 -0
  37. data/rdoc-8.0.0/lib/rdoc/generator/aliki.rb +200 -0
  38. data/rdoc-8.0.0/lib/rdoc/generator/darkfish.rb +824 -0
  39. data/rdoc-8.0.0/lib/rdoc/generator/json_index.rb +284 -0
  40. data/rdoc-8.0.0/lib/rdoc/generator/markup.rb +196 -0
  41. data/rdoc-8.0.0/lib/rdoc/generator/pot/message_extractor.rb +68 -0
  42. data/rdoc-8.0.0/lib/rdoc/generator/pot/po.rb +84 -0
  43. data/rdoc-8.0.0/lib/rdoc/generator/pot/po_entry.rb +141 -0
  44. data/rdoc-8.0.0/lib/rdoc/generator/pot.rb +94 -0
  45. data/rdoc-8.0.0/lib/rdoc/generator/ri.rb +30 -0
  46. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/DESIGN.md +536 -0
  47. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_aside_toc.rhtml +8 -0
  48. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_footer.rhtml +23 -0
  49. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_head.rhtml +163 -0
  50. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_header.rhtml +56 -0
  51. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_icons.rhtml +208 -0
  52. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_sidebar_ancestors.rhtml +16 -0
  53. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_sidebar_classes.rhtml +15 -0
  54. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_sidebar_extends.rhtml +27 -0
  55. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +27 -0
  56. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_sidebar_installed.rhtml +16 -0
  57. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_sidebar_methods.rhtml +41 -0
  58. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_sidebar_pages.rhtml +67 -0
  59. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +15 -0
  60. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_sidebar_sections.rhtml +21 -0
  61. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/_sidebar_toggle.rhtml +3 -0
  62. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/class.rhtml +230 -0
  63. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/css/rdoc.css +2181 -0
  64. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/index.rhtml +22 -0
  65. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/js/aliki.js +513 -0
  66. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/js/bash_highlighter.js +167 -0
  67. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/js/c_highlighter.js +299 -0
  68. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/js/search_controller.js +129 -0
  69. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/js/search_navigation.js +105 -0
  70. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/js/search_ranker.js +239 -0
  71. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/js/theme-toggle.js +112 -0
  72. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/page.rhtml +18 -0
  73. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/servlet_not_found.rhtml +14 -0
  74. data/rdoc-8.0.0/lib/rdoc/generator/template/aliki/servlet_root.rhtml +65 -0
  75. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_footer.rhtml +5 -0
  76. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_head.rhtml +43 -0
  77. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +5 -0
  78. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +17 -0
  79. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +17 -0
  80. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +16 -0
  81. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +21 -0
  82. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml +11 -0
  83. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +32 -0
  84. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +6 -0
  85. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +15 -0
  86. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +11 -0
  87. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +39 -0
  88. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml +3 -0
  89. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/class.rhtml +220 -0
  90. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/css/fonts.css +167 -0
  91. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/css/rdoc.css +701 -0
  92. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf +0 -0
  93. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf +0 -0
  94. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf +0 -0
  95. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf +0 -0
  96. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf +0 -0
  97. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf +0 -0
  98. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/add.png +0 -0
  99. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/arrow_up.png +0 -0
  100. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/brick.png +0 -0
  101. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/brick_link.png +0 -0
  102. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/bug.png +0 -0
  103. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/bullet_black.png +0 -0
  104. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png +0 -0
  105. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png +0 -0
  106. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/date.png +0 -0
  107. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/delete.png +0 -0
  108. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/find.png +0 -0
  109. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif +0 -0
  110. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png +0 -0
  111. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/package.png +0 -0
  112. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/page_green.png +0 -0
  113. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/page_white_text.png +0 -0
  114. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/page_white_width.png +0 -0
  115. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/plugin.png +0 -0
  116. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/ruby.png +0 -0
  117. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/tag_blue.png +0 -0
  118. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/tag_green.png +0 -0
  119. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/transparent.png +0 -0
  120. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/wrench.png +0 -0
  121. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/wrench_orange.png +0 -0
  122. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/images/zoom.png +0 -0
  123. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/index.rhtml +24 -0
  124. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/js/darkfish.js +140 -0
  125. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/js/search.js +120 -0
  126. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/page.rhtml +19 -0
  127. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml +21 -0
  128. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +65 -0
  129. data/rdoc-8.0.0/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +72 -0
  130. data/rdoc-8.0.0/lib/rdoc/generator/template/json_index/js/navigation.js +105 -0
  131. data/rdoc-8.0.0/lib/rdoc/generator/template/json_index/js/searcher.js +271 -0
  132. data/rdoc-8.0.0/lib/rdoc/generator.rb +52 -0
  133. data/rdoc-8.0.0/lib/rdoc/i18n/locale.rb +102 -0
  134. data/rdoc-8.0.0/lib/rdoc/i18n/text.rb +126 -0
  135. data/rdoc-8.0.0/lib/rdoc/i18n.rb +10 -0
  136. data/rdoc-8.0.0/lib/rdoc/known_classes.rb +74 -0
  137. data/rdoc-8.0.0/lib/rdoc/markdown/entities.rb +2131 -0
  138. data/rdoc-8.0.0/lib/rdoc/markdown/literals.kpeg +21 -0
  139. data/rdoc-8.0.0/lib/rdoc/markdown/literals.rb +454 -0
  140. data/rdoc-8.0.0/lib/rdoc/markdown.kpeg +1315 -0
  141. data/rdoc-8.0.0/lib/rdoc/markdown.rb +16865 -0
  142. data/rdoc-8.0.0/lib/rdoc/markup/blank_line.rb +29 -0
  143. data/rdoc-8.0.0/lib/rdoc/markup/block_quote.rb +14 -0
  144. data/rdoc-8.0.0/lib/rdoc/markup/document.rb +164 -0
  145. data/rdoc-8.0.0/lib/rdoc/markup/element.rb +21 -0
  146. data/rdoc-8.0.0/lib/rdoc/markup/formatter.rb +285 -0
  147. data/rdoc-8.0.0/lib/rdoc/markup/hard_break.rb +34 -0
  148. data/rdoc-8.0.0/lib/rdoc/markup/heading.rb +170 -0
  149. data/rdoc-8.0.0/lib/rdoc/markup/include.rb +42 -0
  150. data/rdoc-8.0.0/lib/rdoc/markup/indented_paragraph.rb +47 -0
  151. data/rdoc-8.0.0/lib/rdoc/markup/inline_parser.rb +312 -0
  152. data/rdoc-8.0.0/lib/rdoc/markup/list.rb +101 -0
  153. data/rdoc-8.0.0/lib/rdoc/markup/list_item.rb +99 -0
  154. data/rdoc-8.0.0/lib/rdoc/markup/paragraph.rb +28 -0
  155. data/rdoc-8.0.0/lib/rdoc/markup/parser.rb +585 -0
  156. data/rdoc-8.0.0/lib/rdoc/markup/pre_process.rb +317 -0
  157. data/rdoc-8.0.0/lib/rdoc/markup/raw.rb +66 -0
  158. data/rdoc-8.0.0/lib/rdoc/markup/rule.rb +20 -0
  159. data/rdoc-8.0.0/lib/rdoc/markup/table.rb +64 -0
  160. data/rdoc-8.0.0/lib/rdoc/markup/to_ansi.rb +144 -0
  161. data/rdoc-8.0.0/lib/rdoc/markup/to_bs.rb +86 -0
  162. data/rdoc-8.0.0/lib/rdoc/markup/to_html.rb +682 -0
  163. data/rdoc-8.0.0/lib/rdoc/markup/to_html_crossref.rb +261 -0
  164. data/rdoc-8.0.0/lib/rdoc/markup/to_html_snippet.rb +287 -0
  165. data/rdoc-8.0.0/lib/rdoc/markup/to_joined_paragraph.rb +41 -0
  166. data/rdoc-8.0.0/lib/rdoc/markup/to_label.rb +84 -0
  167. data/rdoc-8.0.0/lib/rdoc/markup/to_markdown.rb +215 -0
  168. data/rdoc-8.0.0/lib/rdoc/markup/to_rdoc.rb +421 -0
  169. data/rdoc-8.0.0/lib/rdoc/markup/to_table_of_contents.rb +88 -0
  170. data/rdoc-8.0.0/lib/rdoc/markup/to_test.rb +77 -0
  171. data/rdoc-8.0.0/lib/rdoc/markup/to_tt_only.rb +107 -0
  172. data/rdoc-8.0.0/lib/rdoc/markup/verbatim.rb +83 -0
  173. data/rdoc-8.0.0/lib/rdoc/markup.rb +219 -0
  174. data/rdoc-8.0.0/lib/rdoc/options.rb +1412 -0
  175. data/rdoc-8.0.0/lib/rdoc/parser/c.rb +1227 -0
  176. data/rdoc-8.0.0/lib/rdoc/parser/changelog.rb +379 -0
  177. data/rdoc-8.0.0/lib/rdoc/parser/markdown.rb +22 -0
  178. data/rdoc-8.0.0/lib/rdoc/parser/rbs.rb +275 -0
  179. data/rdoc-8.0.0/lib/rdoc/parser/rd.rb +22 -0
  180. data/rdoc-8.0.0/lib/rdoc/parser/ruby.rb +1266 -0
  181. data/rdoc-8.0.0/lib/rdoc/parser/ruby_colorizer.rb +253 -0
  182. data/rdoc-8.0.0/lib/rdoc/parser/simple.rb +44 -0
  183. data/rdoc-8.0.0/lib/rdoc/parser/text.rb +11 -0
  184. data/rdoc-8.0.0/lib/rdoc/parser.rb +298 -0
  185. data/rdoc-8.0.0/lib/rdoc/rbs_helper.rb +186 -0
  186. data/rdoc-8.0.0/lib/rdoc/rd/block_parser.rb +1706 -0
  187. data/rdoc-8.0.0/lib/rdoc/rd/block_parser.ry +643 -0
  188. data/rdoc-8.0.0/lib/rdoc/rd/inline.rb +71 -0
  189. data/rdoc-8.0.0/lib/rdoc/rd/inline_parser.rb +1854 -0
  190. data/rdoc-8.0.0/lib/rdoc/rd/inline_parser.ry +593 -0
  191. data/rdoc-8.0.0/lib/rdoc/rd.rb +99 -0
  192. data/rdoc-8.0.0/lib/rdoc/rdoc.rb +724 -0
  193. data/rdoc-8.0.0/lib/rdoc/ri/driver.rb +1572 -0
  194. data/rdoc-8.0.0/lib/rdoc/ri/formatter.rb +6 -0
  195. data/rdoc-8.0.0/lib/rdoc/ri/paths.rb +171 -0
  196. data/rdoc-8.0.0/lib/rdoc/ri/servlet.rb +452 -0
  197. data/rdoc-8.0.0/lib/rdoc/ri/store.rb +6 -0
  198. data/rdoc-8.0.0/lib/rdoc/ri/task.rb +71 -0
  199. data/rdoc-8.0.0/lib/rdoc/ri.rb +21 -0
  200. data/rdoc-8.0.0/lib/rdoc/rubygems_hook.rb +327 -0
  201. data/rdoc-8.0.0/lib/rdoc/server.rb +460 -0
  202. data/rdoc-8.0.0/lib/rdoc/stats/normal.rb +58 -0
  203. data/rdoc-8.0.0/lib/rdoc/stats/quiet.rb +59 -0
  204. data/rdoc-8.0.0/lib/rdoc/stats/verbose.rb +44 -0
  205. data/rdoc-8.0.0/lib/rdoc/stats.rb +484 -0
  206. data/rdoc-8.0.0/lib/rdoc/store.rb +1205 -0
  207. data/rdoc-8.0.0/lib/rdoc/task.rb +355 -0
  208. data/rdoc-8.0.0/lib/rdoc/text.rb +244 -0
  209. data/rdoc-8.0.0/lib/rdoc/token_stream.rb +104 -0
  210. data/rdoc-8.0.0/lib/rdoc/tom_doc.rb +257 -0
  211. data/rdoc-8.0.0/lib/rdoc/version.rb +10 -0
  212. data/rdoc-8.0.0/lib/rdoc.rb +239 -0
  213. data/rdoc-8.0.0/lib/rubygems_plugin.rb +14 -0
  214. data/rdoc-8.0.0/man/ri.1 +249 -0
  215. data/rdoc-8.0.0/rdoc-logo.svg +43 -0
  216. data/rdoc-8.0.0/rdoc.gemspec +74 -0
  217. data/super-quick-rb.gemspec +12 -0
  218. metadata +257 -0
@@ -0,0 +1,1227 @@
1
+ # frozen_string_literal: true
2
+ require 'tsort'
3
+
4
+ ##
5
+ # RDoc::Parser::C attempts to parse C extension files. It looks for
6
+ # the standard patterns that you find in extensions: +rb_define_class+,
7
+ # +rb_define_method+ and so on. It tries to find the corresponding
8
+ # C source for the methods and extract comments, but if we fail
9
+ # we don't worry too much.
10
+ #
11
+ # The comments associated with a Ruby method are extracted from the C
12
+ # comment block associated with the routine that _implements_ that
13
+ # method, that is to say the method whose name is given in the
14
+ # +rb_define_method+ call. For example, you might write:
15
+ #
16
+ # /*
17
+ # * Returns a new array that is a one-dimensional flattening of this
18
+ # * array (recursively). That is, for every element that is an array,
19
+ # * extract its elements into the new array.
20
+ # *
21
+ # * s = [ 1, 2, 3 ] #=> [1, 2, 3]
22
+ # * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
23
+ # * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
24
+ # * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
25
+ # */
26
+ # static VALUE
27
+ # rb_ary_flatten(VALUE ary)
28
+ # {
29
+ # ary = rb_obj_dup(ary);
30
+ # rb_ary_flatten_bang(ary);
31
+ # return ary;
32
+ # }
33
+ #
34
+ # ...
35
+ #
36
+ # void
37
+ # Init_Array(void)
38
+ # {
39
+ # ...
40
+ # rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0);
41
+ #
42
+ # Here RDoc will determine from the +rb_define_method+ line that there's a
43
+ # method called "flatten" in class Array, and will look for the implementation
44
+ # in the method +rb_ary_flatten+. It will then use the comment from that
45
+ # method in the HTML output. This method must be in the same source file
46
+ # as the +rb_define_method+.
47
+ #
48
+ # The comment blocks may include special directives:
49
+ #
50
+ # [Document-class: +name+]
51
+ # Documentation for the named class.
52
+ #
53
+ # [Document-module: +name+]
54
+ # Documentation for the named module.
55
+ #
56
+ # [Document-const: +name+]
57
+ # Documentation for the named +rb_define_const+.
58
+ #
59
+ # Constant values can be supplied on the first line of the comment like so:
60
+ #
61
+ # /* 300: The highest possible score in bowling */
62
+ # rb_define_const(cFoo, "PERFECT", INT2FIX(300));
63
+ #
64
+ # The value can contain internal colons so long as they are escaped with a \
65
+ #
66
+ # [Document-global: +name+]
67
+ # Documentation for the named +rb_define_global_const+
68
+ #
69
+ # [Document-variable: +name+]
70
+ # Documentation for the named +rb_define_variable+
71
+ #
72
+ # [Document-method\: +method_name+]
73
+ # Documentation for the named method. Use this when the method name is
74
+ # unambiguous.
75
+ #
76
+ # [Document-method\: <tt>ClassName::method_name</tt>]
77
+ # Documentation for a singleton method in the given class. Use this when
78
+ # the method name alone is ambiguous.
79
+ #
80
+ # [Document-method\: <tt>ClassName#method_name</tt>]
81
+ # Documentation for a instance method in the given class. Use this when the
82
+ # method name alone is ambiguous.
83
+ #
84
+ # [Document-attr: +name+]
85
+ # Documentation for the named attribute.
86
+ #
87
+ # [call-seq: <i>text up to an empty line</i>]
88
+ # Because C source doesn't give descriptive names to Ruby-level parameters,
89
+ # you need to document the calling sequence explicitly
90
+ #
91
+ # In addition, RDoc assumes by default that the C method implementing a
92
+ # Ruby function is in the same source file as the rb_define_method call.
93
+ # If this isn't the case, add the comment:
94
+ #
95
+ # rb_define_method(....); // in filename
96
+ #
97
+ # As an example, we might have an extension that defines multiple classes
98
+ # in its Init_xxx method. We could document them using
99
+ #
100
+ # /*
101
+ # * Document-class: MyClass
102
+ # *
103
+ # * Encapsulate the writing and reading of the configuration
104
+ # * file. ...
105
+ # */
106
+ #
107
+ # /*
108
+ # * Document-method: read_value
109
+ # *
110
+ # * call-seq:
111
+ # * cfg.read_value(key) -> value
112
+ # * cfg.read_value(key} { |key| } -> value
113
+ # *
114
+ # * Return the value corresponding to +key+ from the configuration.
115
+ # * In the second form, if the key isn't found, invoke the
116
+ # * block and return its value.
117
+ # */
118
+
119
+ class RDoc::Parser::C < RDoc::Parser
120
+
121
+ parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/)
122
+
123
+ include RDoc::Text
124
+
125
+ # :stopdoc:
126
+ BOOL_ARG_PATTERN = /\s*+\b([01]|Q?(?:true|false)|TRUE|FALSE)\b\s*/
127
+ TRUE_VALUES = ['1', 'TRUE', 'true', 'Qtrue'].freeze
128
+ # :startdoc:
129
+
130
+ ##
131
+ # Maps C variable names to names of Ruby classes or modules
132
+
133
+ attr_reader :classes
134
+
135
+ ##
136
+ # C file the parser is parsing
137
+
138
+ attr_accessor :content
139
+
140
+ ##
141
+ # Dependencies from a missing enclosing class to the classes in
142
+ # missing_dependencies that depend upon it.
143
+
144
+ attr_reader :enclosure_dependencies
145
+
146
+ ##
147
+ # Maps C variable names to names of Ruby classes (and singleton classes)
148
+
149
+ attr_reader :known_classes
150
+
151
+ ##
152
+ # Classes found while parsing the C file that were not yet registered due to
153
+ # a missing enclosing class. These are processed by do_missing
154
+
155
+ attr_reader :missing_dependencies
156
+
157
+ ##
158
+ # Maps C variable names to names of Ruby singleton classes
159
+
160
+ attr_reader :singleton_classes
161
+
162
+ ##
163
+ # The TopLevel items in the parsed file belong to
164
+
165
+ attr_reader :top_level
166
+
167
+ ##
168
+ # Prepares for parsing a C file. See RDoc::Parser#initialize for details on
169
+ # the arguments.
170
+
171
+ def initialize(top_level, content, options, stats)
172
+ super
173
+
174
+ @known_classes = RDoc::KNOWN_CLASSES.dup
175
+ @content = handle_tab_width handle_ifdefs_in @content
176
+ @file_dir = File.dirname @file_name
177
+
178
+ @classes = load_variable_map :c_class_variables
179
+ @singleton_classes = load_variable_map :c_singleton_class_variables
180
+
181
+ @markup = @options.markup
182
+
183
+ # class_variable => { function => [method, ...] }
184
+ @methods = Hash.new { |h, f| h[f] = Hash.new { |i, m| i[m] = [] } }
185
+
186
+ # missing variable => [handle_class_module arguments]
187
+ @missing_dependencies = {}
188
+
189
+ # missing enclosure variable => [dependent handle_class_module arguments]
190
+ @enclosure_dependencies = Hash.new { |h, k| h[k] = [] }
191
+ @enclosure_dependencies.instance_variable_set :@missing_dependencies,
192
+ @missing_dependencies
193
+
194
+ @enclosure_dependencies.extend TSort
195
+
196
+ def @enclosure_dependencies.tsort_each_node(&block)
197
+ each_key(&block)
198
+ rescue TSort::Cyclic => e
199
+ cycle_vars = e.message.scan(/"(.*?)"/).flatten
200
+
201
+ cycle = cycle_vars.sort.map do |var_name|
202
+ delete var_name
203
+
204
+ var_name, type, mod_name, = @missing_dependencies[var_name]
205
+
206
+ "#{type} #{mod_name} (#{var_name})"
207
+ end.join ', '
208
+
209
+ warn "Unable to create #{cycle} due to a cyclic class or module creation"
210
+
211
+ retry
212
+ end
213
+
214
+ def @enclosure_dependencies.tsort_each_child(node, &block)
215
+ fetch(node, []).each(&block)
216
+ end
217
+ end
218
+
219
+ ##
220
+ # Scans #content for rb_define_alias
221
+
222
+ def do_aliases
223
+ @content.scan(/rb_define_alias\s*\(
224
+ \s*(\w+),
225
+ \s*"(.+?)",
226
+ \s*"(.+?)"
227
+ \s*\)/xm) do |var_name, new_name, old_name|
228
+ class_name = @known_classes[var_name]
229
+
230
+ unless class_name then
231
+ @options.warn "Enclosing class or module %p for alias %s %s is not known" % [
232
+ var_name, new_name, old_name]
233
+ next
234
+ end
235
+
236
+ class_obj = find_class var_name, class_name
237
+ comment = find_alias_comment var_name, new_name, old_name
238
+ comment.normalize
239
+ if comment.to_s.empty? and existing_method = class_obj.method_list.find { |m| m.name == old_name}
240
+ comment = existing_method.comment
241
+ end
242
+ add_alias(var_name, class_obj, old_name, new_name, comment)
243
+ end
244
+ end
245
+
246
+ ##
247
+ # Add alias, either from a direct alias definition, or from two
248
+ # method that reference the same function.
249
+
250
+ def add_alias(var_name, class_obj, old_name, new_name, comment)
251
+ al = RDoc::Alias.new old_name, new_name, comment, singleton: @singleton_classes.key?(var_name)
252
+ al.record_location @top_level
253
+ class_obj.add_alias al
254
+ @stats.add_alias al
255
+ al
256
+ end
257
+
258
+ ##
259
+ # Scans #content for rb_attr and rb_define_attr
260
+
261
+ def do_attrs
262
+ @content.scan(/rb_attr\s*\(
263
+ \s*(\w+),
264
+ \s*([\w"()]+),
265
+ #{BOOL_ARG_PATTERN},
266
+ #{BOOL_ARG_PATTERN},
267
+ \s*\w+\);/xmo) do |var_name, attr_name, read, write|
268
+ handle_attr var_name, attr_name, read, write
269
+ end
270
+
271
+ @content.scan(%r%rb_define_attr\(
272
+ \s*([\w\.]+),
273
+ \s*"([^"]+)",
274
+ #{BOOL_ARG_PATTERN},
275
+ #{BOOL_ARG_PATTERN}\);
276
+ %xmo) do |var_name, attr_name, read, write|
277
+ handle_attr var_name, attr_name, read, write
278
+ end
279
+ end
280
+
281
+ ##
282
+ # Scans #content for boot_defclass
283
+
284
+ def do_boot_defclass
285
+ @content.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do
286
+ |var_name, class_name, parent|
287
+ parent = nil if parent == "0"
288
+ handle_class_module(var_name, :class, class_name, parent, nil)
289
+ end
290
+ end
291
+
292
+ ##
293
+ # Scans #content for rb_define_class, boot_defclass, rb_define_class_under
294
+ # and rb_singleton_class
295
+
296
+ def do_classes_and_modules
297
+ do_boot_defclass if @file_name == "class.c"
298
+
299
+ @content.scan(
300
+ %r(
301
+ (?<open>\s*\(\s*) {0}
302
+ (?<close>\s*\)\s*) {0}
303
+ (?<name>\s*"(?<class_name>\w+)") {0}
304
+ (?<parent>\s*(?:
305
+ (?<parent_name>[\w\*\s\(\)\.\->]+) |
306
+ rb_path2class\s*\(\s*"(?<path>[\w:]+)"\s*\)
307
+ )) {0}
308
+ (?<under>\w+) {0}
309
+
310
+ (?<var_name>[\w\.]+)\s* =
311
+ \s*rb_(?:
312
+ define_(?:
313
+ class(?: # rb_define_class(name, parent_name)
314
+ \(\s*
315
+ \g<name>,
316
+ \g<parent>
317
+ \s*\)
318
+ |
319
+ _under\g<open> # rb_define_class_under(under, name, parent_name...)
320
+ \g<under>,
321
+ \g<name>,
322
+ \g<parent>
323
+ \g<close>
324
+ )
325
+ |
326
+ (?<module>)
327
+ module(?: # rb_define_module(name)
328
+ \g<open>
329
+ \g<name>
330
+ \g<close>
331
+ |
332
+ _under\g<open> # rb_define_module_under(under, name)
333
+ \g<under>,
334
+ \g<name>
335
+ \g<close>
336
+ )
337
+ )
338
+ |
339
+ (?<attributes>(?:\s*"\w+",)*\s*NULL\s*) {0}
340
+ struct_define(?:
341
+ \g<open> # rb_struct_define(name, ...)
342
+ \g<name>,
343
+ |
344
+ _under\g<open> # rb_struct_define_under(under, name, ...)
345
+ \g<under>,
346
+ \g<name>,
347
+ |
348
+ _without_accessor(?:
349
+ \g<open> # rb_struct_define_without_accessor(name, parent_name, ...)
350
+ |
351
+ _under\g<open> # rb_struct_define_without_accessor_under(under, name, parent_name, ...)
352
+ \g<under>,
353
+ )
354
+ \g<name>,
355
+ \g<parent>,
356
+ \s*\w+, # Allocation function
357
+ )
358
+ \g<attributes>
359
+ \g<close>
360
+ |
361
+ singleton_class\g<open> # rb_singleton_class(target_class_name)
362
+ (?<target_class_name>\w+)
363
+ \g<close>
364
+ )
365
+ )mx
366
+ ) do
367
+ if target_class_name = $~[:target_class_name]
368
+ # rb_singleton_class(target_class_name)
369
+ handle_singleton $~[:var_name], target_class_name
370
+ next
371
+ end
372
+
373
+ var_name = $~[:var_name]
374
+ type = $~[:module] ? :module : :class
375
+ class_name = $~[:class_name]
376
+ parent_name = $~[:parent_name] || $~[:path]
377
+ under = $~[:under]
378
+ attributes = $~[:attributes]
379
+
380
+ handle_class_module(var_name, type, class_name, parent_name, under)
381
+ if attributes and !parent_name # rb_struct_define *not* without_accessor
382
+ true_flag = 'Qtrue'
383
+ attributes.scan(/"\K\w+(?=")/) do |attr_name|
384
+ handle_attr var_name, attr_name, true_flag, true_flag
385
+ end
386
+ end
387
+ end
388
+ end
389
+
390
+ ##
391
+ # Scans #content for rb_define_variable, rb_define_readonly_variable,
392
+ # rb_define_const and rb_define_global_const
393
+
394
+ def do_constants
395
+ @content.scan(%r%\Wrb_define_
396
+ ( variable |
397
+ readonly_variable |
398
+ const |
399
+ global_const )
400
+ \s*\(
401
+ (?:\s*(\w+),)?
402
+ \s*"(\w+)",
403
+ \s*(.*?)\s*\)\s*;
404
+ %xm) do |type, var_name, const_name, definition|
405
+ var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel"
406
+ type = "const" if type == "global_const"
407
+ handle_constants type, var_name, const_name, definition
408
+ end
409
+
410
+ @content.scan(%r%
411
+ \Wrb_curses_define_const
412
+ \s*\(
413
+ \s*
414
+ (\w+)
415
+ \s*
416
+ \)
417
+ \s*;%xm) do |consts|
418
+ const = consts.first
419
+
420
+ handle_constants 'const', 'mCurses', const, "UINT2NUM(#{const})"
421
+ end
422
+
423
+ @content.scan(%r%
424
+ \Wrb_file_const
425
+ \s*\(
426
+ \s*
427
+ "([^"]+)",
428
+ \s*
429
+ (.*?)
430
+ \s*
431
+ \)
432
+ \s*;%xm) do |name, value|
433
+ handle_constants 'const', 'rb_mFConst', name, value
434
+ end
435
+ end
436
+
437
+
438
+ ##
439
+ # Scans #content for rb_include_module
440
+
441
+ def do_includes
442
+ @content.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c, m|
443
+ next unless cls = @classes[c]
444
+ m = @known_classes[m] || m
445
+
446
+ comment = new_comment '', @top_level, :c
447
+ incl = cls.add_include RDoc::Include.new(m, comment)
448
+ incl.record_location @top_level
449
+ end
450
+ end
451
+
452
+ ##
453
+ # Scans #content for rb_define_method, rb_define_singleton_method,
454
+ # rb_define_module_function, rb_define_private_method,
455
+ # rb_define_global_function and define_filetest_function
456
+
457
+ def do_methods
458
+ @content.scan(%r%rb_define_
459
+ (
460
+ singleton_method |
461
+ method |
462
+ module_function |
463
+ private_method
464
+ )
465
+ \s*\(\s*([\w\.]+),
466
+ \s*"([^"]+)",
467
+ \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\(|\(METHOD\))?(\w+)\)?,
468
+ \s*(-?\w+)\s*\)
469
+ (?:;\s*/[*/]\s+in\s+(\w+?\.(?:cpp|c|y)))?
470
+ %xm) do |type, var_name, meth_name, function, param_count, source_file|
471
+
472
+ # Ignore top-object and weird struct.c dynamic stuff
473
+ next if var_name == "ruby_top_self"
474
+ next if var_name == "nstr"
475
+
476
+ var_name = "rb_cObject" if var_name == "rb_mKernel"
477
+ handle_method(type, var_name, meth_name, function, param_count,
478
+ source_file)
479
+ end
480
+
481
+ @content.scan(%r%rb_define_global_function\s*\(
482
+ \s*"([^"]+)",
483
+ \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
484
+ \s*(-?\w+)\s*\)
485
+ (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
486
+ %xm) do |meth_name, function, param_count, source_file|
487
+ handle_method("method", "rb_mKernel", meth_name, function, param_count,
488
+ source_file)
489
+ end
490
+
491
+ @content.scan(/define_filetest_function\s*\(
492
+ \s*"([^"]+)",
493
+ \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
494
+ \s*(-?\w+)\s*\)/xm) do |meth_name, function, param_count|
495
+
496
+ handle_method("method", "rb_mFileTest", meth_name, function, param_count)
497
+ handle_method("singleton_method", "rb_cFile", meth_name, function,
498
+ param_count)
499
+ end
500
+ end
501
+
502
+ ##
503
+ # Creates classes and module that were missing were defined due to the file
504
+ # order being different than the declaration order.
505
+
506
+ def do_missing
507
+ return if @missing_dependencies.empty?
508
+
509
+ @enclosure_dependencies.tsort.each do |in_module|
510
+ arguments = @missing_dependencies.delete in_module
511
+
512
+ next unless arguments # dependency on existing class
513
+
514
+ handle_class_module(*arguments)
515
+ end
516
+ end
517
+
518
+ ##
519
+ # Finds the comment for an alias on +class_name+ from +new_name+ to
520
+ # +old_name+
521
+
522
+ def find_alias_comment(class_name, new_name, old_name)
523
+ content =~ %r%((?>/\*.*?\*/\s+))
524
+ rb_define_alias\(\s*#{Regexp.escape class_name}\s*,
525
+ \s*"#{Regexp.escape new_name}"\s*,
526
+ \s*"#{Regexp.escape old_name}"\s*\);%xm
527
+
528
+ new_comment($1 || '', @top_level, :c)
529
+ end
530
+
531
+ ##
532
+ # Finds a comment for rb_define_attr, rb_attr or Document-attr.
533
+ #
534
+ # +var_name+ is the C class variable the attribute is defined on.
535
+ # +attr_name+ is the attribute's name.
536
+ #
537
+ # +read+ and +write+ are the read/write flags ('1' or '0'). Either both or
538
+ # neither must be provided.
539
+
540
+ def find_attr_comment(var_name, attr_name, read = nil, write = nil)
541
+ attr_name = Regexp.escape attr_name
542
+
543
+ rw = if read and write then
544
+ /\s*#{read}\s*,\s*#{write}\s*/xm
545
+ else
546
+ /.*?/m
547
+ end
548
+
549
+ comment = if @content =~ %r%((?>/\*.*?\*/\s+))
550
+ rb_define_attr\((?:\s*#{var_name},)?\s*
551
+ "#{attr_name}"\s*,
552
+ #{rw}\)\s*;%xm then
553
+ $1
554
+ elsif @content =~ %r%((?>/\*.*?\*/\s+))
555
+ rb_attr\(\s*#{var_name}\s*,
556
+ \s*#{attr_name}\s*,
557
+ #{rw},.*?\)\s*;%xm then
558
+ $1
559
+ elsif @content =~ %r%(/\*.*?(?:\s*\*\s*)?)
560
+ Document-attr:\s#{attr_name}\s*?\n
561
+ ((?>(.|\n)*?\*/))%x then
562
+ "#{$1}\n#{$2}"
563
+ else
564
+ ''
565
+ end
566
+
567
+ new_comment comment, @top_level, :c
568
+ end
569
+
570
+ ##
571
+ # Generate a Ruby-method table
572
+
573
+ def gen_body_table(file_content)
574
+ table = {}
575
+ file_content.scan(%r{
576
+ ((?>/\*.*?\*/\s*)?)
577
+ ((?:\w+\s+){0,2} VALUE\s+(\w+)
578
+ \s*(?:\([^\)]*\))(?:[^\);]|$))
579
+ | ((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+(\w+)\s+(\w+))
580
+ | ^\s*\#\s*define\s+(\w+)\s+(\w+)
581
+ }xm) do
582
+ case
583
+ when name = $3
584
+ table[name] = [:func_def, $1, $2, $~.offset(2)] if !(t = table[name]) || t[0] != :func_def
585
+ when name = $6
586
+ table[name] = [:macro_def, $4, $5, $~.offset(5), $7] if !(t = table[name]) || t[0] == :macro_alias
587
+ when name = $8
588
+ table[name] ||= [:macro_alias, $9]
589
+ end
590
+ end
591
+ table
592
+ end
593
+
594
+ ##
595
+ # Find the C code corresponding to a Ruby method
596
+
597
+ def find_body(class_name, meth_name, meth_obj, file_content, quiet = false)
598
+ if file_content
599
+ @body_table ||= {}
600
+ @body_table[file_content] ||= gen_body_table file_content
601
+ type, *args = @body_table[file_content][meth_name]
602
+ end
603
+
604
+ case type
605
+ when :func_def
606
+ comment = new_comment args[0], @top_level, :c
607
+ body = args[1]
608
+ offset, = args[2]
609
+
610
+ # try to find the whole body
611
+ body = $& if /#{Regexp.escape body}[^(]*?\{.*?^\}/m =~ file_content
612
+
613
+ # The comment block may have been overridden with a 'Document-method'
614
+ # block. This happens in the interpreter when multiple methods are
615
+ # vectored through to the same C method but those methods are logically
616
+ # distinct (for example Kernel.hash and Kernel.object_id share the same
617
+ # implementation
618
+
619
+ override_comment = find_override_comment class_name, meth_obj
620
+ comment = override_comment if override_comment
621
+
622
+ find_modifiers comment, meth_obj if comment
623
+
624
+ #meth_obj.params = params
625
+ meth_obj.start_collecting_tokens(:c)
626
+ tk = { :line_no => 1, :char_no => 1, :text => body }
627
+ meth_obj.add_token tk
628
+ meth_obj.comment = comment
629
+ meth_obj.line = file_content[0, offset].count("\n") + 1
630
+
631
+ body
632
+ when :macro_def
633
+ comment = new_comment args[0], @top_level, :c
634
+ body = args[1]
635
+ offset, = args[2]
636
+
637
+ find_body class_name, args[3], meth_obj, file_content, true
638
+
639
+ find_modifiers comment, meth_obj
640
+
641
+ meth_obj.start_collecting_tokens(:c)
642
+ tk = { :line_no => 1, :char_no => 1, :text => body }
643
+ meth_obj.add_token tk
644
+ meth_obj.comment = comment
645
+ meth_obj.line = file_content[0, offset].count("\n") + 1
646
+
647
+ body
648
+ when :macro_alias
649
+ # with no comment we hope the aliased definition has it and use it's
650
+ # definition
651
+
652
+ body = find_body(class_name, args[0], meth_obj, file_content, true)
653
+
654
+ return body if body
655
+
656
+ @options.warn "No definition for #{meth_name}"
657
+ false
658
+ else # No body, but might still have an override comment
659
+ comment = find_override_comment class_name, meth_obj
660
+
661
+ if comment then
662
+ find_modifiers comment, meth_obj
663
+ meth_obj.comment = comment
664
+
665
+ ''
666
+ else
667
+ @options.warn "No definition for #{meth_name}"
668
+ false
669
+ end
670
+ end
671
+ end
672
+
673
+ ##
674
+ # Finds a RDoc::NormalClass or RDoc::NormalModule for +raw_name+
675
+
676
+ def find_class(raw_name, name, base_name = nil)
677
+ unless @classes[raw_name]
678
+ if raw_name =~ /^rb_m/
679
+ container = @top_level.add_module RDoc::NormalModule, name
680
+ else
681
+ container = @top_level.add_class RDoc::NormalClass, name
682
+ end
683
+ container.name = base_name if base_name
684
+
685
+ container.record_location @top_level
686
+ @top_level.add_to_classes_or_modules container
687
+ @classes[raw_name] = container
688
+ end
689
+ @classes[raw_name]
690
+ end
691
+
692
+ ##
693
+ # Look for class or module documentation above Init_+class_name+(void),
694
+ # in a Document-class +class_name+ (or module) comment or above an
695
+ # rb_define_class (or module). If a comment is supplied above a matching
696
+ # Init_ and a rb_define_class the Init_ comment is used.
697
+ #
698
+ # /*
699
+ # * This is a comment for Foo
700
+ # */
701
+ # Init_Foo(void) {
702
+ # VALUE cFoo = rb_define_class("Foo", rb_cObject);
703
+ # }
704
+ #
705
+ # /*
706
+ # * Document-class: Foo
707
+ # * This is a comment for Foo
708
+ # */
709
+ # Init_foo(void) {
710
+ # VALUE cFoo = rb_define_class("Foo", rb_cObject);
711
+ # }
712
+ #
713
+ # /*
714
+ # * This is a comment for Foo
715
+ # */
716
+ # VALUE cFoo = rb_define_class("Foo", rb_cObject);
717
+
718
+ def find_class_comment(class_name, class_mod)
719
+ comment = nil
720
+
721
+ if @content =~ %r%
722
+ ((?>/\*.*?\*/\s+))
723
+ (static\s+)?
724
+ void\s+
725
+ Init(?:VM)?_(?i:#{class_name})\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xm then
726
+ comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '')
727
+ elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*?
728
+ (?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm then
729
+ comment = "/*\n#{$1}"
730
+ elsif @content =~ %r%((?>/\*.*?\*/\s+))
731
+ ([\w\.\s]+\s* = \s+)?rb_define_(class|module)[\t (]*?"(#{class_name})"%xm then
732
+ comment = $1
733
+ elsif @content =~ %r%((?>/\*.*?\*/\s+))
734
+ ([\w\. \t]+ = \s+)?rb_define_(class|module)_under[\t\w, (]*?"(#{class_name.split('::').last})"%xm then
735
+ comment = $1
736
+ else
737
+ comment = ''
738
+ end
739
+
740
+ comment = new_comment comment, @top_level, :c
741
+
742
+ look_for_directives_in class_mod, comment
743
+
744
+ class_mod.add_comment comment, @top_level
745
+ end
746
+
747
+ ##
748
+ # Generate a const table
749
+
750
+ def gen_const_table(file_content)
751
+ table = {}
752
+ @content.scan(%r{
753
+ (?<doc>(?>^\s*/\*.*?\*/\s+))
754
+ rb_define_(?<type>\w+)\(\s*(?:\w+),\s*
755
+ "(?<name>\w+)"\s*,
756
+ .*?\)\s*;
757
+ | (?<doc>(?>^\s*/\*.*?\*/\s+))
758
+ rb_define_global_(?<type>const)\(\s*
759
+ "(?<name>\w+)"\s*,
760
+ .*?\)\s*;
761
+ | (?<doc>(?>^\s*/\*.*?\*/\s+))
762
+ rb_file_(?<type>const)\(\s*
763
+ "(?<name>\w+)"\s*,
764
+ .*?\)\s*;
765
+ | (?<doc>(?>^\s*/\*.*?\*/\s+))
766
+ rb_curses_define_(?<type>const)\(\s*
767
+ (?<name>\w+)
768
+ \s*\)\s*;
769
+ | Document-(?:const|global|variable):\s
770
+ (?<name>(?:\w+::)*\w+)
771
+ \s*?\n(?<doc>(?>.*?\*/))
772
+ }mxi) do
773
+ name, doc, type = $~.values_at(:name, :doc, :type)
774
+ if type
775
+ table[[type, name]] = doc
776
+ else
777
+ table[name] = "/*\n" + doc
778
+ end
779
+ end
780
+ table
781
+ end
782
+
783
+ ##
784
+ # Finds a comment matching +type+ and +const_name+ either above the
785
+ # comment or in the matching Document- section.
786
+
787
+ def find_const_comment(type, const_name, class_name = nil)
788
+ @const_table ||= {}
789
+ @const_table[@content] ||= gen_const_table @content
790
+ table = @const_table[@content]
791
+
792
+ comment =
793
+ table[[type, const_name]] ||
794
+ (class_name && table[class_name + "::" + const_name]) ||
795
+ table[const_name] ||
796
+ ''
797
+
798
+ new_comment comment, @top_level, :c
799
+ end
800
+
801
+ ##
802
+ # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
803
+
804
+ def find_modifiers(comment, meth_obj)
805
+ look_for_directives_in meth_obj, comment
806
+ end
807
+
808
+ ##
809
+ # Finds a <tt>Document-method</tt> override for +meth_obj+ on +class_name+
810
+
811
+ def find_override_comment(class_name, meth_obj)
812
+ name = Regexp.escape meth_obj.name
813
+ prefix = Regexp.escape meth_obj.name_prefix
814
+
815
+ comment = if @content =~ %r%Document-method:
816
+ \s+#{class_name}#{prefix}#{name}
817
+ \s*?\n((?>.*?\*/))%xm then
818
+ "/*\n#{$1}"
819
+ elsif @content =~ %r%Document-method:
820
+ \s#{name}\s*?\n((?>.*?\*/))%xm then
821
+ "/*\n#{$1}"
822
+ end
823
+
824
+ return unless comment
825
+
826
+ new_comment comment, @top_level, :c
827
+ end
828
+
829
+ ##
830
+ # Creates a new RDoc::Attr +attr_name+ on class +var_name+ that is either
831
+ # +read+, +write+ or both
832
+
833
+ def handle_attr(var_name, attr_name, read, write)
834
+ rw = ''
835
+ rw += 'R' if TRUE_VALUES.include?(read)
836
+ rw += 'W' if TRUE_VALUES.include?(write)
837
+
838
+ class_name = @known_classes[var_name]
839
+
840
+ return unless class_name
841
+
842
+ class_obj = find_class var_name, class_name
843
+
844
+ return unless class_obj
845
+
846
+ comment = find_attr_comment var_name, attr_name
847
+ comment.normalize
848
+
849
+ name = attr_name.gsub(/rb_intern(?:_const)?\("([^"]+)"\)/, '\1')
850
+
851
+ attr = RDoc::Attr.new name, rw, comment
852
+
853
+ attr.record_location @top_level
854
+ class_obj.add_attribute attr
855
+ @stats.add_attribute attr
856
+ end
857
+
858
+ ##
859
+ # Creates a new RDoc::NormalClass or RDoc::NormalModule based on +type+
860
+ # named +class_name+ in +parent+ which was assigned to the C +var_name+.
861
+
862
+ def handle_class_module(var_name, type, class_name, parent, in_module)
863
+ parent_name = @known_classes[parent] || parent
864
+
865
+ if in_module then
866
+ enclosure = @classes[in_module] || @store.find_c_enclosure(in_module)
867
+
868
+ if enclosure.nil? and enclosure = @known_classes[in_module] then
869
+ enc_type = /^rb_m/ =~ in_module ? :module : :class
870
+ handle_class_module in_module, enc_type, enclosure, nil, nil
871
+ enclosure = @classes[in_module]
872
+ end
873
+
874
+ unless enclosure then
875
+ @enclosure_dependencies[in_module] << var_name
876
+ @missing_dependencies[var_name] =
877
+ [var_name, type, class_name, parent, in_module]
878
+
879
+ return
880
+ end
881
+ else
882
+ enclosure = @top_level
883
+ end
884
+
885
+ if type == :class then
886
+ full_name = if RDoc::ClassModule === enclosure then
887
+ enclosure.full_name + "::#{class_name}"
888
+ else
889
+ class_name
890
+ end
891
+
892
+ if @content =~ %r%Document-class:\s+#{full_name}\s*<\s+([:,\w]+)% then
893
+ parent_name = $1
894
+ end
895
+
896
+ cm = enclosure.add_class RDoc::NormalClass, class_name, parent_name
897
+ else
898
+ cm = enclosure.add_module RDoc::NormalModule, class_name
899
+ end
900
+
901
+ cm.record_location enclosure.top_level
902
+ enclosure.top_level.add_to_classes_or_modules cm
903
+
904
+ find_class_comment cm.full_name, cm
905
+
906
+ case cm
907
+ when RDoc::NormalClass
908
+ @stats.add_class cm
909
+ when RDoc::NormalModule
910
+ @stats.add_module cm
911
+ end
912
+
913
+ @classes[var_name] = cm
914
+ @known_classes[var_name] = cm.full_name
915
+ @store.add_c_enclosure var_name, cm
916
+ end
917
+
918
+ ##
919
+ # Adds constants. By providing some_value: at the start of the comment you
920
+ # can override the C value of the comment to give a friendly definition.
921
+ #
922
+ # /* 300: The perfect score in bowling */
923
+ # rb_define_const(cFoo, "PERFECT", INT2FIX(300));
924
+ #
925
+ # Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
926
+ # RDoc. Values may include quotes and escaped colons (\:).
927
+
928
+ def handle_constants(type, var_name, const_name, definition)
929
+ class_name = @known_classes[var_name]
930
+
931
+ return unless class_name
932
+
933
+ class_obj = find_class var_name, class_name, class_name[/::\K[^:]+\z/]
934
+
935
+ unless class_obj then
936
+ @options.warn 'Enclosing class or module %p is not known' % [const_name]
937
+ return
938
+ end
939
+
940
+ comment = find_const_comment type, const_name, class_name
941
+ comment.normalize
942
+
943
+ # In the case of rb_define_const, the definition and comment are in
944
+ # "/* definition: comment */" form. The literal ':' and '\' characters
945
+ # can be escaped with a backslash.
946
+ if type.downcase == 'const' then
947
+ if /\A(.+?)?:(?!\S)/ =~ comment.text
948
+ new_definition, new_comment = $1, $'
949
+
950
+ if !new_definition # Default to literal C definition
951
+ new_definition = definition
952
+ else
953
+ new_definition = new_definition.gsub(/\\([\\:])/, '\1')
954
+ end
955
+
956
+ new_definition.sub!(/\A(\s+)/, '')
957
+
958
+ new_comment = "#{$1}#{new_comment.lstrip}"
959
+
960
+ new_comment = self.new_comment(new_comment, @top_level, :c)
961
+
962
+ con = RDoc::Constant.new const_name, new_definition, new_comment
963
+ else
964
+ con = RDoc::Constant.new const_name, definition, comment
965
+ end
966
+ else
967
+ con = RDoc::Constant.new const_name, definition, comment
968
+ end
969
+
970
+ con.record_location @top_level
971
+ @stats.add_constant con
972
+ class_obj.add_constant con
973
+ end
974
+
975
+ ##
976
+ # Removes #ifdefs that would otherwise confuse us
977
+
978
+ def handle_ifdefs_in(body)
979
+ body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
980
+ end
981
+
982
+ ##
983
+ # Adds an RDoc::AnyMethod +meth_name+ defined on a class or module assigned
984
+ # to +var_name+. +type+ is the type of method definition function used.
985
+ # +singleton_method+ and +module_function+ create a singleton method.
986
+
987
+ def handle_method(type, var_name, meth_name, function, param_count,
988
+ source_file = nil)
989
+ class_name = @known_classes[var_name]
990
+ singleton = @singleton_classes.key? var_name
991
+
992
+ @methods[var_name][function] << meth_name
993
+
994
+ return unless class_name
995
+
996
+ class_obj = find_class var_name, class_name
997
+
998
+ if existing_method = class_obj.method_list.find { |m| m.c_function == function }
999
+ add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment)
1000
+ end
1001
+
1002
+ if class_obj then
1003
+ if meth_name == 'initialize' then
1004
+ meth_name = 'new'
1005
+ singleton = true
1006
+ type = 'method' # force public
1007
+ end
1008
+
1009
+ singleton = singleton || %w[singleton_method module_function].include?(type)
1010
+ meth_obj = RDoc::AnyMethod.new meth_name, singleton: singleton
1011
+ meth_obj.c_function = function
1012
+
1013
+ p_count = Integer(param_count) rescue -1
1014
+
1015
+ if source_file then
1016
+ file_name = File.join @file_dir, source_file
1017
+
1018
+ if File.exist? file_name then
1019
+ file_content = RDoc::Encoding.read_file file_name, @options.encoding
1020
+ else
1021
+ @options.warn "unknown source #{source_file} for #{meth_name} in #{@file_name}"
1022
+ end
1023
+ else
1024
+ file_content = @content
1025
+ end
1026
+
1027
+ body = find_body class_name, function, meth_obj, file_content
1028
+
1029
+ if body and meth_obj.document_self then
1030
+ meth_obj.params = if p_count < -1 then # -2 is Array
1031
+ '(*args)'
1032
+ elsif p_count == -1 then # argc, argv
1033
+ rb_scan_args body
1034
+ else
1035
+ args = (1..p_count).map { |i| "p#{i}" }
1036
+ "(#{args.join ', '})"
1037
+ end
1038
+
1039
+
1040
+ meth_obj.record_location @top_level
1041
+
1042
+ if meth_obj.section_title
1043
+ class_obj.temporary_section = class_obj.add_section(meth_obj.section_title)
1044
+ end
1045
+ class_obj.add_method meth_obj
1046
+
1047
+ @stats.add_method meth_obj
1048
+ meth_obj.visibility = :private if 'private_method' == type
1049
+ end
1050
+ end
1051
+ end
1052
+
1053
+ ##
1054
+ # Registers a singleton class +sclass_var+ as a singleton of +class_var+
1055
+
1056
+ def handle_singleton(sclass_var, class_var)
1057
+ if (klass = @classes[class_var])
1058
+ @classes[sclass_var] = klass
1059
+ end
1060
+ if (class_name = @known_classes[class_var])
1061
+ @known_classes[sclass_var] = class_name
1062
+ @singleton_classes[sclass_var] = class_name
1063
+ end
1064
+ end
1065
+
1066
+ ##
1067
+ # Loads the variable map with the given +name+ from the RDoc::Store, if
1068
+ # present.
1069
+
1070
+ def load_variable_map(map_name)
1071
+ return {} unless files = @store.cache[map_name]
1072
+ return {} unless name_map = files[@file_name]
1073
+
1074
+ class_map = {}
1075
+
1076
+ name_map.each do |variable, name|
1077
+ next unless mod = @store.find_class_or_module(name)
1078
+
1079
+ class_map[variable] = if map_name == :c_class_variables then
1080
+ mod
1081
+ else
1082
+ name
1083
+ end
1084
+ @known_classes[variable] = name
1085
+ end
1086
+
1087
+ class_map
1088
+ end
1089
+
1090
+ ##
1091
+ # Look for directives in a normal comment block:
1092
+ #
1093
+ # /*
1094
+ # * :nodoc:
1095
+ # */
1096
+ #
1097
+ # This method modifies the +comment+
1098
+
1099
+ def look_for_directives_in(context, comment)
1100
+ comment.text, format = @preprocess.run_pre_processes(comment.text, context, comment.line || 1, :c)
1101
+ comment.format = format if format
1102
+ @preprocess.run_post_processes(comment, context)
1103
+ comment.normalized = true
1104
+ comment
1105
+ end
1106
+
1107
+ ##
1108
+ # Extracts parameters from the +method_body+ and returns a method
1109
+ # parameter string. Follows 1.9.3dev's scan-arg-spec, see README.EXT
1110
+
1111
+ def rb_scan_args(method_body)
1112
+ method_body =~ /rb_scan_args\((.*?)\)/m
1113
+ return '(*args)' unless $1
1114
+
1115
+ $1.split(/,/)[2] =~ /"(.*?)"/ # format argument
1116
+ format = $1.split(//)
1117
+
1118
+ lead = opt = trail = 0
1119
+
1120
+ if format.first =~ /\d/ then
1121
+ lead = $&.to_i
1122
+ format.shift
1123
+ if format.first =~ /\d/ then
1124
+ opt = $&.to_i
1125
+ format.shift
1126
+ if format.first =~ /\d/ then
1127
+ trail = $&.to_i
1128
+ format.shift
1129
+ block_arg = true
1130
+ end
1131
+ end
1132
+ end
1133
+
1134
+ if format.first == '*' and not block_arg then
1135
+ var = true
1136
+ format.shift
1137
+ if format.first =~ /\d/ then
1138
+ trail = $&.to_i
1139
+ format.shift
1140
+ end
1141
+ end
1142
+
1143
+ if format.first == ':' then
1144
+ hash = true
1145
+ format.shift
1146
+ end
1147
+
1148
+ if format.first == '&' then
1149
+ block = true
1150
+ format.shift
1151
+ end
1152
+
1153
+ # if the format string is not empty there's a bug in the C code, ignore it
1154
+
1155
+ args = []
1156
+ position = 1
1157
+
1158
+ (1...(position + lead)).each do |index|
1159
+ args << "p#{index}"
1160
+ end
1161
+
1162
+ position += lead
1163
+
1164
+ (position...(position + opt)).each do |index|
1165
+ args << "p#{index} = v#{index}"
1166
+ end
1167
+
1168
+ position += opt
1169
+
1170
+ if var then
1171
+ args << '*args'
1172
+ position += 1
1173
+ end
1174
+
1175
+ (position...(position + trail)).each do |index|
1176
+ args << "p#{index}"
1177
+ end
1178
+
1179
+ position += trail
1180
+
1181
+ if hash then
1182
+ args << "p#{position} = {}"
1183
+ end
1184
+
1185
+ args << '&block' if block
1186
+
1187
+ "(#{args.join ', '})"
1188
+ end
1189
+
1190
+ ##
1191
+ # Removes lines that are commented out that might otherwise get picked up
1192
+ # when scanning for classes and methods
1193
+
1194
+ def remove_commented_out_lines
1195
+ @content = @content.gsub(%r%//.*rb_define_%, '//')
1196
+ end
1197
+
1198
+ ##
1199
+ # Extracts the classes, modules, methods, attributes, constants and aliases
1200
+ # from a C file and returns an RDoc::TopLevel for this file
1201
+
1202
+ def scan
1203
+ remove_commented_out_lines
1204
+
1205
+ do_classes_and_modules
1206
+ do_missing
1207
+
1208
+ do_constants
1209
+ do_methods
1210
+ do_includes
1211
+ do_aliases
1212
+ do_attrs
1213
+
1214
+ @store.add_c_variables self
1215
+
1216
+ @top_level
1217
+ end
1218
+
1219
+ ##
1220
+ # Creates a RDoc::Comment instance.
1221
+
1222
+ def new_comment(text = nil, location = nil, language = nil)
1223
+ RDoc::Comment.new(text, location, language).tap do |comment|
1224
+ comment.format = @markup
1225
+ end
1226
+ end
1227
+ end