diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-12-31 21:13:27 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-12-31 21:13:27 +0000 |
commit | 4e6f681b40d237c70671c6b3e831a9ad1e7fb26d (patch) | |
tree | 9f23562f891ebff723ccb8060361907210717b98 | |
parent | a3e1b1ce7ed7e7ffac23015fc2fde56511b30681 (diff) | |
download | ruby-4e6f681b40d237c70671c6b3e831a9ad1e7fb26d.tar.gz |
Allow RDoc comment to give friendly value for rb_define_const.
Patch by Daniel Berger <djberg96 at gmail.com>, [ruby-patches-7499].
Fix whitespace handling in constant comments.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11443 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | lib/rdoc/parsers/parse_c.rb | 31 | ||||
-rw-r--r-- | test/rdoc/parsers/test_parse_c.rb | 148 |
3 files changed, 184 insertions, 3 deletions
@@ -1,3 +1,11 @@ +Mon Jan 1 06:05:55 2007 Eric Hodel <drbrain@segment7.net> + + * lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser#handle_constansts): + Allow RDoc comment to give friendly value for rb_define_const. Patch + by Daniel Berger <djberg96 at gmail.com>, [ruby-patches-7499]. + * lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser#handle_constansts): Fix + whitespace handling in constant comments. + Mon Jan 01 00:00:00 2007 Koichi Sasada <ko1@atdot.net> * Merge YARV diff --git a/lib/rdoc/parsers/parse_c.rb b/lib/rdoc/parsers/parse_c.rb index a1ea9a5da7..e4c4a4a0f5 100644 --- a/lib/rdoc/parsers/parse_c.rb +++ b/lib/rdoc/parsers/parse_c.rb @@ -95,7 +95,8 @@ require "rdoc/code_objects" require "rdoc/parsers/parserfactory" - +require "rdoc/options" +require "rdoc/rdoc" module RDoc @@ -165,6 +166,7 @@ module RDoc class C_Parser + attr_accessor :progress extend ParserFactory parse_files_matching(/\.(c|cc|cpp|CC)$/) @@ -444,14 +446,37 @@ module RDoc comment = find_const_comment(type, const_name) - con = Constant.new(const_name, definition, mangle_comment(comment)) + # In the case of rb_define_const, the definition and comment are in + # "/* definition: comment */" form. The literal ':' and '\' characters + # can be escaped with a backslash. + if type.downcase == 'const' then + elements = mangle_comment(comment).split(':') + if elements.nil? or elements.empty? then + con = Constant.new(const_name, definition, mangle_comment(comment)) + else + new_definition = elements[0..-2].join(':') + if new_definition.empty? then # Default to literal C definition + new_definition = definition + else + new_definition.gsub!("\:", ":") + new_definition.gsub!("\\", '\\') + end + new_definition.sub!(/\A(\s+)/, '') + new_comment = $1.nil? ? elements.last : "#{$1}#{elements.last.lstrip}" + con = Constant.new(const_name, new_definition, + mangle_comment(new_comment)) + end + else + con = Constant.new(const_name, definition, mangle_comment(comment)) + end + class_obj.add_constant(con) end ########################################################### def find_const_comment(type, const_name) - if @body =~ %r{((?>/\*.*?\*/\s+)) + if @body =~ %r{((?>^\s*/\*.*?\*/\s+)) rb_define_#{type}\((?:\s*(\w+),)?\s*"#{const_name}"\s*,.*?\)\s*;}xmi $1 elsif @body =~ %r{Document-(?:const|global|variable):\s#{const_name}\s*?\n((?>.*?\*/))}m diff --git a/test/rdoc/parsers/test_parse_c.rb b/test/rdoc/parsers/test_parse_c.rb new file mode 100644 index 0000000000..c7815a95c0 --- /dev/null +++ b/test/rdoc/parsers/test_parse_c.rb @@ -0,0 +1,148 @@ +require 'pp' +require 'stringio' +require 'tempfile' +require 'test/unit' +require 'rdoc/parsers/parse_c' + +class RDoc::C_Parser + attr_accessor :classes + + public :do_classes, :do_constants +end + +class TestRdocC_Parser < Test::Unit::TestCase + + def setup + @tempfile = Tempfile.new self.class.name + filename = @tempfile.path + + @top_level = RDoc::TopLevel.new filename + @fn = filename + @options = Options.instance + @stats = RDoc::Stats.new + + @progress = StringIO.new + end + + def teardown + @tempfile.unlink + end + + def test_do_constants + content = <<-EOF +#include <ruby.h> + +void Init_foo(){ + VALUE cFoo = rb_define_class("Foo", rb_cObject); + + /* 300: The highest possible score in bowling */ + rb_define_const(cFoo, "PERFECT", INT2FIX(300)); + + /* Huzzah!: What you cheer when you roll a perfect game */ + rb_define_const(cFoo, "CHEER", rb_str_new2("Huzzah!")); + + /* TEST\:TEST: Checking to see if escaped semicolon works */ + rb_define_const(cFoo, "TEST", rb_str_new2("TEST:TEST")); + + /* \\: The file separator on MS Windows */ + rb_define_const(cFoo, "MSEPARATOR", rb_str_new2("\\")); + + /* /: The file separator on Unix */ + rb_define_const(cFoo, "SEPARATOR", rb_str_new2("/")); + + /* C:\\Program Files\\Stuff: A directory on MS Windows */ + rb_define_const(cFoo, "STUFF", rb_str_new2("C:\\Program Files\\Stuff")); + + /* Default definition */ + rb_define_const(cFoo, "NOSEMI", INT2FIX(99)); + + rb_define_const(cFoo, "NOCOMMENT", rb_str_new2("No comment")); + + /* + * Multiline comment goes here because this comment spans multiple lines. + * Multiline comment goes here because this comment spans multiple lines. + */ + rb_define_const(cFoo, "MULTILINE", INT2FIX(1)); + + /* + * 1: Multiline comment goes here because this comment spans multiple lines. + * Multiline comment goes here because this comment spans multiple lines. + */ + rb_define_const(cFoo, "MULTILINE_VALUE", INT2FIX(1)); + + /* Multiline comment goes here because this comment spans multiple lines. + * Multiline comment goes here because this comment spans multiple lines. + */ + rb_define_const(cFoo, "MULTILINE_NOT_EMPTY", INT2FIX(1)); + +} + EOF + + parser = util_parser content + + parser.do_classes + parser.do_constants + + klass = parser.classes['cFoo'] + assert klass + + constants = klass.constants + assert !klass.constants.empty? + + constants = constants.map { |c| [c.name, c.value, c.comment] } + + assert_equal ['PERFECT', '300', + "\n The highest possible score in bowling \n "], + constants.shift + assert_equal ['CHEER', 'Huzzah!', + "\n What you cheer when you roll a perfect game \n "], + constants.shift + assert_equal ['TEST', 'TEST:TEST', + "\n Checking to see if escaped semicolon works \n "], + constants.shift + assert_equal ['MSEPARATOR', '\\', + "\n The file separator on MS Windows \n "], + constants.shift + assert_equal ['SEPARATOR', '/', + "\n The file separator on Unix \n "], + constants.shift + assert_equal ['STUFF', 'C:\\Program Files\\Stuff', + "\n A directory on MS Windows \n "], + constants.shift + assert_equal ['NOSEMI', 'INT2FIX(99)', + "\n Default definition \n "], + constants.shift + assert_equal ['NOCOMMENT', 'rb_str_new2("No comment")', nil], + constants.shift + + comment = <<-EOF.chomp + + + Multiline comment goes here because this comment spans multiple lines. + Multiline comment goes here because this comment spans multiple lines. + + + EOF + assert_equal ['MULTILINE', 'INT2FIX(1)', comment], constants.shift + assert_equal ['MULTILINE_VALUE', '1', comment], constants.shift + + comment = <<-EOF.chomp + + Multiline comment goes here because this comment spans multiple lines. + Multiline comment goes here because this comment spans multiple lines. + + + EOF + assert_equal ['MULTILINE_NOT_EMPTY', 'INT2FIX(1)', comment], constants.shift + + assert constants.empty?, constants.inspect + end + + def util_parser(content) + parser = RDoc::C_Parser.new @top_level, @fn, content, @options, @stats + parser.progress = @progress + parser + end + +end + |