mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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
This commit is contained in:
parent
a3e1b1ce7e
commit
4e6f681b40
3 changed files with 184 additions and 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
|
||||
|
|
|
@ -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
|
||||
|
|
148
test/rdoc/parsers/test_parse_c.rb
Normal file
148
test/rdoc/parsers/test_parse_c.rb
Normal file
|
@ -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
|
||||
|
Loading…
Reference in a new issue