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

Finish documenting internal stuff. See Changelog for other details

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5364 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
dave 2004-01-02 06:01:12 +00:00
parent eee1377a60
commit 88c127c19b
20 changed files with 1453 additions and 266 deletions

11
.document Normal file
View file

@ -0,0 +1,11 @@
# This file determines which files in the
# Ruby hierarchy will be processed by the RDoc
# tool when it is given the top-level directory
# as an argument
# Process all the C source files
*.c
# the lib/ directory (which has its own .document file)
lib

View file

@ -1,3 +1,16 @@
Fri Jan 2 14:54:11 2004 Dave Thomas <dave@pragprog.com>
* bin/ri: Add new --classes option, and arrange for
help messages to be paged too.
* bin/rdoc: Add statistics.
* process.c: (MG) Added Process documentation
* lib/rdoc/ri/ri_formatter.rb (RI::AttributeFormatter::wrap):
Fix problem with labels not displaying in RI labeled
lists using BS and ANSI modes.
Thu Jan 1 09:03:20 2004 Dave Thomas <dave@pragprog.com>
* bin/ri (report_class_stuff): Fix problem with ambiguous nested

View file

@ -1,3 +1,4 @@
.document
COPYING
COPYING.ja
ChangeLog
@ -109,6 +110,7 @@ ext/Setup.emx
ext/Setup.nt
ext/Setup.x68
ext/extmk.rb
lib/.document
lib/English.rb
lib/Env.rb
lib/README

119
bin/ri
View file

@ -20,17 +20,6 @@ require 'rdoc/ri/ri_reader'
require 'rdoc/ri/ri_formatter'
require 'rdoc/ri/ri_options'
######################################################################
def display_usage
RI::Options::OptionList.usage(short_form=true)
# File.open(__FILE__) do |f|
# f.gets
# puts $1 while (f.gets =~ /^# ?(.*)/)
# end
# exit
end
######################################################################
@ -53,18 +42,29 @@ class RiDisplay
end
######################################################################
def display_usage
setup_pager
RI::Options::OptionList.usage(short_form=true)
page_output
end
######################################################################
def setup_pager
unless @options.use_stdout
require 'tempfile'
@save_stdout = STDOUT.clone
STDOUT.reopen(Tempfile.new("ri_"))
end
end
######################################################################
def page_output
unless @options.use_stdout
path = STDOUT.path
STDOUT.reopen(@save_stdout)
@save_stdout = nil
@ -80,6 +80,7 @@ class RiDisplay
puts File.read(path)
end
end
end
######################################################################
@ -107,9 +108,9 @@ class RiDisplay
end
end
######################################################################
######################################################################
def display_method_info(method_entry)
def display_method_info(method_entry)
method = @ri_reader.get_method(method_entry)
@formatter.draw_line(method.full_name)
display_params(method)
@ -122,13 +123,23 @@ def display_method_info(method_entry)
aka << ")"
@formatter.wrap(aka)
end
end
end
######################################################################
######################################################################
def display_class_info(class_entry)
def display_class_info(class_entry)
klass = @ri_reader.get_class(class_entry)
@formatter.draw_line(klass.display_name + ": " + klass.full_name)
superclass = klass.superclass_string
if superclass
superclass = " < " + superclass
else
superclass = ""
end
@formatter.draw_line(klass.display_name + ": " +
klass.full_name + superclass)
display_flow(klass.comment)
@formatter.draw_line
@ -179,16 +190,16 @@ def display_class_info(class_entry)
@formatter.wrap("Attributes:", "")
@formatter.wrap(klass.attributes.map{|a| a.name}.sort.join(', '))
end
end
end
######################################################################
######################################################################
# If the list of matching methods contains exactly one entry, or
# if it contains an entry that exactly matches the requested method,
# then display that entry, otherwise display the list of
# matching method names
# If the list of matching methods contains exactly one entry, or
# if it contains an entry that exactly matches the requested method,
# then display that entry, otherwise display the list of
# matching method names
def report_method_stuff(requested_method_name, methods)
def report_method_stuff(requested_method_name, methods)
if methods.size == 1
display_method_info(methods[0])
else
@ -201,11 +212,11 @@ def report_method_stuff(requested_method_name, methods)
@formatter.wrap(methods.map {|m| m.full_name} .join(", "))
end
end
end
end
######################################################################
######################################################################
def report_class_stuff(requested_class_name, namespaces)
def report_class_stuff(requested_class_name, namespaces)
if namespaces.size == 1
display_class_info(namespaces[0])
else
@ -218,12 +229,12 @@ def report_class_stuff(requested_class_name, namespaces)
@formatter.wrap(namespaces.map {|m| m.full_name}.join(", "))
end
end
end
end
######################################################################
######################################################################
def display_info_for(arg)
def display_info_for(arg)
desc = NameDescriptor.new(arg)
namespaces = @ri_reader.top_level_namespace
@ -235,7 +246,7 @@ def display_info_for(arg)
end
end
setup_pager unless @options.use_stdout
setup_pager
begin
if desc.method_name.nil?
@ -252,26 +263,54 @@ def display_info_for(arg)
end
end
page_output unless @options.use_stdout
page_output
ensure
STDOUT.reopen(@save_stdout) if @save_stdout
end
end
end
end
######################################################################
######################################################################
if ARGV.size.zero?
def process_args
if @options.list_classes
display_class_list
else
if ARGV.size.zero?
display_usage
else
ri = RiDisplay.new
else
begin
ARGV.each do |arg|
ri.display_info_for(arg)
display_info_for(arg)
end
rescue RiError => e
$stderr.puts(e.message)
exit(1)
end
end
end
end
end
######################################################################
def display_class_list
classes = @ri_reader.class_names
if classes.empty?
puts "Before using ri, you need to generate documentation"
puts "using 'rdoc' with the --ri option"
else
setup_pager
@formatter.draw_line("Known classes and modules")
@formatter.blankline
@formatter.wrap(@ri_reader.class_names.sort.join(", "))
page_output
end
end
end # class RiDisplay
######################################################################
ri = RiDisplay.new
ri.process_args

13
eval.c
View file

@ -4181,9 +4181,12 @@ rb_exit(status)
exit(status);
}
/*
* call-seq:
* exit(integer=0)
* Kernel::exit(integer=0)
* Process::exit(integer=0)
*
* Initiates the termination of the Ruby script by raising the
* <code>SystemExit</code> exception. This exception may be caught. The
@ -4203,9 +4206,9 @@ rb_exit(status)
* rescued a SystemExit exception
* after begin block
*
* Just prior to termination, Ruby executes any <code>at_exit</code>
* functions and runs any object finalizers (see
* <code>ObjectSpace</code> beginning on page 434).
* Just prior to termination, Ruby executes any <code>at_exit</code> functions
* (see Kernel::at_exit) and runs any object finalizers (see
* ObjectSpace::define_finalizer).
*
* at_exit { puts "at_exit function" }
* ObjectSpace.define_finalizer("string", proc { puts "in finalizer" })
@ -4246,10 +4249,12 @@ rb_f_exit(argc, argv)
return Qnil; /* not reached */
}
/*
* call-seq:
* abort
* abort(msg)
* Kernel::abort
* Process::abort
*
* Terminate execution immediately, effectively by calling
* <code>Kernel.exit(1)</code>. If _msg_ is given, it is written

4
lib/.document Normal file
View file

@ -0,0 +1,4 @@
# We only run RDoc on the top-level files in here: we skip
# all the helper stuff in sub-directories
*.rb

View file

@ -263,6 +263,11 @@ module RDoc
return self if self.name == name
res = @modules[name] || @classes[name]
return res if res
find_enclosing_module_named(name)
end
# find a module at a higher scope
def find_enclosing_module_named(name)
parent && parent.find_module_named(name)
end
@ -316,6 +321,7 @@ module RDoc
if result
modules.each do |module_name|
result = result.find_module_named(module_name)
break unless result
end
end
end

View file

@ -97,10 +97,10 @@ module Generators
def generate_class_info(cls)
if cls === RDoc::NormalModule
cls_desc = RI::ModuleDescription.new
else
cls_desc = RI::ClassDescription.new
cls_desc.superclass = cls.superclass
else
cls_desc = RI::ModuleDescription.new
end
cls_desc.name = cls.name
cls_desc.full_name = cls.full_name

View file

@ -127,10 +127,11 @@ module RDoc
@@known_bodies = {}
# prepare to parse a C file
def initialize(top_level, file_name, body, options)
def initialize(top_level, file_name, body, options, stats)
@known_classes = KNOWN_CLASSES.dup
@body = body
@options = options
@stats = stats
@top_level = top_level
@classes = Hash.new
@file_dir = File.dirname(file_name)
@ -173,8 +174,10 @@ module RDoc
if class_mod == "class"
cm = enclosure.add_class(NormalClass, class_name, parent_name)
@stats.num_classes += 1
else
cm = enclosure.add_module(NormalModule, class_name)
@stats.num_modules += 1
end
cm.record_location(enclosure.toplevel)
@ -303,6 +306,8 @@ module RDoc
def handle_method(type, var_name, meth_name,
meth_body, param_count, source_file = nil)
@stats.num_methods += 1
class_name = @known_classes[var_name] || var_name
class_obj = find_class(var_name, class_name)

View file

@ -32,8 +32,9 @@ module RDoc
parse_files_matching(/\.(f9(0|5)|F)$/)
# prepare to parse a Fortran 95 file
def initialize(top_level, file_name, body, options)
def initialize(top_level, file_name, body, options, stats)
@body = body
@stats = stats
@options = options
@top_level = top_level
@progress = $stderr unless options.quiet

View file

@ -1374,8 +1374,9 @@ module RDoc
parse_files_matching(/\.rbw?$/)
def initialize(top_level, file_name, content, options)
def initialize(top_level, file_name, content, options, stats)
@options = options
@stats = stats
@size = 0
@token_listeners = nil
@input_file_name = file_name
@ -1710,6 +1711,8 @@ module RDoc
def parse_class(container, single, tk, comment, &block)
progress("c")
@stats.num_classes += 1
container, name_t = get_class_or_module(container)
case name_t
@ -1762,6 +1765,7 @@ module RDoc
def parse_module(container, single, tk, comment)
progress("m")
@stats.num_modules += 1
container, name_t = get_class_or_module(container)
# skip_tkspace
name = name_t.name
@ -1853,6 +1857,7 @@ module RDoc
def parse_method(container, single, tk, comment)
progress(".")
@stats.num_methods += 1
line_no = tk.line_no
column = tk.char_no

View file

@ -12,7 +12,7 @@ module RDoc
class SimpleParser
# prepare to parse a plain file
def initialize(top_level, file_name, body, options)
def initialize(top_level, file_name, body, options, stats)
preprocess = SM::PreProcess.new(file_name, options.rdoc_include)

View file

@ -73,14 +73,15 @@ module RDoc
# Find the correct parser for a particular file name. Return a
# SimpleParser for ones that we don't know
def ParserFactory.parser_for(top_level, file_name, body, options)
def ParserFactory.parser_for(top_level, file_name, body, options, stats)
parser_description = can_parse(file_name)
if parser_description
parser = parser_description.parser
else
parser = SimpleParser
end
parser.new(top_level, file_name, body, options)
parser.new(top_level, file_name, body, options, stats)
end
end
end

View file

@ -31,6 +31,27 @@ require 'ftools'
module RDoc
# Name of the dotfile that contains the description of files to be
# processed in the current directory
DOT_DOC_FILENAME = ".document"
# Simple stats collector
class Stats
attr_accessor :num_files, :num_classes, :num_modules, :num_methods
def initialize
@num_files = @num_classes = @num_modules = @num_methods = 0
@start = Time.now
end
def print
puts "Files: #@num_files"
puts "Classes: #@num_classes"
puts "Modules: #@num_modules"
puts "Methods: #@num_methods"
puts "Elapsed: " + sprintf("%0.3fs", Time.now - @start)
end
end
# Exception thrown by any rdoc error. Only the #message part is
# of use externally.
@ -110,25 +131,40 @@ module RDoc
end
# The .document file contains a list of file and directory name
# patterns, representing candidates for documentation. It may
# also contain comments (starting with '#')
def parse_dot_doc_file(in_dir, filename, options)
# read and strip comments
patterns = File.read(filename).gsub(/#.*/, '')
result = []
patterns.split.each do |patt|
candidates = Dir.glob(File.join(in_dir, patt))
result.concat(normalized_file_list(options, candidates))
end
result
end
# Given a list of files and directories, create a list
# of all the Ruby files they contain.
def normalized_file_list(options, *relative_files)
def normalized_file_list(options, relative_files)
file_list = []
relative_files.each do |rel_file_name|
case type = File.stat(rel_file_name).ftype
when "file"
file_list << rel_file_name
when "directory"
next if options.exclude && options.exclude =~ rel_file_name
Find.find(rel_file_name) do |fn|
next if options.exclude && options.exclude =~ fn
next unless ParserFactory.can_parse(fn)
next unless File.file?(fn)
file_list << fn.sub(%r{\./}, '')
dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME)
if File.file?(dot_doc)
file_list.concat(parse_dot_doc_file(rel_file_name, dot_doc, options))
else
file_list.concat(list_files_in_directory(rel_file_name, options))
end
else
raise RDocError.new("I can't deal with a #{type} #{rel_file_name}")
@ -137,6 +173,16 @@ module RDoc
file_list
end
# Return a list of the files to be processed in
# a directory. We know that this directory doesn't have
# a .document file, so we're looking for real files. However
# we may well contain subdirectories which must
# be tested for .document files
def list_files_in_directory(dir, options)
normalized_file_list(options, Dir.glob(File.join(dir, "*")))
end
# Parse each file on the command line, recursively entering
# directories
@ -147,7 +193,7 @@ module RDoc
files = options.files
files = ["."] if files.empty?
file_list = normalized_file_list(options, *files)
file_list = normalized_file_list(options, files)
file_list.each do |fn|
$stderr.printf("\n%35s: ", File.basename(fn)) unless options.quiet
@ -155,8 +201,9 @@ module RDoc
content = File.open(fn, "r") {|f| f.read}
top_level = TopLevel.new(fn)
parser = ParserFactory.parser_for(top_level, fn, content, options)
parser = ParserFactory.parser_for(top_level, fn, content, options, @stats)
file_info << parser.scan
@stats.num_files += 1
end
file_info
@ -182,6 +229,8 @@ module RDoc
TopLevel::reset
@stats = Stats.new
options = Options.instance
options.parse(argv, GENERATORS)
@ -211,7 +260,11 @@ module RDoc
ensure
Dir.chdir(pwd)
end
end
unless options.quiet
puts
@stats.print
end
end
end

View file

@ -100,6 +100,12 @@ module RI
"Module"
end
# the 'ClassDescription' subclass overrides this
# to format up the name of a parent
def superclass_string
nil
end
private
def merge(into, from)
@ -116,6 +122,14 @@ module RI
def display_name
"Class"
end
def superclass_string
if @superclass && @superclass != "Object"
@superclass
else
nil
end
end
end

View file

@ -197,7 +197,6 @@ module RI
end
end
######################################################################
def display_flow(flow)
flow.each do |f|
@ -207,6 +206,7 @@ module RI
end
######################################################################
# Handle text with attributes. We're a base class: there are
# different presentation classes (one, for example, uses overstrikes
# to handle bold and underlinig, while another using ANSI escape
@ -278,27 +278,30 @@ module RI
return unless txt && !txt.empty?
txt = add_attributes_to(txt)
next_prefix = prefix.tr("^ ", " ")
linelen -= prefix.size
line = []
until txt.empty?
word = txt.next_word
if word.size + line.size > linelen - @indent.size
write_attribute_text(line)
if word.size + line.size > linelen
write_attribute_text(prefix, line)
prefix = next_prefix
line = []
end
line.concat(word)
end
write_attribute_text(line) if line.length > 0
write_attribute_text(prefix, line) if line.length > 0
end
protected
# overridden in specific formatters
def write_attribute_text(line)
print @indent
def write_attribute_text(prefix, line)
print prefix
line.each do |achar|
print achar.char
end
@ -340,8 +343,8 @@ module RI
BS = "\C-h"
def write_attribute_text(line)
print @indent
def write_attribute_text(prefix, line)
print prefix
line.each do |achar|
attr = achar.attr
if (attr & (ITALIC+CODE)) != 0
@ -371,15 +374,13 @@ module RI
class AnsiFormatter < AttributeFormatter
BS = "\C-h"
def initialize(*args)
print "\033[0m"
super
end
def write_attribute_text(line)
print @indent
def write_attribute_text(prefix, line)
print prefix
curr_attr = 0
line.each do |achar|
attr = achar.attr

View file

@ -16,6 +16,9 @@ module RI
# can't find a pager
attr_accessor :use_stdout
# should we just display a class list and exit
attr_reader :list_classes
# The width of the output line
attr_reader :width
@ -28,6 +31,10 @@ module RI
[ "--help", "-h", nil,
"you're looking at it" ],
[ "--classes", "-c", nil,
"Display the names of classes and modules we\n" +
"know about"],
[ "--format", "-f", "<name>",
"Format to use when displaying output:\n" +
" " + RI::TextFormatter.list + "\n" +
@ -112,8 +119,8 @@ module RI
EOT
if short_form
class_list
puts "For help, type 'ri -h'"
puts "For help on options, type 'ri -h'"
puts "For a list of classes I know about, type 'ri -c'"
else
puts "Options:\n\n"
OPTION_LIST.each do |long, short, arg, desc|
@ -136,21 +143,6 @@ module RI
end
end
def OptionList.class_list
paths = RI::Paths::PATH
if paths.empty?
puts "Before using ri, you need to generate documentation"
puts "using 'rdoc' with the --ri option"
else
@ri_reader = RI::RiReader.new(RI::RiCache.new(paths))
puts
puts "Classes and modules I know about:"
puts
puts @ri_reader.class_names.sort.join(", ")
puts
end
end
end
# Parse command line options.
@ -160,6 +152,7 @@ module RI
@use_stdout = !STDOUT.tty?
@width = 72
@formatter = RI::TextFormatter.for("plain")
@list_classes = false
begin
@ -170,6 +163,8 @@ module RI
case opt
when "--help" then OptionList.usage
when "--no-pager" then @use_stdout = true
when "--classes" then @list_classes = true
when "--format"
@formatter = RI::TextFormatter.for(arg)
unless @formatter

View file

@ -1197,6 +1197,15 @@ sym_to_sym(sym)
*
*/
/*
* call-seq:
* mod.to_s => string
*
* Return a string representing this module or class. For basic
* classes and modules, this is the name. For singletons, we
* show information on the thing we're attached to as well.
*/
static VALUE
rb_mod_to_s(klass)
VALUE klass;
@ -2417,8 +2426,6 @@ VALUE ruby_top_self;
* ^ |
* | |
* +----------------+
*
*
*/

1007
process.c

File diff suppressed because it is too large Load diff

View file

@ -198,6 +198,30 @@ ruby_signal_name(no)
return signo2signm(no);
}
/*
* call-seq:
* Process.kill(signal, pid, ...) => fixnum
*
* Sends the given signal to the specified process id(s), or to the
* current process if _pid_ is zero. _signal_ may be an
* integer signal number or a POSIX signal name (either with or without
* a +SIG+ prefix). If _signal_ is negative (or starts
* with a minus sign), kills process groups instead of
* processes. Not all signals are available on all platforms.
*
* pid = fork do
* Signal.trap("HUP") { puts "Ouch!"; exit }
* # ... do some work ...
* end
* # ...
* Process.kill("HUP", pid)
* Process.wait
*
* <em>produces:</em>
*
* Ouch!
*/
VALUE
rb_f_kill(argc, argv)
int argc;