mirror of
https://github.com/ruby/ruby.git
synced 2025-09-17 09:33:59 +02:00
Release branch of Ruby 2.1
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@44340 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
commit
e39b6aaac2
1668 changed files with 163123 additions and 86060 deletions
|
@ -10,12 +10,9 @@
|
|||
prelude.rb
|
||||
|
||||
# the lib/ directory (which has its own .document file)
|
||||
|
||||
lib
|
||||
|
||||
|
||||
# and some of the ext/ directory (which has its own .document file)
|
||||
|
||||
ext
|
||||
|
||||
# rdoc files
|
||||
|
|
462
.gdbinit
462
.gdbinit
|
@ -1,80 +1,34 @@
|
|||
define rp
|
||||
define hook-run
|
||||
set $color_type = 0
|
||||
set $color_highlite = 0
|
||||
set $color_end = 0
|
||||
end
|
||||
|
||||
define ruby_gdb_init
|
||||
if !$color_type
|
||||
set $color_type = "\033[31m"
|
||||
end
|
||||
if !$color_highlite
|
||||
set $color_highlite = "\033[36m"
|
||||
end
|
||||
if !$color_end
|
||||
set $color_end = "\033[m"
|
||||
end
|
||||
if ruby_dummy_gdb_enums.special_consts
|
||||
end
|
||||
end
|
||||
|
||||
# set prompt \033[36m(gdb)\033[m\040
|
||||
|
||||
define rp
|
||||
ruby_gdb_init
|
||||
if (VALUE)($arg0) & RUBY_FIXNUM_FLAG
|
||||
printf "FIXNUM: %ld\n", (long)($arg0) >> 1
|
||||
else
|
||||
if ((VALUE)($arg0) & ~(~(VALUE)0<<RUBY_SPECIAL_SHIFT)) == RUBY_SYMBOL_FLAG
|
||||
set $id = (($arg0) >> RUBY_SPECIAL_SHIFT)
|
||||
if $id == '!' || $id == '+' || $id == '-' || $id == '*' || $id == '/' || $id == '%' || $id == '<' || $id == '>' || $id == '`'
|
||||
printf "SYMBOL(:%c)\n", $id
|
||||
else
|
||||
if $id == idDot2
|
||||
echo SYMBOL(:..)\n
|
||||
else
|
||||
if $id == idDot3
|
||||
echo SYMBOL(:...)\n
|
||||
else
|
||||
if $id == idUPlus
|
||||
echo SYMBOL(:+@)\n
|
||||
else
|
||||
if $id == idUMinus
|
||||
echo SYMBOL(:-@)\n
|
||||
else
|
||||
if $id == idPow
|
||||
echo SYMBOL(:**)\n
|
||||
else
|
||||
if $id == idCmp
|
||||
echo SYMBOL(:<=>)\n
|
||||
else
|
||||
if $id == idLTLT
|
||||
echo SYMBOL(:<<)\n
|
||||
else
|
||||
if $id == idLE
|
||||
echo SYMBOL(:<=)\n
|
||||
else
|
||||
if $id == idGE
|
||||
echo SYMBOL(:>=)\n
|
||||
else
|
||||
if $id == idEq
|
||||
echo SYMBOL(:==)\n
|
||||
else
|
||||
if $id == idEqq
|
||||
echo SYMBOL(:===)\n
|
||||
else
|
||||
if $id == idNeq
|
||||
echo SYMBOL(:!=)\n
|
||||
else
|
||||
if $id == idEqTilde
|
||||
echo SYMBOL(:=~)\n
|
||||
else
|
||||
if $id == idNeqTilde
|
||||
echo SYMBOL(:!~)\n
|
||||
else
|
||||
if $id == idAREF
|
||||
echo SYMBOL(:[])\n
|
||||
else
|
||||
if $id == idASET
|
||||
echo SYMBOL(:[]=)\n
|
||||
else
|
||||
printf "SYMBOL(%ld)\n", $id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
printf "%sSYMBOL%s: ", $color_type, $color_end
|
||||
rp_id $id
|
||||
else
|
||||
if ($arg0) == RUBY_Qfalse
|
||||
echo false\n
|
||||
|
@ -90,80 +44,51 @@ define rp
|
|||
else
|
||||
if (VALUE)($arg0) & RUBY_IMMEDIATE_MASK
|
||||
if ((VALUE)($arg0) & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG
|
||||
printf "FLONUM: %g\n", (double)rb_float_value($arg0)
|
||||
printf "%sFLONUM%s: %g\n", $color_type, $color_end, (double)rb_float_value($arg0)
|
||||
else
|
||||
echo immediate\n
|
||||
end
|
||||
else
|
||||
set $flags = ((struct RBasic*)($arg0))->flags
|
||||
if ($flags & RUBY_FL_PROMOTED)
|
||||
printf "[PROMOTED] "
|
||||
end
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_NONE
|
||||
printf "T_NONE: "
|
||||
printf "%sT_NONE%s: ", $color_type, $color_end
|
||||
print (struct RBasic *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_NIL
|
||||
printf "T_NIL: "
|
||||
printf "%sT_NIL%s: ", $color_type, $color_end
|
||||
print (struct RBasic *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_OBJECT
|
||||
printf "T_OBJECT: "
|
||||
printf "%sT_OBJECT%s: ", $color_type, $color_end
|
||||
print (struct RObject *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_CLASS
|
||||
printf "T_CLASS%s: ", ($flags & RUBY_FL_SINGLETON) ? "*" : ""
|
||||
printf "%sT_CLASS%s%s: ", $color_type, ($flags & RUBY_FL_SINGLETON) ? "*" : "", $color_end
|
||||
rp_class $arg0
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_ICLASS
|
||||
printf "T_ICLASS: "
|
||||
printf "%sT_ICLASS%s: ", $color_type, $color_end
|
||||
rp_class $arg0
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_MODULE
|
||||
printf "T_MODULE: "
|
||||
printf "%sT_MODULE%s: ", $color_type, $color_end
|
||||
rp_class $arg0
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_FLOAT
|
||||
printf "T_FLOAT: %.16g ", (((struct RFloat*)($arg0))->float_value)
|
||||
printf "%sT_FLOAT%s: %.16g ", $color_type, $color_end, (((struct RFloat*)($arg0))->float_value)
|
||||
print (struct RFloat *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_STRING
|
||||
printf "T_STRING: "
|
||||
set print address off
|
||||
output (char *)(($flags & RUBY_FL_USER1) ? \
|
||||
((struct RString*)($arg0))->as.heap.ptr : \
|
||||
((struct RString*)($arg0))->as.ary)
|
||||
set print address on
|
||||
printf " bytesize:%ld ", ($flags & RUBY_FL_USER1) ? \
|
||||
((struct RString*)($arg0))->as.heap.len : \
|
||||
(($flags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
|
||||
if !($flags & RUBY_FL_USER1)
|
||||
printf "(embed) "
|
||||
else
|
||||
if ($flags & RUBY_FL_USER2)
|
||||
printf "(shared) "
|
||||
end
|
||||
if ($flags & RUBY_FL_USER3)
|
||||
printf "(assoc) "
|
||||
end
|
||||
end
|
||||
printf "encoding:%d ", ($flags & RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT
|
||||
if ($flags & RUBY_ENC_CODERANGE_MASK) == 0
|
||||
printf "coderange:unknown "
|
||||
else
|
||||
if ($flags & RUBY_ENC_CODERANGE_MASK) == RUBY_ENC_CODERANGE_7BIT
|
||||
printf "coderange:7bit "
|
||||
else
|
||||
if ($flags & RUBY_ENC_CODERANGE_MASK) == RUBY_ENC_CODERANGE_VALID
|
||||
printf "coderange:valid "
|
||||
else
|
||||
printf "coderange:broken "
|
||||
end
|
||||
end
|
||||
end
|
||||
print (struct RString *)($arg0)
|
||||
printf "%sT_STRING%s: ", $color_type, $color_end
|
||||
rp_string $arg0 $flags
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_REGEXP
|
||||
set $regsrc = ((struct RRegexp*)($arg0))->src
|
||||
set $rsflags = ((struct RBasic*)$regsrc)->flags
|
||||
printf "T_REGEXP: "
|
||||
printf "%sT_REGEXP%s: ", $color_type, $color_end
|
||||
set print address off
|
||||
output (char *)(($rsflags & RUBY_FL_USER1) ? \
|
||||
((struct RString*)$regsrc)->as.heap.ptr : \
|
||||
|
@ -187,7 +112,7 @@ define rp
|
|||
if ($flags & RUBY_T_MASK) == RUBY_T_ARRAY
|
||||
if ($flags & RUBY_FL_USER1)
|
||||
set $len = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
|
||||
printf "T_ARRAY: len=%ld ", $len
|
||||
printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len
|
||||
printf "(embed) "
|
||||
if ($len == 0)
|
||||
printf "{(empty)} "
|
||||
|
@ -197,7 +122,7 @@ define rp
|
|||
end
|
||||
else
|
||||
set $len = ((struct RArray*)($arg0))->as.heap.len
|
||||
printf "T_ARRAY: len=%ld ", $len
|
||||
printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len
|
||||
if ($flags & RUBY_FL_USER2)
|
||||
printf "(shared) shared="
|
||||
output/x ((struct RArray*)($arg0))->as.heap.aux.shared
|
||||
|
@ -215,18 +140,18 @@ define rp
|
|||
print (struct RArray *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_FIXNUM
|
||||
printf "T_FIXNUM: "
|
||||
printf "%sT_FIXNUM%s: ", $color_type, $color_end
|
||||
print (struct RBasic *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_HASH
|
||||
printf "T_HASH: ",
|
||||
printf "%sT_HASH%s: ", $color_type, $color_end,
|
||||
if ((struct RHash *)($arg0))->ntbl
|
||||
printf "len=%ld ", ((struct RHash *)($arg0))->ntbl->num_entries
|
||||
end
|
||||
print (struct RHash *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_STRUCT
|
||||
printf "T_STRUCT: len=%ld ", \
|
||||
printf "%sT_STRUCT%s: len=%ld ", $color_type, $color_end, \
|
||||
(($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) ? \
|
||||
($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) >> (RUBY_FL_USHIFT+1) : \
|
||||
((struct RStruct *)($arg0))->as.heap.len)
|
||||
|
@ -236,7 +161,7 @@ define rp
|
|||
((struct RStruct *)($arg0))->as.heap.ptr)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_BIGNUM
|
||||
printf "T_BIGNUM: sign=%d len=%ld ", \
|
||||
printf "%sT_BIGNUM%s: sign=%d len=%ld ", $color_type, $color_end, \
|
||||
(($flags & RUBY_FL_USER1) != 0), \
|
||||
(($flags & RUBY_FL_USER2) ? \
|
||||
($flags & (RUBY_FL_USER5|RUBY_FL_USER4|RUBY_FL_USER3)) >> (RUBY_FL_USHIFT+3) : \
|
||||
|
@ -250,59 +175,59 @@ define rp
|
|||
((struct RBignum*)($arg0))->as.heap.digits)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_RATIONAL
|
||||
printf "T_RATIONAL: "
|
||||
printf "%sT_RATIONAL%s: ", $color_type, $color_end
|
||||
print (struct RRational *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_COMPLEX
|
||||
printf "T_COMPLEX: "
|
||||
printf "%sT_COMPLEX%s: ", $color_type, $color_end
|
||||
print (struct RComplex *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_FILE
|
||||
printf "T_FILE: "
|
||||
printf "%sT_FILE%s: ", $color_type, $color_end
|
||||
print (struct RFile *)($arg0)
|
||||
output *((struct RFile *)($arg0))->fptr
|
||||
printf "\n"
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_TRUE
|
||||
printf "T_TRUE: "
|
||||
printf "%sT_TRUE%s: ", $color_type, $color_end
|
||||
print (struct RBasic *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_FALSE
|
||||
printf "T_FALSE: "
|
||||
printf "%sT_FALSE%s: ", $color_type, $color_end
|
||||
print (struct RBasic *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_DATA
|
||||
if ((struct RTypedData *)($arg0))->typed_flag == 1
|
||||
printf "T_DATA(%s): ", ((struct RTypedData *)($arg0))->type->wrap_struct_name
|
||||
printf "%sT_DATA%s(%s): ", $color_type, $color_end, ((struct RTypedData *)($arg0))->type->wrap_struct_name
|
||||
print (struct RTypedData *)($arg0)
|
||||
else
|
||||
printf "T_DATA: "
|
||||
printf "%sT_DATA%s: ", $color_type, $color_end
|
||||
print (struct RData *)($arg0)
|
||||
end
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_MATCH
|
||||
printf "T_MATCH: "
|
||||
printf "%sT_MATCH%s: ", $color_type, $color_end
|
||||
print (struct RMatch *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_SYMBOL
|
||||
printf "T_SYMBOL: "
|
||||
printf "%sT_SYMBOL%s: ", $color_type, $color_end
|
||||
print (struct RBasic *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_UNDEF
|
||||
printf "T_UNDEF: "
|
||||
printf "%sT_UNDEF%s: ", $color_type, $color_end
|
||||
print (struct RBasic *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_NODE
|
||||
printf "T_NODE("
|
||||
printf "%sT_NODE%s(", $color_type, $color_end
|
||||
output (enum node_type)(($flags&RUBY_NODE_TYPEMASK)>>RUBY_NODE_TYPESHIFT)
|
||||
printf "): "
|
||||
print *(NODE *)($arg0)
|
||||
else
|
||||
if ($flags & RUBY_T_MASK) == RUBY_T_ZOMBIE
|
||||
printf "T_ZOMBIE: "
|
||||
printf "%sT_ZOMBIE%s: ", $color_type, $color_end
|
||||
print (struct RData *)($arg0)
|
||||
else
|
||||
printf "unknown: "
|
||||
printf "%sunknown%s: ", $color_type, $color_end
|
||||
print (struct RBasic *)($arg0)
|
||||
end
|
||||
end
|
||||
|
@ -341,12 +266,165 @@ document rp
|
|||
Print a Ruby's VALUE.
|
||||
end
|
||||
|
||||
define rp_id
|
||||
set $id = (ID)$arg0
|
||||
if $id == '!' || $id == '+' || $id == '-' || $id == '*' || $id == '/' || $id == '%' || $id == '<' || $id == '>' || $id == '`'
|
||||
printf "(:%c)\n", $id
|
||||
else
|
||||
if $id == idDot2
|
||||
printf "(:..)\n"
|
||||
else
|
||||
if $id == idDot3
|
||||
printf "(:...)\n"
|
||||
else
|
||||
if $id == idUPlus
|
||||
printf "(:+@)\n"
|
||||
else
|
||||
if $id == idUMinus
|
||||
printf "(:-@)\n"
|
||||
else
|
||||
if $id == idPow
|
||||
printf "(:**)\n"
|
||||
else
|
||||
if $id == idCmp
|
||||
printf "(:<=>)\n"
|
||||
else
|
||||
if $id == idLTLT
|
||||
printf "(:<<)\n"
|
||||
else
|
||||
if $id == idLE
|
||||
printf "(:<=)\n"
|
||||
else
|
||||
if $id == idGE
|
||||
printf "(:>=)\n"
|
||||
else
|
||||
if $id == idEq
|
||||
printf "(:==)\n"
|
||||
else
|
||||
if $id == idEqq
|
||||
printf "(:===)\n"
|
||||
else
|
||||
if $id == idNeq
|
||||
printf "(:!=)\n"
|
||||
else
|
||||
if $id == idEqTilde
|
||||
printf "(:=~)\n"
|
||||
else
|
||||
if $id == idNeqTilde
|
||||
printf "(:!~)\n"
|
||||
else
|
||||
if $id == idAREF
|
||||
printf "(:[])\n"
|
||||
else
|
||||
if $id == idASET
|
||||
printf "(:[]=)\n"
|
||||
else
|
||||
if $id <= tLAST_OP_ID
|
||||
printf "O"
|
||||
else
|
||||
set $id_type = $id & RUBY_ID_SCOPE_MASK
|
||||
if $id_type == RUBY_ID_LOCAL
|
||||
printf "l"
|
||||
else
|
||||
if $id_type == RUBY_ID_INSTANCE
|
||||
printf "i"
|
||||
else
|
||||
if $id_type == RUBY_ID_GLOBAL
|
||||
printf "G"
|
||||
else
|
||||
if $id_type == RUBY_ID_ATTRSET
|
||||
printf "a"
|
||||
else
|
||||
if $id_type == RUBY_ID_CONST
|
||||
printf "C"
|
||||
else
|
||||
if $id_type == RUBY_ID_CLASS
|
||||
printf "c"
|
||||
else
|
||||
printf "j"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
printf "(%ld): ", $id
|
||||
rb_numtable_entry global_symbols.id_str $id
|
||||
if $rb_numtable_rec
|
||||
rp_string $rb_numtable_rec
|
||||
else
|
||||
echo undef\n
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
document rp_id
|
||||
Print an ID.
|
||||
end
|
||||
|
||||
define rp_string
|
||||
set $flags = ((struct RBasic*)($arg0))->flags
|
||||
set print address off
|
||||
output (char *)(($flags & RUBY_FL_USER1) ? \
|
||||
((struct RString*)($arg0))->as.heap.ptr : \
|
||||
((struct RString*)($arg0))->as.ary)
|
||||
set print address on
|
||||
printf " bytesize:%ld ", ($flags & RUBY_FL_USER1) ? \
|
||||
((struct RString*)($arg0))->as.heap.len : \
|
||||
(($flags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
|
||||
if !($flags & RUBY_FL_USER1)
|
||||
printf "(embed) "
|
||||
else
|
||||
if ($flags & RUBY_FL_USER2)
|
||||
printf "(shared) "
|
||||
end
|
||||
if ($flags & RUBY_FL_USER3)
|
||||
printf "(assoc) "
|
||||
end
|
||||
end
|
||||
printf "encoding:%d ", ($flags & RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT
|
||||
if ($flags & RUBY_ENC_CODERANGE_MASK) == 0
|
||||
printf "coderange:unknown "
|
||||
else
|
||||
if ($flags & RUBY_ENC_CODERANGE_MASK) == RUBY_ENC_CODERANGE_7BIT
|
||||
printf "coderange:7bit "
|
||||
else
|
||||
if ($flags & RUBY_ENC_CODERANGE_MASK) == RUBY_ENC_CODERANGE_VALID
|
||||
printf "coderange:valid "
|
||||
else
|
||||
printf "coderange:broken "
|
||||
end
|
||||
end
|
||||
end
|
||||
print (struct RString *)($arg0)
|
||||
end
|
||||
document rp_string
|
||||
Print the content of a String.
|
||||
end
|
||||
|
||||
define rp_class
|
||||
printf "(struct RClass *) %p", (void*)$arg0
|
||||
if ((struct RClass *)($arg0))->ptr.origin != $arg0
|
||||
printf " -> %p", ((struct RClass *)($arg0))->ptr.origin
|
||||
end
|
||||
printf "\n"
|
||||
rb_classname $arg0
|
||||
print *(struct RClass *)($arg0)
|
||||
print *((struct RClass *)($arg0))->ptr
|
||||
end
|
||||
|
@ -378,257 +456,257 @@ end
|
|||
# Print members of ruby node.
|
||||
|
||||
define nd_head
|
||||
printf "u1.node: "
|
||||
printf "%su1.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.node
|
||||
end
|
||||
|
||||
define nd_alen
|
||||
printf "u2.argc: "
|
||||
printf "%su2.argc%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u2.argc
|
||||
end
|
||||
|
||||
define nd_next
|
||||
printf "u3.node: "
|
||||
printf "%su3.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u3.node
|
||||
end
|
||||
|
||||
|
||||
define nd_cond
|
||||
printf "u1.node: "
|
||||
printf "%su1.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.node
|
||||
end
|
||||
|
||||
define nd_body
|
||||
printf "u2.node: "
|
||||
printf "%su2.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u2.node
|
||||
end
|
||||
|
||||
define nd_else
|
||||
printf "u3.node: "
|
||||
printf "%su3.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u3.node
|
||||
end
|
||||
|
||||
|
||||
define nd_orig
|
||||
printf "u3.value: "
|
||||
printf "%su3.value%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u3.value
|
||||
end
|
||||
|
||||
|
||||
define nd_resq
|
||||
printf "u2.node: "
|
||||
printf "%su2.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u2.node
|
||||
end
|
||||
|
||||
define nd_ensr
|
||||
printf "u3.node: "
|
||||
printf "%su3.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u3.node
|
||||
end
|
||||
|
||||
|
||||
define nd_1st
|
||||
printf "u1.node: "
|
||||
printf "%su1.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.node
|
||||
end
|
||||
|
||||
define nd_2nd
|
||||
printf "u2.node: "
|
||||
printf "%su2.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u2.node
|
||||
end
|
||||
|
||||
|
||||
define nd_stts
|
||||
printf "u1.node: "
|
||||
printf "%su1.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.node
|
||||
end
|
||||
|
||||
|
||||
define nd_entry
|
||||
printf "u3.entry: "
|
||||
printf "%su3.entry%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u3.entry
|
||||
end
|
||||
|
||||
define nd_vid
|
||||
printf "u1.id: "
|
||||
printf "%su1.id%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u1.id
|
||||
end
|
||||
|
||||
define nd_cflag
|
||||
printf "u2.id: "
|
||||
printf "%su2.id%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u2.id
|
||||
end
|
||||
|
||||
define nd_cval
|
||||
printf "u3.value: "
|
||||
printf "%su3.value%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u3.value
|
||||
end
|
||||
|
||||
|
||||
define nd_cnt
|
||||
printf "u3.cnt: "
|
||||
printf "%su3.cnt%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u3.cnt
|
||||
end
|
||||
|
||||
define nd_tbl
|
||||
printf "u1.tbl: "
|
||||
printf "%su1.tbl%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u1.tbl
|
||||
end
|
||||
|
||||
|
||||
define nd_var
|
||||
printf "u1.node: "
|
||||
printf "%su1.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.node
|
||||
end
|
||||
|
||||
define nd_ibdy
|
||||
printf "u2.node: "
|
||||
printf "%su2.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u2.node
|
||||
end
|
||||
|
||||
define nd_iter
|
||||
printf "u3.node: "
|
||||
printf "%su3.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u3.node
|
||||
end
|
||||
|
||||
|
||||
define nd_value
|
||||
printf "u2.node: "
|
||||
printf "%su2.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u2.node
|
||||
end
|
||||
|
||||
define nd_aid
|
||||
printf "u3.id: "
|
||||
printf "%su3.id%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u3.id
|
||||
end
|
||||
|
||||
|
||||
define nd_lit
|
||||
printf "u1.value: "
|
||||
printf "%su1.value%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.value
|
||||
end
|
||||
|
||||
|
||||
define nd_frml
|
||||
printf "u1.node: "
|
||||
printf "%su1.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.node
|
||||
end
|
||||
|
||||
define nd_rest
|
||||
printf "u2.argc: "
|
||||
printf "%su2.argc%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u2.argc
|
||||
end
|
||||
|
||||
define nd_opt
|
||||
printf "u1.node: "
|
||||
printf "%su1.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.node
|
||||
end
|
||||
|
||||
|
||||
define nd_recv
|
||||
printf "u1.node: "
|
||||
printf "%su1.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.node
|
||||
end
|
||||
|
||||
define nd_mid
|
||||
printf "u2.id: "
|
||||
printf "%su2.id%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u2.id
|
||||
end
|
||||
|
||||
define nd_args
|
||||
printf "u3.node: "
|
||||
printf "%su3.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u3.node
|
||||
end
|
||||
|
||||
|
||||
define nd_noex
|
||||
printf "u1.id: "
|
||||
printf "%su1.id%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u1.id
|
||||
end
|
||||
|
||||
define nd_defn
|
||||
printf "u3.node: "
|
||||
printf "%su3.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u3.node
|
||||
end
|
||||
|
||||
|
||||
define nd_old
|
||||
printf "u1.id: "
|
||||
printf "%su1.id%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u1.id
|
||||
end
|
||||
|
||||
define nd_new
|
||||
printf "u2.id: "
|
||||
printf "%su2.id%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u2.id
|
||||
end
|
||||
|
||||
|
||||
define nd_cfnc
|
||||
printf "u1.cfunc: "
|
||||
printf "%su1.cfunc%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u1.cfunc
|
||||
end
|
||||
|
||||
define nd_argc
|
||||
printf "u2.argc: "
|
||||
printf "%su2.argc%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u2.argc
|
||||
end
|
||||
|
||||
|
||||
define nd_cname
|
||||
printf "u1.id: "
|
||||
printf "%su1.id%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u1.id
|
||||
end
|
||||
|
||||
define nd_super
|
||||
printf "u3.node: "
|
||||
printf "%su3.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u3.node
|
||||
end
|
||||
|
||||
|
||||
define nd_modl
|
||||
printf "u1.id: "
|
||||
printf "%su1.id%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u1.id
|
||||
end
|
||||
|
||||
define nd_clss
|
||||
printf "u1.value: "
|
||||
printf "%su1.value%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.value
|
||||
end
|
||||
|
||||
|
||||
define nd_beg
|
||||
printf "u1.node: "
|
||||
printf "%su1.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u1.node
|
||||
end
|
||||
|
||||
define nd_end
|
||||
printf "u2.node: "
|
||||
printf "%su2.node%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u2.node
|
||||
end
|
||||
|
||||
define nd_state
|
||||
printf "u3.state: "
|
||||
printf "%su3.state%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u3.state
|
||||
end
|
||||
|
||||
define nd_rval
|
||||
printf "u2.value: "
|
||||
printf "%su2.value%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u2.value
|
||||
end
|
||||
|
||||
|
||||
define nd_nth
|
||||
printf "u2.argc: "
|
||||
printf "%su2.argc%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u2.argc
|
||||
end
|
||||
|
||||
|
||||
define nd_tag
|
||||
printf "u1.id: "
|
||||
printf "%su1.id%s: ", $color_highlite, $color_end
|
||||
p ($arg0).u1.id
|
||||
end
|
||||
|
||||
define nd_tval
|
||||
printf "u2.value: "
|
||||
printf "%su2.value%s: ", $color_highlite, $color_end
|
||||
rp ($arg0).u2.value
|
||||
end
|
||||
|
||||
|
@ -667,12 +745,9 @@ define rb_numtable_entry
|
|||
end
|
||||
|
||||
define rb_id2name
|
||||
rb_numtable_entry global_symbols.id_str (ID)$arg0
|
||||
if $rb_numtable_rec
|
||||
rp $rb_numtable_rec
|
||||
else
|
||||
echo undef\n
|
||||
end
|
||||
ruby_gdb_init
|
||||
printf "%sID%s: ", $color_type, $color_end
|
||||
rp_id $arg0
|
||||
end
|
||||
document rb_id2name
|
||||
Print the name of id
|
||||
|
@ -683,7 +758,7 @@ define rb_method_entry
|
|||
set $rb_method_entry_id = (ID)$arg1
|
||||
set $rb_method_entry_me = (rb_method_entry_t *)0
|
||||
while !$rb_method_entry_me && $rb_method_entry_klass
|
||||
rb_numtable_entry $rb_method_entry_klass->m_tbl $rb_method_entry_id
|
||||
rb_numtable_entry $rb_method_entry_klass->m_tbl_wrapper->tbl $rb_method_entry_id
|
||||
set $rb_method_entry_me = (rb_method_entry_t *)$rb_numtable_rec
|
||||
if !$rb_method_entry_me
|
||||
set $rb_method_entry_klass = (struct RClass *)$rb_method_entry_klass->ptr->super
|
||||
|
@ -701,15 +776,20 @@ document rb_method_entry
|
|||
end
|
||||
|
||||
define rb_classname
|
||||
call classname($arg0)
|
||||
rb_p $
|
||||
print *(struct RClass*)($arg0)
|
||||
# up to 128bit int
|
||||
set $rb_classname_permanent = "0123456789ABCDEF"
|
||||
set $rb_classname = classname($arg0, $rb_classname_permanent)
|
||||
if $rb_classname != RUBY_Qnil
|
||||
rp $rb_classname
|
||||
else
|
||||
echo anonymous class/module\n
|
||||
end
|
||||
end
|
||||
|
||||
define rb_ancestors
|
||||
set $rb_ancestors_module = $arg0
|
||||
while $rb_ancestors_module
|
||||
rp $rb_ancestors_module
|
||||
rp_class $rb_ancestors_module
|
||||
set $rb_ancestors_module = ((struct RClass *)($rb_ancestors_module))->ptr.super
|
||||
end
|
||||
end
|
||||
|
@ -722,7 +802,7 @@ define rb_backtrace
|
|||
end
|
||||
|
||||
define iseq
|
||||
if dummy_gdb_enums.special_consts
|
||||
if ruby_dummy_gdb_enums.special_consts
|
||||
end
|
||||
if ($arg0)->type == ISEQ_ELEMENT_NONE
|
||||
echo [none]\n
|
||||
|
|
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -23,6 +23,7 @@
|
|||
.ppack
|
||||
.svn
|
||||
Makefile
|
||||
Makefile.old
|
||||
extconf.h
|
||||
y.output
|
||||
y.tab.c
|
||||
|
@ -36,6 +37,7 @@ y.tab.c
|
|||
/ChangeLog.pre1_1
|
||||
/Doxyfile
|
||||
/GNUmakefile
|
||||
/GNUmakefile.old
|
||||
/README.atheos
|
||||
/README.fat-patch
|
||||
/README.v6
|
||||
|
@ -82,6 +84,7 @@ y.tab.c
|
|||
/rubicon
|
||||
/ruby
|
||||
/ruby-man.rd.gz
|
||||
/sizes.c
|
||||
/test.rb
|
||||
/tmp
|
||||
/transdb.h
|
||||
|
@ -103,6 +106,9 @@ y.tab.c
|
|||
/ext/dl/callback/callback-*.c
|
||||
/ext/dl/callback/callback.c
|
||||
|
||||
# /ext/rbconfig/
|
||||
/ext/rbconfig/sizeof/sizes.c
|
||||
|
||||
# /ext/ripper/
|
||||
/ext/ripper/eventids1.c
|
||||
/ext/ripper/eventids2table.c
|
||||
|
@ -122,6 +128,10 @@ y.tab.c
|
|||
/spec/mspec
|
||||
/spec/rubyspec
|
||||
|
||||
# /tool/
|
||||
/tool/config.guess
|
||||
/tool/config.sub
|
||||
|
||||
# /win32/
|
||||
/win32/*.ico
|
||||
/win32/.time
|
||||
|
|
19
.travis.yml
19
.travis.yml
|
@ -38,11 +38,19 @@ install: "sudo apt-get -qq build-dep ruby1.9.1 2>/dev/null"
|
|||
# like test-all, test-rubyspec. This is because they take too much time,
|
||||
# enough for Travis to shut down the VM as being stalled.
|
||||
before_script:
|
||||
- "make -f common.mk BASERUBY=ruby srcdir=. update-config_files"
|
||||
- "autoconf"
|
||||
- "./configure --with-gcc=$CC"
|
||||
- "mkdir config_1st config_2nd"
|
||||
- "./configure -C --with-gcc=$CC"
|
||||
- "cp -pr config.status .ext/include config_1st"
|
||||
- "make reconfig"
|
||||
- "cp -pr config.status .ext/include config_2nd"
|
||||
- "diff -ru config_1st config_2nd"
|
||||
- "make -sj encs"
|
||||
- "make -sj exts"
|
||||
script: "make test OPTS=-v"
|
||||
script:
|
||||
- "make test OPTS=-v"
|
||||
# - "make test-all TESTS='-v'"
|
||||
|
||||
# Branch matrix. Not all branches are Travis-ready so we limit branches here.
|
||||
branches:
|
||||
|
@ -61,6 +69,13 @@ notifications:
|
|||
template:
|
||||
- "%{message} by @%{author}: See %{build_url}"
|
||||
|
||||
# Update ruby-head installed on Travis CI so other projects can test against it.
|
||||
webhooks:
|
||||
urls:
|
||||
- "https://rubies.travis-ci.org/rebuild/ruby-head"
|
||||
on_success: always
|
||||
on_failure: never
|
||||
|
||||
# Local Variables:
|
||||
# mode: YAML
|
||||
# coding: utf-8-unix
|
||||
|
|
2
BSDL
2
BSDL
|
@ -1,4 +1,4 @@
|
|||
Copyright (C) 1993-2010 Yukihiro Matsumoto. All rights reserved.
|
||||
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
|
40
Makefile.in
40
Makefile.in
|
@ -40,6 +40,7 @@ datadir = @datadir@
|
|||
arch = @arch@
|
||||
sitearch = @sitearch@
|
||||
sitedir = @sitedir@
|
||||
archlibdir = @archlibdir@
|
||||
ruby_version = @ruby_version@
|
||||
|
||||
TESTUI = console
|
||||
|
@ -52,6 +53,7 @@ arch_hdrdir = $(EXTOUT)/include/$(arch)
|
|||
VPATH = $(arch_hdrdir)/ruby:$(hdrdir)/ruby:$(srcdir):$(srcdir)/enc:$(srcdir)/missing
|
||||
|
||||
empty =
|
||||
CC_VERSION = @CC_VERSION@
|
||||
OUTFLAG = @OUTFLAG@$(empty)
|
||||
COUTFLAG = @COUTFLAG@$(empty)
|
||||
ARCH_FLAG = @ARCH_FLAG@
|
||||
|
@ -60,6 +62,7 @@ cflags = @cflags@
|
|||
optflags = @optflags@
|
||||
debugflags = @debugflags@
|
||||
warnflags = @warnflags@ @strict_warnflags@
|
||||
cppflags = @cppflags@
|
||||
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir)
|
||||
XCFLAGS = @XCFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@ $(INCFLAGS)
|
||||
|
@ -93,8 +96,11 @@ PROGRAM=$(RUBY_INSTALL_NAME)$(EXEEXT)
|
|||
RUBY = $(RUBY_INSTALL_NAME)
|
||||
MINIRUBY = @MINIRUBY@\
|
||||
$(MINIRUBYOPT)
|
||||
RUNRUBY_COMMAND = @RUNRUBY@ $(RUNRUBYOPT)
|
||||
RUNRUBY = $(RUNRUBY_COMMAND) -- $(RUN_OPTS)
|
||||
# RUNRUBY_COMMAND:: runruby.rb or baseruby. do not append options directly
|
||||
RUNRUBY_COMMAND = @RUNRUBY_COMMAND@
|
||||
# RUNRUBY:: run ruby with RUN_OPTS which is passed to ruby
|
||||
RUNRUBY = @RUNRUBY@ $(RUN_OPTS)
|
||||
# RUNRUBY_DEBUGGER:: debugging option for runruby.rb
|
||||
RUNRUBY_DEBUGGER = --debugger='gdb -x run.gdb --quiet --args'
|
||||
XRUBY = @XRUBY@
|
||||
BTESTRUBY = @BTESTRUBY@\
|
||||
|
@ -107,7 +113,7 @@ XRUBY_LIBDIR = @XRUBY_LIBDIR@
|
|||
XRUBY_RUBYLIBDIR = @XRUBY_RUBYLIBDIR@
|
||||
XRUBY_RUBYHDRDIR = @XRUBY_RUBYHDRDIR@
|
||||
|
||||
DEFAULT_PRELUDES = $(@USE_RUBYGEMS@_GEM_PRELUDE)
|
||||
DEFAULT_PRELUDES = $(GEM_PRELUDE)
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
|
@ -178,6 +184,8 @@ OS_DEST_FILE = $@
|
|||
|
||||
MESSAGE_BEGIN = @for line in
|
||||
MESSAGE_END = ; do echo "$$line"; done
|
||||
ECHO_BEGIN = @sep=''; for word in
|
||||
ECHO_END = ; do echo @ECHO_N@ "$$sep'$$word'@ECHO_C@"; sep=' '; done; echo
|
||||
|
||||
configure_args = @configure_args@
|
||||
#### End of variables
|
||||
|
@ -194,12 +202,12 @@ all:
|
|||
miniruby$(EXEEXT):
|
||||
@-if test -f $@; then $(MV) -f $@ $@.old; $(RM) $@.old; fi
|
||||
$(ECHO) linking $@
|
||||
$(Q) $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(NORMALMAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(DMYEXT) $(DTRACE_OBJ) $(LIBS) $(OUTFLAG)$@
|
||||
$(Q) $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(NORMALMAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(DMYEXT) $(DTRACE_OBJ) $(MAINLIBS) $(LIBS) $(OUTFLAG)$@
|
||||
|
||||
$(PROGRAM):
|
||||
@$(RM) $@
|
||||
$(ECHO) linking $@
|
||||
$(Q) $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) $(EXTLIBS) $(OUTFLAG)$@
|
||||
$(Q) $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(MAINLIBS) $(LIBS) $(EXTLIBS) $(OUTFLAG)$@
|
||||
$(Q) $(POSTLINK)
|
||||
|
||||
# We must `rm' the library each time this rule is invoked because "updating" a
|
||||
|
@ -211,7 +219,7 @@ $(LIBRUBY_A):
|
|||
$(Q) $(AR) $(ARFLAGS) $@ $(LIBRUBY_A_OBJS) $(DMYEXT)
|
||||
@-$(RANLIB) $@ 2> /dev/null || true
|
||||
$(ECHO) verifying static-library $@
|
||||
@$(PURIFY) $(CC) $(XLDFLAGS) $(MAINOBJ) $(LIBRUBY_A) $(MAINLIBS) $(EXTLIBS) $(LIBS) $(OUTFLAG)conftest$(EXEEXT) $(LDFLAGS)
|
||||
@$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(LIBRUBY_A) $(MAINLIBS) $(EXTLIBS) $(LIBS) $(OUTFLAG)conftest$(EXEEXT)
|
||||
@$(RM) conftest$(EXEEXT) conftest.c
|
||||
|
||||
$(LIBRUBY_SO):
|
||||
|
@ -220,7 +228,7 @@ $(LIBRUBY_SO):
|
|||
$(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) $(DLDOBJS) $(DTRACE_OBJ) $(SOLIBS) $(EXTSOLIBS) $(OUTFLAG)$@
|
||||
-$(Q) $(OBJCOPY) -w -L '$(SYMBOL_PREFIX)Init_*' -L '$(SYMBOL_PREFIX)*_threadptr_*' $@
|
||||
$(Q) $(POSTLINK)
|
||||
@-$(MINIRUBY) -e 'ARGV.each{|link| File.delete link if File.exist? link; \
|
||||
@-$(MINIRUBY) -e 'ARGV.each{|link| File.delete link rescue nil; \
|
||||
File.symlink "$(LIBRUBY_SO)", link}' \
|
||||
$(LIBRUBY_ALIASES) || true
|
||||
$(arch)-fake.rb: config.status $(srcdir)/template/fake.rb.in
|
||||
|
@ -251,14 +259,16 @@ install-cross: $(arch)-fake.rb $(RBCONFIG) rbconfig.rb $(arch_hdrdir)/ruby/confi
|
|||
Makefile: $(srcdir)/Makefile.in $(srcdir)/enc/Makefile.in
|
||||
|
||||
$(MKFILES): config.status
|
||||
MAKE=$(MAKE) $(SHELL) ./config.status
|
||||
@{ \
|
||||
@[ -f $@ ] && mv $@ $@.old
|
||||
MAKE=$(MAKE) $(SHELL) ./config.status $@
|
||||
@cmp $@ $@.old > /dev/null 2>&1 && echo $@ unchanged && exit 0; \
|
||||
{ \
|
||||
echo "all:; -@rm -f conftest.mk"; \
|
||||
echo "conftest.mk: .force; @echo AUTO_REMAKE"; \
|
||||
echo ".force:"; \
|
||||
} > conftest.mk || exit 1; \
|
||||
$(MAKE) -f conftest.mk | grep '^AUTO_REMAKE$$' >/dev/null 2>&1 || \
|
||||
{ echo "Makefile updated, restart."; exit 1; }
|
||||
{ echo "$@ updated, restart."; exit 1; }
|
||||
|
||||
uncommon.mk: $(srcdir)/common.mk
|
||||
sed 's/{\$$([^(){}]*)[^{}]*}//g' $< > $@
|
||||
|
@ -425,6 +435,11 @@ enc/encinit.$(OBJEXT): enc/encinit.c $(SETUP)
|
|||
up::
|
||||
@$(CHDIR) "$(srcdir)" && LC_TIME=C exec $(VCSUP)
|
||||
|
||||
up::
|
||||
-$(Q)$(MAKE) $(MFLAGS) after-update
|
||||
|
||||
after-update:: update-config_files
|
||||
|
||||
update-mspec:
|
||||
@$(CHDIR) $(srcdir); \
|
||||
if [ -d spec/mspec ]; then \
|
||||
|
@ -458,3 +473,8 @@ $(INSNS): $(srcdir)/insns.def vm_opts.h \
|
|||
$(srcdir)/tool/instruction.rb $(srcdir)/tool/insns2vm.rb
|
||||
$(ECHO) generating $@
|
||||
$(Q) $(BASERUBY) -Ku $(srcdir)/tool/insns2vm.rb $(INSNS2VMOPT) $@
|
||||
|
||||
loadpath: verconf.h
|
||||
@$(CPP) $(XCFLAGS) $(CPPFLAGS) $(srcdir)/loadpath.c | \
|
||||
sed -e '1,/^const char ruby_initial_load_paths/d;/;/,$$d' \
|
||||
-e '/^ /!d;s/ *"\\0"$$//;s/" *"//g'
|
||||
|
|
759
NEWS
759
NEWS
|
@ -1,6 +1,6 @@
|
|||
# -*- rdoc -*-
|
||||
|
||||
= NEWS for Ruby 2.0.0
|
||||
= NEWS for Ruby 2.1.0
|
||||
|
||||
This document is a list of user visible feature changes made between
|
||||
releases except for bug fixes.
|
||||
|
@ -9,446 +9,365 @@ Note that each entry is kept so brief that no reason behind or
|
|||
reference information is supplied with. For a full list of changes
|
||||
with all sufficient information, see the ChangeLog file.
|
||||
|
||||
== Changes since the 1.9.3 release
|
||||
|
||||
=== C API updates
|
||||
* NUM2SHORT() and NUM2USHORT() added. They are similar to NUM2INT, but short.
|
||||
* rb_newobj_of() and NEWOBJ_OF() added. They create a new object of a given class.
|
||||
|
||||
=== Library updates (outstanding ones only)
|
||||
|
||||
* builtin classes
|
||||
|
||||
* Array
|
||||
* added method:
|
||||
* added Array#bsearch for binary search.
|
||||
* incompatible changes:
|
||||
* random parameter of Array#shuffle! and Array#sample now
|
||||
will be called with one argument, maximum value.
|
||||
* when given Range arguments, Array#values_at now returns nil for each
|
||||
value that is out-of-range.
|
||||
|
||||
* Enumerable
|
||||
* added method:
|
||||
* added Enumerable#lazy method for lazy enumeration.
|
||||
|
||||
* Enumerator
|
||||
* added method:
|
||||
* added Enumerator#size for lazy size evaluation.
|
||||
* extended method:
|
||||
* Enumerator.new accept an argument for lazy size evaluation.
|
||||
|
||||
* ENV
|
||||
* aliased method:
|
||||
* ENV.to_h is a new alias for ENV.to_hash
|
||||
|
||||
* Fiber
|
||||
* incompatible changes:
|
||||
* Fiber#resume cannot resume a fiber which invokes "Fiber#transfer".
|
||||
|
||||
* File
|
||||
* extended method:
|
||||
* File.fnmatch? now expands braces in the pattern if
|
||||
File::FNM_EXTGLOB option is given.
|
||||
|
||||
* GC
|
||||
* improvements:
|
||||
* introduced the bitmap marking which suppresses to copy a memory page
|
||||
with Copy-on-Write.
|
||||
* introduced the non-recursive marking which avoids unexpected stack overflow.
|
||||
|
||||
* GC::Profiler
|
||||
* added method:
|
||||
* added GC::Profiler.raw_data which returns raw profile data for GC.
|
||||
|
||||
* Hash
|
||||
* added method:
|
||||
* added Hash#to_h as explicit conversion method, like Array#to_a.
|
||||
* extended method:
|
||||
* Hash#default_proc= can be passed nil to clear the default proc.
|
||||
|
||||
* IO
|
||||
* deprecated methods:
|
||||
* IO#lines, #bytes, #chars and #codepoints are deprecated.
|
||||
|
||||
* Kernel
|
||||
* added method:
|
||||
* added Kernel#Hash conversion method like Array() or Float().
|
||||
* added Kernel#__dir__ which returns a current dirname.
|
||||
* added Kernel#caller_locations which returns an array of
|
||||
frame information objects.
|
||||
* extended method:
|
||||
* Kernel#warn accepts multiple args in like puts.
|
||||
* Kernel#caller accepts second optional argument `n' which specify
|
||||
required caller size.
|
||||
* Kernel#to_enum and enum_for accept a block for lazy size evaluation.
|
||||
* incompatible changes:
|
||||
* system() and exec() closes non-standard file descriptors
|
||||
(The default of :close_others option is changed to true by default.)
|
||||
* respond_to? against a protected method now returns false unless
|
||||
the second argument is true.
|
||||
* __callee__ has returned to the original behavior, and now
|
||||
returns the called name but not the original name in an
|
||||
aliased method.
|
||||
* Kernel#inspect does not call #to_s anymore
|
||||
(it used to call redefined #to_s).
|
||||
|
||||
* LoadError
|
||||
* added method:
|
||||
* added LoadError#path method to return the file name that could not be
|
||||
loaded.
|
||||
|
||||
* Module
|
||||
* added method:
|
||||
* added Module#prepend which is similar to Module#include,
|
||||
however a method in the prepended module overrides the
|
||||
corresponding method in the prepending module.
|
||||
* added Module#refine, which extends a class or module locally.
|
||||
[experimental]
|
||||
* extended method:
|
||||
* Module#define_method accepts a UnboundMethod from a Module.
|
||||
* Module#const_get accepts a qualified constant string, e.g.
|
||||
Object.const_get("Foo::Bar::Baz")
|
||||
|
||||
* Mutex
|
||||
* added method:
|
||||
* added Mutex#owned? which returns the mutex is held by current
|
||||
thread or not. [experimental]
|
||||
* incompatible changes:
|
||||
* Mutex#lock, Mutex#unlock, Mutex#try_lock, Mutex#synchronize
|
||||
and Mutex#sleep are no longer allowed to be used from trap handler
|
||||
and raise a ThreadError in such case.
|
||||
* Mutex#sleep may spurious wakeup. Check after wakeup.
|
||||
|
||||
* NilClass
|
||||
* added method:
|
||||
* added nil.to_h which returns {}
|
||||
|
||||
* Process
|
||||
* added method:
|
||||
* added getsid for getting session id (unix only).
|
||||
|
||||
* Range
|
||||
* added method:
|
||||
* added Range#size for lazy size evaluation.
|
||||
* added Range#bsearch for binary search.
|
||||
|
||||
* RubyVM (MRI specific)
|
||||
* added Environment variables to specify stack usage:
|
||||
* RUBY_THREAD_VM_STACK_SIZE: vm stack size used at thread creation.
|
||||
default: 128KB (32bit CPU) or 256KB (64bit CPU).
|
||||
* RUBY_THREAD_MACHINE_STACK_SIZE: machine stack size used at thread
|
||||
creation. default: 512KB or 1024KB.
|
||||
* RUBY_FIBER_VM_STACK_SIZE: vm stack size used at fiber creation.
|
||||
default: 64KB or 128KB.
|
||||
* RUBY_FIBER_MACHINE_STACK_SIZE: machine stack size used at fiber
|
||||
creation. default: 256KB or 256KB.
|
||||
These variables are checked only at launched time.
|
||||
* added constant DEFAULT_PARAMS to get above default parameters.
|
||||
|
||||
* Signal
|
||||
* added method:
|
||||
* added Signal.signame which returns signal name
|
||||
|
||||
* incompatible changes:
|
||||
* Signal.trap raises ArgumentError when :SEGV, :BUS, :ILL, :FPE, :VTALRM
|
||||
are specified.
|
||||
|
||||
* String
|
||||
* added method:
|
||||
* added String#b returning a copied string whose encoding is ASCII-8BIT.
|
||||
* change return value:
|
||||
* String#lines now returns an array instead of an enumerator.
|
||||
* String#chars now returns an array instead of an enumerator.
|
||||
* String#codepoints now returns an array instead of an enumerator.
|
||||
* String#bytes now returns an array instead of an enumerator.
|
||||
|
||||
* Struct
|
||||
* added method:
|
||||
* added Struct#to_h returning values with keys corresponding to the
|
||||
instance variable names.
|
||||
|
||||
* Thread
|
||||
* added method:
|
||||
* added Thread#thread_variable_get for getting thread local variables
|
||||
(these are different than Fiber local variables).
|
||||
* added Thread#thread_variable_set for setting thread local variables.
|
||||
* added Thread#thread_variables for getting a list of the thread local
|
||||
variable keys.
|
||||
* added Thread#thread_variable? for testing to see if a particular thread
|
||||
variable has been set.
|
||||
* added Thread#backtrace_locations which returns similar information of
|
||||
Kernel#caller_locations.
|
||||
* incompatible changes:
|
||||
* Thread#join and Thread#value now raises a ThreadError if target thread
|
||||
is the current or main thread.
|
||||
|
||||
* Time
|
||||
* change return value:
|
||||
* Time#to_s returned encoding defaults to US-ASCII but automatically
|
||||
transcodes to Encoding.default_internal if it is set.
|
||||
|
||||
* TracePoint
|
||||
* new class. This class is replacement of set_trace_func.
|
||||
Easy to use and efficient implementation.
|
||||
|
||||
* toplevel
|
||||
* added method:
|
||||
* added main.define_method which defines a global function.
|
||||
* added main.using, which imports refinements into the current file or
|
||||
eval string. [experimental]
|
||||
|
||||
* cgi
|
||||
* Add HTML5 tag maker.
|
||||
* CGI#header has been renamed to CGI#http_header and
|
||||
aliased to CGI#header.
|
||||
* When HTML5 tagmaker called, overwrite CGI#header,
|
||||
CGI#header function is to create a <header> element.
|
||||
|
||||
* iconv
|
||||
* Iconv has been removed. Use String#encode instead.
|
||||
|
||||
* io/wait
|
||||
* new features:
|
||||
* added IO#wait_writable method.
|
||||
* added IO#wait_readable method as alias of IO#wait.
|
||||
|
||||
* net/http
|
||||
* new features:
|
||||
* Proxies are now automatically detected from the http_proxy environment
|
||||
variable. See Net::HTTP::new for details.
|
||||
* gzip and deflate compression are now requested for all requests by
|
||||
default. See Net::HTTP for details.
|
||||
* SSL sessions are now reused across connections for a single instance.
|
||||
This speeds up connection by using a previously negotiated session.
|
||||
* Requests may be created from a URI which sets the request_uri and host
|
||||
header of the request (but does not change the host connected to).
|
||||
* Responses contain the URI requested which allows easier implementation of
|
||||
redirect following.
|
||||
* new methods:
|
||||
* Net::HTTP#local_host
|
||||
* Net::HTTP#local_host=
|
||||
* Net::HTTP#local_port
|
||||
* Net::HTTP#local_port=
|
||||
* extended method:
|
||||
* Net::HTTP#connect uses local_host and local_port if specified.
|
||||
|
||||
* net/imap
|
||||
* new methods:
|
||||
* Net::IMAP.default_port
|
||||
* Net::IMAP.default_imap_port
|
||||
* Net::IMAP.default_tls_port
|
||||
* Net::IMAP.default_ssl_port
|
||||
* Net::IMAP.default_imaps_port
|
||||
|
||||
* objspace
|
||||
* new method:
|
||||
* ObjectSpace.reachable_objects_from(obj)
|
||||
|
||||
* openssl
|
||||
* Consistently raise an error when trying to encode nil values. All instances
|
||||
of OpenSSL::ASN1::Primitive now raise TypeError when calling to_der on an
|
||||
instance whose value is nil. All instances of OpenSSL::ASN1::Constructive
|
||||
raise NoMethodError in the same case. Constructing such values is still
|
||||
permitted.
|
||||
* TLS 1.1 & 1.2 support by setting OpenSSL::SSL::SSLContext#ssl_version to
|
||||
:TLSv1_2, :TLSv1_2_server, :TLSv1_2_client or :TLSv1_1, :TLSv1_1_server
|
||||
:TLSv1_1_client. The version being effectively used can be queried
|
||||
with OpenSSL::SSL#ssl_version. Furthermore, it is also possible to
|
||||
blacklist the new TLS versions with OpenSSL::SSL:OP_NO_TLSv1_1 and
|
||||
OpenSSL::SSL::OP_NO_TLSv1_2.
|
||||
* Added OpenSSL::SSL::SSLContext#renegotiation_cb. A user-defined callback
|
||||
may be set which gets called whenever a new handshake is negotiated. This
|
||||
also allows to programmatically decline (client) renegotiation attempts.
|
||||
* Support for "0/n" splitting of records as BEAST mitigation via
|
||||
OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS.
|
||||
* The default options for OpenSSL::SSL::SSLContext have changed to
|
||||
OpenSSL::SSL::OP_ALL & ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
|
||||
instead of OpenSSL::SSL::OP_ALL only. This enables the countermeasure for
|
||||
the BEAST attack by default.
|
||||
* OpenSSL requires passwords for decrypting PEM-encoded files to be at least
|
||||
four characters long. This led to awkward situations where an export with
|
||||
a password with fewer than four characters was possible, but accessing the
|
||||
file afterwards failed. OpenSSL::PKey::RSA, OpenSSL::PKey::DSA and
|
||||
OpenSSL::PKey::EC therefore now enforce the same check when exporting a
|
||||
private key to PEM with a password - it has to be at least four characters
|
||||
long.
|
||||
* SSL/TLS support for the Next Protocol Negotiation extension. Supported
|
||||
with OpenSSL 1.0.1 and higher.
|
||||
* OpenSSL::OPENSSL_FIPS allows client applications to detect whether OpenSSL
|
||||
is FIPS-enabled. OpenSSL.fips_mode= allows turning on and off FIPS mode
|
||||
manually in order to adapt to situations where FIPS mode would be an
|
||||
explicit requirement.
|
||||
* Authenticated Encryption with Associated Data (AEAD) is supported via
|
||||
Cipher#auth_data= and Cipher#auth_tag/Cipher#auth_tag=.
|
||||
Currently (OpenSSL 1.0.1c), only GCM mode is supported.
|
||||
|
||||
* ostruct
|
||||
* new methods:
|
||||
* OpenStruct#[], []=
|
||||
* OpenStruct#each_pair
|
||||
* OpenStruct#eql?
|
||||
* OpenStruct#hash
|
||||
* OpenStruct#to_h converts the struct to a hash.
|
||||
* extended method:
|
||||
* OpenStruct.new also accepts an OpenStruct / Struct.
|
||||
|
||||
* pathname
|
||||
* extended method:
|
||||
* Pathname#find returns an enumerator if no block is given.
|
||||
|
||||
* rake
|
||||
* rake has been updated to version 0.9.5.
|
||||
|
||||
This version is backwards-compatible with previous rake versions and
|
||||
contains many bug fixes.
|
||||
|
||||
See
|
||||
http://rake.rubyforge.org/doc/release_notes/rake-0_9_5_rdoc.html for a list
|
||||
of changes in rake 0.9.3, 0.9.4 and 0.9.5.
|
||||
|
||||
* rdoc
|
||||
* rdoc has been updated to version 4.0
|
||||
|
||||
This version is largely backwards-compatible with previous rdoc versions.
|
||||
The most notable change is an update to the ri data format (ri data must
|
||||
be regenerated for gems shared across rdoc versions). Further API changes
|
||||
are internal and won't affect most users.
|
||||
|
||||
See https://github.com/rdoc/rdoc/blob/master/History.rdoc for a list of
|
||||
changes in rdoc 4.0.
|
||||
|
||||
* resolv
|
||||
* new methods:
|
||||
* Resolv::DNS#timeouts=
|
||||
* Resolv::DNS::Config#timeouts=
|
||||
|
||||
* rexml
|
||||
* REXML::Document#write supports Hash arguments.
|
||||
* REXML::Document#write supports new :encoding option. It changes
|
||||
XML document encoding. Without :encoding option, encoding in
|
||||
XML declaration is used for XML document encoding.
|
||||
|
||||
* RubyGems
|
||||
* Updated to 2.0.0.preview2
|
||||
|
||||
RubyGems 2.0.0 features the following improvements:
|
||||
|
||||
* Improved support for default gems shipping with ruby 2.0.0+
|
||||
* A gem can have arbitrary metadata through Gem::Specification#metadata
|
||||
* `gem search` now defaults to --remote and is anchored like gem list.
|
||||
* Added --document to replace --rdoc and --ri. Use --no-document to
|
||||
disable documentation, --document=rdoc to only generate rdoc.
|
||||
* Only ri-format documentation is generated by default.
|
||||
* `gem server` uses RDoc::Servlet from RDoc 4.0 to generate HTML
|
||||
documentation.
|
||||
|
||||
For an expanded list of updates and bug fixes see:
|
||||
https://github.com/rubygems/rubygems/blob/master/History.txt
|
||||
|
||||
* shellwords
|
||||
* Shellwords#shellescape() now stringifies the given object using to_s.
|
||||
* Shellwords#shelljoin() accepts non-string objects in the given
|
||||
array, each of which is stringified using to_s.
|
||||
|
||||
* stringio
|
||||
* deprecated methods:
|
||||
* StringIO#lines, #bytes, #chars and #codepoints are deprecated.
|
||||
|
||||
* syslog
|
||||
* Added Syslog::Logger which provides a Logger API atop Syslog.
|
||||
* Syslog::Priority, Syslog::Level, Syslog::Option and Syslog::Macros
|
||||
are introduced for easy detection of available constants on a
|
||||
running system.
|
||||
|
||||
* tmpdir
|
||||
* incompatible changes:
|
||||
* Dir.mktmpdir uses FileUtils.remove_entry instead of
|
||||
FileUtils.remove_entry_secure. This means that applications should not
|
||||
change the permission of the created temporary directory to make
|
||||
accessible from other users.
|
||||
|
||||
* yaml
|
||||
* Syck has been removed. YAML now completely depends on libyaml being
|
||||
installed.
|
||||
|
||||
* zlib
|
||||
* Added streaming support for Zlib::Inflate and Zlib::Deflate. This allows
|
||||
processing of a stream without the use of large amounts of memory.
|
||||
* Added support for the new deflate strategies Zlib::RLE and Zlib::FIXED.
|
||||
* Zlib streams are now processed without the GVL. This allows gzip, zlib and
|
||||
deflate streams to be processed in parallel.
|
||||
* deprecated methods:
|
||||
* Zlib::GzipReader#lines and #bytes are deprecated.
|
||||
== Changes since the 2.0.0 release
|
||||
|
||||
=== Language changes
|
||||
|
||||
* Added %i and %I for symbol list creation (similar to %w and %W).
|
||||
* Now the default values of keyword arguments can be omitted. Those
|
||||
"required keyword arguments" need giving explicitly at the call time.
|
||||
|
||||
* Default source encoding is changed to UTF-8. (was US-ASCII)
|
||||
* Added suffixes for integer and float literals: 'r', 'i', and 'ri'.
|
||||
* "42r" and "3.14r" are evaluated as Rational(42, 1) and 3.14.rationalize,
|
||||
respectively. But exponential form with 'r' suffix like "6.022e+23r" is
|
||||
not accepted because it is misleading.
|
||||
* "42i" and "3.14i" are evaluated as Complex(0, 42) and Complex(0, 3.14),
|
||||
respectively.
|
||||
* "42ri" and "3.14ri" are evaluated as Complex(0, 42r) and Complex(0, 3.14r),
|
||||
respectively.
|
||||
|
||||
=== Compatibility issues (excluding feature bug fixes)
|
||||
* def-expr now returns the symbol of its name instead of nil.
|
||||
|
||||
* Array#values_at
|
||||
=== Core classes updates (outstanding ones only)
|
||||
|
||||
See above.
|
||||
* Array
|
||||
* New methods
|
||||
* Array#to_h converts an array of key-value pairs into a Hash.
|
||||
|
||||
* String#lines
|
||||
* String#chars
|
||||
* String#codepoints
|
||||
* String#bytes
|
||||
* Binding
|
||||
* New methods
|
||||
* Binding#local_variable_get(symbol)
|
||||
* Binding#local_variable_set(symbol, obj)
|
||||
* Binding#local_variable_defined?(symbol)
|
||||
|
||||
These methods no longer return an Enumerator, although passing a
|
||||
block is still supported for backwards compatibility.
|
||||
* Enumerable
|
||||
* New methods
|
||||
* Enumerable#to_h converts a list of key-value pairs into a Hash.
|
||||
|
||||
Code like str.lines.with_index(1) { |line, lineno| ... } no longer
|
||||
works because str.lines returns an array. Replace lines with
|
||||
each_line in such cases.
|
||||
* Exception
|
||||
* New methods
|
||||
* Exception#cause provides the previous exception which has been caught
|
||||
at where raising the new exception.
|
||||
|
||||
* IO#lines
|
||||
* IO#chars
|
||||
* IO#codepoints
|
||||
* IO#bytes
|
||||
* ARGF#lines
|
||||
* ARGF#chars
|
||||
* ARGF#codepoints
|
||||
* ARGF#bytes
|
||||
* StringIO#lines
|
||||
* StringIO#chars
|
||||
* StringIO#codepoints
|
||||
* StringIO#bytes
|
||||
* Zlib::GzipReader#lines
|
||||
* Zlib::GzipReader#bytes
|
||||
* GC
|
||||
* improvements:
|
||||
* introduced the generational GC a.k.a RGenGC.
|
||||
* added environment variables:
|
||||
* RUBY_GC_HEAP_INIT_SLOTS
|
||||
* RUBY_GC_HEAP_FREE_SLOTS
|
||||
* RUBY_GC_HEAP_GROWTH_FACTOR
|
||||
* RUBY_GC_HEAP_GROWTH_MAX_SLOTS
|
||||
* RUBY_GC_MALLOC_LIMIT_MAX
|
||||
* RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR
|
||||
* RUBY_GC_OLDMALLOC_LIMIT
|
||||
* RUBY_GC_OLDMALLOC_LIMIT_MAX
|
||||
* RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR
|
||||
* obsoleted environment variables:
|
||||
* RUBY_FREE_MIN (Use RUBY_GC_HEAP_FREE_SLOTS instead)
|
||||
* RUBY_HEAP_MIN_SLOTS (Use RUBY_GC_HEAP_INIT_SLOTS instead)
|
||||
|
||||
These methods are deprecated in favor of each_line, each_byte,
|
||||
each_char and each_codepoint.
|
||||
* Integer
|
||||
* New methods
|
||||
* Fixnum#bit_length
|
||||
* Bignum#bit_length
|
||||
* Bignum performance improvement
|
||||
* Use GMP if available.
|
||||
GMP is used only for several operations:
|
||||
multiplication, division, radix conversion, GCD
|
||||
|
||||
* Signal.trap
|
||||
* IO
|
||||
* extended methods:
|
||||
* IO#seek supports SEEK_DATA and SEEK_HOLE as whence.
|
||||
* IO#seek accepts symbols (:CUR, :END, :SET, :DATA, :HOLE) for 2nd argument.
|
||||
* IO#read_nonblock accepts optional `exception: false` to return symbols
|
||||
* IO#write_nonblock accepts optional `exception: false` to return symbols
|
||||
|
||||
See above.
|
||||
* Kernel
|
||||
* New methods:
|
||||
* Kernel#singleton_method
|
||||
|
||||
* Merge Onigmo.
|
||||
https://github.com/k-takata/Onigmo
|
||||
* Module
|
||||
* New methods:
|
||||
* Module#using, which activates refinements of the specified module only
|
||||
in the current class or module definition.
|
||||
* Module#singleton_class? returns true if the receiver is a singleton class
|
||||
or false if it is an ordinary class or module.
|
||||
* extended methods:
|
||||
* Module#refine is no longer experimental.
|
||||
* Module#include and Module#prepend are now public methods.
|
||||
|
||||
* The :close_others option is true by default for system() and exec().
|
||||
Also, the close-on-exec flag is set by default for all new file descriptors.
|
||||
This means file descriptors doesn't inherit to spawned process unless
|
||||
explicitly requested such as system(..., fd=>fd).
|
||||
* Mutex
|
||||
* misc
|
||||
* Mutex#owned? is no longer experimental.
|
||||
|
||||
* Kernel#respond_to? against a protected method now returns false
|
||||
unless the second argument is true.
|
||||
* Numeric
|
||||
* extended methods:
|
||||
* Numeric#step allows the limit argument to be omitted, in which
|
||||
case an infinite sequence of numbers is generated. Keyword
|
||||
arguments `to` and `by` are introduced for ease of use.
|
||||
|
||||
* Dir.mktmpdir in lib/tmpdir.rb
|
||||
* Process
|
||||
* New methods:
|
||||
* alternative methods to $0/$0=:
|
||||
* Process.argv0() returns the original value of $0.
|
||||
* Process.setproctitle() sets the process title without affecting $0.
|
||||
* Process.clock_gettime
|
||||
* Process.clock_getres
|
||||
|
||||
See above.
|
||||
* String
|
||||
* New methods:
|
||||
* String#scrub and String#scrub! verify and fix invalid byte sequence.
|
||||
If you want to use this function with older Ruby,
|
||||
consider to use string-scrub.gem.
|
||||
|
||||
* OpenStruct new methods can conflict with custom attributes named
|
||||
"each_pair", "eql?", "hash" or "to_h".
|
||||
* Symbol
|
||||
* All symbols are now frozen.
|
||||
|
||||
* Thread#join, Thread#value
|
||||
* pack/unpack (Array/String)
|
||||
* Q! and q! directives for long long type if platform has the type.
|
||||
|
||||
See above.
|
||||
* toplevel
|
||||
* extended methods:
|
||||
* main.using is no longer experimental. The method activates refinements
|
||||
in the ancestors of the argument module to support refinement
|
||||
inheritance by Module#include.
|
||||
|
||||
* Mutex#lock, Mutex#unlock, Mutex#try_lock, Mutex#synchronize and Mutex#sleep
|
||||
=== Core classes compatibility issues (excluding feature bug fixes)
|
||||
|
||||
See above.
|
||||
* Hash
|
||||
* incompatible changes:
|
||||
* Hash#reject will return plain Hash object in the future versions, that
|
||||
is the original object's subclass, instance variables, default value,
|
||||
and taintedness will be no longer copied, so now warnings are emitted
|
||||
when called with such Hash.
|
||||
|
||||
* IO
|
||||
* incompatible changes:
|
||||
* open ignore internal encoding if external encoding is ASCII-8BIT.
|
||||
|
||||
* Kernel#eval, Kernel#instance_eval, and Module#module_eval.
|
||||
* Copies the scope information of the original environment, which means
|
||||
that private, protected, public, and module_function without arguments
|
||||
do not affect the environment outside the eval string.
|
||||
For example, `class Foo; eval "private"; def foo; end; end' doesn't make
|
||||
Foo#foo private.
|
||||
|
||||
* Kernel#untrusted?, untrust, and trust
|
||||
* These methods are deprecated and their behavior is same as tainted?,
|
||||
taint, and untaint, respectively. If $VERBOSE is true, they show warnings.
|
||||
|
||||
* Module#ancestors
|
||||
* The ancestors of a singleton class now include singleton classes,
|
||||
in particular itself.
|
||||
|
||||
* Module#define_method and Object#define_singleton_method
|
||||
* Now they return the symbols of the defined methods, not the methods/procs
|
||||
themselves.
|
||||
|
||||
* Numeric#quo
|
||||
* Raises TypeError instead of ArgumentError if the receiver doesn't have
|
||||
to_r method.
|
||||
|
||||
* Proc
|
||||
* Returning from lambda proc now always exits from the Proc, not from the
|
||||
method where the lambda is created. Returning from non-lambda proc exits
|
||||
from the method, same as the former behavior.
|
||||
|
||||
String
|
||||
* If invalid: :replace is specified for String#encode, replace
|
||||
invalid byte sequence even if the destination encoding equals to
|
||||
the source encoding.
|
||||
|
||||
=== Stdlib updates (outstanding ones only)
|
||||
|
||||
* CGI::Util
|
||||
* All class methods modulized.
|
||||
|
||||
* Digest
|
||||
* extended methods:
|
||||
* Digest::Class.file takes optional arguments for its constructor
|
||||
|
||||
* Matrix
|
||||
* Added Vector#cross_product.
|
||||
|
||||
* Net::SMTP
|
||||
* Added Net::SMTP#rset to implement the RSET command
|
||||
|
||||
* objspace
|
||||
* new method:
|
||||
* ObjectSpace.trace_object_allocations
|
||||
* ObjectSpace.trace_object_allocations_start
|
||||
* ObjectSpace.trace_object_allocations_stop
|
||||
* ObjectSpace.trace_object_allocations_clear
|
||||
* ObjectSpace.allocation_sourcefile
|
||||
* ObjectSpace.allocation_sourceline
|
||||
* ObjectSpace.allocation_class_path
|
||||
* ObjectSpace.allocation_method_id
|
||||
* ObjectSpace.allocation_generation
|
||||
* ObjectSpace.reachable_objects_from_root
|
||||
* ObjectSpace.dump
|
||||
* ObjectSpace.dump_all
|
||||
|
||||
* OpenSSL::BN
|
||||
* extended methods:
|
||||
* OpenSSL::BN.new allows Fixnum/Bignum argument.
|
||||
|
||||
* open-uri
|
||||
* Support multiple fields with same field name (like Set-Cookie).
|
||||
|
||||
* Pathname
|
||||
* New methods:
|
||||
* Pathname#write
|
||||
* Pathname#binwrite
|
||||
|
||||
* rake
|
||||
* Updated to 10.1.0. Major changes include removal of the class namespace,
|
||||
Rake::DSL to hold the rake DSL methods and removal of support for legacy
|
||||
rake features.
|
||||
|
||||
For a complete list of changes since rake 0.9.6 see:
|
||||
|
||||
http://rake.rubyforge.org/doc/release_notes/rake-10_1_0_rdoc.html
|
||||
|
||||
http://rake.rubyforge.org/doc/release_notes/rake-10_0_3_rdoc.html
|
||||
|
||||
* RbConfig
|
||||
* New constants:
|
||||
* RbConfig::SIZEOF is added to provide the size of C types.
|
||||
|
||||
* RDoc
|
||||
* Updated to 4.1.0. Major enhancements include a modified default template
|
||||
* and accessibility enhancements.
|
||||
|
||||
For a list of minor enhancements and bug fixes see:
|
||||
https://github.com/rdoc/rdoc/blob/v4.1.0.preview.1/History.rdoc
|
||||
|
||||
* Resolv
|
||||
* New methods:
|
||||
* Resolv::DNS.fetch_resource
|
||||
* One-shot multicast DNS support
|
||||
* Support LOC resources
|
||||
|
||||
* REXML::Parsers::SAX2Parser
|
||||
* Fixes wrong number of arguments of entitydecl event. Document of the event
|
||||
says "an array of the entity declaration" but implementation passes two
|
||||
or more arguments. It is an implementation bug but it breaks backword
|
||||
compatibility.
|
||||
|
||||
* REXML::Parsers::StreamParser
|
||||
* Supports "entity" event.
|
||||
|
||||
* REXML::Text
|
||||
* REXML::Text#<< supports method chain like 'text << "XXX" << "YYY"'.
|
||||
* REXML::Text#<< supports not "raw" mode.
|
||||
|
||||
* Rinda::RingServer, Rinda::RingFinger
|
||||
* Rinda now supports multicast sockets. See Rinda::RingServer and
|
||||
Rinda::RingFinger for details.
|
||||
|
||||
* RubyGems
|
||||
* Updated to 2.2.0. Notable new features include:
|
||||
|
||||
* Gemfile or gem.deps.rb support including Gem.file.lock (experimental)
|
||||
* Improved, iterative resolver (compared to RubyGems 2.1 and earlier)
|
||||
* Support for a sharing a GEM_HOME across ruby platforms and versions
|
||||
|
||||
For a complete list of enhancements and bug fixes see:
|
||||
https://github.com/rubygems/rubygems/tree/master/History.txt
|
||||
|
||||
* Set
|
||||
* New methods:
|
||||
* Set#intersect?
|
||||
* Set#disjoint?
|
||||
|
||||
* Socket
|
||||
* New methods:
|
||||
* Socket.getifaddrs
|
||||
|
||||
* StringScanner
|
||||
* extended methods:
|
||||
* StringScanner#[] supports named captures.
|
||||
|
||||
* Syslog::Logger
|
||||
* Added facility.
|
||||
|
||||
* Tempfile
|
||||
* New methods:
|
||||
* Tempfile.create
|
||||
|
||||
* Timeout
|
||||
* The exception to terminate the given block can no longer be rescued
|
||||
inside the block, by default, unless the exception class is given
|
||||
explicitly.
|
||||
|
||||
* TSort
|
||||
* New methods:
|
||||
* TSort.tsort
|
||||
* TSort.tsort_each
|
||||
* TSort.strongly_connected_components
|
||||
* TSort.each_strongly_connected_component
|
||||
* TSort.each_strongly_connected_component_from
|
||||
|
||||
* WEBrick
|
||||
* The body of a response may now be a StringIO or other IO-like that responds
|
||||
to #readpartial and #read.
|
||||
|
||||
* XMLRPC::Client
|
||||
* New methods:
|
||||
* XMLRPC::Client#http. It returns Net::HTTP for the client. Normally,
|
||||
it is not needed. It is useful when you want to change minor HTTP client
|
||||
options. You can change major HTTP client options by XMLRPC::Client
|
||||
methods. You should use XMLRPC::Client methods for changing major
|
||||
HTTP client options instead of XMLRPC::Client#http.
|
||||
|
||||
=== Stdlib compatibility issues (excluding feature bug fixes)
|
||||
|
||||
* Set
|
||||
* incompatible changes:
|
||||
* Set#to_set now returns self instead of generating a copy.
|
||||
|
||||
* URI
|
||||
* incompatible changes:
|
||||
* URI.decode_www_form follows current WHATWG URL Standard.
|
||||
It gets encoding argument to specify the character encoding.
|
||||
It now allows loose percent encoded strings, but denies ;-separator.
|
||||
* URI.encode_www_form follows current WHATWG URL Standard.
|
||||
It gets encoding argument to convert before percent encode.
|
||||
UTF-16 strings aren't converted to UTF-8 before percent encode by default.
|
||||
|
||||
* curses
|
||||
* Removed.
|
||||
curses is now available as a gem.
|
||||
See https://rubygems.org/gems/curses for details.
|
||||
|
||||
=== Built-in global variables compatibility issues
|
||||
|
||||
* $SAFE
|
||||
* $SAFE=4 is obsolete. If $SAFE is set to 4 or larger, an ArgumentError
|
||||
is raised.
|
||||
|
||||
=== C API updates
|
||||
|
||||
* rb_gc_set_params() is deprecated. This is only used in Ruby internal.
|
||||
|
||||
* rb_gc_count() added. This returns the number of times GC occurred.
|
||||
|
||||
* rb_gc_stat() added. This allows access to specific GC.stat() values from C
|
||||
without any allocation overhead.
|
||||
|
||||
* rb_gc_latest_gc_info() added. This allows access to GC.latest_gc_info().
|
||||
|
||||
* rb_postponed_job_register() added. Takes a function callback which is invoked
|
||||
when the VM is in a consistent state, i.e. to perform work from a C signal
|
||||
handler.
|
||||
|
||||
* rb_profile_frames() added. Provides low-cost access to the current ruby stack
|
||||
for callstack profiling.
|
||||
|
||||
* rb_tracepoint_new() supports new internal events accessible only from C:
|
||||
* RUBY_INTERNAL_EVENT_NEWOBJ
|
||||
* RUBY_INTERNAL_EVENT_FREEOBJ
|
||||
* RUBY_INTERNAL_EVENT_GC_START
|
||||
* RUBY_INTERNAL_EVENT_GC_END_MARK
|
||||
* RUBY_INTERNAL_EVENT_GC_END_SWEEP
|
||||
* Note that you *can not* specify "internal events" with normal events
|
||||
(such as RUBY_EVENT_CALL, RUBY_EVENT_RETURN) simultaneously.
|
||||
|
|
25
README
25
README
|
@ -23,6 +23,11 @@ Perl). It is simple, straight-forward, and extensible.
|
|||
|
||||
== How to get Ruby
|
||||
|
||||
For a complete list of ways to install Ruby, including using third party
|
||||
tools like rvm, see:
|
||||
|
||||
http://www.ruby-lang.org/en/downloads/
|
||||
|
||||
The Ruby distribution files can be found in the following FTP site:
|
||||
|
||||
ftp://ftp.ruby-lang.org/pub/ruby/
|
||||
|
@ -32,7 +37,7 @@ following command:
|
|||
|
||||
$ svn co http://svn.ruby-lang.org/repos/ruby/trunk/ ruby
|
||||
|
||||
Or if you are using git then use following command:
|
||||
Or if you are using git then use the following command:
|
||||
|
||||
$ git clone git://github.com/ruby/ruby.git
|
||||
|
||||
|
@ -41,7 +46,7 @@ command and see the list of branches:
|
|||
|
||||
$ svn ls http://svn.ruby-lang.org/repos/ruby/branches/
|
||||
|
||||
Or if you are using git then use following command:
|
||||
Or if you are using git then use the following command:
|
||||
|
||||
$ git ls-remote git://github.com/ruby/ruby.git
|
||||
|
||||
|
@ -132,21 +137,29 @@ This is what you need to do to compile and install Ruby:
|
|||
If you fail to compile ruby, please send the detailed error report with
|
||||
the error log and machine/OS type, to help others.
|
||||
|
||||
Some extension libraries may not get compiled because of lack of
|
||||
necessary external libraries and/or headers, then you will need to run
|
||||
'<tt>make distclean-ext</tt>' to remove old configuration after
|
||||
installing them in such case.
|
||||
|
||||
== Copying
|
||||
|
||||
See the file +COPYING+.
|
||||
|
||||
== Feedback
|
||||
|
||||
Questions about the Ruby language can be asked on the Ruby-Talk mailing list
|
||||
(http://www.ruby-lang.org/en/community/mailing-lists) or on websites like
|
||||
(http://stackoverflow.com).
|
||||
|
||||
Bug reports should be filed at http://bugs.ruby-lang.org
|
||||
|
||||
== The Author
|
||||
|
||||
Feel free to send comments and bug reports to the author. Here is the
|
||||
author's latest mail address:
|
||||
Ruby was originally designed and developed by Yukihiro Matsumoto (Matz) in 1995.
|
||||
|
||||
<mailto:matz@ruby-lang.org>
|
||||
|
||||
-------------------------------------------------------
|
||||
created at: Thu Aug 3 11:57:36 JST 1995
|
||||
--
|
||||
Local variables:
|
||||
mode: rdoc
|
||||
|
|
55
README.EXT
55
README.EXT
|
@ -125,12 +125,15 @@ Other data types have corresponding C structures, e.g. struct RArray
|
|||
for T_ARRAY etc. The VALUE of the type which has the corresponding
|
||||
structure can be cast to retrieve the pointer to the struct. The
|
||||
casting macro will be of the form RXXXX for each data type; for
|
||||
instance, RARRAY(obj). See "ruby.h".
|
||||
instance, RARRAY(obj). See "ruby.h". However, we do not recommend
|
||||
to access RXXXX data directly because these data structure is complex.
|
||||
Use corresponding rb_xxx() functions to access internal struct.
|
||||
For example, to access an entry of array, use rb_ary_entry(ary, offset)
|
||||
and rb_ary_store(ary, offset, obj).
|
||||
|
||||
There are some accessing macros for structure members, for example
|
||||
`RSTRING_LEN(str)' to get the size of the Ruby String object. The
|
||||
allocated region can be accessed by `RSTRING_PTR(str)'. For arrays,
|
||||
use `RARRAY_LEN(ary)' and `RARRAY_PTR(ary)' respectively.
|
||||
allocated region can be accessed by `RSTRING_PTR(str)'.
|
||||
|
||||
Notice: Do not change the value of the structure directly, unless you
|
||||
are responsible for the result. This ends up being the cause of
|
||||
|
@ -196,6 +199,10 @@ rb_vsprintf(const char *format, va_list ap) ::
|
|||
|
||||
Creates a new Ruby string with printf(3) format.
|
||||
|
||||
Note: In the format string, %i is used for Object#to_s (or Object#inspect if
|
||||
'+' flag is set) output (and related argument must be a VALUE). For integers
|
||||
in format strings, use %d.
|
||||
|
||||
rb_str_cat(VALUE str, const char *ptr, long len) ::
|
||||
|
||||
Appends len bytes of data from ptr to the Ruby string.
|
||||
|
@ -214,6 +221,7 @@ rb_str_vcatf(VALUE str, const char* format, va_list ap) ::
|
|||
rb_str_cat2(str, rb_vsprintf(format, ap)), respectively.
|
||||
|
||||
rb_enc_str_new(const char *ptr, long len, rb_encoding *enc) ::
|
||||
rb_enc_str_new_cstr(const char *ptr, rb_encoding *enc) ::
|
||||
|
||||
Creates a new Ruby string with the specified encoding.
|
||||
|
||||
|
@ -246,15 +254,18 @@ rb_ary_new() ::
|
|||
Creates an array with no elements.
|
||||
|
||||
rb_ary_new2(long len) ::
|
||||
rb_ary_new_capa(long len) ::
|
||||
|
||||
Creates an array with no elements, allocating internal buffer
|
||||
for len elements.
|
||||
|
||||
rb_ary_new3(long n, ...) ::
|
||||
rb_ary_new_from_args(long n, ...) ::
|
||||
|
||||
Creates an n-element array from the arguments.
|
||||
|
||||
rb_ary_new4(long n, VALUE *elts) ::
|
||||
rb_ary_new_from_values(long n, VALUE *elts) ::
|
||||
|
||||
Creates an n-element array from a C array.
|
||||
|
||||
|
@ -268,12 +279,16 @@ types are given.
|
|||
|
||||
rb_ary_aref(argc, VALUE *argv, VALUE ary) ::
|
||||
|
||||
Equivaelent to Array#[].
|
||||
Equivalent to Array#[].
|
||||
|
||||
rb_ary_entry(VALUE ary, long offset) ::
|
||||
|
||||
ary[offset]
|
||||
|
||||
rb_ary_store(VALUE ary, long offset, VALUE obj) ::
|
||||
|
||||
ary[offset] = obj
|
||||
|
||||
rb_ary_subseq(VALUE ary, long beg, long len) ::
|
||||
|
||||
ary[beg, len]
|
||||
|
@ -756,7 +771,7 @@ various conditions.
|
|||
check_sizeof(type[, headers[, opts]]): check size of type
|
||||
check_signedness(type[, headers[, opts]]): check signedness of type
|
||||
convertible_int(type[, headers[, opts]]): find convertible integer type
|
||||
find_executable(bin[, path]): find excutable file path
|
||||
find_executable(bin[, path]): find executable file path
|
||||
create_header(header): generate configured header
|
||||
create_makefile(target[, target_prefix]): generate Makefile
|
||||
|
||||
|
@ -849,7 +864,7 @@ lex.c :: automatically generated from keywords
|
|||
eval_safe.c
|
||||
insns.def : definition of VM instructions
|
||||
iseq.c : implementation of VM::ISeq
|
||||
thread.c : thread management and context swiching
|
||||
thread.c : thread management and context switching
|
||||
thread_win32.c : thread implementation
|
||||
thread_pthread.c : ditto
|
||||
vm.c
|
||||
|
@ -878,7 +893,7 @@ lex.c :: automatically generated from keywords
|
|||
|
||||
== Utility Functions
|
||||
|
||||
debug.c :: debug symbols for C debuggger
|
||||
debug.c :: debug symbols for C debugger
|
||||
dln.c :: dynamic loading
|
||||
st.c :: general purpose hash table
|
||||
strftime.c :: formatting times
|
||||
|
@ -1053,6 +1068,10 @@ NUM2SSIZET(value), SSIZET2NUM(ssize) ::
|
|||
|
||||
Numeric <-> ssize_t
|
||||
|
||||
rb_integer_pack(value, words, numwords, wordsize, nails, flags), rb_integer_unpack(words, numwords, wordsize, nails, flags) ::
|
||||
|
||||
Numeric <-> Arbitrary size integer buffer
|
||||
|
||||
NUM2DBL(value) ::
|
||||
|
||||
Numeric -> double
|
||||
|
@ -1235,10 +1254,18 @@ rb_scan_args(int argc, VALUE *argv, const char *fmt, ...) ::
|
|||
VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) ::
|
||||
|
||||
Invokes a method. To retrieve mid from a method name, use rb_intern().
|
||||
Able to call even private/protected methods.
|
||||
|
||||
VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv) ::
|
||||
VALUE rb_funcallv(VALUE recv, ID mid, int argc, VALUE *argv) ::
|
||||
|
||||
Invokes a method, passing arguments by an array of values.
|
||||
Invokes a method, passing arguments as an array of values.
|
||||
Able to call even private/protected methods.
|
||||
|
||||
VALUE rb_funcallv_public(VALUE recv, ID mid, int argc, VALUE *argv) ::
|
||||
|
||||
Invokes a method, passing arguments as an array of values.
|
||||
Able to call only public methods.
|
||||
|
||||
VALUE rb_eval_string(const char *str) ::
|
||||
|
||||
|
@ -1308,12 +1335,12 @@ VALUE rb_ensure(VALUE (*func1)(), VALUE arg1, VALUE (*func2)(), VALUE arg2) ::
|
|||
|
||||
Calls the function func1 with arg1 as the argument, then calls func2
|
||||
with arg2 if execution terminated. The return value from
|
||||
rb_ensure() is that of func1 when no exception occured.
|
||||
rb_ensure() is that of func1 when no exception occurred.
|
||||
|
||||
VALUE rb_protect(VALUE (*func) (VALUE), VALUE arg, int *state) ::
|
||||
|
||||
Calls the function func with arg as the argument. If no exception
|
||||
occured during func, it returns the result of func and *state is zero.
|
||||
occurred during func, it returns the result of func and *state is zero.
|
||||
Otherwise, it returns Qnil and sets *state to nonzero. If state is
|
||||
NULL, it is not set in both cases.
|
||||
You have to clear the error info with rb_set_errinfo(Qnil) when
|
||||
|
@ -1366,6 +1393,10 @@ void rb_bug(const char *fmt, ...) ::
|
|||
called under the situation caused by the bug in the interpreter. No
|
||||
exception handling nor ensure execution will be done.
|
||||
|
||||
Note: In the format string, %i is used for Object#to_s (or Object#inspect if
|
||||
'+' flag is set) output (and related argument must be a VALUE). For integers
|
||||
in format strings, use %d.
|
||||
|
||||
== Initialize and Start the Interpreter
|
||||
|
||||
The embedding API functions are below (not needed for extension libraries):
|
||||
|
@ -1457,6 +1488,10 @@ RB_EVENT_HOOKS_HAVE_CALLBACK_DATA ::
|
|||
Means that rb_add_event_hook() takes the third argument `data', to be
|
||||
passed to the given event hook function.
|
||||
|
||||
= Appendix C. Functions available for use in extconf.rb
|
||||
|
||||
See documentation for {mkmf}[rdoc-ref:MakeMakefile].
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* fill-column: 70
|
||||
|
|
101
README.EXT.ja
101
README.EXT.ja
|
@ -140,13 +140,15 @@ var は lvalue である必要があります.
|
|||
あるのは文字列と配列くらいだと思います.
|
||||
|
||||
ruby.hでは構造体へキャストするマクロも「RXXXXX()」(全部大文
|
||||
字にしたもの)という名前で提供されています(例: RSTRING()).
|
||||
字にしたもの)という名前で提供されています(例: RSTRING()).た
|
||||
だし、構造体への直接のアクセスはできるだけ避け,対応する
|
||||
rb_xxxx() といった関数を使うようにして下さい.例えば,配列の
|
||||
要素へアクセスする場合は,rb_ary_entry(ary, offset),
|
||||
rb_ary_store(ary, offset, obj) を利用するようにして下さい.
|
||||
|
||||
構造体からデータを取り出すマクロが提供されています.文字列
|
||||
strの長さを得るためには「RSTRING_LEN(str)」とし,文字列strを
|
||||
char*として得るためには「RSTRING_PTR(str)」とします.配列の
|
||||
場合には,それぞれ「RARRAY_LEN(ary)」,「RARRAY_PTR(ary)」と
|
||||
なります.
|
||||
char*として得るためには「RSTRING_PTR(str)」とします.
|
||||
|
||||
Rubyの構造体を直接アクセスする時に気をつけなければならないこ
|
||||
とは,配列や文字列の構造体の中身は参照するだけで,直接変更し
|
||||
|
@ -193,7 +195,7 @@ INT2NUM()は整数がFIXNUMの範囲に収まらない場合,Bignumに変換
|
|||
Rubyが用意している関数を用いてください.
|
||||
|
||||
ここではもっとも使われるであろう文字列と配列の生成/操作を行
|
||||
い関数をあげます(全部ではないです).
|
||||
う関数をあげます(全部ではないです).
|
||||
|
||||
=== 文字列に対する関数
|
||||
|
||||
|
@ -224,6 +226,9 @@ rb_vsprintf(const char *format, va_list ap)
|
|||
Cの文字列formatと続く引数をprintf(3)のフォーマットにしたがって
|
||||
整形し,Rubyの文字列を生成する.
|
||||
|
||||
注意: %iはObject#to_s('+'フラグが指定されているときはObject#inspect)を
|
||||
使ったVALUEの出力に使用されているため,整数には%dを使用すること.
|
||||
|
||||
rb_str_cat(VALUE str, const char *ptr, long len)
|
||||
|
||||
Rubyの文字列strにlenバイトの文字列ptrを追加する.
|
||||
|
@ -242,6 +247,7 @@ rb_str_vcatf(VALUE str, const char* format, va_list ap)
|
|||
rb_str_cat2(str, rb_vsprintf(format, ap)) と同等である.
|
||||
|
||||
rb_enc_str_new(const char *ptr, long len, rb_encoding *enc)
|
||||
rb_enc_str_new_cstr(const char *ptr, rb_encoding *enc)
|
||||
|
||||
指定されたエンコーディングでRubyの文字列を生成する.
|
||||
|
||||
|
@ -274,15 +280,18 @@ rb_ary_new()
|
|||
要素が0の配列を生成する.
|
||||
|
||||
rb_ary_new2(long len)
|
||||
rb_ary_new_capa(long len)
|
||||
|
||||
要素が0の配列を生成する.len要素分の領域をあらかじめ割り
|
||||
当てておく.
|
||||
|
||||
rb_ary_new3(long n, ...)
|
||||
rb_ary_new_from_args(long n, ...)
|
||||
|
||||
引数で指定したn要素を含む配列を生成する.
|
||||
|
||||
rb_ary_new4(long n, VALUE *elts)
|
||||
rb_ary_new_from_values(long n, VALUE *elts)
|
||||
|
||||
配列で与えたn要素の配列を生成する.
|
||||
|
||||
|
@ -303,6 +312,10 @@ rb_ary_entry(VALUE ary, long offset)
|
|||
|
||||
ary[offset]
|
||||
|
||||
rb_ary_store(VALUE ary, long offset, VALUE obj) ::
|
||||
|
||||
ary[offset] = obj
|
||||
|
||||
rb_ary_subseq(VALUE ary, long beg, long len)
|
||||
|
||||
ary[beg, len]
|
||||
|
@ -521,6 +534,7 @@ Cから文字列を経由せずにRubyのメソッドを呼び出すためには
|
|||
します.その他に引数の指定の仕方が違う以下の関数もあります.
|
||||
|
||||
VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv)
|
||||
VALUE rb_funcallv(VALUE recv, ID mid, int argc, VALUE *argv)
|
||||
VALUE rb_apply(VALUE recv, ID mid, VALUE args)
|
||||
|
||||
applyには引数としてRubyの配列を与えます.
|
||||
|
@ -628,10 +642,9 @@ Dataオブジェクトを生成して構造体をRubyオブジェクトにカプ
|
|||
|
||||
このマクロの戻り値は生成されたDataオブジェクトです.
|
||||
|
||||
klassはこのDataオブジェクトのクラスです.ptrはカプセル化する
|
||||
Cの構造体へのポインタです.markはこの構造体がRubyのオブジェ
|
||||
クトへの参照がある時に使う関数です.そのような参照を含まない
|
||||
時には0を指定します.
|
||||
klassはこのDataオブジェクトのクラスです.markはこの構造体が
|
||||
Rubyのオブジェクトへの参照がある時に使う関数です.そのような
|
||||
参照を含まない時には0を指定します.
|
||||
|
||||
# そのような参照は勧められません.
|
||||
|
||||
|
@ -649,7 +662,10 @@ Cの構造体の割当とDataオブジェクトの生成を同時に行うマク
|
|||
|
||||
Data_Make_Struct(klass, type, mark, free, sval)
|
||||
|
||||
このマクロの戻り値は生成されたDataオブジェクトです.
|
||||
このマクロの戻り値は生成されたDataオブジェクトです.このマク
|
||||
ロは以下の式のように働きます:
|
||||
|
||||
(sval = ALLOC(type), Data_Wrap_Struct(klass, mark, free, sval))
|
||||
|
||||
klass, mark, freeはData_Wrap_Structと同じ働きをします.type
|
||||
は割り当てるC構造体の型です.割り当てられた構造体は変数sval
|
||||
|
@ -1099,6 +1115,7 @@ Data_Get_Struct(data, type, sval) ::
|
|||
NUM2OFFT(value), OFFT2NUM(off)
|
||||
NUM2SIZET(value), SIZET2NUM(size)
|
||||
NUM2SSIZET(value), SSIZET2NUM(ssize)
|
||||
rb_integer_pack(value, words, numwords, wordsize, nails, flags), rb_integer_unpack(words, numwords, wordsize, nails, flags)
|
||||
NUM2DBL(value)
|
||||
rb_float_new(f)
|
||||
StringValue(value)
|
||||
|
@ -1250,10 +1267,18 @@ VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) ::
|
|||
|
||||
メソッド呼び出し.文字列からmidを得るためにはrb_intern()を
|
||||
使う.
|
||||
private/protectedなメソッドでも呼び出せる.
|
||||
|
||||
VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv) ::
|
||||
VALUE rb_funcallv(VALUE recv, ID mid, int argc, VALUE *argv) ::
|
||||
|
||||
メソッド呼び出し.引数をargc, argv形式で渡す.
|
||||
private/protectedなメソッドでも呼び出せる.
|
||||
|
||||
VALUE rb_funcallv_public(VALUE recv, ID mid, int argc, VALUE *argv) ::
|
||||
|
||||
メソッド呼び出し.
|
||||
publicなメソッドしか呼べない.
|
||||
|
||||
VALUE rb_eval_string(const char *str)
|
||||
|
||||
|
@ -1379,6 +1404,9 @@ void rb_bug(const char *fmt, ...) ::
|
|||
状況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.
|
||||
例外処理は一切行なわれない.
|
||||
|
||||
注意: %iはObject#to_s('+'フラグが指定されているときはObject#inspect)を
|
||||
使ったVALUEの出力に使用されているため,整数には%dを使用すること.
|
||||
|
||||
== Rubyの初期化・実行
|
||||
|
||||
Rubyをアプリケーションに埋め込む場合には以下のインタフェース
|
||||
|
@ -1487,53 +1515,62 @@ have_macro(macro, headers) ::
|
|||
have_library(lib, func) ::
|
||||
|
||||
関数funcを定義しているライブラリlibの存在をチェックする.
|
||||
ライブラリが存在する時,trueを返す.
|
||||
チェックに成功すると,-llibを$libsに追加し,trueを返す.
|
||||
|
||||
find_library(lib, func, path...) ::
|
||||
|
||||
関数funcを定義しているライブラリlibの存在を -Lpath を追加
|
||||
しながらチェックする.ライブラリが見付かった時,trueを返す.
|
||||
しながらチェックする.チェックに成功すると,-llibを$libsに
|
||||
追加し,trueを返す.
|
||||
|
||||
have_func(func, header) ::
|
||||
|
||||
ヘッダファイルheaderをインクルードして関数funcの存在をチェ
|
||||
ックする.funcが標準ではリンクされないライブラリ内のもので
|
||||
ある時には先にhave_libraryでそのライブラリをチェックしてお
|
||||
く事.関数が存在する時trueを返す.
|
||||
く事.チェックに成功すると,プリプロセッサマクロ
|
||||
`HAVE_{FUNC}` を定義し,trueを返す.
|
||||
|
||||
have_var(var, header) ::
|
||||
|
||||
ヘッダファイルheaderをインクルードして変数varの存在をチェッ
|
||||
クする.varが標準ではリンクされないライブラリ内のものであ
|
||||
る時には先にhave_libraryでそのライブラリをチェックしておく
|
||||
事.変数が存在する時trueを返す.
|
||||
事.チェックに成功すると,プリプロセッサマクロ
|
||||
`HAVE_{VAR}` を定義し,trueを返す.
|
||||
|
||||
have_header(header) ::
|
||||
|
||||
ヘッダファイルの存在をチェックする.ヘッダファイルが存在す
|
||||
る時trueを返す.
|
||||
ヘッダファイルの存在をチェックする.チェックに成功すると,
|
||||
プリプロセッサマクロ `HAVE_{HEADER_H}` を定義し,trueを返す.
|
||||
(スラッシュやドットはアンダースコアに置換される)
|
||||
|
||||
find_header(header, path...) ::
|
||||
|
||||
ヘッダファイルheaderの存在を -Ipath を追加しながらチェック
|
||||
する.ヘッダファイルが見付かった時,trueを返す.
|
||||
する.チェックに成功すると,プリプロセッサマクロ
|
||||
`HAVE_{HEADER_H}` を定義し,trueを返す.
|
||||
(スラッシュやドットはアンダースコアに置換される)
|
||||
|
||||
have_struct_member(type, member[, header[, opt]]) ::
|
||||
|
||||
ヘッダファイルheaderをインクルードして型typeにメンバmember
|
||||
が存在するかをチェックする.typeが定義されていて,memberを
|
||||
持つする時trueを返す.
|
||||
ヘッダファイルheaderをインクルードして型typeが定義され,
|
||||
なおかつメンバmemberが存在するかをチェックする.チェックに
|
||||
成功すると,プリプロセッサマクロ `HAVE_{TYPE}_{MEMBER}` を
|
||||
定義し,trueを返す.
|
||||
|
||||
have_type(type, header, opt) ::
|
||||
|
||||
ヘッダファイルheaderをインクルードして型typeが存在するかを
|
||||
チェックする.typeが定義されている時trueを返す.
|
||||
チェックする.チェックに成功すると,プリプロセッサマクロ
|
||||
`HAVE_TYPE_{TYPE}` を定義し,trueを返す.
|
||||
|
||||
check_sizeof(type, header) ::
|
||||
|
||||
ヘッダファイルheaderをインクルードして型typeのchar単位サイ
|
||||
ズを調べる.typeが定義されている時そのサイズを返す.定義さ
|
||||
れていないときはnilを返す.
|
||||
ズを調べる.チェックに成功すると,プリプロセッサマクロ
|
||||
`SIZEOF_{TYPE}` を定義し,そのサイズを返す.定義されていな
|
||||
いときはnilを返す.
|
||||
|
||||
create_makefile(target[, target_prefix]) ::
|
||||
|
||||
|
@ -1574,11 +1611,21 @@ dir_config(target[, default_include, default_lib]) ::
|
|||
と等価である.追加された include ディレクトリと lib ディレ
|
||||
クトリの配列を返す. ([include_dir, lib_dir])
|
||||
|
||||
pkg_config(pkg) ::
|
||||
pkg_config(pkg, option=nil) ::
|
||||
|
||||
pkg-configコマンドからパッケージpkgの情報を得る.
|
||||
pkg-configの実際のコマンド名は,--with-pkg-configコマンド
|
||||
ラインオプションで指定可能.
|
||||
pkg-configコマンドからパッケージpkgの情報を [cflags, ldflags, libs]
|
||||
の配列として得る.$CFLAGS, $LDFLAGS, $libs にはそれぞれの値が
|
||||
追加される.
|
||||
|
||||
pkg-configの実際のコマンドは,以下の順で試される.
|
||||
|
||||
1. コマンドラインで--with-{pkg}-config={command}オプションが
|
||||
指定された場合: {command} {option}
|
||||
2. {pkg}-config {option}
|
||||
3. pkg-config {option} {pkg}
|
||||
|
||||
optionが指定された場合は、上記の配列の代わりにそのオプションを
|
||||
指定して得られた出力をstripしたものを返す.
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
|
|
@ -183,7 +183,7 @@ UNIXであれば +configure+ がほとんどの差異を吸収してくれるは
|
|||
|
||||
== 著者
|
||||
|
||||
コメント,バグレポートその他は mailto:matz@ruby-lang.jp まで.
|
||||
コメント,バグレポートその他は mailto:matz@ruby-lang.org まで.
|
||||
-------------------------------------------------------
|
||||
created at: Thu Aug 3 11:57:36 JST 1995
|
||||
--
|
||||
|
|
473
addr2line.c
473
addr2line.c
|
@ -9,6 +9,7 @@
|
|||
**********************************************************************/
|
||||
|
||||
#include "ruby/config.h"
|
||||
#include "ruby/missing.h"
|
||||
#include "addr2line.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -16,11 +17,6 @@
|
|||
|
||||
#ifdef USE_ELF
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#include <elf_abi.h>
|
||||
#else
|
||||
#include <elf.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
@ -32,6 +28,12 @@
|
|||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#include <elf_abi.h>
|
||||
#else
|
||||
#include <elf.h>
|
||||
#endif
|
||||
|
||||
/* Make alloca work the best possible way. */
|
||||
#ifdef __GNUC__
|
||||
# ifndef atarist
|
||||
|
@ -90,6 +92,8 @@ void *alloca();
|
|||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
int kprintf(const char *fmt, ...);
|
||||
|
||||
typedef struct {
|
||||
const char *dirname;
|
||||
const char *filename;
|
||||
|
@ -153,7 +157,7 @@ get_nth_dirname(unsigned long dir, char *p)
|
|||
while (*p) p++;
|
||||
p++;
|
||||
if (!*p) {
|
||||
fprintf(stderr, "Unexpected directory number %lu in %s\n",
|
||||
kprintf("Unexpected directory number %lu in %s\n",
|
||||
dir, binary_filename);
|
||||
return "";
|
||||
}
|
||||
|
@ -173,7 +177,7 @@ fill_filename(int file, char *include_directories, char *filenames,
|
|||
filename = p;
|
||||
if (!*p) {
|
||||
/* Need to output binary file name? */
|
||||
fprintf(stderr, "Unexpected file number %d in %s\n",
|
||||
kprintf("Unexpected file number %d in %s\n",
|
||||
file, binary_filename);
|
||||
return;
|
||||
}
|
||||
|
@ -375,7 +379,7 @@ parse_debug_line_cu(int num_traces, void **traces,
|
|||
p += sizeof(unsigned long);
|
||||
break;
|
||||
case DW_LNE_define_file:
|
||||
fprintf(stderr, "Unsupported operation in %s\n",
|
||||
kprintf("Unsupported operation in %s\n",
|
||||
binary_filename);
|
||||
break;
|
||||
case DW_LNE_set_discriminator:
|
||||
|
@ -383,7 +387,7 @@ parse_debug_line_cu(int num_traces, void **traces,
|
|||
uleb128(&p);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown extended opcode: %d in %s\n",
|
||||
kprintf("Unknown extended opcode: %d in %s\n",
|
||||
op, binary_filename);
|
||||
}
|
||||
break;
|
||||
|
@ -411,7 +415,7 @@ parse_debug_line(int num_traces, void **traces,
|
|||
parse_debug_line_cu(num_traces, traces, &debug_line, lines);
|
||||
}
|
||||
if (debug_line != debug_line_end) {
|
||||
fprintf(stderr, "Unexpected size of .debug_line in %s\n",
|
||||
kprintf("Unexpected size of .debug_line in %s\n",
|
||||
binary_filename);
|
||||
}
|
||||
}
|
||||
|
@ -473,13 +477,13 @@ fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
|
|||
if (filesize < 0) {
|
||||
int e = errno;
|
||||
close(fd);
|
||||
fprintf(stderr, "lseek: %s\n", strerror(e));
|
||||
kprintf("lseek: %s\n", strerror(e));
|
||||
return;
|
||||
}
|
||||
#if SIZEOF_OFF_T > SIZEOF_SIZE_T
|
||||
if (filesize > (off_t)SIZE_MAX) {
|
||||
close(fd);
|
||||
fprintf(stderr, "Too large file %s\n", binary_filename);
|
||||
kprintf("Too large file %s\n", binary_filename);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -489,7 +493,7 @@ fill_lines(int num_traces, void **traces, char **syms, int check_debuglink,
|
|||
if (file == MAP_FAILED) {
|
||||
int e = errno;
|
||||
close(fd);
|
||||
fprintf(stderr, "mmap: %s\n", strerror(e));
|
||||
kprintf("mmap: %s\n", strerror(e));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -614,23 +618,22 @@ rb_dump_backtrace_with_lines(int num_traces, void **trace, char **syms)
|
|||
fill_lines(num_traces, trace, syms, 1, &lines[i], lines);
|
||||
}
|
||||
|
||||
/* fprintf may not be async-signal safe */
|
||||
for (i = 0; i < num_traces; i++) {
|
||||
line_info_t *line = &lines[i];
|
||||
|
||||
if (line->line > 0) {
|
||||
fprintf(stderr, "%s ", syms[i]);
|
||||
if (line->filename) {
|
||||
if (line->dirname && line->dirname[0]) {
|
||||
fprintf(stderr, "%s/", line->dirname);
|
||||
kprintf("%s %s/%s:%d\n", syms[i], line->dirname, line->filename, line->line);
|
||||
}
|
||||
else {
|
||||
kprintf("%s %s:%d\n", syms[i], line->filename, line->line);
|
||||
}
|
||||
fprintf(stderr, "%s", line->filename);
|
||||
} else {
|
||||
fprintf(stderr, "???");
|
||||
kprintf("%s ???:%d\n", syms[i], line->line);
|
||||
}
|
||||
fprintf(stderr, ":%d\n", line->line);
|
||||
} else {
|
||||
fprintf(stderr, "%s\n", syms[i]);
|
||||
kprintf("%s\n", syms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -644,6 +647,436 @@ rb_dump_backtrace_with_lines(int num_traces, void **trace, char **syms)
|
|||
free(lines);
|
||||
}
|
||||
|
||||
/* From FreeBSD's lib/libstand/printf.c */
|
||||
/*-
|
||||
* Copyright (c) 1986, 1988, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1)
|
||||
extern int rb_toupper(int c);
|
||||
#define toupper(c) rb_toupper(c)
|
||||
#define hex2ascii(hex) (hex2ascii_data[hex])
|
||||
char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
static inline int imax(int a, int b) { return (a > b ? a : b); }
|
||||
static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap);
|
||||
|
||||
static void putce(int c)
|
||||
{
|
||||
char s[1];
|
||||
ssize_t ret;
|
||||
|
||||
s[0] = (char)c;
|
||||
ret = write(2, s, 1);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
int
|
||||
kprintf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int retval;
|
||||
|
||||
va_start(ap, fmt);
|
||||
retval = kvprintf(fmt, putce, NULL, 10, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
|
||||
* order; return an optional length and a pointer to the last character
|
||||
* written in the buffer (i.e., the first character of the string).
|
||||
* The buffer pointed to by `nbuf' must have length >= MAXNBUF.
|
||||
*/
|
||||
static char *
|
||||
ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
|
||||
{
|
||||
char *p, c;
|
||||
|
||||
p = nbuf;
|
||||
*p = '\0';
|
||||
do {
|
||||
c = hex2ascii(num % base);
|
||||
*++p = upper ? toupper(c) : c;
|
||||
} while (num /= base);
|
||||
if (lenp)
|
||||
*lenp = (int)(p - nbuf);
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scaled down version of printf(3).
|
||||
*
|
||||
* Two additional formats:
|
||||
*
|
||||
* The format %b is supported to decode error registers.
|
||||
* Its usage is:
|
||||
*
|
||||
* printf("reg=%b\n", regval, "<base><arg>*");
|
||||
*
|
||||
* where <base> is the output base expressed as a control character, e.g.
|
||||
* \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
|
||||
* the first of which gives the bit number to be inspected (origin 1), and
|
||||
* the next characters (up to a control character, i.e. a character <= 32),
|
||||
* give the name of the register. Thus:
|
||||
*
|
||||
* kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
|
||||
*
|
||||
* would produce output:
|
||||
*
|
||||
* reg=3<BITTWO,BITONE>
|
||||
*
|
||||
* XXX: %D -- Hexdump, takes pointer and separator string:
|
||||
* ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
|
||||
* ("%*D", len, ptr, " " -> XX XX XX XX ...
|
||||
*/
|
||||
static int
|
||||
kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
|
||||
{
|
||||
#define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; }
|
||||
char nbuf[MAXNBUF];
|
||||
char *d;
|
||||
const char *p, *percent, *q;
|
||||
unsigned char *up;
|
||||
int ch, n;
|
||||
uintmax_t num;
|
||||
int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
|
||||
int cflag, hflag, jflag, tflag, zflag;
|
||||
int dwidth, upper;
|
||||
char padc;
|
||||
int stop = 0, retval = 0;
|
||||
|
||||
num = 0;
|
||||
if (!func)
|
||||
d = (char *) arg;
|
||||
else
|
||||
d = NULL;
|
||||
|
||||
if (fmt == NULL)
|
||||
fmt = "(fmt null)\n";
|
||||
|
||||
if (radix < 2 || radix > 36)
|
||||
radix = 10;
|
||||
|
||||
for (;;) {
|
||||
padc = ' ';
|
||||
width = 0;
|
||||
while ((ch = (unsigned char)*fmt++) != '%' || stop) {
|
||||
if (ch == '\0')
|
||||
return (retval);
|
||||
PCHAR(ch);
|
||||
}
|
||||
percent = fmt - 1;
|
||||
qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
|
||||
sign = 0; dot = 0; dwidth = 0; upper = 0;
|
||||
cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
|
||||
reswitch: switch (ch = (unsigned char)*fmt++) {
|
||||
case '.':
|
||||
dot = 1;
|
||||
goto reswitch;
|
||||
case '#':
|
||||
sharpflag = 1;
|
||||
goto reswitch;
|
||||
case '+':
|
||||
sign = 1;
|
||||
goto reswitch;
|
||||
case '-':
|
||||
ladjust = 1;
|
||||
goto reswitch;
|
||||
case '%':
|
||||
PCHAR(ch);
|
||||
break;
|
||||
case '*':
|
||||
if (!dot) {
|
||||
width = va_arg(ap, int);
|
||||
if (width < 0) {
|
||||
ladjust = !ladjust;
|
||||
width = -width;
|
||||
}
|
||||
} else {
|
||||
dwidth = va_arg(ap, int);
|
||||
}
|
||||
goto reswitch;
|
||||
case '0':
|
||||
if (!dot) {
|
||||
padc = '0';
|
||||
goto reswitch;
|
||||
}
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
for (n = 0;; ++fmt) {
|
||||
n = n * 10 + ch - '0';
|
||||
ch = *fmt;
|
||||
if (ch < '0' || ch > '9')
|
||||
break;
|
||||
}
|
||||
if (dot)
|
||||
dwidth = n;
|
||||
else
|
||||
width = n;
|
||||
goto reswitch;
|
||||
case 'b':
|
||||
num = (unsigned int)va_arg(ap, int);
|
||||
p = va_arg(ap, char *);
|
||||
for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
|
||||
PCHAR(*q--);
|
||||
|
||||
if (num == 0)
|
||||
break;
|
||||
|
||||
for (tmp = 0; *p;) {
|
||||
n = *p++;
|
||||
if (num & (1 << (n - 1))) {
|
||||
PCHAR(tmp ? ',' : '<');
|
||||
for (; (n = *p) > ' '; ++p)
|
||||
PCHAR(n);
|
||||
tmp = 1;
|
||||
} else
|
||||
for (; *p > ' '; ++p)
|
||||
continue;
|
||||
}
|
||||
if (tmp)
|
||||
PCHAR('>');
|
||||
break;
|
||||
case 'c':
|
||||
PCHAR(va_arg(ap, int));
|
||||
break;
|
||||
case 'D':
|
||||
up = va_arg(ap, unsigned char *);
|
||||
p = va_arg(ap, char *);
|
||||
if (!width)
|
||||
width = 16;
|
||||
while(width--) {
|
||||
PCHAR(hex2ascii(*up >> 4));
|
||||
PCHAR(hex2ascii(*up & 0x0f));
|
||||
up++;
|
||||
if (width)
|
||||
for (q=p;*q;q++)
|
||||
PCHAR(*q);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
base = 10;
|
||||
sign = 1;
|
||||
goto handle_sign;
|
||||
case 'h':
|
||||
if (hflag) {
|
||||
hflag = 0;
|
||||
cflag = 1;
|
||||
} else
|
||||
hflag = 1;
|
||||
goto reswitch;
|
||||
case 'j':
|
||||
jflag = 1;
|
||||
goto reswitch;
|
||||
case 'l':
|
||||
if (lflag) {
|
||||
lflag = 0;
|
||||
qflag = 1;
|
||||
} else
|
||||
lflag = 1;
|
||||
goto reswitch;
|
||||
case 'n':
|
||||
if (jflag)
|
||||
*(va_arg(ap, intmax_t *)) = retval;
|
||||
else if (qflag)
|
||||
*(va_arg(ap, int64_t *)) = retval;
|
||||
else if (lflag)
|
||||
*(va_arg(ap, long *)) = retval;
|
||||
else if (zflag)
|
||||
*(va_arg(ap, size_t *)) = retval;
|
||||
else if (hflag)
|
||||
*(va_arg(ap, short *)) = retval;
|
||||
else if (cflag)
|
||||
*(va_arg(ap, char *)) = retval;
|
||||
else
|
||||
*(va_arg(ap, int *)) = retval;
|
||||
break;
|
||||
case 'o':
|
||||
base = 8;
|
||||
goto handle_nosign;
|
||||
case 'p':
|
||||
base = 16;
|
||||
sharpflag = (width == 0);
|
||||
sign = 0;
|
||||
num = (uintptr_t)va_arg(ap, void *);
|
||||
goto number;
|
||||
case 'q':
|
||||
qflag = 1;
|
||||
goto reswitch;
|
||||
case 'r':
|
||||
base = radix;
|
||||
if (sign)
|
||||
goto handle_sign;
|
||||
goto handle_nosign;
|
||||
case 's':
|
||||
p = va_arg(ap, char *);
|
||||
if (p == NULL)
|
||||
p = "(null)";
|
||||
if (!dot)
|
||||
n = (int)strlen (p);
|
||||
else
|
||||
for (n = 0; n < dwidth && p[n]; n++)
|
||||
continue;
|
||||
|
||||
width -= n;
|
||||
|
||||
if (!ladjust && width > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
while (n--)
|
||||
PCHAR(*p++);
|
||||
if (ladjust && width > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
break;
|
||||
case 't':
|
||||
tflag = 1;
|
||||
goto reswitch;
|
||||
case 'u':
|
||||
base = 10;
|
||||
goto handle_nosign;
|
||||
case 'X':
|
||||
upper = 1;
|
||||
case 'x':
|
||||
base = 16;
|
||||
goto handle_nosign;
|
||||
case 'y':
|
||||
base = 16;
|
||||
sign = 1;
|
||||
goto handle_sign;
|
||||
case 'z':
|
||||
zflag = 1;
|
||||
goto reswitch;
|
||||
handle_nosign:
|
||||
sign = 0;
|
||||
if (jflag)
|
||||
num = va_arg(ap, uintmax_t);
|
||||
else if (qflag)
|
||||
num = va_arg(ap, uint64_t);
|
||||
else if (tflag)
|
||||
num = va_arg(ap, ptrdiff_t);
|
||||
else if (lflag)
|
||||
num = va_arg(ap, unsigned long);
|
||||
else if (zflag)
|
||||
num = va_arg(ap, size_t);
|
||||
else if (hflag)
|
||||
num = (unsigned short)va_arg(ap, int);
|
||||
else if (cflag)
|
||||
num = (unsigned char)va_arg(ap, int);
|
||||
else
|
||||
num = va_arg(ap, unsigned int);
|
||||
goto number;
|
||||
handle_sign:
|
||||
if (jflag)
|
||||
num = va_arg(ap, intmax_t);
|
||||
else if (qflag)
|
||||
num = va_arg(ap, int64_t);
|
||||
else if (tflag)
|
||||
num = va_arg(ap, ptrdiff_t);
|
||||
else if (lflag)
|
||||
num = va_arg(ap, long);
|
||||
else if (zflag)
|
||||
num = va_arg(ap, ssize_t);
|
||||
else if (hflag)
|
||||
num = (short)va_arg(ap, int);
|
||||
else if (cflag)
|
||||
num = (char)va_arg(ap, int);
|
||||
else
|
||||
num = va_arg(ap, int);
|
||||
number:
|
||||
if (sign && (intmax_t)num < 0) {
|
||||
neg = 1;
|
||||
num = -(intmax_t)num;
|
||||
}
|
||||
p = ksprintn(nbuf, num, base, &n, upper);
|
||||
tmp = 0;
|
||||
if (sharpflag && num != 0) {
|
||||
if (base == 8)
|
||||
tmp++;
|
||||
else if (base == 16)
|
||||
tmp += 2;
|
||||
}
|
||||
if (neg)
|
||||
tmp++;
|
||||
|
||||
if (!ladjust && padc == '0')
|
||||
dwidth = width - tmp;
|
||||
width -= tmp + imax(dwidth, n);
|
||||
dwidth -= n;
|
||||
if (!ladjust)
|
||||
while (width-- > 0)
|
||||
PCHAR(' ');
|
||||
if (neg)
|
||||
PCHAR('-');
|
||||
if (sharpflag && num != 0) {
|
||||
if (base == 8) {
|
||||
PCHAR('0');
|
||||
} else if (base == 16) {
|
||||
PCHAR('0');
|
||||
PCHAR('x');
|
||||
}
|
||||
}
|
||||
while (dwidth-- > 0)
|
||||
PCHAR('0');
|
||||
|
||||
while (*p)
|
||||
PCHAR(*p--);
|
||||
|
||||
if (ladjust)
|
||||
while (width-- > 0)
|
||||
PCHAR(' ');
|
||||
|
||||
break;
|
||||
default:
|
||||
while (percent < fmt)
|
||||
PCHAR(*percent++);
|
||||
/*
|
||||
* Since we ignore an formatting argument it is no
|
||||
* longer safe to obey the remaining formatting
|
||||
* arguments as the arguments will no longer match
|
||||
* the format specs.
|
||||
*/
|
||||
stop = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef PCHAR
|
||||
}
|
||||
#else /* defined(USE_ELF) */
|
||||
#error not supported
|
||||
#endif
|
||||
|
|
|
@ -1,617 +0,0 @@
|
|||
# -*- makefile -*-
|
||||
|
||||
SHELL = $(COMSPEC)
|
||||
MKFILES = Makefile
|
||||
|
||||
!ifndef MFLAGS
|
||||
MFLAGS=-
|
||||
!endif
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
!ifndef OS
|
||||
OS = bccwin32
|
||||
!endif
|
||||
!if !defined(RT)
|
||||
!error RT not defined. Retry from configure pass.
|
||||
!endif
|
||||
|
||||
arch = $(ARCH)-$(OS)
|
||||
|
||||
## variables may be overridden by $(compile_dir)/Makefile
|
||||
!ifndef srcdir
|
||||
srcdir = ..
|
||||
!endif
|
||||
!ifndef RUBY_INSTALL_NAME
|
||||
RUBY_INSTALL_NAME = ruby
|
||||
!endif
|
||||
!ifndef RUBYW_INSTALL_NAME
|
||||
RUBYW_INSTALL_NAME = $(RUBY_INSTALL_NAME:ruby=rubyw)
|
||||
!elif "$(RUBYW_INSTALL_NAME)" == "$(RUBY_INSTALL_NAME)"
|
||||
RUBYW_INSTALL_NAME = $(RUBY_INSTALL_NAME:ruby=rubyw)
|
||||
!endif
|
||||
!if "$(RUBYW_INSTALL_NAME)" == "$(RUBY_INSTALL_NAME)"
|
||||
RUBYW_INSTALL_NAME = $(RUBY_INSTALL_NAME)w
|
||||
!endif
|
||||
!ifndef RUBY_SO_NAME
|
||||
RUBY_SO_NAME = $(RT)-$(RUBY_INSTALL_NAME)$(MAJOR)$(MINOR)$(TEENY)
|
||||
!endif
|
||||
!ifndef icondirs
|
||||
!ifdef ICONDIRS
|
||||
icondirs=$(ICONDIRS)
|
||||
!endif
|
||||
!endif
|
||||
!ifdef icondirs
|
||||
icondirs=$(icondirs:\=/)
|
||||
iconinc=-I$(icondirs: = -I)
|
||||
!endif
|
||||
###############
|
||||
|
||||
.SUFFIXES: .y
|
||||
|
||||
!ifndef CC
|
||||
CC = bcc32
|
||||
!endif
|
||||
!ifndef CPP
|
||||
CPP = cpp32
|
||||
!endif
|
||||
!ifndef RC
|
||||
RC = brcc32
|
||||
!endif
|
||||
!ifndef YACC
|
||||
YACC = bison
|
||||
!endif
|
||||
!ifndef AR
|
||||
AR = tlib
|
||||
!endif
|
||||
!ifndef BASERUBY
|
||||
BASERUBY = ruby
|
||||
!endif
|
||||
|
||||
PURIFY =
|
||||
AUTOCONF = autoconf
|
||||
IFCHANGE = $(srcdir:/=\)\win32\ifchange.bat
|
||||
RM = $(srcdir:/=\)\win32\rm.bat
|
||||
CP = copy > nul
|
||||
MV = move > nul
|
||||
|
||||
!if !defined(PROCESSOR_ARCHITECTURE)
|
||||
PROCESSOR_ARCHITECTURE = x86
|
||||
!endif
|
||||
MACHINE = $(PROCESSOR_ARCHITECTURE)
|
||||
!if "$(PROCESSOR_ARCHITECTURE)" == "x86"
|
||||
!ifndef PROCESSOR_LEVEL
|
||||
PROCESSOR_LEVEL = 5
|
||||
!endif
|
||||
!if 6 < $(PROCESSOR_LEVEL)
|
||||
PROCESSOR_LEVEL = 6
|
||||
!endif
|
||||
PROCESSOR_FLAG = -$(PROCESSOR_LEVEL)
|
||||
CPU = i$(PROCESSOR_LEVEL)86
|
||||
ARCH = i386
|
||||
!else
|
||||
CPU = $(PROCESSOR_ARCHITECTURE)
|
||||
ARCH = $(PROCESSOR_ARCHITECTURE)
|
||||
!endif
|
||||
!ifndef DEBUGFLAGS
|
||||
DEBUGFLAGS =
|
||||
!endif
|
||||
!ifndef OPTFLAGS
|
||||
OPTFLAGS = -O
|
||||
!endif
|
||||
|
||||
!ifndef prefix
|
||||
prefix = /usr
|
||||
!endif
|
||||
!ifndef exec_prefix
|
||||
exec_prefix = $(prefix)
|
||||
!endif
|
||||
!ifndef libdir
|
||||
libdir = $(exec_prefix)/lib
|
||||
!endif
|
||||
!if !defined(datadir)
|
||||
datadir = $(prefix)/share
|
||||
!endif
|
||||
!ifndef EXTOUT
|
||||
EXTOUT = .ext
|
||||
!endif
|
||||
!ifndef TESTUI
|
||||
TESTUI = console
|
||||
!endif
|
||||
!ifndef TESTS
|
||||
TESTS =
|
||||
!endif
|
||||
!ifndef RDOCTARGET
|
||||
RDOCTARGET = install-doc
|
||||
!endif
|
||||
|
||||
OUTFLAG = -o
|
||||
COUTFLAG = -o
|
||||
!ifndef CFLAGS
|
||||
CFLAGS = -q -tWR -tWC $(DEBUGFLAGS) $(OPTFLAGS) $(PROCESSOR_FLAG) -w- -wsus -wcpt -wdup -wext -wrng -wrpt -wzdi
|
||||
!endif
|
||||
!ifndef DEFS
|
||||
DEFS =
|
||||
!endif
|
||||
!ifndef CPPFLAGS
|
||||
CPPFLAGS =
|
||||
!endif
|
||||
CPPFLAGS = $(DEFS) $(CPPFLAGS)
|
||||
!ifndef CXXFLAGS
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
!endif
|
||||
!ifndef LDFLAGS
|
||||
LDFLAGS = -S:$(STACK)
|
||||
!endif
|
||||
!ifndef RFLAGS
|
||||
RFLAGS = $(iconinc)
|
||||
!endif
|
||||
!ifndef EXTLIBS
|
||||
EXTLIBS =
|
||||
!endif
|
||||
!ifndef MEMLIB
|
||||
MEMLIB =
|
||||
!endif
|
||||
LIBS = $(MEMLIB) cw32i.lib import32.lib ws2_32.lib $(EXTLIBS)
|
||||
MISSING = acosh.obj cbrt.obj crypt.obj erf.obj lgamma_r.obj strlcat.obj strlcpy.obj tgamma.obj win32.obj
|
||||
|
||||
!ifndef STACK
|
||||
STACK = 0x2000000
|
||||
!endif
|
||||
|
||||
XCFLAGS = -DRUBY_EXPORT -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) -I$(srcdir)/missing
|
||||
|
||||
ARFLAGS = /a /p32
|
||||
LD = ilink32 -q -Gn
|
||||
LDSHARED = $(LD)
|
||||
XLDFLAGS = -Tpe c0x32.obj
|
||||
WLDFLAGS = -aa -Tpe c0w32.obj
|
||||
DLDFLAGS = -Tpd c0d32.obj
|
||||
LIBRUBY_LDSHARED = $(LDSHARED)
|
||||
LIBRUBY_DLDFLAGS = -Gi $(DLDFLAGS) $(EXTLDFLAGS)
|
||||
LDOBJECTS = $(MAINOBJ)
|
||||
|
||||
SOLIBS =
|
||||
|
||||
EXEEXT = .exe
|
||||
PROGRAM=$(RUBY_INSTALL_NAME)$(EXEEXT)
|
||||
WPROGRAM=$(RUBYW_INSTALL_NAME)$(EXEEXT)
|
||||
RUBYDEF = $(RUBY_SO_NAME).def
|
||||
MINIRUBY = .\miniruby$(EXEEXT) -I$(srcdir)/lib $(MINIRUBYOPT)
|
||||
RUNRUBY = .\$(PROGRAM) -i"$(EXTOUT)/$(arch)" "$(srcdir)/runruby.rb" --extout="$(EXTOUT)" --
|
||||
|
||||
ORGLIBPATH = $(LIB)
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
LIBRUBY_A = $(RUBY_SO_NAME)-static.lib
|
||||
LIBRUBY_SO = $(RUBY_SO_NAME).dll
|
||||
LIBRUBY = $(RUBY_SO_NAME).lib
|
||||
LIBRUBYARG = $(LIBRUBY)
|
||||
THREAD_MODEL = win32
|
||||
|
||||
PREP = miniruby$(EXEEXT)
|
||||
|
||||
OBJEXT = obj
|
||||
ASMEXT = asm
|
||||
|
||||
INSTALLED_LIST= .installed.list
|
||||
|
||||
MKMAIN_CMD = mkmain.bat
|
||||
|
||||
SRC_FILE = $(<:\=/)
|
||||
|
||||
WINMAINOBJ = winmain.$(OBJEXT)
|
||||
ARCHMINIOBJS = dmydln.$(OBJEXT)
|
||||
|
||||
arch_hdrdir = $(EXTOUT)/include/$(arch)
|
||||
hdrdir = $(srcdir)/include
|
||||
VPATH = $(arch_hdrdir)/ruby;$(hdrdir)/ruby;$(srcdir);$(srcdir)/enc;$(srcdir)/missing;$(srcdir)/win32
|
||||
|
||||
.path.c = .;$(srcdir);$(srcdir)/enc;$(srcdir)/win32;$(srcdir)/missing
|
||||
.path.ci = $(srcdir)
|
||||
.path.inc = .;$(srcdir)
|
||||
.path.def = .;$(srcdir)
|
||||
.path.h = .;$(arch_hdrdir)/ruby;$(hdrdir)/ruby;$(srcdir);$(srcdir)/win32;$(srcdir)/missing
|
||||
.path.y = $(srcdir)
|
||||
.path. = $(srcdir)
|
||||
|
||||
.c.obj:
|
||||
$(CC) $(CFLAGS) $(XCFLAGS) -I. $(CPPFLAGS) $(COUTFLAG)$@ -c $(<:/=\)
|
||||
|
||||
.c.asm:
|
||||
$(CC) $(CFLAGS) $(XCFLAGS) -I. $(CPPFLAGS) $(COUTFLAG)$@ -S $(<:\=/)
|
||||
|
||||
.rc.res:
|
||||
$(RC) $(RFLAGS) -I. -I$(<D). $(iconinc) -I$(srcdir)/win32 $(RFLAGS) -fo$@ $(<:/=\)
|
||||
|
||||
all: $(srcdir)/bcc32/Makefile.sub $(srcdir)/common.mk
|
||||
|
||||
ruby: $(PROGRAM)
|
||||
rubyw: $(WPROGRAM)
|
||||
|
||||
!include $(srcdir)/common.mk
|
||||
|
||||
$(MKFILES): $(srcdir)/bcc32/Makefile.sub $(srcdir)/bcc32/configure.bat $(srcdir)/bcc32/setup.mak
|
||||
$(COMSPEC) /C $(srcdir:/=\)\bcc32\configure.bat $(configure_args)
|
||||
@echo $(MKFILES) should be updated, re-run $(MAKE).
|
||||
@$(MAKE) > nul -q -f &&|
|
||||
PHONY: nul
|
||||
@exit
|
||||
|
|
||||
|
||||
PHONY: nul
|
||||
|
||||
RUBY_CONFIG_H = $(arch_hdrdir)/ruby/config.h
|
||||
CONFIG_H = ./.config.h.time
|
||||
|
||||
config: config.status
|
||||
|
||||
config.status: $(CONFIG_H)
|
||||
|
||||
guard = INCLUDE_RUBY_CONFIG_H
|
||||
|
||||
$(CONFIG_H): $(MKFILES) $(srcdir)/bcc32/Makefile.sub
|
||||
@if not exist $(arch_hdrdir:/=\) md $(arch_hdrdir:/=\)
|
||||
@if not exist $(arch_hdrdir:/=\)\ruby md $(arch_hdrdir:/=\)\ruby
|
||||
@$(IFCHANGE) $(RUBY_CONFIG_H:/=\) &&|
|
||||
\#ifndef $(guard)
|
||||
\#define $(guard) 1
|
||||
\#define NO_BIG_INLINE 1
|
||||
\#define HAVE_SYS_TYPES_H 1
|
||||
\#define HAVE_SYS_STAT_H 1
|
||||
\#define HAVE_STDLIB_H 1
|
||||
\#define HAVE_STRING_H 1
|
||||
\#define HAVE_MEMORY_H 1
|
||||
\#define HAVE_LONG_LONG 1
|
||||
\#define HAVE_OFF_T 1
|
||||
\#define SIZEOF_INT 4
|
||||
\#define SIZEOF_SHORT 2
|
||||
\#define SIZEOF_LONG 4
|
||||
\#define SIZEOF_LONG_LONG 0
|
||||
\#define SIZEOF___INT64 8
|
||||
\#define SIZEOF_OFF_T 8
|
||||
\#define SIZEOF_VOIDP 4
|
||||
\#define SIZEOF_FLOAT 4
|
||||
\#define SIZEOF_DOUBLE 8
|
||||
\#define SIZEOF_TIME_T 4
|
||||
\#define SIZEOF_RLIM_T 0
|
||||
\#define SIZEOF_SIZE_T 4
|
||||
\#define SIZEOF_PTRDIFF_T 4
|
||||
\#define HAVE_PROTOTYPES 1
|
||||
\#define TOKEN_PASTE(x,y) x\#\#y
|
||||
\#define HAVE_STDARG_PROTOTYPES 1
|
||||
\#define NORETURN(x) x
|
||||
\#define RUBY_EXTERN extern __declspec(dllimport)
|
||||
\#define HAVE_DECL_SYS_NERR 1
|
||||
\#define HAVE_LIMITS_H 1
|
||||
\#define HAVE_FCNTL_H 1
|
||||
\#define HAVE_UTIME_H 1
|
||||
\#define HAVE_FLOAT_H 1
|
||||
\#define rb_uid_t uid_t
|
||||
\#define rb_gid_t gid_t
|
||||
\#define rb_pid_t int
|
||||
\#define HAVE_STRUCT_STAT_ST_RDEV 1
|
||||
\#define HAVE_ST_RDEV 1
|
||||
!if $(BORLANDC) < 0x0580
|
||||
\#define int8_t signed char
|
||||
\#define uint8_t unsigned char
|
||||
\#define int16_t short
|
||||
\#define uint16_t unsigned short
|
||||
\#define int32_t int
|
||||
\#define uint32_t unsigned int
|
||||
\#define int64_t __int64
|
||||
\#define uint64_t unsigned __int64
|
||||
\#define ssize_t int
|
||||
!endif
|
||||
\#define HAVE_INT8_T 1
|
||||
\#define HAVE_UINT8_T 1
|
||||
\#define SIZEOF_INT8_T 1
|
||||
\#define HAVE_INT16_T 1
|
||||
\#define HAVE_UINT16_T 1
|
||||
\#define SIZEOF_INT32_T 2
|
||||
\#define HAVE_INT32_T 1
|
||||
\#define HAVE_UINT32_T 1
|
||||
\#define SIZEOF_INT32_T 4
|
||||
\#define HAVE_INT64_T 1
|
||||
\#define HAVE_UINT64_T 1
|
||||
\#define SIZEOF_INT64_T 8
|
||||
\#define HAVE_INTPTR_T 1
|
||||
\#define HAVE_UINTPTR_T 1
|
||||
\#define HAVE_SSIZE_T 1
|
||||
\#define GETGROUPS_T int
|
||||
\#define RETSIGTYPE void
|
||||
\#define HAVE_ALLOCA 1
|
||||
\#define HAVE_DUP2 1
|
||||
\#define HAVE_MEMMOVE 1
|
||||
\#define HAVE_MKDIR 1
|
||||
\#define HAVE_STRCASECMP 1
|
||||
\#define HAVE_STRNCASECMP 1
|
||||
\#define HAVE_STRERROR 1
|
||||
\#define HAVE_STRFTIME 1
|
||||
\#define HAVE_STRCHR 1
|
||||
\#define HAVE_STRSTR 1
|
||||
\#define HAVE_STRTOD 1
|
||||
\#define HAVE_STRTOL 1
|
||||
\#define HAVE_STRTOUL 1
|
||||
\#define HAVE_SNPRINTF 1
|
||||
\#define HAVE_VSNPRINTF 1
|
||||
\#define HAVE_ISNAN 1
|
||||
\#define HAVE_FINITE 1
|
||||
\#define HAVE_HYPOT 1
|
||||
\#define HAVE_FMOD 1
|
||||
\#define HAVE_WAITPID 1
|
||||
\#define HAVE_FSYNC 1
|
||||
\#define HAVE_GETCWD 1
|
||||
\#define HAVE_TRUNCATE 1
|
||||
\#define HAVE_FTRUNCATE 1
|
||||
\#define HAVE_FSEEKO 1
|
||||
\#define HAVE_FTELLO 1
|
||||
\#define HAVE_TIMES 1
|
||||
\#define HAVE_FCNTL 1
|
||||
\#define HAVE_LINK 1
|
||||
\#define HAVE_TELLDIR 1
|
||||
\#define HAVE_SEEKDIR 1
|
||||
\#define HAVE_COSH 1
|
||||
\#define HAVE_SINH 1
|
||||
\#define HAVE_TANH 1
|
||||
\#define RSHIFT(x,y) ((x)>>(int)y)
|
||||
\#define FILE_COUNT level
|
||||
\#define FILE_READPTR curp
|
||||
\#define RUBY_SETJMP(env) setjmp(env)
|
||||
\#define RUBY_LONGJMP(env,val) longjmp(env,val)
|
||||
\#define RUBY_JMP_BUF jmp_buf
|
||||
\#define inline __inline
|
||||
\#define NEED_IO_SEEK_BETWEEN_RW 1
|
||||
\#define STACK_GROW_DIRECTION -1
|
||||
\#define DEFAULT_KCODE KCODE_NONE
|
||||
\#define LOAD_RELATIVE 1
|
||||
\#define DLEXT ".so"
|
||||
\#define RUBY_LIB_PREFIX "/lib/ruby"
|
||||
\#define RUBY_PLATFORM "$(ARCH)-$(OS)"
|
||||
\#endif /* $(guard) */
|
||||
|
|
||||
@exit > $(@:/=\)
|
||||
|
||||
config.status: $(MKFILES) $(srcdir)/bcc32/Makefile.sub $(srcdir)/common.mk
|
||||
@echo Creating $@
|
||||
@type > $@ &&|
|
||||
# Generated automatically by Makefile.sub.
|
||||
s,@SHELL@,$$(COMSPEC),;t t
|
||||
s,@BUILD_FILE_SEPARATOR@,\,;t t
|
||||
s,@PATH_SEPARATOR@,;,;t t
|
||||
s,@CFLAGS@,$(CFLAGS),;t t
|
||||
s,@DEFS@,$(DEFS),;t t
|
||||
s,@CPPFLAGS@,$(CPPFLAGS),;t t
|
||||
s,@CXXFLAGS@,$(CXXFLAGS),;t t
|
||||
s,@FFLAGS@,$(FFLAGS),;t t
|
||||
s,@LDFLAGS@,,;t t
|
||||
s,@LIBS@,$(LIBS),;t t
|
||||
s,@exec_prefix@,$${prefix},;t t
|
||||
s,@prefix@,$(prefix),;t t
|
||||
s,@program_transform_name@,s,,,,;t t
|
||||
s,@bindir@,$${exec_prefix}/bin,;t t
|
||||
s,@sbindir@,$${exec_prefix}/sbin,;t t
|
||||
s,@libexecdir@,$${exec_prefix}/libexec,;t t
|
||||
s,@datadir@,$${prefix}/share,;t t
|
||||
s,@sysconfdir@,$${prefix}/etc,;t t
|
||||
s,@sharedstatedir@,/etc,;t t
|
||||
s,@localstatedir@,/var,;t t
|
||||
s,@libdir@,$${exec_prefix}/lib,;t t
|
||||
s,@includedir@,$${prefix}/include,;t t
|
||||
s,@oldincludedir@,/usr/include,;t t
|
||||
s,@infodir@,$${prefix}/info,;t t
|
||||
s,@mandir@,$${prefix}/man,;t t
|
||||
s,@ridir@,$${prefix}/share/ri,;t t
|
||||
s,@build@,$(CPU)-pc-$(OS),;t t
|
||||
s,@build_alias@,$(CPU)-$(OS),;t t
|
||||
s,@build_cpu@,$(CPU),;t t
|
||||
s,@build_vendor@,pc,;t t
|
||||
s,@build_os@,$(OS),;t t
|
||||
s,@host@,$(CPU)-pc-$(OS),;t t
|
||||
s,@host_alias@,$(CPU)-$(OS),;t t
|
||||
s,@host_cpu@,$(CPU),;t t
|
||||
s,@host_vendor@,pc,;t t
|
||||
s,@host_os@,$(OS),;t t
|
||||
s,@target@,$(ARCH)-pc-$(OS),;t t
|
||||
s,@target_alias@,$(ARCH)-$(OS),;t t
|
||||
s,@target_cpu@,$(ARCH),;t t
|
||||
s,@target_vendor@,pc,;t t
|
||||
s,@target_os@,$(OS),;t t
|
||||
s,@CC@,$(CC),;t t
|
||||
s,@CPP@,cpp32,;t t
|
||||
s,@CXX@,$$(CC),;t t
|
||||
s,@LD@,$(LD),;t t
|
||||
s,@YACC@,$(YACC),;t t
|
||||
s,@RANLIB@,,;t t
|
||||
s,@AR@,$(AR),;t t
|
||||
s,@ARFLAGS@,$(ARFLAGS) ,;t t
|
||||
s,@LN_S@,$(LN_S),;t t
|
||||
s,@SET_MAKE@,MFLAGS = -$$(MAKEFLAGS),;t t
|
||||
s,@RM@,$$(top_srcdir:/=\)\win32\rm.bat,;t t
|
||||
s,@CP@,copy > nul,;t t
|
||||
s,@LIBOBJS@, $(MISSING),;t t
|
||||
s,@ALLOCA@,$(ALLOCA),;t t
|
||||
s,@DEFAULT_KCODE@,$(DEFAULT_KCODE),;t t
|
||||
s,@EXEEXT@,.exe,;t t
|
||||
s,@OBJEXT@,obj,;t t
|
||||
s,@XCFLAGS@,$(XCFLAGS),;t t
|
||||
s,@XLDFLAGS@,$(XLDFLAGS),;t t
|
||||
s,@DLDFLAGS@,$(DLDFLAGS),;t t
|
||||
s,@ARCH_FLAG@,$(ARCH_FLAG),;t t
|
||||
s,@STATIC@,$(STATIC),;t t
|
||||
s,@CCDLFLAGS@,,;t t
|
||||
s,@LDSHARED@,$(LDSHARED),;t t
|
||||
s,@DLEXT@,so,;t t
|
||||
s,@LIBEXT@,lib,;t t
|
||||
s,@STRIP@,$(STRIP),;t t
|
||||
s,@EXTSTATIC@,$(EXTSTATIC),;t t
|
||||
s,@setup@,Setup,;t t
|
||||
s,@MINIRUBY@,$(MINIRUBY),;t t
|
||||
s,@PREP@,miniruby$(EXEEXT),;t t
|
||||
s,@RUNRUBY@,$(RUNRUBY),;t t
|
||||
s,@EXTOUT@,$(EXTOUT),;t t
|
||||
s,@ARCHFILE@,,;t t
|
||||
s,@RDOCTARGET@,,;t t
|
||||
s,@LIBRUBY_LDSHARED@,$$(LDSHARED),;t t
|
||||
s,@LIBRUBY_DLDFLAGS@,-Gi $$(DLDFLAGS),;t t
|
||||
s,@RUBY_INSTALL_NAME@,$(RUBY_INSTALL_NAME),;t t
|
||||
s,@rubyw_install_name@,$(RUBYW_INSTALL_NAME),;t t
|
||||
s,@RUBYW_INSTALL_NAME@,$(RUBYW_INSTALL_NAME),;t t
|
||||
s,@RUBY_SO_NAME@,$(RUBY_SO_NAME),;t t
|
||||
s,@LIBRUBY_A@,$$(RUBY_SO_NAME)-static.lib,;t t
|
||||
s,@LIBRUBY_SO@,$$(RUBY_SO_NAME).dll,;t t
|
||||
s,@LIBRUBY_ALIASES@,$(LIBRUBY_ALIASES),;t t
|
||||
s,@LIBRUBY@,$$(RUBY_SO_NAME).lib,;t t
|
||||
s,@LIBRUBYARG@,$$(LIBRUBYARG_SHARED),;t t
|
||||
s,@LIBRUBYARG_STATIC@,$$(LIBRUBY_A),;t t
|
||||
s,@LIBRUBYARG_SHARED@,$$(LIBRUBY),;t t
|
||||
s,@SOLIBS@,$(SOLIBS),;t t
|
||||
s,@DLDLIBS@,$(DLDLIBS),;t t
|
||||
s,@ENABLE_SHARED@,yes,;t t
|
||||
s,@OUTFLAG@,$(OUTFLAG),;t t
|
||||
s,@COUTFLAG@,$(COUTFLAG),;t t
|
||||
s,@CPPOUTFILE@,,;t t
|
||||
s,@LIBPATHFLAG@, -L"%s",;t t
|
||||
s,@RPATHFLAG@,,;t t
|
||||
s,@LIBARG@,%s.lib,;t t
|
||||
s,@LINK_SO@,$$(LDSHARED) $$(DLDFLAGS) $$(LIBPATH) $$(OBJS:/=\), $$(@:/=\), nul, $$(LIBS) $$(LOCAL_LIBS), $$(DEFFILE:/=\), $$(RESFILE:/=\),;t t
|
||||
s,@COMPILE_C@,$$(CC) $$(INCFLAGS) $$(CFLAGS) $$(CPPFLAGS) $(COUTFLAG)$$(@) -c $$(<:/=\),;t t
|
||||
s,@COMPILE_CXX@,$$(CXX) $$(INCFLAGS) $$(CXXFLAGS) $$(CPPFLAGS) -P $(COUTFLAG)$$(@) -c $$(<:/=\),;t t
|
||||
s,@COMPILE_RULES@,{$$(srcdir)}.%s{}.%s: {$$(topdir)}.%s{}.%s: {$$(hdrdir)}.%s{}.%s: .%s.%s:,;t t
|
||||
s,@RULE_SUBST@,{.;$$(VPATH)}%s,;t t
|
||||
s,@COMMON_LIBS@,m advapi32 avicap32 avifil32 cap comctl32 comdlg32 dlcapi gdi32 glu32 imagehlp imm32 inetmib1 kernel32 loadperf lsapi32 lz32 mapi32 mgmtapi mpr msacm32 msvfw32 nddeapi netapi32 ole32 oleaut32 oledlg olepro32 opengl32 pdh pkpd32 rasapi32 rasdlg rassapi rpcrt4 setupapi shell32 shfolder snmpapi sporder tapi32 url user32 vdmdbg version win32spl winmm wintrust wsock32,;t t
|
||||
s,@COMMON_MACROS@,WIN32_LEAN_AND_MEAN WIN32,;t t
|
||||
s,@COMMON_HEADERS@,winsock2.h windows.h,;t t
|
||||
s,@cleanlibs@,$$*.tds,;t t
|
||||
s,@cleanobjs@,$$*-$$(arch).def $$*.il? $$*.lib,;t t
|
||||
s,@TRY_LINK@,$$(CC) -oconftest $$(INCFLAGS) -I$$(hdrdir) $$(CPPFLAGS) $$(CFLAGS) $$(LIBPATH) $$(LDFLAGS) $$(src) $$(LOCAL_LIBS) $$(LIBS),;t t
|
||||
s,@EXPORT_PREFIX@,_,;t t
|
||||
s,@arch@,$(ARCH)-$(OS),;t t
|
||||
s,@sitearch@,$(ARCH)-$(OS),;t t
|
||||
s,@sitedir@,$${prefix}/lib/ruby/site_ruby,;t t
|
||||
s,@vendordir@,$${prefix}/lib/ruby/vendor_ruby,;t t
|
||||
s,@rubyhdrdir@,$$(includedir)/ruby-$$(MAJOR).$$(MINOR).$$(TEENY),;t t
|
||||
s,@sitehdrdir@,$$(rubyhdrdir)/site_ruby,;t t
|
||||
s,@vendorhdrdir@,$$(rubyhdrdir)/vendor_ruby,;t t
|
||||
s,@configure_args@,--enable-shared $(configure_args),;t t
|
||||
s,@configure_input@,$$configure_input,;t t
|
||||
s,@srcdir@,$(srcdir),;t t
|
||||
s,@top_srcdir@,$(srcdir),;t t
|
||||
|
|
||||
|
||||
miniruby$(EXEEXT):
|
||||
@echo $(LIBS)
|
||||
$(LD) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(MINIOBJS) $(COMMONOBJS:/=\) $(DMYEXT),$@,nul,$(LIBS)
|
||||
|
||||
$(PROGRAM): $(MAINOBJ) $(LIBRUBY_SO) $(RUBY_INSTALL_NAME).res
|
||||
$(LD) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ),$@,nul,$(LIBRUBYARG) $(LIBS),,$(RUBY_INSTALL_NAME).res
|
||||
|
||||
$(WPROGRAM): $(MAINOBJ) $(WINMAINOBJ) $(LIBRUBY_SO) $(RUBYW_INSTALL_NAME).res
|
||||
$(LD) $(LDFLAGS) $(WLDFLAGS) $(MAINOBJ) $(WINMAINOBJ),$@,nul,$(LIBRUBYARG) $(LIBS),,$(RUBYW_INSTALL_NAME).res
|
||||
|
||||
$(LIBRUBY_A): $(OBJS) $(DMYEXT)
|
||||
@-if exist $@ del $@
|
||||
$(AR) $(ARFLAGS) "$@" $(OBJS) $(DMYEXT)
|
||||
|
||||
# $(LIBRUBY): $(LIBRUBY_SO)
|
||||
# implib $@ $(LIBRUBY_SO)
|
||||
|
||||
$(LIBRUBY_SO): $(LIBRUBY_A) $(DLDOBJS) $(RUBYDEF) $(RUBY_SO_NAME).res
|
||||
@echo $(DLDOBJS)
|
||||
@$(PRE_LIBRUBY_UPDATE)
|
||||
$(LIBRUBY_LDSHARED) $(LIBRUBY_DLDFLAGS) $(DLDOBJS:/=\),$(LIBRUBY_SO),nul,$(LIBRUBY_A) $(LIBS),$(RUBYDEF),$(RUBY_SO_NAME).res
|
||||
|
||||
$(LIBRUBY): $(LIBRUBY_SO)
|
||||
|
||||
$(RUBYDEF): $(LIBRUBY_A) $(PREP)
|
||||
$(MINIRUBY) $(srcdir)/bcc32/mkexports.rb -output=$@ -base=$(RUBY_SO_NAME) $(LIBRUBY_A)
|
||||
|
||||
$(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(RUBY_SO_NAME).rc: rbconfig.rb $(srcdir)/revision.h $(srcdir)/win32/resource.rb
|
||||
@$(MINIRUBY) $(srcdir)/win32/resource.rb \
|
||||
-ruby_name=$(RUBY_INSTALL_NAME) \
|
||||
-rubyw_name=$(RUBYW_INSTALL_NAME) \
|
||||
-so_name=$(RUBY_SO_NAME) \
|
||||
. $(icondirs) $(srcdir)/win32
|
||||
|
||||
lex.c: {$(srcdir)}lex.c.blt
|
||||
copy "$(?:/=\)" $@
|
||||
|
||||
post-install-bin::
|
||||
@$(NULLCMD)
|
||||
post-install-lib::
|
||||
@$(NULLCMD)
|
||||
post-install-ext-comm::
|
||||
@$(NULLCMD)
|
||||
post-install-ext-arch::
|
||||
@$(NULLCMD)
|
||||
post-install-man::
|
||||
@$(NULLCMD)
|
||||
post-install-doc::
|
||||
@$(NULLCMD)
|
||||
|
||||
clean-local::
|
||||
@$(RM) $(WINMAINOBJ) ext\extinit.c ext\extinit.$(OBJEXT) *.tds *.il? $(RUBY_SO_NAME).lib
|
||||
@$(RM) $(RUBY_INSTALL_NAME).res $(RUBYW_INSTALL_NAME).res $(RUBY_SO_NAME).res
|
||||
@$(RM) *.map *.pdb *.ilk *.exp $(RUBYDEF) ext\ripper\y.output
|
||||
|
||||
distclean-local::
|
||||
@$(RM) ext\config.cache $(RBCONFIG:/=\)
|
||||
@$(RM) $(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(RUBY_SO_NAME).rc
|
||||
|
||||
clean-ext distclean-ext realclean-ext::
|
||||
@for /R ext %I in (.) do @if exist %I\Makefile ( \
|
||||
echo $(@:-ext=)ing %~nI & \
|
||||
cd %I & \
|
||||
$(MAKE) $(MFLAGS) $(@:-ext=) & \
|
||||
cd %CD% \
|
||||
)
|
||||
|
||||
ext/extinit.obj: ext/extinit.c $(SETUP)
|
||||
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c ext/extinit.c
|
||||
|
||||
main.$(OBJEXT): win32.h
|
||||
ascii.$(OBJEXT): win32.h
|
||||
array.$(OBJEXT): win32.h
|
||||
bignum.$(OBJEXT): win32.h
|
||||
class.$(OBJEXT): win32.h
|
||||
compar.$(OBJEXT): win32.h
|
||||
dir.$(OBJEXT): dir.h win32.h
|
||||
dln.$(OBJEXT): win32.h
|
||||
enum.$(OBJEXT): win32.h
|
||||
error.$(OBJEXT): win32.h
|
||||
euc_jp.$(OBJEXT): win32.h
|
||||
eval.$(OBJEXT): win32.h
|
||||
file.$(OBJEXT): win32.h
|
||||
gc.$(OBJEXT): win32.h
|
||||
hash.$(OBJEXT): win32.h
|
||||
inits.$(OBJEXT): win32.h
|
||||
io.$(OBJEXT): win32.h
|
||||
marshal.$(OBJEXT): win32.h
|
||||
math.$(OBJEXT): win32.h
|
||||
numeric.$(OBJEXT): win32.h
|
||||
object.$(OBJEXT): win32.h
|
||||
pack.$(OBJEXT): win32.h
|
||||
parse.$(OBJEXT): win32.h
|
||||
process.$(OBJEXT): win32.h
|
||||
prec.$(OBJEXT): win32.h
|
||||
random.$(OBJEXT): win32.h
|
||||
range.$(OBJEXT): win32.h
|
||||
re.$(OBJEXT): win32.h
|
||||
regcomp.$(OBJEXT): win32.h
|
||||
regenc.$(OBJEXT): win32.h
|
||||
regerror.$(OBJEXT): win32.h
|
||||
regexec.$(OBJEXT): win32.h
|
||||
reggnu.$(OBJEXT): win32.h
|
||||
regparse.$(OBJEXT): win32.h
|
||||
ruby.$(OBJEXT): win32.h
|
||||
signal.$(OBJEXT): win32.h
|
||||
sjis.$(OBJEXT): win32.h
|
||||
sprintf.$(OBJEXT): win32.h
|
||||
st.$(OBJEXT): win32.h
|
||||
string.$(OBJEXT): win32.h
|
||||
struct.$(OBJEXT): win32.h
|
||||
time.$(OBJEXT): win32.h
|
||||
utf_8.$(OBJEXT): win32.h
|
||||
util.$(OBJEXT): win32.h
|
||||
variable.$(OBJEXT): win32.h
|
||||
version.$(OBJEXT): win32.h
|
|
@ -1,130 +0,0 @@
|
|||
=begin
|
||||
|
||||
= How to build ruby using Borland C++
|
||||
|
||||
== Requirement
|
||||
|
||||
(1) Borland C++ 5.0 or later.
|
||||
|
||||
(2) Please set environment variable (({PATH}))
|
||||
to run required commands properly from the command line.
|
||||
|
||||
Note: building ruby requires following commands.
|
||||
* make
|
||||
* bcc32
|
||||
* tlib
|
||||
* ilink32
|
||||
|
||||
(3) If you want to build from CVS source, following commands are required.
|
||||
* bison ((<URL:http://gnuwin32.sourceforge.net/packages/bison.htm>))
|
||||
* sed ((<URL:http://gnuwin32.sourceforge.net/packages/sed.htm>))
|
||||
|
||||
(4) We strongly recommend to build ruby on C++Builder, to link following files.
|
||||
* usebormm.lib
|
||||
* memmgr.lib
|
||||
|
||||
RTL's internal memory manager cannot handle large memory block properly,
|
||||
so we should use borlndmm.dll instead.
|
||||
10000.times { "" << "." * 529671; GC.start } # crash
|
||||
|
||||
== How to compile and install
|
||||
|
||||
(1) Execute bcc32\configure.bat on your build directory.
|
||||
ex. c:\src\ruby> bcc32\configure.bat
|
||||
You can specify the target platform as an argument.
|
||||
For example, run `((%configure i686-bccwin32%))'
|
||||
You can also specify the install directory.
|
||||
For example, run `((%configure --prefix=<install_directory>%))'
|
||||
Default of the install directory is /usr .
|
||||
The default ((|<PLATFORM>|)) is `(({i386-bccwin32}))'.
|
||||
|
||||
(2) Change ((|RUBY_INSTALL_NAME|)) and ((|RUBY_SO_NAME|)) in (({Makefile}))
|
||||
if you want to change the name of the executable files.
|
||||
And add ((|RUBYW_INSTALL_NAME|)) to change the name of the
|
||||
executable without console window if also you want.
|
||||
|
||||
(3) Run `((%make%))'
|
||||
|
||||
(4) Run `((%make test%))'
|
||||
|
||||
(5) Run `((%make install%))'
|
||||
|
||||
(6) Requires dynamic RTL (cc3250.dll on C++Builder5) and borlndmm.dll (If built with
|
||||
usebormm.lib) to use installed binary. These files are ordinary in bcc32's bin
|
||||
directory.
|
||||
|
||||
== Icons
|
||||
|
||||
Any icon files(*.ico) in the build directory, directories specified with
|
||||
((|icondirs|)) make variable and (({win32})) directory under the ruby
|
||||
source directory will be included in DLL or executable files, according
|
||||
to their base names.
|
||||
$(RUBY_INSTALL_NAME).ico or ruby.ico --> $(RUBY_INSTALL_NAME).exe
|
||||
$(RUBYW_INSTALL_NAME).ico or rubyw.ico --> $(RUBYW_INSTALL_NAME).exe
|
||||
the others --> $(RUBY_SO_NAME).dll
|
||||
|
||||
Although no icons are distributed with the ruby source or in the official
|
||||
site, you can use anything you like. For example, followings are written
|
||||
in Japanese, but you can download at least.
|
||||
|
||||
* ((<URL:http://member.nifty.ne.jp/ueivu/rubyico.html>)) or
|
||||
((<zipped icons|URL:http://member.nifty.ne.jp/ueivu/Ruby_ico.zip>))
|
||||
* ((<URL:http://homepage1.nifty.com/a_nakata/ruby/>)) or
|
||||
((<icon itself|URL:http://homepage1.nifty.com/a_nakata/ruby/RubyIcon.ico>))
|
||||
|
||||
== Build examples
|
||||
|
||||
* Build on the ruby source directory.
|
||||
|
||||
ex.)
|
||||
ruby source directory: C:\ruby
|
||||
build directory: C:\ruby
|
||||
install directory: C:\usr\local
|
||||
|
||||
C:
|
||||
cd \ruby
|
||||
bcc32\configure --prefix=/usr/local
|
||||
make
|
||||
make test
|
||||
make install
|
||||
|
||||
* Build on the relative directory from the ruby source directory and CPU type
|
||||
i386.
|
||||
|
||||
ex.)
|
||||
ruby source directory: C:\ruby
|
||||
build directory: C:\ruby\bccwin32
|
||||
install directory: C:\usr\local
|
||||
CPU i386
|
||||
|
||||
C:
|
||||
cd \ruby
|
||||
mkdir bccwin32
|
||||
cd bccwin32
|
||||
..\bcc32\configure --prefix=/usr/local
|
||||
make
|
||||
make test
|
||||
make install
|
||||
|
||||
* Build on the different drive.
|
||||
|
||||
ex.)
|
||||
ruby source directory: C:\src\ruby
|
||||
build directory: D:\build\ruby
|
||||
install directory: C:\usr\local
|
||||
|
||||
D:
|
||||
cd D:\build\ruby
|
||||
C:\src\ruby\bcc32\configure --prefix=C:/usr/local
|
||||
make
|
||||
make test
|
||||
make install
|
||||
|
||||
== Bugs
|
||||
|
||||
You can ((*NOT*)) use a path name contains any white space characters as
|
||||
the ruby source directory, this restriction comes from the behavior of
|
||||
(({!INCLUDE})) directives of (({MAKE})).
|
||||
((- you may call it a bug. -))
|
||||
|
||||
=end
|
|
@ -1,163 +0,0 @@
|
|||
@echo off
|
||||
::: Don't set environment variable in batch file other than autoexec.bat
|
||||
::: to avoid "Out of environment space" problem on Windows 95/98.
|
||||
::: set TMPMAKE=~tmp~.mak
|
||||
|
||||
echo> ~tmp~.mak ####
|
||||
echo>> ~tmp~.mak conf = %0
|
||||
echo>> ~tmp~.mak $(conf:\=/): nul
|
||||
echo>> ~tmp~.mak @del ~setup~.mak
|
||||
echo>> ~tmp~.mak @-$(MAKE) -l$(MAKEFLAGS) -f $(@D)setup.mak \
|
||||
if exist pathlist.tmp del pathlist.tmp
|
||||
if exist confargs.mk del confargs.mk
|
||||
:loop
|
||||
if "%1" == "" goto :end
|
||||
if "%1" == "--prefix" goto :prefix
|
||||
if "%1" == "prefix" goto :prefix
|
||||
if "%1" == "--srcdir" goto :srcdir
|
||||
if "%1" == "srcdir" goto :srcdir
|
||||
if "%1" == "--target" goto :target
|
||||
if "%1" == "target" goto :target
|
||||
if "%1" == "--with-static-linked-ext" goto :extstatic
|
||||
if "%1" == "--program-suffix" goto :suffix
|
||||
if "%1" == "RUBY_SUFFIX" goto :suffix
|
||||
if "%1" == "--program-name" goto :installname
|
||||
if "%1" == "--install-name" goto :installname
|
||||
if "%1" == "RUBY_INSTALL_NAME" goto :installname
|
||||
if "%1" == "--so-name" goto :soname
|
||||
if "%1" == "RUBY_SO_NAME" goto :soname
|
||||
if "%1" == "--enable-install-doc" goto :enable-rdoc
|
||||
if "%1" == "--disable-install-doc" goto :disable-rdoc
|
||||
if "%1" == "--extout" goto :extout
|
||||
if "%1" == "EXTOUT" goto :extout
|
||||
if "%1" == "--with-baseruby" goto :baseruby
|
||||
if "%1" == "BASERUBY" goto :baseruby
|
||||
if "%1" == "--path" goto :path
|
||||
if "%1" == "-h" goto :help
|
||||
if "%1" == "--help" goto :help
|
||||
echo>>confargs.tmp %1 \
|
||||
shift
|
||||
goto :loop
|
||||
:srcdir
|
||||
echo>> ~tmp~.mak -Dsrcdir=%2 \
|
||||
echo>>confargs.tmp --srcdir=%2 \
|
||||
shift
|
||||
shift
|
||||
goto :loop
|
||||
:prefix
|
||||
echo>> ~tmp~.mak -Dprefix=%2 \
|
||||
echo>>confargs.tmp %1=%2 \
|
||||
shift
|
||||
shift
|
||||
goto :loop
|
||||
:suffix
|
||||
echo>>confargs.mk !ifndef RUBY_SUFFIX
|
||||
echo>>confargs.mk RUBY_SUFFIX = %2
|
||||
echo>>confargs.mk !endif
|
||||
echo>>confargs.tmp %1=%2 \
|
||||
shift
|
||||
shift
|
||||
goto :loop
|
||||
:installname
|
||||
echo>>confargs.mk !ifndef RUBY_INSTALL_NAME
|
||||
echo>>confargs.mk RUBY_INSTALL_NAME = %2
|
||||
echo>>confargs.mk !endif
|
||||
echo>>confargs.tmp %1=%2 \
|
||||
shift
|
||||
shift
|
||||
goto :loop
|
||||
:soname
|
||||
echo>>confargs.mk !ifndef RUBY_SO_NAME
|
||||
echo>>confargs.mk RUBY_SO_NAME = %2
|
||||
echo>>confargs.mk !endif
|
||||
echo>>confargs.tmp %1=%2 \
|
||||
shift
|
||||
shift
|
||||
goto :loop
|
||||
:target
|
||||
echo>> ~tmp~.mak %2 \
|
||||
echo>>confargs.tmp --target=%2 \
|
||||
shift
|
||||
shift
|
||||
goto :loop
|
||||
:extstatic
|
||||
echo>>confargs.mk !ifndef EXTSTATIC
|
||||
echo>>confargs.mk EXTSTATIC = static
|
||||
echo>>confargs.mk !endif
|
||||
echo>>confargs.tmp %1 \
|
||||
shift
|
||||
goto :loop
|
||||
:enable-rdoc
|
||||
echo>>confargs.mk !ifndef RDOCTARGET
|
||||
echo>>confargs.mk RDOCTARGET = install-doc
|
||||
echo>>confargs.mk !endif
|
||||
echo>>confargs.tmp %1 \
|
||||
shift
|
||||
goto :loop
|
||||
:disable-rdoc
|
||||
echo>>confargs.mk !ifndef RDOCTARGET
|
||||
echo>>confargs.mk RDOCTARGET = install-nodoc
|
||||
echo>>confargs.mk !endif
|
||||
echo>>confargs.tmp %1 \
|
||||
shift
|
||||
goto :loop
|
||||
:extout
|
||||
echo>>confargs.mk !ifndef EXTOUT
|
||||
echo>>confargs.mk EXTOUT = %2
|
||||
echo>>confargs.mk !endif
|
||||
echo>>confargs.tmp %1=%2 \
|
||||
shift
|
||||
shift
|
||||
goto :loop
|
||||
:baseruby
|
||||
echo>>confargs.mk !ifndef BASERUBY
|
||||
echo>>confargs.mk BASERUBY = %2
|
||||
echo>>confargs.mk !endif
|
||||
echo>>confargs.tmp %1=%2 \
|
||||
shift
|
||||
shift
|
||||
goto :loop
|
||||
:path
|
||||
echo>>pathlist.tmp %2;\
|
||||
echo>>confargs.tmp %1=%2 \
|
||||
shift
|
||||
shift
|
||||
goto :loop
|
||||
:help
|
||||
echo Configuration:
|
||||
echo --help display this help
|
||||
echo --srcdir=DIR find the sources in DIR [configure dir or `..']
|
||||
echo Installation directories:
|
||||
echo --prefix=PREFIX install files in PREFIX (ignored currently)
|
||||
echo System types:
|
||||
echo --target=TARGET configure for TARGET [i386-bccwin32]
|
||||
echo Optional Package:
|
||||
echo --with-baseruby=RUBY use RUBY as baseruby [ruby]
|
||||
echo --with-static-linked-ext link external modules statically
|
||||
echo --enable-install-doc install rdoc indexes during install
|
||||
del *.tmp
|
||||
del ~tmp~.mak
|
||||
goto :exit
|
||||
:end
|
||||
echo>> ~tmp~.mak -Dbcc32dir=$(@D)
|
||||
if not exist confargs.tmp goto :noconfargs
|
||||
echo>>confargs.mk configure_args = \
|
||||
type>>confargs.mk confargs.tmp
|
||||
echo.>>confargs.mk
|
||||
echo>>confargs.mk ####
|
||||
:noconfargs
|
||||
if not exist pathlist.tmp goto :nopathlist
|
||||
echo>>confargs.mk pathlist = \
|
||||
type>>confargs.mk pathlist.tmp
|
||||
echo.>>confargs.mk
|
||||
echo>>confargs.mk ####
|
||||
echo>>confargs.mk PATH = $(pathlist:;=/bin;)$(PATH)
|
||||
echo>>confargs.mk INCLUDE = $(pathlist:;=/include;)
|
||||
echo>>confargs.mk LIB = $(pathlist:;=/lib;)
|
||||
:nopathlist
|
||||
if exist confargs.mk copy confargs.mk ~setup~.mak > nul
|
||||
type>>~setup~.mak ~tmp~.mak
|
||||
del *.tmp > nul
|
||||
del ~tmp~.mak > nul
|
||||
make -s -f ~setup~.mak
|
||||
:exit
|
|
@ -1,26 +0,0 @@
|
|||
#!./miniruby -s
|
||||
|
||||
$:.unshift(File.expand_path("../..", __FILE__))
|
||||
require 'win32/mkexports'
|
||||
|
||||
class Exports::Bcc < Exports
|
||||
def forwarding(internal, export)
|
||||
internal[/\A_?/]+export
|
||||
end
|
||||
|
||||
def each_line(objs, &block)
|
||||
objs.each do |obj|
|
||||
opt = /\.(?:so|dll)\z/i =~ obj ? "-ee" : "-oiPUBDEF -oiPUBD32"
|
||||
IO.foreach("|tdump -q #{opt} #{obj.tr('/', '\\')} < nul", &block)
|
||||
end
|
||||
end
|
||||
|
||||
def each_export(objs)
|
||||
objdump(objs) do |l|
|
||||
next unless /(?:PUBDEF|PUBD32|EXPORT)/ =~ l
|
||||
yield $1 if /'(.*?)'/ =~ l
|
||||
end
|
||||
yield "_strcasecmp", "_stricmp"
|
||||
yield "_strncasecmp", "_strnicmp"
|
||||
end
|
||||
end
|
179
bcc32/setup.mak
179
bcc32/setup.mak
|
@ -1,179 +0,0 @@
|
|||
# -*- makefile -*-
|
||||
|
||||
!if "$(srcdir)" != ""
|
||||
bcc32dir = $(srcdir)/bcc32
|
||||
!elseif "$(bcc32dir)" == "bcc32/"
|
||||
srcdir = .
|
||||
!elseif "$(bcc32dir:/bcc32/=)/bcc32/" == "$(bcc32dir)"
|
||||
srcdir = $(bcc32dir:/bcc32/=)
|
||||
!else
|
||||
srcdir = $(bcc32dir)/..
|
||||
!endif
|
||||
!ifndef prefix
|
||||
prefix = /usr
|
||||
!endif
|
||||
OS = bccwin32
|
||||
RT = $(OS)
|
||||
BANG = !
|
||||
APPEND = echo.>>$(MAKEFILE)
|
||||
!ifdef MAKEFILE
|
||||
MAKE = $(MAKE) -f $(MAKEFILE)
|
||||
!else
|
||||
MAKEFILE = Makefile
|
||||
!endif
|
||||
|
||||
all: Makefile
|
||||
Makefile: -prologue- -generic- -epilogue-
|
||||
i386-$(OS): -prologue- -i386- -epilogue-
|
||||
i486-$(OS): -prologue- -i486- -epilogue-
|
||||
i586-$(OS): -prologue- -i586- -epilogue-
|
||||
i686-$(OS): -prologue- -i686- -epilogue-
|
||||
alpha-$(OS): -prologue- -alpha- -epilogue-
|
||||
|
||||
-prologue-: -basic-vars- -version- -system-vars-
|
||||
|
||||
-basic-vars-: nul
|
||||
@echo Creating $(MAKEFILE)
|
||||
@type > $(MAKEFILE) &&|
|
||||
\#\#\# Makefile for ruby $(OS) \#\#\#
|
||||
$(BANG)ifndef srcdir
|
||||
srcdir = $(srcdir:\=/)
|
||||
$(BANG)endif
|
||||
$(BANG)ifndef prefix
|
||||
prefix = $(prefix:\=/)
|
||||
$(BANG)endif
|
||||
$(BANG)if !defined(BASERUBY)
|
||||
!if defined(BASERUBY)
|
||||
BASERUBY = $(BASERUBY)
|
||||
!endif
|
||||
|
|
||||
!if !defined(BASERUBY)
|
||||
@for %I in (ruby.exe) do @echo BASERUBY = "%~$$PATH:I" >> $(MAKEFILE)
|
||||
!endif
|
||||
@type >> $(MAKEFILE) &&|
|
||||
$(BANG)endif
|
||||
|
|
||||
!if exist(confargs.mk)
|
||||
@type confargs.mk >> $(MAKEFILE)
|
||||
@del confargs.mk
|
||||
!endif
|
||||
|
||||
-system-vars-: -runtime- -bormm-
|
||||
|
||||
-bormm-: nul
|
||||
@-ilink32 -q -Gn -x usebormm.lib > nul
|
||||
@-if exist usebormm.tds $(APPEND) MEMLIB = usebormm.lib
|
||||
@if exist usebormm.* del usebormm.*
|
||||
|
||||
-osname-: nul
|
||||
@echo OS = >>$(MAKEFILE)
|
||||
|
||||
-runtime-: nul
|
||||
type > conftest.c &&|
|
||||
\#include <stdio.h>
|
||||
int main(){printf("");return 0;}
|
||||
|
|
||||
bcc32 conftest.c cw32i.lib > nul
|
||||
tdump conftest.exe < nul > conftest.i
|
||||
grep "^Imports from CC" conftest.i > conftest.c
|
||||
cpp32 -P- -DFile=\# -DImports=RTNAME -Dfrom== conftest.c > nul
|
||||
$(MAKE) > nul -DBANG=$(BANG) -f &&|
|
||||
-runtime-: nul
|
||||
$(BANG)include conftest.i
|
||||
RT = $$(RTNAME:.DLL=)
|
||||
OS = $$(RT:CC32=)
|
||||
-runtime-:
|
||||
del conftest.*
|
||||
$(BANG)if "$$(OS)" == "50"
|
||||
echo OS = bccwin32 >> $(MAKEFILE)
|
||||
$(BANG)else
|
||||
echo OS = bccwin32_$$(OS) >> $(MAKEFILE)
|
||||
$(BANG)endif
|
||||
|
|
||||
@echo RT = $$(OS) >> $(MAKEFILE)
|
||||
|
||||
-version-: nul
|
||||
@cpp32 -I$(srcdir) -P- -o$(MAKEFILE) > nul &&|
|
||||
\#define RUBY_REVISION 0
|
||||
\#include "version.h"
|
||||
MAJOR = RUBY_API_VERSION_MAJOR
|
||||
MINOR = RUBY_API_VERSION_MINOR
|
||||
TEENY = RUBY_API_VERSION_TEENY
|
||||
|
||||
BORLANDC = __BORLANDC__
|
||||
|
|
||||
@$(MAKE) > nul -DBANG=$(BANG) -f &&,
|
||||
-version-: nul
|
||||
$(BANG)include $(MAKEFILE)
|
||||
$(BANG)include $(MAKEFILE).i
|
||||
-version-:
|
||||
@del $(MAKEFILE).i
|
||||
@type >> $(MAKEFILE) &&|
|
||||
MAJOR = $$(MAJOR)
|
||||
MINOR = $$(MINOR)
|
||||
TEENY = $$(TEENY)
|
||||
BORLANDC = $$(BORLANDC)
|
||||
|
|
||||
,
|
||||
|
||||
-generic-: nul
|
||||
!if defined(PROCESSOR_ARCHITECTURE) || defined(PROCESSOR_LEVEL)
|
||||
@type >> $(MAKEFILE) &&|
|
||||
!if defined(PROCESSOR_ARCHITECTURE)
|
||||
$(BANG)ifndef PROCESSOR_ARCHITECTURE
|
||||
PROCESSOR_ARCHITECTURE = $(PROCESSOR_ARCHITECTURE)
|
||||
$(BANG)endif
|
||||
!endif
|
||||
!if defined(PROCESSOR_LEVEL)
|
||||
$(BANG)ifndef PROCESSOR_LEVEL
|
||||
PROCESSOR_LEVEL = $(PROCESSOR_LEVEL)
|
||||
$(BANG)endif
|
||||
!endif
|
||||
|
|
||||
!endif
|
||||
|
||||
-alpha-: nul
|
||||
@$(APPEND) !ifndef PROCESSOR_ARCHITECTURE
|
||||
@$(APPEND) PROCESSOR_ARCHITECTURE = alpha
|
||||
@$(APPEND) !endif
|
||||
-ix86-: nul
|
||||
@$(APPEND) !ifndef PROCESSOR_ARCHITECTURE
|
||||
@$(APPEND) PROCESSOR_ARCHITECTURE = x86
|
||||
@$(APPEND) !endif
|
||||
|
||||
-i386-: -ix86-
|
||||
@$(APPEND) !ifndef PROCESSOR_LEVEL
|
||||
@$(APPEND) PROCESSOR_LEVEL = 3
|
||||
@$(APPEND) !endif
|
||||
-i486-: -ix86-
|
||||
@$(APPEND) !ifndef PROCESSOR_LEVEL
|
||||
@$(APPEND) PROCESSOR_LEVEL = 4
|
||||
@$(APPEND) !endif
|
||||
-i586-: -ix86-
|
||||
@$(APPEND) !ifndef PROCESSOR_LEVEL
|
||||
@$(APPEND) PROCESSOR_LEVEL = 5
|
||||
@$(APPEND) !endif
|
||||
-i686-: -ix86-
|
||||
@$(APPEND) !ifndef PROCESSOR_LEVEL
|
||||
@$(APPEND) PROCESSOR_LEVEL = 6
|
||||
@$(APPEND) !endif
|
||||
|
||||
-epilogue-: -encs-
|
||||
|
||||
-encs-: nul
|
||||
@$(MAKE) -f $(srcdir)/win32/enc-setup.mak srcdir="$(srcdir)" MAKEFILE=$(MAKEFILE)
|
||||
|
||||
-epilogue-: nul
|
||||
@type >> $(MAKEFILE) &&|
|
||||
|
||||
\# RUBY_INSTALL_NAME = ruby
|
||||
\# RUBY_SO_NAME = $$(RT)-$$(RUBY_INSTALL_NAME)$$(MAJOR)$$(MINOR)
|
||||
\# CFLAGS = -q $$(DEBUGFLAGS) $$(OPTFLAGS) $$(PROCESSOR_FLAG) -w- -wsus -wcpt -wdup -wext -wrng -wrpt -wzdi
|
||||
\# CPPFLAGS = -I. -I$$(srcdir) -I$$(srcdir)/missing -DLIBRUBY_SO=\"$$(LIBRUBY_SO)\"
|
||||
\# STACK = 0x2000000
|
||||
\# LDFLAGS = -S:$$(STACK)
|
||||
\# RFLAGS = $$(iconinc)
|
||||
\# EXTLIBS = cw32.lib import32.lib user32.lib kernel32.lib
|
||||
$(BANG)include $$(srcdir)/bcc32/Makefile.sub
|
||||
|
|
||||
@echo type "`$(MAKE)'" to make ruby for $(OS).
|
292
benchmark/bm_app_aobench.rb
Normal file
292
benchmark/bm_app_aobench.rb
Normal file
|
@ -0,0 +1,292 @@
|
|||
# AO rebder benchmark
|
||||
# Original program (C) Syoyo Fujita in Javascript (and other languages)
|
||||
# http://lucille.atso-net.jp/blog/?p=642
|
||||
# http://lucille.atso-net.jp/blog/?p=711
|
||||
# Ruby(yarv2llvm) version by Hideki Miura
|
||||
#
|
||||
|
||||
IMAGE_WIDTH = 256
|
||||
IMAGE_HEIGHT = 256
|
||||
NSUBSAMPLES = 2
|
||||
NAO_SAMPLES = 8
|
||||
|
||||
class Vec
|
||||
def initialize(x, y, z)
|
||||
@x = x
|
||||
@y = y
|
||||
@z = z
|
||||
end
|
||||
|
||||
attr_accessor :x, :y, :z
|
||||
|
||||
def vadd(b)
|
||||
Vec.new(@x + b.x, @y + b.y, @z + b.z)
|
||||
end
|
||||
|
||||
def vsub(b)
|
||||
Vec.new(@x - b.x, @y - b.y, @z - b.z)
|
||||
end
|
||||
|
||||
def vcross(b)
|
||||
Vec.new(@y * b.z - @z * b.y,
|
||||
@z * b.x - @x * b.z,
|
||||
@x * b.y - @y * b.x)
|
||||
end
|
||||
|
||||
def vdot(b)
|
||||
@x * b.x + @y * b.y + @z * b.z
|
||||
end
|
||||
|
||||
def vlength
|
||||
Math.sqrt(@x * @x + @y * @y + @z * @z)
|
||||
end
|
||||
|
||||
def vnormalize
|
||||
len = vlength
|
||||
v = Vec.new(@x, @y, @z)
|
||||
if len > 1.0e-17 then
|
||||
v.x = v.x / len
|
||||
v.y = v.y / len
|
||||
v.z = v.z / len
|
||||
end
|
||||
v
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class Sphere
|
||||
def initialize(center, radius)
|
||||
@center = center
|
||||
@radius = radius
|
||||
end
|
||||
|
||||
attr_reader :center, :radius
|
||||
|
||||
def intersect(ray, isect)
|
||||
rs = ray.org.vsub(@center)
|
||||
b = rs.vdot(ray.dir)
|
||||
c = rs.vdot(rs) - (@radius * @radius)
|
||||
d = b * b - c
|
||||
if d > 0.0 then
|
||||
t = - b - Math.sqrt(d)
|
||||
|
||||
if t > 0.0 and t < isect.t then
|
||||
isect.t = t
|
||||
isect.hit = true
|
||||
isect.pl = Vec.new(ray.org.x + ray.dir.x * t,
|
||||
ray.org.y + ray.dir.y * t,
|
||||
ray.org.z + ray.dir.z * t)
|
||||
n = isect.pl.vsub(@center)
|
||||
isect.n = n.vnormalize
|
||||
else
|
||||
0.0
|
||||
end
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
class Plane
|
||||
def initialize(p, n)
|
||||
@p = p
|
||||
@n = n
|
||||
end
|
||||
|
||||
def intersect(ray, isect)
|
||||
d = -@p.vdot(@n)
|
||||
v = ray.dir.vdot(@n)
|
||||
v0 = v
|
||||
if v < 0.0 then
|
||||
v0 = -v
|
||||
end
|
||||
if v0 < 1.0e-17 then
|
||||
return
|
||||
end
|
||||
|
||||
t = -(ray.org.vdot(@n) + d) / v
|
||||
|
||||
if t > 0.0 and t < isect.t then
|
||||
isect.hit = true
|
||||
isect.t = t
|
||||
isect.n = @n
|
||||
isect.pl = Vec.new(ray.org.x + t * ray.dir.x,
|
||||
ray.org.y + t * ray.dir.y,
|
||||
ray.org.z + t * ray.dir.z)
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
class Ray
|
||||
def initialize(org, dir)
|
||||
@org = org
|
||||
@dir = dir
|
||||
end
|
||||
|
||||
attr_accessor :org, :dir
|
||||
end
|
||||
|
||||
class Isect
|
||||
def initialize
|
||||
@t = 10000000.0
|
||||
@hit = false
|
||||
@pl = Vec.new(0.0, 0.0, 0.0)
|
||||
@n = Vec.new(0.0, 0.0, 0.0)
|
||||
end
|
||||
|
||||
attr_accessor :t, :hit, :pl, :n
|
||||
end
|
||||
|
||||
def clamp(f)
|
||||
i = f * 255.5
|
||||
if i > 255.0 then
|
||||
i = 255.0
|
||||
end
|
||||
if i < 0.0 then
|
||||
i = 0.0
|
||||
end
|
||||
i.to_i
|
||||
end
|
||||
|
||||
def otherBasis(basis, n)
|
||||
basis[2] = Vec.new(n.x, n.y, n.z)
|
||||
basis[1] = Vec.new(0.0, 0.0, 0.0)
|
||||
|
||||
if n.x < 0.6 and n.x > -0.6 then
|
||||
basis[1].x = 1.0
|
||||
elsif n.y < 0.6 and n.y > -0.6 then
|
||||
basis[1].y = 1.0
|
||||
elsif n.z < 0.6 and n.z > -0.6 then
|
||||
basis[1].z = 1.0
|
||||
else
|
||||
basis[1].x = 1.0
|
||||
end
|
||||
|
||||
basis[0] = basis[1].vcross(basis[2])
|
||||
basis[0] = basis[0].vnormalize
|
||||
|
||||
basis[1] = basis[2].vcross(basis[0])
|
||||
basis[1] = basis[1].vnormalize
|
||||
end
|
||||
|
||||
class Scene
|
||||
def initialize
|
||||
@spheres = Array.new
|
||||
@spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5)
|
||||
@spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5)
|
||||
@spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5)
|
||||
@plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0))
|
||||
end
|
||||
|
||||
def ambient_occlusion(isect)
|
||||
basis = Array.new
|
||||
otherBasis(basis, isect.n)
|
||||
|
||||
ntheta = NAO_SAMPLES
|
||||
nphi = NAO_SAMPLES
|
||||
eps = 0.0001
|
||||
occlusion = 0.0
|
||||
|
||||
p0 = Vec.new(isect.pl.x + eps * isect.n.x,
|
||||
isect.pl.y + eps * isect.n.y,
|
||||
isect.pl.z + eps * isect.n.z)
|
||||
nphi.times do |j|
|
||||
ntheta.times do |i|
|
||||
r = rand
|
||||
phi = 2.0 * 3.14159265 * rand
|
||||
x = Math.cos(phi) * Math.sqrt(1.0 - r)
|
||||
y = Math.sin(phi) * Math.sqrt(1.0 - r)
|
||||
z = Math.sqrt(r)
|
||||
|
||||
rx = x * basis[0].x + y * basis[1].x + z * basis[2].x
|
||||
ry = x * basis[0].y + y * basis[1].y + z * basis[2].y
|
||||
rz = x * basis[0].z + y * basis[1].z + z * basis[2].z
|
||||
|
||||
raydir = Vec.new(rx, ry, rz)
|
||||
ray = Ray.new(p0, raydir)
|
||||
|
||||
occisect = Isect.new
|
||||
@spheres[0].intersect(ray, occisect)
|
||||
@spheres[1].intersect(ray, occisect)
|
||||
@spheres[2].intersect(ray, occisect)
|
||||
@plane.intersect(ray, occisect)
|
||||
if occisect.hit then
|
||||
occlusion = occlusion + 1.0
|
||||
else
|
||||
0.0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f)
|
||||
|
||||
Vec.new(occlusion, occlusion, occlusion)
|
||||
end
|
||||
|
||||
def render(w, h, nsubsamples)
|
||||
cnt = 0
|
||||
nsf = nsubsamples.to_f
|
||||
h.times do |y|
|
||||
w.times do |x|
|
||||
rad = Vec.new(0.0, 0.0, 0.0)
|
||||
|
||||
# Subsmpling
|
||||
nsubsamples.times do |v|
|
||||
nsubsamples.times do |u|
|
||||
|
||||
cnt = cnt + 1
|
||||
wf = w.to_f
|
||||
hf = h.to_f
|
||||
xf = x.to_f
|
||||
yf = y.to_f
|
||||
uf = u.to_f
|
||||
vf = v.to_f
|
||||
|
||||
px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0)
|
||||
py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0)
|
||||
|
||||
eye = Vec.new(px, py, -1.0).vnormalize
|
||||
|
||||
ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye)
|
||||
|
||||
isect = Isect.new
|
||||
@spheres[0].intersect(ray, isect)
|
||||
@spheres[1].intersect(ray, isect)
|
||||
@spheres[2].intersect(ray, isect)
|
||||
@plane.intersect(ray, isect)
|
||||
if isect.hit then
|
||||
col = ambient_occlusion(isect)
|
||||
rad.x = rad.x + col.x
|
||||
rad.y = rad.y + col.y
|
||||
rad.z = rad.z + col.z
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
r = rad.x / (nsf * nsf)
|
||||
g = rad.y / (nsf * nsf)
|
||||
b = rad.z / (nsf * nsf)
|
||||
printf("%c", clamp(r))
|
||||
printf("%c", clamp(g))
|
||||
printf("%c", clamp(b))
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
alias printf_orig printf
|
||||
def printf *args
|
||||
end
|
||||
|
||||
# File.open("ao.ppm", "w") do |fp|
|
||||
printf("P6\n")
|
||||
printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT)
|
||||
printf("255\n", IMAGE_WIDTH, IMAGE_HEIGHT)
|
||||
Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES)
|
||||
# end
|
||||
|
||||
undef printf
|
||||
alias printf printf_orig
|
9
benchmark/bm_hash_flatten.rb
Normal file
9
benchmark/bm_hash_flatten.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
h = {}
|
||||
|
||||
10000.times do |i|
|
||||
h[i] = nil
|
||||
end
|
||||
|
||||
1000.times do
|
||||
h.flatten
|
||||
end
|
9
benchmark/bm_hash_keys.rb
Normal file
9
benchmark/bm_hash_keys.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
h = {}
|
||||
|
||||
10000.times do |i|
|
||||
h[i] = nil
|
||||
end
|
||||
|
||||
5000.times do
|
||||
h.keys
|
||||
end
|
10
benchmark/bm_hash_shift.rb
Normal file
10
benchmark/bm_hash_shift.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
h = {}
|
||||
|
||||
10000.times do |i|
|
||||
h[i] = nil
|
||||
end
|
||||
|
||||
50000.times do
|
||||
k, v = h.shift
|
||||
h[k] = v
|
||||
end
|
9
benchmark/bm_hash_values.rb
Normal file
9
benchmark/bm_hash_values.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
h = {}
|
||||
|
||||
10000.times do |i|
|
||||
h[i] = nil
|
||||
end
|
||||
|
||||
5000.times do
|
||||
h.values
|
||||
end
|
|
@ -4,7 +4,9 @@
|
|||
# contributed by Jesse Millikan
|
||||
|
||||
# disable output
|
||||
def STDOUT.write_ *args
|
||||
alias puts_orig puts
|
||||
def puts str
|
||||
# disable puts
|
||||
end
|
||||
|
||||
def item_check(tree)
|
||||
|
@ -25,7 +27,7 @@ def bottom_up_tree(item, depth)
|
|||
end
|
||||
end
|
||||
|
||||
max_depth = 12 # 16 # ARGV[0].to_i
|
||||
max_depth = 16 # ARGV[0].to_i
|
||||
min_depth = 4
|
||||
|
||||
max_depth = min_depth + 2 if min_depth + 2 > max_depth
|
||||
|
@ -55,3 +57,6 @@ min_depth.step(max_depth + 1, 2) do |depth|
|
|||
end
|
||||
|
||||
puts "long lived tree of depth #{max_depth}\t check: #{item_check(long_lived_tree)}"
|
||||
|
||||
undef puts
|
||||
alias puts puts_orig
|
||||
|
|
10
benchmark/bm_vm1_gc_short_lived.rb
Normal file
10
benchmark/bm_vm1_gc_short_lived.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
i = 0
|
||||
while i<30_000_000 # while loop 1
|
||||
a = '' # short-lived String
|
||||
b = ''
|
||||
c = ''
|
||||
d = ''
|
||||
e = ''
|
||||
f = ''
|
||||
i+=1
|
||||
end
|
27
benchmark/bm_vm1_gc_short_with_complex_long.rb
Normal file
27
benchmark/bm_vm1_gc_short_with_complex_long.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
def nested_hash h, n
|
||||
if n == 0
|
||||
''
|
||||
else
|
||||
10.times{
|
||||
h[Object.new] = nested_hash(h, n-1)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
long_lived = Hash.new
|
||||
nested_hash long_lived, 6
|
||||
|
||||
GC.start
|
||||
GC.start
|
||||
|
||||
i = 0
|
||||
while i<30_000_000 # while loop 1
|
||||
a = '' # short-lived String
|
||||
b = ''
|
||||
c = ''
|
||||
d = ''
|
||||
e = ''
|
||||
f = ''
|
||||
i+=1
|
||||
end
|
||||
|
13
benchmark/bm_vm1_gc_short_with_long.rb
Normal file
13
benchmark/bm_vm1_gc_short_with_long.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
long_lived = Array.new(1_000_000){|i| "#{i}"}
|
||||
GC.start
|
||||
GC.start
|
||||
i = 0
|
||||
while i<30_000_000 # while loop 1
|
||||
a = '' # short-lived String
|
||||
b = ''
|
||||
c = ''
|
||||
d = ''
|
||||
e = ''
|
||||
f = ''
|
||||
i+=1
|
||||
end
|
15
benchmark/bm_vm1_gc_short_with_symbol.rb
Normal file
15
benchmark/bm_vm1_gc_short_with_symbol.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
# make many symbols
|
||||
50_000.times{|i| sym = "sym#{i}".to_sym}
|
||||
GC.start
|
||||
GC.start
|
||||
|
||||
i = 0
|
||||
while i<30_000_000 # while loop 1
|
||||
a = '' # short-lived String
|
||||
b = ''
|
||||
c = ''
|
||||
d = ''
|
||||
e = ''
|
||||
f = ''
|
||||
i+=1
|
||||
end
|
10
benchmark/bm_vm1_gc_wb_ary.rb
Normal file
10
benchmark/bm_vm1_gc_wb_ary.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
long_lived = []
|
||||
GC.start
|
||||
GC.start
|
||||
|
||||
i = 0
|
||||
short_lived = ''
|
||||
while i<30_000_000 # while loop 1
|
||||
long_lived[0] = short_lived # write barrier
|
||||
i+=1
|
||||
end
|
13
benchmark/bm_vm1_gc_wb_obj.rb
Normal file
13
benchmark/bm_vm1_gc_wb_obj.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
class C
|
||||
attr_accessor :foo
|
||||
end
|
||||
long_lived = C.new
|
||||
GC.start
|
||||
GC.start
|
||||
|
||||
i = 0
|
||||
short_lived = ''
|
||||
while i<30_000_000 # while loop 1
|
||||
long_lived.foo = short_lived # write barrier
|
||||
i+=1
|
||||
end
|
18
benchmark/bm_vm_thread_queue.rb
Normal file
18
benchmark/bm_vm_thread_queue.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
require 'thread'
|
||||
|
||||
n = 1_000_000
|
||||
q = Queue.new
|
||||
consumer = Thread.new{
|
||||
while q.pop
|
||||
# consuming
|
||||
end
|
||||
}
|
||||
|
||||
producer = Thread.new{
|
||||
n.times{
|
||||
q.push true
|
||||
}
|
||||
q.push nil
|
||||
}
|
||||
|
||||
consumer.join
|
1
benchmark/gc/aobench.rb
Normal file
1
benchmark/gc/aobench.rb
Normal file
|
@ -0,0 +1 @@
|
|||
require_relative '../bm_app_aobench.rb'
|
1
benchmark/gc/binary_trees.rb
Normal file
1
benchmark/gc/binary_trees.rb
Normal file
|
@ -0,0 +1 @@
|
|||
require_relative '../bm_so_binary_trees.rb'
|
56
benchmark/gc/gcbench.rb
Normal file
56
benchmark/gc/gcbench.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
require 'benchmark'
|
||||
require 'pp'
|
||||
require 'optparse'
|
||||
|
||||
$list = true
|
||||
$gcprof = true
|
||||
|
||||
opt = OptionParser.new
|
||||
opt.on('-q'){$list = false}
|
||||
opt.on('-d'){$gcprof = false}
|
||||
opt.parse!(ARGV)
|
||||
|
||||
script = File.join(File.dirname(__FILE__), ARGV.shift)
|
||||
script += '.rb' unless FileTest.exist?(script)
|
||||
raise "#{script} not found" unless FileTest.exist?(script)
|
||||
|
||||
puts "Script: #{script}"
|
||||
|
||||
if $gcprof
|
||||
GC::Profiler.enable
|
||||
end
|
||||
|
||||
tms = Benchmark.measure{|x|
|
||||
load script
|
||||
}
|
||||
|
||||
gc_time = 0
|
||||
|
||||
if $gcprof
|
||||
gc_time = GC::Profiler.total_time
|
||||
GC::Profiler.report if $list and RUBY_VERSION >= '2.0.0' # before 1.9.3, report() may run infinite loop
|
||||
GC::Profiler.disable
|
||||
end
|
||||
|
||||
pp GC.stat
|
||||
|
||||
puts "#{RUBY_DESCRIPTION} #{GC::OPTS.inspect}" if defined?(GC::OPTS)
|
||||
|
||||
desc = "#{RUBY_VERSION}#{RUBY_PATCHLEVEL >= 0 ? "p#{RUBY_PATCHLEVEL}" : "dev"}"
|
||||
name = File.basename(script, '.rb')
|
||||
|
||||
puts
|
||||
puts script
|
||||
puts Benchmark::CAPTION
|
||||
puts tms
|
||||
puts "GC total time (sec): #{gc_time}"
|
||||
|
||||
# show High-Water Mark on Linux
|
||||
if File.exist?('/proc/self/status') && /VmHWM:\s*(\d+.+)/ =~ File.read('/proc/self/status')
|
||||
puts
|
||||
puts "VmHWM: #{$1.chomp}"
|
||||
end
|
||||
|
||||
puts
|
||||
puts "Summary of #{name} on #{desc}\t#{tms.real}\t#{gc_time}\t#{GC.count}"
|
||||
puts " (real time in sec, GC time in sec, GC count)"
|
11
benchmark/gc/hash1.rb
Normal file
11
benchmark/gc/hash1.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
value = 0.01
|
||||
h = {}
|
||||
n = 50_000
|
||||
|
||||
1.upto(n){|i|
|
||||
h["%020d" % i] = "v-#{i}"
|
||||
}
|
||||
|
||||
(n * 1_000).times{
|
||||
''
|
||||
}
|
7
benchmark/gc/hash2.rb
Normal file
7
benchmark/gc/hash2.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
value = 0.01
|
||||
h = {}
|
||||
n = 4*(10**6)
|
||||
|
||||
1.upto(n){|i|
|
||||
h["%020d" % i] = value * i
|
||||
}
|
1
benchmark/gc/null.rb
Normal file
1
benchmark/gc/null.rb
Normal file
|
@ -0,0 +1 @@
|
|||
# null
|
1
benchmark/gc/pentomino.rb
Normal file
1
benchmark/gc/pentomino.rb
Normal file
|
@ -0,0 +1 @@
|
|||
require_relative '../bm_app_pentomino.rb'
|
13
benchmark/gc/rdoc.rb
Normal file
13
benchmark/gc/rdoc.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
require 'rdoc/rdoc'
|
||||
require 'tmpdir'
|
||||
|
||||
srcdir = File.expand_path('../..', __dir__)
|
||||
|
||||
Dir.mktmpdir('rdocbench-'){|d|
|
||||
dir = File.join(d, 'rdocbench')
|
||||
args = %W(--root #{srcdir} --page-dir #{srcdir}/doc --encoding=UTF-8 --no-force-update --all --ri --debug --quiet #{srcdir})
|
||||
args << '--op' << dir
|
||||
|
||||
r = RDoc::RDoc.new
|
||||
r.document args
|
||||
}
|
366
benchmark/gc/redblack.rb
Normal file
366
benchmark/gc/redblack.rb
Normal file
|
@ -0,0 +1,366 @@
|
|||
# This benchmark is imported from https://github.com/jruby/rubybench/blob/master/time/bench_red_black.rb
|
||||
# License is License is Apache-2
|
||||
|
||||
require 'benchmark'
|
||||
|
||||
# Algorithm based on "Introduction to Algorithms" by Cormen and others
|
||||
class RedBlackTree
|
||||
class Node
|
||||
attr_accessor :color
|
||||
attr_accessor :key
|
||||
attr_accessor :left
|
||||
attr_accessor :right
|
||||
attr_accessor :parent
|
||||
|
||||
RED = :red
|
||||
BLACK = :black
|
||||
COLORS = [RED, BLACK].freeze
|
||||
|
||||
def initialize(key, color = RED)
|
||||
raise ArgumentError, "Bad value for color parameter" unless COLORS.include?(color)
|
||||
@color = color
|
||||
@key = key
|
||||
@left = @right = @parent = NilNode.instance
|
||||
end
|
||||
|
||||
def black?
|
||||
return color == BLACK
|
||||
end
|
||||
|
||||
def red?
|
||||
return color == RED
|
||||
end
|
||||
end
|
||||
|
||||
class NilNode < Node
|
||||
class << self
|
||||
private :new
|
||||
|
||||
# it's not thread safe
|
||||
def instance
|
||||
@instance ||= begin
|
||||
def instance
|
||||
return @instance
|
||||
end
|
||||
|
||||
new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def initialize
|
||||
self.color = BLACK
|
||||
self.key = 0
|
||||
self.left = nil
|
||||
self.right = nil
|
||||
self.parent = nil
|
||||
end
|
||||
|
||||
def nil?
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
include Enumerable
|
||||
|
||||
attr_accessor :root
|
||||
attr_accessor :size
|
||||
|
||||
def initialize
|
||||
self.root = NilNode.instance
|
||||
self.size = 0
|
||||
end
|
||||
|
||||
def add(key)
|
||||
insert(Node.new(key))
|
||||
end
|
||||
|
||||
def insert(x)
|
||||
insert_helper(x)
|
||||
|
||||
x.color = Node::RED
|
||||
while x != root && x.parent.color == Node::RED
|
||||
if x.parent == x.parent.parent.left
|
||||
y = x.parent.parent.right
|
||||
if !y.nil? && y.color == Node::RED
|
||||
x.parent.color = Node::BLACK
|
||||
y.color = Node::BLACK
|
||||
x.parent.parent.color = Node::RED
|
||||
x = x.parent.parent
|
||||
else
|
||||
if x == x.parent.right
|
||||
x = x.parent
|
||||
left_rotate(x)
|
||||
end
|
||||
x.parent.color = Node::BLACK
|
||||
x.parent.parent.color = Node::RED
|
||||
right_rotate(x.parent.parent)
|
||||
end
|
||||
else
|
||||
y = x.parent.parent.left
|
||||
if !y.nil? && y.color == Node::RED
|
||||
x.parent.color = Node::BLACK
|
||||
y.color = Node::BLACK
|
||||
x.parent.parent.color = Node::RED
|
||||
x = x.parent.parent
|
||||
else
|
||||
if x == x.parent.left
|
||||
x = x.parent
|
||||
right_rotate(x)
|
||||
end
|
||||
x.parent.color = Node::BLACK
|
||||
x.parent.parent.color = Node::RED
|
||||
left_rotate(x.parent.parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
root.color = Node::BLACK
|
||||
end
|
||||
|
||||
alias << insert
|
||||
|
||||
def delete(z)
|
||||
y = (z.left.nil? || z.right.nil?) ? z : successor(z)
|
||||
x = y.left.nil? ? y.right : y.left
|
||||
x.parent = y.parent
|
||||
|
||||
if y.parent.nil?
|
||||
self.root = x
|
||||
else
|
||||
if y == y.parent.left
|
||||
y.parent.left = x
|
||||
else
|
||||
y.parent.right = x
|
||||
end
|
||||
end
|
||||
|
||||
z.key = y.key if y != z
|
||||
|
||||
if y.color == Node::BLACK
|
||||
delete_fixup(x)
|
||||
end
|
||||
|
||||
self.size -= 1
|
||||
return y
|
||||
end
|
||||
|
||||
def minimum(x = root)
|
||||
while !x.left.nil?
|
||||
x = x.left
|
||||
end
|
||||
return x
|
||||
end
|
||||
|
||||
def maximum(x = root)
|
||||
while !x.right.nil?
|
||||
x = x.right
|
||||
end
|
||||
return x
|
||||
end
|
||||
|
||||
def successor(x)
|
||||
if !x.right.nil?
|
||||
return minimum(x.right)
|
||||
end
|
||||
y = x.parent
|
||||
while !y.nil? && x == y.right
|
||||
x = y
|
||||
y = y.parent
|
||||
end
|
||||
return y
|
||||
end
|
||||
|
||||
def predecessor(x)
|
||||
if !x.left.nil?
|
||||
return maximum(x.left)
|
||||
end
|
||||
y = x.parent
|
||||
while !y.nil? && x == y.left
|
||||
x = y
|
||||
y = y.parent
|
||||
end
|
||||
return y
|
||||
end
|
||||
|
||||
def inorder_walk(x = root)
|
||||
x = self.minimum
|
||||
while !x.nil?
|
||||
yield x.key
|
||||
x = successor(x)
|
||||
end
|
||||
end
|
||||
|
||||
alias each inorder_walk
|
||||
|
||||
def reverse_inorder_walk(x = root)
|
||||
x = self.maximum
|
||||
while !x.nil?
|
||||
yield x.key
|
||||
x = predecessor(x)
|
||||
end
|
||||
end
|
||||
|
||||
alias reverse_each reverse_inorder_walk
|
||||
|
||||
def search(key, x = root)
|
||||
while !x.nil? && x.key != key
|
||||
key < x.key ? x = x.left : x = x.right
|
||||
end
|
||||
return x
|
||||
end
|
||||
|
||||
def empty?
|
||||
return self.root.nil?
|
||||
end
|
||||
|
||||
def black_height(x = root)
|
||||
height = 0
|
||||
while !x.nil?
|
||||
x = x.left
|
||||
height +=1 if x.nil? || x.black?
|
||||
end
|
||||
return height
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def left_rotate(x)
|
||||
raise "x.right is nil!" if x.right.nil?
|
||||
y = x.right
|
||||
x.right = y.left
|
||||
y.left.parent = x if !y.left.nil?
|
||||
y.parent = x.parent
|
||||
if x.parent.nil?
|
||||
self.root = y
|
||||
else
|
||||
if x == x.parent.left
|
||||
x.parent.left = y
|
||||
else
|
||||
x.parent.right = y
|
||||
end
|
||||
end
|
||||
y.left = x
|
||||
x.parent = y
|
||||
end
|
||||
|
||||
def right_rotate(x)
|
||||
raise "x.left is nil!" if x.left.nil?
|
||||
y = x.left
|
||||
x.left = y.right
|
||||
y.right.parent = x if !y.right.nil?
|
||||
y.parent = x.parent
|
||||
if x.parent.nil?
|
||||
self.root = y
|
||||
else
|
||||
if x == x.parent.left
|
||||
x.parent.left = y
|
||||
else
|
||||
x.parent.right = y
|
||||
end
|
||||
end
|
||||
y.right = x
|
||||
x.parent = y
|
||||
end
|
||||
|
||||
def insert_helper(z)
|
||||
y = NilNode.instance
|
||||
x = root
|
||||
while !x.nil?
|
||||
y = x
|
||||
z.key < x.key ? x = x.left : x = x.right
|
||||
end
|
||||
z.parent = y
|
||||
if y.nil?
|
||||
self.root = z
|
||||
else
|
||||
z.key < y.key ? y.left = z : y.right = z
|
||||
end
|
||||
self.size += 1
|
||||
end
|
||||
|
||||
def delete_fixup(x)
|
||||
while x != root && x.color == Node::BLACK
|
||||
if x == x.parent.left
|
||||
w = x.parent.right
|
||||
if w.color == Node::RED
|
||||
w.color = Node::BLACK
|
||||
x.parent.color = Node::RED
|
||||
left_rotate(x.parent)
|
||||
w = x.parent.right
|
||||
end
|
||||
if w.left.color == Node::BLACK && w.right.color == Node::BLACK
|
||||
w.color = Node::RED
|
||||
x = x.parent
|
||||
else
|
||||
if w.right.color == Node::BLACK
|
||||
w.left.color = Node::BLACK
|
||||
w.color = Node::RED
|
||||
right_rotate(w)
|
||||
w = x.parent.right
|
||||
end
|
||||
w.color = x.parent.color
|
||||
x.parent.color = Node::BLACK
|
||||
w.right.color = Node::BLACK
|
||||
left_rotate(x.parent)
|
||||
x = root
|
||||
end
|
||||
else
|
||||
w = x.parent.left
|
||||
if w.color == Node::RED
|
||||
w.color = Node::BLACK
|
||||
x.parent.color = Node::RED
|
||||
right_rotate(x.parent)
|
||||
w = x.parent.left
|
||||
end
|
||||
if w.right.color == Node::BLACK && w.left.color == Node::BLACK
|
||||
w.color = Node::RED
|
||||
x = x.parent
|
||||
else
|
||||
if w.left.color == Node::BLACK
|
||||
w.right.color = Node::BLACK
|
||||
w.color = Node::RED
|
||||
left_rotate(w)
|
||||
w = x.parent.left
|
||||
end
|
||||
w.color = x.parent.color
|
||||
x.parent.color = Node::BLACK
|
||||
w.left.color = Node::BLACK
|
||||
right_rotate(x.parent)
|
||||
x = root
|
||||
end
|
||||
end
|
||||
end
|
||||
x.color = Node::BLACK
|
||||
end
|
||||
end
|
||||
|
||||
def rbt_bm
|
||||
n = 100_000
|
||||
a1 = []; n.times { a1 << rand(999_999) }
|
||||
a2 = []; n.times { a2 << rand(999_999) }
|
||||
|
||||
start = Time.now
|
||||
|
||||
tree = RedBlackTree.new
|
||||
|
||||
n.times {|i| tree.add(i) }
|
||||
n.times { tree.delete(tree.root) }
|
||||
|
||||
tree = RedBlackTree.new
|
||||
a1.each {|e| tree.add(e) }
|
||||
a2.each {|e| tree.search(e) }
|
||||
tree.inorder_walk {|key| key + 1 }
|
||||
tree.reverse_inorder_walk {|key| key + 1 }
|
||||
n.times { tree.minimum }
|
||||
n.times { tree.maximum }
|
||||
|
||||
return Time.now - start
|
||||
end
|
||||
|
||||
N = (ARGV[0] || 10).to_i
|
||||
|
||||
N.times do
|
||||
# puts rbt_bm.to_f
|
||||
rbt_bm.to_f
|
||||
# puts "GC.count = #{GC.count}" if GC.respond_to?(:count)
|
||||
end
|
29
benchmark/gc/ring.rb
Normal file
29
benchmark/gc/ring.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
# create many old objects
|
||||
|
||||
max = 30_000_000
|
||||
|
||||
class Ring
|
||||
attr_reader :next_ring
|
||||
def initialize n = nil
|
||||
@next_ring = n
|
||||
end
|
||||
|
||||
|
||||
def size
|
||||
s = 1
|
||||
ring = self
|
||||
while ring.next_ring
|
||||
s += 1
|
||||
ring = ring.next_ring
|
||||
end
|
||||
s
|
||||
end
|
||||
end
|
||||
|
||||
ring = Ring.new
|
||||
|
||||
max.times{
|
||||
ring = Ring.new(ring)
|
||||
}
|
||||
|
||||
# p ring.size
|
4
bin/erb
4
bin/erb
|
@ -72,7 +72,7 @@ class ERB
|
|||
require ARGV.req_arg
|
||||
when '-S' # security level
|
||||
arg = ARGV.req_arg
|
||||
raise "invalid safe_level #{arg.dump}" unless arg =~ /^[0-4]$/
|
||||
raise "invalid safe_level #{arg.dump}" unless arg =~ /^[0-3]$/
|
||||
safe_level = arg.to_i
|
||||
when '-T' # trim mode
|
||||
arg = ARGV.req_arg
|
||||
|
@ -105,7 +105,7 @@ class ERB
|
|||
-v enable verbose mode
|
||||
-d set $DEBUG to true
|
||||
-r library load a library
|
||||
-S safe_level set $SAFE (0..4)
|
||||
-S safe_level set $SAFE (0..3)
|
||||
-E ex[:in] set default external/internal encodings
|
||||
-U set default encoding to UTF-8.
|
||||
-T trim_mode specify trim_mode (0..2, -)
|
||||
|
|
11
bin/irb
11
bin/irb
|
@ -8,13 +8,4 @@
|
|||
|
||||
require "irb"
|
||||
|
||||
if __FILE__ == $0
|
||||
IRB.start(__FILE__)
|
||||
else
|
||||
# check -e option
|
||||
if /^-e$/ =~ $0
|
||||
IRB.start(__FILE__)
|
||||
else
|
||||
IRB.setup(__FILE__)
|
||||
end
|
||||
end
|
||||
IRB.start(__FILE__)
|
||||
|
|
4
bin/rake
4
bin/rake
|
@ -28,10 +28,6 @@ begin
|
|||
rescue LoadError
|
||||
end
|
||||
|
||||
module Rake
|
||||
REDUCE_COMPAT = true if ARGV.include?("--reduce-compat")
|
||||
end
|
||||
|
||||
require 'rake'
|
||||
|
||||
Rake.application.run
|
||||
|
|
|
@ -62,6 +62,7 @@ def main
|
|||
@verbose = false
|
||||
$stress = false
|
||||
@color = nil
|
||||
@tty = nil
|
||||
@quiet = false
|
||||
dir = nil
|
||||
quiet = false
|
||||
|
@ -87,6 +88,10 @@ def main
|
|||
warn "unknown --color argument: #$3" if $3
|
||||
@color = $1 ? nil : !$2
|
||||
true
|
||||
when /\A--tty(=(?:yes|(no)|(.*)))?\z/
|
||||
warn "unknown --tty argument: #$3" if $3
|
||||
@tty = !$1 || !$2
|
||||
true
|
||||
when /\A(-q|--q(uiet))\z/
|
||||
quiet = true
|
||||
@quiet = true
|
||||
|
@ -123,7 +128,7 @@ End
|
|||
|
||||
@progress = %w[- \\ | /]
|
||||
@progress_bs = "\b" * @progress[0].size
|
||||
@tty = $stderr.tty?
|
||||
@tty = $stderr.tty? if @tty.nil?
|
||||
case @color
|
||||
when nil
|
||||
@color = @tty && /dumb/ !~ ENV["TERM"]
|
||||
|
@ -178,20 +183,20 @@ def exec_test(pathes)
|
|||
$stderr.print "#{@progress_bs}#{@failed}FAIL #{@error-error}/#{@count-count}#{@reset}"
|
||||
end
|
||||
end
|
||||
$stderr.puts unless @quiet
|
||||
$stderr.puts unless @quiet and @tty
|
||||
end
|
||||
if @error == 0
|
||||
if @count == 0
|
||||
$stderr.puts "No tests, no problem"
|
||||
else
|
||||
$stderr.puts "PASS all #{@count} tests"
|
||||
$stderr.puts "#{@passed}PASS#{@reset} all #{@count} tests"
|
||||
end
|
||||
exit true
|
||||
else
|
||||
@errbuf.each do |msg|
|
||||
$stderr.puts msg
|
||||
end
|
||||
$stderr.puts "FAIL #{@error}/#{@count} tests failed"
|
||||
$stderr.puts "#{@failed}FAIL#{@reset} #{@error}/#{@count} tests failed"
|
||||
exit false
|
||||
end
|
||||
end
|
||||
|
@ -316,7 +321,7 @@ def assert_normal_exit(testsrc, *rest)
|
|||
$stderr.reopen(old_stderr)
|
||||
old_stderr.close
|
||||
end
|
||||
if status.signaled?
|
||||
if status && status.signaled?
|
||||
signo = status.termsig
|
||||
signame = Signal.list.invert[signo]
|
||||
unless ignore_signals and ignore_signals.include?(signame)
|
||||
|
@ -402,7 +407,7 @@ def get_result_string(src, opt = '')
|
|||
begin
|
||||
`#{@ruby} -W0 #{opt} #{filename}`
|
||||
ensure
|
||||
raise Interrupt if $?.signaled? && $?.termsig == Signal.list["INT"]
|
||||
raise Interrupt if $? and $?.signaled? && $?.termsig == Signal.list["INT"]
|
||||
raise CoreDumpError, "core dumped" if $? and $?.coredump?
|
||||
end
|
||||
else
|
||||
|
|
|
@ -43,46 +43,6 @@ assert_equal 'ok', %q{
|
|||
ZZZ.ok
|
||||
}
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
|
||||
autoload :ZZZ, "./zzz.rb"
|
||||
proc{$SAFE=4; ZZZ.ok}.call
|
||||
}
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
|
||||
autoload :ZZZ, "./zzz.rb"
|
||||
require "./zzz.rb"
|
||||
proc{$SAFE=4; ZZZ.ok}.call
|
||||
}
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"}
|
||||
autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb')
|
||||
module M; end
|
||||
Thread.new{M.instance_eval('$SAFE=4; ZZZ.new.hoge')}.value
|
||||
}
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"}
|
||||
autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb')
|
||||
module M; end
|
||||
Thread.new{$SAFE=4; M.instance_eval('ZZZ.new.hoge')}.value
|
||||
}
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"}
|
||||
autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb')
|
||||
Thread.new{$SAFE=4; eval('ZZZ.new.hoge')}.value
|
||||
}
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"}
|
||||
autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb')
|
||||
module M; end
|
||||
Thread.new{eval('$SAFE=4; ZZZ.new.hoge')}.value
|
||||
}
|
||||
|
||||
assert_equal 'okok', %q{
|
||||
open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
|
||||
autoload :ZZZ, "./zzz.rb"
|
||||
|
|
|
@ -11,6 +11,16 @@ assert_equal 'C', %q( class C; end
|
|||
C.new.class.name )
|
||||
assert_equal 'Class', %q( class C; end
|
||||
C.new.class.class )
|
||||
assert_equal 'true', %q( Object.__send__(:remove_const, :TrueClass)
|
||||
GC.start
|
||||
true.inspect)
|
||||
assert_equal 'false', %q( Object.__send__(:remove_const, :FalseClass)
|
||||
GC.start
|
||||
false.inspect)
|
||||
assert_equal 'nil', %q( Object.__send__(:remove_const, :NilClass)
|
||||
GC.start
|
||||
nil.inspect)
|
||||
|
||||
|
||||
# inherited class
|
||||
assert_equal 'true', %q( class A; end
|
||||
|
|
|
@ -224,3 +224,8 @@ assert_equal 'ok', %q{ # long hash literal (optimized)
|
|||
eval "a = {#{(1..10_000).map{|n| "#{n} => #{n}"}.join(', ')}}"
|
||||
:ok
|
||||
}
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
[print(:ok), exit] # void literal with side-effect
|
||||
:dummy
|
||||
}
|
||||
|
|
54
bootstraptest/test_literal_suffix.rb
Normal file
54
bootstraptest/test_literal_suffix.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
# numbers with suffix
|
||||
assert_equal '0/1', '0r'
|
||||
assert_equal 'Rational', '0r.class'
|
||||
assert_equal '1/1', '1r'
|
||||
assert_equal 'Rational', '1r.class'
|
||||
assert_equal '-1/1', '-1r'
|
||||
assert_equal 'Rational', '(-1r).class'
|
||||
assert_equal '1/1', '0x1r'
|
||||
assert_equal 'Rational', '0x1r.class'
|
||||
assert_equal '1/1', '0b1r'
|
||||
assert_equal 'Rational', '0b1r.class'
|
||||
assert_equal '1/1', '0d1r'
|
||||
assert_equal 'Rational', '0d1r.class'
|
||||
assert_equal '1/1', '0o1r'
|
||||
assert_equal 'Rational', '0o1r.class'
|
||||
assert_equal '1/1', '01r'
|
||||
assert_equal 'Rational', '01r.class'
|
||||
assert_equal '6/5', '1.2r'
|
||||
assert_equal 'Rational', '1.2r.class'
|
||||
assert_equal '-6/5', '-1.2r'
|
||||
assert_equal 'Rational', '(-1.2r).class'
|
||||
assert_equal '0+0i', '0i'
|
||||
assert_equal 'Complex', '0i.class'
|
||||
assert_equal '0+1i', '1i'
|
||||
assert_equal 'Complex', '1i.class'
|
||||
assert_equal '0+1i', '0x1i'
|
||||
assert_equal 'Complex', '0x1i.class'
|
||||
assert_equal '0+1i', '0b1i'
|
||||
assert_equal 'Complex', '0b1i.class'
|
||||
assert_equal '0+1i', '0d1i'
|
||||
assert_equal 'Complex', '0d1i.class'
|
||||
assert_equal '0+1i', '0o1i'
|
||||
assert_equal 'Complex', '0o1i.class'
|
||||
assert_equal '0+1i', '01i'
|
||||
assert_equal 'Complex', '01i.class'
|
||||
assert_equal '0+1.2i', '1.2i'
|
||||
assert_equal 'Complex', '1.2i.class'
|
||||
assert_equal '0+1/1i', '1ri'
|
||||
assert_equal 'Complex', '1ri.class'
|
||||
assert_equal '0+6/5i', '1.2ri'
|
||||
assert_equal 'Complex', '1.2ri.class'
|
||||
assert_equal '0+10.0i', '1e1i'
|
||||
assert_equal 'Complex', '1e1i.class'
|
||||
assert_equal '1', '1if true'
|
||||
assert_equal '1', '1rescue nil'
|
||||
assert_equal '10000000000000000001/10000000000000000000',
|
||||
'1.0000000000000000001r'
|
||||
|
||||
assert_equal 'syntax error, unexpected tIDENTIFIER, expecting end-of-input',
|
||||
%q{begin eval('1ir', nil, '', 0); rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end}
|
||||
assert_equal 'syntax error, unexpected tIDENTIFIER, expecting end-of-input',
|
||||
%q{begin eval('1.2ir', nil, '', 0); rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end}
|
||||
assert_equal 'syntax error, unexpected tIDENTIFIER, expecting end-of-input',
|
||||
%q{begin eval('1e1r', nil, '', 0); rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end}
|
|
@ -886,50 +886,6 @@ class C0; def m *args; [:C0_m, args]; end; end
|
|||
class C1 < C0; def m a, o=:o; super; end; end
|
||||
; C1.new.m 1, 2}
|
||||
|
||||
assert_equal %q{[:ok, :ok, :ok, :ok, :ok, :ok, :ng, :ng]}, %q{
|
||||
$ans = []
|
||||
class Foo
|
||||
def m
|
||||
end
|
||||
end
|
||||
|
||||
c1 = c2 = nil
|
||||
|
||||
lambda{
|
||||
$SAFE = 4
|
||||
c1 = Class.new{
|
||||
def m
|
||||
end
|
||||
}
|
||||
c2 = Class.new(Foo){
|
||||
alias mm m
|
||||
}
|
||||
}.call
|
||||
|
||||
def test
|
||||
begin
|
||||
yield
|
||||
rescue SecurityError
|
||||
$ans << :ok
|
||||
else
|
||||
$ans << :ng
|
||||
end
|
||||
end
|
||||
|
||||
o1 = c1.new
|
||||
o2 = c2.new
|
||||
|
||||
test{o1.m}
|
||||
test{o2.mm}
|
||||
test{o1.send :m}
|
||||
test{o2.send :mm}
|
||||
test{o1.public_send :m}
|
||||
test{o2.public_send :mm}
|
||||
test{o1.method(:m).call}
|
||||
test{o2.method(:mm).call}
|
||||
$ans
|
||||
}
|
||||
|
||||
assert_equal 'ok', %q{
|
||||
class C
|
||||
def x=(n)
|
||||
|
|
|
@ -10,7 +10,8 @@ assert_equal %q{ok}, %q{
|
|||
:ok
|
||||
}.value
|
||||
}
|
||||
assert_equal %q{20100}, %q{
|
||||
assert_equal %q{ok}, %q{
|
||||
begin
|
||||
v = 0
|
||||
(1..200).map{|i|
|
||||
Thread.new{
|
||||
|
@ -19,7 +20,10 @@ assert_equal %q{20100}, %q{
|
|||
}.each{|t|
|
||||
v += t.value
|
||||
}
|
||||
v
|
||||
v == 20100 ? :ok : v
|
||||
rescue ThreadError => e
|
||||
:ok if /can't create Thread/ =~ e.message
|
||||
end
|
||||
}
|
||||
assert_equal %q{5000}, %q{
|
||||
5000.times{|e|
|
||||
|
@ -41,13 +45,17 @@ assert_equal %q{5000}, %q{
|
|||
}
|
||||
}
|
||||
}
|
||||
assert_equal %q{5000}, %q{
|
||||
5000.times{
|
||||
assert_equal %q{ok}, %q{
|
||||
begin
|
||||
:ok if 5000 == 5000.times{
|
||||
t = Thread.new{}
|
||||
while t.alive?
|
||||
Thread.pass
|
||||
end
|
||||
}
|
||||
rescue NoMemoryError
|
||||
:ok
|
||||
end
|
||||
}
|
||||
assert_equal %q{100}, %q{
|
||||
100.times{
|
||||
|
|
502
class.c
502
class.c
|
@ -31,8 +31,113 @@
|
|||
#include "internal.h"
|
||||
#include <ctype.h>
|
||||
|
||||
extern st_table *rb_class_tbl;
|
||||
static ID id_attached;
|
||||
int rb_vm_add_root_module(ID id, VALUE module);
|
||||
|
||||
|
||||
#define id_attached id__attached__
|
||||
|
||||
void
|
||||
rb_class_subclass_add(VALUE super, VALUE klass)
|
||||
{
|
||||
rb_subclass_entry_t *entry, *head;
|
||||
|
||||
if (super && super != Qundef) {
|
||||
entry = malloc(sizeof(*entry));
|
||||
entry->klass = klass;
|
||||
entry->next = NULL;
|
||||
|
||||
head = RCLASS_EXT(super)->subclasses;
|
||||
if (head) {
|
||||
entry->next = head;
|
||||
RCLASS_EXT(head->klass)->parent_subclasses = &entry->next;
|
||||
}
|
||||
|
||||
RCLASS_EXT(super)->subclasses = entry;
|
||||
RCLASS_EXT(klass)->parent_subclasses = &RCLASS_EXT(super)->subclasses;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rb_module_add_to_subclasses_list(VALUE module, VALUE iclass)
|
||||
{
|
||||
rb_subclass_entry_t *entry, *head;
|
||||
|
||||
entry = malloc(sizeof(*entry));
|
||||
entry->klass = iclass;
|
||||
entry->next = NULL;
|
||||
|
||||
head = RCLASS_EXT(module)->subclasses;
|
||||
if (head) {
|
||||
entry->next = head;
|
||||
RCLASS_EXT(head->klass)->module_subclasses = &entry->next;
|
||||
}
|
||||
|
||||
RCLASS_EXT(module)->subclasses = entry;
|
||||
RCLASS_EXT(iclass)->module_subclasses = &RCLASS_EXT(module)->subclasses;
|
||||
}
|
||||
|
||||
void
|
||||
rb_class_remove_from_super_subclasses(VALUE klass)
|
||||
{
|
||||
rb_subclass_entry_t *entry;
|
||||
|
||||
if (RCLASS_EXT(klass)->parent_subclasses) {
|
||||
entry = *RCLASS_EXT(klass)->parent_subclasses;
|
||||
|
||||
*RCLASS_EXT(klass)->parent_subclasses = entry->next;
|
||||
if (entry->next) {
|
||||
RCLASS_EXT(entry->next->klass)->parent_subclasses = RCLASS_EXT(klass)->parent_subclasses;
|
||||
}
|
||||
free(entry);
|
||||
}
|
||||
|
||||
RCLASS_EXT(klass)->parent_subclasses = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
rb_class_remove_from_module_subclasses(VALUE klass)
|
||||
{
|
||||
rb_subclass_entry_t *entry;
|
||||
|
||||
if (RCLASS_EXT(klass)->module_subclasses) {
|
||||
entry = *RCLASS_EXT(klass)->module_subclasses;
|
||||
*RCLASS_EXT(klass)->module_subclasses = entry->next;
|
||||
|
||||
if (entry->next) {
|
||||
RCLASS_EXT(entry->next->klass)->module_subclasses = RCLASS_EXT(klass)->module_subclasses;
|
||||
}
|
||||
|
||||
free(entry);
|
||||
}
|
||||
|
||||
RCLASS_EXT(klass)->module_subclasses = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
rb_class_foreach_subclass(VALUE klass, void(*f)(VALUE))
|
||||
{
|
||||
rb_subclass_entry_t *cur = RCLASS_EXT(klass)->subclasses;
|
||||
|
||||
/* do not be tempted to simplify this loop into a for loop, the order of
|
||||
operations is important here if `f` modifies the linked list */
|
||||
while (cur) {
|
||||
VALUE curklass = cur->klass;
|
||||
cur = cur->next;
|
||||
f(curklass);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_class_detach_subclasses(VALUE klass)
|
||||
{
|
||||
rb_class_foreach_subclass(klass, rb_class_remove_from_super_subclasses);
|
||||
}
|
||||
|
||||
void
|
||||
rb_class_detach_module_subclasses(VALUE klass)
|
||||
{
|
||||
rb_class_foreach_subclass(klass, rb_class_remove_from_module_subclasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a struct RClass for a new class.
|
||||
|
@ -49,14 +154,20 @@ static ID id_attached;
|
|||
static VALUE
|
||||
class_alloc(VALUE flags, VALUE klass)
|
||||
{
|
||||
NEWOBJ_OF(obj, struct RClass, klass, flags);
|
||||
NEWOBJ_OF(obj, struct RClass, klass, (flags & T_MASK) | (RGENGC_WB_PROTECTED_CLASS ? FL_WB_PROTECTED : 0));
|
||||
obj->ptr = ALLOC(rb_classext_t);
|
||||
RCLASS_IV_TBL(obj) = 0;
|
||||
RCLASS_CONST_TBL(obj) = 0;
|
||||
RCLASS_M_TBL(obj) = 0;
|
||||
RCLASS_SUPER(obj) = 0;
|
||||
RCLASS_M_TBL_WRAPPER(obj) = 0;
|
||||
RCLASS_SET_SUPER((VALUE)obj, 0);
|
||||
RCLASS_ORIGIN(obj) = (VALUE)obj;
|
||||
RCLASS_IV_INDEX_TBL(obj) = 0;
|
||||
|
||||
RCLASS_EXT(obj)->subclasses = NULL;
|
||||
RCLASS_EXT(obj)->parent_subclasses = NULL;
|
||||
RCLASS_EXT(obj)->module_subclasses = NULL;
|
||||
RCLASS_SERIAL(obj) = rb_next_class_serial();
|
||||
|
||||
RCLASS_REFINED_CLASS(obj) = Qnil;
|
||||
RCLASS_EXT(obj)->allocator = 0;
|
||||
return (VALUE)obj;
|
||||
|
@ -77,8 +188,8 @@ rb_class_boot(VALUE super)
|
|||
{
|
||||
VALUE klass = class_alloc(T_CLASS, rb_cClass);
|
||||
|
||||
RCLASS_SUPER(klass) = super;
|
||||
RCLASS_M_TBL(klass) = st_init_numtable();
|
||||
RCLASS_SET_SUPER(klass, super);
|
||||
RCLASS_M_TBL_INIT(klass);
|
||||
|
||||
OBJ_INFECT(klass, super);
|
||||
return (VALUE)klass;
|
||||
|
@ -121,21 +232,23 @@ rb_class_new(VALUE super)
|
|||
return rb_class_boot(super);
|
||||
}
|
||||
|
||||
static NODE*
|
||||
rewrite_cref_stack(NODE *node, VALUE old_klass, VALUE new_klass)
|
||||
static void
|
||||
rewrite_cref_stack(NODE *node, VALUE old_klass, VALUE new_klass, NODE **new_cref_ptr)
|
||||
{
|
||||
NODE *new_node;
|
||||
if (!node) {
|
||||
return NULL;
|
||||
}
|
||||
if (node->nd_clss == old_klass) {
|
||||
new_node = NEW_CREF(new_klass);
|
||||
new_node->nd_next = node->nd_next;
|
||||
} else {
|
||||
while (node) {
|
||||
if (node->nd_clss == old_klass) {
|
||||
new_node = NEW_CREF(new_klass);
|
||||
RB_OBJ_WRITE(new_node, &new_node->nd_next, node->nd_next);
|
||||
*new_cref_ptr = new_node;
|
||||
return;
|
||||
}
|
||||
new_node = NEW_CREF(node->nd_clss);
|
||||
new_node->nd_next = rewrite_cref_stack(node->nd_next, old_klass, new_klass);
|
||||
node = node->nd_next;
|
||||
*new_cref_ptr = new_node;
|
||||
new_cref_ptr = &new_node->nd_next;
|
||||
}
|
||||
return new_node;
|
||||
*new_cref_ptr = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -144,9 +257,11 @@ clone_method(VALUE klass, ID mid, const rb_method_entry_t *me)
|
|||
VALUE newiseqval;
|
||||
if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) {
|
||||
rb_iseq_t *iseq;
|
||||
NODE *new_cref;
|
||||
newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass);
|
||||
GetISeqPtr(newiseqval, iseq);
|
||||
iseq->cref_stack = rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass);
|
||||
rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass, &new_cref);
|
||||
RB_OBJ_WRITE(iseq->self, &iseq->cref_stack, new_cref);
|
||||
rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag);
|
||||
RB_GC_GUARD(newiseqval);
|
||||
}
|
||||
|
@ -162,19 +277,27 @@ clone_method_i(st_data_t key, st_data_t value, st_data_t data)
|
|||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
struct clone_const_arg {
|
||||
VALUE klass;
|
||||
st_table *tbl;
|
||||
};
|
||||
|
||||
static int
|
||||
clone_const(ID key, const rb_const_entry_t *ce, st_table *tbl)
|
||||
clone_const(ID key, const rb_const_entry_t *ce, struct clone_const_arg *arg)
|
||||
{
|
||||
rb_const_entry_t *nce = ALLOC(rb_const_entry_t);
|
||||
*nce = *ce;
|
||||
st_insert(tbl, key, (st_data_t)nce);
|
||||
MEMCPY(nce, ce, rb_const_entry_t, 1);
|
||||
RB_OBJ_WRITTEN(arg->klass, Qundef, ce->value);
|
||||
RB_OBJ_WRITTEN(arg->klass, Qundef, ce->file);
|
||||
|
||||
st_insert(arg->tbl, key, (st_data_t)nce);
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
clone_const_i(st_data_t key, st_data_t value, st_data_t data)
|
||||
{
|
||||
return clone_const((ID)key, (const rb_const_entry_t *)value, (st_table *)data);
|
||||
return clone_const((ID)key, (const rb_const_entry_t *)value, (struct clone_const_arg *)data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -200,10 +323,10 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
|
|||
}
|
||||
rb_obj_init_copy(clone, orig);
|
||||
if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
|
||||
RBASIC(clone)->klass = rb_singleton_class_clone(orig);
|
||||
RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig));
|
||||
rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
|
||||
}
|
||||
RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
|
||||
RCLASS_SET_SUPER(clone, RCLASS_SUPER(orig));
|
||||
RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator;
|
||||
if (RCLASS_IV_TBL(orig)) {
|
||||
st_data_t id;
|
||||
|
@ -211,7 +334,7 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
|
|||
if (RCLASS_IV_TBL(clone)) {
|
||||
st_free_table(RCLASS_IV_TBL(clone));
|
||||
}
|
||||
RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
|
||||
RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(orig));
|
||||
CONST_ID(id, "__tmp_classpath__");
|
||||
st_delete(RCLASS_IV_TBL(clone), &id, 0);
|
||||
CONST_ID(id, "__classpath__");
|
||||
|
@ -220,17 +343,20 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
|
|||
st_delete(RCLASS_IV_TBL(clone), &id, 0);
|
||||
}
|
||||
if (RCLASS_CONST_TBL(orig)) {
|
||||
struct clone_const_arg arg;
|
||||
if (RCLASS_CONST_TBL(clone)) {
|
||||
rb_free_const_table(RCLASS_CONST_TBL(clone));
|
||||
}
|
||||
RCLASS_CONST_TBL(clone) = st_init_numtable();
|
||||
st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
|
||||
arg.klass = clone;
|
||||
arg.tbl = RCLASS_CONST_TBL(clone);
|
||||
st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)&arg);
|
||||
}
|
||||
if (RCLASS_M_TBL(orig)) {
|
||||
if (RCLASS_M_TBL(clone)) {
|
||||
rb_free_m_table(RCLASS_M_TBL(clone));
|
||||
if (RCLASS_M_TBL_WRAPPER(clone)) {
|
||||
rb_free_m_tbl_wrapper(RCLASS_M_TBL_WRAPPER(clone));
|
||||
}
|
||||
RCLASS_M_TBL(clone) = st_init_numtable();
|
||||
RCLASS_M_TBL_INIT(clone);
|
||||
st_foreach(RCLASS_M_TBL(orig), clone_method_i, (st_data_t)clone);
|
||||
}
|
||||
|
||||
|
@ -255,28 +381,32 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
|
|||
VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
|
||||
|
||||
if (BUILTIN_TYPE(obj) == T_CLASS) {
|
||||
RBASIC(clone)->klass = clone;
|
||||
RBASIC_SET_CLASS(clone, clone);
|
||||
}
|
||||
else {
|
||||
RBASIC(clone)->klass = rb_singleton_class_clone(klass);
|
||||
RBASIC_SET_CLASS(clone, rb_singleton_class_clone(klass));
|
||||
}
|
||||
|
||||
RCLASS_SUPER(clone) = RCLASS_SUPER(klass);
|
||||
RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass));
|
||||
RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator;
|
||||
if (RCLASS_IV_TBL(klass)) {
|
||||
RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
|
||||
RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(klass));
|
||||
}
|
||||
if (RCLASS_CONST_TBL(klass)) {
|
||||
struct clone_const_arg arg;
|
||||
RCLASS_CONST_TBL(clone) = st_init_numtable();
|
||||
st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
|
||||
arg.klass = clone;
|
||||
arg.tbl = RCLASS_CONST_TBL(clone);
|
||||
st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)&arg);
|
||||
}
|
||||
if (attach != Qundef) {
|
||||
rb_singleton_class_attached(clone, attach);
|
||||
}
|
||||
RCLASS_M_TBL(clone) = st_init_numtable();
|
||||
RCLASS_M_TBL_INIT(clone);
|
||||
st_foreach(RCLASS_M_TBL(klass), clone_method_i, (st_data_t)clone);
|
||||
rb_singleton_class_attached(RBASIC(clone)->klass, clone);
|
||||
FL_SET(clone, FL_SINGLETON);
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
@ -292,13 +422,14 @@ rb_singleton_class_attached(VALUE klass, VALUE obj)
|
|||
if (!RCLASS_IV_TBL(klass)) {
|
||||
RCLASS_IV_TBL(klass) = st_init_numtable();
|
||||
}
|
||||
st_insert(RCLASS_IV_TBL(klass), id_attached, obj);
|
||||
rb_st_insert_id_and_value(klass, RCLASS_IV_TBL(klass), id_attached, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define METACLASS_OF(k) RBASIC(k)->klass
|
||||
#define SET_METACLASS_OF(k, cls) RBASIC_SET_CLASS(k, cls)
|
||||
|
||||
/*!
|
||||
* whether k is a meta^(n)-class of Class class
|
||||
|
@ -307,6 +438,14 @@ rb_singleton_class_attached(VALUE klass, VALUE obj)
|
|||
*/
|
||||
#define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k))
|
||||
|
||||
/*!
|
||||
* whether k has a metaclass
|
||||
* @retval 1 if \a k has a metaclass
|
||||
* @retval 0 otherwise
|
||||
*/
|
||||
#define HAVE_METACLASS_P(k) \
|
||||
(FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \
|
||||
rb_ivar_get(METACLASS_OF(k), id_attached) == (k))
|
||||
|
||||
/*!
|
||||
* ensures \a klass belongs to its own eigenclass.
|
||||
|
@ -316,7 +455,7 @@ rb_singleton_class_attached(VALUE klass, VALUE obj)
|
|||
* @note this macro creates a new eigenclass if necessary.
|
||||
*/
|
||||
#define ENSURE_EIGENCLASS(klass) \
|
||||
(rb_ivar_get(METACLASS_OF(klass), id_attached) == (klass) ? METACLASS_OF(klass) : make_metaclass(klass))
|
||||
(HAVE_METACLASS_P(klass) ? METACLASS_OF(klass) : make_metaclass(klass))
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -338,17 +477,18 @@ make_metaclass(VALUE klass)
|
|||
rb_singleton_class_attached(metaclass, klass);
|
||||
|
||||
if (META_CLASS_OF_CLASS_CLASS_P(klass)) {
|
||||
METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass;
|
||||
SET_METACLASS_OF(klass, metaclass);
|
||||
SET_METACLASS_OF(metaclass, metaclass);
|
||||
}
|
||||
else {
|
||||
VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */
|
||||
METACLASS_OF(klass) = metaclass;
|
||||
METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp);
|
||||
SET_METACLASS_OF(klass, metaclass);
|
||||
SET_METACLASS_OF(metaclass, ENSURE_EIGENCLASS(tmp));
|
||||
}
|
||||
|
||||
super = RCLASS_SUPER(klass);
|
||||
while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
|
||||
RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass;
|
||||
RCLASS_SET_SUPER(metaclass, super ? ENSURE_EIGENCLASS(super) : rb_cClass);
|
||||
|
||||
OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass));
|
||||
|
||||
|
@ -368,10 +508,10 @@ make_singleton_class(VALUE obj)
|
|||
VALUE klass = rb_class_boot(orig_class);
|
||||
|
||||
FL_SET(klass, FL_SINGLETON);
|
||||
RBASIC(obj)->klass = klass;
|
||||
RBASIC_SET_CLASS(obj, klass);
|
||||
rb_singleton_class_attached(klass, obj);
|
||||
|
||||
METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class));
|
||||
SET_METACLASS_OF(klass, METACLASS_OF(rb_class_real(orig_class)));
|
||||
return klass;
|
||||
}
|
||||
|
||||
|
@ -379,12 +519,10 @@ make_singleton_class(VALUE obj)
|
|||
static VALUE
|
||||
boot_defclass(const char *name, VALUE super)
|
||||
{
|
||||
extern st_table *rb_class_tbl;
|
||||
VALUE obj = rb_class_boot(super);
|
||||
ID id = rb_intern(name);
|
||||
|
||||
rb_name_class(obj, id);
|
||||
st_add_direct(rb_class_tbl, id, obj);
|
||||
rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);
|
||||
return obj;
|
||||
}
|
||||
|
@ -392,19 +530,16 @@ boot_defclass(const char *name, VALUE super)
|
|||
void
|
||||
Init_class_hierarchy(void)
|
||||
{
|
||||
id_attached = rb_intern("__attached__");
|
||||
|
||||
rb_cBasicObject = boot_defclass("BasicObject", 0);
|
||||
rb_cObject = boot_defclass("Object", rb_cBasicObject);
|
||||
rb_cModule = boot_defclass("Module", rb_cObject);
|
||||
rb_cClass = boot_defclass("Class", rb_cModule);
|
||||
|
||||
rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject);
|
||||
RBASIC(rb_cClass)->klass
|
||||
= RBASIC(rb_cModule)->klass
|
||||
= RBASIC(rb_cObject)->klass
|
||||
= RBASIC(rb_cBasicObject)->klass
|
||||
= rb_cClass;
|
||||
RBASIC_SET_CLASS(rb_cClass, rb_cClass);
|
||||
RBASIC_SET_CLASS(rb_cModule, rb_cClass);
|
||||
RBASIC_SET_CLASS(rb_cObject, rb_cClass);
|
||||
RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
|
||||
}
|
||||
|
||||
|
||||
|
@ -508,7 +643,7 @@ rb_define_class(const char *name, VALUE super)
|
|||
rb_warn("no super class for `%s', Object assumed", name);
|
||||
}
|
||||
klass = rb_define_class_id(id, super);
|
||||
st_add_direct(rb_class_tbl, id, klass);
|
||||
rb_vm_add_root_module(id, klass);
|
||||
rb_name_class(klass, id);
|
||||
rb_const_set(rb_cObject, id, klass);
|
||||
rb_class_inherited(super, klass);
|
||||
|
@ -588,9 +723,7 @@ VALUE
|
|||
rb_module_new(void)
|
||||
{
|
||||
VALUE mdl = class_alloc(T_MODULE, rb_cModule);
|
||||
|
||||
RCLASS_M_TBL(mdl) = st_init_numtable();
|
||||
|
||||
RCLASS_M_TBL_INIT(mdl);
|
||||
return (VALUE)mdl;
|
||||
}
|
||||
|
||||
|
@ -619,7 +752,7 @@ rb_define_module(const char *name)
|
|||
rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module));
|
||||
}
|
||||
module = rb_define_module_id(id);
|
||||
st_add_direct(rb_class_tbl, id, module);
|
||||
rb_vm_add_root_module(id, module);
|
||||
rb_const_set(rb_cObject, id, module);
|
||||
|
||||
return module;
|
||||
|
@ -667,13 +800,16 @@ rb_include_class_new(VALUE module, VALUE super)
|
|||
}
|
||||
RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
|
||||
RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
|
||||
RCLASS_M_TBL(klass) = RCLASS_M_TBL(RCLASS_ORIGIN(module));
|
||||
RCLASS_SUPER(klass) = super;
|
||||
|
||||
RCLASS_M_TBL_WRAPPER(OBJ_WB_UNPROTECT(klass)) =
|
||||
RCLASS_M_TBL_WRAPPER(OBJ_WB_UNPROTECT(RCLASS_ORIGIN(module)));
|
||||
|
||||
RCLASS_SET_SUPER(klass, super);
|
||||
if (RB_TYPE_P(module, T_ICLASS)) {
|
||||
RBASIC(klass)->klass = RBASIC(module)->klass;
|
||||
RBASIC_SET_CLASS(klass, RBASIC(module)->klass);
|
||||
}
|
||||
else {
|
||||
RBASIC(klass)->klass = module;
|
||||
RBASIC_SET_CLASS(klass, module);
|
||||
}
|
||||
OBJ_INFECT(klass, module);
|
||||
OBJ_INFECT(klass, super);
|
||||
|
@ -681,7 +817,7 @@ rb_include_class_new(VALUE module, VALUE super)
|
|||
return (VALUE)klass;
|
||||
}
|
||||
|
||||
static int include_modules_at(VALUE klass, VALUE c, VALUE module);
|
||||
static int include_modules_at(const VALUE klass, VALUE c, VALUE module);
|
||||
|
||||
void
|
||||
rb_include_module(VALUE klass, VALUE module)
|
||||
|
@ -689,9 +825,6 @@ rb_include_module(VALUE klass, VALUE module)
|
|||
int changed = 0;
|
||||
|
||||
rb_frozen_class_p(klass);
|
||||
if (!OBJ_UNTRUSTED(klass)) {
|
||||
rb_secure(4);
|
||||
}
|
||||
|
||||
if (!RB_TYPE_P(module, T_MODULE)) {
|
||||
Check_Type(module, T_MODULE);
|
||||
|
@ -702,7 +835,6 @@ rb_include_module(VALUE klass, VALUE module)
|
|||
changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module);
|
||||
if (changed < 0)
|
||||
rb_raise(rb_eArgError, "cyclic include detected");
|
||||
if (changed) rb_clear_cache();
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -713,23 +845,24 @@ add_refined_method_entry_i(st_data_t key, st_data_t value, st_data_t data)
|
|||
}
|
||||
|
||||
static int
|
||||
include_modules_at(VALUE klass, VALUE c, VALUE module)
|
||||
include_modules_at(const VALUE klass, VALUE c, VALUE module)
|
||||
{
|
||||
VALUE p;
|
||||
int changed = 0;
|
||||
VALUE p, iclass;
|
||||
int method_changed = 0, constant_changed = 0;
|
||||
const st_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass));
|
||||
|
||||
while (module) {
|
||||
int superclass_seen = FALSE;
|
||||
|
||||
if (RCLASS_ORIGIN(module) != module)
|
||||
goto skip;
|
||||
if (RCLASS_M_TBL(klass) && RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
|
||||
if (klass_m_tbl && klass_m_tbl == RCLASS_M_TBL(module))
|
||||
return -1;
|
||||
/* ignore if the module included already in superclasses */
|
||||
for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
|
||||
switch (BUILTIN_TYPE(p)) {
|
||||
case T_ICLASS:
|
||||
if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
|
||||
if (RCLASS_M_TBL_WRAPPER(p) == RCLASS_M_TBL_WRAPPER(module)) {
|
||||
if (!superclass_seen) {
|
||||
c = p; /* move insertion point */
|
||||
}
|
||||
|
@ -741,7 +874,15 @@ include_modules_at(VALUE klass, VALUE c, VALUE module)
|
|||
break;
|
||||
}
|
||||
}
|
||||
c = RCLASS_SUPER(c) = rb_include_class_new(module, RCLASS_SUPER(c));
|
||||
iclass = rb_include_class_new(module, RCLASS_SUPER(c));
|
||||
c = RCLASS_SET_SUPER(c, iclass);
|
||||
|
||||
if (BUILTIN_TYPE(module) == T_ICLASS) {
|
||||
rb_module_add_to_subclasses_list(RBASIC(module)->klass, iclass);
|
||||
} else {
|
||||
rb_module_add_to_subclasses_list(module, iclass);
|
||||
}
|
||||
|
||||
if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
|
||||
VALUE refined_class =
|
||||
rb_refinement_module_get_refined_class(klass);
|
||||
|
@ -751,12 +892,17 @@ include_modules_at(VALUE klass, VALUE c, VALUE module)
|
|||
FL_SET(c, RMODULE_INCLUDED_INTO_REFINEMENT);
|
||||
}
|
||||
if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
|
||||
changed = 1;
|
||||
method_changed = 1;
|
||||
if (RMODULE_CONST_TBL(module) && RMODULE_CONST_TBL(module)->num_entries)
|
||||
constant_changed = 1;
|
||||
skip:
|
||||
module = RCLASS_SUPER(module);
|
||||
}
|
||||
|
||||
return changed;
|
||||
if (method_changed) rb_clear_method_cache_by_class(klass);
|
||||
if (constant_changed) rb_clear_constant_cache();
|
||||
|
||||
return method_changed;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -789,13 +935,11 @@ move_refined_method(st_data_t key, st_data_t value, st_data_t data)
|
|||
void
|
||||
rb_prepend_module(VALUE klass, VALUE module)
|
||||
{
|
||||
void rb_vm_check_redefinition_by_prepend(VALUE klass);
|
||||
VALUE origin;
|
||||
int changed = 0;
|
||||
|
||||
rb_frozen_class_p(klass);
|
||||
if (!OBJ_UNTRUSTED(klass)) {
|
||||
rb_secure(4);
|
||||
}
|
||||
|
||||
Check_Type(module, T_MODULE);
|
||||
|
||||
|
@ -804,18 +948,21 @@ rb_prepend_module(VALUE klass, VALUE module)
|
|||
origin = RCLASS_ORIGIN(klass);
|
||||
if (origin == klass) {
|
||||
origin = class_alloc(T_ICLASS, klass);
|
||||
RCLASS_SUPER(origin) = RCLASS_SUPER(klass);
|
||||
RCLASS_SUPER(klass) = origin;
|
||||
OBJ_WB_UNPROTECT(origin); /* TODO: conservertive shading. Need more survery. */
|
||||
RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass));
|
||||
RCLASS_SET_SUPER(klass, origin);
|
||||
RCLASS_ORIGIN(klass) = origin;
|
||||
RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass);
|
||||
RCLASS_M_TBL(klass) = st_init_numtable();
|
||||
RCLASS_M_TBL_WRAPPER(origin) = RCLASS_M_TBL_WRAPPER(klass);
|
||||
RCLASS_M_TBL_INIT(klass);
|
||||
st_foreach(RCLASS_M_TBL(origin), move_refined_method,
|
||||
(st_data_t) RCLASS_M_TBL(klass));
|
||||
}
|
||||
changed = include_modules_at(klass, klass, module);
|
||||
if (changed < 0)
|
||||
rb_raise(rb_eArgError, "cyclic prepend detected");
|
||||
if (changed) rb_clear_cache();
|
||||
if (changed) {
|
||||
rb_vm_check_redefinition_by_prepend(klass);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -840,10 +987,13 @@ rb_mod_included_modules(VALUE mod)
|
|||
{
|
||||
VALUE ary = rb_ary_new();
|
||||
VALUE p;
|
||||
VALUE origin = RCLASS_ORIGIN(mod);
|
||||
|
||||
for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
|
||||
if (BUILTIN_TYPE(p) == T_ICLASS) {
|
||||
rb_ary_push(ary, RBASIC(p)->klass);
|
||||
if (p != origin && BUILTIN_TYPE(p) == T_ICLASS) {
|
||||
VALUE m = RBASIC(p)->klass;
|
||||
if (RB_TYPE_P(m, T_MODULE))
|
||||
rb_ary_push(ary, m);
|
||||
}
|
||||
}
|
||||
return ary;
|
||||
|
@ -904,8 +1054,6 @@ rb_mod_ancestors(VALUE mod)
|
|||
VALUE p, ary = rb_ary_new();
|
||||
|
||||
for (p = mod; p; p = RCLASS_SUPER(p)) {
|
||||
if (FL_TEST(p, FL_SINGLETON))
|
||||
continue;
|
||||
if (BUILTIN_TYPE(p) == T_ICLASS) {
|
||||
rb_ary_push(ary, RBASIC(p)->klass);
|
||||
}
|
||||
|
@ -971,6 +1119,10 @@ method_entry_i(st_data_t key, st_data_t value, st_data_t data)
|
|||
st_table *list = (st_table *)data;
|
||||
long type;
|
||||
|
||||
if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
|
||||
me = rb_resolve_refined_method(Qnil, me, NULL);
|
||||
if (!me) return ST_CONTINUE;
|
||||
}
|
||||
if (!st_lookup(list, key, 0)) {
|
||||
if (UNDEFINED_METHOD_ENTRY_P(me)) {
|
||||
type = -1; /* none */
|
||||
|
@ -1106,13 +1258,14 @@ rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.methods(all=true) -> array
|
||||
* obj.methods(regular=true) -> array
|
||||
*
|
||||
* Returns a list of the names of public and protected methods of
|
||||
* <i>obj</i>. This will include all the methods accessible in
|
||||
* <i>obj</i>'s ancestors.
|
||||
* If the <i>all</i> parameter is set to <code>false</code>, only those methods
|
||||
* in the receiver will be listed.
|
||||
* If the <i>regular</i> parameter is set to <code>false</code>,
|
||||
* Returns an array of obj's public and protected singleton methods,
|
||||
* the array will not include methods in modules included in <i>obj</i>.
|
||||
*
|
||||
* class Klass
|
||||
* def klass_method()
|
||||
|
@ -1123,6 +1276,14 @@ rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)
|
|||
* # :==~, :!, :eql?
|
||||
* # :hash, :<=>, :class, :singleton_class]
|
||||
* k.methods.length #=> 57
|
||||
*
|
||||
* k.methods(false) #=> []
|
||||
* def k.singleton_method; end
|
||||
* k.methods(false) #=> [:singleton_method]
|
||||
*
|
||||
* module M123; def m123; end end
|
||||
* k.extend M123
|
||||
* k.methods(false) #=> [:singleton_method]
|
||||
*/
|
||||
|
||||
VALUE
|
||||
|
@ -1225,8 +1386,8 @@ rb_obj_public_methods(int argc, VALUE *argv, VALUE obj)
|
|||
VALUE
|
||||
rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
|
||||
{
|
||||
VALUE recur, ary, klass;
|
||||
st_table *list;
|
||||
VALUE recur, ary, klass, origin;
|
||||
st_table *list, *mtbl;
|
||||
|
||||
if (argc == 0) {
|
||||
recur = Qtrue;
|
||||
|
@ -1235,16 +1396,17 @@ rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
|
|||
rb_scan_args(argc, argv, "01", &recur);
|
||||
}
|
||||
klass = CLASS_OF(obj);
|
||||
origin = RCLASS_ORIGIN(klass);
|
||||
list = st_init_numtable();
|
||||
if (klass && FL_TEST(klass, FL_SINGLETON)) {
|
||||
if (RCLASS_M_TBL(klass))
|
||||
st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list);
|
||||
if ((mtbl = RCLASS_M_TBL(origin)) != 0)
|
||||
st_foreach(mtbl, method_entry_i, (st_data_t)list);
|
||||
klass = RCLASS_SUPER(klass);
|
||||
}
|
||||
if (RTEST(recur)) {
|
||||
while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) {
|
||||
if (RCLASS_M_TBL(klass))
|
||||
st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list);
|
||||
if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0)
|
||||
st_foreach(mtbl, method_entry_i, (st_data_t)list);
|
||||
klass = RCLASS_SUPER(klass);
|
||||
}
|
||||
}
|
||||
|
@ -1397,7 +1559,7 @@ singleton_class_of(VALUE obj)
|
|||
else {
|
||||
enum ruby_value_type type = BUILTIN_TYPE(obj);
|
||||
if (type == T_FLOAT || type == T_BIGNUM) {
|
||||
rb_raise(rb_eTypeError, "can't define singleton");
|
||||
rb_raise(rb_eTypeError, "can't define singleton");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1415,17 +1577,31 @@ singleton_class_of(VALUE obj)
|
|||
else {
|
||||
FL_UNSET(klass, FL_TAINT);
|
||||
}
|
||||
if (OBJ_UNTRUSTED(obj)) {
|
||||
OBJ_UNTRUST(klass);
|
||||
}
|
||||
else {
|
||||
FL_UNSET(klass, FL_UNTRUSTED);
|
||||
}
|
||||
if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the singleton class of \a obj, or nil if obj is not a
|
||||
* singleton object.
|
||||
*
|
||||
* \param obj an arbitrary object.
|
||||
* \return the singleton class or nil.
|
||||
*/
|
||||
VALUE
|
||||
rb_singleton_class_get(VALUE obj)
|
||||
{
|
||||
VALUE klass;
|
||||
|
||||
if (SPECIAL_CONST_P(obj)) {
|
||||
return rb_special_singleton_class(obj);
|
||||
}
|
||||
klass = RBASIC(obj)->klass;
|
||||
if (!FL_TEST(klass, FL_SINGLETON)) return Qnil;
|
||||
if (rb_ivar_get(klass, id_attached) != obj) return Qnil;
|
||||
return klass;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the singleton class of \a obj. Creates it if necessary.
|
||||
|
@ -1609,8 +1785,11 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
|
|||
}
|
||||
else {
|
||||
hash = rb_check_hash_type(last);
|
||||
if (!NIL_P(hash))
|
||||
argc--;
|
||||
if (!NIL_P(hash)) {
|
||||
VALUE opts = rb_extract_keywords(&hash);
|
||||
if (!hash) argc--;
|
||||
hash = opts ? opts : Qnil;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* capture leading mandatory arguments */
|
||||
|
@ -1674,6 +1853,119 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
|
|||
return argc;
|
||||
}
|
||||
|
||||
NORETURN(static void keyword_error(const char *error, VALUE keys));
|
||||
static void
|
||||
keyword_error(const char *error, VALUE keys)
|
||||
{
|
||||
const char *msg = "";
|
||||
if (RARRAY_LEN(keys) == 1) {
|
||||
keys = RARRAY_AREF(keys, 0);
|
||||
}
|
||||
else {
|
||||
keys = rb_ary_join(keys, rb_usascii_str_new2(", "));
|
||||
msg = "s";
|
||||
}
|
||||
rb_raise(rb_eArgError, "%s keyword%s: %"PRIsVALUE, error, msg, keys);
|
||||
}
|
||||
|
||||
NORETURN(static void unknown_keyword_error(VALUE hash, const ID *table, int keywords));
|
||||
static void
|
||||
unknown_keyword_error(VALUE hash, const ID *table, int keywords)
|
||||
{
|
||||
VALUE keys;
|
||||
int i;
|
||||
for (i = 0; i < keywords; i++) {
|
||||
rb_hash_delete(hash, ID2SYM(table[i]));
|
||||
}
|
||||
keys = rb_funcall(hash, rb_intern("keys"), 0, 0);
|
||||
if (!RB_TYPE_P(keys, T_ARRAY)) rb_raise(rb_eArgError, "unknown keyword");
|
||||
keyword_error("unknown", keys);
|
||||
}
|
||||
|
||||
static int
|
||||
separate_symbol(st_data_t key, st_data_t value, st_data_t arg)
|
||||
{
|
||||
VALUE *kwdhash = (VALUE *)arg;
|
||||
|
||||
if (!SYMBOL_P(key)) kwdhash++;
|
||||
if (!*kwdhash) *kwdhash = rb_hash_new();
|
||||
rb_hash_aset(*kwdhash, (VALUE)key, (VALUE)value);
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_extract_keywords(VALUE *orighash)
|
||||
{
|
||||
VALUE parthash[2] = {0, 0};
|
||||
VALUE hash = *orighash;
|
||||
|
||||
if (RHASH_EMPTY_P(hash)) {
|
||||
*orighash = 0;
|
||||
return hash;
|
||||
}
|
||||
st_foreach(rb_hash_tbl_raw(hash), separate_symbol, (st_data_t)&parthash);
|
||||
*orighash = parthash[1];
|
||||
return parthash[0];
|
||||
}
|
||||
|
||||
int
|
||||
rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
|
||||
{
|
||||
int i = 0, j;
|
||||
int rest = 0;
|
||||
VALUE missing = Qnil;
|
||||
st_data_t key;
|
||||
|
||||
#define extract_kwarg(keyword, val) \
|
||||
(key = (st_data_t)(keyword), values ? \
|
||||
st_delete(rb_hash_tbl_raw(keyword_hash), &key, (val)) : \
|
||||
st_lookup(rb_hash_tbl_raw(keyword_hash), key, (val)))
|
||||
|
||||
if (optional < 0) {
|
||||
rest = 1;
|
||||
optional = -1-optional;
|
||||
}
|
||||
if (values) {
|
||||
for (j = 0; j < required + optional; j++) {
|
||||
values[j] = Qundef;
|
||||
}
|
||||
}
|
||||
if (required) {
|
||||
for (; i < required; i++) {
|
||||
VALUE keyword = ID2SYM(table[i]);
|
||||
if (keyword_hash) {
|
||||
st_data_t val;
|
||||
if (extract_kwarg(keyword, &val)) {
|
||||
if (values) values[i] = (VALUE)val;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (NIL_P(missing)) missing = rb_ary_tmp_new(1);
|
||||
rb_ary_push(missing, keyword);
|
||||
}
|
||||
if (!NIL_P(missing)) {
|
||||
keyword_error("missing", missing);
|
||||
}
|
||||
}
|
||||
j = i;
|
||||
if (optional && keyword_hash) {
|
||||
for (i = 0; i < optional; i++) {
|
||||
st_data_t val;
|
||||
if (extract_kwarg(ID2SYM(table[required+i]), &val)) {
|
||||
if (values) values[required+i] = (VALUE)val;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!rest && keyword_hash) {
|
||||
if (RHASH_SIZE(keyword_hash) > (unsigned int)j) {
|
||||
unknown_keyword_error(keyword_hash, table, required+optional);
|
||||
}
|
||||
}
|
||||
return j;
|
||||
#undef extract_kwarg
|
||||
}
|
||||
|
||||
/*!
|
||||
* \}
|
||||
*/
|
||||
|
|
269
common.mk
269
common.mk
|
@ -14,7 +14,7 @@ RUBYLIB = $(PATH_SEPARATOR)
|
|||
RUBYOPT = -
|
||||
RUN_OPTS = --disable-gems
|
||||
|
||||
SPEC_GIT_BASE = git://github.com/rubyspec
|
||||
SPEC_GIT_BASE = git://github.com/nurse
|
||||
MSPEC_GIT_URL = $(SPEC_GIT_BASE)/mspec.git
|
||||
RUBYSPEC_GIT_URL = $(SPEC_GIT_BASE)/rubyspec.git
|
||||
|
||||
|
@ -33,7 +33,7 @@ MAINOBJ = $(NORMALMAINOBJ)
|
|||
EXTOBJS =
|
||||
DLDOBJS = $(DMYEXT)
|
||||
EXTSOLIBS =
|
||||
MINIOBJS = $(ARCHMINIOBJS) dmyencoding.$(OBJEXT) dmyversion.$(OBJEXT) miniprelude.$(OBJEXT)
|
||||
MINIOBJS = $(ARCHMINIOBJS) miniinit.$(OBJEXT) miniprelude.$(OBJEXT)
|
||||
ENC_MK = enc.mk
|
||||
|
||||
COMMONOBJS = array.$(OBJEXT) \
|
||||
|
@ -43,6 +43,7 @@ COMMONOBJS = array.$(OBJEXT) \
|
|||
complex.$(OBJEXT) \
|
||||
dir.$(OBJEXT) \
|
||||
dln_find.$(OBJEXT) \
|
||||
encoding.$(OBJEXT) \
|
||||
enum.$(OBJEXT) \
|
||||
enumerator.$(OBJEXT) \
|
||||
error.$(OBJEXT) \
|
||||
|
@ -84,6 +85,7 @@ COMMONOBJS = array.$(OBJEXT) \
|
|||
transcode.$(OBJEXT) \
|
||||
util.$(OBJEXT) \
|
||||
variable.$(OBJEXT) \
|
||||
version.$(OBJEXT) \
|
||||
compile.$(OBJEXT) \
|
||||
debug.$(OBJEXT) \
|
||||
iseq.$(OBJEXT) \
|
||||
|
@ -98,8 +100,8 @@ COMMONOBJS = array.$(OBJEXT) \
|
|||
$(MISSING)
|
||||
|
||||
EXPORTOBJS = $(DLNOBJ) \
|
||||
encoding.$(OBJEXT) \
|
||||
version.$(OBJEXT) \
|
||||
localeinit.$(OBJEXT) \
|
||||
loadpath.$(OBJEXT) \
|
||||
$(COMMONOBJS)
|
||||
|
||||
OBJS = $(EXPORTOBJS) prelude.$(OBJEXT)
|
||||
|
@ -109,8 +111,6 @@ GOLFOBJS = goruby.$(OBJEXT) golf_prelude.$(OBJEXT)
|
|||
|
||||
PRELUDE_SCRIPTS = $(srcdir)/prelude.rb $(srcdir)/enc/prelude.rb $(DEFAULT_PRELUDES)
|
||||
GEM_PRELUDE = $(srcdir)/gem_prelude.rb
|
||||
YES_GEM_PRELUDE = $(GEM_PRELUDE)
|
||||
NO_GEM_PRELUDE =
|
||||
PRELUDES = prelude.c miniprelude.c
|
||||
GOLFPRELUDES = golf_prelude.c
|
||||
|
||||
|
@ -120,7 +120,7 @@ SCRIPT_ARGS = --dest-dir="$(DESTDIR)" \
|
|||
--make-flags="$(MAKEFLAGS)"
|
||||
EXTMK_ARGS = $(SCRIPT_ARGS) --extension $(EXTS) --extstatic $(EXTSTATIC) \
|
||||
--make-flags="V=$(V) MINIRUBY='$(MINIRUBY)'" --
|
||||
INSTRUBY = $(SUDO) $(MINIRUBY) $(srcdir)/tool/rbinstall.rb
|
||||
INSTRUBY = $(SUDO) $(RUNRUBY) -r./$(arch)-fake $(srcdir)/tool/rbinstall.rb
|
||||
INSTRUBY_ARGS = $(SCRIPT_ARGS) \
|
||||
--data-mode=$(INSTALL_DATA_MODE) \
|
||||
--prog-mode=$(INSTALL_PROG_MODE) \
|
||||
|
@ -159,12 +159,13 @@ showflags:
|
|||
" DLDFLAGS = $(DLDFLAGS)" \
|
||||
" SOLIBS = $(SOLIBS)" \
|
||||
$(MESSAGE_END)
|
||||
-@$(CC_VERSION)
|
||||
|
||||
.PHONY: showconfig
|
||||
showconfig:
|
||||
@$(MESSAGE_BEGIN) \
|
||||
"$(configure_args)" \
|
||||
$(MESSAGE_END)
|
||||
@$(ECHO_BEGIN) \
|
||||
$(configure_args) \
|
||||
$(ECHO_END)
|
||||
|
||||
exts: build-ext
|
||||
|
||||
|
@ -183,9 +184,6 @@ $(MKMAIN_CMD): $(MKFILES) all-incs $(PREP) $(RBCONFIG) $(LIBRUBY)
|
|||
|
||||
prog: program wprogram
|
||||
|
||||
loadpath: $(PREP) PHONY
|
||||
$(MINIRUBY) -e 'p $$:'
|
||||
|
||||
$(PREP): $(MKFILES)
|
||||
|
||||
miniruby$(EXEEXT): config.status $(ALLOBJS) $(ARCHFILE) $(DTRACE_OBJ)
|
||||
|
@ -206,10 +204,11 @@ $(CAPIOUT)/.timestamp: Doxyfile $(PREP)
|
|||
Doxyfile: $(srcdir)/template/Doxyfile.tmpl $(PREP) $(srcdir)/tool/generic_erb.rb $(RBCONFIG)
|
||||
$(ECHO) generating $@
|
||||
$(Q) $(MINIRUBY) $(srcdir)/tool/generic_erb.rb -o $@ $(srcdir)/template/Doxyfile.tmpl \
|
||||
--srcdir="$(srcdir)" --miniruby="$(MINIRUBY)"
|
||||
--srcdir="$(srcdir)" --miniruby="$(BASERUBY)"
|
||||
|
||||
program: showflags $(PROGRAM)
|
||||
wprogram: showflags $(WPROGRAM)
|
||||
mini: PHONY miniruby$(EXEEXT)
|
||||
|
||||
$(PROGRAM) $(WPROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(SETUP) $(PREP)
|
||||
|
||||
|
@ -224,8 +223,8 @@ $(STATIC_RUBY)$(EXEEXT): $(MAINOBJ) $(DLDOBJS) $(EXTOBJS) $(LIBRUBY_A)
|
|||
$(Q)$(RM) $@
|
||||
$(PURIFY) $(CC) $(MAINOBJ) $(DLDOBJS) $(EXTOBJS) $(LIBRUBY_A) $(MAINLIBS) $(EXTLIBS) $(LIBS) $(OUTFLAG)$@ $(LDFLAGS) $(XLDFLAGS)
|
||||
|
||||
ruby.imp: $(EXPORTOBJS)
|
||||
$(Q)$(NM) -Pgp $(EXPORTOBJS) | \
|
||||
ruby.imp: $(COMMONOBJS)
|
||||
$(Q)$(NM) -Pgp $(COMMONOBJS) | \
|
||||
awk 'BEGIN{print "#!"}; $$2~/^[BDT]$$/&&$$1!~/^(Init_|.*_threadptr_|\.)/{print $$1}' | \
|
||||
sort -u -o $@
|
||||
|
||||
|
@ -262,7 +261,7 @@ post-install-ext:: post-install-ext-arch post-install-ext-comm
|
|||
install-arch: pre-install-arch do-install-arch post-install-arch
|
||||
pre-install-arch:: pre-install-bin pre-install-ext-arch
|
||||
do-install-arch: main
|
||||
$(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=bin --install=ext-arch
|
||||
$(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=arch
|
||||
post-install-arch:: post-install-bin post-install-ext-arch
|
||||
|
||||
install-comm: pre-install-comm do-install-comm post-install-comm
|
||||
|
@ -323,6 +322,11 @@ dont-install-all: $(PROGRAM)
|
|||
post-no-install-all:: post-no-install-local post-no-install-ext post-no-install-doc
|
||||
@$(NULLCMD)
|
||||
|
||||
uninstall: $(INSTALLED_LIST)
|
||||
$(Q)$(SUDO) $(MINIRUBY) $(srcdir)/tool/rbuninstall.rb --destdir=$(DESTDIR) $(INSTALLED_LIST)
|
||||
|
||||
reinstall: uninstall install
|
||||
|
||||
what-where-nodoc: no-install-nodoc
|
||||
no-install-nodoc: pre-no-install-nodoc dont-install-nodoc post-no-install-nodoc
|
||||
pre-no-install-nodoc:: pre-no-install-local pre-no-install-ext
|
||||
|
@ -405,6 +409,13 @@ do-install-doc: $(PROGRAM)
|
|||
post-install-doc::
|
||||
@$(NULLCMD)
|
||||
|
||||
install-gem: pre-install-gem do-install-gem post-install-gem
|
||||
pre-install-gem:: pre-install-bin pre-install-lib pre-install-man
|
||||
do-install-gem: $(PROGRAM)
|
||||
$(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=gem
|
||||
post-install-gem::
|
||||
@$(NULLCMD)
|
||||
|
||||
rdoc: PHONY main
|
||||
@echo Generating RDoc documentation
|
||||
$(Q) $(XRUBY) "$(srcdir)/bin/rdoc" --root "$(srcdir)" --page-dir "$(srcdir)/doc" --encoding=UTF-8 --no-force-update --all --ri --op "$(RDOCOUT)" --debug $(RDOCFLAGS) "$(srcdir)"
|
||||
|
@ -413,6 +424,16 @@ rdoc-coverage: PHONY main
|
|||
@echo Generating RDoc coverage report
|
||||
$(Q) $(XRUBY) "$(srcdir)/bin/rdoc" --root "$(srcdir)" --encoding=UTF-8 --all --quiet -C $(RDOCFLAGS) "$(srcdir)"
|
||||
|
||||
RDOCBENCHOUT=/tmp/rdocbench
|
||||
|
||||
GCBENCH_ITEM=null
|
||||
|
||||
gcbench: PHONY
|
||||
$(Q) $(XRUBY) "$(srcdir)/benchmark/gc/gcbench.rb" $(GCBENCH_ITEM)
|
||||
|
||||
gcbench-rdoc: PHONY
|
||||
$(Q) $(XRUBY) "$(srcdir)/benchmark/gc/gcbench.rb" rdoc
|
||||
|
||||
nodoc: PHONY
|
||||
|
||||
what-where-doc: no-install-doc
|
||||
|
@ -425,7 +446,7 @@ post-no-install-doc::
|
|||
|
||||
CLEAR_INSTALLED_LIST = clear-installed-list
|
||||
|
||||
install-prereq: $(CLEAR_INSTALLED_LIST) PHONY
|
||||
install-prereq: $(CLEAR_INSTALLED_LIST) yes-fake PHONY
|
||||
|
||||
clear-installed-list: PHONY
|
||||
@> $(INSTALLED_LIST) set MAKE="$(MAKE)"
|
||||
|
@ -447,7 +468,7 @@ clean-docs: clean-rdoc clean-capi
|
|||
distclean: distclean-ext distclean-local distclean-enc distclean-golf distclean-extout distclean-platform
|
||||
distclean-local:: clean-local
|
||||
$(Q)$(RM) $(MKFILES) yasmdata.rb *.inc
|
||||
$(Q)$(RM) config.cache config.status config.status.lineno $(PRELUDES)
|
||||
$(Q)$(RM) config.cache config.status config.status.lineno
|
||||
$(Q)$(RM) *~ *.bak *.stackdump core *.core gmon.out $(PREP)
|
||||
distclean-ext:: PHONY
|
||||
distclean-golf: clean-golf
|
||||
|
@ -459,14 +480,15 @@ distclean-platform: clean-platform
|
|||
|
||||
realclean:: realclean-ext realclean-local realclean-enc realclean-golf realclean-extout
|
||||
realclean-local:: distclean-local
|
||||
$(Q)$(RM) parse.c parse.h lex.c newline.c revision.h
|
||||
realclean-ext::
|
||||
$(Q)$(RM) parse.c parse.h lex.c newline.c miniprelude.c revision.h
|
||||
realclean-ext:: PHONY
|
||||
realclean-golf: distclean-golf
|
||||
realclean-capi: PHONY
|
||||
realclean-extout: distclean-extout
|
||||
|
||||
clean-ext distclean-ext realclean-ext::
|
||||
$(Q)$(RM) $(EXTS_MK)
|
||||
$(Q)$(RM) $(EXTOUT)/.timestamp/.*.time
|
||||
|
||||
clean-enc distclean-enc realclean-enc: PHONY
|
||||
|
||||
|
@ -481,23 +503,23 @@ no-fake: PHONY
|
|||
btest: $(TEST_RUNNABLE)-btest
|
||||
no-btest: PHONY
|
||||
yes-btest: fake miniruby$(EXEEXT) PHONY
|
||||
$(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(BTESTRUBY)" $(OPTS) $(TESTOPTS)
|
||||
$(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(BTESTRUBY) $(RUN_OPTS)" $(OPTS) $(TESTOPTS)
|
||||
|
||||
btest-ruby: $(TEST_RUNNABLE)-btest-ruby
|
||||
no-btest-ruby: PHONY
|
||||
yes-btest-ruby: prog PHONY
|
||||
$(Q)$(RUNRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM) -I$(srcdir)/lib" -q $(OPTS) $(TESTOPTS)
|
||||
$(Q)$(RUNRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM) -I$(srcdir)/lib $(RUN_OPTS)" -q $(OPTS) $(TESTOPTS)
|
||||
|
||||
test-sample: $(TEST_RUNNABLE)-test-sample
|
||||
no-test-sample: PHONY
|
||||
yes-test-sample: prog PHONY
|
||||
$(Q)$(RUNRUBY) $(srcdir)/tool/rubytest.rb $(OPTS) $(TESTOPTS)
|
||||
$(Q)$(RUNRUBY) $(srcdir)/tool/rubytest.rb --run-opt=$(RUN_OPTS) $(OPTS) $(TESTOPTS)
|
||||
|
||||
test-knownbugs: test-knownbug
|
||||
test-knownbug: $(TEST_RUNNABLE)-test-knownbug
|
||||
no-test-knownbug: PHONY
|
||||
yes-test-knownbug: prog PHONY
|
||||
-$(RUNRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM)" $(OPTS) $(TESTOPTS) $(srcdir)/KNOWNBUGS.rb
|
||||
-$(RUNRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM) $(RUN_OPTS)" $(OPTS) $(TESTOPTS) $(srcdir)/KNOWNBUGS.rb
|
||||
|
||||
test: test-sample btest-ruby test-knownbug
|
||||
|
||||
|
@ -568,7 +590,7 @@ PHONY:
|
|||
|
||||
{$(srcdir)}.y.c:
|
||||
$(ECHO) generating $@
|
||||
$(Q)$(BASERUBY) $(srcdir)/tool/id2token.rb --path-separator=$(PATH_SEPARATOR) --vpath=$(VPATH) id.h $(SRC_FILE) > parse.tmp.y
|
||||
$(Q)$(BASERUBY) $(srcdir)/tool/id2token.rb --path-separator=.$(PATH_SEPARATOR)./ --vpath=$(VPATH) id.h $(SRC_FILE) > parse.tmp.y
|
||||
$(Q)$(YACC) -d $(YFLAGS) -o y.tab.c parse.tmp.y
|
||||
$(Q)$(RM) parse.tmp.y
|
||||
$(Q)sed -f $(srcdir)/tool/ytab.sed -e "/^#/s!parse\.tmp\.[iy]!parse.y!" -e "/^#/s!y\.tab\.c!$@!" y.tab.c > $@.new
|
||||
|
@ -576,31 +598,6 @@ PHONY:
|
|||
$(Q)sed -e "/^#line.*y\.tab\.h/d;/^#line.*parse.*\.y/d" y.tab.h > $(@:.c=.h)
|
||||
$(Q)$(RM) y.tab.c y.tab.h
|
||||
|
||||
acosh.$(OBJEXT): {$(VPATH)}acosh.c
|
||||
alloca.$(OBJEXT): {$(VPATH)}alloca.c {$(VPATH)}config.h
|
||||
crypt.$(OBJEXT): {$(VPATH)}crypt.c
|
||||
dup2.$(OBJEXT): {$(VPATH)}dup2.c
|
||||
erf.$(OBJEXT): {$(VPATH)}erf.c
|
||||
finite.$(OBJEXT): {$(VPATH)}finite.c
|
||||
flock.$(OBJEXT): {$(VPATH)}flock.c
|
||||
memcmp.$(OBJEXT): {$(VPATH)}memcmp.c
|
||||
memmove.$(OBJEXT): {$(VPATH)}memmove.c
|
||||
mkdir.$(OBJEXT): {$(VPATH)}mkdir.c
|
||||
setproctitle.$(OBJEXT): {$(VPATH)}setproctitle.c {$(VPATH)}util.h $(RUBY_H_INCLUDES)
|
||||
strchr.$(OBJEXT): {$(VPATH)}strchr.c
|
||||
strdup.$(OBJEXT): {$(VPATH)}strdup.c
|
||||
strerror.$(OBJEXT): {$(VPATH)}strerror.c
|
||||
strlcat.$(OBJEXT): {$(VPATH)}strlcat.c
|
||||
strlcpy.$(OBJEXT): {$(VPATH)}strlcpy.c
|
||||
strstr.$(OBJEXT): {$(VPATH)}strstr.c
|
||||
strtod.$(OBJEXT): {$(VPATH)}strtod.c
|
||||
strtol.$(OBJEXT): {$(VPATH)}strtol.c
|
||||
nt.$(OBJEXT): {$(VPATH)}nt.c
|
||||
os2.$(OBJEXT): {$(VPATH)}os2.c
|
||||
dl_os2.$(OBJEXT): {$(VPATH)}dl_os2.c
|
||||
ia64.$(OBJEXT): {$(VPATH)}ia64.s
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
$(PLATFORM_D):
|
||||
$(Q) $(MAKEDIRS) $(PLATFORM_DIR)
|
||||
@exit > $@
|
||||
|
@ -614,18 +611,47 @@ ENCODING_H_INCLUDES= {$(VPATH)}encoding.h {$(VPATH)}oniguruma.h
|
|||
PROBES_H_INCLUDES = {$(VPATH)}probes.h
|
||||
VM_CORE_H_INCLUDES = {$(VPATH)}vm_core.h {$(VPATH)}thread_$(THREAD_MODEL).h \
|
||||
{$(VPATH)}node.h {$(VPATH)}method.h {$(VPATH)}ruby_atomic.h \
|
||||
{$(VPATH)}vm_debug.h {$(VPATH)}id.h
|
||||
{$(VPATH)}vm_debug.h {$(VPATH)}id.h {$(VPATH)}thread_native.h
|
||||
|
||||
###
|
||||
|
||||
acosh.$(OBJEXT): {$(VPATH)}acosh.c
|
||||
alloca.$(OBJEXT): {$(VPATH)}alloca.c {$(VPATH)}config.h
|
||||
crypt.$(OBJEXT): {$(VPATH)}crypt.c
|
||||
dup2.$(OBJEXT): {$(VPATH)}dup2.c
|
||||
erf.$(OBJEXT): {$(VPATH)}erf.c
|
||||
finite.$(OBJEXT): {$(VPATH)}finite.c
|
||||
flock.$(OBJEXT): {$(VPATH)}flock.c
|
||||
memcmp.$(OBJEXT): {$(VPATH)}memcmp.c
|
||||
memmove.$(OBJEXT): {$(VPATH)}memmove.c
|
||||
mkdir.$(OBJEXT): {$(VPATH)}mkdir.c
|
||||
setproctitle.$(OBJEXT): {$(VPATH)}setproctitle.c {$(VPATH)}util.h $(RUBY_H_INCLUDES) $(hdrdir)/ruby.h
|
||||
strchr.$(OBJEXT): {$(VPATH)}strchr.c
|
||||
strdup.$(OBJEXT): {$(VPATH)}strdup.c
|
||||
strerror.$(OBJEXT): {$(VPATH)}strerror.c
|
||||
strlcat.$(OBJEXT): {$(VPATH)}strlcat.c
|
||||
strlcpy.$(OBJEXT): {$(VPATH)}strlcpy.c
|
||||
strstr.$(OBJEXT): {$(VPATH)}strstr.c
|
||||
strtod.$(OBJEXT): {$(VPATH)}strtod.c
|
||||
strtol.$(OBJEXT): {$(VPATH)}strtol.c
|
||||
nt.$(OBJEXT): {$(VPATH)}nt.c
|
||||
os2.$(OBJEXT): {$(VPATH)}os2.c
|
||||
dl_os2.$(OBJEXT): {$(VPATH)}dl_os2.c
|
||||
ia64.$(OBJEXT): {$(VPATH)}ia64.s
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
###
|
||||
|
||||
addr2line.$(OBJEXT): {$(VPATH)}addr2line.c {$(VPATH)}addr2line.h {$(VPATH)}config.h
|
||||
array.$(OBJEXT): {$(VPATH)}array.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h $(PROBES_H_INCLUDES) {$(VPATH)}id.h
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h $(PROBES_H_INCLUDES) {$(VPATH)}id.h {$(VPATH)}vm_opts.h
|
||||
bignum.$(OBJEXT): {$(VPATH)}bignum.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
|
||||
{$(VPATH)}thread.h {$(VPATH)}internal.h
|
||||
class.$(OBJEXT): {$(VPATH)}class.c $(RUBY_H_INCLUDES) \
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}internal.h {$(VPATH)}constant.h
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}internal.h {$(VPATH)}constant.h {$(VPATH)}vm_opts.h
|
||||
compar.$(OBJEXT): {$(VPATH)}compar.c $(RUBY_H_INCLUDES)
|
||||
complex.$(OBJEXT): {$(VPATH)}complex.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}internal.h
|
||||
{$(VPATH)}internal.h $(hdrdir)/ruby.h
|
||||
dir.$(OBJEXT): {$(VPATH)}dir.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
|
||||
$(ENCODING_H_INCLUDES) \
|
||||
{$(VPATH)}internal.h
|
||||
|
@ -633,26 +659,23 @@ dln.$(OBJEXT): {$(VPATH)}dln.c {$(VPATH)}dln.h $(RUBY_H_INCLUDES)
|
|||
dln_find.$(OBJEXT): {$(VPATH)}dln_find.c {$(VPATH)}dln.h $(RUBY_H_INCLUDES)
|
||||
dmydln.$(OBJEXT): {$(VPATH)}dmydln.c $(RUBY_H_INCLUDES)
|
||||
dmyext.$(OBJEXT): {$(VPATH)}dmyext.c
|
||||
dmyencoding.$(OBJEXT): {$(VPATH)}dmyencoding.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}regenc.h {$(VPATH)}util.h $(ENCODING_H_INCLUDES) \
|
||||
{$(VPATH)}encoding.c {$(VPATH)}internal.h
|
||||
encoding.$(OBJEXT): {$(VPATH)}encoding.c $(RUBY_H_INCLUDES) \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}regenc.h {$(VPATH)}util.h \
|
||||
{$(VPATH)}internal.h
|
||||
enum.$(OBJEXT): {$(VPATH)}enum.c $(RUBY_H_INCLUDES) {$(VPATH)}node.h \
|
||||
{$(VPATH)}util.h {$(VPATH)}id.h
|
||||
{$(VPATH)}util.h {$(VPATH)}id.h {$(VPATH)}internal.h
|
||||
enumerator.$(OBJEXT): {$(VPATH)}enumerator.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}internal.h
|
||||
{$(VPATH)}internal.h {$(VPATH)}node.h
|
||||
error.$(OBJEXT): {$(VPATH)}error.c {$(VPATH)}known_errors.inc \
|
||||
$(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) $(ENCODING_H_INCLUDES) \
|
||||
{$(VPATH)}internal.h
|
||||
{$(VPATH)}internal.h {$(VPATH)}vm_opts.h
|
||||
eval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}eval_intern.h {$(VPATH)}vm.h \
|
||||
$(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) {$(VPATH)}eval_error.c \
|
||||
{$(VPATH)}eval_jump.c {$(VPATH)}gc.h {$(VPATH)}iseq.h \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h $(PROBES_H_INCLUDES)
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h $(PROBES_H_INCLUDES) {$(VPATH)}vm_opts.h {$(VPATH)}probes_helper.h
|
||||
load.$(OBJEXT): {$(VPATH)}load.c {$(VPATH)}eval_intern.h \
|
||||
{$(VPATH)}util.h $(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) \
|
||||
{$(VPATH)}dln.h {$(VPATH)}internal.h $(PROBES_H_INCLUDES)
|
||||
{$(VPATH)}dln.h {$(VPATH)}internal.h $(PROBES_H_INCLUDES) {$(VPATH)}vm_opts.h
|
||||
file.$(OBJEXT): {$(VPATH)}file.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}util.h {$(VPATH)}dln.h \
|
||||
{$(VPATH)}internal.h
|
||||
|
@ -660,44 +683,45 @@ gc.$(OBJEXT): {$(VPATH)}gc.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \
|
|||
{$(VPATH)}regex.h $(ENCODING_H_INCLUDES) $(VM_CORE_H_INCLUDES) \
|
||||
{$(VPATH)}gc.h {$(VPATH)}io.h {$(VPATH)}eval_intern.h {$(VPATH)}util.h \
|
||||
{$(VPATH)}internal.h {$(VPATH)}constant.h \
|
||||
{$(VPATH)}thread.h $(PROBES_H_INCLUDES)
|
||||
{$(VPATH)}thread.h $(PROBES_H_INCLUDES) {$(VPATH)}vm_opts.h {$(VPATH)}debug.h
|
||||
hash.$(OBJEXT): {$(VPATH)}hash.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h $(PROBES_H_INCLUDES)
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h $(PROBES_H_INCLUDES) {$(VPATH)}vm_opts.h
|
||||
inits.$(OBJEXT): {$(VPATH)}inits.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}internal.h
|
||||
io.$(OBJEXT): {$(VPATH)}io.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \
|
||||
{$(VPATH)}util.h $(ENCODING_H_INCLUDES) {$(VPATH)}dln.h \
|
||||
{$(VPATH)}internal.h {$(VPATH)}thread.h {$(VPATH)}id.h
|
||||
main.$(OBJEXT): {$(VPATH)}main.c $(RUBY_H_INCLUDES) {$(VPATH)}node.h {$(VPATH)}vm_debug.h
|
||||
{$(VPATH)}internal.h {$(VPATH)}thread.h {$(VPATH)}id.h {$(VPATH)}ruby_atomic.h
|
||||
main.$(OBJEXT): {$(VPATH)}main.c $(RUBY_H_INCLUDES) {$(VPATH)}node.h {$(VPATH)}vm_debug.h {$(VPATH)}vm_opts.h $(hdrdir)/ruby.h
|
||||
marshal.$(OBJEXT): {$(VPATH)}marshal.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}util.h {$(VPATH)}internal.h
|
||||
math.$(OBJEXT): {$(VPATH)}math.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}internal.h
|
||||
node.$(OBJEXT): {$(VPATH)}node.c $(RUBY_H_INCLUDES) \
|
||||
$(VM_CORE_H_INCLUDES)
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}vm_opts.h {$(VPATH)}internal.h
|
||||
numeric.$(OBJEXT): {$(VPATH)}numeric.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}util.h $(ENCODING_H_INCLUDES) {$(VPATH)}internal.h {$(VPATH)}id.h
|
||||
object.$(OBJEXT): {$(VPATH)}object.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
|
||||
{$(VPATH)}internal.h {$(VPATH)}constant.h $(ENCODING_H_INCLUDES) $(PROBES_H_INCLUDES)
|
||||
{$(VPATH)}internal.h {$(VPATH)}constant.h $(ENCODING_H_INCLUDES) $(PROBES_H_INCLUDES) \
|
||||
{$(VPATH)}vm_opts.h {$(VPATH)}id.h
|
||||
pack.$(OBJEXT): {$(VPATH)}pack.c $(RUBY_H_INCLUDES) {$(VPATH)}encoding.h \
|
||||
{$(VPATH)}oniguruma.h
|
||||
{$(VPATH)}oniguruma.h {$(VPATH)}internal.h
|
||||
parse.$(OBJEXT): {$(VPATH)}parse.c $(RUBY_H_INCLUDES) {$(VPATH)}node.h \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}id.h {$(VPATH)}regenc.h \
|
||||
{$(VPATH)}regex.h {$(VPATH)}util.h {$(VPATH)}lex.c \
|
||||
{$(VPATH)}defs/keywords {$(VPATH)}id.c {$(VPATH)}parse.y \
|
||||
{$(VPATH)}parse.h {$(VPATH)}internal.h $(PROBES_H_INCLUDES)
|
||||
{$(VPATH)}parse.h {$(VPATH)}internal.h $(PROBES_H_INCLUDES) {$(VPATH)}vm_opts.h
|
||||
proc.$(OBJEXT): {$(VPATH)}proc.c {$(VPATH)}eval_intern.h \
|
||||
$(RUBY_H_INCLUDES) {$(VPATH)}gc.h $(VM_CORE_H_INCLUDES) \
|
||||
{$(VPATH)}internal.h {$(VPATH)}iseq.h
|
||||
{$(VPATH)}internal.h {$(VPATH)}iseq.h {$(VPATH)}vm_opts.h
|
||||
process.$(OBJEXT): {$(VPATH)}process.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}util.h {$(VPATH)}io.h $(ENCODING_H_INCLUDES) {$(VPATH)}dln.h \
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}internal.h \
|
||||
{$(VPATH)}thread.h
|
||||
{$(VPATH)}thread.h {$(VPATH)}vm_opts.h
|
||||
random.$(OBJEXT): {$(VPATH)}random.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}siphash.c {$(VPATH)}siphash.h
|
||||
{$(VPATH)}siphash.c {$(VPATH)}siphash.h {$(VPATH)}internal.h
|
||||
range.$(OBJEXT): {$(VPATH)}range.c $(RUBY_H_INCLUDES) \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h {$(VPATH)}id.h
|
||||
rational.$(OBJEXT): {$(VPATH)}rational.c $(RUBY_H_INCLUDES) {$(VPATH)}internal.h
|
||||
rational.$(OBJEXT): {$(VPATH)}rational.c $(RUBY_H_INCLUDES) {$(VPATH)}internal.h $(hdrdir)/ruby.h
|
||||
re.$(OBJEXT): {$(VPATH)}re.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \
|
||||
{$(VPATH)}regex.h $(ENCODING_H_INCLUDES) {$(VPATH)}util.h \
|
||||
{$(VPATH)}regint.h {$(VPATH)}regenc.h {$(VPATH)}internal.h
|
||||
|
@ -717,47 +741,52 @@ regsyntax.$(OBJEXT): {$(VPATH)}regsyntax.c {$(VPATH)}regint.h \
|
|||
{$(VPATH)}regenc.h {$(VPATH)}oniguruma.h $(RUBY_H_INCLUDES)
|
||||
ruby.$(OBJEXT): {$(VPATH)}ruby.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}eval_intern.h $(VM_CORE_H_INCLUDES) \
|
||||
{$(VPATH)}dln.h {$(VPATH)}internal.h
|
||||
safe.$(OBJEXT): {$(VPATH)}safe.c $(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES)
|
||||
{$(VPATH)}dln.h {$(VPATH)}internal.h {$(VPATH)}vm_opts.h
|
||||
safe.$(OBJEXT): {$(VPATH)}safe.c $(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) {$(VPATH)}vm_opts.h {$(VPATH)}internal.h
|
||||
signal.$(OBJEXT): {$(VPATH)}signal.c $(RUBY_H_INCLUDES) \
|
||||
$(VM_CORE_H_INCLUDES)
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}vm_opts.h {$(VPATH)}internal.h {$(VPATH)}ruby_atomic.h {$(VPATH)}eval_intern.h
|
||||
sprintf.$(OBJEXT): {$(VPATH)}sprintf.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \
|
||||
{$(VPATH)}regex.h {$(VPATH)}vsnprintf.c $(ENCODING_H_INCLUDES)
|
||||
{$(VPATH)}regex.h {$(VPATH)}vsnprintf.c $(ENCODING_H_INCLUDES) {$(VPATH)}internal.h
|
||||
st.$(OBJEXT): {$(VPATH)}st.c $(RUBY_H_INCLUDES)
|
||||
strftime.$(OBJEXT): {$(VPATH)}strftime.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}timev.h $(ENCODING_H_INCLUDES)
|
||||
string.$(OBJEXT): {$(VPATH)}string.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \
|
||||
{$(VPATH)}regex.h $(ENCODING_H_INCLUDES) {$(VPATH)}internal.h $(PROBES_H_INCLUDES)
|
||||
{$(VPATH)}regex.h $(ENCODING_H_INCLUDES) {$(VPATH)}internal.h $(PROBES_H_INCLUDES) {$(VPATH)}vm_opts.h {$(VPATH)}node.h {$(VPATH)}ruby_atomic.h {$(VPATH)}vm_core.h {$(VPATH)}vm_debug.h {$(VPATH)}id.h {$(VPATH)}method.h {$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}thread_native.h
|
||||
struct.$(OBJEXT): {$(VPATH)}struct.c $(RUBY_H_INCLUDES) {$(VPATH)}internal.h
|
||||
thread.$(OBJEXT): {$(VPATH)}thread.c {$(VPATH)}eval_intern.h \
|
||||
$(RUBY_H_INCLUDES) {$(VPATH)}gc.h $(VM_CORE_H_INCLUDES) \
|
||||
{$(VPATH)}thread_$(THREAD_MODEL).c $(ENCODING_H_INCLUDES) \
|
||||
{$(VPATH)}internal.h {$(VPATH)}io.h {$(VPATH)}thread.h
|
||||
{$(VPATH)}internal.h {$(VPATH)}io.h {$(VPATH)}thread.h {$(VPATH)}timev.h {$(VPATH)}vm_opts.h
|
||||
transcode.$(OBJEXT): {$(VPATH)}transcode.c $(RUBY_H_INCLUDES) \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}transcode_data.h {$(VPATH)}internal.h
|
||||
cont.$(OBJEXT): {$(VPATH)}cont.c $(RUBY_H_INCLUDES) \
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}gc.h {$(VPATH)}eval_intern.h \
|
||||
{$(VPATH)}internal.h
|
||||
{$(VPATH)}internal.h {$(VPATH)}vm_opts.h
|
||||
time.$(OBJEXT): {$(VPATH)}time.c $(RUBY_H_INCLUDES) \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}timev.h {$(VPATH)}internal.h
|
||||
util.$(OBJEXT): {$(VPATH)}util.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
|
||||
{$(VPATH)}internal.h
|
||||
variable.$(OBJEXT): {$(VPATH)}variable.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}node.h {$(VPATH)}util.h {$(VPATH)}encoding.h \
|
||||
{$(VPATH)}node.h {$(VPATH)}util.h {$(VPATH)}encoding.h {$(VPATH)}id.h \
|
||||
{$(VPATH)}oniguruma.h {$(VPATH)}internal.h {$(VPATH)}constant.h
|
||||
version.$(OBJEXT): {$(VPATH)}version.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}version.h $(srcdir)/version.h $(srcdir)/revision.h {$(VPATH)}config.h \
|
||||
$(srcdir)/include/ruby/version.h $(srcdir)/version.h $(srcdir)/revision.h {$(VPATH)}config.h
|
||||
loadpath.$(OBJEXT): {$(VPATH)}loadpath.c $(RUBY_H_INCLUDES) \
|
||||
$(srcdir)/include/ruby/version.h $(srcdir)/version.h {$(VPATH)}config.h \
|
||||
verconf.h
|
||||
dmyversion.$(OBJEXT): {$(VPATH)}dmyversion.c version.$(OBJEXT)
|
||||
localeinit.$(OBJEXT): {$(VPATH)}localeinit.c $(RUBY_H_INCLUDES) \
|
||||
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h
|
||||
miniinit.$(OBJEXT): {$(VPATH)}miniinit.c $(RUBY_H_INCLUDES) \
|
||||
$(ENCODING_H_INCLUDES)
|
||||
|
||||
compile.$(OBJEXT): {$(VPATH)}compile.c {$(VPATH)}iseq.h \
|
||||
$(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) {$(VPATH)}insns.inc \
|
||||
{$(VPATH)}insns_info.inc {$(VPATH)}optinsn.inc \
|
||||
{$(VPATH)}optunifs.inc {$(VPATH)}opt_sc.inc {$(VPATH)}insns.inc \
|
||||
{$(VPATH)}internal.h
|
||||
{$(VPATH)}internal.h {$(VPATH)}vm_opts.h
|
||||
iseq.$(OBJEXT): {$(VPATH)}iseq.c {$(VPATH)}gc.h {$(VPATH)}iseq.h \
|
||||
$(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) {$(VPATH)}insns.inc \
|
||||
{$(VPATH)}insns_info.inc {$(VPATH)}node_name.inc {$(VPATH)}internal.h
|
||||
{$(VPATH)}insns_info.inc {$(VPATH)}node_name.inc {$(VPATH)}internal.h {$(VPATH)}vm_opts.h {$(VPATH)}ruby_atomic.h {$(VPATH)}eval_intern.h
|
||||
vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}gc.h {$(VPATH)}iseq.h \
|
||||
{$(VPATH)}eval_intern.h $(RUBY_H_INCLUDES) $(ENCODING_H_INCLUDES) \
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}vm_method.c {$(VPATH)}vm_eval.c \
|
||||
|
@ -765,28 +794,30 @@ vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}gc.h {$(VPATH)}iseq.h \
|
|||
{$(VPATH)}vm_exec.h {$(VPATH)}insns.def {$(VPATH)}vmtc.inc \
|
||||
{$(VPATH)}vm.inc {$(VPATH)}insns.inc \
|
||||
{$(VPATH)}internal.h {$(VPATH)}vm.h {$(VPATH)}constant.h \
|
||||
$(PROBES_H_INCLUDES) {$(VPATH)}probes_helper.h
|
||||
$(PROBES_H_INCLUDES) {$(VPATH)}probes_helper.h {$(VPATH)}vm_opts.h
|
||||
vm_dump.$(OBJEXT): {$(VPATH)}vm_dump.c $(RUBY_H_INCLUDES) \
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}addr2line.h \
|
||||
{$(VPATH)}internal.h
|
||||
{$(VPATH)}internal.h {$(VPATH)}vm_opts.h
|
||||
debug.$(OBJEXT): {$(VPATH)}debug.c $(RUBY_H_INCLUDES) \
|
||||
$(ENCODING_H_INCLUDES) $(VM_CORE_H_INCLUDES) {$(VPATH)}eval_intern.h \
|
||||
{$(VPATH)}util.h
|
||||
{$(VPATH)}util.h {$(VPATH)}vm_opts.h {$(VPATH)}internal.h
|
||||
id.$(OBJEXT): {$(VPATH)}id.c $(RUBY_H_INCLUDES) {$(VPATH)}id.h {$(VPATH)}vm_opts.h
|
||||
vm_backtrace.$(OBJEXT): {$(VPATH)}vm_backtrace.c \
|
||||
$(VM_CORE_H_INCLUDES) $(RUBY_H_INCLUDES) $(ENCODING_H_INCLUDES) \
|
||||
{$(VPATH)}internal.h {$(VPATH)}iseq.h {$(VPATH)}debug.h
|
||||
{$(VPATH)}internal.h {$(VPATH)}iseq.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}ruby_atomic.h {$(VPATH)}eval_intern.h
|
||||
vm_trace.$(OBJEXT): {$(VPATH)}vm_trace.c $(ENCODING_H_INCLUDES) \
|
||||
$(VM_CORE_H_INCLUDES) $(RUBY_H_INCLUDES) {$(VPATH)}debug.h \
|
||||
{$(VPATH)}internal.h
|
||||
{$(VPATH)}internal.h {$(VPATH)}vm_opts.h {$(VPATH)}ruby_atomic.h {$(VPATH)}eval_intern.h
|
||||
miniprelude.$(OBJEXT): {$(VPATH)}miniprelude.c $(RUBY_H_INCLUDES) \
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}internal.h
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}internal.h {$(VPATH)}vm_opts.h
|
||||
prelude.$(OBJEXT): {$(VPATH)}prelude.c $(RUBY_H_INCLUDES) \
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}internal.h
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}internal.h {$(VPATH)}vm_opts.h
|
||||
golf_prelude.$(OBJEXT): {$(VPATH)}golf_prelude.c $(RUBY_H_INCLUDES) \
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}internal.h
|
||||
$(VM_CORE_H_INCLUDES) {$(VPATH)}internal.h {$(VPATH)}vm_opts.h
|
||||
goruby.$(OBJEXT): {$(VPATH)}goruby.c {$(VPATH)}main.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}vm_debug.h {$(VPATH)}node.h
|
||||
{$(VPATH)}vm_debug.h {$(VPATH)}node.h $(hdrdir)/ruby.h
|
||||
|
||||
sizes.$(OBJEXT): {$(VPATH)}sizes.c $(RUBY_H_INCLUDES)
|
||||
|
||||
ascii.$(OBJEXT): {$(VPATH)}ascii.c {$(VPATH)}regenc.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}oniguruma.h {$(VPATH)}missing.h $(RUBY_H_INCLUDES)
|
||||
|
@ -802,7 +833,8 @@ unicode.$(OBJEXT): {$(VPATH)}unicode.c {$(VPATH)}regint.h \
|
|||
utf_8.$(OBJEXT): {$(VPATH)}utf_8.c {$(VPATH)}regenc.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}oniguruma.h {$(VPATH)}missing.h $(RUBY_H_INCLUDES)
|
||||
|
||||
win32/win32.$(OBJEXT): {$(VPATH)}win32/win32.c $(RUBY_H_INCLUDES) $(PLATFORM_D)
|
||||
win32/win32.$(OBJEXT): {$(VPATH)}win32/win32.c {$(VPATH)}dln.h {$(VPATH)}dln_find.c \
|
||||
{$(VPATH)}internal.h $(RUBY_H_INCLUDES) $(PLATFORM_D)
|
||||
win32/file.$(OBJEXT): {$(VPATH)}win32/file.c $(RUBY_H_INCLUDES) $(PLATFORM_D)
|
||||
|
||||
$(NEWLINE_C): $(srcdir)/enc/trans/newline.trans $(srcdir)/tool/transcode-tblgen.rb
|
||||
|
@ -811,6 +843,10 @@ newline.$(OBJEXT): $(NEWLINE_C) {$(VPATH)}defines.h \
|
|||
{$(VPATH)}intern.h {$(VPATH)}missing.h {$(VPATH)}st.h \
|
||||
{$(VPATH)}transcode_data.h {$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}subst.h
|
||||
|
||||
verconf.h: $(srcdir)/template/verconf.h.in $(srcdir)/tool/generic_erb.rb $(RBCONFIG)
|
||||
$(ECHO) creating $@
|
||||
$(Q) $(MINIRUBY) "$(srcdir)/tool/generic_erb.rb" $(srcdir)/template/verconf.h.in > $@
|
||||
|
||||
DTRACE_DEPENDENT_OBJS = array.$(OBJEXT) \
|
||||
eval.$(OBJEXT) \
|
||||
gc.$(OBJEXT) \
|
||||
|
@ -847,7 +883,7 @@ INSNS2VMOPT = --srcdir="$(srcdir)"
|
|||
srcs: {$(VPATH)}parse.c {$(VPATH)}lex.c {$(VPATH)}newline.c {$(VPATH)}id.c srcs-ext srcs-enc
|
||||
|
||||
EXT_SRCS = $(srcdir)/ext/ripper/ripper.c $(srcdir)/ext/json/parser/parser.c \
|
||||
$(srcdir)/ext/dl/callback/callback.c
|
||||
$(srcdir)/ext/dl/callback/callback.c $(srcdir)/ext/rbconfig/sizeof/sizes.c
|
||||
|
||||
srcs-ext: $(EXT_SRCS)
|
||||
|
||||
|
@ -864,12 +900,12 @@ insns: $(INSNS)
|
|||
id.h: $(srcdir)/tool/generic_erb.rb $(srcdir)/template/id.h.tmpl $(srcdir)/defs/id.def
|
||||
$(ECHO) generating $@
|
||||
$(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb --output=$@ \
|
||||
$(srcdir)/template/$@.tmpl
|
||||
$(srcdir)/template/id.h.tmpl
|
||||
|
||||
id.c: $(srcdir)/tool/generic_erb.rb $(srcdir)/template/id.c.tmpl $(srcdir)/defs/id.def
|
||||
$(ECHO) generating $@
|
||||
$(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb --output=$@ \
|
||||
$(srcdir)/template/$@.tmpl
|
||||
$(srcdir)/template/id.c.tmpl
|
||||
|
||||
node_name.inc: {$(VPATH)}node.h
|
||||
$(ECHO) generating $@
|
||||
|
@ -921,21 +957,27 @@ $(REVISION_H): $(srcdir)/version.h $(srcdir)/ChangeLog $(srcdir)/tool/file2lastr
|
|||
-$(Q) $(BASERUBY) $(srcdir)/tool/file2lastrev.rb --revision.h "$(srcdir)" > revision.tmp
|
||||
$(Q)$(IFCHANGE) "--timestamp=$@" "$(srcdir)/revision.h" revision.tmp
|
||||
|
||||
$(srcdir)/ext/ripper/ripper.c: parse.y
|
||||
$(srcdir)/ext/ripper/ripper.c: parse.y id.h
|
||||
$(ECHO) generating $@
|
||||
$(Q) $(CHDIR) $(@D) && $(exec) $(MAKE) -f depend $(MFLAGS) \
|
||||
Q=$(Q) ECHO=$(ECHO) top_srcdir=../.. srcdir=. VPATH=../.. RUBY="$(BASERUBY)"
|
||||
Q=$(Q) ECHO=$(ECHO) top_srcdir=../.. srcdir=. VPATH=../.. RUBY="$(BASERUBY)" PATH_SEPARATOR="$(PATH_SEPARATOR)"
|
||||
|
||||
$(srcdir)/ext/json/parser/parser.c: $(srcdir)/ext/json/parser/parser.rl
|
||||
$(ECHO) generating $@
|
||||
$(Q) $(CHDIR) $(@D) && $(exec) $(MAKE) -f prereq.mk $(MFLAGS) \
|
||||
Q=$(Q) ECHO=$(ECHO) top_srcdir=../../.. srcdir=.
|
||||
Q=$(Q) ECHO=$(ECHO) top_srcdir=../../.. srcdir=. VPATH=../../.. BASERUBY="$(BASERUBY)"
|
||||
|
||||
$(srcdir)/ext/dl/callback/callback.c: $(srcdir)/ext/dl/callback/mkcallback.rb $(srcdir)/ext/dl/dl.h
|
||||
$(ECHO) generating $@
|
||||
$(Q) $(CHDIR) $(@D) && $(exec) $(MAKE) -f depend $(MFLAGS) \
|
||||
Q=$(Q) ECHO=$(ECHO) top_srcdir=../.. srcdir=. VPATH=../.. RUBY="$(BASERUBY)"
|
||||
|
||||
$(srcdir)/ext/rbconfig/sizeof/sizes.c: $(srcdir)/ext/rbconfig/sizeof/depend \
|
||||
$(srcdir)/tool/generic_erb.rb $(srcdir)/template/sizes.c.tmpl $(srcdir)/configure.in
|
||||
$(ECHO) generating $@
|
||||
$(Q) $(CHDIR) $(@D) && $(exec) $(MAKE) -f depend $(MFLAGS) \
|
||||
Q=$(Q) ECHO=$(ECHO) top_srcdir=../../.. srcdir=. VPATH=../../.. RUBY="$(BASERUBY)"
|
||||
|
||||
##
|
||||
|
||||
run: fake miniruby$(EXEEXT) PHONY
|
||||
|
@ -947,6 +989,12 @@ runruby: $(PROGRAM) PHONY
|
|||
parse: fake miniruby$(EXEEXT) PHONY
|
||||
$(BTESTRUBY) $(srcdir)/tool/parse.rb $(TESTRUN_SCRIPT)
|
||||
|
||||
bisect: PHONY
|
||||
$(srcdir)/tool/bisect.sh miniruby $(srcdir)
|
||||
|
||||
bisect-ruby: PHONY
|
||||
$(srcdir)/tool/bisect.sh ruby $(srcdir)
|
||||
|
||||
COMPARE_RUBY = $(BASERUBY)
|
||||
ITEM =
|
||||
OPTS =
|
||||
|
@ -967,7 +1015,8 @@ tbench: $(PROGRAM) PHONY
|
|||
--pattern='bmx_' --directory=$(srcdir)/benchmark $(OPTS)
|
||||
|
||||
run.gdb:
|
||||
echo b ruby_debug_breakpoint > run.gdb
|
||||
echo set breakpoint pending on > run.gdb
|
||||
echo b ruby_debug_breakpoint >> run.gdb
|
||||
echo '# handle SIGINT nostop' >> run.gdb
|
||||
echo '# handle SIGPIPE nostop' >> run.gdb
|
||||
echo '# b rb_longjmp' >> run.gdb
|
||||
|
@ -992,6 +1041,12 @@ dist:
|
|||
up::
|
||||
-$(Q)$(MAKE) $(MFLAGS) REVISION_FORCE=PHONY "$(REVISION_H)"
|
||||
|
||||
update-config_files: $(srcdir)/tool/config.guess $(srcdir)/tool/config.sub
|
||||
$(srcdir)/tool/config.guess:
|
||||
$(Q) $(BASERUBY) -C $(@D) get-config_files $(@F)
|
||||
$(srcdir)/tool/config.sub:
|
||||
$(Q) $(BASERUBY) -C $(@D) get-config_files $(@F)
|
||||
|
||||
info: info-program info-libruby_a info-libruby_so info-arch
|
||||
info-program:
|
||||
@echo PROGRAM=$(PROGRAM)
|
||||
|
@ -1008,6 +1063,8 @@ change: PHONY
|
|||
love: sudo-precheck up all test install test-all
|
||||
@echo love is all you need
|
||||
|
||||
yes-test-all: sudo-precheck
|
||||
|
||||
sudo-precheck:
|
||||
@$(SUDO) echo > $(NULL)
|
||||
|
||||
|
@ -1028,10 +1085,12 @@ help: PHONY
|
|||
" gdb-ruby: runs test.rb by ruby under gdb" \
|
||||
" check: equals make test test-all" \
|
||||
" test: ruby core tests" \
|
||||
" test-all: all ruby tests" \
|
||||
" test-all: all ruby tests [TESTS=<test files>]" \
|
||||
" test-rubyspec: run RubySpec test suite" \
|
||||
" update-rubyspec: update local copy of RubySpec" \
|
||||
" benchmark: benchmark this ruby and COMPARE_RUBY" \
|
||||
" gcbench: gc benchmark [GCBENCH_ITEM=<item_name>]" \
|
||||
" gcbench-rdoc: gc benchmark with GCBENCH_ITEM=rdoc" \
|
||||
" install: install all ruby distributions" \
|
||||
" install-nodoc: install without rdoc" \
|
||||
" install-cross: install cross compiling staff" \
|
||||
|
|
32
compar.c
32
compar.c
|
@ -31,10 +31,37 @@ rb_cmperr(VALUE x, VALUE y)
|
|||
rb_obj_classname(x), classname);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
invcmp_recursive(VALUE x, VALUE y, int recursive)
|
||||
{
|
||||
if (recursive) return Qnil;
|
||||
return rb_check_funcall(y, cmp, 1, &x);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_invcmp(VALUE x, VALUE y)
|
||||
{
|
||||
VALUE invcmp = rb_exec_recursive(invcmp_recursive, x, y);
|
||||
if (invcmp == Qundef || NIL_P(invcmp)) {
|
||||
return Qnil;
|
||||
}
|
||||
else {
|
||||
int result = -rb_cmpint(invcmp, x, y);
|
||||
return INT2FIX(result);
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
cmp_eq_recursive(VALUE arg1, VALUE arg2, int recursive)
|
||||
{
|
||||
if (recursive) return Qfalse;
|
||||
return rb_funcallv(arg1, cmp, 1, &arg2);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
cmp_eq(VALUE *a)
|
||||
{
|
||||
VALUE c = rb_funcall(a[0], cmp, 1, a[1]);
|
||||
VALUE c = rb_exec_recursive_paired_outer(cmp_eq_recursive, a[0], a[1], a[1]);
|
||||
|
||||
if (NIL_P(c)) return Qfalse;
|
||||
if (rb_cmpint(c, a[0], a[1]) == 0) return Qtrue;
|
||||
|
@ -54,6 +81,9 @@ cmp_failed(void)
|
|||
* Compares two objects based on the receiver's <code><=></code>
|
||||
* method, returning true if it returns 0. Also returns true if
|
||||
* _obj_ and _other_ are the same object.
|
||||
*
|
||||
* Even if _obj_ <=> _other_ raised an exception, the exception
|
||||
* is ignored and returns false.
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
|
|
114
complex.c
114
complex.c
|
@ -210,17 +210,16 @@ f_negative_p(VALUE x)
|
|||
inline static VALUE
|
||||
f_zero_p(VALUE x)
|
||||
{
|
||||
switch (TYPE(x)) {
|
||||
case T_FIXNUM:
|
||||
if (RB_TYPE_P(x, T_FIXNUM)) {
|
||||
return f_boolcast(FIX2LONG(x) == 0);
|
||||
case T_BIGNUM:
|
||||
}
|
||||
else if (RB_TYPE_P(x, T_BIGNUM)) {
|
||||
return Qfalse;
|
||||
case T_RATIONAL:
|
||||
{
|
||||
VALUE num = RRATIONAL(x)->num;
|
||||
}
|
||||
else if (RB_TYPE_P(x, T_RATIONAL)) {
|
||||
VALUE num = RRATIONAL(x)->num;
|
||||
|
||||
return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 0);
|
||||
}
|
||||
return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 0);
|
||||
}
|
||||
return rb_funcall(x, id_eqeq_p, 1, ZERO);
|
||||
}
|
||||
|
@ -230,19 +229,18 @@ f_zero_p(VALUE x)
|
|||
inline static VALUE
|
||||
f_one_p(VALUE x)
|
||||
{
|
||||
switch (TYPE(x)) {
|
||||
case T_FIXNUM:
|
||||
if (RB_TYPE_P(x, T_FIXNUM)) {
|
||||
return f_boolcast(FIX2LONG(x) == 1);
|
||||
case T_BIGNUM:
|
||||
}
|
||||
else if (RB_TYPE_P(x, T_BIGNUM)) {
|
||||
return Qfalse;
|
||||
case T_RATIONAL:
|
||||
{
|
||||
VALUE num = RRATIONAL(x)->num;
|
||||
VALUE den = RRATIONAL(x)->den;
|
||||
}
|
||||
else if (RB_TYPE_P(x, T_RATIONAL)) {
|
||||
VALUE num = RRATIONAL(x)->num;
|
||||
VALUE den = RRATIONAL(x)->den;
|
||||
|
||||
return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 1 &&
|
||||
FIXNUM_P(den) && FIX2LONG(den) == 1);
|
||||
}
|
||||
return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 1 &&
|
||||
FIXNUM_P(den) && FIX2LONG(den) == 1);
|
||||
}
|
||||
return rb_funcall(x, id_eqeq_p, 1, ONE);
|
||||
}
|
||||
|
@ -313,10 +311,10 @@ k_complex_p(VALUE x)
|
|||
inline static VALUE
|
||||
nucomp_s_new_internal(VALUE klass, VALUE real, VALUE imag)
|
||||
{
|
||||
NEWOBJ_OF(obj, struct RComplex, klass, T_COMPLEX);
|
||||
NEWOBJ_OF(obj, struct RComplex, klass, T_COMPLEX | (RGENGC_WB_PROTECTED_COMPLEX ? FL_WB_PROTECTED : 0));
|
||||
|
||||
obj->real = real;
|
||||
obj->imag = imag;
|
||||
RCOMPLEX_SET_REAL(obj, real);
|
||||
RCOMPLEX_SET_IMAG(obj, imag);
|
||||
|
||||
return (VALUE)obj;
|
||||
}
|
||||
|
@ -383,13 +381,10 @@ nucomp_canonicalization(int f)
|
|||
inline static void
|
||||
nucomp_real_check(VALUE num)
|
||||
{
|
||||
switch (TYPE(num)) {
|
||||
case T_FIXNUM:
|
||||
case T_BIGNUM:
|
||||
case T_FLOAT:
|
||||
case T_RATIONAL:
|
||||
break;
|
||||
default:
|
||||
if (!RB_TYPE_P(num, T_FIXNUM) &&
|
||||
!RB_TYPE_P(num, T_BIGNUM) &&
|
||||
!RB_TYPE_P(num, T_FLOAT) &&
|
||||
!RB_TYPE_P(num, T_RATIONAL)) {
|
||||
if (!k_numeric_p(num) || !f_real_p(num))
|
||||
rb_raise(rb_eTypeError, "not a real");
|
||||
}
|
||||
|
@ -483,6 +478,28 @@ f_complex_new2(VALUE klass, VALUE x, VALUE y)
|
|||
*
|
||||
* Complex(1, 2) #=> (1+2i)
|
||||
* Complex('1+2i') #=> (1+2i)
|
||||
*
|
||||
* Syntax of string form:
|
||||
*
|
||||
* string form = extra spaces , complex , extra spaces ;
|
||||
* complex = real part | [ sign ] , imaginary part
|
||||
* | real part , sign , imaginary part
|
||||
* | rational , "@" , rational ;
|
||||
* real part = rational ;
|
||||
* imaginary part = imaginary unit | unsigned rational , imaginary unit ;
|
||||
* rational = [ sign ] , unsigned rational ;
|
||||
* unsigned rational = numerator | numerator , "/" , denominator ;
|
||||
* numerator = integer part | fractional part | integer part , fractional part ;
|
||||
* denominator = digits ;
|
||||
* integer part = digits ;
|
||||
* fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ;
|
||||
* imaginary unit = "i" | "I" | "j" | "J" ;
|
||||
* sign = "-" | "+" ;
|
||||
* digits = digit , { digit | "_" , digit };
|
||||
* digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
|
||||
* extra spaces = ? \s* ? ;
|
||||
*
|
||||
* See String#to_c.
|
||||
*/
|
||||
static VALUE
|
||||
nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
|
||||
|
@ -1220,11 +1237,9 @@ f_signbit(VALUE x)
|
|||
!defined(signbit)
|
||||
extern int signbit(double);
|
||||
#endif
|
||||
switch (TYPE(x)) {
|
||||
case T_FLOAT: {
|
||||
if (RB_TYPE_P(x, T_FLOAT)) {
|
||||
double f = RFLOAT_VALUE(x);
|
||||
return f_boolcast(!isnan(f) && signbit(f));
|
||||
}
|
||||
}
|
||||
return f_negative_p(x);
|
||||
}
|
||||
|
@ -1310,8 +1325,8 @@ nucomp_loader(VALUE self, VALUE a)
|
|||
{
|
||||
get_dat1(self);
|
||||
|
||||
dat->real = rb_ivar_get(a, id_i_real);
|
||||
dat->imag = rb_ivar_get(a, id_i_imag);
|
||||
RCOMPLEX_SET_REAL(dat, rb_ivar_get(a, id_i_real));
|
||||
RCOMPLEX_SET_IMAG(dat, rb_ivar_get(a, id_i_imag));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -1324,6 +1339,7 @@ nucomp_marshal_dump(VALUE self)
|
|||
get_dat1(self);
|
||||
|
||||
a = rb_assoc_new(dat->real, dat->imag);
|
||||
rb_copy_generic_ivar(a, self);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -1334,8 +1350,8 @@ nucomp_marshal_load(VALUE self, VALUE a)
|
|||
Check_Type(a, T_ARRAY);
|
||||
if (RARRAY_LEN(a) != 2)
|
||||
rb_raise(rb_eArgError, "marshaled complex must have an array whose length is 2 but %ld", RARRAY_LEN(a));
|
||||
rb_ivar_set(self, id_i_real, RARRAY_PTR(a)[0]);
|
||||
rb_ivar_set(self, id_i_imag, RARRAY_PTR(a)[1]);
|
||||
rb_ivar_set(self, id_i_real, RARRAY_AREF(a, 0));
|
||||
rb_ivar_set(self, id_i_imag, RARRAY_AREF(a, 1));
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -1824,6 +1840,8 @@ string_to_c_strict(VALUE self)
|
|||
* '-0.0-0.0i'.to_c #=> (-0.0-0.0i)
|
||||
* '1/2+3/4i'.to_c #=> ((1/2)+(3/4)*i)
|
||||
* 'ruby'.to_c #=> (0+0i)
|
||||
*
|
||||
* See Kernel.Complex.
|
||||
*/
|
||||
static VALUE
|
||||
string_to_c(VALUE self)
|
||||
|
@ -1862,30 +1880,17 @@ nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
|
|||
backref = rb_backref_get();
|
||||
rb_match_busy(backref);
|
||||
|
||||
switch (TYPE(a1)) {
|
||||
case T_FIXNUM:
|
||||
case T_BIGNUM:
|
||||
case T_FLOAT:
|
||||
break;
|
||||
case T_STRING:
|
||||
if (RB_TYPE_P(a1, T_STRING)) {
|
||||
a1 = string_to_c_strict(a1);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (TYPE(a2)) {
|
||||
case T_FIXNUM:
|
||||
case T_BIGNUM:
|
||||
case T_FLOAT:
|
||||
break;
|
||||
case T_STRING:
|
||||
if (RB_TYPE_P(a2, T_STRING)) {
|
||||
a2 = string_to_c_strict(a2);
|
||||
break;
|
||||
}
|
||||
|
||||
rb_backref_set(backref);
|
||||
|
||||
switch (TYPE(a1)) {
|
||||
case T_COMPLEX:
|
||||
if (RB_TYPE_P(a1, T_COMPLEX)) {
|
||||
{
|
||||
get_dat1(a1);
|
||||
|
||||
|
@ -1894,8 +1899,7 @@ nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
|
|||
}
|
||||
}
|
||||
|
||||
switch (TYPE(a2)) {
|
||||
case T_COMPLEX:
|
||||
if (RB_TYPE_P(a2, T_COMPLEX)) {
|
||||
{
|
||||
get_dat1(a2);
|
||||
|
||||
|
@ -1904,8 +1908,7 @@ nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
|
|||
}
|
||||
}
|
||||
|
||||
switch (TYPE(a1)) {
|
||||
case T_COMPLEX:
|
||||
if (RB_TYPE_P(a1, T_COMPLEX)) {
|
||||
if (argc == 1 || (k_exact_zero_p(a2)))
|
||||
return a1;
|
||||
}
|
||||
|
@ -1993,6 +1996,7 @@ numeric_arg(VALUE self)
|
|||
/*
|
||||
* call-seq:
|
||||
* num.rect -> array
|
||||
* num.rectangular -> array
|
||||
*
|
||||
* Returns an array; [num, 0].
|
||||
*/
|
||||
|
|
1398
configure.in
1398
configure.in
File diff suppressed because it is too large
Load diff
|
@ -18,8 +18,8 @@ typedef enum {
|
|||
|
||||
typedef struct rb_const_entry_struct {
|
||||
rb_const_flag_t flag;
|
||||
VALUE value; /* should be mark */
|
||||
VALUE file;
|
||||
const VALUE value; /* should be mark */
|
||||
const VALUE file; /* should be mark */
|
||||
int line;
|
||||
} rb_const_entry_t;
|
||||
|
||||
|
|
164
cont.c
164
cont.c
|
@ -15,9 +15,6 @@
|
|||
#include "gc.h"
|
||||
#include "eval_intern.h"
|
||||
|
||||
#if ((defined(_WIN32) && _WIN32_WINNT >= 0x0400) || (defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT))) && !defined(__NetBSD__) && !defined(__sun) && !defined(FIBER_USE_NATIVE)
|
||||
#define FIBER_USE_NATIVE 1
|
||||
|
||||
/* FIBER_USE_NATIVE enables Fiber performance improvement using system
|
||||
* dependent method such as make/setcontext on POSIX system or
|
||||
* CreateFiber() API on Windows.
|
||||
|
@ -29,12 +26,45 @@
|
|||
* in Proc. of 51th Programming Symposium, pp.21--28 (2010) (in Japanese).
|
||||
*/
|
||||
|
||||
#if !defined(FIBER_USE_NATIVE)
|
||||
# if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)
|
||||
# if 0
|
||||
# elif defined(__NetBSD__)
|
||||
/* On our experience, NetBSD doesn't support using setcontext() and pthread
|
||||
* simultaneously. This is because pthread_self(), TLS and other information
|
||||
* are represented by stack pointer (higher bits of stack pointer).
|
||||
* TODO: check such constraint on configure.
|
||||
*/
|
||||
#elif !defined(FIBER_USE_NATIVE)
|
||||
# define FIBER_USE_NATIVE 0
|
||||
# elif defined(__sun)
|
||||
/* On Solaris because resuming any Fiber caused SEGV, for some reason.
|
||||
*/
|
||||
# define FIBER_USE_NATIVE 0
|
||||
# elif defined(__ia64)
|
||||
/* At least, Linux/ia64's getcontext(3) doesn't save register window.
|
||||
*/
|
||||
# define FIBER_USE_NATIVE 0
|
||||
# elif defined(__GNU__)
|
||||
/* GNU/Hurd doesn't fully support getcontext, setcontext, makecontext
|
||||
* and swapcontext functions. Disabling their usage till support is
|
||||
* implemented. More info at
|
||||
* http://darnassus.sceen.net/~hurd-web/open_issues/glibc/#getcontext
|
||||
*/
|
||||
# define FIBER_USE_NATIVE 0
|
||||
# else
|
||||
# define FIBER_USE_NATIVE 1
|
||||
# endif
|
||||
# elif defined(_WIN32)
|
||||
# if _WIN32_WINNT >= 0x0400
|
||||
/* only when _WIN32_WINNT >= 0x0400 on Windows because Fiber APIs are
|
||||
* supported only such building (and running) environments.
|
||||
* [ruby-dev:41192]
|
||||
*/
|
||||
# define FIBER_USE_NATIVE 1
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(FIBER_USE_NATIVE)
|
||||
#define FIBER_USE_NATIVE 0
|
||||
#endif
|
||||
|
||||
|
@ -77,6 +107,8 @@ typedef struct rb_context_struct {
|
|||
rb_thread_t saved_thread;
|
||||
rb_jmpbuf_t jmpbuf;
|
||||
size_t machine_stack_size;
|
||||
rb_ensure_entry_t *ensure_array;
|
||||
rb_ensure_list_t *ensure_list;
|
||||
} rb_context_t;
|
||||
|
||||
enum fiber_status {
|
||||
|
@ -86,13 +118,13 @@ enum fiber_status {
|
|||
};
|
||||
|
||||
#if FIBER_USE_NATIVE && !defined(_WIN32)
|
||||
#define MAX_MAHINE_STACK_CACHE 10
|
||||
#define MAX_MACHINE_STACK_CACHE 10
|
||||
static int machine_stack_cache_index = 0;
|
||||
typedef struct machine_stack_cache_struct {
|
||||
void *ptr;
|
||||
size_t size;
|
||||
} machine_stack_cache_t;
|
||||
static machine_stack_cache_t machine_stack_cache[MAX_MAHINE_STACK_CACHE];
|
||||
static machine_stack_cache_t machine_stack_cache[MAX_MACHINE_STACK_CACHE];
|
||||
static machine_stack_cache_t terminated_machine_stack;
|
||||
#endif
|
||||
|
||||
|
@ -193,6 +225,7 @@ cont_free(void *ptr)
|
|||
#if FIBER_USE_NATIVE
|
||||
if (cont->type == CONTINUATION_CONTEXT) {
|
||||
/* cont */
|
||||
ruby_xfree(cont->ensure_array);
|
||||
RUBY_FREE_UNLESS_NULL(cont->machine_stack);
|
||||
}
|
||||
else {
|
||||
|
@ -223,6 +256,7 @@ cont_free(void *ptr)
|
|||
#endif
|
||||
}
|
||||
#else /* not FIBER_USE_NATIVE */
|
||||
ruby_xfree(cont->ensure_array);
|
||||
RUBY_FREE_UNLESS_NULL(cont->machine_stack);
|
||||
#endif
|
||||
#ifdef __ia64
|
||||
|
@ -321,7 +355,8 @@ fiber_memsize(const void *ptr)
|
|||
size_t size = 0;
|
||||
if (ptr) {
|
||||
size = sizeof(*fib);
|
||||
if (fib->cont.type != ROOT_FIBER_CONTEXT) {
|
||||
if (fib->cont.type != ROOT_FIBER_CONTEXT &&
|
||||
fib->cont.saved_thread.local_storage != NULL) {
|
||||
size += st_memsize(fib->cont.saved_thread.local_storage);
|
||||
}
|
||||
size += cont_memsize(&fib->cont);
|
||||
|
@ -387,6 +422,7 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
|
|||
static const rb_data_type_t cont_data_type = {
|
||||
"continuation",
|
||||
{cont_mark, cont_free, cont_memsize,},
|
||||
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -453,6 +489,22 @@ cont_capture(volatile int *stat)
|
|||
|
||||
cont_save_machine_stack(th, cont);
|
||||
|
||||
/* backup ensure_list to array for search in another context */
|
||||
{
|
||||
rb_ensure_list_t *p;
|
||||
int size = 0;
|
||||
rb_ensure_entry_t *entry;
|
||||
for (p=th->ensure_list; p; p=p->next)
|
||||
size++;
|
||||
entry = cont->ensure_array = ALLOC_N(rb_ensure_entry_t,size+1);
|
||||
for (p=th->ensure_list; p; p=p->next) {
|
||||
if (!p->entry.marker)
|
||||
p->entry.marker = rb_ary_tmp_new(0); /* dummy object */
|
||||
*entry++ = p->entry;
|
||||
}
|
||||
entry->marker = 0;
|
||||
}
|
||||
|
||||
if (ruby_setjmp(cont->jmpbuf)) {
|
||||
volatile VALUE value;
|
||||
|
||||
|
@ -512,6 +564,10 @@ cont_restore_thread(rb_context_t *cont)
|
|||
th->protect_tag = sth->protect_tag;
|
||||
th->errinfo = sth->errinfo;
|
||||
th->first_proc = sth->first_proc;
|
||||
th->root_lep = sth->root_lep;
|
||||
th->root_svar = sth->root_svar;
|
||||
th->ensure_list = sth->ensure_list;
|
||||
|
||||
}
|
||||
|
||||
#if FIBER_USE_NATIVE
|
||||
|
@ -566,9 +622,10 @@ fiber_machine_stack_alloc(size_t size)
|
|||
void *page;
|
||||
STACK_GROW_DIR_DETECTION;
|
||||
|
||||
errno = 0;
|
||||
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, FIBER_STACK_FLAGS, -1, 0);
|
||||
if (ptr == MAP_FAILED) {
|
||||
rb_raise(rb_eFiberError, "can't alloc machine stack to fiber");
|
||||
rb_raise(rb_eFiberError, "can't alloc machine stack to fiber: %s", strerror(errno));
|
||||
}
|
||||
|
||||
/* guard page setup */
|
||||
|
@ -882,6 +939,80 @@ make_passing_arg(int argc, VALUE *argv)
|
|||
}
|
||||
}
|
||||
|
||||
/* CAUTION!! : Currently, error in rollback_func is not supported */
|
||||
/* same as rb_protect if set rollback_func to NULL */
|
||||
void
|
||||
ruby_register_rollback_func_for_ensure(VALUE (*ensure_func)(ANYARGS), VALUE (*rollback_func)(ANYARGS))
|
||||
{
|
||||
st_table **table_p = &GET_VM()->ensure_rollback_table;
|
||||
if (UNLIKELY(*table_p == NULL)) {
|
||||
*table_p = st_init_numtable();
|
||||
}
|
||||
st_insert(*table_p, (st_data_t)ensure_func, (st_data_t)rollback_func);
|
||||
}
|
||||
|
||||
static inline VALUE
|
||||
lookup_rollback_func(VALUE (*ensure_func)(ANYARGS))
|
||||
{
|
||||
st_table *table = GET_VM()->ensure_rollback_table;
|
||||
st_data_t val;
|
||||
if (table && st_lookup(table, (st_data_t)ensure_func, &val))
|
||||
return (VALUE) val;
|
||||
return Qundef;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
rollback_ensure_stack(VALUE self,rb_ensure_list_t *current,rb_ensure_entry_t *target)
|
||||
{
|
||||
rb_ensure_list_t *p;
|
||||
rb_ensure_entry_t *entry;
|
||||
size_t i;
|
||||
size_t cur_size;
|
||||
size_t target_size;
|
||||
size_t base_point;
|
||||
VALUE (*func)(ANYARGS);
|
||||
|
||||
cur_size = 0;
|
||||
for (p=current; p; p=p->next)
|
||||
cur_size++;
|
||||
target_size = 0;
|
||||
for (entry=target; entry->marker; entry++)
|
||||
target_size++;
|
||||
|
||||
/* search common stack point */
|
||||
p = current;
|
||||
base_point = cur_size;
|
||||
while (base_point) {
|
||||
if (target_size >= base_point &&
|
||||
p->entry.marker == target[target_size - base_point].marker)
|
||||
break;
|
||||
base_point --;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
/* rollback function check */
|
||||
for (i=0; i < target_size - base_point; i++) {
|
||||
if (!lookup_rollback_func(target[i].e_proc)) {
|
||||
rb_raise(rb_eRuntimeError, "continuation called from out of critical rb_ensure scope");
|
||||
}
|
||||
}
|
||||
/* pop ensure stack */
|
||||
while (cur_size > base_point) {
|
||||
/* escape from ensure block */
|
||||
(*current->entry.e_proc)(current->entry.data2);
|
||||
current = current->next;
|
||||
cur_size--;
|
||||
}
|
||||
/* push ensure stack */
|
||||
while (i--) {
|
||||
func = (VALUE (*)(ANYARGS)) lookup_rollback_func(target[i].e_proc);
|
||||
if ((VALUE)func != Qundef) {
|
||||
(*func)(target[i].data2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* cont.call(args, ...)
|
||||
|
@ -919,6 +1050,7 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
|
|||
rb_raise(rb_eRuntimeError, "continuation called across fiber");
|
||||
}
|
||||
}
|
||||
rollback_ensure_stack(contval, th->ensure_list, cont->ensure_array);
|
||||
|
||||
cont->argc = argc;
|
||||
cont->value = make_passing_arg(argc, argv);
|
||||
|
@ -999,6 +1131,7 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
|
|||
static const rb_data_type_t fiber_data_type = {
|
||||
"fiber",
|
||||
{fiber_mark, fiber_free, fiber_memsize,},
|
||||
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
||||
};
|
||||
|
||||
static VALUE
|
||||
|
@ -1146,10 +1279,9 @@ rb_fiber_start(void)
|
|||
TH_PUSH_TAG(th);
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
int argc;
|
||||
VALUE *argv, args;
|
||||
const VALUE *argv, args = cont->value;
|
||||
GetProcPtr(cont->saved_thread.first_proc, proc);
|
||||
args = cont->value;
|
||||
argv = (argc = cont->argc) > 1 ? RARRAY_PTR(args) : &args;
|
||||
argv = (argc = cont->argc) > 1 ? RARRAY_CONST_PTR(args) : &args;
|
||||
cont->value = Qnil;
|
||||
th->errinfo = Qnil;
|
||||
th->root_lep = rb_vm_ep_local_ep(proc->block.ep);
|
||||
|
@ -1231,7 +1363,7 @@ fiber_store(rb_fiber_t *next_fib)
|
|||
fiber_setcontext(next_fib, fib);
|
||||
#ifndef _WIN32
|
||||
if (terminated_machine_stack.ptr) {
|
||||
if (machine_stack_cache_index < MAX_MAHINE_STACK_CACHE) {
|
||||
if (machine_stack_cache_index < MAX_MACHINE_STACK_CACHE) {
|
||||
machine_stack_cache[machine_stack_cache_index].ptr = terminated_machine_stack.ptr;
|
||||
machine_stack_cache[machine_stack_cache_index].size = terminated_machine_stack.size;
|
||||
machine_stack_cache_index++;
|
||||
|
@ -1538,9 +1670,7 @@ Init_Cont(void)
|
|||
rb_define_method(rb_cFiber, "resume", rb_fiber_m_resume, -1);
|
||||
}
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 4
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
RUBY_SYMBOL_EXPORT_BEGIN
|
||||
|
||||
void
|
||||
ruby_Init_Continuation_body(void)
|
||||
|
@ -1561,6 +1691,4 @@ ruby_Init_Fiber_as_Coroutine(void)
|
|||
rb_define_singleton_method(rb_cFiber, "current", rb_fiber_s_current, 0);
|
||||
}
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 4
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
RUBY_SYMBOL_EXPORT_END
|
||||
|
|
6
debug.c
6
debug.c
|
@ -24,6 +24,7 @@ const union {
|
|||
enum ruby_tag_type tag_type;
|
||||
enum node_type node_type;
|
||||
enum ruby_method_ids method_ids;
|
||||
enum ruby_id_types id_types;
|
||||
enum {
|
||||
RUBY_ENCODING_INLINE_MAX = ENCODING_INLINE_MAX,
|
||||
RUBY_ENCODING_SHIFT = ENCODING_SHIFT,
|
||||
|
@ -32,11 +33,10 @@ const union {
|
|||
RUBY_ENC_CODERANGE_7BIT = ENC_CODERANGE_7BIT,
|
||||
RUBY_ENC_CODERANGE_VALID = ENC_CODERANGE_VALID,
|
||||
RUBY_ENC_CODERANGE_BROKEN = ENC_CODERANGE_BROKEN,
|
||||
RUBY_FL_RESERVED1 = FL_RESERVED1,
|
||||
RUBY_FL_RESERVED2 = FL_RESERVED2,
|
||||
RUBY_FL_WB_PROTECTED = FL_WB_PROTECTED,
|
||||
RUBY_FL_PROMOTED = FL_PROMOTED,
|
||||
RUBY_FL_FINALIZE = FL_FINALIZE,
|
||||
RUBY_FL_TAINT = FL_TAINT,
|
||||
RUBY_FL_UNTRUSTED = FL_UNTRUSTED,
|
||||
RUBY_FL_EXIVAR = FL_EXIVAR,
|
||||
RUBY_FL_FREEZE = FL_FREEZE,
|
||||
RUBY_FL_SINGLETON = FL_SINGLETON,
|
||||
|
|
29
defs/gmake.mk
Normal file
29
defs/gmake.mk
Normal file
|
@ -0,0 +1,29 @@
|
|||
# -*- makefile-gmake -*-
|
||||
TEST_TARGETS := $(filter check test check% test% btest%,$(MAKECMDGOALS))
|
||||
TEST_TARGETS += $(subst check,test-all,$(patsubst check-%,test-%,$(TEST_TARGETS)))
|
||||
TEST_TARGETS := $(patsubst test-%,yes-test-%,$(patsubst btest-%,yes-btest-%,$(TEST_TARGETS)))
|
||||
TEST_DEPENDS := $(if $(TEST_TARGETS),$(filter all main exts,$(MAKECMDGOALS)))
|
||||
TEST_DEPENDS += $(TEST_DEPENDS) $(if $(filter check%,$(MAKECMDGOALS)),main)
|
||||
|
||||
ifneq ($(filter check% test,$(MAKECMDGOALS)),)
|
||||
yes-test-knownbug: $(TEST_DEPENDS) yes-btest-ruby
|
||||
yes-btest-ruby: $(TEST_DEPENDS) yes-test-sample
|
||||
yes-test-sample: $(TEST_DEPENDS)
|
||||
endif
|
||||
ifneq ($(filter check%,$(MAKECMDGOALS)) $(filter test-all,$(TEST_TARGETS)),)
|
||||
yes-test-all yes-test-ruby: $(filter-out %test-all %test-ruby check%,$(TEST_TARGETS))
|
||||
endif
|
||||
ifneq ($(filter check%,$(MAKECMDGOALS))$(if $(filter test-all,$(MAKECMDGOALS)),$(filter test-knownbug,$(MAKECMDGOALS))),)
|
||||
yes-test-all yes-test-ruby: yes-test-knownbug
|
||||
endif
|
||||
|
||||
$(TEST_TARGETS): $(TEST_DEPENDS)
|
||||
|
||||
ifneq ($(if $(filter install,$(MAKECMDGOALS)),$(filter uninstall,$(MAKECMDGOALS))),)
|
||||
install-targets := $(filter install uninstall,$(MAKECMDGOALS))
|
||||
$(word 1,$(install-targets)): $(word 0,$(install-targets))
|
||||
endif
|
||||
|
||||
ifneq ($(filter reinstall,$(MAKECMDGOALS)),)
|
||||
install: uninstall
|
||||
endif
|
18
defs/id.def
18
defs/id.def
|
@ -1,15 +1,27 @@
|
|||
# -*- mode: ruby; coding: us-ascii -*-
|
||||
firstline, predefined = __LINE__+1, %[\
|
||||
freeze
|
||||
inspect
|
||||
intern
|
||||
object_id
|
||||
const_missing
|
||||
method_missing MethodMissing
|
||||
method_added
|
||||
singleton_method_added
|
||||
method_removed
|
||||
singleton_method_removed
|
||||
method_undefined
|
||||
singleton_method_undefined
|
||||
length
|
||||
size
|
||||
gets
|
||||
succ
|
||||
each
|
||||
proc
|
||||
lambda
|
||||
send
|
||||
__send__
|
||||
__attached__
|
||||
initialize
|
||||
initialize_copy
|
||||
initialize_clone
|
||||
|
@ -17,6 +29,7 @@ firstline, predefined = __LINE__+1, %[\
|
|||
_ UScore
|
||||
"/*NULL*/" NULL
|
||||
empty?
|
||||
eql?
|
||||
respond_to? Respond_to
|
||||
respond_to_missing? Respond_to_missing
|
||||
<IFUNC>
|
||||
|
@ -48,7 +61,10 @@ const_ids = []
|
|||
class_ids = []
|
||||
names = {}
|
||||
predefined.split(/^/).each_with_index do |line, num|
|
||||
next if /^#/ =~ line or (name, token = line.split; !name)
|
||||
next if /^#/ =~ line
|
||||
line.sub!(/\s+#.*/, '')
|
||||
name, token = line.split
|
||||
next unless name
|
||||
token ||= name
|
||||
if /#/ =~ token
|
||||
token = "_#{token.gsub(/\W+/, '_')}"
|
||||
|
|
448
dir.c
448
dir.c
|
@ -63,10 +63,6 @@ char *strchr(char*,char);
|
|||
|
||||
#include "ruby/util.h"
|
||||
|
||||
#if !defined HAVE_LSTAT && !defined lstat
|
||||
#define lstat stat
|
||||
#endif
|
||||
|
||||
/* define system APIs */
|
||||
#ifdef _WIN32
|
||||
#undef chdir
|
||||
|
@ -79,7 +75,40 @@ char *strchr(char*,char);
|
|||
#define opendir(p) rb_w32_uopendir(p)
|
||||
#endif
|
||||
|
||||
#define rb_sys_fail_path(path) rb_sys_fail_str(path)
|
||||
#ifdef __APPLE__
|
||||
# define HAVE_HFS 1
|
||||
#else
|
||||
# define HAVE_HFS 0
|
||||
#endif
|
||||
#if HAVE_HFS
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
static inline int
|
||||
is_hfs(DIR *dirp)
|
||||
{
|
||||
struct statfs buf;
|
||||
if (fstatfs(dirfd(dirp), &buf) == 0) {
|
||||
return buf.f_type == 17; /* HFS on darwin */
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline int
|
||||
has_nonascii(const char *ptr, size_t len)
|
||||
{
|
||||
while (len > 0) {
|
||||
if (!ISASCII(*ptr)) return 1;
|
||||
ptr++;
|
||||
--len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# define IF_HAVE_HFS(something) something
|
||||
#else
|
||||
# define IF_HAVE_HFS(something) /* nothing */
|
||||
#endif
|
||||
|
||||
#define FNM_NOESCAPE 0x01
|
||||
#define FNM_PATHNAME 0x02
|
||||
|
@ -137,7 +166,7 @@ bracket(
|
|||
p = t2 + (r2 = rb_enc_mbclen(t2, pend, enc));
|
||||
if (ok) continue;
|
||||
if ((r <= (send-s) && memcmp(t1, s, r) == 0) ||
|
||||
(r2 <= (send-s) && memcmp(t2, s, r) == 0)) {
|
||||
(r2 <= (send-s) && memcmp(t2, s, r2) == 0)) {
|
||||
ok = 1;
|
||||
continue;
|
||||
}
|
||||
|
@ -352,6 +381,7 @@ dir_memsize(const void *ptr)
|
|||
static const rb_data_type_t dir_data_type = {
|
||||
"dir",
|
||||
{dir_mark, dir_free, dir_memsize,},
|
||||
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
||||
};
|
||||
|
||||
static VALUE dir_close(VALUE);
|
||||
|
@ -381,8 +411,12 @@ dir_s_alloc(VALUE klass)
|
|||
/*
|
||||
* call-seq:
|
||||
* Dir.new( string ) -> aDir
|
||||
* Dir.new( string, encoding: enc ) -> aDir
|
||||
*
|
||||
* Returns a new directory object for the named directory.
|
||||
*
|
||||
* The optional <i>enc</i> argument specifies the encoding of the directory.
|
||||
* If not specified, the filesystem encoding is used.
|
||||
*/
|
||||
static VALUE
|
||||
dir_initialize(int argc, VALUE *argv, VALUE dir)
|
||||
|
@ -390,18 +424,20 @@ dir_initialize(int argc, VALUE *argv, VALUE dir)
|
|||
struct dir_data *dp;
|
||||
rb_encoding *fsenc;
|
||||
VALUE dirname, opt, orig;
|
||||
static VALUE sym_enc;
|
||||
static ID keyword_ids[1];
|
||||
|
||||
if (!sym_enc) {
|
||||
sym_enc = ID2SYM(rb_intern("encoding"));
|
||||
if (!keyword_ids[0]) {
|
||||
keyword_ids[0] = rb_intern("encoding");
|
||||
}
|
||||
|
||||
fsenc = rb_filesystem_encoding();
|
||||
|
||||
rb_scan_args(argc, argv, "1:", &dirname, &opt);
|
||||
|
||||
if (!NIL_P(opt)) {
|
||||
VALUE enc = rb_hash_aref(opt, sym_enc);
|
||||
if (!NIL_P(enc)) {
|
||||
VALUE enc;
|
||||
rb_get_kwargs(opt, keyword_ids, 0, 1, &enc);
|
||||
if (enc != Qundef && !NIL_P(enc)) {
|
||||
fsenc = rb_to_encoding(enc);
|
||||
}
|
||||
}
|
||||
|
@ -434,7 +470,12 @@ dir_initialize(int argc, VALUE *argv, VALUE dir)
|
|||
/*
|
||||
* call-seq:
|
||||
* Dir.open( string ) -> aDir
|
||||
* Dir.open( string, encoding: enc ) -> aDir
|
||||
* Dir.open( string ) {| aDir | block } -> anObject
|
||||
* Dir.open( string, encoding: enc ) {| aDir | block } -> anObject
|
||||
*
|
||||
* The optional <i>enc</i> argument specifies the encoding of the directory.
|
||||
* If not specified, the filesystem encoding is used.
|
||||
*
|
||||
* With no block, <code>open</code> is a synonym for
|
||||
* <code>Dir::new</code>. If a block is present, it is passed
|
||||
|
@ -466,8 +507,6 @@ static struct dir_data *
|
|||
dir_check(VALUE dir)
|
||||
{
|
||||
struct dir_data *dirp;
|
||||
if (!OBJ_UNTRUSTED(dir) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: operation on trusted Dir");
|
||||
rb_check_frozen(dir);
|
||||
dirp = rb_check_typeddata(dir, &dir_data_type);
|
||||
if (!dirp->dir) dir_closed();
|
||||
|
@ -503,6 +542,7 @@ dir_inspect(VALUE dir)
|
|||
/*
|
||||
* call-seq:
|
||||
* dir.path -> string or nil
|
||||
* dir.to_path -> string or nil
|
||||
*
|
||||
* Returns the path parameter passed to <em>dir</em>'s constructor.
|
||||
*
|
||||
|
@ -519,50 +559,10 @@ dir_path(VALUE dir)
|
|||
return rb_str_dup(dirp->path);
|
||||
}
|
||||
|
||||
#if defined HAVE_READDIR_R
|
||||
# define READDIR(dir, enc, entry, dp) (readdir_r((dir), (entry), &(dp)) == 0 && (dp) != 0)
|
||||
#elif defined _WIN32
|
||||
# define READDIR(dir, enc, entry, dp) (((dp) = rb_w32_readdir((dir), (enc))) != 0)
|
||||
#if defined _WIN32
|
||||
# define READDIR(dir, enc) rb_w32_readdir((dir), (enc))
|
||||
#else
|
||||
# define READDIR(dir, enc, entry, dp) (((dp) = readdir(dir)) != 0)
|
||||
#endif
|
||||
#if defined HAVE_READDIR_R
|
||||
# define IF_HAVE_READDIR_R(something) something
|
||||
#else
|
||||
# define IF_HAVE_READDIR_R(something) /* nothing */
|
||||
#endif
|
||||
|
||||
#if defined SIZEOF_STRUCT_DIRENT_TOO_SMALL
|
||||
# include <limits.h>
|
||||
# define NAME_MAX_FOR_STRUCT_DIRENT 255
|
||||
# if defined NAME_MAX
|
||||
# if NAME_MAX_FOR_STRUCT_DIRENT < NAME_MAX
|
||||
# undef NAME_MAX_FOR_STRUCT_DIRENT
|
||||
# define NAME_MAX_FOR_STRUCT_DIRENT NAME_MAX
|
||||
# endif
|
||||
# endif
|
||||
# if defined _POSIX_NAME_MAX
|
||||
# if NAME_MAX_FOR_STRUCT_DIRENT < _POSIX_NAME_MAX
|
||||
# undef NAME_MAX_FOR_STRUCT_DIRENT
|
||||
# define NAME_MAX_FOR_STRUCT_DIRENT _POSIX_NAME_MAX
|
||||
# endif
|
||||
# endif
|
||||
# if defined _XOPEN_NAME_MAX
|
||||
# if NAME_MAX_FOR_STRUCT_DIRENT < _XOPEN_NAME_MAX
|
||||
# undef NAME_MAX_FOR_STRUCT_DIRENT
|
||||
# define NAME_MAX_FOR_STRUCT_DIRENT _XOPEN_NAME_MAX
|
||||
# endif
|
||||
# endif
|
||||
# define DEFINE_STRUCT_DIRENT \
|
||||
union { \
|
||||
struct dirent dirent; \
|
||||
char dummy[offsetof(struct dirent, d_name) + \
|
||||
NAME_MAX_FOR_STRUCT_DIRENT + 1]; \
|
||||
}
|
||||
# define STRUCT_DIRENT(entry) ((entry).dirent)
|
||||
#else
|
||||
# define DEFINE_STRUCT_DIRENT struct dirent
|
||||
# define STRUCT_DIRENT(entry) (entry)
|
||||
# define READDIR(dir, enc) readdir((dir))
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -582,11 +582,10 @@ dir_read(VALUE dir)
|
|||
{
|
||||
struct dir_data *dirp;
|
||||
struct dirent *dp;
|
||||
IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);
|
||||
|
||||
GetDIR(dir, dirp);
|
||||
errno = 0;
|
||||
if (READDIR(dirp->dir, dirp->enc, &STRUCT_DIRENT(entry), dp)) {
|
||||
if ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
|
||||
return rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc);
|
||||
}
|
||||
else {
|
||||
|
@ -620,13 +619,25 @@ dir_each(VALUE dir)
|
|||
{
|
||||
struct dir_data *dirp;
|
||||
struct dirent *dp;
|
||||
IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);
|
||||
IF_HAVE_HFS(int hfs_p);
|
||||
|
||||
RETURN_ENUMERATOR(dir, 0, 0);
|
||||
GetDIR(dir, dirp);
|
||||
rewinddir(dirp->dir);
|
||||
while (READDIR(dirp->dir, dirp->enc, &STRUCT_DIRENT(entry), dp)) {
|
||||
rb_yield(rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc));
|
||||
IF_HAVE_HFS(hfs_p = is_hfs(dirp->dir));
|
||||
while ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
|
||||
const char *name = dp->d_name;
|
||||
size_t namlen = NAMLEN(dp);
|
||||
VALUE path;
|
||||
#if HAVE_HFS
|
||||
if (hfs_p && has_nonascii(name, namlen) &&
|
||||
!NIL_P(path = rb_str_normalize_ospath(name, namlen))) {
|
||||
path = rb_external_str_with_enc(path, dirp->enc);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
path = rb_external_str_new_with_enc(name, namlen, dirp->enc);
|
||||
rb_yield(path);
|
||||
if (dirp->dir == NULL) dir_closed();
|
||||
}
|
||||
return dir;
|
||||
|
@ -689,9 +700,10 @@ dir_seek(VALUE dir, VALUE pos)
|
|||
#define dir_seek rb_f_notimplement
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SEEKDIR
|
||||
/*
|
||||
* call-seq:
|
||||
* dir.pos( integer ) -> integer
|
||||
* dir.pos = integer -> integer
|
||||
*
|
||||
* Synonym for <code>Dir#seek</code>, but returns the position
|
||||
* parameter.
|
||||
|
@ -709,6 +721,9 @@ dir_set_pos(VALUE dir, VALUE pos)
|
|||
dir_seek(dir, pos);
|
||||
return pos;
|
||||
}
|
||||
#else
|
||||
#define dir_set_pos rb_f_notimplement
|
||||
#endif
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
|
@ -726,9 +741,6 @@ dir_rewind(VALUE dir)
|
|||
{
|
||||
struct dir_data *dirp;
|
||||
|
||||
if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(dir)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close");
|
||||
}
|
||||
GetDIR(dir, dirp);
|
||||
rewinddir(dirp->dir);
|
||||
return dir;
|
||||
|
@ -876,7 +888,6 @@ rb_dir_getwd(void)
|
|||
char *path;
|
||||
VALUE cwd;
|
||||
|
||||
rb_secure(4);
|
||||
path = my_getcwd();
|
||||
cwd = rb_tainted_str_new2(path);
|
||||
rb_enc_associate(cwd, rb_filesystem_encoding());
|
||||
|
@ -1021,18 +1032,25 @@ sys_warning_1(VALUE mesg)
|
|||
*/
|
||||
#define to_be_ignored(e) ((e) == ENOENT || (e) == ENOTDIR)
|
||||
|
||||
#ifdef _WIN32
|
||||
#define STAT(p, s) rb_w32_ustati64((p), (s))
|
||||
#else
|
||||
#define STAT(p, s) stat((p), (s))
|
||||
#endif
|
||||
|
||||
/* System call with warning */
|
||||
static int
|
||||
do_stat(const char *path, struct stat *pst, int flags)
|
||||
|
||||
{
|
||||
int ret = stat(path, pst);
|
||||
int ret = STAT(path, pst);
|
||||
if (ret < 0 && !to_be_ignored(errno))
|
||||
sys_warning(path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined HAVE_LSTAT || defined lstat
|
||||
static int
|
||||
do_lstat(const char *path, struct stat *pst, int flags)
|
||||
{
|
||||
|
@ -1042,6 +1060,9 @@ do_lstat(const char *path, struct stat *pst, int flags)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define do_lstat do_stat
|
||||
#endif
|
||||
|
||||
static DIR *
|
||||
do_opendir(const char *path, int flags, rb_encoding *enc)
|
||||
|
@ -1248,9 +1269,8 @@ glob_free_pattern(struct glob_pattern *list)
|
|||
}
|
||||
|
||||
static char *
|
||||
join_path(const char *path, int dirsep, const char *name, size_t namlen)
|
||||
join_path(const char *path, long len, int dirsep, const char *name, size_t namlen)
|
||||
{
|
||||
long len = strlen(path);
|
||||
char *buf = GLOB_ALLOC_N(char, len+namlen+(dirsep?1:0)+1);
|
||||
|
||||
if (!buf) return 0;
|
||||
|
@ -1313,6 +1333,7 @@ glob_helper(
|
|||
struct glob_pattern **cur, **new_beg, **new_end;
|
||||
int plain = 0, magical = 0, recursive = 0, match_all = 0, match_dir = 0;
|
||||
int escape = !(flags & FNM_NOESCAPE);
|
||||
long pathlen;
|
||||
|
||||
for (cur = beg; cur < end; ++cur) {
|
||||
struct glob_pattern *p = *cur;
|
||||
|
@ -1338,6 +1359,7 @@ glob_helper(
|
|||
}
|
||||
}
|
||||
|
||||
pathlen = strlen(path);
|
||||
if (*path) {
|
||||
if (match_all && exist == UNKNOWN) {
|
||||
if (do_lstat(path, &st, flags) == 0) {
|
||||
|
@ -1364,7 +1386,7 @@ glob_helper(
|
|||
if (status) return status;
|
||||
}
|
||||
if (match_dir && isdir == YES) {
|
||||
char *tmp = join_path(path, dirsep, "", 0);
|
||||
char *tmp = join_path(path, pathlen, dirsep, "", 0);
|
||||
if (!tmp) return -1;
|
||||
status = glob_call_func(func, tmp, arg, enc);
|
||||
GLOB_FREE(tmp);
|
||||
|
@ -1377,29 +1399,50 @@ glob_helper(
|
|||
if (magical || recursive) {
|
||||
struct dirent *dp;
|
||||
DIR *dirp;
|
||||
IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);
|
||||
IF_HAVE_HFS(int hfs_p);
|
||||
dirp = do_opendir(*path ? path : ".", flags, enc);
|
||||
if (dirp == NULL) return 0;
|
||||
IF_HAVE_HFS(hfs_p = is_hfs(dirp));
|
||||
|
||||
while (READDIR(dirp, enc, &STRUCT_DIRENT(entry), dp)) {
|
||||
while ((dp = READDIR(dirp, enc)) != NULL) {
|
||||
char *buf;
|
||||
enum answer new_isdir = UNKNOWN;
|
||||
const char *name;
|
||||
size_t namlen;
|
||||
int dotfile = 0;
|
||||
IF_HAVE_HFS(VALUE utf8str = Qnil);
|
||||
|
||||
if (recursive && dp->d_name[0] == '.') {
|
||||
/* RECURSIVE never match dot files unless FNM_DOTMATCH is set */
|
||||
if (!(flags & FNM_DOTMATCH)) continue;
|
||||
|
||||
/* always skip current and parent directories not to recurse infinitely */
|
||||
if (!dp->d_name[1]) continue;
|
||||
if (dp->d_name[1] == '.' && !dp->d_name[2]) continue;
|
||||
++dotfile;
|
||||
if (!dp->d_name[1]) {
|
||||
/* unless DOTMATCH, skip current directories not to recurse infinitely */
|
||||
if (!(flags & FNM_DOTMATCH)) continue;
|
||||
++dotfile;
|
||||
}
|
||||
else if (dp->d_name[1] == '.' && !dp->d_name[2]) {
|
||||
/* always skip parent directories not to recurse infinitely */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
buf = join_path(path, dirsep, dp->d_name, NAMLEN(dp));
|
||||
name = dp->d_name;
|
||||
namlen = NAMLEN(dp);
|
||||
# if HAVE_HFS
|
||||
if (hfs_p && has_nonascii(name, namlen)) {
|
||||
if (!NIL_P(utf8str = rb_str_normalize_ospath(name, namlen))) {
|
||||
RSTRING_GETMEM(utf8str, name, namlen);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
buf = join_path(path, pathlen, dirsep, name, namlen);
|
||||
IF_HAVE_HFS(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0));
|
||||
if (!buf) {
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
if (recursive) {
|
||||
name = buf + pathlen + (dirsep != 0);
|
||||
if (recursive && dotfile < ((flags & FNM_DOTMATCH) ? 2 : 1)) {
|
||||
/* RECURSIVE never match dot files unless FNM_DOTMATCH is set */
|
||||
#ifndef _WIN32
|
||||
if (do_lstat(buf, &st, flags) == 0)
|
||||
new_isdir = S_ISDIR(st.st_mode) ? YES : S_ISLNK(st.st_mode) ? UNKNOWN : NO;
|
||||
|
@ -1425,7 +1468,7 @@ glob_helper(
|
|||
p = p->next; /* 0 times recursion */
|
||||
}
|
||||
if (p->type == PLAIN || p->type == MAGICAL) {
|
||||
if (fnmatch(p->str, enc, dp->d_name, flags) == 0)
|
||||
if (fnmatch(p->str, enc, name, flags) == 0)
|
||||
*new_end++ = p->next;
|
||||
}
|
||||
}
|
||||
|
@ -1475,7 +1518,7 @@ glob_helper(
|
|||
}
|
||||
}
|
||||
|
||||
buf = join_path(path, dirsep, name, len);
|
||||
buf = join_path(path, pathlen, dirsep, name, len);
|
||||
GLOB_FREE(name);
|
||||
if (!buf) {
|
||||
GLOB_FREE(new_beg);
|
||||
|
@ -1723,7 +1766,7 @@ rb_push_glob(VALUE str, int flags) /* '\0' is delimiter */
|
|||
}
|
||||
|
||||
static VALUE
|
||||
dir_globs(long argc, VALUE *argv, int flags)
|
||||
dir_globs(long argc, const VALUE *argv, int flags)
|
||||
{
|
||||
VALUE ary = rb_ary_new();
|
||||
long i;
|
||||
|
@ -1760,49 +1803,56 @@ dir_s_aref(int argc, VALUE *argv, VALUE obj)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* Dir.glob( pattern, [flags] ) -> array
|
||||
* Dir.glob( pattern, [flags] ) {| filename | block } -> nil
|
||||
* Dir.glob( pattern, [flags] ) -> matches
|
||||
* Dir.glob( pattern, [flags] ) { |filename| block } -> nil
|
||||
*
|
||||
* Returns the filenames found by expanding <i>pattern</i> which is
|
||||
* an +Array+ of the patterns or the pattern +String+, either as an
|
||||
* <i>array</i> or as parameters to the block. Note that this pattern
|
||||
* is not a regexp (it's closer to a shell glob). See
|
||||
* <code>File::fnmatch</code> for the meaning of the <i>flags</i>
|
||||
* parameter. Note that case sensitivity depends on your system (so
|
||||
* <code>File::FNM_CASEFOLD</code> is ignored), as does the order
|
||||
* in which the results are returned.
|
||||
* Expands +pattern+, which is an Array of patterns or a pattern String, and
|
||||
* returns the results as +matches+ or as arguments given to the block.
|
||||
*
|
||||
* <code>*</code>:: Matches any file. Can be restricted by
|
||||
* other values in the glob. <code>*</code>
|
||||
* will match all files; <code>c*</code> will
|
||||
* match all files beginning with
|
||||
* <code>c</code>; <code>*c</code> will match
|
||||
* all files ending with <code>c</code>; and
|
||||
* <code>\*c\*</code> will match all files that
|
||||
* have <code>c</code> in them (including at
|
||||
* the beginning or end). Equivalent to
|
||||
* <code>/ .* /x</code> in regexp. Note, this
|
||||
* will not match Unix-like hidden files (dotfiles).
|
||||
* In order to include those in the match results,
|
||||
* you must use something like <code>"{*,.*}"</code>.
|
||||
* <code>**</code>:: Matches directories recursively.
|
||||
* <code>?</code>:: Matches any one character. Equivalent to
|
||||
* <code>/.{1}/</code> in regexp.
|
||||
* <code>[set]</code>:: Matches any one character in +set+.
|
||||
* Behaves exactly like character sets in
|
||||
* Regexp, including set negation
|
||||
* (<code>[^a-z]</code>).
|
||||
* <code>{p,q}</code>:: Matches either literal <code>p</code> or
|
||||
* literal <code>q</code>. Matching literals
|
||||
* may be more than one character in length.
|
||||
* More than two literals may be specified.
|
||||
* Equivalent to pattern alternation in
|
||||
* regexp.
|
||||
* <code> \\ </code>:: Escapes the next metacharacter.
|
||||
* Note that this means you cannot use backslash
|
||||
* in windows as part of a glob,
|
||||
* i.e. <code>Dir["c:\\foo*"]</code> will not work,
|
||||
* use <code>Dir["c:/foo*"]</code> instead.
|
||||
* Note that this pattern is not a regexp, it's closer to a shell glob. See
|
||||
* File::fnmatch for the meaning of the +flags+ parameter. Note that case
|
||||
* sensitivity depends on your system (so File::FNM_CASEFOLD is ignored), as
|
||||
* does the order in which the results are returned.
|
||||
*
|
||||
* <code>*</code>::
|
||||
* Matches any file. Can be restricted by other values in the glob.
|
||||
* Equivalent to <code>/ .* /x</code> in regexp.
|
||||
*
|
||||
* <code>*</code>:: Matches all files
|
||||
* <code>c*</code>:: Matches all files beginning with <code>c</code>
|
||||
* <code>*c</code>:: Matches all files ending with <code>c</code>
|
||||
* <code>\*c\*</code>:: Match all files that have <code>c</code> in them
|
||||
* (including at the beginning or end).
|
||||
*
|
||||
* Note, this will not match Unix-like hidden files (dotfiles). In order
|
||||
* to include those in the match results, you must use the
|
||||
* File::FNM_DOTMATCH flag or something like <code>"{*,.*}"</code>.
|
||||
*
|
||||
* <code>**</code>::
|
||||
* Matches directories recursively.
|
||||
*
|
||||
* <code>?</code>::
|
||||
* Matches any one character. Equivalent to <code>/.{1}/</code> in regexp.
|
||||
*
|
||||
* <code>[set]</code>::
|
||||
* Matches any one character in +set+. Behaves exactly like character sets
|
||||
* in Regexp, including set negation (<code>[^a-z]</code>).
|
||||
*
|
||||
* <code>{p,q}</code>::
|
||||
* Matches either literal <code>p</code> or literal <code>q</code>.
|
||||
* Equivalent to pattern alternation in regexp.
|
||||
*
|
||||
* Matching literals may be more than one character in length. More than
|
||||
* two literals may be specified.
|
||||
*
|
||||
* <code> \\ </code>::
|
||||
* Escapes the next metacharacter.
|
||||
*
|
||||
* Note that this means you cannot use backslash on windows as part of a
|
||||
* glob, i.e. <code>Dir["c:\\foo*"]</code> will not work, use
|
||||
* <code>Dir["c:/foo*"]</code> instead.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* Dir["config.?"] #=> ["config.h"]
|
||||
* Dir.glob("config.?") #=> ["config.h"]
|
||||
|
@ -1843,7 +1893,7 @@ dir_s_glob(int argc, VALUE *argv, VALUE obj)
|
|||
}
|
||||
else {
|
||||
volatile VALUE v = ary;
|
||||
ary = dir_globs(RARRAY_LEN(v), RARRAY_PTR(v), flags);
|
||||
ary = dir_globs(RARRAY_LEN(v), RARRAY_CONST_PTR(v), flags);
|
||||
}
|
||||
|
||||
if (rb_block_given_p()) {
|
||||
|
@ -1865,8 +1915,10 @@ dir_open_dir(int argc, VALUE *argv)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* Dir.foreach( dirname ) {| filename | block } -> nil
|
||||
* Dir.foreach( dirname ) -> an_enumerator
|
||||
* Dir.foreach( dirname ) {| filename | block } -> nil
|
||||
* Dir.foreach( dirname, encoding: enc ) {| filename | block } -> nil
|
||||
* Dir.foreach( dirname ) -> an_enumerator
|
||||
* Dir.foreach( dirname, encoding: enc ) -> an_enumerator
|
||||
*
|
||||
* Calls the block once for each entry in the named directory, passing
|
||||
* the filename of each entry as a parameter to the block.
|
||||
|
@ -1896,12 +1948,16 @@ dir_foreach(int argc, VALUE *argv, VALUE io)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* Dir.entries( dirname ) -> array
|
||||
* Dir.entries( dirname ) -> array
|
||||
* Dir.entries( dirname, encoding: enc ) -> array
|
||||
*
|
||||
* Returns an array containing all of the filenames in the given
|
||||
* directory. Will raise a <code>SystemCallError</code> if the named
|
||||
* directory doesn't exist.
|
||||
*
|
||||
* The optional <i>enc</i> argument specifies the encoding of the directory.
|
||||
* If not specified, the filesystem encoding is used.
|
||||
*
|
||||
* Dir.entries("testdir") #=> [".", "..", "config.h", "main.rb"]
|
||||
*
|
||||
*/
|
||||
|
@ -1919,7 +1975,24 @@ fnmatch_brace(const char *pattern, VALUE val, void *enc)
|
|||
{
|
||||
struct brace_args *arg = (struct brace_args *)val;
|
||||
VALUE path = arg->value;
|
||||
rb_encoding *enc_pattern = enc;
|
||||
rb_encoding *enc_path = rb_enc_get(path);
|
||||
|
||||
if (enc_pattern != enc_path) {
|
||||
if (!rb_enc_asciicompat(enc_pattern))
|
||||
return FNM_NOMATCH;
|
||||
if (!rb_enc_asciicompat(enc_path))
|
||||
return FNM_NOMATCH;
|
||||
if (!rb_enc_str_asciionly_p(path)) {
|
||||
int cr = ENC_CODERANGE_7BIT;
|
||||
long len = strlen(pattern);
|
||||
if (rb_str_coderange_scan_restartable(pattern, pattern + len,
|
||||
enc_pattern, &cr) != len)
|
||||
return FNM_NOMATCH;
|
||||
if (cr != ENC_CODERANGE_7BIT)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
}
|
||||
return (fnmatch(pattern, enc, RSTRING_PTR(path), arg->flags) == 0);
|
||||
}
|
||||
|
||||
|
@ -1928,38 +2001,50 @@ fnmatch_brace(const char *pattern, VALUE val, void *enc)
|
|||
* File.fnmatch( pattern, path, [flags] ) -> (true or false)
|
||||
* File.fnmatch?( pattern, path, [flags] ) -> (true or false)
|
||||
*
|
||||
* Returns true if <i>path</i> matches against <i>pattern</i> The
|
||||
* pattern is not a regular expression; instead it follows rules
|
||||
* similar to shell filename globbing. It may contain the following
|
||||
* metacharacters:
|
||||
* Returns true if +path+ matches against +pattern+. The pattern is not a
|
||||
* regular expression; instead it follows rules similar to shell filename
|
||||
* globbing. It may contain the following metacharacters:
|
||||
*
|
||||
* <code>*</code>:: Matches any file. Can be restricted by
|
||||
* other values in the glob. <code>*</code>
|
||||
* will match all files; <code>c*</code> will
|
||||
* match all files beginning with
|
||||
* <code>c</code>; <code>*c</code> will match
|
||||
* all files ending with <code>c</code>; and
|
||||
* <code>\*c*</code> will match all files that
|
||||
* have <code>c</code> in them (including at
|
||||
* the beginning or end). Equivalent to
|
||||
* <code>/ .* /x</code> in regexp.
|
||||
* <code>**</code>:: Matches directories recursively or files
|
||||
* expansively.
|
||||
* <code>?</code>:: Matches any one character. Equivalent to
|
||||
* <code>/.{1}/</code> in regexp.
|
||||
* <code>[set]</code>:: Matches any one character in +set+.
|
||||
* Behaves exactly like character sets in
|
||||
* Regexp, including set negation
|
||||
* (<code>[^a-z]</code>).
|
||||
* <code> \ </code>:: Escapes the next metacharacter.
|
||||
* <code>*</code>::
|
||||
* Matches any file. Can be restricted by other values in the glob.
|
||||
* Equivalent to <code>/ .* /x</code> in regexp.
|
||||
*
|
||||
* <i>flags</i> is a bitwise OR of the <code>FNM_xxx</code>
|
||||
* parameters. The same glob pattern and flags are used by
|
||||
* <code>Dir::glob</code>.
|
||||
* <code>*</code>:: Matches all files regular files
|
||||
* <code>c*</code>:: Matches all files beginning with <code>c</code>
|
||||
* <code>*c</code>:: Matches all files ending with <code>c</code>
|
||||
* <code>\*c*</code>:: Matches all files that have <code>c</code> in them
|
||||
* (including at the beginning or end).
|
||||
*
|
||||
* To match hidden files (that start with a <code>.</code> set the
|
||||
* File::FNM_DOTMATCH flag.
|
||||
*
|
||||
* <code>**</code>::
|
||||
* Matches directories recursively or files expansively.
|
||||
*
|
||||
* <code>?</code>::
|
||||
* Matches any one character. Equivalent to <code>/.{1}/</code> in regexp.
|
||||
*
|
||||
* <code>[set]</code>::
|
||||
* Matches any one character in +set+. Behaves exactly like character sets
|
||||
* in Regexp, including set negation (<code>[^a-z]</code>).
|
||||
*
|
||||
* <code> \ </code>::
|
||||
* Escapes the next metacharacter.
|
||||
*
|
||||
* <code>{a,b}</code>::
|
||||
* Matches pattern a and pattern b if File::FNM_EXTGLOB flag is enabled.
|
||||
* Behaves like a Regexp union (<code>(?:a|b)</code>).
|
||||
*
|
||||
* +flags+ is a bitwise OR of the <code>FNM_XXX</code> constants. The same
|
||||
* glob pattern and flags are used by Dir::glob.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* File.fnmatch('cat', 'cat') #=> true # match entire string
|
||||
* File.fnmatch('cat', 'category') #=> false # only match partial string
|
||||
* File.fnmatch('c{at,ub}s', 'cats') #=> false # { } isn't supported
|
||||
*
|
||||
* File.fnmatch('c{at,ub}s', 'cats') #=> false # { } isn't supported by default
|
||||
* File.fnmatch('c{at,ub}s', 'cats', File::FNM_EXTGLOB) #=> true # { } is supported on FNM_EXTGLOB
|
||||
*
|
||||
* File.fnmatch('c?t', 'cat') #=> true # '?' match only 1 character
|
||||
* File.fnmatch('c??t', 'cat') #=> false # ditto
|
||||
|
@ -1977,7 +2062,7 @@ fnmatch_brace(const char *pattern, VALUE val, void *enc)
|
|||
*
|
||||
* File.fnmatch('\?', '?') #=> true # escaped wildcard becomes ordinary
|
||||
* File.fnmatch('\a', 'a') #=> true # escaped ordinary remains ordinary
|
||||
* File.fnmatch('\a', '\a', File::FNM_NOESCAPE) #=> true # FNM_NOESACPE makes '\' ordinary
|
||||
* File.fnmatch('\a', '\a', File::FNM_NOESCAPE) #=> true # FNM_NOESCAPE makes '\' ordinary
|
||||
* File.fnmatch('[\?]', '?') #=> true # can escape inside bracket expression
|
||||
*
|
||||
* File.fnmatch('*', '.profile') #=> false # wildcard doesn't match leading
|
||||
|
@ -2029,8 +2114,9 @@ file_s_fnmatch(int argc, VALUE *argv, VALUE obj)
|
|||
return Qtrue;
|
||||
}
|
||||
else {
|
||||
if (fnmatch(RSTRING_PTR(pattern), rb_enc_get(pattern), RSTRING_PTR(path),
|
||||
flags) == 0)
|
||||
rb_encoding *enc = rb_enc_compatible(pattern, path);
|
||||
if (!enc) return Qfalse;
|
||||
if (fnmatch(RSTRING_PTR(pattern), enc, RSTRING_PTR(path), flags) == 0)
|
||||
return Qtrue;
|
||||
}
|
||||
RB_GC_GUARD(pattern);
|
||||
|
@ -2052,12 +2138,18 @@ dir_s_home(int argc, VALUE *argv, VALUE obj)
|
|||
VALUE user;
|
||||
const char *u = 0;
|
||||
|
||||
rb_scan_args(argc, argv, "01", &user);
|
||||
rb_check_arity(argc, 0, 1);
|
||||
user = (argc > 0) ? argv[0] : Qnil;
|
||||
if (!NIL_P(user)) {
|
||||
SafeStringValue(user);
|
||||
rb_must_asciicompat(user);
|
||||
u = StringValueCStr(user);
|
||||
if (*u) {
|
||||
return rb_home_dir_of(user, rb_str_new(0, 0));
|
||||
}
|
||||
}
|
||||
return rb_home_dir(u, rb_str_new(0, 0));
|
||||
return rb_default_home_dir(rb_str_new(0, 0));
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -2076,6 +2168,13 @@ rb_file_directory_p()
|
|||
}
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
rb_dir_exists_p(VALUE obj, VALUE fname)
|
||||
{
|
||||
rb_warning("Dir.exists? is a deprecated name, use Dir.exist? instead");
|
||||
return rb_file_directory_p(obj, fname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Objects of class <code>Dir</code> are directory streams representing
|
||||
* directories in the underlying file system. They provide a variety of
|
||||
|
@ -2125,15 +2224,42 @@ Init_Dir(void)
|
|||
rb_define_singleton_method(rb_cDir,"glob", dir_s_glob, -1);
|
||||
rb_define_singleton_method(rb_cDir,"[]", dir_s_aref, -1);
|
||||
rb_define_singleton_method(rb_cDir,"exist?", rb_file_directory_p, 1);
|
||||
rb_define_singleton_method(rb_cDir,"exists?", rb_file_directory_p, 1);
|
||||
rb_define_singleton_method(rb_cDir,"exists?", rb_dir_exists_p, 1);
|
||||
|
||||
rb_define_singleton_method(rb_cFile,"fnmatch", file_s_fnmatch, -1);
|
||||
rb_define_singleton_method(rb_cFile,"fnmatch?", file_s_fnmatch, -1);
|
||||
|
||||
/* Document-const: File::Constants::FNM_NOESCAPE
|
||||
*
|
||||
* Disables escapes in File.fnmatch and Dir.glob patterns
|
||||
*/
|
||||
rb_file_const("FNM_NOESCAPE", INT2FIX(FNM_NOESCAPE));
|
||||
|
||||
/* Document-const: File::Constants::FNM_PATHNAME
|
||||
*
|
||||
* Wildcards in File.fnmatch and Dir.glob patterns do not match directory
|
||||
* separators
|
||||
*/
|
||||
rb_file_const("FNM_PATHNAME", INT2FIX(FNM_PATHNAME));
|
||||
|
||||
/* Document-const: File::Constants::FNM_DOTMATCH
|
||||
*
|
||||
* The '*' wildcard matches filenames starting with "." in File.fnmatch
|
||||
* and Dir.glob patterns
|
||||
*/
|
||||
rb_file_const("FNM_DOTMATCH", INT2FIX(FNM_DOTMATCH));
|
||||
|
||||
/* Document-const: File::Constants::FNM_CASEFOLD
|
||||
*
|
||||
* Makes File.fnmatch patterns case insensitive (but not Dir.glob
|
||||
* patterns).
|
||||
*/
|
||||
rb_file_const("FNM_CASEFOLD", INT2FIX(FNM_CASEFOLD));
|
||||
|
||||
/* Document-const: File::Constants::FNM_EXTGLOB
|
||||
*
|
||||
* Allows file globbing through "{a,b}" in File.fnmatch patterns.
|
||||
*/
|
||||
rb_file_const("FNM_EXTGLOB", INT2FIX(FNM_EXTGLOB));
|
||||
rb_file_const("FNM_SYSCASE", INT2FIX(FNM_SYSCASE));
|
||||
}
|
||||
|
|
19
dln.h
19
dln.h
|
@ -28,14 +28,17 @@
|
|||
# define _(args) ()
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 4
|
||||
#pragma GCC visibility push(default)
|
||||
RUBY_SYMBOL_EXPORT_BEGIN
|
||||
|
||||
#ifndef DLN_FIND_EXTRA_ARG
|
||||
#define DLN_FIND_EXTRA_ARG
|
||||
#endif
|
||||
#ifndef DLN_FIND_EXTRA_ARG_DECL
|
||||
#define DLN_FIND_EXTRA_ARG_DECL
|
||||
#endif
|
||||
|
||||
DEPRECATED(char *dln_find_exe(const char*,const char*));
|
||||
DEPRECATED(char *dln_find_file(const char*,const char*));
|
||||
char *dln_find_exe_r(const char*,const char*,char*,size_t);
|
||||
char *dln_find_file_r(const char*,const char*,char*,size_t);
|
||||
char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
|
||||
char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
|
||||
|
||||
#ifdef USE_DLN_A_OUT
|
||||
extern char *dln_argv0;
|
||||
|
@ -43,8 +46,6 @@ extern char *dln_argv0;
|
|||
|
||||
void *dln_load(const char*);
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 4
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
RUBY_SYMBOL_EXPORT_END
|
||||
|
||||
#endif
|
||||
|
|
40
dln_find.c
40
dln_find.c
|
@ -11,19 +11,11 @@
|
|||
|
||||
#ifdef RUBY_EXPORT
|
||||
#include "ruby/ruby.h"
|
||||
#define dln_notimplement rb_notimplement
|
||||
#define dln_memerror rb_memerror
|
||||
#define dln_exit rb_exit
|
||||
#define dln_loaderror rb_loaderror
|
||||
#define dln_warning rb_warning
|
||||
#define dln_warning_arg
|
||||
#else
|
||||
#define dln_notimplement --->>> dln not implemented <<<---
|
||||
#define dln_memerror abort
|
||||
#define dln_exit exit
|
||||
#define dln_warning fprintf
|
||||
#define dln_warning_arg stderr,
|
||||
static void dln_loaderror(const char *format, ...);
|
||||
#endif
|
||||
#include "dln.h"
|
||||
|
||||
|
@ -67,14 +59,16 @@ char *dln_argv0;
|
|||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#if !defined(_WIN32) && !HAVE_DECL_GETENV
|
||||
char *getenv();
|
||||
#endif
|
||||
|
||||
static char *dln_find_1(const char *fname, const char *path, char *buf, size_t size, int exe_flag);
|
||||
static char *dln_find_1(const char *fname, const char *path, char *buf, size_t size, int exe_flag
|
||||
DLN_FIND_EXTRA_ARG_DECL);
|
||||
|
||||
char *
|
||||
dln_find_exe_r(const char *fname, const char *path, char *buf, size_t size)
|
||||
dln_find_exe_r(const char *fname, const char *path, char *buf, size_t size
|
||||
DLN_FIND_EXTRA_ARG_DECL)
|
||||
{
|
||||
char *envpath = 0;
|
||||
|
||||
|
@ -90,35 +84,23 @@ dln_find_exe_r(const char *fname, const char *path, char *buf, size_t size)
|
|||
path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:.";
|
||||
#endif
|
||||
}
|
||||
buf = dln_find_1(fname, path, buf, size, 1);
|
||||
buf = dln_find_1(fname, path, buf, size, 1 DLN_FIND_EXTRA_ARG);
|
||||
if (envpath) free(envpath);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *
|
||||
dln_find_file_r(const char *fname, const char *path, char *buf, size_t size)
|
||||
dln_find_file_r(const char *fname, const char *path, char *buf, size_t size
|
||||
DLN_FIND_EXTRA_ARG_DECL)
|
||||
{
|
||||
if (!path) path = ".";
|
||||
return dln_find_1(fname, path, buf, size, 0);
|
||||
}
|
||||
|
||||
static char fbuf[MAXPATHLEN];
|
||||
|
||||
char *
|
||||
dln_find_exe(const char *fname, const char *path)
|
||||
{
|
||||
return dln_find_exe_r(fname, path, fbuf, sizeof(fbuf));
|
||||
}
|
||||
|
||||
char *
|
||||
dln_find_file(const char *fname, const char *path)
|
||||
{
|
||||
return dln_find_file_r(fname, path, fbuf, sizeof(fbuf));
|
||||
return dln_find_1(fname, path, buf, size, 0 DLN_FIND_EXTRA_ARG);
|
||||
}
|
||||
|
||||
static char *
|
||||
dln_find_1(const char *fname, const char *path, char *fbuf, size_t size,
|
||||
int exe_flag /* non 0 if looking for executable. */)
|
||||
int exe_flag /* non 0 if looking for executable. */
|
||||
DLN_FIND_EXTRA_ARG_DECL)
|
||||
{
|
||||
register const char *dp;
|
||||
register const char *ep;
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
#define NO_LOCALE_CHARMAP 1
|
||||
#include "encoding.c"
|
|
@ -1,2 +0,0 @@
|
|||
#define NO_INITIAL_LOAD_PATH 1
|
||||
#include "version.c"
|
|
@ -13763,7 +13763,7 @@ Tue Apr 17 17:33:55 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
|||
|
||||
* eval.c (handle_rescue): use === to compare exception match.
|
||||
|
||||
* error.c (syserr_eqq): comparison between SytemCallErrors should
|
||||
* error.c (syserr_eqq): comparison between SystemCallErrors should
|
||||
based on their error numbers.
|
||||
|
||||
Tue Apr 17 16:54:39 2001 K.Kosako <kosako@sofnec.co.jp>
|
||||
|
|
|
@ -14297,7 +14297,7 @@ Thu Jun 10 09:10:08 2010 Yukihiro Matsumoto <matz@ruby-lang.org>
|
|||
|
||||
Wed Jun 9 22:51:50 2010 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* time.c (find_time_t): always outerpolate from past.
|
||||
* time.c (find_time_t): always extrapolate from past.
|
||||
[ruby-core:30672] reported by Benoit Daloze.
|
||||
|
||||
Wed Jun 9 22:13:08 2010 Tanaka Akira <akr@fsij.org>
|
||||
|
@ -76917,7 +76917,7 @@ Tue May 31 15:52:45 2005 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
|||
break the loop if the socket reached to EOF. [ruby-talk:142285]
|
||||
|
||||
* lib/webrick/httpserver.rb (WEBrick::HTTPServer#run): send response
|
||||
without reading the whole request body if keep-alive is diabled.
|
||||
without reading the whole request body if keep-alive is disabled.
|
||||
[experimental]
|
||||
|
||||
Mon May 30 23:48:29 2005 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||
|
@ -76939,7 +76939,7 @@ Sat May 28 16:39:21 2005 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
|||
Sat May 28 05:15:44 2005 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
||||
|
||||
* ext/openssl/ossl_x509store.c (ossl_x509stctx_set_time): should
|
||||
not set internal flag directry.
|
||||
not set internal flag directory.
|
||||
|
||||
Sat May 28 02:00:11 2005 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
||||
|
||||
|
|
24015
doc/ChangeLog-2.0.0
Normal file
24015
doc/ChangeLog-2.0.0
Normal file
File diff suppressed because it is too large
Load diff
|
@ -4328,7 +4328,7 @@ Sun Dec 31 17:42:05 2006 Koichi Sasada <ko1@atdot.net>
|
|||
|
||||
* vm.c : fix to skip pushing value at "next"
|
||||
|
||||
* yarvcore.h : move definision of
|
||||
* yarvcore.h : move definition of
|
||||
"struct iseq_compile_data_ensure_node_stack" to compile.c
|
||||
|
||||
* compile.c : fix ensure catch table creation
|
||||
|
|
|
@ -54,7 +54,7 @@ with all sufficient information, see the ChangeLog file.
|
|||
* Array#flatten
|
||||
* Array#flatten!
|
||||
|
||||
Take an optional argument that determines the level of recursion
|
||||
Takes an optional argument that determines the level of recursion
|
||||
to flatten.
|
||||
|
||||
* Array#eql?
|
||||
|
@ -77,6 +77,7 @@ with all sufficient information, see the ChangeLog file.
|
|||
* Array#reject
|
||||
* Array#reject!
|
||||
* Array#delete_if
|
||||
* Array#select
|
||||
|
||||
Return an enumerator if no block is given.
|
||||
|
||||
|
@ -161,6 +162,10 @@ with all sufficient information, see the ChangeLog file.
|
|||
|
||||
New alias to #inject.
|
||||
|
||||
* Enumerable#to_a
|
||||
|
||||
Can take optional arguments and pass them to #each.
|
||||
|
||||
* Hash#eql?
|
||||
* Hash#hash
|
||||
* Hash#==
|
||||
|
@ -262,12 +267,17 @@ with all sufficient information, see the ChangeLog file.
|
|||
|
||||
* Regexp.union accepts an array of patterns.
|
||||
|
||||
* String#bytes
|
||||
|
||||
New method
|
||||
|
||||
* String#bytesize
|
||||
|
||||
New method, returning the size in bytes. (alias length and size)
|
||||
|
||||
* String#chars
|
||||
* String#each_char
|
||||
* String#lines
|
||||
* String#partition
|
||||
* String#rpartition
|
||||
* String#start_with?
|
||||
|
@ -501,6 +511,15 @@ with all sufficient information, see the ChangeLog file.
|
|||
always use Date.strptime() when you know what you are dealing
|
||||
with.
|
||||
|
||||
* REXML
|
||||
|
||||
* REXML::Document.entity_expansion_limit=
|
||||
|
||||
New method to set the entity expansion limit. By default the limit is
|
||||
set to 10000. See the following URL for details.
|
||||
|
||||
http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/
|
||||
|
||||
* stringio
|
||||
|
||||
* StringIO#each_byte
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- rdoc -*-
|
||||
|
||||
= NEWS for RDoc 1.9.1
|
||||
= NEWS for Ruby 1.9.1
|
||||
|
||||
This document is a list of user visible feature changes made between
|
||||
releases except for bug fixes.
|
||||
|
@ -335,6 +335,11 @@ See doc/NEWS-1.8.7 for changes between 1.8.6 and 1.8.7.
|
|||
o Numeric#upto, #downto, #times, #step
|
||||
o Numeric#real?, Complex#real?
|
||||
o Numeric#magnitude
|
||||
o Numeric#round
|
||||
* Float
|
||||
o Float#round
|
||||
* Integer
|
||||
o Integer#round
|
||||
* Rational / Complex
|
||||
o They are in the core library now
|
||||
* Math
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- rdoc -*-
|
||||
|
||||
= NEWS for Ruby 1.9.2
|
||||
|
||||
This document is a list of user visible feature changes made between
|
||||
|
@ -15,7 +14,7 @@ with all sufficient information, see the ChangeLog file.
|
|||
* builtin classes
|
||||
|
||||
* Array
|
||||
* new method:
|
||||
* new methods:
|
||||
* Array#keep_if
|
||||
* Array#repeated_combination
|
||||
* Array#repeated_permutation
|
||||
|
@ -24,11 +23,11 @@ with all sufficient information, see the ChangeLog file.
|
|||
* Array#select!
|
||||
* Array#sort_by!
|
||||
|
||||
* extended methods:
|
||||
* extended method:
|
||||
* Array#{uniq,uniq!,product} can take a block.
|
||||
|
||||
* Complex
|
||||
* new methods:
|
||||
* new method:
|
||||
* Complex#rationalize
|
||||
|
||||
* Dir
|
||||
|
@ -51,7 +50,7 @@ with all sufficient information, see the ChangeLog file.
|
|||
* ascii_compatible?
|
||||
|
||||
* Enumerable
|
||||
* New methods:
|
||||
* new methods:
|
||||
* Enumerable#chunk
|
||||
* Enumerable#collect_concat
|
||||
* Enumerable#each_entry
|
||||
|
@ -66,7 +65,7 @@ with all sufficient information, see the ChangeLog file.
|
|||
* Enumerator#feed
|
||||
* StopIteration#result
|
||||
|
||||
* extended methods:
|
||||
* extended method:
|
||||
* #with_index accepts an optional argument that specifies the
|
||||
index number to start with, defaulted to 0.
|
||||
|
||||
|
@ -86,14 +85,13 @@ with all sufficient information, see the ChangeLog file.
|
|||
* new constants:
|
||||
* Float::INFINITY
|
||||
* Float::NAN
|
||||
* new methods:
|
||||
* new method:
|
||||
* Float#rationalize
|
||||
|
||||
* File
|
||||
* new methods:
|
||||
* File.realpath
|
||||
* File.realdirpath
|
||||
* File#size
|
||||
|
||||
* GC::Profiler
|
||||
* new method:
|
||||
|
@ -105,14 +103,14 @@ with all sufficient information, see the ChangeLog file.
|
|||
* Hash#select!
|
||||
|
||||
* IO
|
||||
* new method:
|
||||
* new methods:
|
||||
* IO#autoclose=
|
||||
* IO#autoclose?
|
||||
* IO#fdatasync
|
||||
* IO#codepoints
|
||||
* IO#each_codepoint
|
||||
|
||||
* extended methods:
|
||||
* extended method:
|
||||
* IO.pipe can take a block.
|
||||
|
||||
* new modules:
|
||||
|
@ -121,7 +119,7 @@ with all sufficient information, see the ChangeLog file.
|
|||
They are used to extend non-blocking exceptions.
|
||||
|
||||
* Integer
|
||||
* new methods:
|
||||
* new method:
|
||||
* Integer#rationalize
|
||||
|
||||
* Kernel
|
||||
|
@ -130,7 +128,7 @@ with all sufficient information, see the ChangeLog file.
|
|||
* Kernel#singleton_class
|
||||
* Kernel#require_relative
|
||||
|
||||
* extended methods:
|
||||
* extended method:
|
||||
* Kernel#respond_to? can be used to detect methods not implemented.
|
||||
For example, Process.respond_to?(:fork) returns false on Windows.
|
||||
|
||||
|
@ -148,11 +146,15 @@ with all sufficient information, see the ChangeLog file.
|
|||
platforms.
|
||||
|
||||
* MatchData
|
||||
* New method:
|
||||
* new method:
|
||||
* MatchData#==
|
||||
|
||||
* Method
|
||||
* new method:
|
||||
* Method#parameters
|
||||
|
||||
* NilClass
|
||||
* new methods:
|
||||
* new method:
|
||||
* NilClass#rationalize
|
||||
|
||||
* Object
|
||||
|
@ -161,18 +163,20 @@ with all sufficient information, see the ChangeLog file.
|
|||
* printf() supports %a/%A format.
|
||||
|
||||
* Proc
|
||||
* new method:
|
||||
* Proc#parameters
|
||||
* extended method:
|
||||
* Proc#source_location returns location even if receiver is a method
|
||||
defined by attr_reader / attr_writer / attr_accessor.
|
||||
|
||||
* Process
|
||||
* extended methods:
|
||||
* extended method:
|
||||
* Process.spawn accepts [:child, FD] for a redirect target.
|
||||
|
||||
* Random (new class to generate pseudo-random numbers)
|
||||
|
||||
* Rational
|
||||
* new methods:
|
||||
* new method:
|
||||
* Rational#rationalize
|
||||
|
||||
* String
|
||||
|
@ -185,22 +189,27 @@ with all sufficient information, see the ChangeLog file.
|
|||
* Thread#set_trace_func
|
||||
|
||||
* Time
|
||||
* extended feature:
|
||||
* extended features:
|
||||
* time_t restriction is removed to represent before 1901 and after 2038.
|
||||
Proleptic Gregorian calendar is used for old dates.
|
||||
* Time.new have optional arguments to specify date with time offset.
|
||||
* Time#getlocal, Time#localtime have optional time offset argument.
|
||||
|
||||
* new method:
|
||||
* new methods:
|
||||
* Time#to_r
|
||||
* Time#subsec
|
||||
* Time#round
|
||||
|
||||
* incompatible changes:
|
||||
* incompatible change:
|
||||
* The year argument of Time.{utc,gm,local,mktime} is now interpreted as
|
||||
the value itself. For example, Time.utc(99) means the year 99 AD,
|
||||
not 1999 AD.
|
||||
|
||||
* UnboundMethod
|
||||
* new method:
|
||||
* UnboundMethod#parameters
|
||||
|
||||
|
||||
* digest
|
||||
* new methods:
|
||||
* Digest::Class.base64digest
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- rdoc -*-
|
||||
|
||||
= NEWS for Ruby 1.9.3
|
||||
|
||||
This document is a list of user visible feature changes made between
|
||||
|
@ -15,6 +14,13 @@ with all sufficient information, see the ChangeLog file.
|
|||
* Ruby's License is changed from a dual license with GPLv2
|
||||
to a dual license with 2-clause BSDL.
|
||||
|
||||
=== Known platform dependent issues
|
||||
==== OS X Lion
|
||||
|
||||
* You have to configure ruby with '--with-gcc=gcc-4.2' if you're using
|
||||
Xcode 4.1, or, if you're using Xcode 4.2, you have to configure ruby
|
||||
with '--with-gcc=clang'.
|
||||
|
||||
=== C API updates
|
||||
|
||||
* rb_scan_args() is enhanced with support for option hash argument
|
||||
|
@ -23,6 +29,9 @@ with all sufficient information, see the ChangeLog file.
|
|||
* ruby_vm_at_exit() added. This enables extension libs to hook a VM
|
||||
termination.
|
||||
|
||||
* rb_reserved_fd_p() added. If you want to close all file descriptors,
|
||||
check using this API. [ruby-core:37759]
|
||||
|
||||
=== Library updates (outstanding ones only)
|
||||
|
||||
* builtin classes
|
||||
|
@ -103,16 +112,34 @@ with all sufficient information, see the ChangeLog file.
|
|||
the platform don't support supplementary groups concept.
|
||||
|
||||
* bigdecimal
|
||||
|
||||
* BigDecimal#power and BigDecimal#** support non-integral exponent.
|
||||
|
||||
* Kernel.BigDecimal and BigDecimal.new now accept instances of Integer,
|
||||
Rational, and Float. If you pass a Rational or a Float to them, you must
|
||||
specify the precision to produce the digits of a BigDecimal.
|
||||
Rational, Float, and BigDecimal. If you pass a Rational or a Float to
|
||||
them, you must specify the precision to produce the digits of a BigDecimal.
|
||||
|
||||
* The behavior of BigDecimal#coerce with a Rational is changed. It uses
|
||||
the precision of the receiver BigDecimal to produce the digits of a
|
||||
BigDecimal from the given Rational.
|
||||
|
||||
* bigdecimal/util
|
||||
|
||||
* BigDecimal#to_d and Integer#to_d are added.
|
||||
|
||||
* Float#to_d accepts a precision.
|
||||
|
||||
* Rational#to_d raises ArgumentError when passing zero or negative
|
||||
precision.
|
||||
|
||||
* Rational#to_d
|
||||
|
||||
* Zero and an implicit precision is deprecated.
|
||||
This feature is removed at the next release of bigdecimal.
|
||||
|
||||
* A negative precision isn't supported.
|
||||
Be careful it is an incompatible change.
|
||||
|
||||
* date
|
||||
|
||||
* Accepts flonum explicitly with limitations.
|
||||
|
@ -165,6 +192,9 @@ with all sufficient information, see the ChangeLog file.
|
|||
* IO#winsize
|
||||
* IO.console
|
||||
|
||||
* json
|
||||
* updated to v1.5.4.
|
||||
|
||||
* matrix
|
||||
* new classes:
|
||||
* Matrix::EigenvalueDecomposition
|
||||
|
@ -213,9 +243,13 @@ with all sufficient information, see the ChangeLog file.
|
|||
http.request_post('/continue', 'body=BODY', 'expect' => '100-continue')
|
||||
|
||||
* new method:
|
||||
* Net::HTTPRequest#set_form: Added to support
|
||||
* Net::HTTPRequest#set_form): Added to support
|
||||
both application/x-www-form-urlencoded and multipart/form-data.
|
||||
|
||||
* objspace
|
||||
* new method:
|
||||
* ObjectSpace::memsize_of_all
|
||||
|
||||
* openssl
|
||||
* PKey::RSA and PKey::DSA now use the generic X.509 encoding scheme
|
||||
(e.g. used in a X.509 certificate's Subject Public Key Info) when
|
||||
|
@ -237,18 +271,18 @@ with all sufficient information, see the ChangeLog file.
|
|||
* support for bash/zsh completion.
|
||||
|
||||
* Rake
|
||||
* Rake has been upgraded from 0.8.7 to 0.9.2.1. For full release notes see
|
||||
* Rake has been upgraded from 0.8.7 to 0.9.2.2. For full release notes see
|
||||
https://github.com/jimweirich/rake/blob/master/CHANGES
|
||||
|
||||
* RDoc
|
||||
* RDoc has been upgraded from 2.5.8 to 3.8. For full release notes see
|
||||
* RDoc has been upgraded to version 3.9.4. For full release notes see
|
||||
http://docs.seattlerb.org/rdoc/History_txt.html
|
||||
|
||||
* rexml
|
||||
* Support Ruby native encoding mechanism and iconv dependency is dropped.
|
||||
|
||||
* RubyGems
|
||||
* RubyGems has been upgraded to version 1.8.5.1. For full release notes see
|
||||
* RubyGems has been upgraded to version 1.8.10. For full release notes see
|
||||
http://rubygems.rubyforge.org/rubygems-update/History_txt.html
|
||||
|
||||
* stringio
|
||||
|
@ -302,4 +336,6 @@ with all sufficient information, see the ChangeLog file.
|
|||
|
||||
=== Compatibility issues (excluding feature bug fixes)
|
||||
|
||||
None
|
||||
* Rational#to_d
|
||||
|
||||
See above.
|
||||
|
|
531
doc/NEWS-2.0.0
Normal file
531
doc/NEWS-2.0.0
Normal file
|
@ -0,0 +1,531 @@
|
|||
# -*- rdoc -*-
|
||||
|
||||
= NEWS for Ruby 2.0.0
|
||||
|
||||
This document is a list of user visible feature changes made between
|
||||
releases except for bug fixes.
|
||||
|
||||
Note that each entry is kept so brief that no reason behind or
|
||||
reference information is supplied with. For a full list of changes
|
||||
with all sufficient information, see the ChangeLog file.
|
||||
|
||||
== Changes since the 1.9.3 release
|
||||
|
||||
=== Language changes
|
||||
|
||||
* Added keyword arguments.
|
||||
|
||||
* Added %i and %I for symbol list creation (similar to %w and %W).
|
||||
|
||||
* Default source encoding is changed to UTF-8. (was US-ASCII)
|
||||
|
||||
* No warning for unused variables starting with '_'
|
||||
|
||||
=== Core classes updates (outstanding ones only)
|
||||
|
||||
* ARGF
|
||||
* added method:
|
||||
* added ARGF#codepoints and ARGF#each_codepoint, like the corresponding
|
||||
methods for IO.
|
||||
|
||||
* Array
|
||||
* added method:
|
||||
* added Array#bsearch for binary search.
|
||||
* incompatible changes:
|
||||
* random parameter of Array#shuffle! and Array#sample now
|
||||
will be called with one argument, maximum value.
|
||||
* when given Range arguments, Array#values_at now returns nil for each
|
||||
value that is out-of-range.
|
||||
|
||||
* Enumerable
|
||||
* added method:
|
||||
* added Enumerable#lazy method for lazy enumeration.
|
||||
|
||||
* Enumerator
|
||||
* added method:
|
||||
* added Enumerator#size for lazy size evaluation.
|
||||
* extended method:
|
||||
* Enumerator.new accept an argument for lazy size evaluation.
|
||||
* new class Enumerator::Lazy for lazy enumeration
|
||||
|
||||
* ENV
|
||||
* aliased method:
|
||||
* ENV.to_h is a new alias for ENV.to_hash
|
||||
|
||||
* Fiber
|
||||
* incompatible changes:
|
||||
* Fiber#resume cannot resume a fiber which invokes "Fiber#transfer".
|
||||
|
||||
* File
|
||||
* extended method:
|
||||
* File.fnmatch? now expands braces in the pattern if
|
||||
File::FNM_EXTGLOB option is given.
|
||||
|
||||
* GC
|
||||
* improvements:
|
||||
* introduced the bitmap marking which suppresses to copy a memory page
|
||||
with Copy-on-Write.
|
||||
* introduced the non-recursive marking which avoids unexpected stack overflow.
|
||||
|
||||
* GC::Profiler
|
||||
* added method:
|
||||
* added GC::Profiler.raw_data which returns raw profile data for GC.
|
||||
|
||||
* Hash
|
||||
* added method:
|
||||
* added Hash#to_h as explicit conversion method, like Array#to_a.
|
||||
* extended method:
|
||||
* Hash#default_proc= can be passed nil to clear the default proc.
|
||||
|
||||
* IO
|
||||
* deprecated methods:
|
||||
* IO#lines, #bytes, #chars and #codepoints are deprecated.
|
||||
|
||||
* Kernel
|
||||
* added method:
|
||||
* added Kernel#Hash conversion method like Array() or Float().
|
||||
* added Kernel#__dir__ which returns the absolute path of the
|
||||
directory of the file from which this method is called.
|
||||
* added Kernel#caller_locations which returns an array of
|
||||
frame information objects.
|
||||
* extended method:
|
||||
* Kernel#warn accepts multiple args in like puts.
|
||||
* Kernel#caller accepts second optional argument `n' which specify
|
||||
required caller size.
|
||||
* Kernel#to_enum and enum_for accept a block for lazy size evaluation.
|
||||
* incompatible changes:
|
||||
* system() and exec() closes non-standard file descriptors
|
||||
(The default of :close_others option is changed to true by default.)
|
||||
* respond_to? against a protected method now returns false unless
|
||||
the second argument is true.
|
||||
* __callee__ has returned to the original behavior, and now
|
||||
returns the called name but not the original name in an
|
||||
aliased method.
|
||||
* Kernel#inspect does not call #to_s anymore
|
||||
(it used to call redefined #to_s).
|
||||
|
||||
* LoadError
|
||||
* added method:
|
||||
* added LoadError#path method to return the file name that could not be
|
||||
loaded.
|
||||
|
||||
* Module
|
||||
* added method:
|
||||
* added Module#prepend which is similar to Module#include,
|
||||
however a method in the prepended module overrides the
|
||||
corresponding method in the prepending module.
|
||||
* added Module.prepended and Module.prepend_features, similar
|
||||
to included and append_features.
|
||||
* added Module#refine, which extends a class or module locally.
|
||||
[experimental]
|
||||
* extended method:
|
||||
* Module#define_method accepts a UnboundMethod from a Module.
|
||||
* Module#const_get accepts a qualified constant string, e.g.
|
||||
Object.const_get("Foo::Bar::Baz")
|
||||
|
||||
* Mutex
|
||||
* added method:
|
||||
* added Mutex#owned? which returns the mutex is held by current
|
||||
thread or not. [experimental]
|
||||
* incompatible changes:
|
||||
* Mutex#lock, Mutex#unlock, Mutex#try_lock, Mutex#synchronize
|
||||
and Mutex#sleep are no longer allowed to be used from trap handler
|
||||
and raise a ThreadError in such case.
|
||||
* Mutex#sleep may spurious wakeup. Check after wakeup.
|
||||
|
||||
* NilClass
|
||||
* added method:
|
||||
* added nil.to_h which returns {}
|
||||
|
||||
* ObjectSpace::WeakMap
|
||||
* new low level class to hold weak references to objects.
|
||||
|
||||
* Proc
|
||||
* incompatible change:
|
||||
* removed Proc#== and #eql? so two procs are == only when they are
|
||||
the same object.
|
||||
|
||||
* Process
|
||||
* added method:
|
||||
* added getsid for getting session id (unix only).
|
||||
|
||||
* Range
|
||||
* added method:
|
||||
* added Range#size for lazy size evaluation.
|
||||
* added Range#bsearch for binary search.
|
||||
|
||||
* RubyVM (MRI specific)
|
||||
* added RubyVM::InstructionSequence.of to get the instruction sequence
|
||||
from a method or a block.
|
||||
* added RubyVM::InstructionSequence#path, #absolute_path, #label,
|
||||
#base_label and #first_lineno to retrieve information from where
|
||||
the instruction sequence was defined.
|
||||
* added Environment variables to specify stack usage:
|
||||
* RUBY_THREAD_VM_STACK_SIZE: vm stack size used at thread creation.
|
||||
default: 128KB (32bit CPU) or 256KB (64bit CPU).
|
||||
* RUBY_THREAD_MACHINE_STACK_SIZE: machine stack size used at thread
|
||||
creation. default: 512KB or 1024KB.
|
||||
* RUBY_FIBER_VM_STACK_SIZE: vm stack size used at fiber creation.
|
||||
default: 64KB or 128KB.
|
||||
* RUBY_FIBER_MACHINE_STACK_SIZE: machine stack size used at fiber
|
||||
creation. default: 256KB or 256KB.
|
||||
These variables are checked only at launched time.
|
||||
* added constant DEFAULT_PARAMS to get above default parameters.
|
||||
|
||||
* Signal
|
||||
* added method:
|
||||
* added Signal.signame which returns signal name
|
||||
|
||||
* incompatible changes:
|
||||
* Signal.trap raises ArgumentError when :SEGV, :BUS, :ILL, :FPE, :VTALRM
|
||||
are specified.
|
||||
|
||||
* String
|
||||
* added method:
|
||||
* added String#b returning a copied string whose encoding is ASCII-8BIT.
|
||||
* change return value:
|
||||
* String#lines now returns an array instead of an enumerator.
|
||||
* String#chars now returns an array instead of an enumerator.
|
||||
* String#codepoints now returns an array instead of an enumerator.
|
||||
* String#bytes now returns an array instead of an enumerator.
|
||||
|
||||
* Struct
|
||||
* added method:
|
||||
* added Struct#to_h returning values with keys corresponding to the
|
||||
instance variable names.
|
||||
|
||||
* Thread
|
||||
* added method:
|
||||
* added Thread#thread_variable_get for getting thread local variables
|
||||
(these are different than Fiber local variables).
|
||||
* added Thread#thread_variable_set for setting thread local variables.
|
||||
* added Thread#thread_variables for getting a list of the thread local
|
||||
variable keys.
|
||||
* added Thread#thread_variable? for testing to see if a particular thread
|
||||
variable has been set.
|
||||
* added Thread.handle_interrupt as well as instance and singleton methods
|
||||
pending_interrupt? for asynchronous handling of exceptions
|
||||
* added Thread#backtrace_locations which returns similar information of
|
||||
Kernel#caller_locations.
|
||||
* new class Thread::Backtrace::Location to hold backtrace location
|
||||
information. These are returned by Thread#backtrace_locations and
|
||||
Kernel#caller_locations.
|
||||
* incompatible changes:
|
||||
* Thread#join and Thread#value now raises a ThreadError if target thread
|
||||
is the current or main thread.
|
||||
|
||||
* Time
|
||||
* change return value:
|
||||
* Time#to_s now returns US-ASCII encoding instead of BINARY.
|
||||
|
||||
* TracePoint
|
||||
* new class. This class is replacement of set_trace_func.
|
||||
Easy to use and efficient implementation.
|
||||
|
||||
* toplevel
|
||||
* added method:
|
||||
* added main.define_method which defines a global function.
|
||||
* added main.using, which imports refinements into the current file or
|
||||
eval string. [experimental]
|
||||
|
||||
=== Core classes compatibility issues (excluding feature bug fixes)
|
||||
|
||||
* Array#values_at
|
||||
|
||||
See above.
|
||||
|
||||
* String#lines
|
||||
* String#chars
|
||||
* String#codepoints
|
||||
* String#bytes
|
||||
|
||||
These methods no longer return an Enumerator, although passing a
|
||||
block is still supported for backwards compatibility.
|
||||
|
||||
Code like str.lines.with_index(1) { |line, lineno| ... } no longer
|
||||
works because str.lines returns an array. Replace lines with
|
||||
each_line in such cases.
|
||||
|
||||
* IO#lines
|
||||
* IO#chars
|
||||
* IO#codepoints
|
||||
* IO#bytes
|
||||
* ARGF#lines
|
||||
* ARGF#chars
|
||||
* ARGF#bytes
|
||||
* StringIO#lines
|
||||
* StringIO#chars
|
||||
* StringIO#codepoints
|
||||
* StringIO#bytes
|
||||
* Zlib::GzipReader#lines
|
||||
* Zlib::GzipReader#bytes
|
||||
|
||||
These methods are deprecated in favor of each_line, each_byte,
|
||||
each_char and each_codepoint.
|
||||
|
||||
* Proc#==
|
||||
* Proc#eql?
|
||||
|
||||
These methods were removed. Two procs are == only when they are
|
||||
the same object.
|
||||
|
||||
* Fixnum
|
||||
* Bignum
|
||||
* Float
|
||||
|
||||
Fixnums, Bignums and Floats are frozen.
|
||||
|
||||
* Signal.trap
|
||||
|
||||
See above.
|
||||
|
||||
* Merge Onigmo.
|
||||
https://github.com/k-takata/Onigmo
|
||||
|
||||
* The :close_others option is true by default for system() and exec().
|
||||
Also, the close-on-exec flag is set by default for all new file descriptors.
|
||||
This means file descriptors doesn't inherit to spawned process unless
|
||||
explicitly requested such as system(..., fd=>fd).
|
||||
|
||||
* Kernel#respond_to? against a protected method now returns false
|
||||
unless the second argument is true.
|
||||
|
||||
* Kernel#respond_to_missing?
|
||||
* Kernel#initialize_clone
|
||||
* Kernel#initialize_dup
|
||||
|
||||
These methods are now private.
|
||||
|
||||
* Thread#join, Thread#value
|
||||
|
||||
See above.
|
||||
|
||||
* Mutex#lock, Mutex#unlock, Mutex#try_lock, Mutex#synchronize and Mutex#sleep
|
||||
|
||||
See above.
|
||||
|
||||
=== Stdlib updates (outstanding ones only)
|
||||
|
||||
* cgi
|
||||
* Add HTML5 tag maker.
|
||||
* CGI#header has been renamed to CGI#http_header and
|
||||
aliased to CGI#header.
|
||||
* When HTML5 tagmaker called, overwrite CGI#header,
|
||||
CGI#header function is to create a <header> element.
|
||||
|
||||
* CSV
|
||||
* Removed CSV::dump and CSV::load to protect users from dangerous
|
||||
serialization vulnerability
|
||||
|
||||
* iconv
|
||||
* Iconv has been removed. Use String#encode instead.
|
||||
|
||||
* io/console
|
||||
* new methods:
|
||||
* added IO#cooked which sets the terminal to cooked mode within the given block.
|
||||
* added IO#cooked! which sets the terminal to cooked.
|
||||
* extended method:
|
||||
* IO#raw, IO#raw!, and IO#getch accept keyword arguments, :min and :time.
|
||||
|
||||
* io/wait
|
||||
* new features:
|
||||
* added IO#wait_writable method.
|
||||
* added IO#wait_readable method as alias of IO#wait.
|
||||
|
||||
* json
|
||||
* updated to 1.7.7.
|
||||
|
||||
* net/http
|
||||
* new features:
|
||||
* Proxies are now automatically detected from the http_proxy environment
|
||||
variable. See Net::HTTP::new for details.
|
||||
* gzip and deflate compression are now requested for all requests by
|
||||
default. See Net::HTTP for details.
|
||||
* SSL sessions are now reused across connections for a single instance.
|
||||
This speeds up connection by using a previously negotiated session.
|
||||
* Requests may be created from a URI which sets the request_uri and host
|
||||
header of the request (but does not change the host connected to).
|
||||
* Responses contain the URI requested which allows easier implementation of
|
||||
redirect following.
|
||||
* new methods:
|
||||
* Net::HTTP#local_host
|
||||
* Net::HTTP#local_host=
|
||||
* Net::HTTP#local_port
|
||||
* Net::HTTP#local_port=
|
||||
* extended method:
|
||||
* Net::HTTP#connect uses local_host and local_port if specified.
|
||||
|
||||
* net/imap
|
||||
* new methods:
|
||||
* Net::IMAP.default_port
|
||||
* Net::IMAP.default_imap_port
|
||||
* Net::IMAP.default_tls_port
|
||||
* Net::IMAP.default_ssl_port
|
||||
* Net::IMAP.default_imaps_port
|
||||
|
||||
* objspace
|
||||
* new method:
|
||||
* ObjectSpace.reachable_objects_from(obj)
|
||||
|
||||
* openssl
|
||||
* Consistently raise an error when trying to encode nil values. All instances
|
||||
of OpenSSL::ASN1::Primitive now raise TypeError when calling to_der on an
|
||||
instance whose value is nil. All instances of OpenSSL::ASN1::Constructive
|
||||
raise NoMethodError in the same case. Constructing such values is still
|
||||
permitted.
|
||||
* TLS 1.1 & 1.2 support by setting OpenSSL::SSL::SSLContext#ssl_version to
|
||||
:TLSv1_2, :TLSv1_2_server, :TLSv1_2_client or :TLSv1_1, :TLSv1_1_server
|
||||
:TLSv1_1_client. The version being effectively used can be queried
|
||||
with OpenSSL::SSL#ssl_version. Furthermore, it is also possible to
|
||||
blacklist the new TLS versions with OpenSSL::SSL:OP_NO_TLSv1_1 and
|
||||
OpenSSL::SSL::OP_NO_TLSv1_2.
|
||||
* Added OpenSSL::SSL::SSLContext#renegotiation_cb. A user-defined callback
|
||||
may be set which gets called whenever a new handshake is negotiated. This
|
||||
also allows to programmatically decline (client) renegotiation attempts.
|
||||
* Support for "0/n" splitting of records as BEAST mitigation via
|
||||
OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS.
|
||||
* The default options for OpenSSL::SSL::SSLContext have changed to
|
||||
OpenSSL::SSL::OP_ALL & ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
|
||||
instead of OpenSSL::SSL::OP_ALL only. This enables the countermeasure for
|
||||
the BEAST attack by default.
|
||||
* OpenSSL requires passwords for decrypting PEM-encoded files to be at least
|
||||
four characters long. This led to awkward situations where an export with
|
||||
a password with fewer than four characters was possible, but accessing the
|
||||
file afterwards failed. OpenSSL::PKey::RSA, OpenSSL::PKey::DSA and
|
||||
OpenSSL::PKey::EC therefore now enforce the same check when exporting a
|
||||
private key to PEM with a password - it has to be at least four characters
|
||||
long.
|
||||
* SSL/TLS support for the Next Protocol Negotiation extension. Supported
|
||||
with OpenSSL 1.0.1 and higher.
|
||||
* OpenSSL::OPENSSL_FIPS allows client applications to detect whether OpenSSL
|
||||
is FIPS-enabled. OpenSSL.fips_mode= allows turning on and off FIPS mode
|
||||
manually in order to adapt to situations where FIPS mode would be an
|
||||
explicit requirement.
|
||||
* Authenticated Encryption with Associated Data (AEAD) is supported via
|
||||
Cipher#auth_data= and Cipher#auth_tag/Cipher#auth_tag=.
|
||||
Currently (OpenSSL 1.0.1c), only GCM mode is supported.
|
||||
|
||||
* ostruct
|
||||
* new methods:
|
||||
* OpenStruct#[], []=
|
||||
* OpenStruct#each_pair
|
||||
* OpenStruct#eql?
|
||||
* OpenStruct#hash
|
||||
* OpenStruct#to_h converts the struct to a hash.
|
||||
* extended method:
|
||||
* OpenStruct.new also accepts an OpenStruct / Struct.
|
||||
|
||||
* pathname
|
||||
* extended method:
|
||||
* Pathname#find returns an enumerator if no block is given.
|
||||
|
||||
* rake
|
||||
* rake has been updated to version 0.9.5.
|
||||
|
||||
This version is backwards-compatible with previous rake versions and
|
||||
contains many bug fixes.
|
||||
|
||||
See
|
||||
http://rake.rubyforge.org/doc/release_notes/rake-0_9_5_rdoc.html for a list
|
||||
of changes in rake 0.9.3, 0.9.4 and 0.9.5.
|
||||
|
||||
* RDoc
|
||||
* RDoc has been updated to version 4.0
|
||||
|
||||
This version is largely backwards-compatible with previous rdoc versions.
|
||||
The most notable change is an update to the ri data format (ri data must
|
||||
be regenerated for gems shared across rdoc versions). Further API changes
|
||||
are internal and won't affect most users.
|
||||
|
||||
Notable changes include:
|
||||
|
||||
* Page support for ri. Try `ri ruby:` for a list of pages in ruby or
|
||||
`ri ruby:syntax/literals` for the syntax documentation for literals.
|
||||
|
||||
This also works for gems such as `ri rspec:README` for the rspec gem's
|
||||
README file.
|
||||
* Markdown support. See ri RDoc::Markdown for details.
|
||||
|
||||
See https://github.com/rdoc/rdoc/blob/master/History.rdoc for a full list
|
||||
of changes in rdoc 4.0.
|
||||
|
||||
* resolv
|
||||
* new methods:
|
||||
* Resolv::DNS#timeouts=
|
||||
* Resolv::DNS::Config#timeouts=
|
||||
|
||||
* rexml
|
||||
* REXML::Document#write supports Hash arguments.
|
||||
* REXML::Document#write supports new :encoding option. It changes
|
||||
XML document encoding. Without :encoding option, encoding in
|
||||
XML declaration is used for XML document encoding.
|
||||
|
||||
* RubyGems
|
||||
* Updated to 2.0.0
|
||||
|
||||
RubyGems 2.0.0 features the following improvements:
|
||||
|
||||
* Improved support for default gems shipping with ruby 2.0.0+
|
||||
* A gem can have arbitrary metadata through Gem::Specification#metadata
|
||||
* `gem search` now defaults to --remote and is anchored like gem list.
|
||||
* Added --document to replace --rdoc and --ri. Use --no-document to
|
||||
disable documentation, --document=rdoc to only generate rdoc.
|
||||
* Only ri-format documentation is generated by default.
|
||||
* `gem server` uses RDoc::Servlet from RDoc 4.0 to generate HTML
|
||||
documentation.
|
||||
|
||||
For an expanded list of updates and bug fixes see:
|
||||
https://github.com/rubygems/rubygems/blob/master/History.txt
|
||||
|
||||
* shellwords
|
||||
* Shellwords#shellescape now stringifies the given object using to_s.
|
||||
* Shellwords#shelljoin accepts non-string objects in the given
|
||||
array, each of which is stringified using to_s.
|
||||
|
||||
* stringio
|
||||
* deprecated methods:
|
||||
* StringIO#lines, #bytes, #chars and #codepoints are deprecated.
|
||||
|
||||
* syslog
|
||||
* Added Syslog::Logger which provides a Logger API atop Syslog.
|
||||
* Syslog::Priority, Syslog::Level, Syslog::Option and Syslog::Macros
|
||||
are introduced for easy detection of available constants on a
|
||||
running system.
|
||||
|
||||
* tmpdir
|
||||
* incompatible changes:
|
||||
* Dir.mktmpdir uses FileUtils.remove_entry instead of
|
||||
FileUtils.remove_entry_secure. This means that applications should not
|
||||
change the permission of the created temporary directory to make
|
||||
accessible from other users.
|
||||
|
||||
* yaml
|
||||
* Syck has been removed. YAML now completely depends on libyaml being
|
||||
installed.
|
||||
* libyaml is now bundled with ruby, for cases where the library is not
|
||||
installed locally.
|
||||
|
||||
* zlib
|
||||
* Added streaming support for Zlib::Inflate and Zlib::Deflate. This allows
|
||||
processing of a stream without the use of large amounts of memory.
|
||||
* Added support for the new deflate strategies Zlib::RLE and Zlib::FIXED.
|
||||
* Zlib streams are now processed without the GVL. This allows gzip, zlib and
|
||||
deflate streams to be processed in parallel.
|
||||
* deprecated methods:
|
||||
* Zlib::GzipReader#lines and #bytes are deprecated.
|
||||
|
||||
=== Stdlib compatibility issues (excluding feature bug fixes)
|
||||
|
||||
* OpenStruct new methods can conflict with custom attributes named
|
||||
"each_pair", "eql?", "hash" or "to_h".
|
||||
|
||||
* Dir.mktmpdir in lib/tmpdir.rb
|
||||
|
||||
See above.
|
||||
|
||||
=== C API updates
|
||||
|
||||
* NUM2SHORT() and NUM2USHORT() added. They are similar to NUM2INT, but short.
|
||||
|
||||
* rb_newobj_of() and NEWOBJ_OF() added. They create a new object of a given class.
|
||||
|
459
doc/contributing.rdoc
Normal file
459
doc/contributing.rdoc
Normal file
|
@ -0,0 +1,459 @@
|
|||
= Contributing to Ruby
|
||||
|
||||
Ruby has a vast and friendly community with hundreds of people contributing to
|
||||
a thriving open-source ecosystem. This guide is designed to cover ways for
|
||||
participating in the development of CRuby.
|
||||
|
||||
There are plenty of ways for you to help even if you're not ready to write
|
||||
code or documentation. You can help by reporting issues, testing patches, and
|
||||
trying out beta releases with your applications.
|
||||
|
||||
== How To Report
|
||||
|
||||
If you've encountered a bug in Ruby please report it to the redmine issue
|
||||
tracker available at {bugs.ruby-lang.org}[http://bugs.ruby-lang.org/]. Do not
|
||||
report security vulnerabilities here, there is a {separate
|
||||
channel}[rdoc-label:label-Reporting+Security+Issues] for them.
|
||||
|
||||
There are a few simple steps you should follow in order to receive feedback
|
||||
on your ticket.
|
||||
|
||||
* If you haven't already,
|
||||
{sign up for an account}[https://bugs.ruby-lang.org/account/register] on the
|
||||
bug tracker.
|
||||
* Try the latest version.
|
||||
|
||||
If you aren't already using the latest version, try installing a newer
|
||||
stable release. See
|
||||
{Downloading Ruby}[http://www.ruby-lang.org/en/downloads/].
|
||||
* Look to see if anyone already reported your issue, try
|
||||
{searching on redmine}[https://bugs.ruby-lang.org/projects/ruby-trunk/issues]
|
||||
for your problem.
|
||||
* If you can't find a ticket addressing your issue,
|
||||
{create a new one}[https://bugs.ruby-lang.org/projects/ruby-trunk/issues/new].
|
||||
* Choose the target version, usually current. Bugs will be first fixed in the
|
||||
current release and then {backported}[rdoc-label:label-Backport+Requests].
|
||||
* Fill in the Ruby version you're using when experiencing this issue
|
||||
(<code>ruby -v</code>).
|
||||
* Attach any logs or reproducible programs to provide additional information.
|
||||
Reproducible scripts should be as small as possible.
|
||||
* Briefly describe your problem. A 2-3 sentence description will help give a
|
||||
quick response.
|
||||
* Pick a category, such as core for common problems, or lib for a standard
|
||||
library.
|
||||
* Check the {Maintainers
|
||||
list}[https://bugs.ruby-lang.org/projects/ruby/wiki/Maintainers] and assign
|
||||
the ticket if there is an active maintainer for the library or feature.
|
||||
* If the ticket doesn't have any replies after 10 days, you can send a
|
||||
reminder.
|
||||
* Please reply to feedback requests. If a bug report doesn't get any feedback,
|
||||
it'll eventually get rejected.
|
||||
|
||||
=== Reporting to downstream distributions
|
||||
|
||||
You can reports downstream issues for the following distributions via their bugtracker:
|
||||
|
||||
* {debian}[http://bugs.debian.org/cgi-bin/pkgreport.cgi?src=ruby-defaults]
|
||||
* {freebsd}[http://www.freebsd.org/cgi/query-pr-summary.cgi?text=ruby]
|
||||
* {redhat}[https://bugzilla.redhat.com/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=MODIFIED]
|
||||
* {macports}[http://trac.macports.org/query?status=assigned&status=new&status=reopened&port=~ruby]
|
||||
* etc (add your distribution bug tracker here)
|
||||
|
||||
=== Platform Maintainers
|
||||
|
||||
For platform specific bugs in Ruby, you can assign your ticket the current
|
||||
maintainer for a specific platform.
|
||||
|
||||
The current active platform maintainers are as follows:
|
||||
|
||||
[mswin32, mswin64 (Microsoft Windows)]
|
||||
NAKAMURA Usaku (usa)
|
||||
[mingw32 (Minimalist GNU for Windows)]
|
||||
Nobuyoshi Nakada (nobu)
|
||||
[IA-64 (Debian GNU/Linux)]
|
||||
TAKANO Mitsuhiro (takano32)
|
||||
[Symbian OS]
|
||||
Alexander Zavorine (azov)
|
||||
[AIX]
|
||||
Yutaka Kanemoto (kanemoto)
|
||||
[FreeBSD]
|
||||
Akinori MUSHA (knu)
|
||||
[Solaris]
|
||||
Naohisa Goto (ngoto)
|
||||
[RHEL, CentOS]
|
||||
KOSAKI Motohiro kosaki
|
||||
[Mac OS X]
|
||||
Kenta Murata (mrkn)
|
||||
[cygwin, bcc32, djgpp, wince, ...]
|
||||
none. (Maintainer WANTED)
|
||||
|
||||
== Reporting Security Issues
|
||||
|
||||
Security vulnerabilities receive special treatment since they may negatively
|
||||
affect many users. There is a private mailing list that all security issues
|
||||
should be reported to and will be handled discretely. Email the
|
||||
mailto:security@ruby-lang.org list and the problem will be published after
|
||||
fixes have been released. You can also encrypt the issue using {the PGP public
|
||||
key}[http://www.ruby-lang.org/security.asc] for the list.
|
||||
|
||||
== Reporting Other Issues
|
||||
|
||||
If you're having an issue with the website, or maybe the mailing list, you can
|
||||
contact the webmaster to help resolve the problem.
|
||||
|
||||
The current webmaster is:
|
||||
|
||||
* Hiroshi SHIBATA (hsbt)
|
||||
|
||||
You can also report issues with the ruby-lang.org website on the issue tracker:
|
||||
|
||||
* {issue tracker}[https://github.com/ruby/www.ruby-lang.org/issues]
|
||||
|
||||
== Resolve Existing Issues
|
||||
|
||||
As a next step beyond reporting issues you can help the core team resolve
|
||||
existing issues. If you check the Everyone's Issues list in GitHub Issues,
|
||||
you'll find lots of issues already requiring attention. What can you do for
|
||||
these? Quite a bit, actually:
|
||||
|
||||
When a bug report goes for a while without any feedback, it goes to the bug
|
||||
graveyard which is unfortunate. If you check the {issues
|
||||
list}[https://bugs.ruby-lang.org/projects/ruby-trunk/issues] you'll find lots
|
||||
of delinquent bugs that require attention.
|
||||
|
||||
You can help by verifying the existing tickets, try to reproduce the reported
|
||||
issue on your own and comment if you still experience the bug. Some issues
|
||||
lack attention because of too much ambiguity, to help you can narrow down the
|
||||
problem and provide more specific details or instructions to reproduce the
|
||||
bug. You might also try contributing a failing test in the form of a patch,
|
||||
which we will cover later in this guide.
|
||||
|
||||
It may also help to try out patches other contributors have submitted to
|
||||
redmine, if gone without notice. In this case the +patch+ command is your
|
||||
friend, see <code>man patch</code> for more information. Basically this would
|
||||
go something like this:
|
||||
|
||||
cd path/to/ruby/trunk
|
||||
patch -p0 < path/to/patch
|
||||
|
||||
You will then be prompted to apply the patch with the associated files. After
|
||||
building ruby again, you should try to run the tests and verify if the change
|
||||
actually worked or fixed the bug. It's important to provide valuable feedback
|
||||
on the patch that can help reach the overall goal, try to answer some of these
|
||||
questions:
|
||||
|
||||
* What do you like about this change?
|
||||
* What would you do differently?
|
||||
* Are there any other edge cases not tested?
|
||||
* Is there any documentation that would be affected by this change?
|
||||
|
||||
If you can answer some or all of these questions, you're on the right track.
|
||||
If your comment simply says "+1", then odds are that other reviewers aren't
|
||||
going to take it too seriously. Show that you took the time to review the
|
||||
patch.
|
||||
|
||||
== How To Request Features
|
||||
|
||||
If there's a new feature that you want to see added to Ruby, you'll need to
|
||||
write a convincing proposal and patch to implement the feature.
|
||||
|
||||
For new features in CRuby, use the {'Feature'
|
||||
tracker}[https://bugs.ruby-lang.org/projects/ruby-trunk/issues?set_filter=1&tracker_id=2]
|
||||
on ruby-trunk. For non-CRuby dependent features, features that would apply to
|
||||
alternate Ruby implementations such as JRuby and Rubinius, use the {CommonRuby
|
||||
tracker}[https://bugs.ruby-lang.org/projects/common-ruby].
|
||||
|
||||
When writing a proposal be sure to check for previous discussions on the
|
||||
topic and have a solid use case. You will need to be persuasive and convince
|
||||
Matz on your new feature. You should also consider the potential compatibility
|
||||
issues that this new feature might raise.
|
||||
|
||||
Consider making your feature into a gem, and if there are enough people who
|
||||
benefit from your feature it could help persuade ruby-core. Although feature
|
||||
requests can seem like an alluring way to contribute to Ruby, often these
|
||||
discussions can lead nowhere and exhaust time and energy that could be better
|
||||
spent fixing bugs. Choose your battles.
|
||||
|
||||
A good template for feature proposal should look something like this:
|
||||
|
||||
[Abstract]
|
||||
Summary of your feature
|
||||
[Background]
|
||||
Describe current behavior and why it is problem. Related work, such as
|
||||
solutions in other language helps us to understand the problem.
|
||||
[Proposal]
|
||||
Describe your proposal in details
|
||||
[Details]
|
||||
If it has complicated feature, describe it
|
||||
[Usecase]
|
||||
How would your feature be used? Who will benefit from it?
|
||||
[Discussion]
|
||||
Discuss about this proposal. A list of pros and cons will help start
|
||||
discussion.
|
||||
[Limitation]
|
||||
Limitation of your proposal
|
||||
[Another alternative proposal]
|
||||
If there are alternative proposals, show them.
|
||||
[See also]
|
||||
Links to the other related resources
|
||||
|
||||
=== Slideshow
|
||||
|
||||
On Ruby Developer Meeting Japan, committers discuss about Feature Proposals together at Tokyo. We'll judge proposals accept, reject, or feedback. If you have a stalled proposal, making a slide to submit is good way to get feedback.
|
||||
|
||||
Slides should be:
|
||||
|
||||
* One-page slide
|
||||
* Include a corresponding ticket number
|
||||
* MUST include a figure and/or short example code
|
||||
* SHOULD have less sentence in natural language (try to write less than 140 characters)
|
||||
* It is RECOMMENDED to itemize: motivation/use case, proposal, pros/cons, corner case
|
||||
* PDF or Image (Web browsers can show it)
|
||||
|
||||
Please note:
|
||||
|
||||
* Even if the proposal is generally acceptable, it won't be accepted without writing corner cases in the ticket
|
||||
* Slide's example: DevelopersMeeting20130727Japan
|
||||
|
||||
== Backport Requests
|
||||
|
||||
When a new version of Ruby is released it starts at patch level 0 (p0), and
|
||||
bugs will be fixed first on the trunk branch. If its determined that a bug
|
||||
exists in a previous version of Ruby that is still in the bug fix stage of
|
||||
maintenance, then a patch will be backported. After the maintenance stage of a
|
||||
particular Ruby version ends, it goes into "security fix only" mode which
|
||||
means only security related vulnerabilities will be backported. Versions in
|
||||
End-of-life (EOL) will not receive any updates and it is recommended you
|
||||
upgrade as soon as possible.
|
||||
|
||||
If a major security issue is found or after a certain amount of time since the
|
||||
last patch level release, a new patch-level release will be made.
|
||||
|
||||
When submitting a backport request please confirm the bug has been fixed in
|
||||
newer versions and exists in maintenance mode versions. There is a backport
|
||||
tracker for each major version still in maintenance where you can request a
|
||||
particular revision merged in the affected version of Ruby.
|
||||
|
||||
Each major version of Ruby has a release manager that should be assigned to
|
||||
handle backport requests. You can find the list of release managers on the
|
||||
{wiki}[https://bugs.ruby-lang.org/projects/ruby/wiki/ReleaseEngineering].
|
||||
|
||||
=== Branch Maintainers
|
||||
|
||||
A branch maintainer maintains a branch and releases a new release of Ruby. The
|
||||
branch depends on the associated version of Ruby, such as ruby_1_8_7 for
|
||||
version 1.8.7. The current branch maintainers are as follows:
|
||||
|
||||
[trunk]
|
||||
unnecessary
|
||||
[ruby_2_0_0]
|
||||
Chikanaga Tomoyuki (nagachika)
|
||||
[ruby_1_9_3]
|
||||
NAKAMURA Usaku (usa)
|
||||
[ruby_1_9_2, ruby_1_9_1]
|
||||
_unmaintained_
|
||||
[ruby_1_8]
|
||||
_unmaintained_
|
||||
[ruby_1_8_7]
|
||||
_unmaintained_
|
||||
[ruby_1_8_6 ...]
|
||||
_unmaintained_
|
||||
|
||||
== Running tests
|
||||
|
||||
In order to help resolve existing issues and contributing patches to Ruby you
|
||||
need to be able to run the test suite.
|
||||
|
||||
CRuby uses subversion for source control, you can find installation
|
||||
instructions and lots of great info to learn subversion on the
|
||||
{svnbook.red-bean.com}[http://svnbook.red-bean.com/]. For other resources see
|
||||
the {ruby-core documentation on
|
||||
ruby-lang.org}[http://www.ruby-lang.org/en/community/ruby-core/].
|
||||
|
||||
This guide will use git for contributing. The {git
|
||||
homepage}[http://git-scm.com/] has installation instructions with links to
|
||||
documentation for learning more about git. There is a mirror of the subversion
|
||||
repository on {github}[https://github.com/ruby/ruby].
|
||||
|
||||
Install the prerequisite dependencies for building the CRuby interpreter to
|
||||
run tests.
|
||||
|
||||
* C compiler
|
||||
* autoconf
|
||||
* bison
|
||||
* gperf
|
||||
* ruby - Ruby itself is prerequisite in order to build Ruby from source. It
|
||||
can be 1.8.
|
||||
|
||||
You should also have access to development headers for the following
|
||||
libraries, but these are not required:
|
||||
|
||||
* Tcl/Tk
|
||||
* NDBM/QDBM
|
||||
* GDBM
|
||||
* OpenSSL
|
||||
* readline/editline(libedit)
|
||||
* zlib
|
||||
* libffi
|
||||
* libyaml
|
||||
* libexecinfo (FreeBSD)
|
||||
|
||||
Now let's build CRuby:
|
||||
|
||||
* Checkout the CRuby source code:
|
||||
|
||||
git clone git://github.com/ruby/ruby.git ruby-trunk
|
||||
|
||||
* Generate the configuration files and build:
|
||||
|
||||
cd ruby-trunk
|
||||
autoconf
|
||||
mkdir build && cd build # its good practice to build outside of source dir
|
||||
mkdir ~/.rubies # we will install to .rubies/ruby-trunk in our home dir
|
||||
../configure --prefix=~/.rubies/ruby-trunk
|
||||
make && make install
|
||||
|
||||
After adding Ruby to your PATH, you should be ready to run the test suite:
|
||||
|
||||
make test
|
||||
|
||||
You can also use +test-all+ to run all of the tests with the RUNRUBY
|
||||
interpreter just built. Use TESTS or RUNRUBYOPT to pass parameters, such as:
|
||||
|
||||
make test-all TESTS=-v
|
||||
|
||||
This is also how you can run a specific test from our build dir:
|
||||
|
||||
make test-all TESTS=drb/test_drb.rb
|
||||
|
||||
For older versions of Ruby you'll need to run the build setup again after
|
||||
checking out the associated branch in git, for example if you wanted to
|
||||
checkout 1.9.3:
|
||||
|
||||
git clone git://github.com/ruby/ruby.git --branch ruby_1_9_3
|
||||
|
||||
== Contributing Documentation
|
||||
|
||||
If you're interested in contributing documentation directly to CRuby there is
|
||||
a wealth of information available at
|
||||
{documenting-ruby.org}[http://documenting-ruby.org/].
|
||||
|
||||
There is also the {Ruby Reference
|
||||
Manual}[https://bugs.ruby-lang.org/projects/rurema] in Japanese.
|
||||
|
||||
== Contributing A Patch
|
||||
|
||||
=== Deciding what to patch
|
||||
|
||||
Before you submit a patch, there are a few things you should know:
|
||||
|
||||
* Pay attention to the maintenance policy for stable and maintained versions of Ruby.
|
||||
* Released versions in security mode will not merge feature changes.
|
||||
* Search for previous discussions on ruby-core to verify the maintenance policy
|
||||
* Patches must be distributed under Ruby's license.
|
||||
* This license may change in the future, you must join the discussion if you don't agree to the change
|
||||
|
||||
To improve the chance your patch will be accepted please follow these simple rules:
|
||||
|
||||
* Bug fixes should be committed on trunk first
|
||||
* Format of the patch file must be a unified diff (ie: diff -pu, svn diff, or git diff)
|
||||
* Don't introduce cosmetic changes
|
||||
* Follow the original coding style of the code
|
||||
* Don't mix different changes in one commit
|
||||
|
||||
First thing you should do is check out the code if you haven't already:
|
||||
|
||||
git clone git://github.com/ruby/ruby.git ruby-trunk
|
||||
|
||||
Now create a dedicated branch:
|
||||
|
||||
cd ruby-trunk
|
||||
git checkout -b my_new_branch
|
||||
|
||||
The name of your branch doesn't really matter because it will only exist on
|
||||
your local computer and won't be part of the official Ruby repository. It will
|
||||
be used to create patches based on the differences between your branch and
|
||||
trunk, or edge Ruby.
|
||||
|
||||
=== Coding style
|
||||
|
||||
Here are some general rules to follow when writing Ruby and C code for CRuby:
|
||||
|
||||
* Indent 4 spaces for C with tabs for eight-space indentation (emacs default)
|
||||
* Indent 2 space tabs for Ruby
|
||||
* Do not use TABs in ruby codes
|
||||
* ANSI C style for 1.9+ for function declarations
|
||||
* Follow C90 (not C99) Standard
|
||||
* PascalStyle for class/module names.
|
||||
* UNDERSCORE_SEPARATED_UPPER_CASE for other constants.
|
||||
* Capitalize words.
|
||||
* ABBRs should be all upper case.
|
||||
* Do as others do
|
||||
|
||||
=== ChangeLog
|
||||
|
||||
Although not required, if you wish to add a ChangeLog entry for your change
|
||||
please note:
|
||||
|
||||
You can use the following template for the ChangeLog entry on your commit:
|
||||
|
||||
Thu Jan 1 00:00:00 2004 Your Name <yourmail@example.com>
|
||||
|
||||
* filename (function): short description of this commit.
|
||||
This should include your intention of this change.
|
||||
[bug:#number] [mailinglist:number]
|
||||
|
||||
* filename2 (function2): additional description for this file/function.
|
||||
|
||||
This follows {GNU Coding Standards for Change
|
||||
Logs}[http://www.gnu.org/prep/standards/html_node/Change-Logs.html#Change-Logs],
|
||||
some other requirements and tips:
|
||||
|
||||
* Timestamps must be in JST (+09:00) in the style as above.
|
||||
* Two spaces between the timestamp and your name. Two spaces between
|
||||
your name and your mail address.
|
||||
* One blank line between the timestamp and the description.
|
||||
* Indent the description with TAB. 2nd line should begin with TAB+2SP.
|
||||
* Write a entry (*) for each change.
|
||||
* Refer to redmine issue or discussion on the mailing list.
|
||||
* For GitHub issues, use [GH-#] (such as [Fixes GH-234]
|
||||
* One blank line between entries.
|
||||
* Do as other committers do.
|
||||
|
||||
You can generate the ChangeLog entry by running <code>make change</code>
|
||||
|
||||
When you're ready to commit, copy your ChangeLog entry into the commit message,
|
||||
keeping the same formatting and select your files:
|
||||
|
||||
git commit ChangeLog path/to/files
|
||||
|
||||
In the likely event that your branch becomes outdated, you will have to update
|
||||
your working branch:
|
||||
|
||||
git fetch origin
|
||||
git rebase remotes/origin/master
|
||||
|
||||
Now that you've got some code you want to contribute, let's get set up to
|
||||
generate a patch. Start by forking the github mirror, check the {github docs on
|
||||
forking}[https://help.github.com/articles/fork-a-repo] if you get stuck here.
|
||||
here. You will also need a github account if you don't yet have one.
|
||||
|
||||
Next copy the writable url for your fork and add it as a git remote, replace
|
||||
"my_username" with your github account name:
|
||||
|
||||
git remote add my_fork git@github.com:my_username/ruby.git
|
||||
# Now we can push our branch to our fork
|
||||
git push my_fork my_new_branch
|
||||
|
||||
In order to generate a patch that you can upload to the bug tracker, we can use
|
||||
the github interface to review our changes just visit
|
||||
https://github.com/my_username/ruby/compare/trunk...my_new_branch
|
||||
|
||||
Next, you can simply add '.patch' to the end of this URL and it will generate
|
||||
the patch for you, save the file to your computer and upload it to the bug
|
||||
tracker. Alternatively you can submit a pull request, but for the best chances
|
||||
to receive feedback add it is recommended you add it to redmine.
|
||||
|
||||
|
||||
|
||||
|
778
doc/contributors.rdoc
Normal file
778
doc/contributors.rdoc
Normal file
|
@ -0,0 +1,778 @@
|
|||
= Contributors to Ruby
|
||||
|
||||
The following list might be imcomplete. Feel free to add your name if your
|
||||
patch was accepted into Ruby.
|
||||
|
||||
== A
|
||||
|
||||
Ayumu AIZAWA (ayumin)
|
||||
* committer
|
||||
|
||||
AKIYOSHI, Masamichi (akiyoshi)
|
||||
* committer
|
||||
* He had maintained the VMS support on 2003-2004.
|
||||
|
||||
Muhammad Ali
|
||||
* wrote rdoc for Fiber
|
||||
|
||||
Minero Aoki (aamine)
|
||||
* committer
|
||||
* He is the maintainer of:
|
||||
* fileutils
|
||||
* net/http, net/https
|
||||
* net/pop
|
||||
* net/smtp
|
||||
* racc
|
||||
* ripper
|
||||
* strscan
|
||||
|
||||
Wakou Aoyama (wakou)
|
||||
* committer
|
||||
* He was the maintainer of some standard libraries.
|
||||
|
||||
Koji Arai
|
||||
* committer
|
||||
|
||||
arton
|
||||
* He is the distributor of ActiveScriptRuby and experimental 1.9.0-x installers for win32.
|
||||
* Wrote patches for win32ole, gc.c, tmpdir.rb
|
||||
|
||||
== B
|
||||
|
||||
Daniel Berger
|
||||
* a patch for irb
|
||||
* documentation
|
||||
* He wrote forwardable.rb
|
||||
|
||||
David Black (dblack)
|
||||
* committer
|
||||
* He is the maintainer of scanf
|
||||
|
||||
Ken Bloom
|
||||
* a patch for REXML.
|
||||
|
||||
Oliver M. Bolzer
|
||||
* a patch for soap
|
||||
|
||||
Alexey Borzenkov
|
||||
* a patch for mkmf.rb
|
||||
|
||||
Richard Brown
|
||||
* a patch for configure.in
|
||||
|
||||
Dirkjan Bussink
|
||||
* a patch for date.rb
|
||||
|
||||
Daniel Bovensiepen
|
||||
* documentation
|
||||
* a patch for irb
|
||||
|
||||
== C
|
||||
|
||||
Brian Candler
|
||||
* a patch for configure.in, net/telnet
|
||||
|
||||
keith cascio
|
||||
* a patch for optparse.rb
|
||||
|
||||
Frederick Cheung
|
||||
* a patch for test/ruby/test_symbol.rb
|
||||
|
||||
Christoph
|
||||
* patches for set.rb
|
||||
|
||||
Sean Chittenden
|
||||
* pathces for net/http, cgi
|
||||
|
||||
William D. Clinger
|
||||
* ruby_strtod is based on his paper.
|
||||
|
||||
== D
|
||||
|
||||
Ryan Davis (ryan)
|
||||
* committer
|
||||
* He wrote and is the maintainer of miniunit
|
||||
|
||||
Guy Decoux (ts)
|
||||
* committer
|
||||
|
||||
Zach Dennis
|
||||
|
||||
Martin Duerst (duerst)
|
||||
* committer
|
||||
* M17N
|
||||
|
||||
Paul Duncan
|
||||
* pathces for rdoc
|
||||
|
||||
Alexander Dymo
|
||||
* a patch for lib/benchmark.rb
|
||||
|
||||
== E
|
||||
|
||||
Yusuke Endoh (mame)
|
||||
* committer
|
||||
* He wrote and is the maintainer of base64 library (1.9)
|
||||
* did much upon YARV compiler.
|
||||
|
||||
erlercw
|
||||
* wrote Integer::gcd2
|
||||
|
||||
== F
|
||||
|
||||
Frank S.Fejes
|
||||
* a patch for net/pop
|
||||
|
||||
Fundakowski Feldman
|
||||
* a patch for process.c
|
||||
|
||||
Mauricio Fernandez
|
||||
* patches for parse.y
|
||||
|
||||
David Flanagan (davidflanagan)
|
||||
* committer
|
||||
* M17N
|
||||
|
||||
Takeyuki Fujioka (xibbar)
|
||||
* committer
|
||||
* He is the maintainer of cgi/*
|
||||
|
||||
FUKUMOTO, Atsushi
|
||||
* a patch for tracer.rb
|
||||
|
||||
Shota Fukumori (sorah)
|
||||
* committer
|
||||
* #4415 parallel unit/test
|
||||
|
||||
Tadayoshi Funaba (tadf)
|
||||
* committer
|
||||
* He wrote and is the maintainer of
|
||||
* date
|
||||
* parsedate (1.8)
|
||||
* He ported rational.rb and complex.rb, which 1.8 contains, into rational.c and complex.c of 1.9.
|
||||
|
||||
== G
|
||||
|
||||
David M. Gay
|
||||
* ruby_strtod
|
||||
|
||||
Florian Gilcher
|
||||
* documentation
|
||||
|
||||
GOTOU, Kentaro (gotoken)
|
||||
* committer
|
||||
* He wrote benchmark.rb
|
||||
* He is the maintainer of:
|
||||
* benchmark.rb
|
||||
* open3
|
||||
|
||||
GOTOU, Yuuzou (gotoyuzo)
|
||||
* committer
|
||||
|
||||
James Edward Gray II (jeg2)
|
||||
* committer
|
||||
* He wrote the faster implementation of CSV and is the maintainer of csv.
|
||||
* Wrote documentation for rdoc
|
||||
|
||||
== H
|
||||
|
||||
Phil Hagelberg
|
||||
* patch for ruby-mode.el's documentation.
|
||||
|
||||
Kirk Haines (wyhaines)
|
||||
* committer
|
||||
* the maintainer of ruby_1_8_6 branch
|
||||
|
||||
Shinichiro Hamaji
|
||||
* fixed memory leaks (marshal.c, string.c)
|
||||
|
||||
Shin-ichiro HARA
|
||||
* the developer and the sysop of ruby-{dev,list,core,talk} archive.
|
||||
* a patch for numeric.c
|
||||
|
||||
Chris Heath (traumdeutung)
|
||||
* a patch for proc.c
|
||||
|
||||
HIROKAWA Hisashi
|
||||
* fixed socket/socket.c
|
||||
|
||||
Daniel Hob
|
||||
* He wrote:
|
||||
* SMTP-TLS support for net/smtp.
|
||||
* POP3S support
|
||||
|
||||
Eric Hodel (drbrain)
|
||||
* committer
|
||||
* He is the maintainer of:
|
||||
* rdoc
|
||||
* ri
|
||||
* rubygems
|
||||
|
||||
Erik Hollensbe
|
||||
* a patch for delegate.rb
|
||||
|
||||
Johan Holmberg
|
||||
* a patch for dir.c
|
||||
* documentation
|
||||
|
||||
Erik Huelsmann
|
||||
|
||||
Dae San Hwang
|
||||
* built a continuous integration environment on OpenSolaris.
|
||||
|
||||
== I
|
||||
|
||||
Nobuhiro IMAI
|
||||
* a patch for logger.rb
|
||||
|
||||
"incorporate"
|
||||
* a patch for sprintf.c
|
||||
|
||||
Keiju Ishitsuka (keiju)
|
||||
* committer
|
||||
* He wrote and is the maintainer of:
|
||||
* cmath.rb (1.9)
|
||||
* complex.rb (1.8)
|
||||
* e2mmap.rb
|
||||
* forwardable.rb
|
||||
* irb
|
||||
* mathn
|
||||
* matrix.rb
|
||||
* mutex_m.rb
|
||||
* rational.rb (1.8)
|
||||
* sync.rb
|
||||
* shell/*
|
||||
* thwait.rb
|
||||
* tracer.rb
|
||||
|
||||
== J
|
||||
|
||||
Curtis Jackson
|
||||
* missing/dup2.c
|
||||
|
||||
Alan Johnson
|
||||
* a patch for net/ftp
|
||||
|
||||
Lyle Johnson
|
||||
* patches for nkf, bigdecimal, numeric.c
|
||||
|
||||
== K
|
||||
|
||||
Yoshihiro Kambayashi
|
||||
* a patch for enc/trans/single_byte.trans.
|
||||
* He wrote supports for some encodings.
|
||||
|
||||
Yutaka Kanemoto
|
||||
* patches for common.mk, AIX AF_INET6 support
|
||||
|
||||
Motoyuki Kasahara
|
||||
* He wrote getoptlong.rb
|
||||
|
||||
Masahiro Kawato
|
||||
* a patch for shellwords.rb
|
||||
|
||||
Wataru Kimura
|
||||
* a patch for configure.in
|
||||
|
||||
Michael Klishin
|
||||
* patch for make help.
|
||||
|
||||
Noritada Kobayashi
|
||||
* a patch for optparse.rb
|
||||
|
||||
Shigeo Kobayashi (shigek)
|
||||
* committer
|
||||
* He is the maintainer of bigdecimal
|
||||
|
||||
KONISHI, Hiromasa (H_Konishi)
|
||||
* committer
|
||||
* He had maintained the bcc32 support in 2004.
|
||||
|
||||
Kornelius "murphy" Kalnbach
|
||||
* documentation
|
||||
|
||||
K.Kosako (kosako)
|
||||
* committer
|
||||
* He wrote Oniguruma.
|
||||
|
||||
Takehiro Kubo
|
||||
* patches for dl 64bit support.
|
||||
|
||||
== L
|
||||
|
||||
Marc-Andre Lafortune (marcandre)
|
||||
* committer
|
||||
* patches for hash.c, array.c, thread.c, enumc, string.c, range.c and rdoc documentation.
|
||||
|
||||
Hongli Lai
|
||||
* improved pstore.rb
|
||||
* patch for tool/file2lastrev.rb.
|
||||
|
||||
raspberry lemon
|
||||
* a patch for webrick/httpproxy.rb.
|
||||
|
||||
Christian Loew
|
||||
* a patch for fileutils.rb
|
||||
|
||||
== M
|
||||
|
||||
Shugo Maeda (shugo)
|
||||
* committer
|
||||
* A system administrator of ruby-lang.org servers.
|
||||
* He wrote and is the maintainer of:
|
||||
* monitor.rb
|
||||
* net/ftp
|
||||
* net/imap
|
||||
|
||||
Stephan Maka (mathew)
|
||||
* documentation
|
||||
|
||||
Yukihiro Matsumoto (matz)
|
||||
* Matz -- the founder, language designer of Ruby.
|
||||
* committer
|
||||
* Ruby itself, most of Ruby.
|
||||
* He is the maintainer of:
|
||||
* singleton
|
||||
* timeout
|
||||
* gdbm
|
||||
* sdbm
|
||||
|
||||
Konrad Meyer
|
||||
* documentation
|
||||
|
||||
Mib Software
|
||||
* missing/vsnprintf.c
|
||||
|
||||
Todd C. Miller
|
||||
* missing/strlcat.c
|
||||
* missing/strlcpy.c
|
||||
|
||||
MIYASAKA, Masaru
|
||||
* a patch for cgi.rb
|
||||
|
||||
Stefan Monnier
|
||||
* regex.c was fixed with based on his Emacs21 patch.
|
||||
|
||||
Marcel Moolenaar
|
||||
* patches for eval.c and gc.c.
|
||||
|
||||
moonwolf
|
||||
* a patch for REXML, xmlrpc
|
||||
|
||||
Hiroshi Moriyama
|
||||
* a patch for yaml.
|
||||
|
||||
Kyosuke Morohashi
|
||||
* a patch for gem_prelude.rb
|
||||
|
||||
Kenta Murata
|
||||
* patches for json, bignum.c
|
||||
|
||||
Akinori MUSHA (knu)
|
||||
* committer
|
||||
* He wrote and is the maintainer of:
|
||||
* abbrev.rb
|
||||
* generator (1.8)
|
||||
* enumerator (1.8)
|
||||
* set
|
||||
* ipaddr.rb
|
||||
* digest/*
|
||||
* syslog
|
||||
* He is the branch maintainer of ruby_1_8, the release manager of 1.8 series.
|
||||
|
||||
== N
|
||||
|
||||
Hidetoshi NAGAI (nagai)
|
||||
* committer
|
||||
* He is the maintainer of tk/*
|
||||
|
||||
Nobuyoshi Nakada (nobu)
|
||||
* committer
|
||||
* a.k.a. the "patch monster"
|
||||
* He wrote and is the maintainer of:
|
||||
* optparse
|
||||
* stringio
|
||||
* io/wait
|
||||
* iconv
|
||||
|
||||
Satoshi Nakagawa
|
||||
* patches for util.c
|
||||
|
||||
Narihiro Nakamura (nari)
|
||||
* committer
|
||||
* a.k.a. authorNari
|
||||
* working at GC
|
||||
|
||||
NAKAMURA, Hiroshi (nahi)
|
||||
* committer
|
||||
* He is the maintainer of:
|
||||
* csv.rb (1.8)
|
||||
* logger.rb
|
||||
* soap/* (1.8)
|
||||
* wsdl/* (1.8)
|
||||
* xsd/* (1.8)
|
||||
|
||||
NAKAMURA, Usaku (usa)
|
||||
* committer
|
||||
* a.k.a. unak
|
||||
* He is the maintainer of mswin32 and mswin64 support.
|
||||
|
||||
NARUSE, Yui (naruse)
|
||||
* committer
|
||||
* a.k.a. "nurse"
|
||||
* Did much upon m17n.
|
||||
* He is the maintainer of:
|
||||
* json
|
||||
* nkf
|
||||
|
||||
Christian Neukirchen
|
||||
* a patch for webrick/httputils
|
||||
|
||||
Michael Neumann (mneumann)
|
||||
* committer
|
||||
* He is the maintainer of
|
||||
* xmlrpc (1.8)
|
||||
* gserver (1.8)
|
||||
|
||||
NISHIO Hirokazu
|
||||
* wrote a patch for CVE-2010-0541
|
||||
|
||||
Kazuhiro NISHIYAMA (kazu)
|
||||
* committer
|
||||
* a.k.a. znz
|
||||
|
||||
Go Noguchi
|
||||
|
||||
Martin Nordholts
|
||||
* misc/rdebug.el
|
||||
|
||||
nmu
|
||||
* a patch for socket
|
||||
|
||||
== O
|
||||
|
||||
okkez
|
||||
* He is a sysop of the Ruby Reference Manual Renewal Project.
|
||||
* fixed ipaddr.rb, ext/etc
|
||||
|
||||
Haruhiko Okumura
|
||||
* some of missing/* is based on his book:
|
||||
* missing/erf.c
|
||||
* missing/lgamma_r.c
|
||||
* missing/tgamma.c
|
||||
|
||||
OMAE, jun
|
||||
* a patch for debug.rb
|
||||
|
||||
Eugene Ossintsev
|
||||
* documentation
|
||||
|
||||
== P
|
||||
|
||||
Heesob Park
|
||||
* a patch for win32/win32.c.
|
||||
|
||||
pegacorn
|
||||
* a patch for instruby.rb
|
||||
|
||||
== Q
|
||||
|
||||
== R
|
||||
|
||||
Gaston Ramos
|
||||
* documentation
|
||||
|
||||
The Regents of the University of California
|
||||
* missing/crypt.c
|
||||
* missing/vsnprintf.c
|
||||
|
||||
Sam Roberts
|
||||
* patch for socket
|
||||
* documentation
|
||||
|
||||
Michal Rokos (michal)
|
||||
* committer
|
||||
* He was the maintainer of DJGPP support.
|
||||
|
||||
rubikitch
|
||||
* a patch for io.c
|
||||
|
||||
Marcus Rueckert
|
||||
* a patch for mkconfig.rb.
|
||||
|
||||
Run Paint Run Run
|
||||
* patch for enc/unicode.c
|
||||
* documentation
|
||||
|
||||
Sean Russell (ser)
|
||||
* committer
|
||||
* He wrote and is the maintainer of REXML.
|
||||
|
||||
== S
|
||||
|
||||
Kazuo Saito (ksaito)
|
||||
* committer
|
||||
* M17N
|
||||
|
||||
Tadashi Saito
|
||||
* patches for test/ruby/test_math.rb, thread_*.c, bignum.c
|
||||
* working upon BigDecimal.
|
||||
* did much upon documentation
|
||||
|
||||
Masahiro Sakai
|
||||
* a patch for io.c
|
||||
|
||||
Laurent Sansonetti
|
||||
* a patch for tool/ytab.sed
|
||||
|
||||
Jeff Saracco
|
||||
* documentation
|
||||
|
||||
Koichi Sasada (ko1)
|
||||
* committer
|
||||
* He wrote YARV.
|
||||
|
||||
Hugh Sasse
|
||||
* a patch for net/http
|
||||
* documentation
|
||||
|
||||
Charlie Savage
|
||||
* a patch for win32/Makefile.sub
|
||||
|
||||
Michael Scholz
|
||||
* a patch for ruby-mode.el
|
||||
|
||||
Arthur Schreiber
|
||||
* patch for net/http and rdoc.
|
||||
|
||||
Masatoshi SEKI (seki)
|
||||
* committer
|
||||
* He wrote and is the maintainer of:
|
||||
* drb/*
|
||||
* erb
|
||||
* rinda
|
||||
|
||||
Roman Shterenzon
|
||||
* a patch for open-uri.
|
||||
|
||||
Kent Sibilev
|
||||
|
||||
Gavin Sinclair (gsinclair)
|
||||
* committer
|
||||
|
||||
John W. Small
|
||||
* He wrote gserver.rb
|
||||
|
||||
Yuki Sonoda (yugui)
|
||||
* committer
|
||||
* She is the maintainer of man/* manual pages and is the release manager of 1.9 series.
|
||||
* She wrote prime.rb.
|
||||
* A developer and a sysop of redmine.ruby-lang.org.
|
||||
|
||||
SOUMA, Yutaka
|
||||
* a patch for pack.c.
|
||||
|
||||
Tatsuki Sugiura
|
||||
* WebDAV support for net/http
|
||||
|
||||
Masaki Suketa (suke)
|
||||
* committer
|
||||
* He is the maintainer of win32ole
|
||||
|
||||
sheepman
|
||||
* patches for ruby.c, thread.c, stringio, enum.c, webrick, net/http
|
||||
|
||||
Siena. (siena)
|
||||
* committer
|
||||
|
||||
Kirill A. Shutemov
|
||||
* a patch for parse.y
|
||||
|
||||
Darren Smith
|
||||
* a patch for golf_prelude.rb
|
||||
|
||||
Richard M. Stallman
|
||||
* missing/alloca.c
|
||||
|
||||
Robin Stocker
|
||||
* documentation
|
||||
|
||||
Adam Strzelecki
|
||||
* a patch for compile.c
|
||||
|
||||
Masashi Sumi
|
||||
* improved net/pop.rb
|
||||
|
||||
Eric Sunshine
|
||||
* NeXT OpenStep, Rhapsody support
|
||||
|
||||
Kouhei Sutou (kou)
|
||||
* committer
|
||||
* He wrote and is the maintainer of rss/*
|
||||
|
||||
David Symonds
|
||||
* documentation
|
||||
|
||||
== T
|
||||
|
||||
TAKANO Mitsuhiro (takano32)
|
||||
* committer
|
||||
* He is the maintainer of IA-64 support.
|
||||
* BigDecimal
|
||||
|
||||
TAKAO, Kouji (kouji)
|
||||
* committer
|
||||
* He is the maintainer of readline.
|
||||
|
||||
Nathaniel Talbott (ntalbott)
|
||||
* committer
|
||||
* He was the maintainer of test/unit, runit, rubyunit.
|
||||
|
||||
TANAKA, Akira (akr)
|
||||
* committer
|
||||
* Did much upon m17n.
|
||||
* And he is the maintainer of:
|
||||
* open-uri
|
||||
* pathname
|
||||
* pp
|
||||
* resolv-replace
|
||||
* resolv
|
||||
* time
|
||||
* tsort
|
||||
|
||||
Takaaki Tateishi (ttate)
|
||||
* committer
|
||||
* He was the maintainer of dl
|
||||
|
||||
Technorama Ltd. (technoroma)
|
||||
* committer
|
||||
* openssl
|
||||
|
||||
Andrew Thompson
|
||||
* a patch for socket.c IRIX support.
|
||||
|
||||
Dave Thomas (dave)
|
||||
* committer
|
||||
* a.k.a. the Pragmatic Programmer.
|
||||
* He wrote rdoc.
|
||||
|
||||
Tietew
|
||||
* patches for win32 support
|
||||
|
||||
Masahiro Tomita
|
||||
* a patch for cgi.rb
|
||||
|
||||
Jakub Travnik
|
||||
* a patch for eval.c
|
||||
|
||||
Tom Truscott
|
||||
* missing/crypt.c
|
||||
|
||||
== U
|
||||
|
||||
UEDA, Satoshi
|
||||
* a patch for uri
|
||||
|
||||
Takaaki Uematsu (uema2)
|
||||
* committer
|
||||
* He was the maintainer of WinCE support.
|
||||
|
||||
UENO, Katsuhiro (katsu)
|
||||
* committer
|
||||
* He is the maintainer of zlib
|
||||
|
||||
Hajimu UMEMOTO
|
||||
* He wrote ipaddr.rb
|
||||
|
||||
URABE, Shyouhei (shyouhei)
|
||||
* committer
|
||||
* a.k.a. mput.
|
||||
* He is the branch maintainer of ruby_1_8_6 and ruby_1_8_7
|
||||
* and is the release manager of 1.8.x-pXXX.
|
||||
|
||||
== V
|
||||
|
||||
Joel VanderWerf
|
||||
* a patch for numeric.c
|
||||
|
||||
Peter Vanbroekhoven
|
||||
|
||||
Corinna Vinschen
|
||||
|
||||
== W
|
||||
|
||||
wanabe (wanabe)
|
||||
* committer
|
||||
* fixed YARV and Oniguruma.
|
||||
|
||||
Chun Wang
|
||||
* a patch for time.rb
|
||||
|
||||
WATANABE, Hirofumi (eban)
|
||||
* committer
|
||||
* He is the maintainer of
|
||||
* ftools (1.8)
|
||||
* tmpdir
|
||||
* un
|
||||
* Win32API
|
||||
|
||||
WATANABE, Tetsuya
|
||||
* a patch for ruby.c
|
||||
|
||||
William Webber (wew)
|
||||
* committer
|
||||
|
||||
Jim Weirich (jim)
|
||||
* committer
|
||||
* He wrote Rake.
|
||||
|
||||
Nathan Weizenbaum
|
||||
* fixed misc/ruby-mode.el.
|
||||
|
||||
why the lukky stiff (why)
|
||||
* committer
|
||||
* He is the maintainer of syck
|
||||
|
||||
Caley Woods
|
||||
* documentation
|
||||
|
||||
Gary Wright
|
||||
* documentation
|
||||
|
||||
== X
|
||||
|
||||
== Y
|
||||
|
||||
Akira Yamada (akira)
|
||||
* committer
|
||||
* He is the maintainer of ruby related packages at Debian project.
|
||||
|
||||
Keita Yamaguchi
|
||||
* patches for enum.c, parse.y
|
||||
* documentation
|
||||
|
||||
Hirokazu Yamamoto (ocean)
|
||||
* committer
|
||||
|
||||
Hirotaka Yoshioka
|
||||
* a patch for improving SEGV handling
|
||||
|
||||
== Z
|
||||
|
||||
Aristarkh A Zagorodnikov
|
||||
* a patch for io.c
|
||||
|
||||
Alexander Zavorine
|
||||
* committer
|
||||
* He is the maintainer for Symbian OS.
|
||||
|
||||
Chiyuan Zhang
|
||||
* a patch for misc/ruby-mode.el.
|
||||
|
||||
Dee Zsombor (zunda)
|
||||
* a patch for thread_pthread.c
|
||||
|
||||
Dan Zwell
|
||||
* a patch for net/pop
|
||||
|
||||
|
178
doc/dtrace_probes.rdoc
Normal file
178
doc/dtrace_probes.rdoc
Normal file
|
@ -0,0 +1,178 @@
|
|||
= DTrace Probes
|
||||
|
||||
A list of DTrace probes and their functionality. "Module" and "Function" cannot
|
||||
be defined in user defined probes (known as USDT), so they will not be
|
||||
specified. Probe definitions are in the format of:
|
||||
|
||||
provider:module:function:name(arguments)
|
||||
|
||||
Since module and function cannot be specified, they will be blank. An example
|
||||
probe definition for Ruby would then be:
|
||||
|
||||
ruby:::function-entry(class name, method name, file name, line number)
|
||||
|
||||
Where "ruby" is the provider name, module and function names are blank, the
|
||||
probe name is "function-entry", and the probe takes four arguments:
|
||||
|
||||
* class name
|
||||
* method name
|
||||
* file name
|
||||
* line number
|
||||
|
||||
== Probes List
|
||||
|
||||
=== Stability
|
||||
|
||||
Before we list the specific probes, let's talk about stability. Probe stability
|
||||
is declared in the probes.d file at the bottom on the #pragma D attributes
|
||||
lines. Here is a description of each of the stability declarations.
|
||||
|
||||
[Provider name stability]
|
||||
The provider name of "ruby" has been declared as stable. It is unlikely that
|
||||
we will change the provider name from "ruby" to something else.
|
||||
|
||||
[Module and Function stability]
|
||||
Since we are not allowed to provide values for the module and function name,
|
||||
the values we have provided (no value) is declared as stable.
|
||||
|
||||
[Probe name stability]
|
||||
The probe names are likely to change in the future, so they are marked as
|
||||
"Evolving". Consumers should not depend on these names to be stable.
|
||||
|
||||
[Probe argument stability]
|
||||
The parameters passed to the probes are likely to change in the future, so
|
||||
they are marked as "Evolving". Consumers should not depend on these to be
|
||||
stable.
|
||||
|
||||
=== Declared probes
|
||||
|
||||
Probes are defined in the probes.d file. Here are the declared probes along
|
||||
with when they are fired and the arguments they take:
|
||||
|
||||
[ruby:::method-entry(classname, methodname, filename, lineno);]
|
||||
This probe is fired just before a method is entered.
|
||||
|
||||
classname name of the class (a string)
|
||||
methodname name of the method about to be executed (a string)
|
||||
filename the file name where the method is _being called_ (a string)
|
||||
lineno the line number where the method is _being called_ (an int)
|
||||
|
||||
[ruby:::method-return(classname, methodname, filename, lineno);]
|
||||
This probe is fired just after a method has returned. The arguments are the
|
||||
same as "ruby:::function-entry".
|
||||
|
||||
[ruby:::cmethod-entry(classname, methodname, filename, lineno);]
|
||||
This probe is fired just before a C method is entered. The arguments are the
|
||||
same as "ruby:::function-entry".
|
||||
|
||||
[ruby:::cmethod-return(classname, methodname, filename, lineno);]
|
||||
This probe is fired just before a C method returns. The arguments are the
|
||||
same as "ruby:::function-entry".
|
||||
|
||||
[ruby:::require-entry(requiredfile, filename, lineno);]
|
||||
This probe is fired on calls to rb_require_safe (when a file is required).
|
||||
|
||||
requiredfile is the name of the file to be required (string).
|
||||
filename is the file that called "require" (string).
|
||||
lineno is the line number where the call to require was made (int).
|
||||
|
||||
[ruby:::require-return(requiredfile, filename, lineno);]
|
||||
This probe is fired just before rb_require_safe (when a file is required)
|
||||
returns. The arguments are the same as "ruby:::require-entry". This probe
|
||||
will not fire if there was an exception during file require.
|
||||
|
||||
[ruby:::find-require-entry(requiredfile, filename, lineno);]
|
||||
This probe is fired right before search_required is called. search_required
|
||||
determines whether the file has already been required by searching loaded
|
||||
features ($"), and if not, figures out which file must be loaded.
|
||||
|
||||
requiredfile is the file to be required (string).
|
||||
filename is the file that called "require" (string).
|
||||
lineno is the line number where the call to require was made (int).
|
||||
|
||||
[ruby:::find-require-return(requiredfile, filename, lineno);]
|
||||
This probe is fired right after search_required returns. See the
|
||||
documentation for "ruby:::find-require-entry" for more details. Arguments for
|
||||
this probe are the same as "ruby:::find-require-entry".
|
||||
|
||||
[ruby:::load-entry(loadedfile, filename, lineno);]
|
||||
This probe is fired when calls to "load" are made. The arguments are the same
|
||||
as "ruby:::require-entry".
|
||||
|
||||
[ruby:::load-return(loadedfile, filename, lineno);]
|
||||
This probe is fired when "load" returns. The arguments are the same as
|
||||
"ruby:::load-entry".
|
||||
|
||||
[ruby:::raise(classname, filename, lineno);]
|
||||
This probe is fired when an exception is raised.
|
||||
|
||||
classname is the class name of the raised exception (string)
|
||||
filename the name of the file where the exception was raised (string)
|
||||
lineno the line number in the file where the exception was raised (int)
|
||||
|
||||
[ruby:::object-create(classname, filename, lineno);]
|
||||
This probe is fired when an object is about to be allocated.
|
||||
|
||||
classname the class of the allocated object (string)
|
||||
filename the name of the file where the object is allocated (string)
|
||||
lineno the line number in the file where the object is allocated (int)
|
||||
|
||||
[ruby:::array-create(length, filename, lineno);]
|
||||
This probe is fired when an Array is about to be allocated.
|
||||
|
||||
length the size of the array (long)
|
||||
filename the name of the file where the array is allocated (string)
|
||||
lineno the line number in the file where the array is allocated (int)
|
||||
|
||||
[ruby:::hash-create(length, filename, lineno);]
|
||||
This probe is fired when a Hash is about to be allocated.
|
||||
|
||||
length the size of the hash (long)
|
||||
filename the name of the file where the hash is allocated (string)
|
||||
lineno the line number in the file where the hash is allocated (int)
|
||||
|
||||
[ruby:::string-create(length, filename, lineno);]
|
||||
This probe is fired when a String is about to be allocated.
|
||||
|
||||
length the size of the string (long)
|
||||
filename the name of the file where the string is allocated (string)
|
||||
lineno the line number in the file where the string is allocated (int)
|
||||
|
||||
[ruby:::symbol-create(str, filename, lineno);]
|
||||
This probe is fired when a Symbol is about to be allocated.
|
||||
|
||||
str the contents of the symbol (string)
|
||||
filename the name of the file where the string is allocated (string)
|
||||
lineno the line number in the file where the string is allocated (int)
|
||||
|
||||
[ruby:::parse-begin(sourcefile, lineno);]
|
||||
Fired just before parsing and compiling a source file.
|
||||
|
||||
sourcefile the file being parsed (string)
|
||||
lineno the line number where the source starts (int)
|
||||
|
||||
[ruby:::parse-end(sourcefile, lineno);]
|
||||
Fired just after parsing and compiling a source file.
|
||||
|
||||
sourcefile the file being parsed (string)
|
||||
lineno the line number where the source ended (int)
|
||||
|
||||
[ruby:::gc-mark-begin();]
|
||||
Fired at the beginning of a mark phase.
|
||||
|
||||
[ruby:::gc-mark-end();]
|
||||
Fired at the end of a mark phase.
|
||||
|
||||
[ruby:::gc-sweep-begin();]
|
||||
Fired at the beginning of a sweep phase.
|
||||
|
||||
[ruby:::gc-sweep-end();]
|
||||
Fired at the end of a sweep phase.
|
||||
|
||||
[ruby:::method-cache-clear(class, sourcefile, lineno);]
|
||||
Fired when the method cache is cleared.
|
||||
|
||||
class is the classname being cleared, or "global" (string)
|
||||
sourcefile the file being parsed (string)
|
||||
lineno the line number where the source ended (int)
|
||||
|
|
@ -22,26 +22,34 @@ $_:: The last input line of string by gets or readline.
|
|||
$0:: Contains the name of the script being executed. May be assignable.
|
||||
$*:: Command line arguments given for the script sans args.
|
||||
$$:: The process number of the Ruby running this script.
|
||||
$?:: The status of the last executed child process.
|
||||
$?:: The status of the last executed child process. This value is
|
||||
thread-local.
|
||||
$::: Load path for scripts and binary modules by load or require.
|
||||
$":: The array contains the module names loaded by require.
|
||||
$DEBUG:: The status of the -d switch.
|
||||
$DEBUG:: The debug flag, which is set by the -d switch. Enabling debug
|
||||
output prints each exception raised to $stderr (but not its
|
||||
backtrace). Setting this to a true value enables debug output as
|
||||
if -d were given on the command line. Setting this to a false
|
||||
value disables debug output.
|
||||
$FILENAME:: Current input file from $<. Same as $<.filename.
|
||||
$LOAD_PATH:: The alias to the $:.
|
||||
$stderr:: The current standard error output.
|
||||
$stdin:: The current standard input.
|
||||
$stdout:: The current standard output.
|
||||
$VERBOSE:: The verbose flag, which is set by the -v switch.
|
||||
$VERBOSE:: The verbose flag, which is set by the -w or -v switch. Setting
|
||||
this to a true value enables warnings as if -w or -v were given
|
||||
on the command line. Setting this to nil disables warnings,
|
||||
including from Kernel#warn.
|
||||
$-0:: The alias to $/.
|
||||
$-a:: True if option -a is set. Read-only variable.
|
||||
$-d:: The alias to $DEBUG.
|
||||
$-d:: The alias of $DEBUG. See $DEBUG above for further discussion.
|
||||
$-F:: The alias to $;.
|
||||
$-i:: In in-place-edit mode, this variable holds the extension, otherwise nil.
|
||||
$-I:: The alias to $:.
|
||||
$-l:: True if option -l is set. Read-only variable.
|
||||
$-p:: True if option -p is set. Read-only variable.
|
||||
$-v:: The alias to $VERBOSE.
|
||||
$-w:: True if option -w is set.
|
||||
$-v:: An alias of $VERBOSE. See $VERBOSE above for further discussion.
|
||||
$-w:: An alias of $VERBOSE. See $VERBOSE above for further discussion.
|
||||
|
||||
== Pre-defined global constants
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ irb起動時に``~/.irbrc''を読み込みます. もし存在しない場合は
|
|||
IRB.conf[:USE_TRACER] = false
|
||||
IRB.conf[:IGNORE_SIGINT] = true
|
||||
IRB.conf[:IGNORE_EOF] = false
|
||||
IRB.conf[:PROMPT_MODE] = :DEFALUT
|
||||
IRB.conf[:PROMPT_MODE] = :DEFAULT
|
||||
IRB.conf[:PROMPT] = {...}
|
||||
IRB.conf[:DEBUG_LEVEL]=0
|
||||
IRB.conf[:VERBOSE]=true
|
||||
|
|
322
doc/maintainers.rdoc
Normal file
322
doc/maintainers.rdoc
Normal file
|
@ -0,0 +1,322 @@
|
|||
= Maintainers
|
||||
|
||||
This page describes the current module, library, and extension maintainers of Ruby.
|
||||
|
||||
== Module Maintainers
|
||||
|
||||
A module maintainer is responsible for a certain part of Ruby.
|
||||
|
||||
* The maintainer fixes bugs of the part. Particularly, they should fix security vulnerabilities as soon as possible.
|
||||
* They handle issues related the module on the Redmine or ML.
|
||||
* They may be discharged by the 3 months rule [ruby-core:25764].
|
||||
* They have commit right to Ruby's repository to modify their part in the repository.
|
||||
* They have "developer" role on the Redmine to modify issues.
|
||||
* They have authority to decide the feature of their part. But they should always respect discussions on ruby-core/ruby-dev.
|
||||
|
||||
A submaintainer of a module is like a maintainer. But The submaintainer does
|
||||
not have authority to change/add a feature on his/her part. They need consensus
|
||||
on ruby-core/ruby-dev before changing/adding. Some of submaintainers have
|
||||
commit right, others don't.
|
||||
|
||||
=== Language core features including security
|
||||
|
||||
Yukihiro Matsumoto (matz)
|
||||
|
||||
=== Evaluator
|
||||
|
||||
Koichi Sasada (ko1)
|
||||
|
||||
=== Core classes
|
||||
|
||||
Yukihiro Matsumoto (matz)
|
||||
|
||||
=== Documentation
|
||||
|
||||
Zachary Scott (zzak)
|
||||
|
||||
== Library Maintainers
|
||||
|
||||
[lib/English.rb]
|
||||
_unmaintained_
|
||||
[lib/abbrev.rb]
|
||||
Akinori MUSHA (knu)
|
||||
[lib/base64.rb]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: Yusuke Endoh (mame)
|
||||
[lib/benchmark.rb]
|
||||
_unmaintained_
|
||||
[lib/cgi.rb, lib/cgi/*]
|
||||
Takeyuki Fujioka (xibbar)
|
||||
[lib/complex.rb]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: moved into core
|
||||
[lib/cmath.rb]
|
||||
* 1.8: 1.9 feature
|
||||
* 1.9: _unmaintained_
|
||||
[lib/csv.rb]
|
||||
* 1.8: Hiroshi Nakamura (nahi)
|
||||
* 1.9: James Edward Gray II (jeg2)
|
||||
[lib/date.rb, lib/date/*]
|
||||
Tadayoshi Funaba (tadf)
|
||||
[lib/drb.rb, lib/drb/*]
|
||||
Masatoshi SEKI (seki)
|
||||
[lib/debug.rb]
|
||||
_unmaintained_
|
||||
[lib/delegate.rb]
|
||||
_unmaintained_
|
||||
[lib/e2mmap.rb]
|
||||
Keiju ISHITSUKA (keiju)
|
||||
[lib/erb.rb]
|
||||
Masatoshi SEKI (seki)
|
||||
[lib/fileutils.rb]
|
||||
_unmaintained_
|
||||
[lib/find.rb]
|
||||
Kazuki Tsujimoto (ktsj)
|
||||
[lib/finalize.rb]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: _deprecated_
|
||||
[lib/forwardable.rb]
|
||||
Keiju ISHITSUKA (keiju)
|
||||
[lib/ftools.rb]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: _deprecated_
|
||||
[lib/generator.rb]
|
||||
* 1.8: Akinori MUSHA (knu)
|
||||
* 1.9: moved into core
|
||||
[lib/getoptlong.rb]
|
||||
_unmaintained_
|
||||
[lib/getopts.rb]
|
||||
* 1.8: Akinori MUSHA (knu)
|
||||
* 1.9: _deprecated_
|
||||
[lib/gserver.rb]
|
||||
James Edward Gray II (jeg2)
|
||||
[lib/ipaddr.rb]
|
||||
Akinori MUSHA (knu)
|
||||
[lib/irb.rb, lib/irb/*]
|
||||
Keiju ISHITSUKA (keiju)
|
||||
[lib/jcode.rb]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: _deprecated_
|
||||
[lib/logger.rb]
|
||||
Hiroshi Nakamura (nahi)
|
||||
[lib/mathn.rb]
|
||||
Keiju ISHITSUKA (keiju)
|
||||
[lib/matrix.rb]
|
||||
Marc-Andre Lafortune (marcandre)
|
||||
[lib/minitest/*]
|
||||
* 1.8: 1.9 feature
|
||||
* 1.9: Ryan Davis (ryan)
|
||||
[lib/mkmf.rb]
|
||||
_unmaintained_
|
||||
[lib/monitor.rb]
|
||||
Shugo Maeda (shugo)
|
||||
[lib/mutex_m.rb]
|
||||
Keiju ISHITSUKA (keiju)
|
||||
[lib/net/ftp.rb]
|
||||
Shugo Maeda (shugo)
|
||||
[lib/net/imap.rb]
|
||||
Shugo Maeda (shugo)
|
||||
[lib/net/telnet.rb]
|
||||
_unmaintained_
|
||||
[lib/net/http.rb, lib/net/https]
|
||||
NARUSE, Yui (naruse)
|
||||
[lib/net/pop.rb]
|
||||
_unmaintained_
|
||||
[lib/net/smtp.rb]
|
||||
_unmaintained_
|
||||
[lib/observer.rb]
|
||||
_unmaintained_
|
||||
[lib/open-uri.rb]
|
||||
Tanaka Akira (akr)
|
||||
[lib/open3.rb]
|
||||
_unmaintained_
|
||||
[lib/optparse.rb, lib/optparse/*]
|
||||
Nobuyuki Nakada (nobu)
|
||||
[lib/ostruct.rb]
|
||||
Marc-Andre Lafortune (marcandre)
|
||||
[lib/parsearg.rb]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: _deprecated_
|
||||
[lib/parsedate.rb]
|
||||
* 1.8: Tadayoshi Funaba (tadf)
|
||||
* 1.9: _deprecated_
|
||||
[lib/pathname.rb]
|
||||
Tanaka Akira (akr)
|
||||
[lib/ping.rb]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: _deprecated_
|
||||
[lib/pp.rb]
|
||||
Tanaka Akira (akr)
|
||||
[lib/prettyprint.rb]
|
||||
Tanaka Akira (akr)
|
||||
[lib/prime.rb]
|
||||
Yuki Sonoda (yugui)
|
||||
[lib/profile.rb]
|
||||
_unmaintained_
|
||||
[lib/profiler.rb]
|
||||
_unmaintained_
|
||||
[lib/pstore.rb]
|
||||
_unmaintained_
|
||||
[lib/racc/*]
|
||||
Aaron Patterson (tenderlove)
|
||||
[lib/rake/*]
|
||||
Eric Hodel (drbrain)
|
||||
[lib/rational.rb]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: moved into core
|
||||
[lib/rdoc/*]
|
||||
Eric Hodel (drbrain)
|
||||
[lib/readbytes.rb]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: _deprecated_
|
||||
[lib/resolv-replace.rb]
|
||||
Tanaka Akira (akr)
|
||||
[lib/resolv.rb]
|
||||
Tanaka Akira (akr)
|
||||
[lib/rexml/*]
|
||||
Kouhei Sutou (kou)
|
||||
[lib/rinda/*]
|
||||
Masatoshi SEKI (seki)
|
||||
[lib/rss/*]
|
||||
Kouhei Sutou (kou)
|
||||
[lib/rubygems.rb, lib/ubygems.rb, lib/rubygems/*]
|
||||
* 1.8: 1.9 feature
|
||||
* 1.9: Eric Hodel (drbrain)
|
||||
[lib/rubyunit.rb, lib/runit/*]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: _deprecated_
|
||||
[lib/scanf.rb]
|
||||
David A. Black (dblack)
|
||||
[lib/set.rb]
|
||||
Akinori MUSHA (knu)
|
||||
[lib/securerandom.rb]
|
||||
Tanaka Akira (akr)
|
||||
[lib/shell.rb, lib/shell/*]
|
||||
Keiju ISHITSUKA (keiju)
|
||||
[lib/shellwords.rb]
|
||||
Akinori MUSHA (knu)
|
||||
[lib/singleton.rb]
|
||||
Yukihiro Matsumoto (matz)
|
||||
[lib/{soap|wsdl|xsd}/*]
|
||||
* 1.8: Hiroshi Nakamura (nahi)
|
||||
* 1.9: _deprecated_
|
||||
[lib/sync.rb]
|
||||
Keiju ISHITSUKA (keiju)
|
||||
[lib/tempfile.rb]
|
||||
_unmaintained_
|
||||
[lib/test/*]
|
||||
Shota Fukumori (sorah)
|
||||
[lib/tmpdir.rb]
|
||||
_unmaintained_
|
||||
[lib/thread.rb]
|
||||
_unmaintained_
|
||||
[lib/thwait.rb]
|
||||
Keiju ISHITSUKA (keiju)
|
||||
[lib/time.rb]
|
||||
Tanaka Akira (akr)
|
||||
[lib/timeout.rb]
|
||||
Yukihiro Matsumoto (matz)
|
||||
[lib/tracer.rb]
|
||||
Keiju ISHITSUKA (keiju)
|
||||
[lib/tsort.rb]
|
||||
Tanaka Akira (akr)
|
||||
[lib/un.rb]
|
||||
WATANABE Hirofumi (eban)
|
||||
[lib/uri.rb, lib/uri/*]
|
||||
YAMADA, Akira (akira)
|
||||
[lib/weakref.rb]
|
||||
_unmaintained_
|
||||
[lib/webrick.rb, lib/webrick/*]
|
||||
Hiroshi Nakamura (nahi)
|
||||
[lib/xmlrpc/*]
|
||||
Kouhei Sutou (kou)
|
||||
[lib/yaml.rb, lib/yaml/*]
|
||||
Aaron Patterson (tenderlove)
|
||||
|
||||
== Extension Maintainers
|
||||
|
||||
[ext/Win32API]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: merged into dl
|
||||
[ext/bigdecimal]
|
||||
Kenta Murata (mrkn)
|
||||
[ext/continuation]
|
||||
* 1.8: 1.9 feature
|
||||
* 1.9: Koichi Sasada (ko1)
|
||||
[ext/coverage]
|
||||
Yusuke Endoh (mame)
|
||||
[ext/dbm]
|
||||
_unmaintained_
|
||||
[ext/digest, ext/digest/*]
|
||||
Akinori MUSHA (knu)
|
||||
[ext/dl]
|
||||
Aaron Patterson (tenderlove)
|
||||
[ext/dl/win32]
|
||||
NAKAMURA Usaku (usa)
|
||||
[ext/enumerator]
|
||||
* 1.8: Akinori MUSHA (knu)
|
||||
* 1.9: moved into core
|
||||
[ext/etc]
|
||||
_unmaintained_
|
||||
[ext/fcntl]
|
||||
_unmaintained_
|
||||
[ext/fiber]
|
||||
* 1.8: 1.9 feature
|
||||
* 1.9: Koichi Sasada (ko1)
|
||||
[ext/fiddle]
|
||||
Aaron Patterson (tenderlove)
|
||||
[ext/gdbm]
|
||||
Yukihiro Matsumoto (matz)
|
||||
[ext/iconv]
|
||||
Nobuyuki Nakada (nobu)
|
||||
[ext/io/wait]
|
||||
Nobuyuki Nakada (nobu)
|
||||
[ext/json]
|
||||
NARUSE, Yui (naruse)
|
||||
[ext/mathn/complex]
|
||||
* 1.8: 1.9 feature
|
||||
* 1.9: Keiju ISHITSUKA (keiju)
|
||||
[ext/mathn/rational]
|
||||
* 1.8: 1.9 feature
|
||||
* 1.9: Keiju ISHITSUKA (keiju)
|
||||
[ext/nkf]
|
||||
NARUSE, Yui (narse)
|
||||
[ext/objspace]
|
||||
_unmaintained_
|
||||
[ext/openssl]
|
||||
Martin Boßlet (emboss)
|
||||
[ext/psych]
|
||||
Aaron Patterson (tenderlove)
|
||||
[ext/pty]
|
||||
_unmaintained_
|
||||
[ext/racc]
|
||||
Aaron Patterson (tenderlove)
|
||||
[ext/readline]
|
||||
TAKAO Kouji (kouji)
|
||||
[ext/ripper]
|
||||
_unmaintained_
|
||||
[ext/sdbm]
|
||||
Yukihiro Matsumoto (matz)
|
||||
[ext/socket]
|
||||
* Tanaka Akira (akr)
|
||||
* API change needs matz's approval
|
||||
[ext/stringio]
|
||||
Nobuyuki Nakada (nobu)
|
||||
[ext/strscan]
|
||||
_unmaintained_
|
||||
[ext/syck]
|
||||
_unmaintained_
|
||||
[ext/syslog]
|
||||
Akinori MUSHA (knu)
|
||||
[ext/thread]
|
||||
* 1.8: _unmaintained_
|
||||
* 1.9: 1.8 feature
|
||||
[ext/tcltklib]
|
||||
_deprecated_
|
||||
[ext/tk]
|
||||
Hidetoshi NAGAI (nagai)
|
||||
[ext/win32ole]
|
||||
Masaki Suketa (suke)
|
||||
[ext/zlib]
|
||||
_unmaintained_
|
||||
|
313
doc/marshal.rdoc
Normal file
313
doc/marshal.rdoc
Normal file
|
@ -0,0 +1,313 @@
|
|||
= Marshal Format
|
||||
|
||||
The Marshal format is used to serialize ruby objects. The format can store
|
||||
arbitrary objects through three user-defined extension mechanisms.
|
||||
|
||||
For documentation on using Marshal to serialize and deserialize objects, see
|
||||
the Marshal module.
|
||||
|
||||
This document calls a serialized set of objects a stream. The Ruby
|
||||
implementation can load a set of objects from a String, an IO or an object
|
||||
that implements a +getc+ method.
|
||||
|
||||
== Stream Format
|
||||
|
||||
The first two bytes of the stream contain the major and minor version, each as
|
||||
a single byte encoding a digit. The version implemented in Ruby is 4.8
|
||||
(stored as "\x04\x08") and is supported by ruby 1.8.0 and newer.
|
||||
|
||||
Different major versions of the Marshal format are not compatible and cannot
|
||||
be understood by other major versions. Lesser minor versions of the format
|
||||
can be understood by newer minor versions. Format 4.7 can be loaded by a 4.8
|
||||
implementation but format 4.8 cannot be loaded by a 4.7 implementation.
|
||||
|
||||
Following the version bytes is a stream describing the serialized object. The
|
||||
stream contains nested objects (the same as a Ruby object) but objects in the
|
||||
stream do not necessarily have a direct mapping to the Ruby object model.
|
||||
|
||||
Each object in the stream is described by a byte indicating its type followed
|
||||
by one or more bytes describing the object. When "object" is mentioned below
|
||||
it means any of the types below that defines a Ruby object.
|
||||
|
||||
=== true, false, nil
|
||||
|
||||
These objects are each one byte long. "T" is represents +true+, "F"
|
||||
represents +false+ and "0" represents +nil+.
|
||||
|
||||
=== Fixnum and long
|
||||
|
||||
"i" represents a signed 32 bit value using a packed format. One through five
|
||||
bytes follows the type. The value loaded will always be a Fixnum. On
|
||||
32 bit platforms (where the precision of a Fixnum is less than 32 bits)
|
||||
loading large values will cause overflow on CRuby.
|
||||
|
||||
The fixnum type is used to represent both ruby Fixnum objects and the sizes of
|
||||
marshaled arrays, hashes, instance variables and other types. In the
|
||||
following sections "long" will mean the format described below, which supports
|
||||
full 32 bit precision.
|
||||
|
||||
The first byte has the following special values:
|
||||
|
||||
"\x00"::
|
||||
The value of the integer is 0. No bytes follow.
|
||||
|
||||
"\x01"::
|
||||
The total size of the integer is two bytes. The following byte is a
|
||||
positive integer in the range of 0 through 255. Only values between 123
|
||||
and 255 should be represented this way to save bytes.
|
||||
|
||||
"\xff"::
|
||||
The total size of the integer is two bytes. The following byte is a
|
||||
negative integer in the range of -1 through -256.
|
||||
|
||||
"\x02"::
|
||||
The total size of the integer is three bytes. The following two bytes are a
|
||||
positive little-endian integer.
|
||||
|
||||
"\xfe"::
|
||||
The total size of the integer is three bytes. The following two bytes are a
|
||||
negative little-endian integer.
|
||||
|
||||
"\x03"::
|
||||
The total size of the integer is four bytes. The following three bytes are
|
||||
a positive little-endian integer.
|
||||
|
||||
"\xfd"::
|
||||
The total size of the integer is two bytes. The following three bytes are a
|
||||
negative little-endian integer.
|
||||
|
||||
"\x04"::
|
||||
The total size of the integer is five bytes. The following four bytes are a
|
||||
positive little-endian integer. For compatibility with 32 bit ruby,
|
||||
only Fixnums less than 1073741824 should be represented this way. For sizes
|
||||
of stream objects full precision may be used.
|
||||
|
||||
"\xfc"::
|
||||
The total size of the integer is two bytes. The following four bytes are a
|
||||
negative little-endian integer. For compatibility with 32 bit ruby,
|
||||
only Fixnums greater than -10737341824 should be represented this way. For
|
||||
sizes of stream objects full precision may be used.
|
||||
|
||||
Otherwise the first byte is a sign-extended eight-bit value with an offset.
|
||||
If the value is positive the value is determined by subtracting 5 from the
|
||||
value. If the value is negative the value is determined by adding 5 to the
|
||||
value.
|
||||
|
||||
There are multiple representations for many values. CRuby always outputs the
|
||||
shortest representation possible.
|
||||
|
||||
=== Symbols and Byte Sequence
|
||||
|
||||
":" represents a real symbol. A real symbol contains the data needed to
|
||||
define the symbol for the rest of the stream as future occurrences in the
|
||||
stream will instead be references (a symbol link) to this one. The reference
|
||||
is a zero-indexed 32 bit value (so the first occurrence of <code>:hello</code>
|
||||
is 0).
|
||||
|
||||
Following the type byte is byte sequence which consists of a long indicating
|
||||
the number of bytes in the sequence followed by that many bytes of data. Byte
|
||||
sequences have no encoding.
|
||||
|
||||
For example, the following stream contains the Symbol <code>:hello</code>:
|
||||
|
||||
"\x04\x08:\x0ahello"
|
||||
|
||||
";" represents a Symbol link which references a previously defined Symbol.
|
||||
Following the type byte is a long containing the index in the lookup table for
|
||||
the linked (referenced) Symbol.
|
||||
|
||||
For example, the following stream contains <code>[:hello, :hello]</code>:
|
||||
|
||||
"\x04\b[\a:\nhello;\x00"
|
||||
|
||||
When a "symbol" is referenced below it may be either a real symbol or a
|
||||
symbol link.
|
||||
|
||||
=== Object References
|
||||
|
||||
Separate from but similar to symbol references, the stream contains only one
|
||||
copy of each object (as determined by #object_id) for all objects except
|
||||
true, false, nil, Fixnums and Symbols (which are stored separately as
|
||||
described above) a one-indexed 32 bit value will be stored and reused when the
|
||||
object is encountered again. (The first object has an index of 1).
|
||||
|
||||
"@" represents an object link. Following the type byte is a long giving the
|
||||
index of the object.
|
||||
|
||||
For example, the following stream contains an Array of the object
|
||||
<code>"hello"</code> twice:
|
||||
|
||||
"\004\b[\a\"\nhello@\006"
|
||||
|
||||
=== Instance Variables
|
||||
|
||||
"I" indicates that instance variables follow the next object. An object
|
||||
follows the type byte. Following the object is a length indicating the number
|
||||
of instance variables for the object. Following the length is a set of
|
||||
name-value pairs. The names are symbols while the values are objects. The
|
||||
symbols must be instance variable names (<code>:@name</code>).
|
||||
|
||||
An Object ("o" type, described below) uses the same format for its instance
|
||||
variables as described here.
|
||||
|
||||
For a String and Regexp (described below) a special instance variable
|
||||
<code>:E</code> is used to indicate the Encoding.
|
||||
|
||||
=== Extended
|
||||
|
||||
"e" indicates that the next object is extended by a module. An object follows
|
||||
the type byte. Following the object is a symbol that contains the name of the
|
||||
module the object is extended by.
|
||||
|
||||
=== Array
|
||||
|
||||
"[" represents an Array. Following the type byte is a long indicating the
|
||||
number of objects in the array. The given number of objects follow the
|
||||
length.
|
||||
|
||||
=== Bignum
|
||||
|
||||
"l" represents a Bignum which is composed of three parts:
|
||||
|
||||
sign::
|
||||
A single byte containing "+" for a positive value or "-" for a negative
|
||||
value.
|
||||
length::
|
||||
A long indicating the number of bytes of Bignum data follows, divided by
|
||||
two. Multiply the length by two to determine the number of bytes of data
|
||||
that follow.
|
||||
data::
|
||||
Bytes of Bignum data representing the number.
|
||||
|
||||
The following ruby code will reconstruct the Bignum value from an array of
|
||||
bytes:
|
||||
|
||||
result = 0
|
||||
|
||||
bytes.each_with_index do |byte, exp|
|
||||
result += (byte * 2 ** (exp * 8))
|
||||
end
|
||||
|
||||
=== Class and Module
|
||||
|
||||
"c" represents a Class object, "m" represents a Module and "M" represents
|
||||
either a class or module (this is an old-style for compatibility). No class
|
||||
or module content is included, this type is only a reference. Following the
|
||||
type byte is a byte sequence which is used to look up an existing class or
|
||||
module, respectively.
|
||||
|
||||
Instance variables are not allowed on a class or module.
|
||||
|
||||
If no class or module exists an exception should be raised.
|
||||
|
||||
For "c" and "m" types, the loaded object must be a class or module,
|
||||
respectively.
|
||||
|
||||
=== Data
|
||||
|
||||
"d" represents a Data object. (Data objects are wrapped pointers from ruby
|
||||
extensions.) Following the type byte is a symbol indicating the class for the
|
||||
Data object and an object that contains the state of the Data object.
|
||||
|
||||
To dump a Data object Ruby calls _dump_data. To load a Data object Ruby calls
|
||||
_load_data with the state of the object on a newly allocated instance.
|
||||
|
||||
=== Float
|
||||
|
||||
"f" represents a Float object. Following the type byte is a byte sequence
|
||||
containing the float value. The following values are special:
|
||||
|
||||
"inf"::
|
||||
Positive infinity
|
||||
|
||||
"-inf"::
|
||||
Negative infinity
|
||||
|
||||
"nan"::
|
||||
Not a Number
|
||||
|
||||
Otherwise the byte sequence contains a C double (loadable by strtod(3)).
|
||||
Older minor versions of Marshal also stored extra mantissa bits to ensure
|
||||
portability across platforms but 4.8 does not include these. See
|
||||
[ruby-talk:69518] for some explanation.
|
||||
|
||||
=== Hash and Hash with Default Value
|
||||
|
||||
"{" represents a Hash object while "}" represents a Hash with a default value
|
||||
set (<code>Hash.new 0</code>). Following the type byte is a long indicating
|
||||
the number of key-value pairs in the Hash, the size. Double the given number
|
||||
of objects follow the size.
|
||||
|
||||
For a Hash with a default value, the default value follows all the pairs.
|
||||
|
||||
=== Module and Old Module
|
||||
|
||||
=== Object
|
||||
|
||||
"o" represents an object that doesn't have any other special form (such as
|
||||
a user-defined or built-in format). Following the type byte is a symbol
|
||||
containing the class name of the object. Following the class name is a long
|
||||
indicating the number of instance variable names and values for the object.
|
||||
Double the given number of pairs of objects follow the size.
|
||||
|
||||
The keys in the pairs must be symbols containing instance variable names.
|
||||
|
||||
=== Regular Expression
|
||||
|
||||
"/" represents a regular expression. Following the type byte is a byte
|
||||
sequence containing the regular expression source. Following the type byte is
|
||||
a byte containing the regular expression options (case-insensitive, etc.) as a
|
||||
signed 8-bit value.
|
||||
|
||||
Regular expressions can have an encoding attached through instance variables
|
||||
(see above). If no encoding is attached escapes for the following regexp
|
||||
specials not present in ruby 1.8 must be removed: g-m, o-q, u, y, E, F, H-L,
|
||||
N-V, X, Y.
|
||||
|
||||
=== String
|
||||
|
||||
'"' represents a String. Following the type byte is a byte sequence
|
||||
containing the string content. When dumped from ruby 1.9 an encoding instance
|
||||
variable (<code>:E</code> see above) should be included unless the encoding is
|
||||
binary.
|
||||
|
||||
=== Struct
|
||||
|
||||
"S" represents a Struct. Following the type byte is a symbol containing the
|
||||
name of the struct. Following the name is a long indicating the number of
|
||||
members in the struct. Double the number of objects follow the member count.
|
||||
Each member is a pair containing the member's symbol and an object for the
|
||||
value of that member.
|
||||
|
||||
If the struct name does not match a Struct subclass in the running ruby an
|
||||
exception should be raised.
|
||||
|
||||
If there is a mismatch between the struct in the currently running ruby and
|
||||
the member count in the marshaled struct an exception should be raised.
|
||||
|
||||
=== User Class
|
||||
|
||||
"C" represents a subclass of a String, Regexp, Array or Hash. Following the
|
||||
type byte is a symbol containing the name of the subclass. Following the name
|
||||
is the wrapped object.
|
||||
|
||||
=== User Defined
|
||||
|
||||
"u" represents an object with a user-defined serialization format using the
|
||||
+_dump+ instance method and +_load+ class method. Following the type byte is
|
||||
a symbol containing the class name. Following the class name is a byte
|
||||
sequence containing the user-defined representation of the object.
|
||||
|
||||
The class method +_load+ is called on the class with a string created from the
|
||||
byte-sequence.
|
||||
|
||||
=== User Marshal
|
||||
|
||||
"U" represents an object with a user-defined serialization format using the
|
||||
+marshal_dump+ and +marshal_load+ instance methods. Following the type byte
|
||||
is a symbol containing the class name. Following the class name is an object
|
||||
containing the data.
|
||||
|
||||
Upon loading a new instance must be allocated and +marshal_load+ must be
|
||||
called on the instance with the data.
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
pty extension version 0.3 by A.ito
|
||||
|
||||
1. Introduction
|
||||
|
||||
This extension module adds ruby a functionality to execute an
|
||||
arbitrary command through pseudo tty (pty).
|
||||
|
||||
2. Install
|
||||
|
||||
Follow the instruction below.
|
||||
|
||||
(1) Execute
|
||||
|
||||
ruby extconf.rb
|
||||
|
||||
then Makefile is generated.
|
||||
|
||||
(3) Do make; make install.
|
||||
|
||||
3. What you can do
|
||||
|
||||
This extension module defines a module named PTY, which contains
|
||||
following module fungtions:
|
||||
|
||||
getpty(command)
|
||||
spawn(command)
|
||||
|
||||
This function reserves a pty, executes command over the pty
|
||||
and returns an array. The return value is an array with three
|
||||
elements. The first element in the array is for reading and the
|
||||
second for writing. The third element is the process ID of the
|
||||
child process. If this function is called with an iterator block,
|
||||
the array is passed to the block as block parameters, and the
|
||||
function itself returns nil.
|
||||
|
||||
When the child process is suspended or finished, an exception is
|
||||
raised. If this function is called with an iterator block,
|
||||
exception is raised only within the block. Child process
|
||||
monitor is terminated on block exit.
|
||||
|
||||
protect_signal
|
||||
reset_signal
|
||||
|
||||
These functions are obsolete in this version of pty.
|
||||
|
||||
PTY.open
|
||||
|
||||
Allocates a pty (pseudo-terminal).
|
||||
|
||||
It returns an array which contains an IO object and a File object.
|
||||
The former is the master of the pty.
|
||||
The latter is the slave of the pty.
|
||||
|
||||
If a block is given, it yields the array instead of return.
|
||||
The value of the block is returned.
|
||||
master_io and slave_file is closed when return if they are not closed.
|
||||
|
||||
PTY.check(pid[, raise=false])
|
||||
|
||||
checks the status of the child process specified by pid, and
|
||||
returns nil if the process is still alive and active.
|
||||
Otherwise, returns Process::Status about the process if raise is
|
||||
false, or PTY::ChildExited exception is raised.
|
||||
|
||||
4. License
|
||||
|
||||
(C) Copyright 1998 by Akinori Ito.
|
||||
|
||||
This software may be redistributed freely for this purpose, in full
|
||||
or in part, provided that this entire copyright notice is included
|
||||
on any copies of this software and applications and derivations thereof.
|
||||
|
||||
This software is provided on an "as is" basis, without warranty of any
|
||||
kind, either expressed or implied, as to any matter including, but not
|
||||
limited to warranty of fitness of purpose, or merchantability, or
|
||||
results obtained from use of this software.
|
||||
|
||||
5. Bug report
|
||||
|
||||
Please feel free to send E-mail to
|
||||
|
||||
aito@ei5sun.yz.yamagata-u.ac.jp
|
||||
|
||||
for any bug report, opinion, contribution, etc.
|
|
@ -1,22 +0,0 @@
|
|||
README for expect
|
||||
by A. Ito, 28 October, 1998
|
||||
|
||||
Expect library adds IO class a method called expect(), which
|
||||
does similar act to tcl's expect extension.
|
||||
|
||||
The usage of the method is:
|
||||
|
||||
IO#expect(pattern,timeout=9999999)
|
||||
|
||||
where `pattern' is an instance of String or Regexp and `timeout'
|
||||
is Fixnum, which can be omitted.
|
||||
When the method is called without block, it waits until the
|
||||
input which matches the pattern is obtained from the IO or the time
|
||||
specified as the timeout passes. When the pattern is obtained from the
|
||||
IO, the method returns an array. The first element of the array is the
|
||||
entire string obtained from the IO until the pattern matches. The
|
||||
following elements indicates the specific pattern which matched to the
|
||||
anchor in the regular expression. If the method ends because of
|
||||
timeout, it returns nil.
|
||||
When the method is called with block, the array is passed as
|
||||
the block parameter.
|
440
doc/rake/CHANGES
440
doc/rake/CHANGES
|
@ -1,440 +0,0 @@
|
|||
|
||||
= Rake Changelog
|
||||
|
||||
== Version 0.8.7
|
||||
|
||||
* Fixed EXEEXT for JRuby on windows.
|
||||
|
||||
== Version 0.8.6
|
||||
|
||||
* Minor fixes to the RDoc generation (removed dependency on darkfish
|
||||
and removed inline source option).
|
||||
|
||||
== Version 0.8.5
|
||||
|
||||
* Better support for the system command on Windows.
|
||||
|
||||
== Version 0.8.4
|
||||
|
||||
* Preserve case when locating rakefiles (patch from James
|
||||
M. Lawrence/quix)
|
||||
|
||||
* Better support for windows paths in the test task (patch from Simon
|
||||
Chiang/bahuvrihi)
|
||||
|
||||
* Windows system dir search order is now: HOME, HOMEDRIVE + HOMEPATH,
|
||||
APPDATA, USERPROFILE (patch from Luis Lavena)
|
||||
|
||||
* MingGW is now recognized as a windows platform. (patch from Luis
|
||||
Lavena)
|
||||
|
||||
* Numerous fixes to the windows test suite (patch from Luis Lavena).
|
||||
|
||||
* Improved Rakefile case insensitivity testing (patch from Luis
|
||||
Lavena).
|
||||
|
||||
* Fixed stray ARGV option problem that was interfering with
|
||||
Test::Unit::Runner.
|
||||
|
||||
* Fixed default verbose mode (was accidently changed to false).
|
||||
|
||||
* Removed reference to manage_gem to fix the warning produced by the
|
||||
gem package task.
|
||||
|
||||
== Version 0.8.3
|
||||
|
||||
* Enhanced the system directory detection in windows. We now check
|
||||
HOMEDRIVE/HOMEPATH and USERPROFILE if APPDATA isn't found. (Patch
|
||||
supplied by James Tucker). Rake no long aborts if it can't find the
|
||||
directory.
|
||||
|
||||
* Added fix to handle ruby installations in directories with spaces in
|
||||
their name.
|
||||
|
||||
== Version 0.8.2
|
||||
|
||||
* Fixed bug in package task so that it will include the subdir
|
||||
directory in the package for testing. (Bug found by Adam Majer)
|
||||
|
||||
* Added ENV var to rakefile to prevent OS X from including extended
|
||||
attribute junk in a tar file. (Bug found by Adam Majer)
|
||||
|
||||
* Fixed filename dependency order bug in test_inspect_pending and
|
||||
test_to_s_pending. (Bug found by Adam Majer)
|
||||
|
||||
* Fixed check for file utils options to make them immune to the
|
||||
symbol/string differences. (Patch supplied by Edwin Pratomo)
|
||||
|
||||
* Fixed bug with rules involving multiple source (Patch supplied by
|
||||
Emanuel Indermühle)
|
||||
|
||||
* Switched from getoptlong to optparse (patches supplied by Edwin
|
||||
Pratomo)
|
||||
|
||||
* The -T option will now attempt to dynamically sense the size of the
|
||||
terminal. RAKE_COLUMNS will override any dynamic sensing.
|
||||
|
||||
* FileList#clone and FileList#dup have better sematics w.r.t. taint
|
||||
and freeze.
|
||||
|
||||
* Added ability clear prerequisites, and/or actions from an existing
|
||||
task.
|
||||
|
||||
* Added the ability to reenable a task to be invoked a second time.
|
||||
|
||||
* Changed RDoc test task to have no default template. This makes it
|
||||
easier for the tempate to pick up the template from the environment.
|
||||
|
||||
* Changed from using Mutex to Monitor. Evidently Mutex causes thread
|
||||
join errors when Ruby is compiled with -disable-pthreads. (Patch
|
||||
supplied by Ittay Dror)
|
||||
|
||||
* Fixed bug in makefile parser that had problems with extra spaces in
|
||||
file task names. (Patch supplied by Ittay Dror)
|
||||
|
||||
* Added a performance patch for reading large makefile dependency
|
||||
files. (Patch supplied by Ittay Dror)
|
||||
|
||||
* Default values for task arguments can easily be specified with the
|
||||
:with_defaults method. (Idea for default argument merging supplied
|
||||
by (Adam Q. Salter)
|
||||
|
||||
* The -T output will only self-truncate if the output is a tty.
|
||||
However, if RAKE_COLUMNS is explicitly set, it will be honored in
|
||||
any case. (Patch provided by Gavin Stark).
|
||||
|
||||
* Numerous fixes for running under windows. A big thanks to Bheeshmar
|
||||
Redheendran for spending a good part of the afternoon at the
|
||||
Lonestar Ruby Conference to help me work out these issues.
|
||||
|
||||
== Version 0.8.1
|
||||
|
||||
* Removed requires on parsedate.rb (in Ftptools)
|
||||
* Removed ftools from rake.rb. Made it options in sys.rb
|
||||
|
||||
== Version 0.8.0
|
||||
|
||||
* Added task parameters (e.g. "rake build[version7]")
|
||||
* Made task parameters passable to prerequisites.
|
||||
* Comments are limited to 80 columns or so (suggested by Jamis Buck).
|
||||
* Added -D to display full comments (suggested by Jamis Buck).
|
||||
* The rake program will set the status value used in any explicit
|
||||
exit(n) calls. (patch provided by Stephen Touset)
|
||||
* Fixed error in functional tests that were not including session (and
|
||||
silently skipping the functionl tests.
|
||||
* Removed --usage and make -h the same as -H.
|
||||
* Make a prettier inspect for tasks.
|
||||
|
||||
== Version 0.7.3
|
||||
|
||||
* Added existing and existing! methods to FileList
|
||||
* FileLists now claim to be Arrays (via is_a?) to get better support
|
||||
from the FileUtil module.
|
||||
* Added init and top_level for custom rake applications.
|
||||
|
||||
== Version 0.7.2
|
||||
|
||||
* Error messages are now send to stderr rather than stdout (from
|
||||
Payton Quackenbush).
|
||||
* Better error handling on invalid command line arguments (from Payton
|
||||
Quackenbush).
|
||||
* Added rcov task and updated unit testing for better code coverage.
|
||||
* Fixed some bugs where the application object was going to the global
|
||||
appliation instead of using its own data.
|
||||
* Added square and curly bracket patterns to FileList#include (Tilman
|
||||
Sauerbeck).
|
||||
* Added plain filename support to rule dependents (suggested by Nobu
|
||||
Nakada).
|
||||
* Added pathmap support to rule dependents.
|
||||
* Added a 'tasks' method to a namespace to get a list of tasks
|
||||
associated with the namespace.
|
||||
* Fixed the method name leak from FileUtils (bug found by Glenn
|
||||
Vanderburg).
|
||||
* Added rake_extension to handle detection of extension collisions.
|
||||
* Added test for noop, bad_option and verbose flags to sh command.
|
||||
* Removed dependency on internal fu_xxx functions from FileUtils.
|
||||
* Added a 'shame' task to the Rakefile.
|
||||
* Added tar_command and zip_command options to the Package task.
|
||||
* Added a description to the gem task in GemPackageTask.
|
||||
* Fixed a bug when rules have multiple prerequisites (patch by Joel
|
||||
VanderWerf)
|
||||
* Added a protected 'require "rubygems"' to test/test_application to
|
||||
unbreak cruisecontrol.rb.
|
||||
* Added the handful of RakeFileUtils to the private method as well.
|
||||
* Added block based exclusion.
|
||||
* The clean task will no longer delete 'core' if it is a directory.
|
||||
* Removed rake_dup. Now we just simply rescue a bad dup.
|
||||
* Refactored the FileList reject logic to remove duplication.
|
||||
* Removed if __FILE__ at the end of the rake.rb file.
|
||||
|
||||
== Version 0.7.1
|
||||
|
||||
* Added optional filter parameter to the --tasks command line option.
|
||||
* Added flatten to allow rule transform procs to return lists of
|
||||
prereqs (Joel VanderWerf provided patch).
|
||||
* Added pathmap to String and FileList.
|
||||
* The -r option will now load .rake files (but a straight require
|
||||
doesn't yet). NOTE: This is experimental ... it may be
|
||||
discontinued.
|
||||
* The -f option without a value will disable the search for a
|
||||
Rakefile. The assumption is that the -r files are adequate.
|
||||
* Fixed the safe_ln function to fall back to cp in more error
|
||||
scenarios.
|
||||
|
||||
== Version 0.7.0
|
||||
|
||||
* Added Rake.original_dir to return the original starting directory of
|
||||
the rake application.
|
||||
* Added safe_ln support for openAFS (from Ludvig Omholt).
|
||||
* Added --trace reminder on short exception messages (David Heinemeier
|
||||
Hansson suggestion).
|
||||
* Added multitask declaration that executes prerequisites in
|
||||
parallel. (Doug Young providied an initial implementation).
|
||||
* Fixed missing_const hack to be compatible with Rails. (Jamis Buck
|
||||
supplied test case).
|
||||
* Made the RDoc task default to internal (in-process) RDoc formatting.
|
||||
The old behavior is still available by setting the +external+ flag
|
||||
to true.
|
||||
* Rakefiles are now loaded with the expanded path to prevent
|
||||
accidental polution from the Ruby load path.
|
||||
* The +namespace+ command now returns a NameSpace object that can be
|
||||
used to lookup tasks defined in that namespace. This allows for
|
||||
better anonymous namespace behavior.
|
||||
* Task objects my now be used in prerequisite lists directly.
|
||||
|
||||
== Version 0.6.1
|
||||
|
||||
* Rebuilt 0.6.0 gem without signing.
|
||||
|
||||
== Version 0.6.0
|
||||
|
||||
* Fixed file creation bug in the unit tests (caused infinite loop on
|
||||
windows).
|
||||
* Fixed bug where session based functional tests were run under
|
||||
windows.
|
||||
* Fixed bug in directory tasks so that updating a directory will not
|
||||
retrigger file tasks depending on the directory (see
|
||||
FileCreationTask and EarlyTime).
|
||||
* Added egrep to FileList
|
||||
* ruby command now runs same ruby version as rake.
|
||||
* Added investigation to task object. (suggested by Martin Fowler)
|
||||
* Added ruby_opts to the test task to allow arbitrary ruby options to
|
||||
be passed to the test script. (Greg Fast)
|
||||
* Fixed the test loader to ignore options. (Greg Fast)
|
||||
* Moved Task, FileTask, FileCreationTask and RakeApp into the Rake
|
||||
module namespace. Old style namespace behavior can be invoked via
|
||||
the --classic-namespace option. (requested by Kelly Felkins).
|
||||
* GemTask is now sensitive to the gem platform (Masao Mutoh).
|
||||
* A non-existing file prerequisite will no longer cause an exception
|
||||
(Philipp Neubeck).
|
||||
* Multiple prerequisites on Rake rules now allowed (initial patch
|
||||
supplied by Stuart Jansen).
|
||||
|
||||
== Version 0.5.4
|
||||
|
||||
* Added double quotes to the test runner.
|
||||
* Added .svn to default ignore list.
|
||||
* Updated FileList#include to support nested arrays and filelists.
|
||||
|
||||
== Version 0.5.3
|
||||
|
||||
* Added support for importing Rakefile and other dependencies.
|
||||
* Fixed bug so that now rules can chain off of existing tasks as well
|
||||
as existing files.
|
||||
* Fixed verbose flag bug in the testing task. Shortened some failure
|
||||
messages.
|
||||
* Make FileUtils methods private at the top level module to avoid
|
||||
accidental method leaking into other objects.
|
||||
* Added test loader option to test task. "testrb" is no longer the
|
||||
default test loader. It is now eating syntax errors that should
|
||||
halt the unit tests.
|
||||
* Revamped FileList so that it works more like and array (addressed
|
||||
flatten bug). Added many tests around file list.
|
||||
* Added +ext+ method to both String and FileList.
|
||||
|
||||
== Version 0.5.0
|
||||
|
||||
* Fixed documentation that was lacking the Rake module name (Tilman
|
||||
Sauerbeck).
|
||||
* Added tar.gz and tar.bz2 support to package task (Tilman Sauerbeck).
|
||||
* Recursive rules are now supported (Tilman Sauerbeck).
|
||||
* Added warning option for the Test Task (requested by Eric Hodel).
|
||||
* The jamis rdoc template is only used if it exists.
|
||||
* Added fix for Ruby 1.8.2 test/unit and rails problem.
|
||||
* Added contributed rake man file (Jani Monoses).
|
||||
* Added Brian Candler's fix for problems in --trace and --dry-run
|
||||
mode.
|
||||
|
||||
== Version 0.4.15
|
||||
|
||||
* Fixed a bug that prevented the TESTOPTS flag from working with the
|
||||
revised for 1.8.2 test task.
|
||||
* Updated the docs on --trace to indicate that it also enables a full
|
||||
backtrace on errors.
|
||||
|
||||
== Version 0.4.14
|
||||
|
||||
* Modified the TestTask to workaround the Ruby 1.8.2 change in
|
||||
autoexecuting unit tests.
|
||||
|
||||
== Version 0.4.13
|
||||
|
||||
* Fixed the dry-run flag so it is operating again.
|
||||
* Multiple arguments to sh and ruby commands will not be interpreted
|
||||
by the shell (patch provided by Jonathan Paisley).
|
||||
|
||||
== Version 0.4.12
|
||||
|
||||
* Added --silent (-s) to suppress the (in directory) rake message.
|
||||
|
||||
== Version 0.4.11
|
||||
|
||||
* Changed the "don't know how to rake" message (finally)
|
||||
* Changes references to a literal "Rakefile" to reference the global
|
||||
variable $rakefile (which contains the actual name of the rakefile).
|
||||
|
||||
== Version 0.4.10
|
||||
|
||||
* Added block support to the "sh" command, allowing users to take
|
||||
special actions on the result of the system call. E.g.
|
||||
|
||||
sh "shell_command" do |ok, res|
|
||||
puts "Program returned #{res.exitstatus}" if ! ok
|
||||
end
|
||||
|
||||
== Version 0.4.9
|
||||
|
||||
* Switched to Jamis Buck's RDoc template.
|
||||
* Removed autorequire from Rake's gem spec. This prevents the Rake
|
||||
libraries from loading while using rails.
|
||||
|
||||
== Version 0.4.8
|
||||
|
||||
* Added support for .rb versions of Rakefile.
|
||||
* Removed \\\n's from test task.
|
||||
* Fixed Ruby 1.9 compatibility issue with FileList.
|
||||
|
||||
== Version 0.4.7
|
||||
|
||||
* Fixed problem in FileList that caused Ruby 1.9 to go into infinite
|
||||
recursion. Since to_a was removed from Object, it does not need to
|
||||
added back into the list of methods to rewrite in FileList. (Thanks
|
||||
to Kent Sibilev for pointing this out).
|
||||
|
||||
== Version 0.4.6
|
||||
* Removed test version of ln in FileUtils that prevented safe_ln from
|
||||
using ln.
|
||||
|
||||
== Version 0.4.5
|
||||
* Upgraded comments in TestTask.
|
||||
* FileList to_s and inspect now automatically resolve pending changes.
|
||||
* FileList#exclude properly returns the FileList.
|
||||
|
||||
== Version 0.4.4
|
||||
* Fixed initialization problem with @comment.
|
||||
* Now using multi -r technique in TestTask. Switch Rakefile back to
|
||||
using the built-in test task macros because the rake runtime is no
|
||||
longer needed.
|
||||
* Added 'TEST=filename' and 'TESTOPTS=options' to the Test Task
|
||||
macros.
|
||||
* Allow a +test_files+ attribute in test tasks. This allows more
|
||||
flexibility in specifying test files.
|
||||
|
||||
== Version 0.4.3
|
||||
* Fixed Comment leakage.
|
||||
|
||||
== Version 0.4.2
|
||||
* Added safe_ln that falls back to a copy if a file link is not supported.
|
||||
* Package builder now uses safe_ln.
|
||||
|
||||
== Version 0.4.1
|
||||
* Task comments are now additive, combined with "/".
|
||||
* Works with (soon to be released) rubygems 0.6.2 (or 0.7.0)
|
||||
|
||||
== Version 0.4.0
|
||||
* FileList now uses deferred loading. The file system is not searched
|
||||
until the first call that needs the file names.
|
||||
* VAR=VALUE options are now accepted on the command line and are
|
||||
treated like environment variables. The values may be tested in a
|
||||
Rakefile by referencing ENV['VAR'].
|
||||
* File.mtime is now used (instead of File.new().mtime).
|
||||
|
||||
== Version 0.3.2.x
|
||||
|
||||
* Removed some hidden dependencies on rubygems. Tests now will test
|
||||
gems only if they are installed.
|
||||
* Removed Sys from some example files. I believe that is that last
|
||||
reference to Sys outside of the contrib area.
|
||||
* Updated all copyright notices to include 2004.
|
||||
|
||||
== Version 0.3.2
|
||||
|
||||
* GEM Installation now works with the application stub.
|
||||
|
||||
== Version 0.3.1
|
||||
|
||||
* FileLists now automatically ignore CVS, .bak, !
|
||||
* GEM Installation now works.
|
||||
|
||||
== Version 0.3.0
|
||||
|
||||
Promoted 0.2.10.
|
||||
|
||||
== Version 0.2.10
|
||||
General
|
||||
|
||||
* Added title to Rake's rdocs
|
||||
* Contrib packages are no longer included in the documentation.
|
||||
|
||||
RDoc Issues
|
||||
|
||||
* Removed default for the '--main' option
|
||||
* Fixed rendering of the rdoc options
|
||||
* Fixed clean/clobber confusion with rerdoc
|
||||
* 'title' attribute added
|
||||
|
||||
Package Task Library Issues
|
||||
|
||||
* Version (or explicit :noversion) is required.
|
||||
* +package_file+ attribute is now writable
|
||||
|
||||
FileList Issues
|
||||
|
||||
* Dropped bang version of exclude. Now using ant-like include/exclude semantics.
|
||||
* Enabled the "yield self" idiom in FileList#initialize.
|
||||
|
||||
== Version 0.2.9
|
||||
|
||||
This version contains numerous changes as the RubyConf.new(2003)
|
||||
presentation was being prepared. The changes include:
|
||||
|
||||
* The monolithic rubyapp task library is in the process of being
|
||||
dropped in favor of lighter weight task libraries.
|
||||
|
||||
== Version 0.2.7
|
||||
|
||||
* Added "desc" for task descriptions.
|
||||
* -T will now display tasks with descriptions.
|
||||
* -P will display tasks and prerequisites.
|
||||
* Dropped the Sys module in favor of the 1.8.x FileUtils module. Sys
|
||||
is still supported in the contrib area.
|
||||
|
||||
== Version 0.2.6
|
||||
|
||||
* Moved to RubyForge
|
||||
|
||||
== Version 0.2.5
|
||||
|
||||
* Switched to standard ruby app builder.
|
||||
* Added no_match option to file matcher.
|
||||
|
||||
== Version 0.2.4
|
||||
|
||||
* Fixed indir, which neglected to actually change directories.
|
||||
|
||||
== Version 0.2.3
|
||||
|
||||
* Added rake module for a help target
|
||||
* Added 'for_files' to Sys
|
||||
* Added a $rakefile constant
|
||||
* Added test for selecting proper rule with multiple targets.
|
196
doc/rake/README
196
doc/rake/README
|
@ -1,196 +0,0 @@
|
|||
= RAKE -- Ruby Make
|
||||
|
||||
Supporting Rake version: 0.8.6
|
||||
|
||||
This package contains Rake, a simple ruby build program with
|
||||
capabilities similar to make.
|
||||
|
||||
Rake has the following features:
|
||||
|
||||
* Rakefiles (rake's version of Makefiles) are completely defined in
|
||||
standard Ruby syntax. No XML files to edit. No quirky Makefile
|
||||
syntax to worry about (is that a tab or a space?)
|
||||
|
||||
* Users can specify tasks with prerequisites.
|
||||
|
||||
* Rake supports rule patterns to synthesize implicit tasks.
|
||||
|
||||
* Flexible FileLists that act like arrays but know about manipulating
|
||||
file names and paths.
|
||||
|
||||
* A library of prepackaged tasks to make building rakefiles easier. For example,
|
||||
tasks for building tarballs, gems and RDoc output are provided.
|
||||
|
||||
* Supports parallel execution of tasks.
|
||||
|
||||
|
||||
== Installation
|
||||
|
||||
=== Gem Installation
|
||||
|
||||
Download and install rake with the following.
|
||||
|
||||
gem install rake
|
||||
|
||||
=== Normal Installation
|
||||
|
||||
You can download the source tarball of the latest version of Rake from
|
||||
|
||||
* http://rubyforge.org/project/showfiles.php?group_id=50
|
||||
|
||||
Extract the tarball and run
|
||||
|
||||
% ruby install.rb
|
||||
|
||||
from its distribution directory.
|
||||
|
||||
== Usage
|
||||
|
||||
=== Simple Example
|
||||
|
||||
First, you must write a "Rakefile" file which contains the build rules. Here's
|
||||
a simple example:
|
||||
|
||||
task :default => [:test]
|
||||
|
||||
task :test do
|
||||
ruby "test/unittest.rb"
|
||||
end
|
||||
|
||||
This Rakefile has two tasks:
|
||||
|
||||
* A task named "test", which - upon invocation - will run a unit test file in
|
||||
Ruby.
|
||||
* A task named "default". This task does nothing by itself, but it has exactly
|
||||
one dependency, namely the "test" task. Invoking the "default" task will
|
||||
cause Rake to invoke the "test" task as well.
|
||||
|
||||
Running the "rake" command without any options will cause it to run the
|
||||
"default" task in the Rakefile:
|
||||
|
||||
% ls
|
||||
Rakefile test/
|
||||
% rake
|
||||
(in /home/some_user/Projects/rake)
|
||||
ruby test/unittest.rb
|
||||
....unit test output here...
|
||||
|
||||
Type "rake --help" for all available options.
|
||||
|
||||
|
||||
=== More Information
|
||||
|
||||
* For details on Rake's command-line invocation, read
|
||||
doc/command_line_usage.rdoc[http://rake.rubyforge.org/files/doc/command_line_usage_rdoc.html]
|
||||
* For details on writing Rakefiles, see
|
||||
doc/rakefile.rdoc[http://rake.rubyforge.org/files/doc/rakefile_rdoc.html].
|
||||
* For the original announcement of Rake, see
|
||||
doc/rational.rdoc[http://rake.rubyforge.org/files/doc/rational_rdoc.html].
|
||||
* For a glossary of terms, see
|
||||
doc/glossary.rdoc[http://rake.rubyforge.org/files/doc/glossary_rdoc.html].
|
||||
|
||||
|
||||
== Development
|
||||
|
||||
=== Source Repository
|
||||
|
||||
Rake is currently hosted at github. The github web page is
|
||||
http://github.com/jimweirich/rake. The public git clone URL is
|
||||
|
||||
* git://github.com/jimweirich/rake.git
|
||||
|
||||
=== Running the Rake Test Suite
|
||||
|
||||
If you wish to run the unit and functional tests that come with Rake:
|
||||
|
||||
* Install the 'session' gem in order to run the functional tests.
|
||||
* CD into the top project directory of rake.
|
||||
* Type one of the following:
|
||||
|
||||
rake # If you have a version of rake installed
|
||||
ruby -Ilib bin/rake # If you do not have a version of rake installed.
|
||||
|
||||
=== Issues and Bug Reports
|
||||
|
||||
Bugs, features requests and other issues can be logged at
|
||||
|
||||
* http://onestepback.org/redmine/projects/show/rake
|
||||
|
||||
You will need an account to before you can post issues. Register at
|
||||
http://onestepback.org/redmine/account/register. Or you can send me
|
||||
an email (at jim dot weirich at gmail dot com)
|
||||
|
||||
|
||||
== Online Resources
|
||||
|
||||
=== Rake References
|
||||
|
||||
* Rake Documentation Home: http://docs.rubyrake.org
|
||||
* Rake Project Page: http://rubyforge.org/projects/rake
|
||||
* Rake API Documents: http://rake.rubyforge.org
|
||||
* Rake Source Code Repo: http://github.com/jimweirich/rake
|
||||
* Rake Git Repo Clone URL: git://github.com/jimweirich/rake.git
|
||||
|
||||
=== Presentations and Articles about Rake
|
||||
|
||||
* Jim Weirich's 2003 RubyConf presentation: http://onestepback.org/articles/buildingwithrake/
|
||||
* Martin Fowler's article on Rake: http://martinfowler.com/articles/rake.html
|
||||
|
||||
== Other Make Reinvisionings ...
|
||||
|
||||
Rake is a late entry in the make replacement field. Here are links to
|
||||
other projects with similar (and not so similar) goals.
|
||||
|
||||
* http://directory.fsf.org/bras.html -- Bras, one of earliest
|
||||
implementations of "make in a scripting language".
|
||||
* http://www.a-a-p.org -- Make in Python
|
||||
* http://www.aromatic.com/tools/jam.txt -- JAM, Java Automated Make
|
||||
* http://ant.apache.org -- The Ant project
|
||||
* http://ppt.perl.org/commands/make/index.html -- Make from the Perl
|
||||
Power Tools implementation.
|
||||
* http://search.cpan.org/search?query=PerlBuildSystem -- The Perl Build System
|
||||
* http://make.rubyforge.org -- Rant, another Ruby make tool.
|
||||
|
||||
== Credits
|
||||
|
||||
[<b>Ryan Dlugosz</b>] For the initial conversation that sparked Rake.
|
||||
|
||||
[<b>nobu.nokada@softhome.net</b>] For the initial patch for rule support.
|
||||
|
||||
[<b>Tilman Sauerbeck <tilman@code-monkey.de></b>] For the recursive rule patch.
|
||||
|
||||
== License
|
||||
|
||||
Rake is available under an MIT-style license.
|
||||
|
||||
:include: MIT-LICENSE
|
||||
|
||||
== Support
|
||||
|
||||
The Rake homepage is http://rake.rubyforge.org. You can find the Rake
|
||||
RubyForge page at http://rubyforge.org/projects/rake.
|
||||
|
||||
Feel free to submit commits or feature requests. If you send a patch,
|
||||
remember to update the corresponding unit tests. If fact, I prefer
|
||||
new feature to be submitted in the form of new unit tests.
|
||||
|
||||
For other information, feel free to ask on the ruby-talk mailing list
|
||||
(which is mirrored to comp.lang.ruby) or contact
|
||||
jim dot weirich at gmail.com.
|
||||
|
||||
---
|
||||
|
||||
= Other stuff
|
||||
|
||||
Author:: Jim Weirich <jim.weirich@gmail.com>
|
||||
Requires:: Ruby 1.8.0 or later
|
||||
License:: Copyright 2003-2008 by Jim Weirich.
|
||||
Released under an MIT-style license. See the LICENSE file
|
||||
included in the distribution.
|
||||
|
||||
== Warranty
|
||||
|
||||
This software is provided "as is" and without any express or
|
||||
implied warranties, including, without limitation, the implied
|
||||
warranties of merchantibility and fitness for a particular
|
||||
purpose.
|
|
@ -1,169 +0,0 @@
|
|||
= Rake Command Line Usage
|
||||
|
||||
Rake is invoked from the command line using:
|
||||
|
||||
% rake [options ...] [VAR=VALUE ...] [targets ...]
|
||||
|
||||
Options are:
|
||||
|
||||
[<tt><em>name</em>=<em>value</em></tt>]
|
||||
Set the environment variable <em>name</em> to <em>value</em>
|
||||
during the execution of the <b>rake</b> command. You can access
|
||||
the value by using ENV['<em>name</em>'].
|
||||
|
||||
[<tt>--all</tt> (-A)]
|
||||
Used in combination with the -T and -D options, will force
|
||||
those options to show all the tasks, even the ones without comments.
|
||||
|
||||
[<tt>--backtrace</tt>{=_output_} (-n)]
|
||||
Enable a full backtrace (i.e. like --trace, but without the task
|
||||
tracing details). The _output_ parameter is optional, but if
|
||||
specified it controls where the backtrace output is sent. If
|
||||
_output_ is <tt>stdout</tt>, then backtrace output is directed to
|
||||
stardard output. If _output_ is <tt>stderr</tt>, or if it is
|
||||
missing, then the backtrace output is sent to standard error.
|
||||
|
||||
[<tt>--classic-namespace</tt> (-n)]
|
||||
Import the Task, FileTask, and FileCreateTask into the top-level
|
||||
scope to be compatible with older versions of Rake. Alternatively
|
||||
you can include the line <code>require
|
||||
'rake/classic_namespace'</code> in your Rakefile to get the
|
||||
classic behavior.
|
||||
|
||||
[<tt>--comments</tt>]
|
||||
Used in combination with the -W options to force the output to
|
||||
contain commented options only. This is the reverse of
|
||||
<tt>--all</tt>.
|
||||
|
||||
[<tt>--describe</tt> _pattern_ (-D)]
|
||||
Describe the tasks (matching optional PATTERN), then exit.
|
||||
|
||||
[<tt>--dry-run</tt> (-n)]
|
||||
Do a dry run. Print the tasks invoked and executed, but do not
|
||||
actually execute any of the actions.
|
||||
|
||||
[<tt>--execute</tt> _code_ (-e)]
|
||||
Execute some Ruby code and exit.
|
||||
|
||||
[<tt>--execute-print</tt> _code_ (-p)]
|
||||
Execute some Ruby code, print the result, and exit.
|
||||
|
||||
[<tt>--execute-continue</tt> _code_ (-E)]
|
||||
Execute some Ruby code, then continue with normal task processing.
|
||||
|
||||
[<tt>--help</tt> (-H)]
|
||||
Display some help text and exit.
|
||||
|
||||
[<tt>--jobs</tt> _number_ (-j)]
|
||||
Specifies the number of active concurrent tasks used. The
|
||||
suggested value is equal to the number of CPUs. The concurrent
|
||||
tasks are used to execute the <tt>multitask</tt> prerequisites.
|
||||
Also see the <tt>-m</tt> option which turns all tasks into
|
||||
multitasks.
|
||||
|
||||
Sample values:
|
||||
(no -j) : unlimited concurrent tasks (standard rake behavior)
|
||||
-j : 2 concurrent tasks (exact number may change)
|
||||
-j 16 : 16 concurrent tasks
|
||||
|
||||
[<tt>--job-stats</tt> _level_]
|
||||
|
||||
Display job statistics at the completion of the run. By default,
|
||||
this will display the requested number of active tasks (from the
|
||||
-j options) and the maximum number of tasks in play at any given
|
||||
time.
|
||||
|
||||
If the optional _level_ is <tt>history</tt>, then a complete trace
|
||||
of task history will be displayed on standard output.
|
||||
|
||||
[<tt>--libdir</tt> _directory_ (-I)]
|
||||
Add _directory_ to the list of directories searched for require.
|
||||
|
||||
[<tt>--multitask</tt> (-m)]
|
||||
Treat all tasks as multitasks. ('make/drake' semantics)
|
||||
|
||||
[<tt>--nosearch</tt> (-N)]
|
||||
Do not search for a Rakefile in parent directories.
|
||||
|
||||
[<tt>--prereqs</tt> (-P)]
|
||||
Display a list of all tasks and their immediate prerequisites.
|
||||
|
||||
[<tt>--quiet</tt> (-q)]
|
||||
Do not echo commands from FileUtils.
|
||||
|
||||
[<tt>--rakefile</tt> _filename_ (-f)]
|
||||
Use _filename_ as the name of the rakefile. The default rakefile
|
||||
names are +rakefile+ and +Rakefile+ (with +rakefile+ taking
|
||||
precedence). If the rakefile is not found in the current
|
||||
directory, +rake+ will search parent directories for a match. The
|
||||
directory where the Rakefile is found will become the current
|
||||
directory for the actions executed in the Rakefile.
|
||||
|
||||
[<tt>--rakelibdir</tt> _rakelibdir_ (-R)]
|
||||
Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')
|
||||
|
||||
[<tt>--reduce-compat</tt>]
|
||||
|
||||
Remove the DSL commands from the Object inheritance hierarchy and
|
||||
do not define top level constants. This reduces the backwards
|
||||
compatibility of Rake, but allows rake to be used with software
|
||||
that would otherwise have conflicting definitions.
|
||||
|
||||
*NOTE:* The next major version of Rake will only be able to be run
|
||||
in "reduce-compat" mode.
|
||||
|
||||
[<tt>--require</tt> _name_ (-r)]
|
||||
Require _name_ before executing the Rakefile.
|
||||
|
||||
[<tt>--rules</tt>]
|
||||
Trace the rules resolution.
|
||||
|
||||
[<tt>--silent (-s)</tt>]
|
||||
Like --quiet, but also suppresses the 'in directory' announcement.
|
||||
|
||||
[<tt>--suppress-backtrace _pattern_ </tt>]
|
||||
Line matching the regular expression _pattern_ will be removed
|
||||
from the backtrace output. Note that the --backtrace option is the
|
||||
full backtrace without these lines suppressed.
|
||||
|
||||
[<tt>--system</tt> (-g)]
|
||||
Use the system wide (global) rakefiles. The project Rakefile is
|
||||
ignored. By default, the system wide rakefiles are used only if no
|
||||
project Rakefile is found. On Unix-like system, the system wide
|
||||
rake files are located in $HOME/.rake. On a windows system they
|
||||
are stored in $APPDATA/Rake.
|
||||
|
||||
[<tt>--no-system</tt> (-G)]
|
||||
Use the project level Rakefile, ignoring the system-wide (global)
|
||||
rakefiles.
|
||||
|
||||
[<tt>--tasks</tt> <em>pattern</em> (-T)]
|
||||
Display a list of the major tasks and their comments. Comments
|
||||
are defined using the "desc" command. If a pattern is given, then
|
||||
only tasks matching the pattern are displayed.
|
||||
|
||||
[<tt>--trace</tt>{=_output_} (-t)]
|
||||
Turn on invoke/execute tracing. Also enable full backtrace on
|
||||
errors. The _output_ parameter is optional, but if specified it
|
||||
controls where the trace output is sent. If _output_ is
|
||||
<tt>stdout</tt>, then trace output is directed to stardard output.
|
||||
If _output_ is <tt>stderr</tt>, or if it is missing, then trace
|
||||
output is sent to standard error.
|
||||
|
||||
[<tt>--verbose</tt> (-v)]
|
||||
Echo the Sys commands to standard output.
|
||||
|
||||
[<tt>--version</tt> (-V)]
|
||||
Display the program version and exit.
|
||||
|
||||
[<tt>--where</tt> <em>pattern</em> (-W)]
|
||||
Display tasks that match <em>pattern</em> and the file and line
|
||||
number where the task is defined. By default this option will
|
||||
display all tasks, not just the tasks that have descriptions.
|
||||
|
||||
[<tt>--no-deprecation-warnings</tt> (-W)]
|
||||
Do not display the deprecation warnings.
|
||||
|
||||
In addition, any command line option of the form
|
||||
<em>VAR</em>=<em>VALUE</em> will be added to the environment hash
|
||||
<tt>ENV</tt> and may be tested in the Rakefile.
|
|
@ -1,38 +0,0 @@
|
|||
# Example Rakefile -*- ruby -*-
|
||||
|
||||
task :default => [:main]
|
||||
|
||||
file "a.o" => ["a.c"] do |t|
|
||||
src = t.name.sub(/\.o$/, '.c')
|
||||
sh "gcc #{src} -c -o #{t.name}"
|
||||
end
|
||||
|
||||
file "b.o" => ["b.c"] do |t|
|
||||
src = t.name.sub(/\.o$/, '.c')
|
||||
sh "gcc #{src} -c -o #{t.name}"
|
||||
end
|
||||
|
||||
file "main.o" => ["main.c"] do |t|
|
||||
src = t.name.sub(/\.o$/, '.c')
|
||||
sh "gcc #{src} -c -o #{t.name}"
|
||||
end
|
||||
|
||||
OBJFILES = ["a.o", "b.o", "main.o"]
|
||||
task :obj => OBJFILES
|
||||
|
||||
file "main" => OBJFILES do |t|
|
||||
sh "gcc -o #{t.name} main.o a.o b.o"
|
||||
end
|
||||
|
||||
task :clean do
|
||||
rm_f FileList['*.o']
|
||||
Dir['*~'].each { |fn| rm_f fn }
|
||||
end
|
||||
|
||||
task :clobber => [:clean] do
|
||||
rm_f "main"
|
||||
end
|
||||
|
||||
task :run => ["main"] do
|
||||
sh "./main"
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
# Example Rakefile -*- ruby -*-
|
||||
# Using the power of Ruby
|
||||
|
||||
task :default => [:main]
|
||||
|
||||
def ext(fn, newext)
|
||||
fn.sub(/\.[^.]+$/, newext)
|
||||
end
|
||||
|
||||
SRCFILES = Dir['*.c']
|
||||
OBJFILES = SRCFILES.collect { |fn| ext(fn,".o") }
|
||||
|
||||
OBJFILES.each do |objfile|
|
||||
srcfile = ext(objfile, ".c")
|
||||
file objfile => [srcfile] do |t|
|
||||
sh "gcc #{srcfile} -c -o #{t.name}"
|
||||
end
|
||||
end
|
||||
|
||||
file "main" => OBJFILES do |t|
|
||||
sh "gcc -o #{t.name} main.o a.o b.o"
|
||||
end
|
||||
|
||||
task :clean do
|
||||
rm_f FileList['*.o']
|
||||
Dir['*~'].each { |fn| rm_f fn }
|
||||
end
|
||||
|
||||
task :clobber => [:clean] do
|
||||
rm_f "main"
|
||||
end
|
||||
|
||||
task :run => ["main"] do
|
||||
sh "./main"
|
||||
end
|
|
@ -1,6 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void a()
|
||||
{
|
||||
printf ("In function a\n");
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void b()
|
||||
{
|
||||
printf ("In function b\n");
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
extern void a();
|
||||
extern void b();
|
||||
|
||||
int main ()
|
||||
{
|
||||
a();
|
||||
b();
|
||||
return 0;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
= Glossary
|
||||
|
||||
[<b>action</b>]
|
||||
Code to be executed in order to perform a task. Actions in a
|
||||
rakefile are specified in a code block (usually delimited by
|
||||
+do+/+end+ pairs.
|
||||
|
||||
[<b>execute</b>]
|
||||
When a task is executed, all of its actions are performed, in
|
||||
the order they were defined. Note that unlike
|
||||
<tt>invoke</tt>, <tt>execute</tt> always executes the actions
|
||||
(without invoking or executing the prerequisites).
|
||||
|
||||
[<b>file task</b> (FileTask)]
|
||||
A file task is a task whose purpose is to create a file
|
||||
(which has the same name as the task). When invoked, a file
|
||||
task will only execute if one or more of the following
|
||||
conditions are true.
|
||||
|
||||
1. The associated file does not exist.
|
||||
2. A prerequisite has a later time stamp than the existing file.
|
||||
|
||||
Because normal Tasks always have the current time as
|
||||
timestamp, a FileTask that has a normal Task prerequisite
|
||||
will always execute.
|
||||
|
||||
[<b>invoke</b>]
|
||||
When a task is invoked, first we check to see if it has been
|
||||
invoked before. if it has been, then nothing else is done.
|
||||
If this is the first time its been invoked, then we invoke
|
||||
each of its prerequisites. Finally, we check to see if we
|
||||
need to execute the actions of this task by calling
|
||||
<tt>needed?</tt>. Finally, if the task is needed, we execute
|
||||
its actions.
|
||||
|
||||
NOTE: Currently prerequisites are invoked even if the task is
|
||||
not needed. This may change in the future.
|
||||
|
||||
[<b>prerequisites</b>]
|
||||
Every task has a set (possibly empty) of prerequisites. A
|
||||
prerequisite P to Task T is itself a task that must be invoked
|
||||
before Task T.
|
||||
|
||||
[<b>rule</b>]
|
||||
A rule is a recipe for synthesizing a task when no task is
|
||||
explicitly defined. Rules generally synthesize file tasks.
|
||||
|
||||
[<b>task</b> (Task)]
|
||||
Basic unit of work in a rakefile. A task has a name, a set of
|
||||
prerequisites and a list of actions to be performed.
|
||||
|
|
@ -1,591 +0,0 @@
|
|||
module RDoc
|
||||
module Page
|
||||
|
||||
FONTS = "\"Bitstream Vera Sans\", Verdana, Arial, Helvetica, sans-serif"
|
||||
|
||||
STYLE = <<CSS
|
||||
a {
|
||||
color: #00F;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #77F;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
body, td, p {
|
||||
font-family: %fonts%;
|
||||
background: #FFF;
|
||||
color: #000;
|
||||
margin: 0px;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin: 2em;
|
||||
}
|
||||
|
||||
#description p {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.sectiontitle {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
padding: 0.5em;
|
||||
padding-left: 2em;
|
||||
background: #005;
|
||||
color: #FFF;
|
||||
font-weight: bold;
|
||||
border: 1px dotted black;
|
||||
}
|
||||
|
||||
.attr-rw {
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
text-align: center;
|
||||
color: #055;
|
||||
}
|
||||
|
||||
.attr-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.attr-desc {
|
||||
}
|
||||
|
||||
.attr-value {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.file-title-prefix {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.file-title {
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
background: #005;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.banner {
|
||||
background: #005;
|
||||
color: #FFF;
|
||||
border: 1px solid black;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.banner td {
|
||||
background: transparent;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
h1 a, h2 a, .sectiontitle a, .banner a {
|
||||
color: #FF0;
|
||||
}
|
||||
|
||||
h1 a:hover, h2 a:hover, .sectiontitle a:hover, .banner a:hover {
|
||||
color: #FF7;
|
||||
}
|
||||
|
||||
.dyn-source {
|
||||
display: none;
|
||||
background: #FFE;
|
||||
color: #000;
|
||||
border: 1px dotted black;
|
||||
margin: 0.5em 2em 0.5em 2em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.dyn-source .cmt {
|
||||
color: #00F;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.dyn-source .kw {
|
||||
color: #070;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.method {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.description pre {
|
||||
padding: 0.5em;
|
||||
border: 1px dotted black;
|
||||
background: #FFE;
|
||||
}
|
||||
|
||||
.method .title {
|
||||
font-family: monospace;
|
||||
font-size: large;
|
||||
border-bottom: 1px dashed black;
|
||||
margin-bottom: 0.3em;
|
||||
padding-bottom: 0.1em;
|
||||
}
|
||||
|
||||
.method .description, .method .sourcecode {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.description p, .sourcecode p {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.method .sourcecode p.source-link {
|
||||
text-indent: 0em;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.method .aka {
|
||||
margin-top: 0.3em;
|
||||
margin-left: 1em;
|
||||
font-style: italic;
|
||||
text-indent: 2em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding: 1em;
|
||||
border: 1px solid black;
|
||||
font-size: x-large;
|
||||
font-weight: bold;
|
||||
color: #FFF;
|
||||
background: #007;
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding: 0.5em 1em 0.5em 1em;
|
||||
border: 1px solid black;
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
color: #FFF;
|
||||
background: #009;
|
||||
}
|
||||
|
||||
h3, h4, h5, h6 {
|
||||
padding: 0.2em 1em 0.2em 1em;
|
||||
border: 1px dashed black;
|
||||
color: #000;
|
||||
background: #AAF;
|
||||
}
|
||||
|
||||
.sourcecode > pre {
|
||||
padding: 0.5em;
|
||||
border: 1px dotted black;
|
||||
background: #FFE;
|
||||
}
|
||||
|
||||
CSS
|
||||
|
||||
XHTML_PREAMBLE = %{<?xml version="1.0" encoding="%charset%"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
}
|
||||
|
||||
HEADER = XHTML_PREAMBLE + <<ENDHEADER
|
||||
<html>
|
||||
<head>
|
||||
<title>%title%</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
|
||||
<link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
|
||||
|
||||
<script language="JavaScript" type="text/javascript">
|
||||
// <![CDATA[
|
||||
|
||||
function toggleSource( id )
|
||||
{
|
||||
var elem
|
||||
var link
|
||||
|
||||
if( document.getElementById )
|
||||
{
|
||||
elem = document.getElementById( id )
|
||||
link = document.getElementById( "l_" + id )
|
||||
}
|
||||
else if ( document.all )
|
||||
{
|
||||
elem = eval( "document.all." + id )
|
||||
link = eval( "document.all.l_" + id )
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
if( elem.style.display == "block" )
|
||||
{
|
||||
elem.style.display = "none"
|
||||
link.innerHTML = "show source"
|
||||
}
|
||||
else
|
||||
{
|
||||
elem.style.display = "block"
|
||||
link.innerHTML = "hide source"
|
||||
}
|
||||
}
|
||||
|
||||
function openCode( url )
|
||||
{
|
||||
window.open( url, "SOURCE_CODE", "width=400,height=400,scrollbars=yes" )
|
||||
}
|
||||
// ]]>
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
ENDHEADER
|
||||
|
||||
FILE_PAGE = <<HTML
|
||||
<table border='0' cellpadding='0' cellspacing='0' width="100%" class='banner'>
|
||||
<tr><td>
|
||||
<table width="100%" border='0' cellpadding='0' cellspacing='0'><tr>
|
||||
<td class="file-title" colspan="2"><span class="file-title-prefix">File</span><br />%short_name%</td>
|
||||
<td align="right">
|
||||
<table border='0' cellspacing="0" cellpadding="2">
|
||||
<tr>
|
||||
<td>Path:</td>
|
||||
<td>%full_path%
|
||||
IF:cvsurl
|
||||
(<a href="%cvsurl%">CVS</a>)
|
||||
ENDIF:cvsurl
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Modified:</td>
|
||||
<td>%dtm_modified%</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table><br>
|
||||
HTML
|
||||
|
||||
###################################################################
|
||||
|
||||
CLASS_PAGE = <<HTML
|
||||
<table width="100%" border='0' cellpadding='0' cellspacing='0' class='banner'><tr>
|
||||
<td class="file-title"><span class="file-title-prefix">%classmod%</span><br />%full_name%</td>
|
||||
<td align="right">
|
||||
<table cellspacing=0 cellpadding=2>
|
||||
<tr valign="top">
|
||||
<td>In:</td>
|
||||
<td>
|
||||
START:infiles
|
||||
HREF:full_path_url:full_path:
|
||||
IF:cvsurl
|
||||
(<a href="%cvsurl%">CVS</a>)
|
||||
ENDIF:cvsurl
|
||||
END:infiles
|
||||
</td>
|
||||
</tr>
|
||||
IF:parent
|
||||
<tr>
|
||||
<td>Parent:</td>
|
||||
<td>
|
||||
IF:par_url
|
||||
<a href="%par_url%">
|
||||
ENDIF:par_url
|
||||
%parent%
|
||||
IF:par_url
|
||||
</a>
|
||||
ENDIF:par_url
|
||||
</td>
|
||||
</tr>
|
||||
ENDIF:parent
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
HTML
|
||||
|
||||
###################################################################
|
||||
|
||||
METHOD_LIST = <<HTML
|
||||
<div id="content">
|
||||
IF:diagram
|
||||
<table cellpadding='0' cellspacing='0' border='0' width="100%"><tr><td align="center">
|
||||
%diagram%
|
||||
</td></tr></table>
|
||||
ENDIF:diagram
|
||||
|
||||
IF:description
|
||||
<div class="description">%description%</div>
|
||||
ENDIF:description
|
||||
|
||||
IF:requires
|
||||
<div class="sectiontitle">Required Files</div>
|
||||
<ul>
|
||||
START:requires
|
||||
<li>HREF:aref:name:</li>
|
||||
END:requires
|
||||
</ul>
|
||||
ENDIF:requires
|
||||
|
||||
IF:toc
|
||||
<div class="sectiontitle">Contents</div>
|
||||
<ul>
|
||||
START:toc
|
||||
<li><a href="#%href%">%secname%</a></li>
|
||||
END:toc
|
||||
</ul>
|
||||
ENDIF:toc
|
||||
|
||||
IF:methods
|
||||
<div class="sectiontitle">Methods</div>
|
||||
<ul>
|
||||
START:methods
|
||||
<li>HREF:aref:name:</li>
|
||||
END:methods
|
||||
</ul>
|
||||
ENDIF:methods
|
||||
|
||||
IF:includes
|
||||
<div class="sectiontitle">Included Modules</div>
|
||||
<ul>
|
||||
START:includes
|
||||
<li>HREF:aref:name:</li>
|
||||
END:includes
|
||||
</ul>
|
||||
ENDIF:includes
|
||||
|
||||
START:sections
|
||||
IF:sectitle
|
||||
<div class="sectiontitle"><a nem="%secsequence%">%sectitle%</a></div>
|
||||
IF:seccomment
|
||||
<div class="description">
|
||||
%seccomment%
|
||||
</div>
|
||||
ENDIF:seccomment
|
||||
ENDIF:sectitle
|
||||
|
||||
IF:classlist
|
||||
<div class="sectiontitle">Classes and Modules</div>
|
||||
%classlist%
|
||||
ENDIF:classlist
|
||||
|
||||
IF:constants
|
||||
<div class="sectiontitle">Constants</div>
|
||||
<table border='0' cellpadding='5'>
|
||||
START:constants
|
||||
<tr valign='top'>
|
||||
<td class="attr-name">%name%</td>
|
||||
<td>=</td>
|
||||
<td class="attr-value">%value%</td>
|
||||
</tr>
|
||||
IF:desc
|
||||
<tr valign='top'>
|
||||
<td> </td>
|
||||
<td colspan="2" class="attr-desc">%desc%</td>
|
||||
</tr>
|
||||
ENDIF:desc
|
||||
END:constants
|
||||
</table>
|
||||
ENDIF:constants
|
||||
|
||||
IF:attributes
|
||||
<div class="sectiontitle">Attributes</div>
|
||||
<table border='0' cellpadding='5'>
|
||||
START:attributes
|
||||
<tr valign='top'>
|
||||
<td class='attr-rw'>
|
||||
IF:rw
|
||||
[%rw%]
|
||||
ENDIF:rw
|
||||
</td>
|
||||
<td class='attr-name'>%name%</td>
|
||||
<td class='attr-desc'>%a_desc%</td>
|
||||
</tr>
|
||||
END:attributes
|
||||
</table>
|
||||
ENDIF:attributes
|
||||
|
||||
IF:method_list
|
||||
START:method_list
|
||||
IF:methods
|
||||
<div class="sectiontitle">%type% %category% methods</div>
|
||||
START:methods
|
||||
<div class="method">
|
||||
<div class="title">
|
||||
IF:callseq
|
||||
<a name="%aref%"></a><b>%callseq%</b>
|
||||
ENDIF:callseq
|
||||
IFNOT:callseq
|
||||
<a name="%aref%"></a><b>%name%</b>%params%
|
||||
ENDIF:callseq
|
||||
IF:codeurl
|
||||
[ <a href="javascript:openCode('%codeurl%')">source</a> ]
|
||||
ENDIF:codeurl
|
||||
</div>
|
||||
IF:m_desc
|
||||
<div class="description">
|
||||
%m_desc%
|
||||
</div>
|
||||
ENDIF:m_desc
|
||||
IF:aka
|
||||
<div class="aka">
|
||||
This method is also aliased as
|
||||
START:aka
|
||||
<a href="%aref%">%name%</a>
|
||||
END:aka
|
||||
</div>
|
||||
ENDIF:aka
|
||||
IF:sourcecode
|
||||
<div class="sourcecode">
|
||||
<p class="source-link">[ <a href="javascript:toggleSource('%aref%_source')" id="l_%aref%_source">show source</a> ]</p>
|
||||
<div id="%aref%_source" class="dyn-source">
|
||||
<pre>
|
||||
%sourcecode%
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
ENDIF:sourcecode
|
||||
</div>
|
||||
END:methods
|
||||
ENDIF:methods
|
||||
END:method_list
|
||||
ENDIF:method_list
|
||||
END:sections
|
||||
</div>
|
||||
HTML
|
||||
|
||||
FOOTER = <<ENDFOOTER
|
||||
</body>
|
||||
</html>
|
||||
ENDFOOTER
|
||||
|
||||
BODY = HEADER + <<ENDBODY
|
||||
!INCLUDE! <!-- banner header -->
|
||||
|
||||
<div id="bodyContent">
|
||||
#{METHOD_LIST}
|
||||
</div>
|
||||
|
||||
#{FOOTER}
|
||||
ENDBODY
|
||||
|
||||
########################## Source code ##########################
|
||||
|
||||
SRC_PAGE = XHTML_PREAMBLE + <<HTML
|
||||
<html>
|
||||
<head><title>%title%</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
|
||||
<style>
|
||||
.ruby-comment { color: green; font-style: italic }
|
||||
.ruby-constant { color: #4433aa; font-weight: bold; }
|
||||
.ruby-identifier { color: #222222; }
|
||||
.ruby-ivar { color: #2233dd; }
|
||||
.ruby-keyword { color: #3333FF; font-weight: bold }
|
||||
.ruby-node { color: #777777; }
|
||||
.ruby-operator { color: #111111; }
|
||||
.ruby-regexp { color: #662222; }
|
||||
.ruby-value { color: #662222; font-style: italic }
|
||||
.kw { color: #3333FF; font-weight: bold }
|
||||
.cmt { color: green; font-style: italic }
|
||||
.str { color: #662222; font-style: italic }
|
||||
.re { color: #662222; }
|
||||
</style>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<pre>%code%</pre>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
|
||||
########################## Index ################################
|
||||
|
||||
FR_INDEX_BODY = <<HTML
|
||||
!INCLUDE!
|
||||
HTML
|
||||
|
||||
FILE_INDEX = XHTML_PREAMBLE + <<HTML
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
|
||||
<style>
|
||||
<!--
|
||||
body {
|
||||
background-color: #EEE;
|
||||
font-family: #{FONTS};
|
||||
color: #000;
|
||||
margin: 0px;
|
||||
}
|
||||
.banner {
|
||||
background: #005;
|
||||
color: #FFF;
|
||||
padding: 0.2em;
|
||||
font-size: small;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
.entries {
|
||||
margin: 0.25em 1em 0 1em;
|
||||
font-size: x-small;
|
||||
}
|
||||
a {
|
||||
color: #00F;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
a:hover {
|
||||
color: #77F;
|
||||
text-decoration: underline;
|
||||
}
|
||||
-->
|
||||
</style>
|
||||
<base target="docwin">
|
||||
</head>
|
||||
<body>
|
||||
<div class="banner">%list_title%</div>
|
||||
<div class="entries">
|
||||
START:entries
|
||||
<a href="%href%">%name%</a><br>
|
||||
END:entries
|
||||
</div>
|
||||
</body></html>
|
||||
HTML
|
||||
|
||||
CLASS_INDEX = FILE_INDEX
|
||||
METHOD_INDEX = FILE_INDEX
|
||||
|
||||
INDEX = XHTML_PREAMBLE + <<HTML
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>%title%</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
|
||||
</head>
|
||||
|
||||
<frameset cols="20%,*">
|
||||
<frameset rows="15%,35%,50%">
|
||||
<frame src="fr_file_index.html" title="Files" name="Files" />
|
||||
<frame src="fr_class_index.html" name="Classes" />
|
||||
<frame src="fr_method_index.html" name="Methods" />
|
||||
</frameset>
|
||||
IF:inline_source
|
||||
<frame src="%initial_page%" name="docwin">
|
||||
ENDIF:inline_source
|
||||
IFNOT:inline_source
|
||||
<frameset rows="80%,20%">
|
||||
<frame src="%initial_page%" name="docwin">
|
||||
<frame src="blank.html" name="source">
|
||||
</frameset>
|
||||
ENDIF:inline_source
|
||||
<noframes>
|
||||
<body bgcolor="white">
|
||||
Click <a href="html/index.html">here</a> for a non-frames
|
||||
version of this page.
|
||||
</body>
|
||||
</noframes>
|
||||
</frameset>
|
||||
|
||||
</html>
|
||||
HTML
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
= Original Prototype Rake
|
||||
|
||||
This is the original 100 line prototype rake program.
|
||||
|
||||
---
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'ftools'
|
||||
|
||||
class Task
|
||||
TASKS = Hash.new
|
||||
|
||||
attr_reader :prerequisites
|
||||
|
||||
def initialize(task_name)
|
||||
@name = task_name
|
||||
@prerequisites = []
|
||||
@actions = []
|
||||
end
|
||||
|
||||
def enhance(deps=nil, &block)
|
||||
@prerequisites |= deps if deps
|
||||
@actions << block if block_given?
|
||||
self
|
||||
end
|
||||
|
||||
def name
|
||||
@name.to_s
|
||||
end
|
||||
|
||||
def invoke
|
||||
@prerequisites.each { |n| Task[n].invoke }
|
||||
execute if needed?
|
||||
end
|
||||
|
||||
def execute
|
||||
return if @triggered
|
||||
@triggered = true
|
||||
@actions.collect { |act| result = act.call(self) }.last
|
||||
end
|
||||
|
||||
def needed?
|
||||
true
|
||||
end
|
||||
|
||||
def timestamp
|
||||
Time.now
|
||||
end
|
||||
|
||||
class << self
|
||||
def [](task_name)
|
||||
TASKS[intern(task_name)] or fail "Don't know how to rake #{task_name}"
|
||||
end
|
||||
|
||||
def define_task(args, &block)
|
||||
case args
|
||||
when Hash
|
||||
fail "Too Many Target Names: #{args.keys.join(' ')}" if args.size > 1
|
||||
fail "No Task Name Given" if args.size < 1
|
||||
task_name = args.keys[0]
|
||||
deps = args[task_name]
|
||||
else
|
||||
task_name = args
|
||||
deps = []
|
||||
end
|
||||
deps = deps.collect {|d| intern(d) }
|
||||
get(task_name).enhance(deps, &block)
|
||||
end
|
||||
|
||||
def get(task_name)
|
||||
name = intern(task_name)
|
||||
TASKS[name] ||= self.new(name)
|
||||
end
|
||||
|
||||
def intern(task_name)
|
||||
(Symbol === task_name) ? task_name : task_name.intern
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class FileTask < Task
|
||||
def needed?
|
||||
return true unless File.exist?(name)
|
||||
latest_prereq = @prerequisites.collect{|n| Task[n].timestamp}.max
|
||||
return false if latest_prereq.nil?
|
||||
timestamp < latest_prereq
|
||||
end
|
||||
|
||||
def timestamp
|
||||
File.new(name.to_s).mtime
|
||||
end
|
||||
end
|
||||
|
||||
def task(args, &block)
|
||||
Task.define_task(args, &block)
|
||||
end
|
||||
|
||||
def file(args, &block)
|
||||
FileTask.define_task(args, &block)
|
||||
end
|
||||
|
||||
def sys(cmd)
|
||||
puts cmd
|
||||
system(cmd) or fail "Command Failed: [#{cmd}]"
|
||||
end
|
||||
|
||||
def rake
|
||||
begin
|
||||
here = Dir.pwd
|
||||
while ! File.exist?("Rakefile")
|
||||
Dir.chdir("..")
|
||||
fail "No Rakefile found" if Dir.pwd == here
|
||||
here = Dir.pwd
|
||||
end
|
||||
puts "(in #{Dir.pwd})"
|
||||
load "./Rakefile"
|
||||
ARGV.push("default") if ARGV.size == 0
|
||||
ARGV.each { |task_name| Task[task_name].invoke }
|
||||
rescue Exception => ex
|
||||
puts "rake aborted ... #{ex.message}"
|
||||
puts ex.backtrace.find {|str| str =~ /Rakefile/ } || ""
|
||||
end
|
||||
end
|
||||
|
||||
if __FILE__ == $0 then
|
||||
rake
|
||||
end
|
|
@ -1,557 +0,0 @@
|
|||
= Rakefile Format (as of version 0.8.7)
|
||||
|
||||
First of all, there is no special format for a Rakefile. A Rakefile
|
||||
contains executable Ruby code. Anything legal in a ruby script is
|
||||
allowed in a Rakefile.
|
||||
|
||||
Now that we understand there is no special syntax in a Rakefile, there
|
||||
are some conventions that are used in a Rakefile that are a little
|
||||
unusual in a typical Ruby program. Since a Rakefile is tailored to
|
||||
specifying tasks and actions, the idioms used in a Rakefile are
|
||||
designed to support that.
|
||||
|
||||
So, what goes into a Rakefile?
|
||||
|
||||
== Tasks
|
||||
|
||||
Tasks are the main unit of work in a Rakefile. Tasks have a name
|
||||
(usually given as a symbol or a string), a list of prerequisites (more
|
||||
symbols or strings) and a list of actions (given as a block).
|
||||
|
||||
=== Simple Tasks
|
||||
|
||||
A task is declared by using the +task+ method. +task+ takes a single
|
||||
parameter that is the name of the task.
|
||||
|
||||
task :name
|
||||
|
||||
=== Tasks with Prerequisites
|
||||
|
||||
Any prerequisites are given as a list (enclosed in square brackets)
|
||||
following the name and an arrow (=>).
|
||||
|
||||
task :name => [:prereq1, :prereq2]
|
||||
|
||||
<b>NOTE:</b> Although this syntax looks a little funky, it is legal
|
||||
Ruby. We are constructing a hash where the key is :name and the value
|
||||
for that key is the list of prerequisites. It is equivalent to the
|
||||
following ...
|
||||
|
||||
hash = Hash.new
|
||||
hash[:name] = [:prereq1, :prereq2]
|
||||
task(hash)
|
||||
|
||||
=== Tasks with Actions
|
||||
|
||||
Actions are defined by passing a block to the +task+ method. Any Ruby
|
||||
code can be placed in the block. The block may reference the task
|
||||
object via the block parameter.
|
||||
|
||||
task :name => [:prereq1, :prereq2] do |t|
|
||||
# actions (may reference t)
|
||||
end
|
||||
|
||||
=== Multiple Definitions
|
||||
|
||||
A task may be specified more than once. Each specification adds its
|
||||
prerequisites and actions to the existing definition. This allows one
|
||||
part of a rakefile to specify the actions and a different rakefile
|
||||
(perhaps separately generated) to specify the dependencies.
|
||||
|
||||
For example, the following is equivalent to the single task
|
||||
specification given above.
|
||||
|
||||
task :name
|
||||
task :name => [:prereq1]
|
||||
task :name => [:prereq2]
|
||||
task :name do |t|
|
||||
# actions
|
||||
end
|
||||
|
||||
== File Tasks
|
||||
|
||||
Some tasks are designed to create a file from one or more other files.
|
||||
Tasks that generate these files may be skipped if the file already
|
||||
exists. File tasks are used to specify file creation tasks.
|
||||
|
||||
File tasks are declared using the +file+ method (instead of the +task+
|
||||
method). In addition, file tasks are usually named with a string
|
||||
rather than a symbol.
|
||||
|
||||
The following file task creates a executable program (named +prog+)
|
||||
given two object files name <tt>a.o</tt> and <tt>b.o</tt>. The tasks
|
||||
for creating <tt>a.o</tt> and <tt>b.o</tt> are not shown.
|
||||
|
||||
file "prog" => ["a.o", "b.o"] do |t|
|
||||
sh "cc -o #{t.name} #{t.prerequisites.join(' ')}"
|
||||
end
|
||||
|
||||
== Directory Tasks
|
||||
|
||||
It is common to need to create directories upon demand. The
|
||||
+directory+ convenience method is a short-hand for creating a FileTask
|
||||
that creates the directory. For example, the following declaration
|
||||
...
|
||||
|
||||
directory "testdata/examples/doc"
|
||||
|
||||
is equivalent to ...
|
||||
|
||||
file "testdata" do |t| mkdir t.name end
|
||||
file "testdata/examples" do |t| mkdir t.name end
|
||||
file "testdata/examples/doc" do |t| mkdir t.name end
|
||||
|
||||
The +directory+ method does not accept prerequisites or actions, but
|
||||
both prerequisites and actions can be added later. For example ...
|
||||
|
||||
directory "testdata"
|
||||
file "testdata" => ["otherdata"]
|
||||
file "testdata" do
|
||||
cp Dir["standard_data/*.data"], "testdata"
|
||||
end
|
||||
|
||||
== Tasks with Parallel Prerequisites
|
||||
|
||||
Rake allows parallel execution of prerequisites using the following syntax:
|
||||
|
||||
multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do
|
||||
puts "All Copies Complete"
|
||||
end
|
||||
|
||||
In this example, +copy_files+ is a normal rake task. Its actions are
|
||||
executed whenever all of its prerequisites are done. The big
|
||||
difference is that the prerequisites (+copy_src+, +copy_bin+ and
|
||||
+copy_doc+) are executed in parallel. Each of the prerequisites are
|
||||
run in their own Ruby thread, possibly allowing faster overall runtime.
|
||||
|
||||
=== Secondary Prerequisites
|
||||
|
||||
If any of the primary prerequisites of a multitask have common secondary
|
||||
prerequisites, all of the primary/parallel prerequisites will wait
|
||||
until the common prerequisites have been run.
|
||||
|
||||
For example, if the <tt>copy_<em>xxx</em></tt> tasks have the
|
||||
following prerequisites:
|
||||
|
||||
task :copy_src => [:prep_for_copy]
|
||||
task :copy_bin => [:prep_for_copy]
|
||||
task :copy_doc => [:prep_for_copy]
|
||||
|
||||
Then the +prep_for_copy+ task is run before starting all the copies in
|
||||
parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+,
|
||||
and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is
|
||||
run only once, even though it is referenced in multiple threads.
|
||||
|
||||
=== Thread Safety
|
||||
|
||||
The Rake internal data structures are thread-safe with respect
|
||||
to the multitask parallel execution, so there is no need for the user
|
||||
to do extra synchronization for Rake's benefit. However, if there are
|
||||
user data structures shared between the parallel prerequisites, the
|
||||
user must do whatever is necessary to prevent race conditions.
|
||||
|
||||
== Tasks with Arguments
|
||||
|
||||
Prior to version 0.8.0, rake was only able to handle command line
|
||||
arguments of the form NAME=VALUE that were passed into Rake via the
|
||||
ENV hash. Many folks had asked for some kind of simple command line
|
||||
arguments, perhaps using "--" to separate regular task names from
|
||||
argument values on the command line. The problem is that there was no
|
||||
easy way to associate positional arguments on the command line with
|
||||
different tasks. Suppose both tasks :a and :b expect a command line
|
||||
argument: does the first value go with :a? What if :b is run first?
|
||||
Should it then get the first command line argument.
|
||||
|
||||
Rake 0.8.0 solves this problem by explicitly passing values directly
|
||||
to the tasks that need them. For example, if I had a release task
|
||||
that required a version number, I could say:
|
||||
|
||||
rake release[0.8.2]
|
||||
|
||||
And the string "0.8.2" will be passed to the :release task. Multiple
|
||||
arguments can be passed by separating them with a comma, for example:
|
||||
|
||||
rake name[john,doe]
|
||||
|
||||
Just a few words of caution. The rake task name and its arguments
|
||||
need to be a single command line argument to rake. This generally
|
||||
means no spaces. If spaces are needed, then the entire rake +
|
||||
argument string should be quoted. Something like this:
|
||||
|
||||
rake "name[billy bob, smith]"
|
||||
|
||||
(Quoting rules vary between operating systems and shells, so make sure
|
||||
you consult the proper docs for your OS/shell).
|
||||
|
||||
=== Tasks Arguments and the Environment
|
||||
|
||||
Task argument values can also be picked up from the environment. For
|
||||
example, if the "release" task expected a parameter named
|
||||
"release_version", then either
|
||||
|
||||
rake release[0.8.2]
|
||||
|
||||
or
|
||||
|
||||
RELEASE_VERSION rake release
|
||||
|
||||
will work. Environment variable names must either match the task
|
||||
parameter exactly, or match an all-uppercase version of the task
|
||||
parameter.
|
||||
|
||||
=== Tasks that Expect Parameters
|
||||
|
||||
Parameters are only given to tasks that are setup to expect them. In
|
||||
order to handle named parameters, the task declaration syntax for
|
||||
tasks has been extended slightly.
|
||||
|
||||
For example, a task that needs a first name and last name might be
|
||||
declared as:
|
||||
|
||||
task :name, [:first_name, :last_name]
|
||||
|
||||
The first argument is still the name of the task (:name in this case).
|
||||
The next two arguments are the names of the parameters expected by
|
||||
:name in an array (:first_name and :last_name in the example).
|
||||
|
||||
To access the values of the parameters, the block defining the task
|
||||
behaviour can now accept a second parameter:
|
||||
|
||||
task :name, [:first_name, :last_name] do |t, args|
|
||||
puts "First name is #{args.first_name}"
|
||||
puts "Last name is #{args.last_name}"
|
||||
end
|
||||
|
||||
The first argument of the block "t" is always bound to the current
|
||||
task object. The second argument "args" is an open-struct like object
|
||||
that allows access to the task arguments. Extra command line
|
||||
arguments to a task are ignored. Missing command line arguments are
|
||||
picked up from matching environment variables. If there are no
|
||||
matching environment variables, they are given the nil value.
|
||||
|
||||
If you wish to specify default values for the arguments, you can use
|
||||
the with_defaults method in the task body. Here is the above example
|
||||
where we specify default values for the first and last names:
|
||||
|
||||
task :name, [:first_name, :last_name] do |t, args|
|
||||
args.with_defaults(:first_name => "John", :last_name => "Dough")
|
||||
puts "First name is #{args.first_name}"
|
||||
puts "Last name is #{args.last_name}"
|
||||
end
|
||||
|
||||
=== Tasks that Expect Parameters and Have Prerequisites
|
||||
|
||||
Tasks that use parameters have a slightly different format for
|
||||
prerequisites. Use the arrow notation to indicate the prerequisites
|
||||
for tasks with arguments. For example:
|
||||
|
||||
task :name, [:first_name, :last_name] => [:pre_name] do |t, args|
|
||||
args.with_defaults(:first_name => "John", :last_name => "Dough")
|
||||
puts "First name is #{args.first_name}"
|
||||
puts "Last name is #{args.last_name}"
|
||||
end
|
||||
|
||||
=== Deprecated Task Parameters Format
|
||||
|
||||
There is an older format for declaring task parameters that omitted
|
||||
the task argument array and used the :needs keyword to introduce the
|
||||
dependencies. That format is still supported for compatibility, but
|
||||
is not recommended for use. The older format may be dropped in future
|
||||
versions of rake.
|
||||
|
||||
== Accessing Task Programmatically
|
||||
|
||||
Sometimes it is useful to manipulate tasks programmatically in a
|
||||
Rakefile. To find a task object, use the <tt>:[]</tt> operator on the
|
||||
<tt>Rake::Task</tt>.
|
||||
|
||||
=== Programmatic Task Example
|
||||
|
||||
For example, the following Rakefile defines two tasks. The :doit task
|
||||
simply prints a simple "DONE" message. The :dont class will lookup
|
||||
the doit class and remove (clear) all of its prerequisites and
|
||||
actions.
|
||||
|
||||
task :doit do
|
||||
puts "DONE"
|
||||
end
|
||||
|
||||
task :dont do
|
||||
Rake::Task[:doit].clear
|
||||
end
|
||||
|
||||
Running this example:
|
||||
|
||||
$ rake doit
|
||||
(in /Users/jim/working/git/rake/x)
|
||||
DONE
|
||||
$ rake dont doit
|
||||
(in /Users/jim/working/git/rake/x)
|
||||
$
|
||||
|
||||
The ability to programmatically manipulate tasks gives rake very
|
||||
powerful meta-programming capabilities w.r.t. task execution, but
|
||||
should be used with cation.
|
||||
|
||||
== Rules
|
||||
|
||||
When a file is named as a prerequisite, but does not have a file task
|
||||
defined for it, Rake will attempt to synthesize a task by looking at a
|
||||
list of rules supplied in the Rakefile.
|
||||
|
||||
Suppose we were trying to invoke task "mycode.o", but no task is
|
||||
defined for it. But the rakefile has a rule that look like this ...
|
||||
|
||||
rule '.o' => ['.c'] do |t|
|
||||
sh "cc #{t.source} -c -o #{t.name}"
|
||||
end
|
||||
|
||||
This rule will synthesize any task that ends in ".o". It has a
|
||||
prerequisite a source file with an extension of ".c" must exist. If
|
||||
Rake is able to find a file named "mycode.c", it will automatically
|
||||
create a task that builds "mycode.o" from "mycode.c".
|
||||
|
||||
If the file "mycode.c" does not exist, rake will attempt
|
||||
to recursively synthesize a rule for it.
|
||||
|
||||
When a task is synthesized from a rule, the +source+ attribute of the
|
||||
task is set to the matching source file. This allows us to write
|
||||
rules with actions that reference the source file.
|
||||
|
||||
=== Advanced Rules
|
||||
|
||||
Any regular expression may be used as the rule pattern. Additionally,
|
||||
a proc may be used to calculate the name of the source file. This
|
||||
allows for complex patterns and sources.
|
||||
|
||||
The following rule is equivalent to the example above.
|
||||
|
||||
rule( /\.o$/ => [
|
||||
proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') }
|
||||
]) do |t|
|
||||
sh "cc #{t.source} -c -o #{t.name}"
|
||||
end
|
||||
|
||||
<b>NOTE:</b> Because of a _quirk_ in Ruby syntax, parenthesis are
|
||||
required on *rule* when the first argument is a regular expression.
|
||||
|
||||
The following rule might be used for Java files ...
|
||||
|
||||
rule '.java' => [
|
||||
proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') }
|
||||
] do |t|
|
||||
java_compile(t.source, t.name)
|
||||
end
|
||||
|
||||
<b>NOTE:</b> +java_compile+ is a hypothetical method that invokes the
|
||||
java compiler.
|
||||
|
||||
== Importing Dependencies
|
||||
|
||||
Any ruby file (including other rakefiles) can be included with a
|
||||
standard Ruby +require+ command. The rules and declarations in the
|
||||
required file are just added to the definitions already accumulated.
|
||||
|
||||
Because the files are loaded _before_ the rake targets are evaluated,
|
||||
the loaded files must be "ready to go" when the rake command is
|
||||
invoked. This make generated dependency files difficult to use. By
|
||||
the time rake gets around to updating the dependencies file, it is too
|
||||
late to load it.
|
||||
|
||||
The +Rake.import+ command addresses this by specifying a file to be
|
||||
loaded _after_ the main rakefile is loaded, but _before_ any targets
|
||||
on the command line are invoked. In addition, if the file name
|
||||
matches an explicit task, that task is invoked before loading the
|
||||
file. This allows dependency files to be generated and used in a
|
||||
single rake command invocation.
|
||||
|
||||
<b>NOTE:</b> Starting in Rake version 0.9.0, the top level +import+
|
||||
command is deprecated and we recommend using the scoped
|
||||
"+Rake.import+" command mentioned above. Future versions of Rake will
|
||||
drop support for the top level +import+ command.
|
||||
|
||||
=== Example:
|
||||
|
||||
require 'rake/loaders/makefile'
|
||||
|
||||
file ".depends.mf" => [SRC_LIST] do |t|
|
||||
sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}"
|
||||
end
|
||||
|
||||
Rake.import ".depends.mf"
|
||||
|
||||
If ".depends" does not exist, or is out of date w.r.t. the source
|
||||
files, a new ".depends" file is generated using +makedepend+ before
|
||||
loading.
|
||||
|
||||
== Comments
|
||||
|
||||
Standard Ruby comments (beginning with "#") can be used anywhere it is
|
||||
legal in Ruby source code, including comments for tasks and rules.
|
||||
However, if you wish a task to be described using the "-T" switch,
|
||||
then you need to use the +desc+ command to describe the task.
|
||||
|
||||
=== Example:
|
||||
|
||||
desc "Create a distribution package"
|
||||
task :package => [ ... ] do ... end
|
||||
|
||||
The "-T" switch (or "--tasks" if you like to spell things out) will
|
||||
display a list of tasks that have a description. If you use +desc+ to
|
||||
describe your major tasks, you have a semi-automatic way of generating
|
||||
a summary of your Rake file.
|
||||
|
||||
traken$ rake -T
|
||||
(in /home/.../rake)
|
||||
rake clean # Remove any temporary products.
|
||||
rake clobber # Remove any generated file.
|
||||
rake clobber_rdoc # Remove rdoc products
|
||||
rake contrib_test # Run tests for contrib_test
|
||||
rake default # Default Task
|
||||
rake install # Install the application
|
||||
rake lines # Count lines in the main rake file
|
||||
rake rdoc # Build the rdoc HTML Files
|
||||
rake rerdoc # Force a rebuild of the RDOC files
|
||||
rake test # Run tests
|
||||
rake testall # Run all test targets
|
||||
|
||||
Only tasks with descriptions will be displayed with the "-T" switch.
|
||||
Use "-P" (or "--prereqs") to get a list of all tasks and their
|
||||
prerequisites.
|
||||
|
||||
== Namespaces
|
||||
|
||||
As projects grow (and along with it, the number of tasks), it is
|
||||
common for task names to begin to clash. For example, if you might
|
||||
have a main program and a set of sample programs built by a single
|
||||
Rakefile. By placing the tasks related to the main program in one
|
||||
namespace, and the tasks for building the sample programs in a
|
||||
different namespace, the task names will not will not interfere with
|
||||
each other.
|
||||
|
||||
For example:
|
||||
|
||||
namespace "main" do
|
||||
task :build do
|
||||
# Build the main program
|
||||
end
|
||||
end
|
||||
|
||||
namespace "samples" do
|
||||
task :build do
|
||||
# Build the sample programs
|
||||
end
|
||||
end
|
||||
|
||||
task :build => ["main:build", "samples:build"]
|
||||
|
||||
Referencing a task in a separate namespace can be achieved by
|
||||
prefixing the task name with the namespace and a colon
|
||||
(e.g. "main:build" refers to the :build task in the +main+ namespace).
|
||||
Nested namespaces are supported, so
|
||||
|
||||
Note that the name given in the +task+ command is always the unadorned
|
||||
task name without any namespace prefixes. The +task+ command always
|
||||
defines a task in the current namespace.
|
||||
|
||||
=== FileTasks
|
||||
|
||||
File task names are not scoped by the namespace command. Since the
|
||||
name of a file task is the name of an actual file in the file system,
|
||||
it makes little sense to include file task names in name space.
|
||||
Directory tasks (created by the +directory+ command) are a type of
|
||||
file task and are also not affected by namespaces.
|
||||
|
||||
=== Name Resolution
|
||||
|
||||
When looking up a task name, rake will start with the current
|
||||
namespace and attempt to find the name there. If it fails to find a
|
||||
name in the current namespace, it will search the parent namespaces
|
||||
until a match is found (or an error occurs if there is no match).
|
||||
|
||||
The "rake" namespace is a special implicit namespace that refers to
|
||||
the toplevel names.
|
||||
|
||||
If a task name begins with a "^" character, the name resolution will
|
||||
start in the parent namespace. Multiple "^" characters are allowed.
|
||||
|
||||
Here is an example file with multiple :run tasks and how various names
|
||||
resolve in different locations.
|
||||
|
||||
task :run
|
||||
|
||||
namespace "one" do
|
||||
task :run
|
||||
|
||||
namespace "two" do
|
||||
task :run
|
||||
|
||||
# :run => "one:two:run"
|
||||
# "two:run" => "one:two:run"
|
||||
# "one:two:run" => "one:two:run"
|
||||
# "one:run" => "one:run"
|
||||
# "^run" => "one:run"
|
||||
# "^^run" => "rake:run" (the top level task)
|
||||
# "rake:run" => "rake:run" (the top level task)
|
||||
end
|
||||
|
||||
# :run => "one:run"
|
||||
# "two:run" => "one:two:run"
|
||||
# "^run" => "rake:run"
|
||||
end
|
||||
|
||||
# :run => "rake:run"
|
||||
# "one:run" => "one:run"
|
||||
# "one:two:run" => "one:two:run"
|
||||
|
||||
== FileLists
|
||||
|
||||
FileLists are the way Rake manages lists of files. You can treat a
|
||||
FileList as an array of strings for the most part, but FileLists
|
||||
support some additional operations.
|
||||
|
||||
=== Creating a FileList
|
||||
|
||||
Creating a file list is easy. Just give it the list of file names:
|
||||
|
||||
fl = FileList['file1.rb', file2.rb']
|
||||
|
||||
Or give it a glob pattern:
|
||||
|
||||
fl = FileList['*.rb']
|
||||
|
||||
== Odds and Ends
|
||||
|
||||
=== do/end versus { }
|
||||
|
||||
Blocks may be specified with either a +do+/+end+ pair, or with curly
|
||||
braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the
|
||||
actions for tasks and rules. Because the rakefile idiom tends to
|
||||
leave off parentheses on the task/file/rule methods, unusual
|
||||
ambiguities can arise when using curly braces.
|
||||
|
||||
For example, suppose that the method +object_files+ returns a list of
|
||||
object files in a project. Now we use +object_files+ as the
|
||||
prerequisites in a rule specified with actions in curly braces.
|
||||
|
||||
# DON'T DO THIS!
|
||||
file "prog" => object_files {
|
||||
# Actions are expected here (but it doesn't work)!
|
||||
}
|
||||
|
||||
Because curly braces have a higher precedence than +do+/+end+, the
|
||||
block is associated with the +object_files+ method rather than the
|
||||
+file+ method.
|
||||
|
||||
This is the proper way to specify the task ...
|
||||
|
||||
# THIS IS FINE
|
||||
file "prog" => object_files do
|
||||
# Actions go here
|
||||
end
|
||||
|
||||
----
|
||||
|
||||
== See
|
||||
|
||||
* README.rdoc -- Main documentation for Rake.
|
|
@ -1,151 +0,0 @@
|
|||
= Why rake?
|
||||
|
||||
Ok, let me state from the beginning that I never intended to write this
|
||||
code. I'm not convinced it is useful, and I'm not convinced anyone
|
||||
would even be interested in it. All I can say is that Why's onion truck
|
||||
must by been passing through the Ohio valley.
|
||||
|
||||
What am I talking about? ... A Ruby version of Make.
|
||||
|
||||
See, I can sense you cringing already, and I agree. The world certainly
|
||||
doesn't need yet another reworking of the "make" program. I mean, we
|
||||
already have "ant". Isn't that enough?
|
||||
|
||||
It started yesterday. I was helping a coworker fix a problem in one of
|
||||
the Makefiles we use in our project. Not a particularly tough problem,
|
||||
but during the course of the conversation I began lamenting some of the
|
||||
shortcomings of make. In particular, in one of my makefiles I wanted to
|
||||
determine the name of a file dynamically and had to resort to some
|
||||
simple scripting (in Ruby) to make it work. "Wouldn't it be nice if you
|
||||
could just use Ruby inside a Makefile" I said.
|
||||
|
||||
My coworker (a recent convert to Ruby) agreed, but wondered what it
|
||||
would look like. So I sketched the following on the whiteboard...
|
||||
|
||||
"What if you could specify the make tasks in Ruby, like this ..."
|
||||
|
||||
task "build" do
|
||||
java_compile(...args, etc ...)
|
||||
end
|
||||
|
||||
"The task function would register "build" as a target to be made,
|
||||
and the block would be the action executed whenever the build
|
||||
system determined that it was time to do the build target."
|
||||
|
||||
We agreed that would be cool, but writing make from scratch would be WAY
|
||||
too much work. And that was the end of that!
|
||||
|
||||
... Except I couldn't get the thought out of my head. What exactly
|
||||
would be needed to make the about syntax work as a make file? Hmmm, you
|
||||
would need to register the tasks, you need some way of specifying
|
||||
dependencies between tasks, and some way of kicking off the process.
|
||||
Hey! What if we did ... and fifteen minutes later I had a working
|
||||
prototype of Ruby make, complete with dependencies and actions.
|
||||
|
||||
I showed the code to my coworker and we had a good laugh. It was just
|
||||
about a page worth of code that reproduced an amazing amount of the
|
||||
functionality of make. We were both truly stunned with the power of
|
||||
Ruby.
|
||||
|
||||
But it didn't do everything make did. In particular, it didn't have
|
||||
timestamp based file dependencies (where a file is rebuilt if any of its
|
||||
prerequisite files have a later timestamp). Obviously THAT would be a
|
||||
pain to add and so Ruby Make would remain an interesting experiment.
|
||||
|
||||
... Except as I walked back to my desk, I started thinking about what
|
||||
file based dependencies would really need. Rats! I was hooked again,
|
||||
and by adding a new class and two new methods, file/timestamp
|
||||
dependencies were implemented.
|
||||
|
||||
Ok, now I was really hooked. Last night (during CSI!) I massaged the
|
||||
code and cleaned it up a bit. The result is a bare-bones replacement
|
||||
for make in exactly 100 lines of code.
|
||||
|
||||
For the curious, you can see it at ...
|
||||
* doc/proto_rake.rdoc
|
||||
|
||||
Oh, about the name. When I wrote the example Ruby Make task on my
|
||||
whiteboard, my coworker exclaimed "Oh! I have the perfect name: Rake ...
|
||||
Get it? Ruby-Make. Rake!" He said he envisioned the tasks as leaves
|
||||
and Rake would clean them up ... or something like that. Anyways, the
|
||||
name stuck.
|
||||
|
||||
Some quick examples ...
|
||||
|
||||
A simple task to delete backup files ...
|
||||
|
||||
task :clean do
|
||||
Dir['*~'].each {|fn| rm fn rescue nil}
|
||||
end
|
||||
|
||||
Note that task names are symbols (they are slightly easier to type
|
||||
than quoted strings ... but you may use quoted string if you would
|
||||
rather). Rake makes the methods of the FileUtils module directly
|
||||
available, so we take advantage of the <tt>rm</tt> command. Also note
|
||||
the use of "rescue nil" to trap and ignore errors in the <tt>rm</tt>
|
||||
command.
|
||||
|
||||
To run it, just type "rake clean". Rake will automatically find a
|
||||
Rakefile in the current directory (or above!) and will invoke the
|
||||
targets named on the command line. If there are no targets explicitly
|
||||
named, rake will invoke the task "default".
|
||||
|
||||
Here's another task with dependencies ...
|
||||
|
||||
task :clobber => [:clean] do
|
||||
rm_r "tempdir"
|
||||
end
|
||||
|
||||
Task :clobber depends upon task :clean, so :clean will be run before
|
||||
:clobber is executed.
|
||||
|
||||
Files are specified by using the "file" command. It is similar to the
|
||||
task command, except that the task name represents a file, and the task
|
||||
will be run only if the file doesn't exist, or if its modification time
|
||||
is earlier than any of its prerequisites.
|
||||
|
||||
Here is a file based dependency that will compile "hello.cc" to
|
||||
"hello.o".
|
||||
|
||||
file "hello.cc"
|
||||
file "hello.o" => ["hello.cc"] do |t|
|
||||
srcfile = t.name.sub(/\.o$/, ".cc")
|
||||
sh %{g++ #{srcfile} -c -o #{t.name}}
|
||||
end
|
||||
|
||||
I normally specify file tasks with string (rather than symbols). Some
|
||||
file names can't be represented by symbols. Plus it makes the
|
||||
distinction between them more clear to the casual reader.
|
||||
|
||||
Currently writing a task for each and every file in the project would be
|
||||
tedious at best. I envision a set of libraries to make this job
|
||||
easier. For instance, perhaps something like this ...
|
||||
|
||||
require 'rake/ctools'
|
||||
Dir['*.c'].each do |fn|
|
||||
c_source_file(fn)
|
||||
end
|
||||
|
||||
where "c_source_file" will create all the tasks need to compile all the
|
||||
C source files in a directory. Any number of useful libraries could be
|
||||
created for rake.
|
||||
|
||||
That's it. There's no documentation (other than whats in this
|
||||
message). Does this sound interesting to anyone? If so, I'll continue
|
||||
to clean it up and write it up and publish it on RAA. Otherwise, I'll
|
||||
leave it as an interesting exercise and a tribute to the power of Ruby.
|
||||
|
||||
Why /might/ rake be interesting to Ruby programmers. I don't know,
|
||||
perhaps ...
|
||||
|
||||
* No weird make syntax (only weird Ruby syntax :-)
|
||||
* No need to edit or read XML (a la ant)
|
||||
* Platform independent build scripts.
|
||||
* Will run anywhere Ruby exists, so no need to have "make" installed.
|
||||
If you stay away from the "sys" command and use things like
|
||||
'ftools', you can have a perfectly platform independent
|
||||
build script. Also rake is only 100 lines of code, so it can
|
||||
easily be packaged along with the rest of your code.
|
||||
|
||||
So ... Sorry for the long rambling message. Like I said, I never
|
||||
intended to write this code at all.
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue