From: Charles Mills Date: 2005-01-24T04:38:10+09:00 Subject: Re: [PATCH] parse_c.rb: allow whitespace after function names --Apple-Mail-7--647140989 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed On Jan 23, 2005, at 1:41 AM, Yukihiro Matsumoto wrote: > Hi, > > In message "Re: [PATCH] parse_c.rb: allow whitespace after function > names" > on Sun, 23 Jan 2005 15:47:23 +0900, Charles Mills > writes: > > |Speaking of RDoc patches I was wondering if this patch was ever > |applied. It adds support for constants (rb_define_const), accessors > |(rb_define_attr), and makes a couple fixes. > > Unified diff please. > > matz Sorry about that. -Charlie --Apple-Mail-7--647140989 Content-Transfer-Encoding: 7bit Content-Type: application/octet-stream; x-unix-mode=0644; name="rdoc_diff2" Content-Disposition: attachment; filename=rdoc_diff2 --- /Users/boson/src/ruby-1.8.2/lib/rdoc/parsers/parse_c.rb Wed Sep 8 19:48:32 2004 +++ parse_c.rb Sun Dec 19 11:18:30 2004 @@ -174,7 +174,7 @@ # prepare to parse a C file def initialize(top_level, file_name, body, options, stats) @known_classes = KNOWN_CLASSES.dup - @body = handle_ifdefs_in(body) + @body = handle_tab_width(handle_ifdefs_in(body)) @options = options @stats = stats @top_level = top_level @@ -187,6 +187,7 @@ def scan remove_commented_out_lines do_classes + do_constants do_methods do_includes do_aliases @@ -240,7 +241,7 @@ if @body =~ %r{((?>/\*.*?\*/\s+)) (static\s+)?void\s+Init_#{class_name}\s*\(\)}xmi comment = $1 - elsif @body =~ %r{Document-(class|module):\s#{class_name}.*?\n((?>.*?\*/))}m + elsif @body =~ %r{Document-(class|module):\s#{class_name}\s*?\n((?>.*?\*/))}m comment = $2 end class_meth.comment = mangle_comment(comment) if comment @@ -293,6 +294,28 @@ end end + + ########################################################### + + def do_constants + @body.scan(%r{\Wrb_define_ + ( + variable | + readonly_variable | + const | + global_const | + ) + \s*\( + (?:\s*(\w+),)? + \s*"(\w+)", + \s*(.*?)\s*\)\s*; + }xm) do + + |type, var_name, const_name, definition| + var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel" + handle_constants(type, var_name, const_name, definition) + end + end ############################################################ @@ -325,6 +348,20 @@ meth_body, param_count, source_file) end + @body.scan(%r{rb_define_attr\( + \s*([\w\.]+), + \s*"([^"]+)", + \s*(\d+), + \s*(\d+)\s*\); + }xm) do #" + |var_name, attr_name, attr_reader, attr_writer| + + #var_name = "rb_cObject" if var_name == "rb_mKernel" + handle_attr(var_name, attr_name, + attr_reader.to_i != 0, + attr_writer.to_i != 0) + end + @body.scan(%r{rb_define_global_function\( \s*"([^"]+)", \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, @@ -362,6 +399,83 @@ ############################################################ + def handle_constants(type, var_name, const_name, definition) + #@stats.num_constants += 1 + class_name = @known_classes[var_name] + + return unless class_name + + class_obj = find_class(var_name, class_name) + + unless class_obj + $stderr.puts("Enclosing class/module '#{const_name}' for not known") + return + end + + comment = find_const_comment(type, const_name) + + con = Constant.new(const_name, definition, mangle_comment(comment)) + class_obj.add_constant(con) + end + + ########################################################### + + def find_const_comment(type, const_name) + if @body =~ %r{((?>/\*.*?\*/\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 + $1 + else + '' + end + end + + ########################################################### + + def handle_attr(var_name, attr_name, reader, writer) + rw = '' + if reader + #@stats.num_methods += 1 + rw << 'R' + end + if writer + #@stats.num_methods += 1 + rw << 'W' + end + + class_name = @known_classes[var_name] + + return unless class_name + + class_obj = find_class(var_name, class_name) + + if class_obj + comment = find_attr_comment(attr_name) + unless comment.empty? + comment = mangle_comment(comment) + end + att = Attr.new('', attr_name, rw, comment) + class_obj.add_attribute(att) + end + + end + + ########################################################### + + def find_attr_comment(attr_name) + if @body =~ %r{((?>/\*.*?\*/\s+)) + rb_define_attr\((?:\s*(\w+),)?\s*"#{attr_name}"\s*,.*?\)\s*;}xmi + $1 + elsif @body =~ %r{Document-attr:\s#{attr_name}\s*?\n((?>.*?\*/))}m + $1 + else + '' + end + end + + ########################################################### + def handle_method(type, var_name, meth_name, meth_body, param_count, source_file = nil) @stats.num_methods += 1 @@ -469,12 +583,10 @@ ############################################################ def find_override_comment(meth_name) - comment = nil name = Regexp.escape(meth_name) - if @body =~ %r{Document-method:\s#{name}.*?\n((?>.*?\*/))}m - comment = $1 + if @body =~ %r{Document-method:\s#{name}\s*?\n((?>.*?\*/))}m + $1 end - comment end ############################################################ @@ -510,6 +622,18 @@ end end @classes[raw_name] + end + + def handle_tab_width(body) + if /\t/ =~ body + tab_width = Options.instance.tab_width + body.split(/\n/).map do |line| + 1 while line.gsub!(/\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)} && $~ #` + line + end .join("\n") + else + body + end end # Remove #ifdefs that would otherwise confuse us --Apple-Mail-7--647140989 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed --Apple-Mail-7--647140989--