1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Add file.c comments (and necessary support in parse_c.rb)

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5234 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
dave 2003-12-21 07:28:54 +00:00
parent 6228cbe5ef
commit da99e407fb
9 changed files with 1564 additions and 67 deletions

18
bin/ri
View file

@ -48,7 +48,7 @@ class RiDisplay
exit 1 exit 1
end end
@ri_reader = RI::RiReader.new(RI::RiCache.new(paths)) @ri_reader = RI::RiReader.new(RI::RiCache.new(paths))
@formatter = RI::RiFormatter.new(@options.width, " ") @formatter = RI::TextFormatter.create(@options, " ")
end end
@ -127,7 +127,7 @@ end
def display_class_info(class_entry) def display_class_info(class_entry)
klass = @ri_reader.get_class(class_entry) klass = @ri_reader.get_class(class_entry)
@formatter.draw_line("Class: " + klass.full_name) @formatter.draw_line(klass.display_name + ": " + klass.full_name)
display_flow(klass.comment) display_flow(klass.comment)
@formatter.draw_line @formatter.draw_line
@ -190,28 +190,34 @@ end
def report_method_stuff(requested_method_name, methods) def report_method_stuff(requested_method_name, methods)
if methods.size == 1 if methods.size == 1
display_method_info(methods[0]) display_method_info(methods[0])
elsif (entry = methods.find {|m| m.name == requested_method_name}) else
display_method_info(entry) entries = methods.find_all {|m| m.name == requested_method_name}
if entries.size == 1
display_method_info(entries[0])
else else
puts "More than one method matched your request. You can refine" puts "More than one method matched your request. You can refine"
puts "your search by asking for information on one of:\n\n" puts "your search by asking for information on one of:\n\n"
@formatter.wrap(methods.map {|m| m.full_name} .join(", ")) @formatter.wrap(methods.map {|m| m.full_name} .join(", "))
end end
end end
end
###################################################################### ######################################################################
def report_class_stuff(requested_class_name, namespaces) def report_class_stuff(requested_class_name, namespaces)
if namespaces.size == 1 if namespaces.size == 1
display_class_info(namespaces[0]) display_class_info(namespaces[0])
elsif (entry = namespaces.find {|m| m.name == requested_class_name}) else
display_class_info(entry) entries = namespaces.find_all {|m| m.name == requested_class_name}
if entries.size == 1
display_class_info(entries[0])
else else
puts "More than one class or module matched your request. You can refine" puts "More than one class or module matched your request. You can refine"
puts "your search by asking for information on one of:\n\n" puts "your search by asking for information on one of:\n\n"
@formatter.wrap(namespaces.map {|m| m.full_name}.join(", ")) @formatter.wrap(namespaces.map {|m| m.full_name}.join(", "))
end end
end end
end
###################################################################### ######################################################################

125
error.c
View file

@ -318,6 +318,14 @@ rb_exc_new3(etype, str)
return rb_exc_new(etype, RSTRING(str)->ptr, RSTRING(str)->len); return rb_exc_new(etype, RSTRING(str)->ptr, RSTRING(str)->len);
} }
/*
* call-seq:
* Exception.new(msg = nil) => exception
*
* Construct a new Exception object, optionally passing in
* a message.
*/
static VALUE static VALUE
exc_initialize(argc, argv, exc) exc_initialize(argc, argv, exc)
int argc; int argc;
@ -336,6 +344,17 @@ exc_initialize(argc, argv, exc)
return exc; return exc;
} }
/*
* call-seq:
* exc.exception(string) -> an_exception or exc
*
* With no argument, or if the argument is the same as the receiver,
* return the receiver. Otherwise, create a new
* exception object of the same class as the receiver, but with a
* message equal to <code>string.to_str</code>.
*
*/
static VALUE static VALUE
exc_exception(argc, argv, self) exc_exception(argc, argv, self)
int argc; int argc;
@ -352,6 +371,14 @@ exc_exception(argc, argv, self)
return exc; return exc;
} }
/*
* call-seq:
* exception.to_s => string
*
* Returns exception's message (or the name of the exception if
* no message is set).
*/
static VALUE static VALUE
exc_to_s(exc) exc_to_s(exc)
VALUE exc; VALUE exc;
@ -363,6 +390,17 @@ exc_to_s(exc)
return mesg; return mesg;
} }
/*
* call-seq:
* exception.message => string
* exception.to_str => string
*
* Returns the result of invoking <code>exception.to_s</code>.
* Normally this returns the exception's message or name. By
* supplying a to_str method, exceptions are agreeing to
* be used where Strings are expected.
*/
static VALUE static VALUE
exc_to_str(exc) exc_to_str(exc)
VALUE exc; VALUE exc;
@ -370,6 +408,13 @@ exc_to_str(exc)
return rb_funcall(exc, rb_intern("to_s"), 0, 0); return rb_funcall(exc, rb_intern("to_s"), 0, 0);
} }
/*
* call-seq:
* exception.inspect => string
*
* Return this exception's class name an message
*/
static VALUE static VALUE
exc_inspect(exc) exc_inspect(exc)
VALUE exc; VALUE exc;
@ -392,6 +437,35 @@ exc_inspect(exc)
return str; return str;
} }
/*
* call-seq:
* exception.backtrace => array
*
* Returns any backtrace associated with the exception. The backtrace
* is an array of strings, each containing either ``filename:lineNo: in
* `method''' or ``filename:lineNo.''
*
* def a
* raise "boom"
* end
*
* def b
* a()
* end
*
* begin
* b()
* rescue => detail
* print detail.backtrace.join("\n")
* end
*
* <em>produces:</em>
*
* prog.rb:2:in `a'
* prog.rb:6:in `b'
* prog.rb:10
*/
static VALUE static VALUE
exc_backtrace(exc) exc_backtrace(exc)
VALUE exc; VALUE exc;
@ -425,6 +499,16 @@ check_backtrace(bt)
return bt; return bt;
} }
/*
* call-seq:
* exc.set_backtrace(array_ => array
*
* Sets the backtrace information associated with <i>exc</i>. The
* argument must be an array of <code>String</code> objects in the
* format described in <code>Exception#backtrace</code>.
*
*/
static VALUE static VALUE
exc_set_backtrace(exc, bt) exc_set_backtrace(exc, bt)
VALUE exc; VALUE exc;
@ -529,6 +613,37 @@ rb_invalid_str(str, type)
rb_raise(rb_eArgError, "invalid value for %s: %s", type, RSTRING(s)->ptr); rb_raise(rb_eArgError, "invalid value for %s: %s", type, RSTRING(s)->ptr);
} }
/*
* Document-module: Errno
*
* Ruby exception objects are subclasses of <code>Exception</code>.
* However, operating systems typically report errors using plain
* integers. Module <code>Errno</code> is created dynamically to map
* these operating system errors to Ruby classes, with each error
* number generating its own subclass of <code>SystemCallError</code>.
* As the subclass is created in module <code>Errno</code>, its name
* will start <code>Errno::</code>.
*
* The names of the <code>Errno::</code> classes depend on
* the environment in which Ruby runs. On a typical Unix or Windows
* platform, there are <code>Errno</code> classes such as
* <code>Errno::EACCES</code>, <code>Errno::EAGAIN</code>,
* <code>Errno::EINTR</code>, and so on.
*
* The integer operating system error number corresponding to a
* particular error is available as the class constant
* <code>Errno::</code><em>error</em><code>::Errno</code>.
*
* Errno::EACCES::Errno #=> 13
* Errno::EAGAIN::Errno #=> 11
* Errno::EINTR::Errno #=> 4
*
* The full list of operating system errors on your particular platform
* are available as the constants of <code>Errno</code>.
*
* Errno.constants #=> E2BIG, EACCES, EADDRINUSE, EADDRNOTAVAIL, ...
*/
static st_table *syserr_tbl; static st_table *syserr_tbl;
static VALUE static VALUE
@ -642,6 +757,16 @@ syserr_eqq(self, exc)
return Qfalse; return Qfalse;
} }
/*
* Descendents of class <code>Exception</code> are used to communicate
* between <code>raise</code> methods and <code>rescue</code>
* statements in <code>begin/end</code> blocks. <code>Exception</code>
* objects carry information about the exception---its type (the
* exception's class name), an optional descriptive string, and
* optional traceback information. Programs may subclass
* <code>Exception</code> to add additional information.
*/
void void
Init_Exception() Init_Exception()
{ {

78
eval.c
View file

@ -10134,8 +10134,70 @@ rb_thread_atfork()
curr_thread->prev = curr_thread; curr_thread->prev = curr_thread;
} }
/*
* Document-class: Continuation
*
* Continuation objects are generated by
* <code>Kernel#callcc</code>. They hold a return address and execution
* context, allowing a nonlocal return to the end of the
* <code>callcc</code> block from anywhere within a program.
* Continuations are somewhat analogous to a structured version of C's
* <code>setjmp/longjmp</code> (although they contain more state, so
* you might consider them closer to threads).
*
* For instance:
*
* arr = [ "Freddie", "Herbie", "Ron", "Max", "Ringo" ]
* callcc{|$cc|}
* puts(message = arr.shift)
* $cc.call unless message =~ /Max/
*
* <em>produces:</em>
*
* Freddie
* Herbie
* Ron
* Max
*
* This (somewhat contrived) example allows the inner loop to abandon
* processing early:
*
* callcc {|cont|
* for i in 0..4
* print "\n#{i}: "
* for j in i*5...(i+1)*5
* cont.call() if j == 17
* printf "%3d", j
* end
* end
* }
* print "\n"
*
* <em>produces:</em>
*
* 0: 0 1 2 3 4
* 1: 5 6 7 8 9
* 2: 10 11 12 13 14
* 3: 15 16
*/
static VALUE rb_cCont; static VALUE rb_cCont;
/*
* call-seq:
* callcc {|cont| block } => obj
*
* Generates a <code>Continuation</code> object, which it passes to the
* associated block. Performing a <em>cont</em><code>.call</code> will
* cause the <code>callcc</code> to return (as will falling through the
* end of the block). The value returned by the <code>callcc</code> is
* the value of the block, or the value passed to
* <em>cont</em><code>.call</code>. See class <code>Continuation</code>
* for more details. Also see <code>Kernel::throw</code> for
* an alternative mechanism for unwinding a call stack.
*/
static VALUE static VALUE
rb_callcc(self) rb_callcc(self)
VALUE self; VALUE self;
@ -10169,6 +10231,22 @@ rb_callcc(self)
} }
} }
/*
* call-seq:
* cont.call(args, ...)
* cont[args, ...]
*
* Invokes the continuation. The program continues from the end of the
* <code>callcc</code> block. If no arguments are given, the original
* <code>callcc</code> returns <code>nil</code>. If one argument is
* given, <code>callcc</code> returns it. Otherwise, an array
* containing <i>args</i> is returned.
*
* callcc {|cont| cont.call } #=> nil
* callcc {|cont| cont.call 1 } #=> 1
* callcc {|cont| cont.call 1, 2, 3 } #=> [1, 2, 3]
*/
static VALUE static VALUE
rb_cont_call(argc, argv, cont) rb_cont_call(argc, argv, cont)
int argc; int argc;

1182
file.c

File diff suppressed because it is too large Load diff

View file

@ -96,10 +96,14 @@ module Generators
end end
def generate_class_info(cls) def generate_class_info(cls)
if cls === RDoc::NormalModule
cls_desc = RI::ClassDescription.new cls_desc = RI::ClassDescription.new
cls_desc.superclass = cls.superclass
else
cls_desc = RI::ModuleDescription.new
end
cls_desc.name = cls.name cls_desc.name = cls.name
cls_desc.full_name = cls.full_name cls_desc.full_name = cls.full_name
cls_desc.superclass = cls.superclass
cls_desc.comment = markup(cls.comment) cls_desc.comment = markup(cls.comment)
cls_desc.attributes =cls.attributes.sort.map do |a| cls_desc.attributes =cls.attributes.sort.map do |a|

View file

@ -156,7 +156,6 @@ module RDoc
end end
def handle_class_module(var_name, class_mod, class_name, parent, in_module) def handle_class_module(var_name, class_mod, class_name, parent, in_module)
@known_classes[var_name] = class_name
parent_name = @known_classes[parent] || parent parent_name = @known_classes[parent] || parent
if in_module if in_module
@ -176,8 +175,10 @@ module RDoc
cm = enclosure.add_module(NormalModule, class_name) cm = enclosure.add_module(NormalModule, class_name)
end end
cm.record_location(enclosure.toplevel) cm.record_location(enclosure.toplevel)
find_class_comment(class_name, cm)
find_class_comment(cm.full_name, cm)
@classes[var_name] = cm @classes[var_name] = cm
@known_classes[var_name] = cm.full_name
end end
@ -186,8 +187,8 @@ module RDoc
if @body =~ %r{((?>/\*.*?\*/\s+)) if @body =~ %r{((?>/\*.*?\*/\s+))
(static\s+)?void\s+Init_#{class_name}\s*\(\)}xm (static\s+)?void\s+Init_#{class_name}\s*\(\)}xm
comment = $1 comment = $1
elsif @body =~ %r{Document-class:\s#{class_name}.*?\n((?>.*?\*/))}m elsif @body =~ %r{Document-(class|module):\s#{class_name}.*?\n((?>.*?\*/))}m
comment = $1 comment = $2
end end
class_meth.comment = mangle_comment(comment) if comment class_meth.comment = mangle_comment(comment) if comment
end end
@ -198,16 +199,6 @@ module RDoc
handle_class_module(var_name, "module", class_name, nil, nil) handle_class_module(var_name, "module", class_name, nil, nil)
end end
@body.scan(/(\w+)\s* = \s*rb_define_module_under
\(
\s*(\w+),
\s*"(\w+)"
\)/mx) do
|var_name, in_module, class_name|
handle_class_module(var_name, "module", class_name, nil, in_module)
end
@body.scan(/(\w+)\s* = \s*rb_define_class @body.scan(/(\w+)\s* = \s*rb_define_class
\( \(
\s*"(\w+)", \s*"(\w+)",
@ -224,6 +215,16 @@ module RDoc
handle_class_module(var_name, "class", class_name, parent, nil) handle_class_module(var_name, "class", class_name, parent, nil)
end end
@body.scan(/(\w+)\s* = \s*rb_define_module_under
\(
\s*(\w+),
\s*"(\w+)"
\)/mx) do
|var_name, in_module, class_name|
handle_class_module(var_name, "module", class_name, nil, in_module)
end
@body.scan(/(\w+)\s* = \s*rb_define_class_under @body.scan(/(\w+)\s* = \s*rb_define_class_under
\( \(
\s*(\w+), \s*(\w+),
@ -247,6 +248,31 @@ module RDoc
next if meth_name == "initialize_copy" next if meth_name == "initialize_copy"
handle_method(type, var_name, meth_name, meth_body, param_count)
end
@body.scan(/rb_define_global_function\(
\s*"([^"]+)",
\s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
\s*(-?\w+)\s*\)/xm) do #"
|meth_name, meth_body, param_count|
handle_method("method", "rb_mKernel", meth_name, meth_body, param_count)
end
@body.scan(/define_filetest_function\(
\s*"([^"]+)",
\s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
\s*(-?\w+)\s*\)/xm) do #"
|meth_name, meth_body, param_count|
handle_method("method", "rb_mFileTest", meth_name, meth_body, param_count)
handle_method("singleton_method", "rb_cFile", meth_name, meth_body, param_count)
end
end
def handle_method(type, var_name, meth_name, meth_body, param_count)
class_name = @known_classes[var_name] || var_name class_name = @known_classes[var_name] || var_name
class_obj = find_class(var_name, class_name) class_obj = find_class(var_name, class_name)
@ -274,7 +300,6 @@ module RDoc
class_obj.add_method(meth_obj) class_obj.add_method(meth_obj)
end end
end end
end
# Find the C code corresponding to a c method # Find the C code corresponding to a c method
def find_body(meth_name, meth_obj) def find_body(meth_name, meth_obj)
@ -331,14 +356,14 @@ module RDoc
end end
def find_class(raw_name, name) def find_class(raw_name, name)
unless @classes[name] unless @classes[raw_name]
if raw_name =~ /^rb_m/ if raw_name =~ /^rb_m/
@classes[name] = @top_level.add_module(NormalModule, name) @classes[raw_name] = @top_level.add_module(NormalModule, name)
else else
@classes[name] = @top_level.add_class(NormalClass, name, nil) @classes[raw_name] = @top_level.add_class(NormalClass, name, nil)
end end
end end
@classes[name] @classes[raw_name]
end end
end end

View file

@ -76,13 +76,12 @@ module RI
end end
end end
class ClassDescription < Description class ModuleDescription < Description
attr_accessor :class_methods attr_accessor :class_methods
attr_accessor :instance_methods attr_accessor :instance_methods
attr_accessor :attributes attr_accessor :attributes
attr_accessor :constants attr_accessor :constants
attr_accessor :superclass
attr_accessor :includes attr_accessor :includes
# merge in another class desscription into this one # merge in another class desscription into this one
@ -92,6 +91,13 @@ module RI
merge(@attributes, old.attributes) merge(@attributes, old.attributes)
merge(@constants, old.constants) merge(@constants, old.constants)
merge(@includes, old.includes) merge(@includes, old.includes)
if @comment.nil? || @comment.empty?
@comment = old.comment
end
end
def display_name
"Module"
end end
private private
@ -104,6 +110,15 @@ module RI
end end
end end
class ClassDescription < ModuleDescription
attr_accessor :superclass
def display_name
"Class"
end
end
class MethodDescription < Description class MethodDescription < Description
attr_accessor :is_class_method attr_accessor :is_class_method

View file

@ -1,10 +1,15 @@
module RI module RI
class RiFormatter class TextFormatter
def TextFormatter.create(options, indent)
new(options, indent)
end
attr_reader :indent attr_reader :indent
def initialize(width, indent) def initialize(options, indent)
@width = width @options = options
@width = options.width
@indent = indent @indent = indent
end end
@ -23,7 +28,7 @@ module RI
def wrap(txt, prefix=@indent, linelen=@width) def wrap(txt, prefix=@indent, linelen=@width)
return unless txt && !txt.empty? return unless txt && !txt.empty?
work = txt.dup work = conv_markup(txt)
textLen = linelen - prefix.length textLen = linelen - prefix.length
patt = Regexp.new("^(.{0,#{textLen}})[ \n]") patt = Regexp.new("^(.{0,#{textLen}})[ \n]")
next_prefix = prefix.tr("^ ", " ") next_prefix = prefix.tr("^ ", " ")
@ -53,9 +58,6 @@ module RI
# convert HTML entities back to ASCII # convert HTML entities back to ASCII
def conv_html(txt) def conv_html(txt)
txt. txt.
gsub(%r{<tt>(.*?)</tt>}) { "+#$1+" } .
gsub(%r{<b>(.*?)</b>}) { "*#$1*" } .
gsub(%r{<em>(.*?)</em>}) { "_#$1_" } .
gsub(/&gt;/, '>'). gsub(/&gt;/, '>').
gsub(/&lt;/, '<'). gsub(/&lt;/, '<').
gsub(/&quot;/, '"'). gsub(/&quot;/, '"').
@ -63,6 +65,15 @@ module RI
end end
# convert markup into display form
def conv_markup(txt)
txt.
gsub(%r{<tt>(.*?)</tt>}) { "+#$1+" } .
gsub(%r{<code>(.*?)</code>}) { "+#$1+" } .
gsub(%r{<b>(.*?)</b>}) { "*#$1*" } .
gsub(%r{<em>(.*?)</em>}) { "_#$1_" }
end
###################################################################### ######################################################################
def display_list(list) def display_list(list)
@ -167,4 +178,7 @@ module RI
end end
end end
end end
end end

View file

@ -476,6 +476,24 @@ true_xor(obj, obj2)
return RTEST(obj2)?Qfalse:Qtrue; return RTEST(obj2)?Qfalse:Qtrue;
} }
/*
* Document-class: FalseClass
*
* The global value <code>false</code> is the only instance of class
* <code>FalseClass</code> and represents a logically false value in
* boolean expressions. The class provides operators allowing
* <code>false</code> to participate correctly in logical expressions.
*
*/
/*
* call-seq:
* false.to_s => "false"
*
* 'nuf said...
*/
static VALUE static VALUE
false_to_s(obj) false_to_s(obj)
VALUE obj; VALUE obj;
@ -483,6 +501,15 @@ false_to_s(obj)
return rb_str_new2("false"); return rb_str_new2("false");
} }
/*
* call-seq:
* false & obj => false
*
* And---Returns <code>false</code>. <i>obj</i> is always
* evaluated as it is the argument to a method call---there is no
* short-circuit evaluation in this case.
*/
static VALUE static VALUE
false_and(obj, obj2) false_and(obj, obj2)
VALUE obj, obj2; VALUE obj, obj2;
@ -490,6 +517,15 @@ false_and(obj, obj2)
return Qfalse; return Qfalse;
} }
/*
* call-seq:
* false | obj => true or false
*
* Or---Returns <code>false</code> if <i>obj</i> is
* <code>nil</code> or <code>false</code>; <code>true</code> otherwise.
*/
static VALUE static VALUE
false_or(obj, obj2) false_or(obj, obj2)
VALUE obj, obj2; VALUE obj, obj2;
@ -497,6 +533,18 @@ false_or(obj, obj2)
return RTEST(obj2)?Qtrue:Qfalse; return RTEST(obj2)?Qtrue:Qfalse;
} }
/*
* call-seq:
* false ^ obj => true or false
*
* Exclusive Or---If <i>obj</i> is <code>nil</code> or
* <code>false</code>, returns <code>false</code>; otherwise, returns
* <code>true</code>.
*
*/
static VALUE static VALUE
false_xor(obj, obj2) false_xor(obj, obj2)
VALUE obj, obj2; VALUE obj, obj2;