From 560a32eb35419cb6c845b7c3dcd90ce1a3959e91 Mon Sep 17 00:00:00 2001 From: "Josep M. Bach" Date: Wed, 9 Nov 2011 17:49:33 +0100 Subject: [PATCH 01/67] Specs for ruby 1.9 StringIO#gets with multiple arguments --- spec/ruby/library/stringio/gets_spec.rb | 95 +++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/spec/ruby/library/stringio/gets_spec.rb b/spec/ruby/library/stringio/gets_spec.rb index a0308c2afa..c2acb3e487 100644 --- a/spec/ruby/library/stringio/gets_spec.rb +++ b/spec/ruby/library/stringio/gets_spec.rb @@ -127,6 +127,101 @@ end end +ruby_version_is "1.9" do + describe "StringIO#gets when passed [limit]" do + before(:each) do + @io = StringIO.new("this>is>an>example") + end + + it "returns the data read until the limit is met" do + @io.gets(4).should == "this" + @io.gets(3).should == ">is" + @io.gets(5).should == ">an>e" + @io.gets(6).should == "xample" + end + + it "sets $_ to the read content" do + @io.gets(4) + $_.should == "this" + @io.gets(3) + $_.should == ">is" + @io.gets(5) + $_.should == ">an>e" + @io.gets(6) + $_.should == "xample" + @io.gets(3) + $_.should be_nil + end + + it "updates self's lineno by one" do + @io.gets(3) + @io.lineno.should eql(1) + + @io.gets(3) + @io.lineno.should eql(2) + + @io.gets(3) + @io.lineno.should eql(3) + end + + it "tries to convert the passed limit to an Integer using #to_int" do + obj = mock('to_int') + obj.should_receive(:to_int).and_return(4) + @io.gets(obj).should == "this" + end + end + + describe "StringIO#gets when passed [separator] and [limit]" do + before(:each) do + @io = StringIO.new("this>is>an>example") + end + + it "returns the data read until the limit is consumed or the separator is met" do + @io.gets('>', 8).should == "this>" + @io.gets('>', 2).should == "is" + @io.gets('>', 10).should == ">" + @io.gets('>', 6).should == "an>" + @io.gets('>', 5).should == "examp" + end + + it "sets $_ to the read content" do + @io.gets('>', 8) + $_.should == "this>" + @io.gets('>', 2) + $_.should == "is" + @io.gets('>', 10) + $_.should == ">" + @io.gets('>', 6) + $_.should == "an>" + @io.gets('>', 5) + $_.should == "examp" + end + + it "updates self's lineno by one" do + @io.gets('>', 3) + @io.lineno.should eql(1) + + @io.gets('>', 3) + @io.lineno.should eql(2) + + @io.gets('>', 3) + @io.lineno.should eql(3) + end + + it "tries to convert the passed separator to a String using #to_str" do + obj = mock('to_str') + obj.should_receive(:to_str).and_return('>') + @io.gets(obj, 5).should == "this>" + end + + it "tries to convert the passed limit to an Integer using #to_int" do + obj = mock('to_int') + obj.should_receive(:to_int).and_return(5) + @io.gets('>', obj).should == "this>" + end + end +end + describe "StringIO#gets when in write-only mode" do it "raises an IOError" do io = StringIO.new("xyz", "w") From c473b0aeeae2391e7f4cea2dce407d9de4c08e75 Mon Sep 17 00:00:00 2001 From: "Josep M. Bach" Date: Wed, 9 Nov 2011 17:49:53 +0100 Subject: [PATCH 02/67] Failing CI tags for Stringio#gets 1.9 specs --- spec/tags/19/ruby/library/stringio/gets_tags.txt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 spec/tags/19/ruby/library/stringio/gets_tags.txt diff --git a/spec/tags/19/ruby/library/stringio/gets_tags.txt b/spec/tags/19/ruby/library/stringio/gets_tags.txt new file mode 100644 index 0000000000..83d1957441 --- /dev/null +++ b/spec/tags/19/ruby/library/stringio/gets_tags.txt @@ -0,0 +1,9 @@ +fails:StringIO#gets when passes [limit] returns the data read until the limit is met +fails:StringIO#gets when passes [limit] sets $_ to the read content +fails:StringIO#gets when passes [limit] updates self's lineno by one +fails:StringIO#gets when passes [limit] tries to convert the passed limit to an Integer using #to_int +fails:StringIO#gets when passed [separator] and [limit] returns the data read until the limit is consumed or the separator is met +fails:StringIO#gets when passed [separator] and [limit] sets $_ to the read content +fails:StringIO#gets when passed [separator] and [limit] updates self's lineno by one +fails:StringIO#gets when passed [separator] and [limit] tries to convert the passed separator to a String using #to_str +fails:StringIO#gets when passed [separator] and [limit] tries to convert the passed limit to an Integer using #to_int From 797bbe248f32e9a36bef5a64c790216f028c9481 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Wed, 9 Nov 2011 13:55:01 -0800 Subject: [PATCH 03/67] Moved lib/ext/syck to lib/syck/ext. --- lib/{ext/syck => syck/ext}/Rakefile | 0 lib/{ext/syck => syck/ext}/bytecode.c | 0 lib/{ext/syck => syck/ext}/depend | 0 lib/{ext/syck => syck/ext}/emitter.c | 0 lib/{ext/syck => syck/ext}/extconf.rb | 0 lib/{ext/syck => syck/ext}/gram.c | 0 lib/{ext/syck => syck/ext}/gram.h | 0 lib/{ext/syck => syck/ext}/handler.c | 0 lib/{ext/syck => syck/ext}/implicit.c | 0 lib/{ext/syck => syck/ext}/node.c | 0 lib/{ext/syck => syck/ext}/rubyext.c | 0 lib/{ext/syck => syck/ext}/st.c | 0 lib/{ext/syck => syck/ext}/st.h | 0 lib/{ext/syck => syck/ext}/syck.c | 0 lib/{ext/syck => syck/ext}/syck.h | 0 lib/{ext/syck => syck/ext}/token.c | 0 lib/{ext/syck => syck/ext}/yaml2byte.c | 0 lib/{ext/syck => syck/ext}/yamlbyte.h | 0 18 files changed, 0 insertions(+), 0 deletions(-) rename lib/{ext/syck => syck/ext}/Rakefile (100%) rename lib/{ext/syck => syck/ext}/bytecode.c (100%) rename lib/{ext/syck => syck/ext}/depend (100%) rename lib/{ext/syck => syck/ext}/emitter.c (100%) rename lib/{ext/syck => syck/ext}/extconf.rb (100%) rename lib/{ext/syck => syck/ext}/gram.c (100%) rename lib/{ext/syck => syck/ext}/gram.h (100%) rename lib/{ext/syck => syck/ext}/handler.c (100%) rename lib/{ext/syck => syck/ext}/implicit.c (100%) rename lib/{ext/syck => syck/ext}/node.c (100%) rename lib/{ext/syck => syck/ext}/rubyext.c (100%) rename lib/{ext/syck => syck/ext}/st.c (100%) rename lib/{ext/syck => syck/ext}/st.h (100%) rename lib/{ext/syck => syck/ext}/syck.c (100%) rename lib/{ext/syck => syck/ext}/syck.h (100%) rename lib/{ext/syck => syck/ext}/token.c (100%) rename lib/{ext/syck => syck/ext}/yaml2byte.c (100%) rename lib/{ext/syck => syck/ext}/yamlbyte.h (100%) diff --git a/lib/ext/syck/Rakefile b/lib/syck/ext/Rakefile similarity index 100% rename from lib/ext/syck/Rakefile rename to lib/syck/ext/Rakefile diff --git a/lib/ext/syck/bytecode.c b/lib/syck/ext/bytecode.c similarity index 100% rename from lib/ext/syck/bytecode.c rename to lib/syck/ext/bytecode.c diff --git a/lib/ext/syck/depend b/lib/syck/ext/depend similarity index 100% rename from lib/ext/syck/depend rename to lib/syck/ext/depend diff --git a/lib/ext/syck/emitter.c b/lib/syck/ext/emitter.c similarity index 100% rename from lib/ext/syck/emitter.c rename to lib/syck/ext/emitter.c diff --git a/lib/ext/syck/extconf.rb b/lib/syck/ext/extconf.rb similarity index 100% rename from lib/ext/syck/extconf.rb rename to lib/syck/ext/extconf.rb diff --git a/lib/ext/syck/gram.c b/lib/syck/ext/gram.c similarity index 100% rename from lib/ext/syck/gram.c rename to lib/syck/ext/gram.c diff --git a/lib/ext/syck/gram.h b/lib/syck/ext/gram.h similarity index 100% rename from lib/ext/syck/gram.h rename to lib/syck/ext/gram.h diff --git a/lib/ext/syck/handler.c b/lib/syck/ext/handler.c similarity index 100% rename from lib/ext/syck/handler.c rename to lib/syck/ext/handler.c diff --git a/lib/ext/syck/implicit.c b/lib/syck/ext/implicit.c similarity index 100% rename from lib/ext/syck/implicit.c rename to lib/syck/ext/implicit.c diff --git a/lib/ext/syck/node.c b/lib/syck/ext/node.c similarity index 100% rename from lib/ext/syck/node.c rename to lib/syck/ext/node.c diff --git a/lib/ext/syck/rubyext.c b/lib/syck/ext/rubyext.c similarity index 100% rename from lib/ext/syck/rubyext.c rename to lib/syck/ext/rubyext.c diff --git a/lib/ext/syck/st.c b/lib/syck/ext/st.c similarity index 100% rename from lib/ext/syck/st.c rename to lib/syck/ext/st.c diff --git a/lib/ext/syck/st.h b/lib/syck/ext/st.h similarity index 100% rename from lib/ext/syck/st.h rename to lib/syck/ext/st.h diff --git a/lib/ext/syck/syck.c b/lib/syck/ext/syck.c similarity index 100% rename from lib/ext/syck/syck.c rename to lib/syck/ext/syck.c diff --git a/lib/ext/syck/syck.h b/lib/syck/ext/syck.h similarity index 100% rename from lib/ext/syck/syck.h rename to lib/syck/ext/syck.h diff --git a/lib/ext/syck/token.c b/lib/syck/ext/token.c similarity index 100% rename from lib/ext/syck/token.c rename to lib/syck/ext/token.c diff --git a/lib/ext/syck/yaml2byte.c b/lib/syck/ext/yaml2byte.c similarity index 100% rename from lib/ext/syck/yaml2byte.c rename to lib/syck/ext/yaml2byte.c diff --git a/lib/ext/syck/yamlbyte.h b/lib/syck/ext/yamlbyte.h similarity index 100% rename from lib/ext/syck/yamlbyte.h rename to lib/syck/ext/yamlbyte.h From 72e6801db4d843b9b7eb8df0c6d4876145ffacd8 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Wed, 9 Nov 2011 13:57:56 -0800 Subject: [PATCH 04/67] Moved yaml/ to lib/18 and fixed building Syck C-ext. --- lib/{ => 18}/yaml.rb | 0 lib/{ => 18}/yaml/baseemitter.rb | 0 lib/{ => 18}/yaml/basenode.rb | 0 lib/{ => 18}/yaml/constants.rb | 0 lib/{ => 18}/yaml/dbm.rb | 0 lib/{ => 18}/yaml/encoding.rb | 0 lib/{ => 18}/yaml/error.rb | 0 lib/{ => 18}/yaml/loader.rb | 0 lib/{ => 18}/yaml/rubytypes.rb | 0 lib/{ => 18}/yaml/store.rb | 0 lib/{ => 18}/yaml/stream.rb | 0 lib/{ => 18}/yaml/stringio.rb | 0 lib/{ => 18}/yaml/syck.rb | 2 +- lib/{ => 18}/yaml/tag.rb | 0 lib/{ => 18}/yaml/types.rb | 0 lib/{ => 18}/yaml/yamlnode.rb | 0 lib/{ => 18}/yaml/ypath.rb | 0 rakelib/extensions.rake | 2 +- 18 files changed, 2 insertions(+), 2 deletions(-) rename lib/{ => 18}/yaml.rb (100%) rename lib/{ => 18}/yaml/baseemitter.rb (100%) rename lib/{ => 18}/yaml/basenode.rb (100%) rename lib/{ => 18}/yaml/constants.rb (100%) rename lib/{ => 18}/yaml/dbm.rb (100%) rename lib/{ => 18}/yaml/encoding.rb (100%) rename lib/{ => 18}/yaml/error.rb (100%) rename lib/{ => 18}/yaml/loader.rb (100%) rename lib/{ => 18}/yaml/rubytypes.rb (100%) rename lib/{ => 18}/yaml/store.rb (100%) rename lib/{ => 18}/yaml/stream.rb (100%) rename lib/{ => 18}/yaml/stringio.rb (100%) rename lib/{ => 18}/yaml/syck.rb (97%) rename lib/{ => 18}/yaml/tag.rb (100%) rename lib/{ => 18}/yaml/types.rb (100%) rename lib/{ => 18}/yaml/yamlnode.rb (100%) rename lib/{ => 18}/yaml/ypath.rb (100%) diff --git a/lib/yaml.rb b/lib/18/yaml.rb similarity index 100% rename from lib/yaml.rb rename to lib/18/yaml.rb diff --git a/lib/yaml/baseemitter.rb b/lib/18/yaml/baseemitter.rb similarity index 100% rename from lib/yaml/baseemitter.rb rename to lib/18/yaml/baseemitter.rb diff --git a/lib/yaml/basenode.rb b/lib/18/yaml/basenode.rb similarity index 100% rename from lib/yaml/basenode.rb rename to lib/18/yaml/basenode.rb diff --git a/lib/yaml/constants.rb b/lib/18/yaml/constants.rb similarity index 100% rename from lib/yaml/constants.rb rename to lib/18/yaml/constants.rb diff --git a/lib/yaml/dbm.rb b/lib/18/yaml/dbm.rb similarity index 100% rename from lib/yaml/dbm.rb rename to lib/18/yaml/dbm.rb diff --git a/lib/yaml/encoding.rb b/lib/18/yaml/encoding.rb similarity index 100% rename from lib/yaml/encoding.rb rename to lib/18/yaml/encoding.rb diff --git a/lib/yaml/error.rb b/lib/18/yaml/error.rb similarity index 100% rename from lib/yaml/error.rb rename to lib/18/yaml/error.rb diff --git a/lib/yaml/loader.rb b/lib/18/yaml/loader.rb similarity index 100% rename from lib/yaml/loader.rb rename to lib/18/yaml/loader.rb diff --git a/lib/yaml/rubytypes.rb b/lib/18/yaml/rubytypes.rb similarity index 100% rename from lib/yaml/rubytypes.rb rename to lib/18/yaml/rubytypes.rb diff --git a/lib/yaml/store.rb b/lib/18/yaml/store.rb similarity index 100% rename from lib/yaml/store.rb rename to lib/18/yaml/store.rb diff --git a/lib/yaml/stream.rb b/lib/18/yaml/stream.rb similarity index 100% rename from lib/yaml/stream.rb rename to lib/18/yaml/stream.rb diff --git a/lib/yaml/stringio.rb b/lib/18/yaml/stringio.rb similarity index 100% rename from lib/yaml/stringio.rb rename to lib/18/yaml/stringio.rb diff --git a/lib/yaml/syck.rb b/lib/18/yaml/syck.rb similarity index 97% rename from lib/yaml/syck.rb rename to lib/18/yaml/syck.rb index 8e31ef23e1..666da201a5 100644 --- a/lib/yaml/syck.rb +++ b/lib/18/yaml/syck.rb @@ -2,7 +2,7 @@ # YAML::Syck module # .. glues syck and yaml.rb together .. # -require 'ext/syck/syck' +require 'syck/ext/syck' require 'yaml/basenode' module YAML diff --git a/lib/yaml/tag.rb b/lib/18/yaml/tag.rb similarity index 100% rename from lib/yaml/tag.rb rename to lib/18/yaml/tag.rb diff --git a/lib/yaml/types.rb b/lib/18/yaml/types.rb similarity index 100% rename from lib/yaml/types.rb rename to lib/18/yaml/types.rb diff --git a/lib/yaml/yamlnode.rb b/lib/18/yaml/yamlnode.rb similarity index 100% rename from lib/yaml/yamlnode.rb rename to lib/18/yaml/yamlnode.rb diff --git a/lib/yaml/ypath.rb b/lib/18/yaml/ypath.rb similarity index 100% rename from lib/yaml/ypath.rb rename to lib/18/yaml/ypath.rb diff --git a/rakelib/extensions.rake b/rakelib/extensions.rake index 08daf5f86d..7ddda2aea2 100644 --- a/rakelib/extensions.rake +++ b/rakelib/extensions.rake @@ -119,7 +119,7 @@ compile_ext "digest:rmd160" compile_ext "digest:sha1" compile_ext "digest:sha2" compile_ext "digest:bubblebabble" -compile_ext "syck" +compile_ext "syck", :dir => "lib/syck/ext" compile_ext "melbourne", :task => "rbx", :doc => "for Rubinius" compile_ext "melbourne", :task => "build", :doc => "for bootstrapping" compile_ext "nkf" From a76b8584d471dfc28211f41a61be3483ee418b6f Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Wed, 9 Nov 2011 13:59:48 -0800 Subject: [PATCH 05/67] Added yaml from 1.9.2p290. --- lib/19/yaml.rb | 43 +++++++++++++++++ lib/19/yaml/dbm.rb | 111 +++++++++++++++++++++++++++++++++++++++++++ lib/19/yaml/store.rb | 43 +++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 lib/19/yaml.rb create mode 100644 lib/19/yaml/dbm.rb create mode 100644 lib/19/yaml/store.rb diff --git a/lib/19/yaml.rb b/lib/19/yaml.rb new file mode 100644 index 0000000000..9b5a9b2787 --- /dev/null +++ b/lib/19/yaml.rb @@ -0,0 +1,43 @@ +module YAML + class EngineManager # :nodoc: + attr_reader :yamler + + def initialize + @yamler = nil + end + + def syck? + 'syck' == @yamler + end + + def yamler= engine + raise(ArgumentError, "bad engine") unless %w{syck psych}.include?(engine) + + require engine + + Object.class_eval <<-eorb, __FILE__, __LINE__ + 1 + remove_const 'YAML' + YAML = #{engine.capitalize} + remove_method :to_yaml + alias :to_yaml :#{engine}_to_yaml + eorb + + @yamler = engine + engine + end + end + + ENGINE = YAML::EngineManager.new +end + +engine = (!defined?(Syck) && defined?(Psych) ? 'psych' : 'syck') + +module Syck + ENGINE = YAML::ENGINE +end + +module Psych + ENGINE = YAML::ENGINE +end + +YAML::ENGINE.yamler = engine diff --git a/lib/19/yaml/dbm.rb b/lib/19/yaml/dbm.rb new file mode 100644 index 0000000000..973e88dbc7 --- /dev/null +++ b/lib/19/yaml/dbm.rb @@ -0,0 +1,111 @@ +require 'yaml' +require 'dbm' +# +# YAML + DBM = YDBM +# - Same interface as DBM class +# +module YAML + +class DBM < ::DBM + VERSION = "0.1" + def []( key ) + fetch( key ) + end + def []=( key, val ) + store( key, val ) + end + def fetch( keystr, ifnone = nil ) + begin + val = super( keystr ) + return YAML.load( val ) if String === val + rescue IndexError + end + if block_given? + yield keystr + else + ifnone + end + end + def index( keystr ) + super( keystr.to_yaml ) + end + def values_at( *keys ) + keys.collect { |k| fetch( k ) } + end + def delete( key ) + v = super( key ) + if String === v + v = YAML.load( v ) + end + v + end + def delete_if + del_keys = keys.dup + del_keys.delete_if { |k| yield( k, fetch( k ) ) == false } + del_keys.each { |k| delete( k ) } + self + end + def reject + hsh = self.to_hash + hsh.reject { |k,v| yield k, v } + end + def each_pair + keys.each { |k| yield k, fetch( k ) } + self + end + def each_value + super { |v| yield YAML.load( v ) } + self + end + def values + super.collect { |v| YAML.load( v ) } + end + def has_value?( val ) + each_value { |v| return true if v == val } + return false + end + def invert + h = {} + keys.each { |k| h[ self.fetch( k ) ] = k } + h + end + def replace( hsh ) + clear + update( hsh ) + end + def shift + a = super + a[1] = YAML.load( a[1] ) if a + a + end + def select( *keys ) + if block_given? + self.keys.collect { |k| v = self[k]; [k, v] if yield k, v }.compact + else + values_at( *keys ) + end + end + def store( key, val ) + super( key, val.to_yaml ) + val + end + def update( hsh ) + hsh.keys.each do |k| + self.store( k, hsh.fetch( k ) ) + end + self + end + def to_a + a = [] + keys.each { |k| a.push [ k, self.fetch( k ) ] } + a + end + def to_hash + h = {} + keys.each { |k| h[ k ] = self.fetch( k ) } + h + end + alias :each :each_pair +end + +end diff --git a/lib/19/yaml/store.rb b/lib/19/yaml/store.rb new file mode 100644 index 0000000000..a7f8a5657d --- /dev/null +++ b/lib/19/yaml/store.rb @@ -0,0 +1,43 @@ +# +# YAML::Store +# +require 'yaml' +require 'pstore' + +class YAML::Store < PStore + def initialize( *o ) + @opt = {} + if String === o.first + super(o.shift) + end + if o.last.is_a? Hash + @opt.update(o.pop) + end + end + + def dump(table) + @table.to_yaml(@opt) + end + + def load(content) + table = YAML.load(content) + if table == false + {} + else + table + end + end + + def marshal_dump_supports_canonical_option? + false + end + + EMPTY_MARSHAL_DATA = {}.to_yaml + EMPTY_MARSHAL_CHECKSUM = Digest::MD5.digest(EMPTY_MARSHAL_DATA) + def empty_marshal_data + EMPTY_MARSHAL_DATA + end + def empty_marshal_checksum + EMPTY_MARSHAL_CHECKSUM + end +end From dcea156c73efbf682ad5d0afeb4f8368ef04b809 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Wed, 9 Nov 2011 14:07:51 -0800 Subject: [PATCH 06/67] Added psych from 1.9.2p290. --- lib/19/psych.rb | 239 +++++++++++++++++ lib/19/psych/coder.rb | 86 ++++++ lib/19/psych/core_ext.rb | 38 +++ lib/19/psych/deprecated.rb | 82 ++++++ lib/19/psych/ext/emitter.c | 412 +++++++++++++++++++++++++++++ lib/19/psych/ext/emitter.h | 8 + lib/19/psych/ext/extconf.rb | 16 ++ lib/19/psych/ext/parser.c | 341 ++++++++++++++++++++++++ lib/19/psych/ext/parser.h | 6 + lib/19/psych/ext/psych.c | 34 +++ lib/19/psych/ext/psych.h | 20 ++ lib/19/psych/ext/to_ruby.c | 41 +++ lib/19/psych/ext/to_ruby.h | 8 + lib/19/psych/ext/yaml_tree.c | 24 ++ lib/19/psych/ext/yaml_tree.h | 8 + lib/19/psych/handler.rb | 215 +++++++++++++++ lib/19/psych/json/tree_builder.rb | 24 ++ lib/19/psych/nodes.rb | 77 ++++++ lib/19/psych/nodes/alias.rb | 18 ++ lib/19/psych/nodes/document.rb | 60 +++++ lib/19/psych/nodes/mapping.rb | 56 ++++ lib/19/psych/nodes/node.rb | 42 +++ lib/19/psych/nodes/scalar.rb | 67 +++++ lib/19/psych/nodes/sequence.rb | 81 ++++++ lib/19/psych/nodes/stream.rb | 37 +++ lib/19/psych/omap.rb | 4 + lib/19/psych/parser.rb | 44 +++ lib/19/psych/scalar_scanner.rb | 105 ++++++++ lib/19/psych/set.rb | 4 + lib/19/psych/tree_builder.rb | 94 +++++++ lib/19/psych/visitors.rb | 5 + lib/19/psych/visitors/emitter.rb | 41 +++ lib/19/psych/visitors/json_tree.rb | 29 ++ lib/19/psych/visitors/to_ruby.rb | 269 +++++++++++++++++++ lib/19/psych/visitors/visitor.rb | 18 ++ lib/19/psych/visitors/yaml_tree.rb | 330 +++++++++++++++++++++++ 36 files changed, 2983 insertions(+) create mode 100644 lib/19/psych.rb create mode 100644 lib/19/psych/coder.rb create mode 100644 lib/19/psych/core_ext.rb create mode 100644 lib/19/psych/deprecated.rb create mode 100644 lib/19/psych/ext/emitter.c create mode 100644 lib/19/psych/ext/emitter.h create mode 100644 lib/19/psych/ext/extconf.rb create mode 100644 lib/19/psych/ext/parser.c create mode 100644 lib/19/psych/ext/parser.h create mode 100644 lib/19/psych/ext/psych.c create mode 100644 lib/19/psych/ext/psych.h create mode 100644 lib/19/psych/ext/to_ruby.c create mode 100644 lib/19/psych/ext/to_ruby.h create mode 100644 lib/19/psych/ext/yaml_tree.c create mode 100644 lib/19/psych/ext/yaml_tree.h create mode 100644 lib/19/psych/handler.rb create mode 100644 lib/19/psych/json/tree_builder.rb create mode 100644 lib/19/psych/nodes.rb create mode 100644 lib/19/psych/nodes/alias.rb create mode 100644 lib/19/psych/nodes/document.rb create mode 100644 lib/19/psych/nodes/mapping.rb create mode 100644 lib/19/psych/nodes/node.rb create mode 100644 lib/19/psych/nodes/scalar.rb create mode 100644 lib/19/psych/nodes/sequence.rb create mode 100644 lib/19/psych/nodes/stream.rb create mode 100644 lib/19/psych/omap.rb create mode 100644 lib/19/psych/parser.rb create mode 100644 lib/19/psych/scalar_scanner.rb create mode 100644 lib/19/psych/set.rb create mode 100644 lib/19/psych/tree_builder.rb create mode 100644 lib/19/psych/visitors.rb create mode 100644 lib/19/psych/visitors/emitter.rb create mode 100644 lib/19/psych/visitors/json_tree.rb create mode 100644 lib/19/psych/visitors/to_ruby.rb create mode 100644 lib/19/psych/visitors/visitor.rb create mode 100644 lib/19/psych/visitors/yaml_tree.rb diff --git a/lib/19/psych.rb b/lib/19/psych.rb new file mode 100644 index 0000000000..62f0f6a585 --- /dev/null +++ b/lib/19/psych.rb @@ -0,0 +1,239 @@ +require 'psych/ext/psych' +require 'psych/nodes' +require 'psych/visitors' +require 'psych/handler' +require 'psych/tree_builder' +require 'psych/json/tree_builder' +require 'psych/parser' +require 'psych/omap' +require 'psych/set' +require 'psych/coder' +require 'psych/core_ext' +require 'psych/deprecated' + +### +# = Overview +# +# Psych is a YAML parser and emitter. Psych leverages +# libyaml[http://libyaml.org] for it's YAML parsing and emitting capabilities. +# In addition to wrapping libyaml, Psych also knows how to serialize and +# de-serialize most Ruby objects to and from the YAML format. +# +# = I NEED TO PARSE OR EMIT YAML RIGHT NOW! +# +# # Parse some YAML +# Psych.load("--- foo") # => "foo" +# +# # Emit some YAML +# Psych.dump("foo") # => "--- foo\n...\n" +# { :a => 'b'}.to_yaml # => "---\n:a: b\n" +# +# Got more time on your hands? Keep on reading! +# +# == YAML Parsing +# +# Psych provides a range of interfaces for parsing a YAML document ranging from +# low level to high level, depending on your parsing needs. At the lowest +# level, is an event based parser. Mid level is access to the raw YAML AST, +# and at the highest level is the ability to unmarshal YAML to ruby objects. +# +# === Low level parsing +# +# The lowest level parser should be used when the YAML input is already known, +# and the developer does not want to pay the price of building an AST or +# automatic detection and conversion to ruby objects. See Psych::Parser for +# more information on using the event based parser. +# +# === Mid level parsing +# +# Psych provides access to an AST produced from parsing a YAML document. This +# tree is built using the Psych::Parser and Psych::TreeBuilder. The AST can +# be examined and manipulated freely. Please see Psych::parse_stream, +# Psych::Nodes, and Psych::Nodes::Node for more information on dealing with +# YAML syntax trees. +# +# === High level parsing +# +# The high level YAML parser provided by Psych simply takes YAML as input and +# returns a Ruby data structure. For information on using the high level parser +# see Psych.load +# +# == YAML Emitting +# +# Psych provides a range of interfaces ranging from low to high level for +# producing YAML documents. Very similar to the YAML parsing interfaces, Psych +# provides at the lowest level, an event based system, mid-level is building +# a YAML AST, and the highest level is converting a Ruby object straight to +# a YAML document. +# +# === Low level emitting +# +# The lowest level emitter is an event based system. Events are sent to a +# Psych::Emitter object. That object knows how to convert the events to a YAML +# document. This interface should be used when document format is known in +# advance or speed is a concern. See Psych::Emitter for more information. +# +# === Mid level emitting +# +# At the mid level is building an AST. This AST is exactly the same as the AST +# used when parsing a YAML document. Users can build an AST by hand and the +# AST knows how to emit itself as a YAML document. See Psych::Nodes, +# Psych::Nodes::Node, and Psych::TreeBuilder for more information on building +# a YAML AST. +# +# === High level emitting +# +# The high level emitter has the easiest interface. Psych simply takes a Ruby +# data structure and converts it to a YAML document. See Psych.dump for more +# information on dumping a Ruby data structure. + +module Psych + # The version is Psych you're using + VERSION = '1.0.0' + + # The version of libyaml Psych is using + LIBYAML_VERSION = Psych.libyaml_version.join '.' + + ### + # Load +yaml+ in to a Ruby data structure. If multiple documents are + # provided, the object contained in the first document will be returned. + # + # Example: + # + # Psych.load("--- a") # => 'a' + # Psych.load("---\n - a\n - b") # => ['a', 'b'] + def self.load yaml + result = parse(yaml) + result ? result.to_ruby : result + end + + ### + # Parse a YAML string in +yaml+. Returns the first object of a YAML AST. + # + # Example: + # + # Psych.parse("---\n - a\n - b") # => # + # + # See Psych::Nodes for more information about YAML AST. + def self.parse yaml + children = parse_stream(yaml).children + children.empty? ? false : children.first.children.first + end + + ### + # Parse a file at +filename+. Returns the YAML AST. + def self.parse_file filename + File.open filename do |f| + parse f + end + end + + ### + # Returns a default parser + def self.parser + Psych::Parser.new(TreeBuilder.new) + end + + ### + # Parse a YAML string in +yaml+. Returns the full AST for the YAML document. + # This method can handle multiple YAML documents contained in +yaml+. + # + # Example: + # + # Psych.parse_stream("---\n - a\n - b") # => # + # + # See Psych::Nodes for more information about YAML AST. + def self.parse_stream yaml + parser = self.parser + parser.parse yaml + parser.handler.root + end + + ### + # Dump Ruby object +o+ to a YAML string using +options+. + # + # Example: + # + # Psych.dump(['a', 'b']) # => "---\n- a\n- b\n" + def self.dump o, io = nil, options = {} + if Hash === io + options = io + io = nil + end + + visitor = Psych::Visitors::YAMLTree.new options + visitor << o + visitor.tree.to_yaml io + end + + ### + # Dump a list of objects as separate documents to a document stream. + # + # Example: + # + # Psych.dump_stream("foo\n ", {}) # => "--- ! \"foo\\n \"\n--- {}\n" + def self.dump_stream *objects + visitor = Psych::Visitors::YAMLTree.new {} + objects.each do |o| + visitor << o + end + visitor.tree.to_yaml + end + + ### + # Dump Ruby object +o+ to a JSON string. + def self.to_json o + visitor = Psych::Visitors::JSONTree.new + visitor << o + visitor.tree.to_yaml + end + + ### + # Load multiple documents given in +yaml+. Returns the parsed documents + # as a list. For example: + # + # Psych.load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar'] + # + def self.load_stream yaml + parse_stream(yaml).children.map { |child| child.to_ruby } + end + + ### + # Load the document contained in +filename+. Returns the yaml contained in + # +filename+ as a ruby object + def self.load_file filename + self.load File.open(filename) + end + + # :stopdoc: + @domain_types = {} + def self.add_domain_type domain, type_tag, &block + key = ['tag', domain, type_tag].join ':' + @domain_types[key] = [key, block] + @domain_types["tag:#{type_tag}"] = [key, block] + end + + def self.add_builtin_type type_tag, &block + domain = 'yaml.org,2002' + key = ['tag', domain, type_tag].join ':' + @domain_types[key] = [key, block] + end + + def self.remove_type type_tag + @domain_types.delete type_tag + end + + @load_tags = {} + @dump_tags = {} + def self.add_tag tag, klass + @load_tags[tag] = klass + @dump_tags[klass] = tag + end + + class << self + attr_accessor :load_tags + attr_accessor :dump_tags + attr_accessor :domain_types + end + # :startdoc: +end diff --git a/lib/19/psych/coder.rb b/lib/19/psych/coder.rb new file mode 100644 index 0000000000..c06c9c1e61 --- /dev/null +++ b/lib/19/psych/coder.rb @@ -0,0 +1,86 @@ +module Psych + ### + # If an object defines +encode_with+, then an instance of Psych::Coder will + # be passed to the method when the object is being serialized. The Coder + # automatically assumes a Psych::Nodes::Mapping is being emitted. Other + # objects like Sequence and Scalar may be emitted if +seq=+ or +scalar=+ are + # called, respectively. + class Coder + attr_accessor :tag, :style, :implicit + attr_reader :type, :seq + + def initialize tag + @map = {} + @seq = [] + @implicit = false + @type = :map + @tag = tag + @style = Psych::Nodes::Mapping::BLOCK + @scalar = nil + end + + def scalar *args + if args.length > 0 + warn "#{caller[0]}: Coder#scalar(a,b,c) is deprecated" if $VERBOSE + @tag, @scalar, _ = args + @type = :scalar + end + @scalar + end + + # Emit a map. The coder will be yielded to the block. + def map tag = @tag, style = @style + @tag = tag + @style = style + yield self if block_given? + @map + end + + # Emit a scalar with +value+ and +tag+ + def represent_scalar tag, value + self.tag = tag + self.scalar = value + end + + # Emit a sequence with +list+ and +tag+ + def represent_seq tag, list + @tag = tag + self.seq = list + end + + # Emit a sequence with +map+ and +tag+ + def represent_map tag, map + @tag = tag + self.map = map + end + + # Emit a scalar with +value+ + def scalar= value + @type = :scalar + @scalar = value + end + + # Emit a map with +value+ + def map= map + @type = :map + @map = map + end + + def []= k, v + @type = :map + @map[k] = v + end + alias :add :[]= + + def [] k + @type = :map + @map[k] + end + + # Emit a sequence of +list+ + def seq= list + @type = :seq + @seq = list + end + end +end diff --git a/lib/19/psych/core_ext.rb b/lib/19/psych/core_ext.rb new file mode 100644 index 0000000000..8d3e8fb7b6 --- /dev/null +++ b/lib/19/psych/core_ext.rb @@ -0,0 +1,38 @@ +class Object + def self.yaml_tag url + Psych.add_tag(url, self) + end + + # FIXME: rename this to "to_yaml" when syck is removed + + ### + # call-seq: to_yaml + # + # Convert an object to YAML + def psych_to_yaml options = {} + Psych.dump self, options + end + remove_method :to_yaml rescue nil + alias :to_yaml :psych_to_yaml +end + +class Module + def psych_yaml_as url + return if caller[0].end_with?('rubytypes.rb') + if $VERBOSE + warn "#{caller[0]}: yaml_as is deprecated, please use yaml_tag" + end + Psych.add_tag(url, self) + end + + remove_method :yaml_as rescue nil + alias :yaml_as :psych_yaml_as +end + +module Kernel + def psych_y *objects + puts Psych.dump_stream(*objects) + end + remove_method :y rescue nil + alias y psych_y +end diff --git a/lib/19/psych/deprecated.rb b/lib/19/psych/deprecated.rb new file mode 100644 index 0000000000..f4034e32c0 --- /dev/null +++ b/lib/19/psych/deprecated.rb @@ -0,0 +1,82 @@ +require 'date' + +module Psych + DEPRECATED = __FILE__ # :nodoc: + + module DeprecatedMethods # :nodoc: + attr_accessor :taguri + attr_accessor :to_yaml_style + end + + def self.quick_emit thing, opts = {}, &block # :nodoc: + warn "#{caller[0]}: YAML.quick_emit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + target = eval 'self', block.binding + target.extend DeprecatedMethods + metaclass = class << target; self; end + metaclass.send(:define_method, :encode_with) do |coder| + target.taguri = coder.tag + target.to_yaml_style = coder.style + block.call coder + end + target.psych_to_yaml unless opts[:nodump] + end + + def self.load_documents yaml, &block + if $VERBOSE + warn "#{caller[0]}: load_documents is deprecated, use load_stream" + end + list = load_stream yaml + return list unless block_given? + list.each(&block) + end + + def self.detect_implicit thing + warn "#{caller[0]}: detect_implicit is deprecated" if $VERBOSE + return '' unless String === thing + return 'null' if '' == thing + ScalarScanner.new.tokenize(thing).class.name.downcase + end + + def self.add_ruby_type type_tag, &block + warn "#{caller[0]}: add_ruby_type is deprecated, use add_domain_type" if $VERBOSE + domain = 'ruby.yaml.org,2002' + key = ['tag', domain, type_tag].join ':' + @domain_types[key] = [key, block] + end + + def self.add_private_type type_tag, &block + warn "#{caller[0]}: add_private_type is deprecated, use add_domain_type" if $VERBOSE + domain = 'x-private' + key = [domain, type_tag].join ':' + @domain_types[key] = [key, block] + end + + def self.tagurize thing + warn "#{caller[0]}: add_private_type is deprecated, use add_domain_type" if $VERBOSE + return thing unless String === thing + "tag:yaml.org,2002:#{thing}" + end + + def self.read_type_class type, reference + warn "#{caller[0]}: read_type_class is deprecated" if $VERBOSE + _, _, type, name = type.split ':', 4 + + reference = name.split('::').inject(reference) do |k,n| + k.const_get(n.to_sym) + end if name + [type, reference] + end + + def self.object_maker klass, hash + warn "#{caller[0]}: object_maker is deprecated" if $VERBOSE + klass.allocate.tap do |obj| + hash.each { |k,v| obj.instance_variable_set(:"@#{k}", v) } + end + end +end + +class Object + def to_yaml_properties # :nodoc: + instance_variables + end +end diff --git a/lib/19/psych/ext/emitter.c b/lib/19/psych/ext/emitter.c new file mode 100644 index 0000000000..befa98e821 --- /dev/null +++ b/lib/19/psych/ext/emitter.c @@ -0,0 +1,412 @@ +#include + +VALUE cPsychEmitter; +static ID id_write; + +static void emit(yaml_emitter_t * emitter, yaml_event_t * event) +{ + if(!yaml_emitter_emit(emitter, event)) + rb_raise(rb_eRuntimeError, "%s", emitter->problem); +} + +static int writer(void *ctx, unsigned char *buffer, size_t size) +{ + VALUE io = (VALUE)ctx; + VALUE str = rb_str_new((const char *)buffer, (long)size); + VALUE wrote = rb_funcall(io, id_write, 1, str); + return (int)NUM2INT(wrote); +} + +static void dealloc(yaml_emitter_t * emitter) +{ + yaml_emitter_delete(emitter); + free(emitter); +} + +static VALUE allocate(VALUE klass) +{ + yaml_emitter_t * emitter = malloc(sizeof(yaml_emitter_t)); + yaml_emitter_initialize(emitter); + yaml_emitter_set_unicode(emitter, 1); + yaml_emitter_set_indent(emitter, 2); + + return Data_Wrap_Struct(klass, 0, dealloc, emitter); +} + +/* call-seq: Psych::Emitter.new(io) + * + * Create a new Psych::Emitter that writes to +io+. + */ +static VALUE initialize(VALUE self, VALUE io) +{ + yaml_emitter_t * emitter; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + yaml_emitter_set_output(emitter, writer, (void *)io); + + return self; +} + +/* call-seq: emitter.start_stream(encoding) + * + * Start a stream emission with +encoding+ + * + * See Psych::Handler#start_stream + */ +static VALUE start_stream(VALUE self, VALUE encoding) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + Data_Get_Struct(self, yaml_emitter_t, emitter); + Check_Type(encoding, T_FIXNUM); + + yaml_stream_start_event_initialize(&event, (yaml_encoding_t)NUM2INT(encoding)); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.end_stream + * + * End a stream emission + * + * See Psych::Handler#end_stream + */ +static VALUE end_stream(VALUE self) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + yaml_stream_end_event_initialize(&event); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.start_document(version, tags, implicit) + * + * Start a document emission with YAML +version+, +tags+, and an +implicit+ + * start. + * + * See Psych::Handler#start_document + */ +static VALUE start_document(VALUE self, VALUE version, VALUE tags, VALUE imp) +{ + yaml_emitter_t * emitter; + yaml_tag_directive_t * head = NULL; + yaml_tag_directive_t * tail = NULL; + yaml_event_t event; + yaml_version_directive_t version_directive; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + + Check_Type(version, T_ARRAY); + + if(RARRAY_LEN(version) > 0) { + VALUE major = rb_ary_entry(version, (long)0); + VALUE minor = rb_ary_entry(version, (long)1); + + version_directive.major = NUM2INT(major); + version_directive.minor = NUM2INT(minor); + } + + if(RTEST(tags)) { + int i = 0; + + Check_Type(tags, T_ARRAY); + + head = xcalloc((size_t)RARRAY_LEN(tags), sizeof(yaml_tag_directive_t)); + tail = head; + + for(i = 0; i < RARRAY_LEN(tags); i++) { + VALUE tuple = RARRAY_PTR(tags)[i]; + Check_Type(tuple, T_ARRAY); + + if(RARRAY_LEN(tuple) < 2) { + xfree(head); + rb_raise(rb_eRuntimeError, "tag tuple must be of length 2"); + } + + tail->handle = (yaml_char_t *)StringValuePtr(RARRAY_PTR(tuple)[0]); + tail->prefix = (yaml_char_t *)StringValuePtr(RARRAY_PTR(tuple)[1]); + + tail++; + } + } + + yaml_document_start_event_initialize( + &event, + (RARRAY_LEN(version) > 0) ? &version_directive : NULL, + head, + tail, + imp ? 1 : 0 + ); + + emit(emitter, &event); + + if(head) xfree(head); + + return self; +} + +/* call-seq: emitter.end_document(implicit) + * + * End a document emission with an +implicit+ ending. + * + * See Psych::Handler#end_document + */ +static VALUE end_document(VALUE self, VALUE imp) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + yaml_document_end_event_initialize(&event, imp ? 1 : 0); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.scalar(value, anchor, tag, plain, quoted, style) + * + * Emit a scalar with +value+, +anchor+, +tag+, and a +plain+ or +quoted+ + * string type with +style+. + * + * See Psych::Handler#scalar + */ +static VALUE scalar( + VALUE self, + VALUE value, + VALUE anchor, + VALUE tag, + VALUE plain, + VALUE quoted, + VALUE style + ) { + yaml_emitter_t * emitter; + yaml_event_t event; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + Check_Type(value, T_STRING); + + yaml_scalar_event_initialize( + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)), + (yaml_char_t *)(NIL_P(tag) ? NULL : StringValuePtr(tag)), + (yaml_char_t*)StringValuePtr(value), + (int)RSTRING_LEN(value), + plain ? 1 : 0, + quoted ? 1 : 0, + (yaml_scalar_style_t)NUM2INT(style) + ); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.start_sequence(anchor, tag, implicit, style) + * + * Start emitting a sequence with +anchor+, a +tag+, +implicit+ sequence + * start and end, along with +style+. + * + * See Psych::Handler#start_sequence + */ +static VALUE start_sequence( + VALUE self, + VALUE anchor, + VALUE tag, + VALUE implicit, + VALUE style + ) { + yaml_emitter_t * emitter; + yaml_event_t event; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + yaml_sequence_start_event_initialize( + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)), + (yaml_char_t *)(NIL_P(tag) ? NULL : StringValuePtr(tag)), + implicit ? 1 : 0, + (yaml_sequence_style_t)NUM2INT(style) + ); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.end_sequence + * + * End sequence emission. + * + * See Psych::Handler#end_sequence + */ +static VALUE end_sequence(VALUE self) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + yaml_sequence_end_event_initialize(&event); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.start_mapping(anchor, tag, implicit, style) + * + * Start emitting a YAML map with +anchor+, +tag+, an +implicit+ start + * and end, and +style+. + * + * See Psych::Handler#start_mapping + */ +static VALUE start_mapping( + VALUE self, + VALUE anchor, + VALUE tag, + VALUE implicit, + VALUE style + ) { + yaml_emitter_t * emitter; + yaml_event_t event; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + yaml_mapping_start_event_initialize( + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)), + (yaml_char_t *)(NIL_P(tag) ? NULL : StringValuePtr(tag)), + implicit ? 1 : 0, + (yaml_sequence_style_t)NUM2INT(style) + ); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.end_mapping + * + * Emit the end of a mapping. + * + * See Psych::Handler#end_mapping + */ +static VALUE end_mapping(VALUE self) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + yaml_mapping_end_event_initialize(&event); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.alias(anchor) + * + * Emit an alias with +anchor+. + * + * See Psych::Handler#alias + */ +static VALUE alias(VALUE self, VALUE anchor) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + yaml_alias_event_initialize( + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)) + ); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.canonical = true + * + * Set the output style to canonical, or not. + */ +static VALUE set_canonical(VALUE self, VALUE style) +{ + yaml_emitter_t * emitter; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + yaml_emitter_set_canonical(emitter, Qtrue == style ? 1 : 0); + + return style; +} + +/* call-seq: emitter.canonical + * + * Get the output style, canonical or not. + */ +static VALUE canonical(VALUE self) +{ + yaml_emitter_t * emitter; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + return (emitter->canonical == 0) ? Qfalse : Qtrue; +} + +/* call-seq: emitter.indentation = level + * + * Set the indentation level to +level+. + */ +static VALUE set_indentation(VALUE self, VALUE level) +{ + yaml_emitter_t * emitter; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + yaml_emitter_set_indent(emitter, NUM2INT(level)); + + return level; +} + +/* call-seq: emitter.indentation + * + * Get the indentation level. + */ +static VALUE indentation(VALUE self) +{ + yaml_emitter_t * emitter; + Data_Get_Struct(self, yaml_emitter_t, emitter); + + return INT2NUM(emitter->best_indent); +} + +void Init_psych_emitter() +{ + VALUE psych = rb_define_module("Psych"); + VALUE handler = rb_define_class_under(psych, "Handler", rb_cObject); + cPsychEmitter = rb_define_class_under(psych, "Emitter", handler); + + rb_define_alloc_func(cPsychEmitter, allocate); + + rb_define_method(cPsychEmitter, "initialize", initialize, 1); + rb_define_method(cPsychEmitter, "start_stream", start_stream, 1); + rb_define_method(cPsychEmitter, "end_stream", end_stream, 0); + rb_define_method(cPsychEmitter, "start_document", start_document, 3); + rb_define_method(cPsychEmitter, "end_document", end_document, 1); + rb_define_method(cPsychEmitter, "scalar", scalar, 6); + rb_define_method(cPsychEmitter, "start_sequence", start_sequence, 4); + rb_define_method(cPsychEmitter, "end_sequence", end_sequence, 0); + rb_define_method(cPsychEmitter, "start_mapping", start_mapping, 4); + rb_define_method(cPsychEmitter, "end_mapping", end_mapping, 0); + rb_define_method(cPsychEmitter, "alias", alias, 1); + rb_define_method(cPsychEmitter, "canonical", canonical, 0); + rb_define_method(cPsychEmitter, "canonical=", set_canonical, 1); + rb_define_method(cPsychEmitter, "indentation", indentation, 0); + rb_define_method(cPsychEmitter, "indentation=", set_indentation, 1); + + id_write = rb_intern("write"); +} +/* vim: set noet sws=4 sw=4: */ diff --git a/lib/19/psych/ext/emitter.h b/lib/19/psych/ext/emitter.h new file mode 100644 index 0000000000..560451ef31 --- /dev/null +++ b/lib/19/psych/ext/emitter.h @@ -0,0 +1,8 @@ +#ifndef PSYCH_EMITTER_H +#define PSYCH_EMITTER_H + +#include + +void Init_psych_emitter(); + +#endif diff --git a/lib/19/psych/ext/extconf.rb b/lib/19/psych/ext/extconf.rb new file mode 100644 index 0000000000..11f44ac104 --- /dev/null +++ b/lib/19/psych/ext/extconf.rb @@ -0,0 +1,16 @@ +require 'mkmf' + +# :stopdoc: + +dir_config 'libyaml' + +def asplode missing + abort "#{missing} is missing. Please install libyaml." +end + +asplode('yaml.h') unless find_header 'yaml.h' +asplode('libyaml') unless find_library 'yaml', 'yaml_get_version' + +create_makefile 'psych' + +# :startdoc: diff --git a/lib/19/psych/ext/parser.c b/lib/19/psych/ext/parser.c new file mode 100644 index 0000000000..a69f2763bc --- /dev/null +++ b/lib/19/psych/ext/parser.c @@ -0,0 +1,341 @@ +#include + +VALUE cPsychParser; +VALUE ePsychSyntaxError; + +static ID id_read; +static ID id_empty; +static ID id_start_stream; +static ID id_end_stream; +static ID id_start_document; +static ID id_end_document; +static ID id_alias; +static ID id_scalar; +static ID id_start_sequence; +static ID id_end_sequence; +static ID id_start_mapping; +static ID id_end_mapping; + +#define PSYCH_TRANSCODE(_str, _yaml_enc, _internal_enc) \ + do { \ + rb_enc_associate_index(_str, _yaml_enc); \ + if(_internal_enc) \ + _str = rb_str_export_to_enc(_str, _internal_enc); \ + } while (0) + +static int io_reader(void * data, unsigned char *buf, size_t size, size_t *read) +{ + VALUE io = (VALUE)data; + VALUE string = rb_funcall(io, id_read, 1, INT2NUM(size)); + + *read = 0; + + if(! NIL_P(string)) { + void * str = (void *)StringValuePtr(string); + *read = (size_t)RSTRING_LEN(string); + memcpy(buf, str, *read); + } + + return 1; +} + +/* + * call-seq: + * parser.parse(yaml) + * + * Parse the YAML document contained in +yaml+. Events will be called on + * the handler set on the parser instance. + * + * See Psych::Parser and Psych::Parser#handler + */ +static VALUE parse(VALUE self, VALUE yaml) +{ + yaml_parser_t parser; + yaml_event_t event; + int done = 0; + int tainted = 0; +#ifdef HAVE_RUBY_ENCODING_H + int encoding = rb_enc_find_index("ASCII-8BIT"); + rb_encoding * internal_enc; +#endif + VALUE handler = rb_iv_get(self, "@handler"); + + + yaml_parser_initialize(&parser); + + if (OBJ_TAINTED(yaml)) tainted = 1; + + if(rb_respond_to(yaml, id_read)) { + yaml_parser_set_input(&parser, io_reader, (void *)yaml); + if (RTEST(rb_obj_is_kind_of(yaml, rb_cIO))) tainted = 1; + } else { + StringValue(yaml); + yaml_parser_set_input_string( + &parser, + (const unsigned char *)RSTRING_PTR(yaml), + (size_t)RSTRING_LEN(yaml) + ); + } + + while(!done) { + if(!yaml_parser_parse(&parser, &event)) { + size_t line = parser.mark.line + 1; + size_t column = parser.mark.column; + + yaml_parser_delete(&parser); + rb_raise(ePsychSyntaxError, "couldn't parse YAML at line %d column %d", + (int)line, (int)column); + } + + switch(event.type) { + case YAML_STREAM_START_EVENT: + +#ifdef HAVE_RUBY_ENCODING_H + switch(event.data.stream_start.encoding) { + case YAML_ANY_ENCODING: + break; + case YAML_UTF8_ENCODING: + encoding = rb_enc_find_index("UTF-8"); + break; + case YAML_UTF16LE_ENCODING: + encoding = rb_enc_find_index("UTF-16LE"); + break; + case YAML_UTF16BE_ENCODING: + encoding = rb_enc_find_index("UTF-16BE"); + break; + default: + break; + } + internal_enc = rb_default_internal_encoding(); +#endif + + rb_funcall(handler, id_start_stream, 1, + INT2NUM((long)event.data.stream_start.encoding) + ); + break; + case YAML_DOCUMENT_START_EVENT: + { + /* Get a list of tag directives (if any) */ + VALUE tag_directives = rb_ary_new(); + /* Grab the document version */ + VALUE version = event.data.document_start.version_directive ? + rb_ary_new3( + (long)2, + INT2NUM((long)event.data.document_start.version_directive->major), + INT2NUM((long)event.data.document_start.version_directive->minor) + ) : rb_ary_new(); + + if(event.data.document_start.tag_directives.start) { + yaml_tag_directive_t *start = + event.data.document_start.tag_directives.start; + yaml_tag_directive_t *end = + event.data.document_start.tag_directives.end; + for(; start != end; start++) { + VALUE handle = Qnil; + VALUE prefix = Qnil; + if(start->handle) { + handle = rb_str_new2((const char *)start->handle); + if (tainted) OBJ_TAINT(handle); +#ifdef HAVE_RUBY_ENCODING_H + PSYCH_TRANSCODE(handle, encoding, internal_enc); +#endif + } + + if(start->prefix) { + prefix = rb_str_new2((const char *)start->prefix); + if (tainted) OBJ_TAINT(prefix); +#ifdef HAVE_RUBY_ENCODING_H + PSYCH_TRANSCODE(prefix, encoding, internal_enc); +#endif + } + + rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix)); + } + } + rb_funcall(handler, id_start_document, 3, + version, tag_directives, + event.data.document_start.implicit == 1 ? Qtrue : Qfalse + ); + } + break; + case YAML_DOCUMENT_END_EVENT: + rb_funcall(handler, id_end_document, 1, + event.data.document_end.implicit == 1 ? Qtrue : Qfalse + ); + break; + case YAML_ALIAS_EVENT: + { + VALUE alias = Qnil; + if(event.data.alias.anchor) { + alias = rb_str_new2((const char *)event.data.alias.anchor); + if (tainted) OBJ_TAINT(alias); +#ifdef HAVE_RUBY_ENCODING_H + PSYCH_TRANSCODE(alias, encoding, internal_enc); +#endif + } + + rb_funcall(handler, id_alias, 1, alias); + } + break; + case YAML_SCALAR_EVENT: + { + VALUE anchor = Qnil; + VALUE tag = Qnil; + VALUE plain_implicit, quoted_implicit, style; + VALUE val = rb_str_new( + (const char *)event.data.scalar.value, + (long)event.data.scalar.length + ); + if (tainted) OBJ_TAINT(val); + +#ifdef HAVE_RUBY_ENCODING_H + PSYCH_TRANSCODE(val, encoding, internal_enc); +#endif + + if(event.data.scalar.anchor) { + anchor = rb_str_new2((const char *)event.data.scalar.anchor); + if (tainted) OBJ_TAINT(anchor); +#ifdef HAVE_RUBY_ENCODING_H + PSYCH_TRANSCODE(anchor, encoding, internal_enc); +#endif + } + + if(event.data.scalar.tag) { + tag = rb_str_new2((const char *)event.data.scalar.tag); + if (tainted) OBJ_TAINT(tag); +#ifdef HAVE_RUBY_ENCODING_H + PSYCH_TRANSCODE(tag, encoding, internal_enc); +#endif + } + + plain_implicit = + event.data.scalar.plain_implicit == 0 ? Qfalse : Qtrue; + + quoted_implicit = + event.data.scalar.quoted_implicit == 0 ? Qfalse : Qtrue; + + style = INT2NUM((long)event.data.scalar.style); + + rb_funcall(handler, id_scalar, 6, + val, anchor, tag, plain_implicit, quoted_implicit, style); + } + break; + case YAML_SEQUENCE_START_EVENT: + { + VALUE anchor = Qnil; + VALUE tag = Qnil; + VALUE implicit, style; + if(event.data.sequence_start.anchor) { + anchor = rb_str_new2((const char *)event.data.sequence_start.anchor); + if (tainted) OBJ_TAINT(anchor); +#ifdef HAVE_RUBY_ENCODING_H + PSYCH_TRANSCODE(anchor, encoding, internal_enc); +#endif + } + + tag = Qnil; + if(event.data.sequence_start.tag) { + tag = rb_str_new2((const char *)event.data.sequence_start.tag); + if (tainted) OBJ_TAINT(tag); +#ifdef HAVE_RUBY_ENCODING_H + PSYCH_TRANSCODE(tag, encoding, internal_enc); +#endif + } + + implicit = + event.data.sequence_start.implicit == 0 ? Qfalse : Qtrue; + + style = INT2NUM((long)event.data.sequence_start.style); + + rb_funcall(handler, id_start_sequence, 4, + anchor, tag, implicit, style); + } + break; + case YAML_SEQUENCE_END_EVENT: + rb_funcall(handler, id_end_sequence, 0); + break; + case YAML_MAPPING_START_EVENT: + { + VALUE anchor = Qnil; + VALUE tag = Qnil; + VALUE implicit, style; + if(event.data.mapping_start.anchor) { + anchor = rb_str_new2((const char *)event.data.mapping_start.anchor); + if (tainted) OBJ_TAINT(anchor); +#ifdef HAVE_RUBY_ENCODING_H + PSYCH_TRANSCODE(anchor, encoding, internal_enc); +#endif + } + + if(event.data.mapping_start.tag) { + tag = rb_str_new2((const char *)event.data.mapping_start.tag); + if (tainted) OBJ_TAINT(tag); +#ifdef HAVE_RUBY_ENCODING_H + PSYCH_TRANSCODE(tag, encoding, internal_enc); +#endif + } + + implicit = + event.data.mapping_start.implicit == 0 ? Qfalse : Qtrue; + + style = INT2NUM((long)event.data.mapping_start.style); + + rb_funcall(handler, id_start_mapping, 4, + anchor, tag, implicit, style); + } + break; + case YAML_MAPPING_END_EVENT: + rb_funcall(handler, id_end_mapping, 0); + break; + case YAML_NO_EVENT: + rb_funcall(handler, id_empty, 0); + break; + case YAML_STREAM_END_EVENT: + rb_funcall(handler, id_end_stream, 0); + done = 1; + break; + } + yaml_event_delete(&event); + } + + return self; +} + +void Init_psych_parser() +{ +#if 0 + mPsych = rb_define_module("Psych"); +#endif + + cPsychParser = rb_define_class_under(mPsych, "Parser", rb_cObject); + + /* Any encoding: Let the parser choose the encoding */ + rb_define_const(cPsychParser, "ANY", INT2NUM(YAML_ANY_ENCODING)); + + /* UTF-8 Encoding */ + rb_define_const(cPsychParser, "UTF8", INT2NUM(YAML_UTF8_ENCODING)); + + /* UTF-16-LE Encoding with BOM */ + rb_define_const(cPsychParser, "UTF16LE", INT2NUM(YAML_UTF16LE_ENCODING)); + + /* UTF-16-BE Encoding with BOM */ + rb_define_const(cPsychParser, "UTF16BE", INT2NUM(YAML_UTF16BE_ENCODING)); + + ePsychSyntaxError = rb_define_class_under(mPsych, "SyntaxError", rb_eSyntaxError); + + rb_define_method(cPsychParser, "parse", parse, 1); + + id_read = rb_intern("read"); + id_empty = rb_intern("empty"); + id_start_stream = rb_intern("start_stream"); + id_end_stream = rb_intern("end_stream"); + id_start_document = rb_intern("start_document"); + id_end_document = rb_intern("end_document"); + id_alias = rb_intern("alias"); + id_scalar = rb_intern("scalar"); + id_start_sequence = rb_intern("start_sequence"); + id_end_sequence = rb_intern("end_sequence"); + id_start_mapping = rb_intern("start_mapping"); + id_end_mapping = rb_intern("end_mapping"); +} +/* vim: set noet sws=4 sw=4: */ diff --git a/lib/19/psych/ext/parser.h b/lib/19/psych/ext/parser.h new file mode 100644 index 0000000000..25e896f01d --- /dev/null +++ b/lib/19/psych/ext/parser.h @@ -0,0 +1,6 @@ +#ifndef PSYCH_PARSER_H +#define PSYCH_PARSER_H + +void Init_psych_parser(); + +#endif diff --git a/lib/19/psych/ext/psych.c b/lib/19/psych/ext/psych.c new file mode 100644 index 0000000000..69ff1d8dfc --- /dev/null +++ b/lib/19/psych/ext/psych.c @@ -0,0 +1,34 @@ +#include + +/* call-seq: Psych.libyaml_version + * + * Returns the version of libyaml being used + */ +static VALUE libyaml_version(VALUE module) +{ + int major, minor, patch; + VALUE list[3]; + + yaml_get_version(&major, &minor, &patch); + + list[0] = INT2NUM((long)major); + list[1] = INT2NUM((long)minor); + list[2] = INT2NUM((long)patch); + + return rb_ary_new4((long)3, list); +} + +VALUE mPsych; + +void Init_psych() +{ + mPsych = rb_define_module("Psych"); + + rb_define_singleton_method(mPsych, "libyaml_version", libyaml_version, 0); + + Init_psych_parser(); + Init_psych_emitter(); + Init_psych_to_ruby(); + Init_psych_yaml_tree(); +} +/* vim: set noet sws=4 sw=4: */ diff --git a/lib/19/psych/ext/psych.h b/lib/19/psych/ext/psych.h new file mode 100644 index 0000000000..9f1be449a2 --- /dev/null +++ b/lib/19/psych/ext/psych.h @@ -0,0 +1,20 @@ +#ifndef PSYCH_H +#define PSYCH_H + +#include + +#ifdef HAVE_RUBY_ENCODING_H +#include +#endif + +#include + +#include +#include +#include +#include + +extern VALUE mPsych; + + +#endif diff --git a/lib/19/psych/ext/to_ruby.c b/lib/19/psych/ext/to_ruby.c new file mode 100644 index 0000000000..ed5245e12e --- /dev/null +++ b/lib/19/psych/ext/to_ruby.c @@ -0,0 +1,41 @@ +#include + +VALUE cPsychVisitorsToRuby; + +/* call-seq: vis.build_exception(klass, message) + * + * Create an exception with class +klass+ and +message+ + */ +static VALUE build_exception(VALUE self, VALUE klass, VALUE mesg) +{ + VALUE e = rb_obj_alloc(klass); + + rb_iv_set(e, "mesg", mesg); + + return e; +} + +/* call-seq: vis.path2class(path) + * + * Convert +path+ string to a class + */ +static VALUE path2class(VALUE self, VALUE path) +{ +#ifdef HAVE_RUBY_ENCODING_H + return rb_path_to_class(path); +#else + return rb_path2class(StringValuePtr(path)); +#endif +} + +void Init_psych_to_ruby(void) +{ + VALUE psych = rb_define_module("Psych"); + VALUE visitors = rb_define_module_under(psych, "Visitors"); + VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject); + cPsychVisitorsToRuby = rb_define_class_under(visitors, "ToRuby", visitor); + + rb_define_private_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2); + rb_define_private_method(cPsychVisitorsToRuby, "path2class", path2class, 1); +} +/* vim: set noet sws=4 sw=4: */ diff --git a/lib/19/psych/ext/to_ruby.h b/lib/19/psych/ext/to_ruby.h new file mode 100644 index 0000000000..7b8e757a45 --- /dev/null +++ b/lib/19/psych/ext/to_ruby.h @@ -0,0 +1,8 @@ +#ifndef PSYCH_TO_RUBY_H +#define PSYCH_TO_RUBY_H + +#include + +void Init_psych_to_ruby(void); + +#endif diff --git a/lib/19/psych/ext/yaml_tree.c b/lib/19/psych/ext/yaml_tree.c new file mode 100644 index 0000000000..bcf24d2070 --- /dev/null +++ b/lib/19/psych/ext/yaml_tree.c @@ -0,0 +1,24 @@ +#include + +VALUE cPsychVisitorsYamlTree; + +/* + * call-seq: private_iv_get(target, prop) + * + * Get the private instance variable +prop+ from +target+ + */ +static VALUE private_iv_get(VALUE self, VALUE target, VALUE prop) +{ + return rb_attr_get(target, rb_intern(StringValuePtr(prop))); +} + +void Init_psych_yaml_tree(void) +{ + VALUE psych = rb_define_module("Psych"); + VALUE visitors = rb_define_module_under(psych, "Visitors"); + VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject); + cPsychVisitorsYamlTree = rb_define_class_under(visitors, "YAMLTree", visitor); + + rb_define_private_method(cPsychVisitorsYamlTree, "private_iv_get", private_iv_get, 2); +} +/* vim: set noet sws=4 sw=4: */ diff --git a/lib/19/psych/ext/yaml_tree.h b/lib/19/psych/ext/yaml_tree.h new file mode 100644 index 0000000000..4628a69d71 --- /dev/null +++ b/lib/19/psych/ext/yaml_tree.h @@ -0,0 +1,8 @@ +#ifndef PSYCH_YAML_TREE_H +#define PSYCH_YAML_TREE_H + +#include + +void Init_psych_yaml_tree(void); + +#endif diff --git a/lib/19/psych/handler.rb b/lib/19/psych/handler.rb new file mode 100644 index 0000000000..bfc62d701f --- /dev/null +++ b/lib/19/psych/handler.rb @@ -0,0 +1,215 @@ +module Psych + ### + # Psych::Handler is an abstract base class that defines the events used + # when dealing with Psych::Parser. Clients who want to use Psych::Parser + # should implement a class that inherits from Psych::Handler and define + # events that they can handle. + # + # Psych::Handler defines all events that Psych::Parser can possibly send to + # event handlers. + # + # See Psych::Parser for more details + class Handler + ### + # Called with +encoding+ when the YAML stream starts. This method is + # called once per stream. A stream may contain multiple documents. + # + # See the constants in Psych::Parser for the possible values of +encoding+. + def start_stream encoding + end + + ### + # Called when the document starts with the declared +version+, + # +tag_directives+, if the document is +implicit+. + # + # +version+ will be an array of integers indicating the YAML version being + # dealt with, +tag_directives+ is a list of tuples indicating the prefix + # and suffix of each tag, and +implicit+ is a boolean indicating whether + # the document is started implicitly. + # + # === Example + # + # Given the following YAML: + # + # %YAML 1.1 + # %TAG ! tag:tenderlovemaking.com,2009: + # --- !squee + # + # The parameters for start_document must be this: + # + # version # => [1, 1] + # tag_directives # => [["!", "tag:tenderlovemaking.com,2009:"]] + # implicit # => false + def start_document version, tag_directives, implicit + end + + ### + # Called with the document ends. +implicit+ is a boolean value indicating + # whether or not the document has an implicit ending. + # + # === Example + # + # Given the following YAML: + # + # --- + # hello world + # + # +implicit+ will be true. Given this YAML: + # + # --- + # hello world + # ... + # + # +implicit+ will be false. + def end_document implicit + end + + ### + # Called when an alias is found to +anchor+. +anchor+ will be the name + # of the anchor found. + # + # === Example + # + # Here we have an example of an array that references itself in YAML: + # + # --- &ponies + # - first element + # - *ponies + # + # &ponies is the achor, *ponies is the alias. In this case, alias is + # called with "ponies". + def alias anchor + end + + ### + # Called when a scalar +value+ is found. The scalar may have an + # +anchor+, a +tag+, be implicitly +plain+ or implicitly +quoted+ + # + # +value+ is the string value of the scalar + # +anchor+ is an associated anchor or nil + # +tag+ is an associated tag or nil + # +plain+ is a boolean value + # +quoted+ is a boolean value + # +style+ is an integer idicating the string style + # + # See the constants in Psych::Nodes::Scalar for the possible values of + # +style+ + # + # === Example + # + # Here is a YAML document that exercises most of the possible ways this + # method can be called: + # + # --- + # - !str "foo" + # - &anchor fun + # - many + # lines + # - | + # many + # newlines + # + # The above YAML document contains a list with four strings. Here are + # the parameters sent to this method in the same order: + # + # # value anchor tag plain quoted style + # ["foo", nil, "!str", false, false, 3 ] + # ["fun", "anchor", nil, true, false, 1 ] + # ["many lines", nil, nil, true, false, 1 ] + # ["many\nnewlines\n", nil, nil, false, true, 4 ] + # + def scalar value, anchor, tag, plain, quoted, style + end + + ### + # Called when a sequence is started. + # + # +anchor+ is the anchor associated with the sequence or nil. + # +tag+ is the tag associated with the sequence or nil. + # +implicit+ a boolean indicating whether or not the sequence was implicitly + # started. + # +style+ is an integer indicating the list style. + # + # See the constants in Psych::Nodes::Sequence for the possible values of + # +style+. + # + # === Example + # + # Here is a YAML document that exercises most of the possible ways this + # method can be called: + # + # --- + # - !!seq [ + # a + # ] + # - &pewpew + # - b + # + # The above YAML document consists of three lists, an outer list that + # contains two inner lists. Here is a matrix of the parameters sent + # to represent these lists: + # + # # anchor tag implicit style + # [nil, nil, true, 1 ] + # [nil, "tag:yaml.org,2002:seq", false, 2 ] + # ["pewpew", nil, true, 1 ] + + def start_sequence anchor, tag, implicit, style + end + + ### + # Called when a sequence ends. + def end_sequence + end + + ### + # Called when a map starts. + # + # +anchor+ is the anchor associated with the map or +nil+. + # +tag+ is the tag associated with the map or +nil+. + # +implicit+ is a boolean indicating whether or not the map was implicitly + # started. + # +style+ is an integer indicating the mapping style. + # + # See the constants in Psych::Nodes::Mapping for the possible values of + # +style+. + # + # === Example + # + # Here is a YAML document that exercises most of the possible ways this + # method can be called: + # + # --- + # k: !!map { hello: world } + # v: &pewpew + # hello: world + # + # The above YAML document consists of three maps, an outer map that contains + # two inner maps. Below is a matrix of the parameters sent in order to + # represent these three maps: + # + # # anchor tag implicit style + # [nil, nil, true, 1 ] + # [nil, "tag:yaml.org,2002:map", false, 2 ] + # ["pewpew", nil, true, 1 ] + + def start_mapping anchor, tag, implicit, style + end + + ### + # Called when a map ends + def end_mapping + end + + ### + # Called when an empty event happens. (Which, as far as I can tell, is + # never). + def empty + end + + ### + # Called when the YAML stream ends + def end_stream + end + end +end diff --git a/lib/19/psych/json/tree_builder.rb b/lib/19/psych/json/tree_builder.rb new file mode 100644 index 0000000000..12e0625866 --- /dev/null +++ b/lib/19/psych/json/tree_builder.rb @@ -0,0 +1,24 @@ +module Psych + module JSON + ### + # Psych::JSON::TreeBuilder is an event based AST builder. Events are sent + # to an instance of Psych::JSON::TreeBuilder and a JSON AST is constructed. + class TreeBuilder < Psych::TreeBuilder + def start_document version, tag_directives, implicit + super(version, tag_directives, true) + end + + def end_document implicit_end + super(true) + end + + def start_mapping anchor, tag, implicit, style + super(anchor, nil, implicit, Nodes::Mapping::FLOW) + end + + def start_sequence anchor, tag, implicit, style + super(anchor, nil, implicit, Nodes::Sequence::FLOW) + end + end + end +end diff --git a/lib/19/psych/nodes.rb b/lib/19/psych/nodes.rb new file mode 100644 index 0000000000..9e5946daa9 --- /dev/null +++ b/lib/19/psych/nodes.rb @@ -0,0 +1,77 @@ +require 'psych/nodes/node' +require 'psych/nodes/stream' +require 'psych/nodes/document' +require 'psych/nodes/sequence' +require 'psych/nodes/scalar' +require 'psych/nodes/mapping' +require 'psych/nodes/alias' + +module Psych + ### + # = Overview + # + # When using Psych.load to deserialize a YAML document, the document is + # translated to an intermediary AST. That intermediary AST is then + # translated in to a Ruby object graph. + # + # In the opposite direction, when using Psych.dump, the Ruby object graph is + # translated to an intermediary AST which is then converted to a YAML + # document. + # + # Psych::Nodes contains all of the classes that make up the nodes of a YAML + # AST. You can manually build an AST and use one of the visitors (see + # Psych::Visitors) to convert that AST to either a YAML document or to a + # Ruby object graph. + # + # Here is an example of building an AST that represents a list with one + # scalar: + # + # # Create our nodes + # stream = Psych::Nodes::Stream.new + # doc = Psych::Nodes::Document.new + # seq = Psych::Nodes::Sequence.new + # scalar = Psych::Nodes::Scalar.new('foo') + # + # # Build up our tree + # stream.children << doc + # doc.children << seq + # seq.children << scalar + # + # The stream is the root of the tree. We can then convert the tree to YAML: + # + # stream.to_yaml => "---\n- foo\n" + # + # Or convert it to Ruby: + # + # stream.to_ruby => [["foo"]] + # + # == YAML AST Requirements + # + # A valid YAML AST *must* have one Psych::Nodes::Stream at the root. A + # Psych::Nodes::Stream node must have 1 or more Psych::Nodes::Document nodes + # as children. + # + # Psych::Nodes::Document nodes must have one and *only* one child. That child + # may be one of: + # + # * Psych::Nodes::Sequence + # * Psych::Nodes::Mapping + # * Psych::Nodes::Scalar + # + # Psych::Nodes::Sequence and Psych::Nodes::Mapping nodes may have many + # children, but Psych::Nodes::Mapping nodes should have an even number of + # children. + # + # All of these are valid children for Psych::Nodes::Sequence and + # Psych::Nodes::Mapping nodes: + # + # * Psych::Nodes::Sequence + # * Psych::Nodes::Mapping + # * Psych::Nodes::Scalar + # * Psych::Nodes::Alias + # + # Psych::Nodes::Scalar and Psych::Nodes::Alias are both terminal nodes and + # should not have any children. + module Nodes + end +end diff --git a/lib/19/psych/nodes/alias.rb b/lib/19/psych/nodes/alias.rb new file mode 100644 index 0000000000..5bd4df13d1 --- /dev/null +++ b/lib/19/psych/nodes/alias.rb @@ -0,0 +1,18 @@ +module Psych + module Nodes + ### + # This class represents a {YAML Alias}[http://yaml.org/spec/1.1/#alias]. + # It points to an +anchor+. + # + # A Psych::Nodes::Alias is a terminal node and may have no children. + class Alias < Psych::Nodes::Node + # The anchor this alias links to + attr_accessor :anchor + + # Create a new Alias that points to an +anchor+ + def initialize anchor + @anchor = anchor + end + end + end +end diff --git a/lib/19/psych/nodes/document.rb b/lib/19/psych/nodes/document.rb new file mode 100644 index 0000000000..32014d60dc --- /dev/null +++ b/lib/19/psych/nodes/document.rb @@ -0,0 +1,60 @@ +module Psych + module Nodes + ### + # This represents a YAML Document. This node must be a child of + # Psych::Nodes::Stream. A Psych::Nodes::Document must have one child, + # and that child may be one of the following: + # + # * Psych::Nodes::Sequence + # * Psych::Nodes::Mapping + # * Psych::Nodes::Scalar + class Document < Psych::Nodes::Node + # The version of the YAML document + attr_accessor :version + + # A list of tag directives for this document + attr_accessor :tag_directives + + # Was this document implicitly created? + attr_accessor :implicit + + # Is the end of the document implicit? + attr_accessor :implicit_end + + ### + # Create a new Psych::Nodes::Document object. + # + # +version+ is a list indicating the YAML version. + # +tags_directives+ is a list of tag directive declarations + # +implicit+ is a flag indicating whether the document will be implicitly + # started. + # + # == Example: + # This creates a YAML document object that represents a YAML 1.1 document + # with one tag directive, and has an implicit start: + # + # Psych::Nodes::Document.new( + # [1,1], + # [["!", "tag:tenderlovemaking.com,2009:"]], + # true + # ) + # + # == See Also + # See also Psych::Handler#start_document + def initialize version = [], tag_directives = [], implicit = false + super() + @version = version + @tag_directives = tag_directives + @implicit = implicit + @implicit_end = true + end + + ### + # Returns the root node. A Document may only have one root node: + # http://yaml.org/spec/1.1/#id898031 + def root + children.first + end + end + end +end diff --git a/lib/19/psych/nodes/mapping.rb b/lib/19/psych/nodes/mapping.rb new file mode 100644 index 0000000000..5ba95ce4b6 --- /dev/null +++ b/lib/19/psych/nodes/mapping.rb @@ -0,0 +1,56 @@ +module Psych + module Nodes + ### + # This class represents a {YAML Mapping}[http://yaml.org/spec/1.1/#mapping]. + # + # A Psych::Nodes::Mapping node may have 0 or more children, but must have + # an even number of children. Here are the valid children a + # Psych::Nodes::Mapping node may have: + # + # * Psych::Nodes::Sequence + # * Psych::Nodes::Mapping + # * Psych::Nodes::Scalar + # * Psych::Nodes::Alias + class Mapping < Psych::Nodes::Node + # Any Map Style + ANY = 0 + + # Block Map Style + BLOCK = 1 + + # Flow Map Style + FLOW = 2 + + # The optional anchor for this mapping + attr_accessor :anchor + + # The optional tag for this mapping + attr_accessor :tag + + # Is this an implicit mapping? + attr_accessor :implicit + + # The style of this mapping + attr_accessor :style + + ### + # Create a new Psych::Nodes::Mapping object. + # + # +anchor+ is the anchor associated with the map or +nil+. + # +tag+ is the tag associated with the map or +nil+. + # +implicit+ is a boolean indicating whether or not the map was implicitly + # started. + # +style+ is an integer indicating the mapping style. + # + # == See Also + # See also Psych::Handler#start_mapping + def initialize anchor = nil, tag = nil, implicit = true, style = BLOCK + super() + @anchor = anchor + @tag = tag + @implicit = implicit + @style = style + end + end + end +end diff --git a/lib/19/psych/nodes/node.rb b/lib/19/psych/nodes/node.rb new file mode 100644 index 0000000000..3ab9acae43 --- /dev/null +++ b/lib/19/psych/nodes/node.rb @@ -0,0 +1,42 @@ +require 'stringio' + +module Psych + module Nodes + ### + # The base class for any Node in a YAML parse tree. This class should + # never be instantiated. + class Node + # The children of this node + attr_reader :children + + # An associated tag + attr_reader :tag + + # Create a new Psych::Nodes::Node + def initialize + @children = [] + end + + ### + # Convert this node to Ruby. + # + # See also Psych::Visitors::ToRuby + def to_ruby + Visitors::ToRuby.new.accept self + end + alias :transform :to_ruby + + ### + # Convert this node to YAML. + # + # See also Psych::Visitors::Emitter + def to_yaml io = nil + real_io = io || StringIO.new + + Visitors::Emitter.new(real_io).accept self + return real_io.string unless io + io + end + end + end +end diff --git a/lib/19/psych/nodes/scalar.rb b/lib/19/psych/nodes/scalar.rb new file mode 100644 index 0000000000..1b1b25b98a --- /dev/null +++ b/lib/19/psych/nodes/scalar.rb @@ -0,0 +1,67 @@ +module Psych + module Nodes + ### + # This class represents a {YAML Scalar}[http://yaml.org/spec/1.1/#id858081]. + # + # This node type is a terminal node and should not have any children. + class Scalar < Psych::Nodes::Node + # Any style scalar, the emitter chooses + ANY = 0 + + # Plain scalar style + PLAIN = 1 + + # Single quoted style + SINGLE_QUOTED = 2 + + # Double quoted style + DOUBLE_QUOTED = 3 + + # Literal style + LITERAL = 4 + + # Folded style + FOLDED = 5 + + # The scalar value + attr_accessor :value + + # The anchor value (if there is one) + attr_accessor :anchor + + # The tag value (if there is one) + attr_accessor :tag + + # Is this a plain scalar? + attr_accessor :plain + + # Is this scalar quoted? + attr_accessor :quoted + + # The style of this scalar + attr_accessor :style + + ### + # Create a new Psych::Nodes::Scalar object. + # + # +value+ is the string value of the scalar + # +anchor+ is an associated anchor or nil + # +tag+ is an associated tag or nil + # +plain+ is a boolean value + # +quoted+ is a boolean value + # +style+ is an integer idicating the string style + # + # == See Also + # + # See also Psych::Handler#scalar + def initialize value, anchor = nil, tag = nil, plain = true, quoted = false, style = ANY + @value = value + @anchor = anchor + @tag = tag + @plain = plain + @quoted = quoted + @style = style + end + end + end +end diff --git a/lib/19/psych/nodes/sequence.rb b/lib/19/psych/nodes/sequence.rb new file mode 100644 index 0000000000..e4b833d330 --- /dev/null +++ b/lib/19/psych/nodes/sequence.rb @@ -0,0 +1,81 @@ +module Psych + module Nodes + ### + # This class represents a + # {YAML sequence}[http://yaml.org/spec/1.1/#sequence/syntax]. + # + # A YAML sequence is basically a list, and looks like this: + # + # %YAML 1.1 + # --- + # - I am + # - a Sequence + # + # A YAML sequence may have an anchor like this: + # + # %YAML 1.1 + # --- + # &A [ + # "This sequence", + # "has an anchor" + # ] + # + # A YAML sequence may also have a tag like this: + # + # %YAML 1.1 + # --- + # !!seq [ + # "This sequence", + # "has a tag" + # ] + # + # This class represents a sequence in a YAML document. A + # Psych::Nodes::Sequence node may have 0 or more children. Valid children + # for this node are: + # + # * Psych::Nodes::Sequence + # * Psych::Nodes::Mapping + # * Psych::Nodes::Scalar + # * Psych::Nodes::Alias + class Sequence < Psych::Nodes::Node + # Any Styles, emitter chooses + ANY = 0 + + # Block style sequence + BLOCK = 1 + + # Flow style sequence + FLOW = 2 + + # The anchor for this sequence (if any) + attr_accessor :anchor + + # The tag name for this sequence (if any) + attr_accessor :tag + + # Is this sequence started implicitly? + attr_accessor :implicit + + # The sequece style used + attr_accessor :style + + ### + # Create a new object representing a YAML sequence. + # + # +anchor+ is the anchor associated with the sequence or nil. + # +tag+ is the tag associated with the sequence or nil. + # +implicit+ a boolean indicating whether or not the sequence was + # implicitly started. + # +style+ is an integer indicating the list style. + # + # See Psych::Handler#start_sequence + def initialize anchor = nil, tag = nil, implicit = true, style = BLOCK + super() + @anchor = anchor + @tag = tag + @implicit = implicit + @style = style + end + end + end +end diff --git a/lib/19/psych/nodes/stream.rb b/lib/19/psych/nodes/stream.rb new file mode 100644 index 0000000000..f4aab5a7dc --- /dev/null +++ b/lib/19/psych/nodes/stream.rb @@ -0,0 +1,37 @@ +module Psych + module Nodes + ### + # Represents a YAML stream. This is the root node for any YAML parse + # tree. This node must have one or more child nodes. The only valid + # child node for a Psych::Nodes::Stream node is Psych::Nodes::Document. + class Stream < Psych::Nodes::Node + + # Encodings supported by Psych (and libyaml) + + # Any encoding + ANY = Psych::Parser::ANY + + # UTF-8 encoding + UTF8 = Psych::Parser::UTF8 + + # UTF-16LE encoding + UTF16LE = Psych::Parser::UTF16LE + + # UTF-16BE encoding + UTF16BE = Psych::Parser::UTF16BE + + # The encoding used for this stream + attr_reader :encoding + + ### + # Create a new Psych::Nodes::Stream node with an +encoding+ that + # defaults to Psych::Nodes::Stream::UTF8. + # + # See also Psych::Handler#start_stream + def initialize encoding = UTF8 + super() + @encoding = encoding + end + end + end +end diff --git a/lib/19/psych/omap.rb b/lib/19/psych/omap.rb new file mode 100644 index 0000000000..6286270616 --- /dev/null +++ b/lib/19/psych/omap.rb @@ -0,0 +1,4 @@ +module Psych + class Omap < ::Hash + end +end diff --git a/lib/19/psych/parser.rb b/lib/19/psych/parser.rb new file mode 100644 index 0000000000..0e38a4ae7d --- /dev/null +++ b/lib/19/psych/parser.rb @@ -0,0 +1,44 @@ +module Psych + ### + # YAML event parser class. This class parses a YAML document and calls + # events on the handler that is passed to the constructor. The events can + # be used for things such as constructing a YAML AST or deserializing YAML + # documents. It can even be fed back to Psych::Emitter to emit the same + # document that was parsed. + # + # See Psych::Handler for documentation on the events that Psych::Parser emits. + # + # Here is an example that prints out ever scalar found in a YAML document: + # + # # Handler for detecting scalar values + # class ScalarHandler < Psych::Handler + # def scalar value, anchor, tag, plain, quoted, style + # puts value + # end + # end + # + # parser = Psych::Parser.new(ScalarHandler.new) + # parser.parse(yaml_document) + # + # Here is an example that feeds the parser back in to Psych::Emitter. The + # YAML document is read from STDIN and written back out to STDERR: + # + # parser = Psych::Parser.new(Psych::Emitter.new($stderr)) + # parser.parse($stdin) + # + # Psych uses Psych::Parser in combination with Psych::TreeBuilder to + # construct an AST of the parsed YAML document. + + class Parser + # The handler on which events will be called + attr_accessor :handler + + ### + # Creates a new Psych::Parser instance with +handler+. YAML events will + # be called on +handler+. See Psych::Parser for more details. + + def initialize handler = Handler.new + @handler = handler + end + end +end diff --git a/lib/19/psych/scalar_scanner.rb b/lib/19/psych/scalar_scanner.rb new file mode 100644 index 0000000000..f7aaea7435 --- /dev/null +++ b/lib/19/psych/scalar_scanner.rb @@ -0,0 +1,105 @@ +require 'strscan' + +module Psych + ### + # Scan scalars for built in types + class ScalarScanner + # Taken from http://yaml.org/type/timestamp.html + TIME = /^\d{4}-\d{1,2}-\d{1,2}([Tt]|\s+)\d{1,2}:\d\d:\d\d(\.\d*)?(\s*Z|[-+]\d{1,2}(:\d\d)?)?/ + + # Create a new scanner + def initialize + @string_cache = {} + end + + # Tokenize +string+ returning the ruby object + def tokenize string + return nil if string.empty? + return string if @string_cache.key?(string) + + case string + when /^[A-Za-z~]/ + if string.length > 5 + @string_cache[string] = true + return string + end + + case string + when /^[^ytonf~]/i + @string_cache[string] = true + string + when '~', /^null$/i + nil + when /^(yes|true|on)$/i + true + when /^(no|false|off)$/i + false + else + @string_cache[string] = true + string + end + when TIME + parse_time string + when /^\d{4}-\d{1,2}-\d{1,2}$/ + require 'date' + Date.strptime(string, '%Y-%m-%d') + when /^\.inf$/i + 1 / 0.0 + when /^-\.inf$/i + -1 / 0.0 + when /^\.nan$/i + 0.0 / 0.0 + when /^:./ + if string =~ /^:(["'])(.*)\1/ + $2.sub(/^:/, '').to_sym + else + string.sub(/^:/, '').to_sym + end + when /^[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+$/ + i = 0 + string.split(':').each_with_index do |n,e| + i += (n.to_i * 60 ** (e - 2).abs) + end + i + when /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*$/ + i = 0 + string.split(':').each_with_index do |n,e| + i += (n.to_f * 60 ** (e - 2).abs) + end + i + else + return Integer(string.gsub(/[,_]/, '')) rescue ArgumentError + return Float(string.gsub(/[,_]/, '')) rescue ArgumentError + @string_cache[string] = true + string + end + end + + ### + # Parse and return a Time from +string+ + def parse_time string + date, time = *(string.split(/[ tT]/, 2)) + (yy, m, dd) = date.split('-').map { |x| x.to_i } + md = time.match(/(\d+:\d+:\d+)(\.\d*)?\s*(Z|[-+]\d+(:\d\d)?)?/) + + (hh, mm, ss) = md[1].split(':').map { |x| x.to_i } + us = (md[2] ? Rational(md[2].sub(/^\./, '0.')) : 0) * 1000000 + + time = Time.utc(yy, m, dd, hh, mm, ss, us) + + return time if 'Z' == md[3] + return Time.at(time.to_i, us) unless md[3] + + tz = md[3].match(/^([+\-]?\d{1,2})\:?(\d{1,2})?$/)[1..-1].compact.map { |digit| Integer(digit, 10) } + offset = tz.first * 3600 + + if offset < 0 + offset -= ((tz[1] || 0) * 60) + else + offset += ((tz[1] || 0) * 60) + end + + Time.at((time - offset).to_i, us) + end + end +end diff --git a/lib/19/psych/set.rb b/lib/19/psych/set.rb new file mode 100644 index 0000000000..6793a8ed1b --- /dev/null +++ b/lib/19/psych/set.rb @@ -0,0 +1,4 @@ +module Psych + class Set < ::Hash + end +end diff --git a/lib/19/psych/tree_builder.rb b/lib/19/psych/tree_builder.rb new file mode 100644 index 0000000000..54d87a0b61 --- /dev/null +++ b/lib/19/psych/tree_builder.rb @@ -0,0 +1,94 @@ +require 'psych/handler' + +module Psych + ### + # This class works in conjunction with Psych::Parser to build an in-memory + # parse tree that represents a YAML document. + # + # == Example + # + # parser = Psych::Parser.new Psych::TreeBuilder.new + # parser.parse('--- foo') + # tree = parser.handler.root + # + # See Psych::Handler for documentation on the event methods used in this + # class. + class TreeBuilder < Psych::Handler + # Returns the root node for the built tree + attr_reader :root + + # Create a new TreeBuilder instance + def initialize + @stack = [] + @last = nil + @root = nil + end + + %w{ + Sequence + Mapping + }.each do |node| + class_eval %{ + def start_#{node.downcase}(anchor, tag, implicit, style) + n = Nodes::#{node}.new(anchor, tag, implicit, style) + @last.children << n + push n + end + + def end_#{node.downcase} + pop + end + } + end + + ### + # Handles start_document events with +version+, +tag_directives+, + # and +implicit+ styling. + # + # See Psych::Handler#start_document + def start_document version, tag_directives, implicit + n = Nodes::Document.new version, tag_directives, implicit + @last.children << n + push n + end + + ### + # Handles end_document events with +version+, +tag_directives+, + # and +implicit+ styling. + # + # See Psych::Handler#start_document + def end_document implicit_end + @last.implicit_end = implicit_end + pop + end + + def start_stream encoding + @root = Nodes::Stream.new(encoding) + push @root + end + + def end_stream + pop + end + + def scalar value, anchor, tag, plain, quoted, style + @last.children << Nodes::Scalar.new(value,anchor,tag,plain,quoted,style) + end + + def alias anchor + @last.children << Nodes::Alias.new(anchor) + end + + private + def push value + @stack.push value + @last = value + end + + def pop + x = @stack.pop + @last = @stack.last + x + end + end +end diff --git a/lib/19/psych/visitors.rb b/lib/19/psych/visitors.rb new file mode 100644 index 0000000000..10ac4ce270 --- /dev/null +++ b/lib/19/psych/visitors.rb @@ -0,0 +1,5 @@ +require 'psych/visitors/visitor' +require 'psych/visitors/to_ruby' +require 'psych/visitors/emitter' +require 'psych/visitors/yaml_tree' +require 'psych/visitors/json_tree' diff --git a/lib/19/psych/visitors/emitter.rb b/lib/19/psych/visitors/emitter.rb new file mode 100644 index 0000000000..0768fbb528 --- /dev/null +++ b/lib/19/psych/visitors/emitter.rb @@ -0,0 +1,41 @@ +module Psych + module Visitors + class Emitter < Psych::Visitors::Visitor + def initialize io + @handler = Psych::Emitter.new io + end + + def visit_Psych_Nodes_Stream o + @handler.start_stream o.encoding + o.children.each { |c| accept c } + @handler.end_stream + end + + def visit_Psych_Nodes_Document o + @handler.start_document o.version, o.tag_directives, o.implicit + o.children.each { |c| accept c } + @handler.end_document o.implicit_end + end + + def visit_Psych_Nodes_Scalar o + @handler.scalar o.value, o.anchor, o.tag, o.plain, o.quoted, o.style + end + + def visit_Psych_Nodes_Sequence o + @handler.start_sequence o.anchor, o.tag, o.implicit, o.style + o.children.each { |c| accept c } + @handler.end_sequence + end + + def visit_Psych_Nodes_Mapping o + @handler.start_mapping o.anchor, o.tag, o.implicit, o.style + o.children.each { |c| accept c } + @handler.end_mapping + end + + def visit_Psych_Nodes_Alias o + @handler.alias o.anchor + end + end + end +end diff --git a/lib/19/psych/visitors/json_tree.rb b/lib/19/psych/visitors/json_tree.rb new file mode 100644 index 0000000000..dcb5ddccae --- /dev/null +++ b/lib/19/psych/visitors/json_tree.rb @@ -0,0 +1,29 @@ +module Psych + module Visitors + class JSONTree < YAMLTree + def initialize options = {}, emitter = Psych::JSON::TreeBuilder.new + super + end + + def visit_NilClass o + @emitter.scalar 'null', nil, nil, true, false, Nodes::Scalar::PLAIN + end + + def visit_Integer o + @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::PLAIN + end + + def visit_Float o + return super if o.nan? || o.infinite? + visit_Integer o + end + + def visit_String o + @emitter.scalar o.to_s, nil, nil, false, true, Nodes::Scalar::DOUBLE_QUOTED + end + alias :visit_Symbol :visit_String + + private + end + end +end diff --git a/lib/19/psych/visitors/to_ruby.rb b/lib/19/psych/visitors/to_ruby.rb new file mode 100644 index 0000000000..a68c8e698e --- /dev/null +++ b/lib/19/psych/visitors/to_ruby.rb @@ -0,0 +1,269 @@ +require 'psych/scalar_scanner' + +module Psych + module Visitors + ### + # This class walks a YAML AST, converting each node to ruby + class ToRuby < Psych::Visitors::Visitor + def initialize + super + @st = {} + @ss = ScalarScanner.new + @domain_types = Psych.domain_types + end + + def accept target + result = super + return result if @domain_types.empty? || !target.tag + + key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:') + key = "tag:#{key}" unless key =~ /^(tag:|x-private)/ + + if @domain_types.key? key + value, block = @domain_types[key] + return block.call value, result + end + + result + end + + def visit_Psych_Nodes_Scalar o + @st[o.anchor] = o.value if o.anchor + + if klass = Psych.load_tags[o.tag] + instance = klass.allocate + + if instance.respond_to?(:init_with) + coder = Psych::Coder.new(o.tag) + coder.scalar = o.value + instance.init_with coder + end + + return instance + end + + return o.value if o.quoted + return @ss.tokenize(o.value) unless o.tag + + case o.tag + when '!binary', 'tag:yaml.org,2002:binary' + o.value.unpack('m').first + when '!str', 'tag:yaml.org,2002:str' + o.value + when "!ruby/object:DateTime" + require 'date' + @ss.parse_time(o.value).to_datetime + when "!ruby/object:Complex" + Complex(o.value) + when "!ruby/object:Rational" + Rational(o.value) + when "tag:yaml.org,2002:float", "!float" + Float(@ss.tokenize(o.value)) + when "!ruby/regexp" + o.value =~ /^\/(.*)\/([mixn]*)$/ + source = $1 + options = 0 + lang = nil + ($2 || '').split('').each do |option| + case option + when 'x' then options |= Regexp::EXTENDED + when 'i' then options |= Regexp::IGNORECASE + when 'm' then options |= Regexp::MULTILINE + + # FIXME: there is no constant for ARG_ENCODING_NONE + when 'n' then options |= 32 + else lang = option + end + end + Regexp.new(*[source, options, lang].compact) + when "!ruby/range" + args = o.value.split(/([.]{2,3})/, 2).map { |s| + accept Nodes::Scalar.new(s) + } + args.push(args.delete_at(1) == '...') + Range.new(*args) + when /^!ruby\/sym(bol)?:?(.*)?$/ + o.value.to_sym + else + @ss.tokenize o.value + end + end + + def visit_Psych_Nodes_Sequence o + if klass = Psych.load_tags[o.tag] + instance = klass.allocate + + if instance.respond_to?(:init_with) + coder = Psych::Coder.new(o.tag) + coder.seq = o.children.map { |c| accept c } + instance.init_with coder + end + + return instance + end + + case o.tag + when '!omap', 'tag:yaml.org,2002:omap' + map = Psych::Omap.new + @st[o.anchor] = map if o.anchor + o.children.each { |a| + map[accept(a.children.first)] = accept a.children.last + } + map + else + list = [] + @st[o.anchor] = list if o.anchor + o.children.each { |c| list.push accept c } + list + end + end + + def visit_Psych_Nodes_Mapping o + return revive(Psych.load_tags[o.tag], o) if Psych.load_tags[o.tag] + + case o.tag + when '!str', 'tag:yaml.org,2002:str' + members = Hash[*o.children.map { |c| accept c }] + string = members.delete 'str' + init_with(string, members.map { |k,v| [k.to_s.sub(/^@/, ''),v] }, o) + when /^!ruby\/struct:?(.*)?$/ + klass = resolve_class($1) + + if klass + s = klass.allocate + @st[o.anchor] = s if o.anchor + + members = {} + struct_members = s.members.map { |x| x.to_sym } + o.children.each_slice(2) do |k,v| + member = accept(k) + value = accept(v) + if struct_members.include?(member.to_sym) + s.send("#{member}=", value) + else + members[member.to_s.sub(/^@/, '')] = value + end + end + init_with(s, members, o) + else + members = o.children.map { |c| accept c } + h = Hash[*members] + Struct.new(*h.map { |k,v| k.to_sym }).new(*h.map { |k,v| v }) + end + + when '!ruby/range' + h = Hash[*o.children.map { |c| accept c }] + Range.new(h['begin'], h['end'], h['excl']) + + when /^!ruby\/exception:?(.*)?$/ + h = Hash[*o.children.map { |c| accept c }] + + e = build_exception((resolve_class($1) || Exception), + h.delete('message')) + init_with(e, h, o) + + when '!set', 'tag:yaml.org,2002:set' + set = Psych::Set.new + @st[o.anchor] = set if o.anchor + o.children.each_slice(2) do |k,v| + set[accept(k)] = accept(v) + end + set + + when '!ruby/object:Complex' + h = Hash[*o.children.map { |c| accept c }] + Complex(h['real'], h['image']) + + when '!ruby/object:Rational' + h = Hash[*o.children.map { |c| accept c }] + Rational(h['numerator'], h['denominator']) + + when /^!ruby\/object:?(.*)?$/ + name = $1 || 'Object' + obj = revive((resolve_class(name) || Object), o) + @st[o.anchor] = obj if o.anchor + obj + else + hash = {} + @st[o.anchor] = hash if o.anchor + + o.children.each_slice(2) { |k,v| + key = accept(k) + + if key == '<<' + case v + when Nodes::Alias + hash.merge! accept(v) + when Nodes::Sequence + accept(v).reverse_each do |value| + hash.merge! value + end + else + hash[key] = accept(v) + end + else + hash[key] = accept(v) + end + + } + hash + end + end + + def visit_Psych_Nodes_Document o + accept o.root + end + + def visit_Psych_Nodes_Stream o + o.children.map { |c| accept c } + end + + def visit_Psych_Nodes_Alias o + @st[o.anchor] + end + + private + def revive klass, node + s = klass.allocate + h = Hash[*node.children.map { |c| accept c }] + init_with(s, h, node) + end + + def init_with o, h, node + c = Psych::Coder.new(node.tag) + c.map = h + + if o.respond_to?(:init_with) + o.init_with c + elsif o.respond_to?(:yaml_initialize) + if $VERBOSE + "Implementing #{o.class}#yaml_initialize is deprecated, please implement \"init_with(coder)\"" + end + o.yaml_initialize c.tag, c.map + else + h.each { |k,v| o.instance_variable_set(:"@#{k}", v) } + end + o + end + + # Convert +klassname+ to a Class + def resolve_class klassname + return nil unless klassname and not klassname.empty? + + name = klassname + retried = false + + begin + path2class(name) + rescue ArgumentError, NameError => ex + unless retried + name = "Struct::#{name}" + retried = ex + retry + end + raise retried + end + end + end + end +end diff --git a/lib/19/psych/visitors/visitor.rb b/lib/19/psych/visitors/visitor.rb new file mode 100644 index 0000000000..ccd8c3bd55 --- /dev/null +++ b/lib/19/psych/visitors/visitor.rb @@ -0,0 +1,18 @@ +module Psych + module Visitors + class Visitor + def accept target + case target + when Psych::Nodes::Scalar then visit_Psych_Nodes_Scalar target + when Psych::Nodes::Mapping then visit_Psych_Nodes_Mapping target + when Psych::Nodes::Sequence then visit_Psych_Nodes_Sequence target + when Psych::Nodes::Alias then visit_Psych_Nodes_Alias target + when Psych::Nodes::Document then visit_Psych_Nodes_Document target + when Psych::Nodes::Stream then visit_Psych_Nodes_Stream target + else + raise "Can't handle #{target}" + end + end + end + end +end diff --git a/lib/19/psych/visitors/yaml_tree.rb b/lib/19/psych/visitors/yaml_tree.rb new file mode 100644 index 0000000000..271bac5a23 --- /dev/null +++ b/lib/19/psych/visitors/yaml_tree.rb @@ -0,0 +1,330 @@ +module Psych + module Visitors + ### + # YAMLTree builds a YAML ast given a ruby object. For example: + # + # builder = Psych::Visitors::YAMLTree.new + # builder << { :foo => 'bar' } + # builder.tree # => # true) + end + end + end + + if target.respond_to?(:encode_with) + dump_coder target + else + send(@dispatch_cache[target.class], target) + end + end + + def visit_Psych_Omap o + seq = @emitter.start_sequence(nil, '!omap', false, Nodes::Sequence::BLOCK) + register(o, seq) + + o.each { |k,v| visit_Hash k => v } + @emitter.end_sequence + end + + def visit_Object o + tag = Psych.dump_tags[o.class] + unless tag + klass = o.class == Object ? nil : o.class.name + tag = ['!ruby/object', klass].compact.join(':') + end + + map = @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) + register(o, map) + + dump_ivars o + @emitter.end_mapping + end + + def visit_Struct o + tag = ['!ruby/struct', o.class.name].compact.join(':') + + register o, @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) + o.members.each do |member| + @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY + accept o[member] + end + + dump_ivars o + + @emitter.end_mapping + end + + def visit_Exception o + tag = ['!ruby/exception', o.class.name].join ':' + + @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK + + { + 'message' => private_iv_get(o, 'mesg'), + 'backtrace' => private_iv_get(o, 'backtrace'), + }.each do |k,v| + next unless v + @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY + accept v + end + + dump_ivars o + + @emitter.end_mapping + end + + def visit_Regexp o + @emitter.scalar o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY + end + + def visit_DateTime o + formatted = format_time o.to_time + tag = '!ruby/object:DateTime' + @emitter.scalar formatted, nil, tag, false, false, Nodes::Scalar::ANY + end + + def visit_Time o + formatted = format_time o + @emitter.scalar formatted, nil, nil, true, false, Nodes::Scalar::ANY + end + + def visit_Rational o + @emitter.start_mapping(nil, '!ruby/object:Rational', false, Nodes::Mapping::BLOCK) + + [ + 'denominator', o.denominator.to_s, + 'numerator', o.numerator.to_s + ].each do |m| + @emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY + end + + @emitter.end_mapping + end + + def visit_Complex o + @emitter.start_mapping(nil, '!ruby/object:Complex', false, Nodes::Mapping::BLOCK) + + ['real', o.real.to_s, 'image', o.imag.to_s].each do |m| + @emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY + end + + @emitter.end_mapping + end + + def visit_Integer o + @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY + end + alias :visit_TrueClass :visit_Integer + alias :visit_FalseClass :visit_Integer + alias :visit_Date :visit_Integer + + def visit_Float o + if o.nan? + @emitter.scalar '.nan', nil, nil, true, false, Nodes::Scalar::ANY + elsif o.infinite? + @emitter.scalar((o.infinite? > 0 ? '.inf' : '-.inf'), + nil, nil, true, false, Nodes::Scalar::ANY) + else + @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY + end + end + + def visit_String o + plain = false + quote = false + style = Nodes::Scalar::ANY + + if o.index("\x00") || o.count("\x00-\x7F", "^ -~\t\r\n").fdiv(o.length) > 0.3 + str = [o].pack('m').chomp + tag = '!binary' # FIXME: change to below when syck is removed + #tag = 'tag:yaml.org,2002:binary' + style = Nodes::Scalar::LITERAL + else + str = o + tag = nil + quote = !(String === @ss.tokenize(o)) + plain = !quote + end + + ivars = find_ivars o + + if ivars.empty? + @emitter.scalar str, nil, tag, plain, quote, style + else + @emitter.start_mapping nil, '!str', false, Nodes::Mapping::BLOCK + @emitter.scalar 'str', nil, nil, true, false, Nodes::Scalar::ANY + @emitter.scalar str, nil, tag, plain, quote, style + + dump_ivars o + + @emitter.end_mapping + end + end + + def visit_Class o + raise TypeError, "can't dump anonymous class #{o.class}" + end + + def visit_Range o + @emitter.start_mapping nil, '!ruby/range', false, Nodes::Mapping::BLOCK + ['begin', o.begin, 'end', o.end, 'excl', o.exclude_end?].each do |m| + accept m + end + @emitter.end_mapping + end + + def visit_Hash o + register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK)) + + o.each do |k,v| + accept k + accept v + end + + @emitter.end_mapping + end + + def visit_Psych_Set o + register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK)) + + o.each do |k,v| + accept k + accept v + end + + @emitter.end_mapping + end + + def visit_Array o + register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK) + o.each { |c| accept c } + @emitter.end_sequence + end + + def visit_NilClass o + @emitter.scalar('', nil, 'tag:yaml.org,2002:null', false, false, Nodes::Scalar::ANY) + end + + def visit_Symbol o + @emitter.scalar ":#{o}", nil, nil, true, false, Nodes::Scalar::ANY + end + + private + def format_time time + formatted = time.strftime("%Y-%m-%d %H:%M:%S.%9N") + if time.utc? + formatted += "Z" + else + zone = time.strftime('%z') + formatted += " #{zone[0,3]}:#{zone[3,5]}" + end + formatted + end + + # FIXME: remove this method once "to_yaml_properties" is removed + def find_ivars target + loc = target.method(:to_yaml_properties).source_location.first + unless loc.start_with?(Psych::DEPRECATED) || loc.end_with?('rubytypes.rb') + if $VERBOSE + warn "#{loc}: to_yaml_properties is deprecated, please implement \"encode_with(coder)\"" + end + return target.to_yaml_properties + end + + target.instance_variables + end + + def register target, yaml_obj + @st[target.object_id] = yaml_obj + yaml_obj + end + + def dump_coder o + tag = Psych.dump_tags[o.class] + unless tag + klass = o.class == Object ? nil : o.class.name + tag = ['!ruby/object', klass].compact.join(':') + end + + c = Psych::Coder.new(tag) + o.encode_with(c) + emit_coder c + end + + def emit_coder c + case c.type + when :scalar + @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, Nodes::Scalar::ANY + when :seq + @emitter.start_sequence nil, c.tag, c.tag.nil?, Nodes::Sequence::BLOCK + c.seq.each do |thing| + accept thing + end + @emitter.end_sequence + when :map + @emitter.start_mapping nil, c.tag, c.implicit, c.style + c.map.each do |k,v| + @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY + accept v + end + @emitter.end_mapping + end + end + + def dump_ivars target + ivars = find_ivars target + + ivars.each do |iv| + @emitter.scalar("#{iv.to_s.sub(/^@/, '')}", nil, nil, true, false, Nodes::Scalar::ANY) + accept target.instance_variable_get(iv) + end + end + end + end +end From c07dd00f19b21784c459d04c3068b85cd1108401 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Wed, 9 Nov 2011 14:08:04 -0800 Subject: [PATCH 07/67] Build Psych if libyaml is available. --- Rakefile | 2 +- configure | 10 ++++++++-- lib/19/psych/.gitignore | 2 ++ rakelib/extensions.rake | 4 ++++ 4 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 lib/19/psych/.gitignore diff --git a/Rakefile b/Rakefile index b4783ae12b..f0104e62fe 100644 --- a/Rakefile +++ b/Rakefile @@ -33,7 +33,7 @@ end require config_rb BUILD_CONFIG = Rubinius::BUILD_CONFIG -unless BUILD_CONFIG[:config_version] == 140 +unless BUILD_CONFIG[:config_version] == 141 STDERR.puts "Your configuration is outdated, please run ./configure first" exit 1 end diff --git a/configure b/configure index 4fa277b057..ddf5afedf7 100755 --- a/configure +++ b/configure @@ -109,12 +109,13 @@ class Configure # Library configuration @rb_readline = false @vendor_zlib = false + @libyaml = false # Essential settings (modify these for creating releases) @libversion = "2.0" @version = "#{@libversion}.0dev" @release_date = "yyyy-mm-dd" - @config_version = 140 + @config_version = 141 # TODO: add conditionals for platforms if RbConfig::CONFIG["build_os"] =~ /darwin/ @@ -862,6 +863,10 @@ int main() { return tgetnum(""); } @rb_readline = true end + if has_function("yaml_parser_initialize", ["yaml.h"]) + @libyaml = true + end + @vendor_zlib = true if @features["vendor-zlib"] end @@ -996,7 +1001,8 @@ module Rubinius :version_list => #{@version_list.inspect}, :default_version => "#{@default_version}", :vendor_zlib => #{@vendor_zlib}, - :readline => :#{@rb_readline ? :rb_readline : :c_readline} + :readline => :#{@rb_readline ? :rb_readline : :c_readline}, + :libyaml => #{@libyaml} } end EOC diff --git a/lib/19/psych/.gitignore b/lib/19/psych/.gitignore new file mode 100644 index 0000000000..5df646e1b9 --- /dev/null +++ b/lib/19/psych/.gitignore @@ -0,0 +1,2 @@ +ext/mkmf.log +ext/Makefile diff --git a/rakelib/extensions.rake b/rakelib/extensions.rake index 7ddda2aea2..cebab05e6a 100644 --- a/rakelib/extensions.rake +++ b/rakelib/extensions.rake @@ -131,6 +131,10 @@ if BUILD_CONFIG[:readline] == :c_readline :env => "-X19" end +if BUILD_CONFIG[:libyaml] + compile_ext "psych", :deps => ["Makefile"], :dir => "lib/19/psych/ext" +end + # rbx must be able to run to build these because they use # extconf.rb, so they must be after melbourne for Rubinius. compile_ext "openssl", :deps => ["Makefile", "extconf.h"] From 75668919aa0e387dba582e75e4f9b94e8956264d Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Wed, 9 Nov 2011 15:22:06 -0800 Subject: [PATCH 08/67] Moved syck/ to lib/18. Rather than dealing with the mess that is YAML/Syck/Psyck on 1.9 in some "cross-lib campatible" fashion, I'm just putting existing Syck in 1.8 lib and adding Syck from 1.9 to 1.9 lib. --- Rakefile | 2 +- configure | 2 +- lib/{ => 18}/syck/ext/Rakefile | 0 lib/{ => 18}/syck/ext/bytecode.c | 0 lib/{ => 18}/syck/ext/depend | 0 lib/{ => 18}/syck/ext/emitter.c | 0 lib/{ => 18}/syck/ext/extconf.rb | 0 lib/{ => 18}/syck/ext/gram.c | 0 lib/{ => 18}/syck/ext/gram.h | 0 lib/{ => 18}/syck/ext/handler.c | 0 lib/{ => 18}/syck/ext/implicit.c | 0 lib/{ => 18}/syck/ext/node.c | 0 lib/{ => 18}/syck/ext/rubyext.c | 0 lib/{ => 18}/syck/ext/st.c | 0 lib/{ => 18}/syck/ext/st.h | 0 lib/{ => 18}/syck/ext/syck.c | 0 lib/{ => 18}/syck/ext/syck.h | 0 lib/{ => 18}/syck/ext/token.c | 0 lib/{ => 18}/syck/ext/yaml2byte.c | 0 lib/{ => 18}/syck/ext/yamlbyte.h | 0 rakelib/extensions.rake | 2 +- 21 files changed, 3 insertions(+), 3 deletions(-) rename lib/{ => 18}/syck/ext/Rakefile (100%) rename lib/{ => 18}/syck/ext/bytecode.c (100%) rename lib/{ => 18}/syck/ext/depend (100%) rename lib/{ => 18}/syck/ext/emitter.c (100%) rename lib/{ => 18}/syck/ext/extconf.rb (100%) rename lib/{ => 18}/syck/ext/gram.c (100%) rename lib/{ => 18}/syck/ext/gram.h (100%) rename lib/{ => 18}/syck/ext/handler.c (100%) rename lib/{ => 18}/syck/ext/implicit.c (100%) rename lib/{ => 18}/syck/ext/node.c (100%) rename lib/{ => 18}/syck/ext/rubyext.c (100%) rename lib/{ => 18}/syck/ext/st.c (100%) rename lib/{ => 18}/syck/ext/st.h (100%) rename lib/{ => 18}/syck/ext/syck.c (100%) rename lib/{ => 18}/syck/ext/syck.h (100%) rename lib/{ => 18}/syck/ext/token.c (100%) rename lib/{ => 18}/syck/ext/yaml2byte.c (100%) rename lib/{ => 18}/syck/ext/yamlbyte.h (100%) diff --git a/Rakefile b/Rakefile index f0104e62fe..7e4a57b169 100644 --- a/Rakefile +++ b/Rakefile @@ -33,7 +33,7 @@ end require config_rb BUILD_CONFIG = Rubinius::BUILD_CONFIG -unless BUILD_CONFIG[:config_version] == 141 +unless BUILD_CONFIG[:config_version] == 142 STDERR.puts "Your configuration is outdated, please run ./configure first" exit 1 end diff --git a/configure b/configure index ddf5afedf7..740cd32979 100755 --- a/configure +++ b/configure @@ -115,7 +115,7 @@ class Configure @libversion = "2.0" @version = "#{@libversion}.0dev" @release_date = "yyyy-mm-dd" - @config_version = 141 + @config_version = 142 # TODO: add conditionals for platforms if RbConfig::CONFIG["build_os"] =~ /darwin/ diff --git a/lib/syck/ext/Rakefile b/lib/18/syck/ext/Rakefile similarity index 100% rename from lib/syck/ext/Rakefile rename to lib/18/syck/ext/Rakefile diff --git a/lib/syck/ext/bytecode.c b/lib/18/syck/ext/bytecode.c similarity index 100% rename from lib/syck/ext/bytecode.c rename to lib/18/syck/ext/bytecode.c diff --git a/lib/syck/ext/depend b/lib/18/syck/ext/depend similarity index 100% rename from lib/syck/ext/depend rename to lib/18/syck/ext/depend diff --git a/lib/syck/ext/emitter.c b/lib/18/syck/ext/emitter.c similarity index 100% rename from lib/syck/ext/emitter.c rename to lib/18/syck/ext/emitter.c diff --git a/lib/syck/ext/extconf.rb b/lib/18/syck/ext/extconf.rb similarity index 100% rename from lib/syck/ext/extconf.rb rename to lib/18/syck/ext/extconf.rb diff --git a/lib/syck/ext/gram.c b/lib/18/syck/ext/gram.c similarity index 100% rename from lib/syck/ext/gram.c rename to lib/18/syck/ext/gram.c diff --git a/lib/syck/ext/gram.h b/lib/18/syck/ext/gram.h similarity index 100% rename from lib/syck/ext/gram.h rename to lib/18/syck/ext/gram.h diff --git a/lib/syck/ext/handler.c b/lib/18/syck/ext/handler.c similarity index 100% rename from lib/syck/ext/handler.c rename to lib/18/syck/ext/handler.c diff --git a/lib/syck/ext/implicit.c b/lib/18/syck/ext/implicit.c similarity index 100% rename from lib/syck/ext/implicit.c rename to lib/18/syck/ext/implicit.c diff --git a/lib/syck/ext/node.c b/lib/18/syck/ext/node.c similarity index 100% rename from lib/syck/ext/node.c rename to lib/18/syck/ext/node.c diff --git a/lib/syck/ext/rubyext.c b/lib/18/syck/ext/rubyext.c similarity index 100% rename from lib/syck/ext/rubyext.c rename to lib/18/syck/ext/rubyext.c diff --git a/lib/syck/ext/st.c b/lib/18/syck/ext/st.c similarity index 100% rename from lib/syck/ext/st.c rename to lib/18/syck/ext/st.c diff --git a/lib/syck/ext/st.h b/lib/18/syck/ext/st.h similarity index 100% rename from lib/syck/ext/st.h rename to lib/18/syck/ext/st.h diff --git a/lib/syck/ext/syck.c b/lib/18/syck/ext/syck.c similarity index 100% rename from lib/syck/ext/syck.c rename to lib/18/syck/ext/syck.c diff --git a/lib/syck/ext/syck.h b/lib/18/syck/ext/syck.h similarity index 100% rename from lib/syck/ext/syck.h rename to lib/18/syck/ext/syck.h diff --git a/lib/syck/ext/token.c b/lib/18/syck/ext/token.c similarity index 100% rename from lib/syck/ext/token.c rename to lib/18/syck/ext/token.c diff --git a/lib/syck/ext/yaml2byte.c b/lib/18/syck/ext/yaml2byte.c similarity index 100% rename from lib/syck/ext/yaml2byte.c rename to lib/18/syck/ext/yaml2byte.c diff --git a/lib/syck/ext/yamlbyte.h b/lib/18/syck/ext/yamlbyte.h similarity index 100% rename from lib/syck/ext/yamlbyte.h rename to lib/18/syck/ext/yamlbyte.h diff --git a/rakelib/extensions.rake b/rakelib/extensions.rake index cebab05e6a..fe4a7634d8 100644 --- a/rakelib/extensions.rake +++ b/rakelib/extensions.rake @@ -119,7 +119,7 @@ compile_ext "digest:rmd160" compile_ext "digest:sha1" compile_ext "digest:sha2" compile_ext "digest:bubblebabble" -compile_ext "syck", :dir => "lib/syck/ext" +compile_ext "syck", :dir => "lib/18/syck/ext" compile_ext "melbourne", :task => "rbx", :doc => "for Rubinius" compile_ext "melbourne", :task => "build", :doc => "for bootstrapping" compile_ext "nkf" From 55f41fefd4f3864addac756410791be3b819b2e2 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Wed, 9 Nov 2011 16:39:52 -0800 Subject: [PATCH 09/67] Added syck/ from 1.9.2p290. --- lib/19/syck.rb | 447 ++++++ lib/19/syck/.gitignore | 2 + lib/19/syck/baseemitter.rb | 242 +++ lib/19/syck/basenode.rb | 223 +++ lib/19/syck/constants.rb | 45 + lib/19/syck/encoding.rb | 35 + lib/19/syck/error.rb | 34 + lib/19/syck/ext/Makefile | 181 +++ lib/19/syck/ext/bytecode.c | 1165 ++++++++++++++ lib/19/syck/ext/emitter.c | 1247 +++++++++++++++ lib/19/syck/ext/extconf.rb | 5 + lib/19/syck/ext/gram.c | 1894 ++++++++++++++++++++++ lib/19/syck/ext/gram.h | 79 + lib/19/syck/ext/handler.c | 173 ++ lib/19/syck/ext/implicit.c | 2990 +++++++++++++++++++++++++++++++++++ lib/19/syck/ext/mkmf.log | 15 + lib/19/syck/ext/node.c | 407 +++++ lib/19/syck/ext/rubyext.c | 2324 +++++++++++++++++++++++++++ lib/19/syck/ext/syck.c | 524 ++++++ lib/19/syck/ext/syck.h | 453 ++++++ lib/19/syck/ext/token.c | 2724 +++++++++++++++++++++++++++++++ lib/19/syck/ext/yaml2byte.c | 259 +++ lib/19/syck/ext/yamlbyte.h | 171 ++ lib/19/syck/loader.rb | 14 + lib/19/syck/rubytypes.rb | 465 ++++++ lib/19/syck/stream.rb | 41 + lib/19/syck/stringio.rb | 85 + lib/19/syck/syck.rb | 16 + lib/19/syck/tag.rb | 95 ++ lib/19/syck/types.rb | 192 +++ lib/19/syck/yamlnode.rb | 54 + lib/19/syck/ypath.rb | 54 + lib/19/yaml/syck.rb | 14 + rakelib/extensions.rake | 6 +- 34 files changed, 16674 insertions(+), 1 deletion(-) create mode 100644 lib/19/syck.rb create mode 100644 lib/19/syck/.gitignore create mode 100644 lib/19/syck/baseemitter.rb create mode 100644 lib/19/syck/basenode.rb create mode 100644 lib/19/syck/constants.rb create mode 100644 lib/19/syck/encoding.rb create mode 100644 lib/19/syck/error.rb create mode 100644 lib/19/syck/ext/Makefile create mode 100644 lib/19/syck/ext/bytecode.c create mode 100644 lib/19/syck/ext/emitter.c create mode 100644 lib/19/syck/ext/extconf.rb create mode 100644 lib/19/syck/ext/gram.c create mode 100644 lib/19/syck/ext/gram.h create mode 100644 lib/19/syck/ext/handler.c create mode 100644 lib/19/syck/ext/implicit.c create mode 100644 lib/19/syck/ext/mkmf.log create mode 100644 lib/19/syck/ext/node.c create mode 100644 lib/19/syck/ext/rubyext.c create mode 100644 lib/19/syck/ext/syck.c create mode 100644 lib/19/syck/ext/syck.h create mode 100644 lib/19/syck/ext/token.c create mode 100644 lib/19/syck/ext/yaml2byte.c create mode 100644 lib/19/syck/ext/yamlbyte.h create mode 100644 lib/19/syck/loader.rb create mode 100644 lib/19/syck/rubytypes.rb create mode 100644 lib/19/syck/stream.rb create mode 100644 lib/19/syck/stringio.rb create mode 100644 lib/19/syck/syck.rb create mode 100644 lib/19/syck/tag.rb create mode 100644 lib/19/syck/types.rb create mode 100644 lib/19/syck/yamlnode.rb create mode 100644 lib/19/syck/ypath.rb create mode 100644 lib/19/yaml/syck.rb diff --git a/lib/19/syck.rb b/lib/19/syck.rb new file mode 100644 index 0000000000..c6efdf96f5 --- /dev/null +++ b/lib/19/syck.rb @@ -0,0 +1,447 @@ +# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4 +# $Id: syck.rb 27334 2010-04-14 02:37:54Z nobu $ +# +# = yaml.rb: top-level module with methods for loading and parsing YAML documents +# +# Author:: why the lucky stiff +# + +require 'yaml/syck' + +# == YAML +# +# YAML(tm) (rhymes with 'camel') is a +# straightforward machine parsable data serialization format designed for +# human readability and interaction with scripting languages such as Perl +# and Python. YAML is optimized for data serialization, formatted +# dumping, configuration files, log files, Internet messaging and +# filtering. This specification describes the YAML information model and +# serialization format. Together with the Unicode standard for characters, it +# provides all the information necessary to understand YAML Version 1.0 +# and construct computer programs to process it. +# +# See http://yaml.org/ for more information. For a quick tutorial, please +# visit YAML In Five Minutes (http://yaml.kwiki.org/?YamlInFiveMinutes). +# +# == About This Library +# +# The YAML 1.0 specification outlines four stages of YAML loading and dumping. +# This library honors all four of those stages, although data is really only +# available to you in three stages. +# +# The four stages are: native, representation, serialization, and presentation. +# +# The native stage refers to data which has been loaded completely into Ruby's +# own types. (See +YAML::load+.) +# +# The representation stage means data which has been composed into +# +YAML::BaseNode+ objects. In this stage, the document is available as a +# tree of node objects. You can perform YPath queries and transformations +# at this level. (See +YAML::parse+.) +# +# The serialization stage happens inside the parser. The YAML parser used in +# Ruby is called Syck. Serialized nodes are available in the extension as +# SyckNode structs. +# +# The presentation stage is the YAML document itself. This is accessible +# to you as a string. (See +YAML::dump+.) +# +# For more information about the various information models, see Chapter +# 3 of the YAML 1.0 Specification (http://yaml.org/spec/#id2491269). +# +# The YAML module provides quick access to the most common loading (YAML::load) +# and dumping (YAML::dump) tasks. This module also provides an API for registering +# global types (YAML::add_domain_type). +# +# == Example +# +# A simple round-trip (load and dump) of an object. +# +# require "yaml" +# +# test_obj = ["dogs", "cats", "badgers"] +# +# yaml_obj = YAML::dump( test_obj ) +# # -> --- +# - dogs +# - cats +# - badgers +# ruby_obj = YAML::load( yaml_obj ) +# # => ["dogs", "cats", "badgers"] +# ruby_obj == test_obj +# # => true +# +# To register your custom types with the global resolver, use +add_domain_type+. +# +# YAML::add_domain_type( "your-site.com,2004", "widget" ) do |type, val| +# Widget.new( val ) +# end +# +module Syck + + DefaultResolver.use_types_at( @@tagged_classes ) + + # Returns a new default parser + def self.parser; Parser.new.set_resolver( self.resolver ); end + + # Returns a new generic parser + def self.generic_parser + warn "#{caller[0]}: YAML.generic_parser is deprecated, switch to psych" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + Parser.new.set_resolver( GenericResolver ) + end + + # Returns the default resolver + def self.resolver + warn "#{caller[0]}: YAML.resolver is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + DefaultResolver + end + + # Returns a new default emitter + def self.emitter + warn "#{caller[0]}: YAML.emitter is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + Emitter.new.set_resolver( self.resolver ) + end + + # + # Converts _obj_ to YAML and writes the YAML result to _io_. + # + # File.open( 'animals.yaml', 'w' ) do |out| + # YAML.dump( ['badger', 'elephant', 'tiger'], out ) + # end + # + # If no _io_ is provided, a string containing the dumped YAML + # is returned. + # + # YAML.dump( :locked ) + # #=> "--- :locked" + # + def self.dump( obj, io = nil ) + obj.to_yaml( io || io2 = StringIO.new ) + io || ( io2.rewind; io2.read ) + end + + # + # Load a document from the current _io_ stream. + # + # File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) } + # #=> ['badger', 'elephant', 'tiger'] + # + # Can also load from a string. + # + # YAML.load( "--- :locked" ) + # #=> :locked + # + def self.load( io ) + yp = parser.load( io ) + end + + # + # Load a document from the file located at _filepath_. + # + # YAML.load_file( 'animals.yaml' ) + # #=> ['badger', 'elephant', 'tiger'] + # + def self.load_file( filepath ) + File.open( filepath ) do |f| + load( f ) + end + end + + # + # Parse the first document from the current _io_ stream + # + # File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) } + # #=> #, + # #, + # #]> + # + # Can also load from a string. + # + # YAML.parse( "--- :locked" ) + # #=> # + # + def self.parse( io ) + yp = generic_parser.load( io ) + end + + # + # Parse a document from the file located at _filepath_. + # + # YAML.parse_file( 'animals.yaml' ) + # #=> #, + # #, + # #]> + # + def self.parse_file( filepath ) + File.open( filepath ) do |f| + parse( f ) + end + end + + # + # Calls _block_ with each consecutive document in the YAML + # stream contained in _io_. + # + # File.open( 'many-docs.yaml' ) do |yf| + # YAML.each_document( yf ) do |ydoc| + # ## ydoc contains the single object + # ## from the YAML document + # end + # end + # + def self.each_document( io, &block ) + warn "#{caller[0]}: YAML.each_document is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + yp = parser.load_documents( io, &block ) + end + + # + # Calls _block_ with each consecutive document in the YAML + # stream contained in _io_. + # + # File.open( 'many-docs.yaml' ) do |yf| + # YAML.load_documents( yf ) do |ydoc| + # ## ydoc contains the single object + # ## from the YAML document + # end + # end + # + def self.load_documents( io, &doc_proc ) + yp = parser.load_documents( io, &doc_proc ) + end + + # + # Calls _block_ with a tree of +YAML::BaseNodes+, one tree for + # each consecutive document in the YAML stream contained in _io_. + # + # File.open( 'many-docs.yaml' ) do |yf| + # YAML.each_node( yf ) do |ydoc| + # ## ydoc contains a tree of nodes + # ## from the YAML document + # end + # end + # + def self.each_node( io, &doc_proc ) + warn "#{caller[0]}: YAML.each_node is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + yp = generic_parser.load_documents( io, &doc_proc ) + end + + # + # Calls _block_ with a tree of +YAML::BaseNodes+, one tree for + # each consecutive document in the YAML stream contained in _io_. + # + # File.open( 'many-docs.yaml' ) do |yf| + # YAML.parse_documents( yf ) do |ydoc| + # ## ydoc contains a tree of nodes + # ## from the YAML document + # end + # end + # + def self.parse_documents( io, &doc_proc ) + warn "#{caller[0]}: YAML.parse_documents is deprecated, use load_stream" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + self.each_node( io, &doc_proc ) + end + + # + # Loads all documents from the current _io_ stream, + # returning a +YAML::Stream+ object containing all + # loaded documents. + # + def self.load_stream( io ) + d = nil + parser.load_documents( io ) do |doc| + d = Stream.new if not d + d.add( doc ) + end + return d + end + + # + # Returns a YAML stream containing each of the items in +objs+, + # each having their own document. + # + # YAML.dump_stream( 0, [], {} ) + # #=> --- 0 + # --- [] + # --- {} + # + def self.dump_stream( *objs ) + d = Stream.new + objs.each do |doc| + d.add( doc ) + end + d.emit + end + + # + # Add a global handler for a YAML domain type. + # + def self.add_domain_type( domain, type_tag, &transfer_proc ) + resolver.add_type( "tag:#{ domain }:#{ type_tag }", transfer_proc ) + end + + # + # Add a transfer method for a builtin type + # + def self.add_builtin_type( type_tag, &transfer_proc ) + resolver.add_type( "tag:yaml.org,2002:#{ type_tag }", transfer_proc ) + end + + # + # Add a transfer method for a builtin type + # + def self.add_ruby_type( type_tag, &transfer_proc ) + warn "#{caller[0]}: YAML.add_ruby_type is deprecated, use add_domain_type" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc ) + end + + # + # Add a private document type + # + def self.add_private_type( type_re, &transfer_proc ) + warn "#{caller[0]}: YAML.add_private_type is deprecated, use add_domain_type" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + resolver.add_type( "x-private:" + type_re, transfer_proc ) + end + + # + # Detect typing of a string + # + def self.detect_implicit( val ) + warn "#{caller[0]}: YAML.detect_implicit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + resolver.detect_implicit( val ) + end + + # + # Convert a type_id to a taguri + # + def self.tagurize( val ) + warn "#{caller[0]}: YAML.tagurize is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + resolver.tagurize( val ) + end + + # + # Apply a transfer method to a Ruby object + # + def self.transfer( type_id, obj ) + warn "#{caller[0]}: YAML.transfer is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + resolver.transfer( tagurize( type_id ), obj ) + end + + # + # Apply any implicit a node may qualify for + # + def self.try_implicit( obj ) + warn "#{caller[0]}: YAML.try_implicit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + transfer( detect_implicit( obj ), obj ) + end + + # + # Method to extract colon-seperated type and class, returning + # the type and the constant of the class + # + def self.read_type_class( type, obj_class ) + warn "#{caller[0]}: YAML.read_type_class is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + scheme, domain, type, tclass = type.split( ':', 4 ) + tclass.split( "::" ).each { |c| obj_class = obj_class.const_get( c ) } if tclass + return [ type, obj_class ] + end + + # + # Allocate blank object + # + def self.object_maker( obj_class, val ) + warn "#{caller[0]}: YAML.object_maker is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + if Hash === val + o = obj_class.allocate + val.each_pair { |k,v| + o.instance_variable_set("@#{k}", v) + } + o + else + raise Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect + end + end + + # + # Allocate an Emitter if needed + # + def self.quick_emit( oid, opts = {}, &e ) + warn "#{caller[0]}: YAML.quick_emit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__)) + out = + if opts.is_a? Emitter + opts + else + emitter.reset( opts ) + end + out.emit( oid, &e ) + end + +end + +module Kernel + # + # ryan:: You know how Kernel.p is a really convenient way to dump ruby + # structures? The only downside is that it's not as legible as + # YAML. + # + # _why:: (listening) + # + # ryan:: I know you don't want to urinate all over your users' namespaces. + # But, on the other hand, convenience of dumping for debugging is, + # IMO, a big YAML use case. + # + # _why:: Go nuts! Have a pony parade! + # + # ryan:: Either way, I certainly will have a pony parade. + # + + # Prints any supplied _objects_ out in YAML. Intended as + # a variation on +Kernel::p+. + # + # S = Struct.new(:name, :state) + # s = S['dave', 'TX'] + # y s + # + # _produces:_ + # + # --- !ruby/struct:S + # name: dave + # state: TX + # + def y( object, *objects ) + objects.unshift object + puts( if objects.length == 1 + YAML.dump( *objects ) + else + YAML.dump_stream( *objects ) + end ) + end + private :y +end + + diff --git a/lib/19/syck/.gitignore b/lib/19/syck/.gitignore new file mode 100644 index 0000000000..5df646e1b9 --- /dev/null +++ b/lib/19/syck/.gitignore @@ -0,0 +1,2 @@ +ext/mkmf.log +ext/Makefile diff --git a/lib/19/syck/baseemitter.rb b/lib/19/syck/baseemitter.rb new file mode 100644 index 0000000000..5e39e450de --- /dev/null +++ b/lib/19/syck/baseemitter.rb @@ -0,0 +1,242 @@ +# +# BaseEmitter +# + +require 'syck/constants' +require 'syck/encoding' +require 'syck/error' + +module Syck + module BaseEmitter + def options( opt = nil ) + if opt + @options[opt] || DEFAULTS[opt] + else + @options + end + end + + def options=( opt ) + @options = opt + end + + # + # Emit binary data + # + def binary_base64( value ) + self << "!binary " + self.node_text( [value].pack("m"), '|' ) + end + + # + # Emit plain, normal flowing text + # + def node_text( value, block = nil ) + @seq_map = false + valx = value.dup + unless block + block = + if options(:UseBlock) + '|' + elsif not options(:UseFold) and valx =~ /\n[ \t]/ and not valx =~ /#{ESCAPE_CHAR}/ + '|' + else + '>' + end + indt = $&.to_i if block =~ /\d+/ + if valx =~ /(\A\n*[ \t#]|^---\s+)/ + indt = options(:Indent) unless indt.to_i > 0 + block += indt.to_s + end + + block += + if valx =~ /\n\Z\n/ + "+" + elsif valx =~ /\Z\n/ + "" + else + "-" + end + end + block += "\n" + if block[0] == ?" + esc_skip = ( "\t\n" unless valx =~ /^[ \t]/ ) || "" + valx = fold( Syck.escape( valx, esc_skip ) + "\"" ).chomp + self << '"' + indent_text( valx, indt, false ) + else + if block[0] == ?> + valx = fold( valx ) + end + #p [block, indt] + self << block + indent_text( valx, indt ) + end + end + + # + # Emit a simple, unqouted string + # + def simple( value ) + @seq_map = false + self << value.to_s + end + + # + # Emit double-quoted string + # + def double( value ) + "\"#{Syck.escape( value )}\"" + end + + # + # Emit single-quoted string + # + def single( value ) + "'#{value}'" + end + + # + # Write a text block with the current indent + # + def indent_text( text, mod, first_line = true ) + return "" if text.to_s.empty? + spacing = indent( mod ) + text = text.gsub( /\A([^\n])/, "#{ spacing }\\1" ) if first_line + return text.gsub( /\n^([^\n])/, "\n#{spacing}\\1" ) + end + + # + # Write a current indent + # + def indent( mod = nil ) + #p [ self.id, level, mod, :INDENT ] + if level <= 0 + mod ||= 0 + else + mod ||= options(:Indent) + mod += ( level - 1 ) * options(:Indent) + end + return " " * mod + end + + # + # Add indent to the buffer + # + def indent! + self << indent + end + + # + # Folding paragraphs within a column + # + def fold( value ) + value.gsub( /(^[ \t]+.*$)|(\S.{0,#{options(:BestWidth) - 1}})(?:[ \t]+|(\n+(?=[ \t]|\Z))|$)/ ) do + $1 || $2 + ( $3 || "\n" ) + end + end + + # + # Quick mapping + # + def map( type, &e ) + val = Mapping.new + e.call( val ) + self << "#{type} " if type.length.nonzero? + + # + # Empty hashes + # + if val.length.zero? + self << "{}" + @seq_map = false + else + # FIXME + # if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero? + # @headless = 1 + # end + + defkey = @options.delete( :DefaultKey ) + if defkey + seq_map_shortcut + self << "= : " + defkey.to_yaml( :Emitter => self ) + end + + # + # Emit the key and value + # + val.each { |v| + seq_map_shortcut + if v[0].is_complex_yaml? + self << "? " + end + v[0].to_yaml( :Emitter => self ) + if v[0].is_complex_yaml? + self << "\n" + indent! + end + self << ": " + v[1].to_yaml( :Emitter => self ) + } + end + end + + def seq_map_shortcut + # FIXME: seq_map needs to work with the new anchoring system + # if @seq_map + # @anchor_extras[@buffer.length - 1] = "\n" + indent + # @seq_map = false + # else + self << "\n" + indent! + # end + end + + # + # Quick sequence + # + def seq( type, &e ) + @seq_map = false + val = Sequence.new + e.call( val ) + self << "#{type} " if type.length.nonzero? + + # + # Empty arrays + # + if val.length.zero? + self << "[]" + else + # FIXME + # if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero? + # @headless = 1 + # end + + # + # Emit the key and value + # + val.each { |v| + self << "\n" + indent! + self << "- " + @seq_map = true if v.class == Hash + v.to_yaml( :Emitter => self ) + } + end + end + end + + # + # Emitter helper classes + # + class Mapping < Array + def add( k, v ) + push [k, v] + end + end + + class Sequence < Array + def add( v ) + push v + end + end +end diff --git a/lib/19/syck/basenode.rb b/lib/19/syck/basenode.rb new file mode 100644 index 0000000000..3739331562 --- /dev/null +++ b/lib/19/syck/basenode.rb @@ -0,0 +1,223 @@ +# +# YAML::BaseNode class +# + +module Syck + + # + # YAML Generic Model container + # + module BaseNode + + # + # Search for YPath entry and return + # qualified nodes. + # + def select( ypath_str ) + warn "#{caller[0]}: select is deprecated" if $VERBOSE + matches = match_path( ypath_str ) + + # + # Create a new generic view of the elements selected + # + if matches + result = [] + matches.each { |m| + result.push m.last + } + Syck.transfer( 'seq', result ) + end + end + + # + # Search for YPath entry and return + # transformed nodes. + # + def select!( ypath_str ) + warn "#{caller[0]}: select!() is deprecated" if $VERBOSE + matches = match_path( ypath_str ) + + # + # Create a new generic view of the elements selected + # + if matches + result = [] + matches.each { |m| + result.push m.last.transform + } + result + end + end + + # + # Search for YPath entry and return a list of + # qualified paths. + # + def search( ypath_str ) + warn "#{caller[0]}: search() is deprecated" if $VERBOSE + matches = match_path( ypath_str ) + + if matches + matches.collect { |m| + path = [] + m.each_index { |i| + path.push m[i] if ( i % 2 ).zero? + } + "/" + path.compact.join( "/" ) + } + end + end + + def at( seg ) + warn "#{caller[0]}: at() is deprecated" if $VERBOSE + if Hash === @value + self[seg] + elsif Array === @value and seg =~ /\A\d+\Z/ and @value[seg.to_i] + @value[seg.to_i] + end + end + + # + # YPath search returning a complete depth array + # + def match_path( ypath_str ) + warn "#{caller[0]}: match_path is deprecated" if $VERBOSE + require 'syck/ypath' + depth = 0 + matches = [] + YPath.each_path( ypath_str ) do |ypath| + seg = match_segment( ypath, 0 ) + matches += seg if seg + end + matches.uniq + end + + # + # Search a node for a single YPath segment + # + def match_segment( ypath, depth ) + warn "#{caller[0]}: match_segment is deprecated" if $VERBOSE + deep_nodes = [] + seg = ypath.segments[ depth ] + if seg == "/" + unless String === @value + idx = -1 + @value.collect { |v| + idx += 1 + if Hash === @value + match_init = [v[0].transform, v[1]] + match_deep = v[1].match_segment( ypath, depth ) + else + match_init = [idx, v] + match_deep = v.match_segment( ypath, depth ) + end + if match_deep + match_deep.each { |m| + deep_nodes.push( match_init + m ) + } + end + } + end + depth += 1 + seg = ypath.segments[ depth ] + end + match_nodes = + case seg + when "." + [[nil, self]] + when ".." + [["..", nil]] + when "*" + if @value.is_a? Enumerable + idx = -1 + @value.collect { |h| + idx += 1 + if Hash === @value + [h[0].transform, h[1]] + else + [idx, h] + end + } + end + else + if seg =~ /^"(.*)"$/ + seg = $1 + elsif seg =~ /^'(.*)'$/ + seg = $1 + end + if ( v = at( seg ) ) + [[ seg, v ]] + end + end + return deep_nodes unless match_nodes + pred = ypath.predicates[ depth ] + if pred + case pred + when /^\.=/ + pred = $' # ' + match_nodes.reject! { |n| + n.last.value != pred + } + else + match_nodes.reject! { |n| + n.last.at( pred ).nil? + } + end + end + return match_nodes + deep_nodes unless ypath.segments.length > depth + 1 + + #puts "DEPTH: #{depth + 1}" + deep_nodes = [] + match_nodes.each { |n| + if n[1].is_a? BaseNode + match_deep = n[1].match_segment( ypath, depth + 1 ) + if match_deep + match_deep.each { |m| + deep_nodes.push( n + m ) + } + end + else + deep_nodes = [] + end + } + deep_nodes = nil if deep_nodes.length == 0 + deep_nodes + end + + # + # We want the node to act like as Hash + # if it is. + # + def []( *key ) + if Hash === @value + v = @value.detect { |k,| k.transform == key.first } + v[1] if v + elsif Array === @value + @value.[]( *key ) + end + end + + def children + if Hash === @value + @value.values.collect { |c| c[1] } + elsif Array === @value + @value + end + end + + def children_with_index + warn "#{caller[0]}: children_with_index is deprecated, use children" if $VERBOSE + if Hash === @value + @value.keys.collect { |i| [self[i], i] } + elsif Array === @value + i = -1; @value.collect { |v| i += 1; [v, i] } + end + end + + def emit + transform.to_yaml + end + end + +end + diff --git a/lib/19/syck/constants.rb b/lib/19/syck/constants.rb new file mode 100644 index 0000000000..19fe42ef85 --- /dev/null +++ b/lib/19/syck/constants.rb @@ -0,0 +1,45 @@ +# +# Constants used throughout the library +# +module Syck + + # + # Constants + # + VERSION = '0.60' + SUPPORTED_YAML_VERSIONS = ['1.0'] + + # + # Parser tokens + # + WORD_CHAR = 'A-Za-z0-9' + PRINTABLE_CHAR = '-_A-Za-z0-9!?/()$\'". ' + NOT_PLAIN_CHAR = '\x7f\x0-\x1f\x80-\x9f' + ESCAPE_CHAR = '[\\x00-\\x09\\x0b-\\x1f]' + INDICATOR_CHAR = '*&!|\\\\^@%{}[]=' + SPACE_INDICATORS = '-#:,?' + RESTRICTED_INDICATORS = '#:,}]' + DNS_COMP_RE = "\\w(?:[-\\w]*\\w)?" + DNS_NAME_RE = "(?:(?:#{DNS_COMP_RE}\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})" + ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a + \x08 \t \n \v \f \r \x0e \x0f + \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 + \x18 \x19 \x1a \e \x1c \x1d \x1e \x1f + } + UNESCAPES = { + 'a' => "\x07", 'b' => "\x08", 't' => "\x09", + 'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c", + 'r' => "\x0d", 'e' => "\x1b", '\\' => '\\', + } + + # + # Default settings + # + DEFAULTS = { + :Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0', + :SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false, + :WidthType => 'absolute', :BestWidth => 80, + :UseBlock => false, :UseFold => false, :Encoding => :None + } + +end diff --git a/lib/19/syck/encoding.rb b/lib/19/syck/encoding.rb new file mode 100644 index 0000000000..dad062994c --- /dev/null +++ b/lib/19/syck/encoding.rb @@ -0,0 +1,35 @@ +# +# Handle Unicode-to-Internal conversion +# + +module Syck + + # + # Escape the string, condensing common escapes + # + def self.escape( value, skip = "" ) + warn "#{caller[0]}: YAML.escape is deprecated" if $VERBOSE + value.gsub( /\\/, "\\\\\\" ). + gsub( /"/, "\\\"" ). + gsub( /([\x00-\x1f])/ ) do + skip[$&] || ESCAPES[ $&.unpack("C")[0] ] + end + end + + # + # Unescape the condenses escapes + # + def self.unescape( value ) + warn "#{caller[0]}: YAML.unescape is deprecated" if $VERBOSE + value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) { + if $3 + ["#$3".hex ].pack('U*') + elsif $2 + [$2].pack( "H2" ) + else + UNESCAPES[$1] + end + } + end + +end diff --git a/lib/19/syck/error.rb b/lib/19/syck/error.rb new file mode 100644 index 0000000000..0bac872411 --- /dev/null +++ b/lib/19/syck/error.rb @@ -0,0 +1,34 @@ +# +# Error messages and exception class +# + +module Syck + + # + # Error messages + # + + ERROR_NO_HEADER_NODE = "With UseHeader=false, the node Array or Hash must have elements" + ERROR_NEED_HEADER = "With UseHeader=false, the node must be an Array or Hash" + ERROR_BAD_EXPLICIT = "Unsupported explicit transfer: '%s'" + ERROR_MANY_EXPLICIT = "More than one explicit transfer" + ERROR_MANY_IMPLICIT = "More than one implicit request" + ERROR_NO_ANCHOR = "No anchor for alias '%s'" + ERROR_BAD_ANCHOR = "Invalid anchor: %s" + ERROR_MANY_ANCHOR = "More than one anchor" + ERROR_ANCHOR_ALIAS = "Can't define both an anchor and an alias" + ERROR_BAD_ALIAS = "Invalid alias: %s" + ERROR_MANY_ALIAS = "More than one alias" + ERROR_ZERO_INDENT = "Can't use zero as an indentation width" + ERROR_UNSUPPORTED_VERSION = "This release of YAML.rb does not support YAML version %s" + ERROR_UNSUPPORTED_ENCODING = "Attempt to use unsupported encoding: %s" + + # + # YAML Error classes + # + + class Error < StandardError; end + class ParseError < Error; end + class TypeError < StandardError; end + +end diff --git a/lib/19/syck/ext/Makefile b/lib/19/syck/ext/Makefile new file mode 100644 index 0000000000..c768a8fa4b --- /dev/null +++ b/lib/19/syck/ext/Makefile @@ -0,0 +1,181 @@ + +SHELL = /bin/sh + +#### Start of system configuration section. #### + +srcdir = . +topdir = /source/rubinius/rubinius/vm/capi/19/include +hdrdir = /source/rubinius/rubinius/vm/capi/19/include +arch_hdrdir = /source/rubinius/rubinius/vm/capi/19/include +VPATH = $(srcdir):$(hdrdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/source/rubinius/rubinius +install_prefix = $(DESTDIR) +exec_prefix = $(prefix) +bindir = $(DESTDIR)/source/rubinius/rubinius/bin +sbindir = $(exec_prefix)/sbin +libexecdir = $(exec_prefix)/libexec +datarootdir = $(prefix)/share +datadir = $(datarootdir) +sysconfdir = $(prefix)/etc +sharedstatedir = $(prefix)/com +localstatedir = $(prefix)/var +includedir = $(prefix)/include +oldincludedir = $(DESTDIR)/usr/include +docdir = $(datarootdir)/doc/$(PACKAGE) +infodir = $(datarootdir)/info +htmldir = $(docdir) +dvidir = $(docdir) +pdfdir = $(docdir) +psdir = $(docdir) +libdir = $(exec_prefix)/lib +localedir = $(datarootdir)/locale +mandir = $(datarootdir)/man +rubyhdrdir = $(DESTDIR)/source/rubinius/rubinius/vm/capi/19/include +sitedir = $(DESTDIR)/source/rubinius/rubinius/lib/site +sitelibdir = $(DESTDIR)/source/rubinius/rubinius/lib/site +rubylibdir = $(DESTDIR)/source/rubinius/rubinius/lib/site +archdir = $(DESTDIR)/source/rubinius/rubinius/lib/site/x86_64-darwin10.8.0 +sitearchdir = $(DESTDIR)/source/rubinius/rubinius/lib/site/x86_64-darwin10.8.0 + +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = +LIBRUBYARG_SHARED = +LIBRUBYARG_STATIC = +OUTFLAG = -o +COUTFLAG = -o + +RUBY_EXTCONF_H = +cflags = +optflags = +debugflags = +warnflags = +CFLAGS = -fPIC -ggdb3 -fPIC -O2 +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = +CXXFLAGS = $(CFLAGS) +ldflags = +dldflags = +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) +LDSHARED = gcc -bundle -undefined suppress -flat_namespace +LDSHAREDXX = $(LDSHARED) +AR = ar +EXEEXT = + +RUBY_BASE_NAME = +RUBY_INSTALL_NAME = rbx +RUBY_SO_NAME = rubinius-2.0.0dev +arch = x86_64-darwin10.8.0 +sitearch = x86_64-darwin10.8.0 +ruby_version = 1.9 +ruby = /source/rubinius/rubinius/bin/rbx +RUBY = $(ruby) +RM = rm -f +RM_RF = $(RUBY) -run -e rm -- -rf +RMDIRS = $(RUBY) -run -e rmdir -- -p +MAKEDIRS = mkdir -p +INSTALL = install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp + +#### End of system configuration section. #### + +preload = + +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_STATIC) +SRCS = bytecode.c emitter.c gram.c handler.c implicit.c node.c rubyext.c syck.c token.c yaml2byte.c +OBJS = bytecode.o emitter.o gram.o handler.o implicit.o node.o rubyext.o syck.o token.o yaml2byte.o +TARGET = syck +DLLIB = $(TARGET).bundle +EXTSTATIC = +STATIC_LIB = + +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(rubyhdrdir)/ruby$(target_prefix) +ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix) + +TARGET_SO = $(DLLIB) +CLEANLIBS = $(TARGET).bundle +CLEANOBJS = *.o *.bak + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-rb + +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-rb-default clean-rb + @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean: clean distclean-so distclean-rb-default distclean-rb + @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + @-$(RMDIRS) $(DISTCLEANDIRS) + +realclean: distclean +install: install-so install-rb + +install-so: $(RUBYARCHDIR) +install-so: $(RUBYARCHDIR)/$(DLLIB) +$(RUBYARCHDIR)/$(DLLIB): $(DLLIB) + @-$(MAKEDIRS) $(@D) + $(INSTALL_PROG) $(DLLIB) $(@D) +install-rb: pre-install-rb install-rb-default +install-rb-default: pre-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +$(RUBYARCHDIR): + $(MAKEDIRS) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .cxx .cpp .C .o + +.cc.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.cxx.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.cpp.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.C.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.c.o: + $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $< + +$(DLLIB): $(OBJS) Makefile + @-$(RM) $(@) + $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + + + +$(OBJS): $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/config.h diff --git a/lib/19/syck/ext/bytecode.c b/lib/19/syck/ext/bytecode.c new file mode 100644 index 0000000000..dd75ed6f90 --- /dev/null +++ b/lib/19/syck/ext/bytecode.c @@ -0,0 +1,1165 @@ +/* Generated by re2c 0.9.10 on Mon Sep 19 23:21:26 2005 */ +#line 1 "bytecode.re" +/* + * bytecode.re + * + * $Author: nobu $ + * + * Copyright (C) 2003 why the lucky stiff + */ +#include "ruby/ruby.h" +#include "syck.h" +#include "gram.h" + +#define QUOTELEN 128 + +/* + * They do my bidding... + */ +#define YYCTYPE char +#define YYCURSOR parser->cursor +#define YYMARKER parser->marker +#define YYLIMIT parser->limit +#define YYTOKEN parser->token +#define YYTOKTMP parser->toktmp +#define YYLINEPTR parser->lineptr +#define YYLINECTPTR parser->linectptr +#define YYLINE parser->linect +#define YYFILL(n) syck_parser_read(parser) + +extern SyckParser *syck_parser_ptr; + +char *get_inline( SyckParser *parser ); + +/* + * Repositions the cursor at `n' offset from the token start. + * Only works in `Header' and `Document' sections. + */ +#define YYPOS(n) YYCURSOR = YYTOKEN + n + +/* + * Track line numbers + */ +#define CHK_NL(ptr) if ( *( ptr - 1 ) == '\n' && ptr > YYLINECTPTR ) { YYLINEPTR = ptr; YYLINE++; YYLINECTPTR = YYLINEPTR; } + +/* + * I like seeing the level operations as macros... + */ +#define ADD_LEVEL(len, status) syck_parser_add_level( parser, len, status ) +#define POP_LEVEL() syck_parser_pop_level( parser ) +#define CURRENT_LEVEL() syck_parser_current_level( parser ) + +/* + * Force a token next time around sycklex() + */ +#define FORCE_NEXT_TOKEN(tok) parser->force_token = tok; + +/* + * Adding levels in bytecode requires us to make sure + * we've got all our tokens worked out. + */ +#define ADD_BYTE_LEVEL(lvl, len, s ) \ + switch ( lvl->status ) \ + { \ + case syck_lvl_seq: \ + lvl->ncount++; \ + ADD_LEVEL(len, syck_lvl_open); \ + YYPOS(0); \ + return '-'; \ + \ + case syck_lvl_map: \ + lvl->ncount++; \ + ADD_LEVEL(len, s); \ + break; \ + \ + case syck_lvl_open: \ + lvl->status = s; \ + break; \ + \ + default: \ + ADD_LEVEL(len, s); \ + break; \ + } + +/* + * Nice little macro to ensure we're YAML_IOPENed to the current level. + * * Only use this macro in the "Document" section * + */ +#define ENSURE_YAML_IOPEN(last_lvl, lvl_type, to_len, reset) \ + if ( last_lvl->spaces < to_len ) \ + { \ + if ( last_lvl->status == syck_lvl_iseq || last_lvl->status == syck_lvl_imap ) \ + { \ + goto Document; \ + } \ + else \ + { \ + ADD_LEVEL( to_len, lvl_type ); \ + if ( reset == 1 ) YYPOS(0); \ + return YAML_IOPEN; \ + } \ + } + +/* + * Nice little macro to ensure closure of levels. + * * Only use this macro in the "Document" section * + */ +#define ENSURE_YAML_IEND(last_lvl, to_len) \ + if ( last_lvl->spaces > to_len ) \ + { \ + syck_parser_pop_level( parser ); \ + YYPOS(0); \ + return YAML_IEND; \ + } + +/* + * Concatenates string items and manages allocation + * to the string + */ +#define CAT(s, c, i, l) \ + { \ + if ( i + 1 >= c ) \ + { \ + c += QUOTELEN; \ + S_REALLOC_N( s, char, c ); \ + } \ + s[i++] = l; \ + s[i] = '\0'; \ + } + +/* + * Parser for standard YAML Bytecode [UTF-8] + */ +int +sycklex_bytecode_utf8( YYSTYPE *sycklval, SyckParser *parser ) +{ + SyckLevel *lvl; + syck_parser_ptr = parser; + if ( YYCURSOR == NULL ) + { + syck_parser_read( parser ); + } + + if ( parser->force_token != 0 ) + { + int t = parser->force_token; + parser->force_token = 0; + return t; + } + +#line 172 "bytecode.re" + + + lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_doc ) + { + goto Document; + } + +/* Header: */ + + YYTOKEN = YYCURSOR; + + +#line 165 "" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + goto yy0; + ++YYCURSOR; +yy0: + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy2; + case 'D': goto yy3; + default: goto yy5; + } +yy2: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy4; + } +yy3: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy6; + case 0x0D: goto yy8; + default: goto yy4; + } +yy4: +#line 199 "bytecode.re" +{ YYPOS(0); + goto Document; + } +#line 195 "" +yy5: yych = *++YYCURSOR; + goto yy4; +yy6: ++YYCURSOR; + goto yy7; +yy7: +#line 186 "bytecode.re" +{ if ( lvl->status == syck_lvl_header ) + { + CHK_NL(YYCURSOR); + goto Directive; + } + else + { + ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } + } +#line 214 "" +yy8: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy6; + default: goto yy2; + } +} +#line 203 "bytecode.re" + + +Document: + { + lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_header ) + { + lvl->status = syck_lvl_doc; + } + + YYTOKEN = YYCURSOR; + + +#line 235 "" +{ + YYCTYPE yych; + goto yy9; + ++YYCURSOR; +yy9: + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy30; + case 0x0A: goto yy27; + case 0x0D: goto yy29; + case 'A': goto yy19; + case 'D': goto yy12; + case 'E': goto yy16; + case 'M': goto yy14; + case 'P': goto yy13; + case 'Q': goto yy15; + case 'R': goto yy21; + case 'S': goto yy17; + case 'T': goto yy23; + case 'c': goto yy25; + default: goto yy11; + } +yy11:yy12: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy41; + case 0x0D: goto yy44; + default: goto yy11; + } +yy13: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy41; + case 0x0D: goto yy43; + default: goto yy11; + } +yy14: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy38; + case 0x0D: goto yy40; + default: goto yy11; + } +yy15: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy35; + case 0x0D: goto yy37; + default: goto yy11; + } +yy16: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy32; + case 0x0D: goto yy34; + default: goto yy11; + } +yy17: ++YYCURSOR; + goto yy18; +yy18: +#line 288 "bytecode.re" +{ ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_str); + goto Scalar; + } +#line 296 "" +yy19: ++YYCURSOR; + goto yy20; +yy20: +#line 292 "bytecode.re" +{ ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_open); + sycklval->name = get_inline( parser ); + syck_hdlr_remove_anchor( parser, sycklval->name ); + CHK_NL(YYCURSOR); + return YAML_ANCHOR; + } +#line 307 "" +yy21: ++YYCURSOR; + goto yy22; +yy22: +#line 299 "bytecode.re" +{ ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_str); + sycklval->name = get_inline( parser ); + POP_LEVEL(); + if ( *( YYCURSOR - 1 ) == '\n' ) YYCURSOR--; + return YAML_ALIAS; + } +#line 318 "" +yy23: ++YYCURSOR; + goto yy24; +yy24: +#line 306 "bytecode.re" +{ char *qstr; + ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_open); + qstr = get_inline( parser ); + CHK_NL(YYCURSOR); + if ( qstr[0] == '!' ) + { + int qidx = strlen( qstr ); + if ( qstr[1] == '\0' ) + { + free( qstr ); + return YAML_ITRANSFER; + } + + lvl = CURRENT_LEVEL(); + + /* + * URL Prefixing + */ + if ( qstr[1] == '^' ) + { + sycklval->name = S_ALLOC_N( char, qidx + strlen( lvl->domain ) ); + sycklval->name[0] = '\0'; + strcat( sycklval->name, lvl->domain ); + strncat( sycklval->name, qstr + 2, qidx - 2 ); + free( qstr ); + } + else + { + char *carat = qstr + 1; + char *qend = qstr + qidx; + while ( (++carat) < qend ) + { + if ( *carat == '^' ) + break; + } + + if ( carat < qend ) + { + free( lvl->domain ); + lvl->domain = syck_strndup( qstr + 1, carat - ( qstr + 1 ) ); + sycklval->name = S_ALLOC_N( char, ( qend - carat ) + strlen( lvl->domain ) ); + sycklval->name[0] = '\0'; + strcat( sycklval->name, lvl->domain ); + strncat( sycklval->name, carat + 1, ( qend - carat ) - 1 ); + free( qstr ); + } + else + { + sycklval->name = S_ALLOC_N( char, strlen( qstr ) ); + sycklval->name[0] = '\0'; + S_MEMCPY( sycklval->name, qstr + 1, char, strlen( qstr ) ); + free( qstr ); + } + } + return YAML_TRANSFER; + } + sycklval->name = qstr; + return YAML_TAGURI; + } +#line 382 "" +yy25: ++YYCURSOR; + goto yy26; +yy26: +#line 366 "bytecode.re" +{ goto Comment; } +#line 388 "" +yy27: ++YYCURSOR; + goto yy28; +yy28: +#line 368 "bytecode.re" +{ CHK_NL(YYCURSOR); + if ( lvl->status == syck_lvl_seq ) + { + return YAML_INDENT; + } + else if ( lvl->status == syck_lvl_map ) + { + if ( lvl->ncount % 2 == 1 ) return ':'; + else return YAML_INDENT; + } + goto Document; + } +#line 405 "" +yy29: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy27; + default: goto yy11; + } +yy30: ++YYCURSOR; + goto yy31; +yy31: +#line 381 "bytecode.re" +{ ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } +#line 419 "" +yy32: ++YYCURSOR; + goto yy33; +yy33: +#line 252 "bytecode.re" +{ if ( lvl->status == syck_lvl_seq && lvl->ncount == 0 ) + { + lvl->ncount++; + YYPOS(0); + FORCE_NEXT_TOKEN( ']' ); + return '['; + } + else if ( lvl->status == syck_lvl_map && lvl->ncount == 0 ) + { + lvl->ncount++; + YYPOS(0); + FORCE_NEXT_TOKEN( '}' ); + return '{'; + } + + POP_LEVEL(); + lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_seq ) + { + FORCE_NEXT_TOKEN(YAML_INDENT); + } + else if ( lvl->status == syck_lvl_map ) + { + if ( lvl->ncount % 2 == 1 ) + { + FORCE_NEXT_TOKEN(':'); + } + else + { + FORCE_NEXT_TOKEN(YAML_INDENT); + } + } + CHK_NL(YYCURSOR); + return YAML_IEND; + } +#line 459 "" +yy34: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy32; + default: goto yy11; + } +yy35: ++YYCURSOR; + goto yy36; +yy36: +#line 237 "bytecode.re" +{ int complex = 0; + if ( lvl->ncount % 2 == 0 && ( lvl->status == syck_lvl_map || lvl->status == syck_lvl_seq ) ) + { + complex = 1; + } + ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_seq); + CHK_NL(YYCURSOR); + if ( complex ) + { + FORCE_NEXT_TOKEN( YAML_IOPEN ); + return '?'; + } + return YAML_IOPEN; + } +#line 483 "" +yy37: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy35; + default: goto yy11; + } +yy38: ++YYCURSOR; + goto yy39; +yy39: +#line 222 "bytecode.re" +{ int complex = 0; + if ( lvl->ncount % 2 == 0 && ( lvl->status == syck_lvl_map || lvl->status == syck_lvl_seq ) ) + { + complex = 1; + } + ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_map); + CHK_NL(YYCURSOR); + if ( complex ) + { + FORCE_NEXT_TOKEN( YAML_IOPEN ); + return '?'; + } + return YAML_IOPEN; + } +#line 507 "" +yy40: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy38; + default: goto yy11; + } +yy41: ++YYCURSOR; + goto yy42; +yy42: +#line 217 "bytecode.re" +{ ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } +#line 521 "" +yy43: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy41; + default: goto yy11; + } +yy44: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy41; + default: goto yy11; + } +} +#line 386 "bytecode.re" + + + } + +Directive: + { + YYTOKEN = YYCURSOR; + + +#line 543 "" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + goto yy45; + ++YYCURSOR; +yy45: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy47; + case 'V': goto yy48; + default: goto yy50; + } +yy47: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy49; + } +yy48: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy51; + default: goto yy49; + } +yy49: +#line 399 "bytecode.re" +{ YYCURSOR = YYTOKEN; + return YAML_DOCSEP; + } +#line 646 "" +yy50: yych = *++YYCURSOR; + goto yy49; +yy51: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy52; +yy52: switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy51; + case ':': goto yy53; + default: goto yy47; + } +yy53: yych = *++YYCURSOR; + switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy54; + default: goto yy47; + } +yy54: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy55; +yy55: switch(yych){ + case 0x0A: goto yy56; + case 0x0D: goto yy58; + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy54; + default: goto yy47; + } +yy56: ++YYCURSOR; + goto yy57; +yy57: +#line 396 "bytecode.re" +{ CHK_NL(YYCURSOR); + goto Directive; } +#line 899 "" +yy58: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy56; + default: goto yy47; + } +} +#line 402 "bytecode.re" + + + } + +Comment: + { + YYTOKEN = YYCURSOR; + + +#line 916 "" +{ + YYCTYPE yych; + goto yy59; + ++YYCURSOR; +yy59: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy61; + case 0x0A: goto yy62; + case 0x0D: goto yy64; + default: goto yy66; + } +yy61:yy62: ++YYCURSOR; + goto yy63; +yy63: +#line 412 "bytecode.re" +{ CHK_NL(YYCURSOR); + goto Document; } +#line 936 "" +yy64: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy67; + default: goto yy65; + } +yy65: +#line 415 "bytecode.re" +{ goto Comment; } +#line 945 "" +yy66: yych = *++YYCURSOR; + goto yy65; +yy67: ++YYCURSOR; + yych = *YYCURSOR; + goto yy63; +} +#line 417 "bytecode.re" + + + } + +Scalar: + { + int idx = 0; + int cap = 100; + char *str = S_ALLOC_N( char, cap ); + char *tok; + + str[0] = '\0'; + +Scalar2: + tok = YYCURSOR; + + +#line 970 "" +{ + YYCTYPE yych; + goto yy68; + ++YYCURSOR; +yy68: + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy74; + case 0x0A: goto yy70; + case 0x0D: goto yy72; + default: goto yy76; + } +yy70: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 'C': goto yy78; + case 'N': goto yy80; + case 'Z': goto yy83; + default: goto yy71; + } +yy71: +#line 461 "bytecode.re" +{ YYCURSOR = tok; + goto ScalarEnd; + } +#line 996 "" +yy72: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy77; + default: goto yy73; + } +yy73: +#line 469 "bytecode.re" +{ CAT(str, cap, idx, tok[0]); + goto Scalar2; + } +#line 1007 "" +yy74: ++YYCURSOR; + goto yy75; +yy75: +#line 465 "bytecode.re" +{ YYCURSOR = tok; + goto ScalarEnd; + } +#line 1015 "" +yy76: yych = *++YYCURSOR; + goto yy73; +yy77: yych = *++YYCURSOR; + switch(yych){ + case 'C': goto yy78; + case 'N': goto yy80; + case 'Z': goto yy83; + default: goto yy71; + } +yy78: ++YYCURSOR; + goto yy79; +yy79: +#line 435 "bytecode.re" +{ CHK_NL(tok+1); + goto Scalar2; } +#line 1031 "" +yy80: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy81; +yy81: switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy80; + default: goto yy82; + } +yy82: +#line 438 "bytecode.re" +{ CHK_NL(tok+1); + if ( tok + 2 < YYCURSOR ) + { + char *count = tok + 2; + int total = strtod( count, NULL ); + int i; + for ( i = 0; i < total; i++ ) + { + CAT(str, cap, idx, '\n'); + } + } + else + { + CAT(str, cap, idx, '\n'); + } + goto Scalar2; + } +#line 1068 "" +yy83: ++YYCURSOR; + goto yy84; +yy84: +#line 456 "bytecode.re" +{ CHK_NL(tok+1); + CAT(str, cap, idx, '\0'); + goto Scalar2; + } +#line 1077 "" +} +#line 473 "bytecode.re" + + +ScalarEnd: + { + SyckNode *n = syck_alloc_str(); + n->data.str->ptr = str; + n->data.str->len = idx; + sycklval->nodeData = n; + POP_LEVEL(); + if ( parser->implicit_typing == 1 ) + { + try_tag_implicit( sycklval->nodeData, parser->taguri_expansion ); + } + return YAML_PLAIN; + } + } + +} + +char * +get_inline( SyckParser *parser ) +{ + int idx = 0; + int cap = 100; + char *str = S_ALLOC_N( char, cap ); + char *tok; + + str[0] = '\0'; + +Inline: + { + tok = YYCURSOR; + + +#line 1114 "" +{ + YYCTYPE yych; + goto yy85; + ++YYCURSOR; +yy85: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy91; + case 0x0A: goto yy87; + case 0x0D: goto yy89; + default: goto yy93; + } +yy87: ++YYCURSOR; + goto yy88; +yy88: +#line 508 "bytecode.re" +{ CHK_NL(YYCURSOR); + return str; } +#line 1134 "" +yy89: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy94; + default: goto yy90; + } +yy90: +#line 515 "bytecode.re" +{ CAT(str, cap, idx, tok[0]); + goto Inline; + } +#line 1145 "" +yy91: ++YYCURSOR; + goto yy92; +yy92: +#line 511 "bytecode.re" +{ YYCURSOR = tok; + return str; + } +#line 1153 "" +yy93: yych = *++YYCURSOR; + goto yy90; +yy94: ++YYCURSOR; + yych = *YYCURSOR; + goto yy88; +} +#line 519 "bytecode.re" + + + } + +} + diff --git a/lib/19/syck/ext/emitter.c b/lib/19/syck/ext/emitter.c new file mode 100644 index 0000000000..80ddcd65eb --- /dev/null +++ b/lib/19/syck/ext/emitter.c @@ -0,0 +1,1247 @@ +/* + * emitter.c + * + * $Author: nobu $ + * + * Copyright (C) 2003 why the lucky stiff + * + * All Base64 code from Ruby's pack.c. + * Ruby is Copyright (C) 1993-2007 Yukihiro Matsumoto + */ +#include "ruby/ruby.h" + +#include +#include + +#include "syck.h" + +#define DEFAULT_ANCHOR_FORMAT "id%03d" + +const char hex_table[] = +"0123456789ABCDEF"; +static char b64_table[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* + * Built-in base64 (from Ruby's pack.c) + */ +char * +syck_base64enc( char *s, long len ) +{ + long i = 0; + int padding = '='; + char *buff = S_ALLOC_N(char, len * 4 / 3 + 6); + + while (len >= 3) { + buff[i++] = b64_table[077 & (*s >> 2)]; + buff[i++] = b64_table[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))]; + buff[i++] = b64_table[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))]; + buff[i++] = b64_table[077 & s[2]]; + s += 3; + len -= 3; + } + if (len == 2) { + buff[i++] = b64_table[077 & (*s >> 2)]; + buff[i++] = b64_table[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))]; + buff[i++] = b64_table[077 & (((s[1] << 2) & 074) | (('\0' >> 6) & 03))]; + buff[i++] = padding; + } + else if (len == 1) { + buff[i++] = b64_table[077 & (*s >> 2)]; + buff[i++] = b64_table[077 & (((*s << 4) & 060) | (('\0' >> 4) & 017))]; + buff[i++] = padding; + buff[i++] = padding; + } + buff[i++] = '\n'; + return buff; +} + +char * +syck_base64dec( char *s, long len ) +{ + int a = -1,b = -1,c = 0,d; + static int first = 1; + static int b64_xtable[256]; + char *ptr = syck_strndup( s, len ); + char *end = ptr; + char *send = s + len; + + if (first) { + int i; + first = 0; + + for (i = 0; i < 256; i++) { + b64_xtable[i] = -1; + } + for (i = 0; i < 64; i++) { + b64_xtable[(int)b64_table[i]] = i; + } + } + while (s < send) { + while (s[0] == '\r' || s[0] == '\n') { s++; } + if ((a = b64_xtable[(int)s[0]]) == -1) break; + if ((b = b64_xtable[(int)s[1]]) == -1) break; + if ((c = b64_xtable[(int)s[2]]) == -1) break; + if ((d = b64_xtable[(int)s[3]]) == -1) break; + *end++ = a << 2 | b >> 4; + *end++ = b << 4 | c >> 2; + *end++ = c << 6 | d; + s += 4; + } + if (a != -1 && b != -1) { + if (s + 2 < send && s[2] == '=') + *end++ = a << 2 | b >> 4; + if (c != -1 && s + 3 < send && s[3] == '=') { + *end++ = a << 2 | b >> 4; + *end++ = b << 4 | c >> 2; + } + } + *end = '\0'; + /*RSTRING_LEN(buf) = ptr - RSTRING_PTR(buf);*/ + return ptr; +} + +/* + * Allocate an emitter + */ +SyckEmitter * +syck_new_emitter(void) +{ + SyckEmitter *e; + e = S_ALLOC( SyckEmitter ); + e->headless = 0; + e->use_header = 0; + e->use_version = 0; + e->sort_keys = 0; + e->anchor_format = NULL; + e->explicit_typing = 0; + e->best_width = 80; + e->style = scalar_none; + e->stage = doc_open; + e->indent = 2; + e->level = -1; + e->anchors = NULL; + e->markers = NULL; + e->anchored = NULL; + e->bufsize = SYCK_BUFFERSIZE; + e->buffer = NULL; + e->marker = NULL; + e->bufpos = 0; + e->emitter_handler = NULL; + e->output_handler = NULL; + e->lvl_idx = 0; + e->lvl_capa = ALLOC_CT; + e->levels = S_ALLOC_N( SyckLevel, e->lvl_capa ); + syck_emitter_reset_levels( e ); + e->bonus = NULL; + return e; +} + +int +syck_st_free_anchors( char *key, char *name, char *arg ) +{ + S_FREE( name ); + return ST_CONTINUE; +} + +void +syck_emitter_st_free( SyckEmitter *e ) +{ + /* + * Free the anchor tables + */ + if ( e->anchors != NULL ) + { + st_foreach( e->anchors, syck_st_free_anchors, 0 ); + st_free_table( e->anchors ); + e->anchors = NULL; + } + + if ( e->anchored != NULL ) + { + st_free_table( e->anchored ); + e->anchored = NULL; + } + + /* + * Free the markers tables + */ + if ( e->markers != NULL ) + { + st_free_table( e->markers ); + e->markers = NULL; + } +} + +SyckLevel * +syck_emitter_current_level( SyckEmitter *e ) +{ + return &e->levels[e->lvl_idx-1]; +} + +SyckLevel * +syck_emitter_parent_level( SyckEmitter *e ) +{ + return &e->levels[e->lvl_idx-2]; +} + +void +syck_emitter_pop_level( SyckEmitter *e ) +{ + ASSERT( e != NULL ); + + /* The root level should never be popped */ + if ( e->lvl_idx <= 1 ) return; + + e->lvl_idx -= 1; + free( e->levels[e->lvl_idx].domain ); +} + +void +syck_emitter_add_level( SyckEmitter *e, int len, enum syck_level_status status ) +{ + ASSERT( e != NULL ); + if ( e->lvl_idx + 1 > e->lvl_capa ) + { + e->lvl_capa += ALLOC_CT; + S_REALLOC_N( e->levels, SyckLevel, e->lvl_capa ); + } + + ASSERT( len > e->levels[e->lvl_idx-1].spaces ); + e->levels[e->lvl_idx].spaces = len; + e->levels[e->lvl_idx].ncount = 0; + e->levels[e->lvl_idx].domain = syck_strndup( e->levels[e->lvl_idx-1].domain, strlen( e->levels[e->lvl_idx-1].domain ) ); + e->levels[e->lvl_idx].status = status; + e->levels[e->lvl_idx].anctag = 0; + e->lvl_idx += 1; +} + +void +syck_emitter_reset_levels( SyckEmitter *e ) +{ + while ( e->lvl_idx > 1 ) + { + syck_emitter_pop_level( e ); + } + + if ( e->lvl_idx < 1 ) + { + e->lvl_idx = 1; + e->levels[0].spaces = -1; + e->levels[0].ncount = 0; + e->levels[0].domain = syck_strndup( "", 0 ); + e->levels[0].anctag = 0; + } + e->levels[0].status = syck_lvl_header; +} + +void +syck_emitter_handler( SyckEmitter *e, SyckEmitterHandler hdlr ) +{ + e->emitter_handler = hdlr; +} + +void +syck_output_handler( SyckEmitter *e, SyckOutputHandler hdlr ) +{ + e->output_handler = hdlr; +} + +void +syck_free_emitter( SyckEmitter *e ) +{ + /* + * Free tables + */ + syck_emitter_st_free( e ); + syck_emitter_reset_levels( e ); + S_FREE( e->levels[0].domain ); + S_FREE( e->levels ); + if ( e->buffer != NULL ) + { + S_FREE( e->buffer ); + } + S_FREE( e ); +} + +void +syck_emitter_clear( SyckEmitter *e ) +{ + if ( e->buffer == NULL ) + { + e->buffer = S_ALLOC_N( char, e->bufsize ); + S_MEMZERO( e->buffer, char, e->bufsize ); + } + e->buffer[0] = '\0'; + e->marker = e->buffer; + e->bufpos = 0; +} + +/* + * Raw write to the emitter buffer. + */ +void +syck_emitter_write( SyckEmitter *e, const char *str, long len ) +{ + long at; + ASSERT( str != NULL ); + if ( e->buffer == NULL ) + { + syck_emitter_clear( e ); + } + + /* + * Flush if at end of buffer + */ + at = e->marker - e->buffer; + if ( len + at >= (long)e->bufsize ) + { + syck_emitter_flush( e, 0 ); + for (;;) { + long rest = e->bufsize - (e->marker - e->buffer); + if (len <= rest) break; + S_MEMCPY( e->marker, str, char, rest ); + e->marker += rest; + str += rest; + len -= rest; + syck_emitter_flush( e, 0 ); + } + } + + /* + * Write to buffer + */ + S_MEMCPY( e->marker, str, char, len ); + e->marker += len; +} + +/* + * Write a chunk of data out. + */ +void +syck_emitter_flush( SyckEmitter *e, long check_room ) +{ + /* + * Check for enough space in the buffer for check_room length. + */ + if ( check_room > 0 ) + { + if ( (long)e->bufsize > ( e->marker - e->buffer ) + check_room ) + { + return; + } + } + else + { + check_room = e->bufsize; + } + + /* + * Commit buffer. + */ + if ( check_room > e->marker - e->buffer ) + { + check_room = e->marker - e->buffer; + } + (e->output_handler)( e, e->buffer, check_room ); + e->bufpos += check_room; + e->marker -= check_room; +} + +/* + * Start emitting from the given node, check for anchoring and then + * issue the callback to the emitter handler. + */ +void +syck_emit( SyckEmitter *e, st_data_t n ) +{ + SYMID oid; + char *anchor_name = NULL; + int indent = 0; + long x = 0; + SyckLevel *lvl = syck_emitter_current_level( e ); + + /* + * Determine headers. + */ + if ( e->stage == doc_open && ( e->headless == 0 || e->use_header == 1 ) ) + { + if ( e->use_version == 1 ) + { + char *header = S_ALLOC_N( char, 64 ); + S_MEMZERO( header, char, 64 ); + sprintf( header, "--- %%YAML:%d.%d ", SYCK_YAML_MAJOR, SYCK_YAML_MINOR ); + syck_emitter_write( e, header, strlen( header ) ); + S_FREE( header ); + } + else + { + syck_emitter_write( e, "--- ", 4 ); + } + e->stage = doc_processing; + } + + /* Add new level */ + if ( lvl->spaces >= 0 ) { + indent = lvl->spaces + e->indent; + } + syck_emitter_add_level( e, indent, syck_lvl_open ); + lvl = syck_emitter_current_level( e ); + + /* Look for anchor */ + if ( e->anchors != NULL && + st_lookup( e->markers, n, (st_data_t *)&oid ) && + st_lookup( e->anchors, (st_data_t)oid, (void *)&anchor_name ) ) + { + if ( e->anchored == NULL ) + { + e->anchored = st_init_numtable(); + } + + if ( ! st_lookup( e->anchored, (st_data_t)anchor_name, (st_data_t *)&x ) ) + { + char *an = S_ALLOC_N( char, strlen( anchor_name ) + 3 ); + sprintf( an, "&%s ", anchor_name ); + syck_emitter_write( e, an, strlen( anchor_name ) + 2 ); + free( an ); + + x = 1; + st_insert( e->anchored, (st_data_t)anchor_name, (st_data_t)x ); + lvl->anctag = 1; + } + else + { + char *an = S_ALLOC_N( char, strlen( anchor_name ) + 2 ); + sprintf( an, "*%s", anchor_name ); + syck_emitter_write( e, an, strlen( anchor_name ) + 1 ); + free( an ); + + goto end_emit; + } + } + + (e->emitter_handler)( e, n ); + + /* Pop the level */ +end_emit: + syck_emitter_pop_level( e ); + if ( e->lvl_idx == 1 ) { + syck_emitter_write( e, "\n", 1 ); + e->headless = 0; + e->stage = doc_open; + } +} + +/* + * Determine what tag needs to be written, based on the taguri of the node + * and the implicit tag which would be assigned to this node. If a tag is + * required, write the tag. + */ +void syck_emit_tag( SyckEmitter *e, const char *tag, const char *ignore ) +{ + SyckLevel *lvl; + if ( tag == NULL ) return; + if ( ignore != NULL && syck_tagcmp( tag, ignore ) == 0 && e->explicit_typing == 0 ) return; + lvl = syck_emitter_current_level( e ); + + /* implicit */ + if ( strlen( tag ) == 0 ) { + syck_emitter_write( e, "! ", 2 ); + + /* global types */ + } else if ( strncmp( tag, "tag:", 4 ) == 0 ) { + int taglen = strlen( tag ); + syck_emitter_write( e, "!", 1 ); + if ( strncmp( tag + 4, YAML_DOMAIN, strlen( YAML_DOMAIN ) ) == 0 ) { + int skip = 4 + strlen( YAML_DOMAIN ) + 1; + syck_emitter_write( e, tag + skip, taglen - skip ); + } else { + const char *subd = tag + 4; + while ( *subd != ':' && *subd != '\0' ) subd++; + if ( *subd == ':' ) { + if ( subd - tag > ( (long)( strlen( YAML_DOMAIN ) + 5 )) && + strncmp( subd - strlen( YAML_DOMAIN ), YAML_DOMAIN, strlen( YAML_DOMAIN ) ) == 0 ) { + syck_emitter_write( e, tag + 4, subd - strlen( YAML_DOMAIN ) - ( tag + 4 ) - 1 ); + syck_emitter_write( e, "/", 1 ); + syck_emitter_write( e, subd + 1, ( tag + taglen ) - ( subd + 1 ) ); + } else { + syck_emitter_write( e, tag + 4, subd - ( tag + 4 ) ); + syck_emitter_write( e, "/", 1 ); + syck_emitter_write( e, subd + 1, ( tag + taglen ) - ( subd + 1 ) ); + } + } else { + /* TODO: Invalid tag (no colon after domain) */ + return; + } + } + syck_emitter_write( e, " ", 1 ); + + /* private types */ + } else if ( strncmp( tag, "x-private:", 10 ) == 0 ) { + syck_emitter_write( e, "!!", 2 ); + syck_emitter_write( e, tag + 10, strlen( tag ) - 10 ); + syck_emitter_write( e, " ", 1 ); + } + lvl->anctag = 1; +} + +/* + * Emit a newline and an appropriately spaced indent. + */ +void syck_emit_indent( SyckEmitter *e ) +{ + int i; + SyckLevel *lvl = syck_emitter_current_level( e ); + if ( e->bufpos == 0 && ( e->marker - e->buffer ) == 0 ) return; + if ( lvl->spaces >= 0 ) { + char *spcs = S_ALLOC_N( char, lvl->spaces + 2 ); + + spcs[0] = '\n'; spcs[lvl->spaces + 1] = '\0'; + for ( i = 0; i < lvl->spaces; i++ ) spcs[i+1] = ' '; + syck_emitter_write( e, spcs, lvl->spaces + 1 ); + free( spcs ); + } +} + +/* Clear the scan */ +#define SCAN_NONE 0 +/* All printable characters? */ +#define SCAN_NONPRINT 1 +/* Any indented lines? */ +#define SCAN_INDENTED 2 +/* Larger than the requested width? */ +#define SCAN_WIDE 4 +/* Opens or closes with whitespace? */ +#define SCAN_WHITEEDGE 8 +/* Contains a newline */ +#define SCAN_NEWLINE 16 +/* Contains a single quote */ +#define SCAN_SINGLEQ 32 +/* Contains a double quote */ +#define SCAN_DOUBLEQ 64 +/* Starts with a token */ +#define SCAN_INDIC_S 128 +/* Contains a flow indicator */ +#define SCAN_INDIC_C 256 +/* Ends without newlines */ +#define SCAN_NONL_E 512 +/* Ends with many newlines */ +#define SCAN_MANYNL_E 1024 +/* Contains flow map indicators */ +#define SCAN_FLOWMAP 2048 +/* Contains flow seq indicators */ +#define SCAN_FLOWSEQ 4096 +/* Contains a valid doc separator */ +#define SCAN_DOCSEP 8192 + +/* + * Basic printable test for LATIN-1 characters. + */ +int +syck_scan_scalar( int req_width, const char *cursor, long len ) +{ + long i = 0, start = 0; + int flags = SCAN_NONE; + + if ( len < 1 ) return flags; + + /* c-indicators from the spec */ + if ( cursor[0] == '[' || cursor[0] == ']' || + cursor[0] == '{' || cursor[0] == '}' || + cursor[0] == '!' || cursor[0] == '*' || + cursor[0] == '&' || cursor[0] == '|' || + cursor[0] == '>' || cursor[0] == '\'' || + cursor[0] == '"' || cursor[0] == '#' || + cursor[0] == '%' || cursor[0] == '@' || + cursor[0] == '&' ) { + flags |= SCAN_INDIC_S; + } + if ( ( cursor[0] == '-' || cursor[0] == ':' || + cursor[0] == '?' || cursor[0] == ',' ) && + ( len == 1 || cursor[1] == ' ' || cursor[1] == '\n' ) ) + { + flags |= SCAN_INDIC_S; + } + + /* whitespace edges */ + if ( cursor[len-1] != '\n' ) { + flags |= SCAN_NONL_E; + } else if ( len > 1 && cursor[len-2] == '\n' ) { + flags |= SCAN_MANYNL_E; + } + if ( + ( len > 0 && ( cursor[0] == ' ' || cursor[0] == '\t' || cursor[0] == '\n' || cursor[0] == '\r' ) ) || + ( len > 1 && ( cursor[len-1] == ' ' || cursor[len-1] == '\t' ) ) + ) { + flags |= SCAN_WHITEEDGE; + } + + /* opening doc sep */ + if ( len >= 3 && strncmp( cursor, "---", 3 ) == 0 ) + flags |= SCAN_DOCSEP; + + /* scan string */ + for ( i = 0; i < len; i++ ) { + + if ( ! ( cursor[i] == 0x9 || + cursor[i] == 0xA || + cursor[i] == 0xD || + ( cursor[i] >= 0x20 && cursor[i] <= 0x7E ) ) + ) { + flags |= SCAN_NONPRINT; + } + else if ( cursor[i] == '\n' ) { + flags |= SCAN_NEWLINE; + if ( len - i >= 3 && strncmp( &cursor[i+1], "---", 3 ) == 0 ) + flags |= SCAN_DOCSEP; + if ( cursor[i+1] == ' ' || cursor[i+1] == '\t' ) + flags |= SCAN_INDENTED; + if ( req_width > 0 && i - start > req_width ) + flags |= SCAN_WIDE; + start = i; + } + else if ( cursor[i] == '\'' ) + { + flags |= SCAN_SINGLEQ; + } + else if ( cursor[i] == '"' ) + { + flags |= SCAN_DOUBLEQ; + } + else if ( cursor[i] == ']' ) + { + flags |= SCAN_FLOWSEQ; + } + else if ( cursor[i] == '}' ) + { + flags |= SCAN_FLOWMAP; + } + /* remember, if plain collections get implemented, to add nb-plain-flow-char */ + else if ( ( cursor[i] == ' ' && cursor[i+1] == '#' ) || + ( cursor[i] == ':' && + ( cursor[i+1] == ' ' || cursor[i+1] == '\n' || i == len - 1 ) ) ) + { + flags |= SCAN_INDIC_C; + } + else if ( cursor[i] == ',' && + ( cursor[i+1] == ' ' || cursor[i+1] == '\n' || i == len - 1 ) ) + { + flags |= SCAN_FLOWMAP; + flags |= SCAN_FLOWSEQ; + } + } + + /* printf( "---STR---\n%s\nFLAGS: %d\n", cursor, flags ); */ + return flags; +} +/* + * All scalars should be emitted through this function, which determines an appropriate style, + * tag and indent. + */ +void syck_emit_scalar( SyckEmitter *e, const char *tag, enum scalar_style force_style, int force_indent, int force_width, + char keep_nl, const char *str, long len ) +{ + enum scalar_style favor_style = scalar_literal; + SyckLevel *parent = syck_emitter_parent_level( e ); + SyckLevel *lvl = syck_emitter_current_level( e ); + int scan = 0; + const char *match_implicit; + char *implicit; + + if ( str == NULL ) str = ""; + + /* No empty nulls as map keys */ + if ( len == 0 && ( parent->status == syck_lvl_map || parent->status == syck_lvl_imap ) && + parent->ncount % 2 == 1 && syck_tagcmp( tag, "tag:yaml.org,2002:null" ) == 0 ) + { + str = "~"; + len = 1; + } + + scan = syck_scan_scalar( force_width, str, len ); + match_implicit = syck_match_implicit( str, len ); + + /* quote strings which default to implicits */ + implicit = syck_taguri( YAML_DOMAIN, match_implicit, strlen( match_implicit ) ); + if ( syck_tagcmp( tag, implicit ) != 0 && syck_tagcmp( tag, "tag:yaml.org,2002:str" ) == 0 ) { + force_style = scalar_2quote; + } else { + /* complex key */ + if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 && + ( !( tag == NULL || + ( implicit != NULL && syck_tagcmp( tag, implicit ) == 0 && e->explicit_typing == 0 ) ) ) ) + { + syck_emitter_write( e, "? ", 2 ); + parent->status = syck_lvl_mapx; + } + syck_emit_tag( e, tag, implicit ); + } + S_FREE( implicit ); + + /* if still arbitrary, sniff a good block style. */ + if ( force_style == scalar_none ) { + if ( scan & SCAN_NEWLINE ) { + force_style = scalar_literal; + } else { + force_style = scalar_plain; + } + } + + if ( e->style == scalar_fold ) { + favor_style = scalar_fold; + } + + /* Determine block style */ + if ( scan & SCAN_NONPRINT ) { + force_style = scalar_2quote; + } else if ( scan & SCAN_WHITEEDGE ) { + force_style = scalar_2quote; + } else if ( force_style != scalar_fold && ( scan & SCAN_INDENTED ) ) { + force_style = scalar_literal; + } else if ( force_style == scalar_plain && ( scan & SCAN_NEWLINE ) ) { + force_style = favor_style; + } else if ( force_style == scalar_plain && parent->status == syck_lvl_iseq && ( scan & SCAN_FLOWSEQ ) ) { + force_style = scalar_2quote; + } else if ( force_style == scalar_plain && parent->status == syck_lvl_imap && ( scan & SCAN_FLOWMAP ) ) { + force_style = scalar_2quote; + /* } else if ( force_style == scalar_fold && ( ! ( scan & SCAN_WIDE ) ) ) { + force_style = scalar_literal; */ + } else if ( force_style == scalar_plain && ( scan & SCAN_INDIC_S || scan & SCAN_INDIC_C ) ) { + if ( scan & SCAN_NEWLINE ) { + force_style = favor_style; + } else { + force_style = scalar_2quote; + } + } + + if ( force_indent > 0 ) { + lvl->spaces = parent->spaces + force_indent; + } else if ( scan & SCAN_DOCSEP ) { + lvl->spaces = parent->spaces + e->indent; + } + + /* For now, all ambiguous keys are going to be double-quoted */ + if ( ( parent->status == syck_lvl_map || parent->status == syck_lvl_mapx ) && parent->ncount % 2 == 1 ) { + if ( force_style != scalar_plain ) { + force_style = scalar_2quote; + } + } + + /* If the parent is an inline, double quote anything complex */ + if ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) { + if ( force_style != scalar_plain && force_style != scalar_1quote ) { + force_style = scalar_2quote; + } + } + + /* Fix the ending newlines */ + if ( scan & SCAN_NONL_E ) { + keep_nl = NL_CHOMP; + } else if ( scan & SCAN_MANYNL_E ) { + keep_nl = NL_KEEP; + } + + /* Write the text node */ + switch ( force_style ) + { + case scalar_1quote: + syck_emit_1quoted( e, force_width, str, len ); + break; + + case scalar_none: + case scalar_2quote: + syck_emit_2quoted( e, force_width, str, len ); + break; + + case scalar_fold: + syck_emit_folded( e, force_width, keep_nl, str, len ); + break; + + case scalar_literal: + syck_emit_literal( e, keep_nl, str, len ); + break; + + case scalar_plain: + syck_emitter_write( e, str, len ); + break; + } + + if ( parent->status == syck_lvl_mapx ) + { + syck_emitter_write( e, "\n", 1 ); + } +} + +void +syck_emitter_escape( SyckEmitter *e, const char *src, long len ) +{ + int i; + for( i = 0; i < len; i++ ) + { + if( (src[i] < 0x20) || (0x7E < src[i]) ) + { + syck_emitter_write( e, "\\", 1 ); + if( '\0' == src[i] ) + syck_emitter_write( e, "0", 1 ); + else + { + syck_emitter_write( e, "x", 1 ); + syck_emitter_write( e, (const char *)hex_table + ((src[i] & 0xF0) >> 4), 1 ); + syck_emitter_write( e, (const char *)hex_table + (src[i] & 0x0F), 1 ); + } + } + else + { + syck_emitter_write( e, src + i, 1 ); + if( '\\' == src[i] ) + syck_emitter_write( e, "\\", 1 ); + } + } +} + +/* + * Outputs a single-quoted block. + */ +void +syck_emit_1quoted( SyckEmitter *e, int width, const char *str, long len ) +{ + char do_indent = 0; + const char *mark = str; + const char *start = str; + const char *end = str; + syck_emitter_write( e, "'", 1 ); + while ( mark < str + len ) { + if ( do_indent ) { + syck_emit_indent( e ); + do_indent = 0; + } + switch ( *mark ) { + case '\'': syck_emitter_write( e, "'", 1 ); break; + + case '\n': + end = mark + 1; + if ( *start != ' ' && *start != '\n' && *end != '\n' && *end != ' ' ) { + syck_emitter_write( e, "\n\n", 2 ); + } else { + syck_emitter_write( e, "\n", 1 ); + } + do_indent = 1; + start = mark + 1; + break; + + case ' ': + if ( width > 0 && *start != ' ' && mark - end > width ) { + do_indent = 1; + end = mark + 1; + } else { + syck_emitter_write( e, " ", 1 ); + } + break; + + default: + syck_emitter_write( e, mark, 1 ); + break; + } + mark++; + } + syck_emitter_write( e, "'", 1 ); +} + +/* + * Outputs a double-quoted block. + */ +void +syck_emit_2quoted( SyckEmitter *e, int width, const char *str, long len ) +{ + char do_indent = 0; + const char *mark = str; + const char *start = str; + const char *end = str; + syck_emitter_write( e, "\"", 1 ); + while ( mark < str + len ) { + if ( do_indent > 0 ) { + if ( do_indent == 2 ) { + syck_emitter_write( e, "\\", 1 ); + } + syck_emit_indent( e ); + do_indent = 0; + } + switch ( *mark ) { + + /* Escape sequences allowed within double quotes. */ + case '"': syck_emitter_write( e, "\\\"", 2 ); break; + case '\\': syck_emitter_write( e, "\\\\", 2 ); break; + case '\0': syck_emitter_write( e, "\\0", 2 ); break; + case '\a': syck_emitter_write( e, "\\a", 2 ); break; + case '\b': syck_emitter_write( e, "\\b", 2 ); break; + case '\f': syck_emitter_write( e, "\\f", 2 ); break; + case '\r': syck_emitter_write( e, "\\r", 2 ); break; + case '\t': syck_emitter_write( e, "\\t", 2 ); break; + case '\v': syck_emitter_write( e, "\\v", 2 ); break; + case 0x1b: syck_emitter_write( e, "\\e", 2 ); break; + + case '\n': + end = mark + 1; + syck_emitter_write( e, "\\n", 2 ); + do_indent = 2; + start = mark + 1; + if ( start < str + len && ( *start == ' ' || *start == '\n' ) ) { + do_indent = 0; + } + break; + + case ' ': + if ( width > 0 && *start != ' ' && mark - end > width ) { + do_indent = 1; + end = mark + 1; + } else { + syck_emitter_write( e, " ", 1 ); + } + break; + + default: + syck_emitter_escape( e, mark, 1 ); + break; + } + mark++; + } + syck_emitter_write( e, "\"", 1 ); +} + +/* + * Outputs a literal block. + */ +void +syck_emit_literal( SyckEmitter *e, char keep_nl, const char *str, long len ) +{ + const char *mark = str; + const char *start = str; + const char *end = str; + syck_emitter_write( e, "|", 1 ); + if ( keep_nl == NL_CHOMP ) { + syck_emitter_write( e, "-", 1 ); + } else if ( keep_nl == NL_KEEP ) { + syck_emitter_write( e, "+", 1 ); + } + syck_emit_indent( e ); + while ( mark < str + len ) { + if ( *mark == '\n' ) { + end = mark; + if ( *start != ' ' && *start != '\n' && *end != '\n' && *end != ' ' ) end += 1; + syck_emitter_write( e, start, end - start ); + if ( mark + 1 == str + len ) { + if ( keep_nl != NL_KEEP ) syck_emitter_write( e, "\n", 1 ); + } else { + syck_emit_indent( e ); + } + start = mark + 1; + } + mark++; + } + end = str + len; + if ( start < end ) { + syck_emitter_write( e, start, end - start ); + } +} + +/* + * Outputs a folded block. + */ +void +syck_emit_folded( SyckEmitter *e, int width, char keep_nl, const char *str, long len ) +{ + const char *mark = str; + const char *start = str; + const char *end = str; + syck_emitter_write( e, ">", 1 ); + if ( keep_nl == NL_CHOMP ) { + syck_emitter_write( e, "-", 1 ); + } else if ( keep_nl == NL_KEEP ) { + syck_emitter_write( e, "+", 1 ); + } + syck_emit_indent( e ); + if ( width <= 0 ) width = e->best_width; + while ( mark < str + len ) { + switch ( *mark ) { + case '\n': + syck_emitter_write( e, end, mark - end ); + end = mark + 1; + if ( *start != ' ' && *start != '\n' && *end != '\n' && *end != ' ' ) { + syck_emitter_write( e, "\n", 1 ); + } + if ( mark + 1 == str + len ) { + if ( keep_nl != NL_KEEP ) syck_emitter_write( e, "\n", 1 ); + } else { + syck_emit_indent( e ); + } + start = mark + 1; + break; + + case ' ': + if ( *start != ' ' ) { + if ( mark - end > width ) { + syck_emitter_write( e, end, mark - end ); + syck_emit_indent( e ); + end = mark + 1; + } + } + break; + } + mark++; + } + if ( end < mark ) { + syck_emitter_write( e, end, mark - end ); + } +} + +/* + * Begins emission of a sequence. + */ +void syck_emit_seq( SyckEmitter *e, const char *tag, enum seq_style style ) +{ + SyckLevel *parent = syck_emitter_parent_level( e ); + SyckLevel *lvl = syck_emitter_current_level( e ); + syck_emit_tag( e, tag, "tag:yaml.org,2002:seq" ); + if ( style == seq_inline || ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) ) { + syck_emitter_write( e, "[", 1 ); + lvl->status = syck_lvl_iseq; + } else { + /* complex key */ + if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 ) { + syck_emitter_write( e, "? ", 2 ); + parent->status = syck_lvl_mapx; + } + lvl->status = syck_lvl_seq; + } +} + +/* + * Begins emission of a mapping. + */ +void +syck_emit_map( SyckEmitter *e, const char *tag, enum map_style style ) +{ + SyckLevel *parent = syck_emitter_parent_level( e ); + SyckLevel *lvl = syck_emitter_current_level( e ); + syck_emit_tag( e, tag, "tag:yaml.org,2002:map" ); + if ( style == map_inline || ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) ) { + syck_emitter_write( e, "{", 1 ); + lvl->status = syck_lvl_imap; + } else { + /* complex key */ + if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 ) { + syck_emitter_write( e, "? ", 2 ); + parent->status = syck_lvl_mapx; + } + lvl->status = syck_lvl_map; + } +} + +/* + * Handles emitting of a collection item (for both + * sequences and maps) + */ +void syck_emit_item( SyckEmitter *e, st_data_t n ) +{ + SyckLevel *lvl = syck_emitter_current_level( e ); + switch ( lvl->status ) + { + case syck_lvl_seq: + { + SyckLevel *parent = syck_emitter_parent_level( e ); + + /* seq-in-map shortcut -- the lvl->anctag check should be unneccesary but + * there is a nasty shift/reduce in the parser on this point and + * i'm not ready to tickle it. */ + if ( lvl->anctag == 0 && parent->status == syck_lvl_map && lvl->ncount == 0 ) { + lvl->spaces = parent->spaces; + } + + /* seq-in-seq shortcut */ + else if ( lvl->anctag == 0 && parent->status == syck_lvl_seq && lvl->ncount == 0 ) { + int spcs = ( lvl->spaces - parent->spaces ) - 2; + if ( spcs >= 0 ) { + int i = 0; + for ( i = 0; i < spcs; i++ ) { + syck_emitter_write( e, " ", 1 ); + } + syck_emitter_write( e, "- ", 2 ); + break; + } + } + + syck_emit_indent( e ); + syck_emitter_write( e, "- ", 2 ); + } + break; + + case syck_lvl_iseq: + { + if ( lvl->ncount > 0 ) { + syck_emitter_write( e, ", ", 2 ); + } + } + break; + + case syck_lvl_map: + { + SyckLevel *parent = syck_emitter_parent_level( e ); + + /* map-in-seq shortcut */ + if ( lvl->anctag == 0 && parent->status == syck_lvl_seq && lvl->ncount == 0 ) { + int spcs = ( lvl->spaces - parent->spaces ) - 2; + if ( spcs >= 0 ) { + int i = 0; + for ( i = 0; i < spcs; i++ ) { + syck_emitter_write( e, " ", 1 ); + } + break; + } + } + + if ( lvl->ncount % 2 == 0 ) { + syck_emit_indent( e ); + } else { + syck_emitter_write( e, ": ", 2 ); + } + } + break; + + case syck_lvl_mapx: + { + if ( lvl->ncount % 2 == 0 ) { + syck_emit_indent( e ); + lvl->status = syck_lvl_map; + } else { + int i; + if ( lvl->spaces > 0 ) { + char *spcs = S_ALLOC_N( char, lvl->spaces + 1 ); + + spcs[lvl->spaces] = '\0'; + for ( i = 0; i < lvl->spaces; i++ ) spcs[i] = ' '; + syck_emitter_write( e, spcs, lvl->spaces ); + S_FREE( spcs ); + } + syck_emitter_write( e, ": ", 2 ); + } + } + break; + + case syck_lvl_imap: + { + if ( lvl->ncount > 0 ) { + if ( lvl->ncount % 2 == 0 ) { + syck_emitter_write( e, ", ", 2 ); + } else { + syck_emitter_write( e, ": ", 2 ); + } + } + } + break; + + default: break; + } + lvl->ncount++; + + syck_emit( e, n ); +} + +/* + * Closes emission of a collection. + */ +void syck_emit_end( SyckEmitter *e ) +{ + SyckLevel *lvl = syck_emitter_current_level( e ); + SyckLevel *parent = syck_emitter_parent_level( e ); + switch ( lvl->status ) + { + case syck_lvl_seq: + if ( lvl->ncount == 0 ) { + syck_emitter_write( e, "[]\n", 3 ); + } else if ( parent->status == syck_lvl_mapx ) { + syck_emitter_write( e, "\n", 1 ); + } + break; + + case syck_lvl_iseq: + syck_emitter_write( e, "]\n", 1 ); + break; + + case syck_lvl_map: + if ( lvl->ncount == 0 ) { + syck_emitter_write( e, "{}\n", 3 ); + } else if ( lvl->ncount % 2 == 1 ) { + syck_emitter_write( e, ":\n", 1 ); + } else if ( parent->status == syck_lvl_mapx ) { + syck_emitter_write( e, "\n", 1 ); + } + break; + + case syck_lvl_imap: + syck_emitter_write( e, "}\n", 1 ); + break; + + default: break; + } +} + +/* + * Fill markers table with emitter nodes in the + * soon-to-be-emitted tree. + */ +SYMID +syck_emitter_mark_node( SyckEmitter *e, st_data_t n ) +{ + SYMID oid = 0; + char *anchor_name = NULL; + + /* + * Ensure markers table is initialized. + */ + if ( e->markers == NULL ) + { + e->markers = st_init_numtable(); + } + + /* + * Markers table initially marks the string position of the + * object. Doesn't yet create an anchor, simply notes the + * position. + */ + if ( ! st_lookup( e->markers, n, (st_data_t *)&oid ) ) + { + /* + * Store all markers + */ + oid = e->markers->num_entries + 1; + st_insert( e->markers, n, (st_data_t)oid ); + } + else + { + if ( e->anchors == NULL ) + { + e->anchors = st_init_numtable(); + } + + if ( ! st_lookup( e->anchors, (st_data_t)oid, (void *)&anchor_name ) ) + { + int idx = 0; + const char *anc = ( e->anchor_format == NULL ? DEFAULT_ANCHOR_FORMAT : e->anchor_format ); + + /* + * Second time hitting this object, let's give it an anchor + */ + idx = e->anchors->num_entries + 1; + anchor_name = S_ALLOC_N( char, strlen( anc ) + 10 ); + S_MEMZERO( anchor_name, char, strlen( anc ) + 10 ); + sprintf( anchor_name, anc, idx ); + + /* + * Insert into anchors table + */ + st_insert( e->anchors, (st_data_t)oid, (st_data_t)anchor_name ); + } + } + return oid; +} + diff --git a/lib/19/syck/ext/extconf.rb b/lib/19/syck/ext/extconf.rb new file mode 100644 index 0000000000..6c10448c70 --- /dev/null +++ b/lib/19/syck/ext/extconf.rb @@ -0,0 +1,5 @@ +require 'mkmf' + +have_header( "st.h" ) +create_makefile( "syck" ) + diff --git a/lib/19/syck/ext/gram.c b/lib/19/syck/ext/gram.c new file mode 100644 index 0000000000..8fe4e4f3b5 --- /dev/null +++ b/lib/19/syck/ext/gram.c @@ -0,0 +1,1894 @@ +/* A Bison parser, made by GNU Bison 1.875d. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* If NAME_PREFIX is specified substitute the variables and functions + names. */ +#define yyparse syckparse +#define yylex sycklex +#define yyerror syckerror +#define yylval sycklval +#define yychar syckchar +#define yydebug syckdebug +#define yynerrs sycknerrs + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + YAML_ANCHOR = 258, + YAML_ALIAS = 259, + YAML_TRANSFER = 260, + YAML_TAGURI = 261, + YAML_ITRANSFER = 262, + YAML_WORD = 263, + YAML_PLAIN = 264, + YAML_BLOCK = 265, + YAML_DOCSEP = 266, + YAML_IOPEN = 267, + YAML_INDENT = 268, + YAML_IEND = 269 + }; +#endif +#define YAML_ANCHOR 258 +#define YAML_ALIAS 259 +#define YAML_TRANSFER 260 +#define YAML_TAGURI 261 +#define YAML_ITRANSFER 262 +#define YAML_WORD 263 +#define YAML_PLAIN 264 +#define YAML_BLOCK 265 +#define YAML_DOCSEP 266 +#define YAML_IOPEN 267 +#define YAML_INDENT 268 +#define YAML_IEND 269 + + + + +/* Copy the first part of user declarations. */ +#line 14 "gram.y" + + +#include "syck.h" + +void apply_seq_in_map( SyckParser *parser, SyckNode *n ); + +#define YYPARSE_PARAM parser +#define YYLEX_PARAM parser + +#define NULL_NODE(parser, node) \ + SyckNode *node = syck_new_str( "", scalar_plain ); \ + if ( ((SyckParser *)parser)->taguri_expansion == 1 ) \ + { \ + node->type_id = syck_taguri( YAML_DOMAIN, "null", 4 ); \ + } \ + else \ + { \ + node->type_id = syck_strndup( "null", 4 ); \ + } + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 35 "gram.y" +typedef union YYSTYPE { + SYMID nodeId; + SyckNode *nodeData; + char *name; +} YYSTYPE; +/* Line 191 of yacc.c. */ +#line 140 "gram.c" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 214 of yacc.c. */ +#line 152 "gram.c" + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +# ifndef YYFREE +# define YYFREE free +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# endif + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# endif +# else +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short int yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined (__GNUC__) && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short int yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 52 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 396 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 23 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 29 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 79 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 128 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 269 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 21, 15, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 16, 2, + 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 17, 2, 18, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 19, 2, 20, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned char yyprhs[] = +{ + 0, 0, 3, 5, 8, 9, 11, 13, 15, 18, + 21, 24, 28, 30, 32, 36, 37, 40, 43, 46, + 49, 51, 54, 56, 58, 60, 63, 66, 69, 72, + 75, 77, 79, 81, 85, 87, 89, 91, 93, 95, + 99, 103, 106, 110, 113, 117, 120, 124, 127, 129, + 133, 136, 140, 143, 145, 149, 151, 153, 157, 161, + 165, 168, 172, 175, 179, 182, 184, 188, 190, 194, + 196, 200, 204, 207, 211, 215, 218, 220, 224, 226 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 24, 0, -1, 25, -1, 11, 27, -1, -1, 33, + -1, 26, -1, 34, -1, 5, 26, -1, 6, 26, + -1, 3, 26, -1, 29, 26, 32, -1, 25, -1, + 28, -1, 29, 28, 30, -1, -1, 7, 28, -1, + 5, 28, -1, 6, 28, -1, 3, 28, -1, 12, + -1, 29, 13, -1, 14, -1, 13, -1, 14, -1, + 31, 32, -1, 5, 33, -1, 6, 33, -1, 7, + 33, -1, 3, 33, -1, 4, -1, 8, -1, 9, + -1, 29, 33, 32, -1, 10, -1, 35, -1, 39, + -1, 42, -1, 49, -1, 29, 37, 30, -1, 29, + 38, 30, -1, 15, 27, -1, 5, 31, 38, -1, + 5, 37, -1, 6, 31, 38, -1, 6, 37, -1, + 3, 31, 38, -1, 3, 37, -1, 36, -1, 38, + 31, 36, -1, 38, 31, -1, 17, 40, 18, -1, + 17, 18, -1, 41, -1, 40, 21, 41, -1, 25, + -1, 48, -1, 29, 43, 30, -1, 29, 47, 30, + -1, 5, 31, 47, -1, 5, 43, -1, 6, 31, + 47, -1, 6, 43, -1, 3, 31, 47, -1, 3, + 43, -1, 33, -1, 22, 25, 31, -1, 27, -1, + 44, 16, 45, -1, 46, -1, 47, 31, 36, -1, + 47, 31, 46, -1, 47, 31, -1, 25, 16, 27, + -1, 19, 50, 20, -1, 19, 20, -1, 51, -1, + 50, 21, 51, -1, 25, -1, 48, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short int yyrline[] = +{ + 0, 56, 56, 60, 65, 70, 71, 74, 75, 80, + 85, 94, 100, 101, 104, 109, 113, 121, 126, 131, + 145, 146, 149, 152, 155, 156, 164, 169, 174, 182, + 186, 194, 207, 208, 218, 219, 220, 221, 222, 228, + 232, 238, 244, 249, 254, 259, 264, 268, 274, 278, + 283, 292, 296, 302, 306, 313, 314, 320, 325, 332, + 337, 342, 347, 352, 356, 362, 363, 369, 379, 396, + 397, 409, 417, 426, 434, 438, 444, 445, 454, 461 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "YAML_ANCHOR", "YAML_ALIAS", + "YAML_TRANSFER", "YAML_TAGURI", "YAML_ITRANSFER", "YAML_WORD", + "YAML_PLAIN", "YAML_BLOCK", "YAML_DOCSEP", "YAML_IOPEN", "YAML_INDENT", + "YAML_IEND", "'-'", "':'", "'['", "']'", "'{'", "'}'", "','", "'?'", + "$accept", "doc", "atom", "ind_rep", "atom_or_empty", "empty", + "indent_open", "indent_end", "indent_sep", "indent_flex_end", "word_rep", + "struct_rep", "implicit_seq", "basic_seq", "top_imp_seq", + "in_implicit_seq", "inline_seq", "in_inline_seq", "inline_seq_atom", + "implicit_map", "top_imp_map", "complex_key", "complex_value", + "complex_mapping", "in_implicit_map", "basic_mapping", "inline_map", + "in_inline_map", "inline_map_atom", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short int yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 45, 58, 91, 93, 123, + 125, 44, 63 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 23, 24, 24, 24, 25, 25, 26, 26, 26, + 26, 26, 27, 27, 28, 28, 28, 28, 28, 28, + 29, 29, 30, 31, 32, 32, 33, 33, 33, 33, + 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, + 35, 36, 37, 37, 37, 37, 37, 37, 38, 38, + 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, + 43, 43, 43, 43, 43, 44, 44, 45, 46, 47, + 47, 47, 47, 48, 49, 49, 50, 50, 51, 51 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 2, 0, 1, 1, 1, 2, 2, + 2, 3, 1, 1, 3, 0, 2, 2, 2, 2, + 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, + 1, 1, 1, 3, 1, 1, 1, 1, 1, 3, + 3, 2, 3, 2, 3, 2, 3, 2, 1, 3, + 2, 3, 2, 1, 3, 1, 1, 3, 3, 3, + 2, 3, 2, 3, 2, 1, 3, 1, 3, 1, + 3, 3, 2, 3, 3, 2, 1, 3, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 4, 0, 30, 0, 0, 0, 31, 32, 34, 15, + 20, 0, 0, 0, 2, 6, 0, 5, 7, 35, + 36, 37, 38, 10, 29, 8, 26, 9, 27, 0, + 0, 0, 0, 28, 15, 15, 15, 15, 12, 3, + 13, 15, 52, 55, 0, 53, 56, 75, 78, 79, + 0, 76, 1, 0, 0, 0, 21, 15, 0, 0, + 65, 48, 0, 0, 0, 0, 69, 0, 0, 19, + 17, 18, 15, 15, 15, 16, 15, 15, 15, 15, + 0, 15, 51, 0, 74, 0, 23, 0, 47, 64, + 0, 43, 60, 0, 45, 62, 41, 0, 24, 0, + 11, 33, 22, 39, 40, 50, 57, 15, 58, 72, + 14, 73, 54, 77, 65, 46, 63, 42, 59, 44, + 61, 66, 25, 49, 67, 68, 70, 71 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yysigned_char yydefgoto[] = +{ + -1, 13, 38, 15, 39, 40, 16, 103, 99, 101, + 17, 18, 19, 61, 62, 63, 20, 44, 45, 21, + 64, 65, 125, 66, 67, 46, 22, 50, 51 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -97 +static const short int yypact[] = +{ + 250, 318, -97, 318, 318, 374, -97, -97, -97, 335, + -97, 267, 232, 7, -97, -97, 192, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, 374, + 374, 374, 352, -97, 335, 335, 335, 384, -97, -97, + -97, 212, -97, 10, 0, -97, -97, -97, 10, -97, + -4, -97, -97, 284, 284, 284, -97, 335, 318, 30, + 30, -97, -2, 36, -2, 16, -97, 36, 30, -97, + -97, -97, 384, 384, 384, -97, 363, 301, 301, 301, + -2, 335, -97, 318, -97, 318, -97, 158, -97, -97, + 158, -97, -97, 158, -97, -97, -97, 24, -97, 30, + -97, -97, -97, -97, -97, 26, -97, 335, -97, 158, + -97, -97, -97, -97, -97, 24, 24, 24, 24, 24, + 24, -97, -97, -97, -97, -97, -97, -97 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yysigned_char yypgoto[] = +{ + -97, -97, 8, 81, -56, 109, 33, -53, 74, -54, + -1, -97, -97, -96, -31, -32, -97, -97, -44, -97, + 77, -97, -97, -52, 9, -6, -97, -97, -29 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const unsigned char yytable[] = +{ + 24, 96, 26, 28, 33, 100, 49, 52, 14, 123, + 104, 106, 102, 126, 108, 60, 84, 85, 82, 43, + 48, 83, 88, 91, 94, 111, 81, 110, 24, 26, + 28, 68, 107, 24, 26, 28, 33, 86, 32, 112, + 60, 57, 41, 86, 98, 122, 88, 91, 94, 86, + 102, 124, 24, 26, 28, 115, 113, 127, 117, 0, + 0, 119, 32, 32, 32, 32, 97, 41, 41, 41, + 76, 24, 26, 28, 41, 68, 24, 26, 28, 49, + 0, 0, 23, 0, 25, 27, 114, 0, 0, 114, + 41, 43, 114, 48, 0, 0, 116, 59, 0, 118, + 0, 0, 120, 0, 0, 76, 76, 76, 114, 76, + 41, 41, 41, 0, 41, 23, 25, 27, 0, 0, + 32, 0, 59, 32, 0, 0, 32, 87, 90, 93, + 89, 92, 95, 0, 23, 25, 27, 105, 0, 0, + 41, 109, 32, 69, 70, 71, 75, 0, 0, 0, + 80, 87, 90, 93, 89, 92, 95, 0, 23, 25, + 27, 29, 2, 30, 31, 5, 6, 7, 0, 0, + 10, 121, 0, 57, 0, 0, 0, 0, 0, 0, + 58, 69, 70, 71, 0, 80, 69, 70, 71, 105, + 109, 105, 109, 105, 109, 53, 2, 54, 55, 5, + 6, 7, 8, 0, 10, 56, 0, 57, 0, 11, + 0, 12, 0, 0, 58, 77, 2, 78, 79, 37, + 6, 7, 8, 0, 10, 56, 0, 57, 0, 11, + 0, 12, 0, 0, 58, 1, 2, 3, 4, 5, + 6, 7, 8, 0, 10, 0, 0, 0, 0, 11, + 0, 12, 47, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 0, 0, 0, 0, 11, 0, 12, + 1, 2, 3, 4, 5, 6, 7, 8, 0, 10, + 0, 0, 0, 0, 11, 42, 12, 53, 2, 54, + 55, 5, 6, 7, 8, 0, 10, 86, 0, 0, + 0, 11, 0, 12, 77, 2, 78, 79, 37, 6, + 7, 8, 0, 10, 86, 0, 0, 0, 11, 0, + 12, 1, 2, 3, 4, 5, 6, 7, 8, 0, + 10, 0, 0, 0, 0, 11, 0, 12, 34, 2, + 35, 36, 37, 6, 7, 8, 0, 10, 0, 0, + 0, 0, 11, 0, 12, 29, 2, 30, 31, 5, + 6, 7, 0, 0, 10, 56, 72, 2, 73, 74, + 37, 6, 7, 0, 0, 10, 56, 29, 2, 30, + 31, 5, 6, 7, 0, 0, 10, 72, 2, 73, + 74, 37, 6, 7, 0, 0, 10 +}; + +static const yysigned_char yycheck[] = +{ + 1, 57, 3, 4, 5, 59, 12, 0, 0, 105, + 63, 64, 14, 109, 67, 16, 20, 21, 18, 11, + 12, 21, 53, 54, 55, 81, 16, 80, 29, 30, + 31, 32, 16, 34, 35, 36, 37, 13, 5, 83, + 41, 15, 9, 13, 14, 99, 77, 78, 79, 13, + 14, 107, 53, 54, 55, 87, 85, 109, 90, -1, + -1, 93, 29, 30, 31, 32, 58, 34, 35, 36, + 37, 72, 73, 74, 41, 76, 77, 78, 79, 85, + -1, -1, 1, -1, 3, 4, 87, -1, -1, 90, + 57, 83, 93, 85, -1, -1, 87, 16, -1, 90, + -1, -1, 93, -1, -1, 72, 73, 74, 109, 76, + 77, 78, 79, -1, 81, 34, 35, 36, -1, -1, + 87, -1, 41, 90, -1, -1, 93, 53, 54, 55, + 53, 54, 55, -1, 53, 54, 55, 63, -1, -1, + 107, 67, 109, 34, 35, 36, 37, -1, -1, -1, + 41, 77, 78, 79, 77, 78, 79, -1, 77, 78, + 79, 3, 4, 5, 6, 7, 8, 9, -1, -1, + 12, 97, -1, 15, -1, -1, -1, -1, -1, -1, + 22, 72, 73, 74, -1, 76, 77, 78, 79, 115, + 116, 117, 118, 119, 120, 3, 4, 5, 6, 7, + 8, 9, 10, -1, 12, 13, -1, 15, -1, 17, + -1, 19, -1, -1, 22, 3, 4, 5, 6, 7, + 8, 9, 10, -1, 12, 13, -1, 15, -1, 17, + -1, 19, -1, -1, 22, 3, 4, 5, 6, 7, + 8, 9, 10, -1, 12, -1, -1, -1, -1, 17, + -1, 19, 20, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, -1, -1, -1, -1, 17, -1, 19, + 3, 4, 5, 6, 7, 8, 9, 10, -1, 12, + -1, -1, -1, -1, 17, 18, 19, 3, 4, 5, + 6, 7, 8, 9, 10, -1, 12, 13, -1, -1, + -1, 17, -1, 19, 3, 4, 5, 6, 7, 8, + 9, 10, -1, 12, 13, -1, -1, -1, 17, -1, + 19, 3, 4, 5, 6, 7, 8, 9, 10, -1, + 12, -1, -1, -1, -1, 17, -1, 19, 3, 4, + 5, 6, 7, 8, 9, 10, -1, 12, -1, -1, + -1, -1, 17, -1, 19, 3, 4, 5, 6, 7, + 8, 9, -1, -1, 12, 13, 3, 4, 5, 6, + 7, 8, 9, -1, -1, 12, 13, 3, 4, 5, + 6, 7, 8, 9, -1, -1, 12, 3, 4, 5, + 6, 7, 8, 9, -1, -1, 12 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 17, 19, 24, 25, 26, 29, 33, 34, 35, + 39, 42, 49, 26, 33, 26, 33, 26, 33, 3, + 5, 6, 29, 33, 3, 5, 6, 7, 25, 27, + 28, 29, 18, 25, 40, 41, 48, 20, 25, 48, + 50, 51, 0, 3, 5, 6, 13, 15, 22, 26, + 33, 36, 37, 38, 43, 44, 46, 47, 33, 28, + 28, 28, 3, 5, 6, 28, 29, 3, 5, 6, + 28, 16, 18, 21, 20, 21, 13, 31, 37, 43, + 31, 37, 43, 31, 37, 43, 27, 25, 14, 31, + 32, 32, 14, 30, 30, 31, 30, 16, 30, 31, + 30, 27, 41, 51, 33, 38, 47, 38, 47, 38, + 47, 31, 32, 36, 27, 45, 36, 46 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + ((Current).first_line = (Rhs)[1].first_line, \ + (Current).first_column = (Rhs)[1].first_column, \ + (Current).last_line = (Rhs)[N].last_line, \ + (Current).last_column = (Rhs)[N].last_column) +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short int *bottom, short int *top) +#else +static void +yy_stack_print (bottom, top) + short int *bottom; + short int *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + /* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short int yyssa[YYINITDEPTH]; + short int *yyss = yyssa; + register short int *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short int *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short int *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 57 "gram.y" + { + ((SyckParser *)parser)->root = syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ); + } + break; + + case 3: +#line 61 "gram.y" + { + ((SyckParser *)parser)->root = syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ); + } + break; + + case 4: +#line 65 "gram.y" + { + ((SyckParser *)parser)->eof = 1; + } + break; + + case 8: +#line 76 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 9: +#line 81 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 10: +#line 86 "gram.y" + { + /* + * _Anchors_: The language binding must keep a separate symbol table + * for anchors. The actual ID in the symbol table is returned to the + * higher nodes, though. + */ + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData ); + } + break; + + case 11: +#line 95 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 14: +#line 105 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 15: +#line 109 "gram.y" + { + NULL_NODE( parser, n ); + yyval.nodeData = n; + } + break; + + case 16: +#line 114 "gram.y" + { + if ( ((SyckParser *)parser)->implicit_typing == 1 ) + { + try_tag_implicit( yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + } + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 17: +#line 122 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 18: +#line 127 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 19: +#line 132 "gram.y" + { + /* + * _Anchors_: The language binding must keep a separate symbol table + * for anchors. The actual ID in the symbol table is returned to the + * higher nodes, though. + */ + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData ); + } + break; + + case 26: +#line 165 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 27: +#line 170 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 28: +#line 175 "gram.y" + { + if ( ((SyckParser *)parser)->implicit_typing == 1 ) + { + try_tag_implicit( yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + } + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 29: +#line 183 "gram.y" + { + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData ); + } + break; + + case 30: +#line 187 "gram.y" + { + /* + * _Aliases_: The anchor symbol table is scanned for the anchor name. + * The anchor's ID in the language's symbol table is returned. + */ + yyval.nodeData = syck_hdlr_get_anchor( (SyckParser *)parser, yyvsp[0].name ); + } + break; + + case 31: +#line 195 "gram.y" + { + SyckNode *n = yyvsp[0].nodeData; + if ( ((SyckParser *)parser)->taguri_expansion == 1 ) + { + n->type_id = syck_taguri( YAML_DOMAIN, "str", 3 ); + } + else + { + n->type_id = syck_strndup( "str", 3 ); + } + yyval.nodeData = n; + } + break; + + case 33: +#line 209 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 39: +#line 229 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 40: +#line 233 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 41: +#line 239 "gram.y" + { + yyval.nodeId = syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ); + } + break; + + case 42: +#line 245 "gram.y" + { + syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 43: +#line 250 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 44: +#line 255 "gram.y" + { + syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 45: +#line 260 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 46: +#line 265 "gram.y" + { + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-2].name, yyvsp[0].nodeData ); + } + break; + + case 47: +#line 269 "gram.y" + { + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData ); + } + break; + + case 48: +#line 275 "gram.y" + { + yyval.nodeData = syck_new_seq( yyvsp[0].nodeId ); + } + break; + + case 49: +#line 279 "gram.y" + { + syck_seq_add( yyvsp[-2].nodeData, yyvsp[0].nodeId ); + yyval.nodeData = yyvsp[-2].nodeData; + } + break; + + case 50: +#line 284 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 51: +#line 293 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 52: +#line 297 "gram.y" + { + yyval.nodeData = syck_alloc_seq(); + } + break; + + case 53: +#line 303 "gram.y" + { + yyval.nodeData = syck_new_seq( syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) ); + } + break; + + case 54: +#line 307 "gram.y" + { + syck_seq_add( yyvsp[-2].nodeData, syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) ); + yyval.nodeData = yyvsp[-2].nodeData; + } + break; + + case 57: +#line 321 "gram.y" + { + apply_seq_in_map( (SyckParser *)parser, yyvsp[-1].nodeData ); + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 58: +#line 326 "gram.y" + { + apply_seq_in_map( (SyckParser *)parser, yyvsp[-1].nodeData ); + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 59: +#line 333 "gram.y" + { + syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 60: +#line 338 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 61: +#line 343 "gram.y" + { + syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 62: +#line 348 "gram.y" + { + syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 ); + yyval.nodeData = yyvsp[0].nodeData; + } + break; + + case 63: +#line 353 "gram.y" + { + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-2].name, yyvsp[0].nodeData ); + } + break; + + case 64: +#line 357 "gram.y" + { + yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData ); + } + break; + + case 66: +#line 364 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 68: +#line 380 "gram.y" + { + yyval.nodeData = syck_new_map( + syck_hdlr_add_node( (SyckParser *)parser, yyvsp[-2].nodeData ), + syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) ); + } + break; + + case 70: +#line 398 "gram.y" + { + if ( yyvsp[-2].nodeData->shortcut == NULL ) + { + yyvsp[-2].nodeData->shortcut = syck_new_seq( yyvsp[0].nodeId ); + } + else + { + syck_seq_add( yyvsp[-2].nodeData->shortcut, yyvsp[0].nodeId ); + } + yyval.nodeData = yyvsp[-2].nodeData; + } + break; + + case 71: +#line 410 "gram.y" + { + apply_seq_in_map( (SyckParser *)parser, yyvsp[-2].nodeData ); + syck_map_update( yyvsp[-2].nodeData, yyvsp[0].nodeData ); + syck_free_node( yyvsp[0].nodeData ); + yyvsp[0].nodeData = NULL; + yyval.nodeData = yyvsp[-2].nodeData; + } + break; + + case 72: +#line 418 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 73: +#line 427 "gram.y" + { + yyval.nodeData = syck_new_map( + syck_hdlr_add_node( (SyckParser *)parser, yyvsp[-2].nodeData ), + syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) ); + } + break; + + case 74: +#line 435 "gram.y" + { + yyval.nodeData = yyvsp[-1].nodeData; + } + break; + + case 75: +#line 439 "gram.y" + { + yyval.nodeData = syck_alloc_map(); + } + break; + + case 77: +#line 446 "gram.y" + { + syck_map_update( yyvsp[-2].nodeData, yyvsp[0].nodeData ); + syck_free_node( yyvsp[0].nodeData ); + yyvsp[0].nodeData = NULL; + yyval.nodeData = yyvsp[-2].nodeData; + } + break; + + case 78: +#line 455 "gram.y" + { + NULL_NODE( parser, n ); + yyval.nodeData = syck_new_map( + syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ), + syck_hdlr_add_node( (SyckParser *)parser, n ) ); + } + break; + + + } + +/* Line 1010 of yacc.c. */ +#line 1651 "gram.c" + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + const char* yyprefix; + char *yymsg; + int yyx; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 0; + + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); + yycount += 1; + if (yycount == 5) + { + yysize = 0; + break; + } + } + yysize += (sizeof ("syntax error, unexpected ") + + yystrlen (yytname[yytype])); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yyp = yystpcpy (yyp, yyprefix); + yyp = yystpcpy (yyp, yytname[yyx]); + yyprefix = " or "; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* If at end of input, pop the error token, + then the rest of the stack, then return failure. */ + if (yychar == YYEOF) + for (;;) + { + YYPOPSTACK; + if (yyssp == yyss) + YYABORT; + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + } + } + else + { + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + +#ifdef __GNUC__ + /* Pacify GCC when the user code never invokes YYERROR and the label + yyerrorlab therefore never appears in user code. */ + if (0) + goto yyerrorlab; +#endif + + yyvsp -= yylen; + yyssp -= yylen; + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 464 "gram.y" + + +void +apply_seq_in_map( SyckParser *parser, SyckNode *n ) +{ + long map_len; + if ( n->shortcut == NULL ) + { + return; + } + + map_len = syck_map_count( n ); + syck_map_assign( n, map_value, map_len - 1, + syck_hdlr_add_node( parser, n->shortcut ) ); + + n->shortcut = NULL; +} + + diff --git a/lib/19/syck/ext/gram.h b/lib/19/syck/ext/gram.h new file mode 100644 index 0000000000..547149ab4b --- /dev/null +++ b/lib/19/syck/ext/gram.h @@ -0,0 +1,79 @@ +/* A Bison parser, made by GNU Bison 1.875d. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + YAML_ANCHOR = 258, + YAML_ALIAS = 259, + YAML_TRANSFER = 260, + YAML_TAGURI = 261, + YAML_ITRANSFER = 262, + YAML_WORD = 263, + YAML_PLAIN = 264, + YAML_BLOCK = 265, + YAML_DOCSEP = 266, + YAML_IOPEN = 267, + YAML_INDENT = 268, + YAML_IEND = 269 + }; +#endif +#define YAML_ANCHOR 258 +#define YAML_ALIAS 259 +#define YAML_TRANSFER 260 +#define YAML_TAGURI 261 +#define YAML_ITRANSFER 262 +#define YAML_WORD 263 +#define YAML_PLAIN 264 +#define YAML_BLOCK 265 +#define YAML_DOCSEP 266 +#define YAML_IOPEN 267 +#define YAML_INDENT 268 +#define YAML_IEND 269 + + + + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 35 "gram.y" +typedef union YYSTYPE { + SYMID nodeId; + SyckNode *nodeData; + char *name; +} YYSTYPE; +/* Line 1285 of yacc.c. */ +#line 71 "gram.h" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + + + diff --git a/lib/19/syck/ext/handler.c b/lib/19/syck/ext/handler.c new file mode 100644 index 0000000000..dee5bc8196 --- /dev/null +++ b/lib/19/syck/ext/handler.c @@ -0,0 +1,173 @@ +/* + * handler.c + * + * $Author: nobu $ + * + * Copyright (C) 2003 why the lucky stiff + */ + +#include "ruby/ruby.h" +#include "syck.h" + +SYMID +syck_hdlr_add_node( SyckParser *p, SyckNode *n ) +{ + SYMID id; + + if ( ! n->id ) + { + n->id = (p->handler)( p, n ); + } + id = n->id; + + if ( n->anchor == NULL ) + { + syck_free_node( n ); + } + return id; +} + +SyckNode * +syck_hdlr_add_anchor( SyckParser *p, char *a, SyckNode *n ) +{ + SyckNode *ntmp = NULL; + + n->anchor = a; + if ( p->bad_anchors != NULL ) + { + SyckNode *bad; + if ( st_lookup( p->bad_anchors, (st_data_t)a, (void *)&bad ) ) + { + if ( n->kind != syck_str_kind ) + { + n->id = bad->id; + (p->handler)( p, n ); + } + } + } + if ( p->anchors == NULL ) + { + p->anchors = st_init_strtable(); + } + if ( st_lookup( p->anchors, (st_data_t)a, (void *)&ntmp ) ) + { + if ( ntmp != (void *)1 ) + { + syck_free_node( ntmp ); + } + } + st_insert( p->anchors, (st_data_t)a, (st_data_t)n ); + return n; +} + +void +syck_hdlr_remove_anchor( SyckParser *p, char *a ) +{ + char *atmp = a; + SyckNode *ntmp; + if ( p->anchors == NULL ) + { + p->anchors = st_init_strtable(); + } + if ( st_delete( p->anchors, (void *)&atmp, (void *)&ntmp ) ) + { + if ( ntmp != (void *)1 ) + { + syck_free_node( ntmp ); + } + } + st_insert( p->anchors, (st_data_t)a, (st_data_t)1 ); +} + +SyckNode * +syck_hdlr_get_anchor( SyckParser *p, char *a ) +{ + SyckNode *n = NULL; + + if ( p->anchors != NULL ) + { + if ( st_lookup( p->anchors, (st_data_t)a, (void *)&n ) ) + { + if ( n != (void *)1 ) + { + S_FREE( a ); + return n; + } + else + { + if ( p->bad_anchors == NULL ) + { + p->bad_anchors = st_init_strtable(); + } + if ( ! st_lookup( p->bad_anchors, (st_data_t)a, (void *)&n ) ) + { + n = (p->bad_anchor_handler)( p, a ); + st_insert( p->bad_anchors, (st_data_t)a, (st_data_t)n ); + } + } + } + } + + if ( n == NULL ) + { + n = (p->bad_anchor_handler)( p, a ); + } + + if ( n->anchor ) + { + S_FREE( a ); + } + else + { + n->anchor = a; + } + + return n; +} + +void +syck_add_transfer( char *uri, SyckNode *n, int taguri ) +{ + if ( n->type_id != NULL ) + { + S_FREE( n->type_id ); + } + + if ( taguri == 0 ) + { + n->type_id = uri; + return; + } + + n->type_id = syck_type_id_to_uri( uri ); + S_FREE( uri ); +} + +char * +syck_xprivate( const char *type_id, int type_len ) +{ + char *uri = S_ALLOC_N( char, type_len + 14 ); + uri[0] = '\0'; + strcat( uri, "x-private:" ); + strncat( uri, type_id, type_len ); + return uri; +} + +char * +syck_taguri( const char *domain, const char *type_id, int type_len ) +{ + char *uri = S_ALLOC_N( char, strlen( domain ) + type_len + 14 ); + uri[0] = '\0'; + strcat( uri, "tag:" ); + strcat( uri, domain ); + strcat( uri, ":" ); + strncat( uri, type_id, type_len ); + return uri; +} + +int +syck_try_implicit( SyckNode *n ) +{ + return 1; +} + diff --git a/lib/19/syck/ext/implicit.c b/lib/19/syck/ext/implicit.c new file mode 100644 index 0000000000..21e2cf477e --- /dev/null +++ b/lib/19/syck/ext/implicit.c @@ -0,0 +1,2990 @@ +/* Generated by re2c 0.9.10 on Mon Sep 19 21:46:50 2005 */ +#line 1 "implicit.re" +/* + * implicit.re + * + * $Author: yugui $ + * + * Copyright (C) 2003 why the lucky stiff + */ + +#include "ruby/ruby.h" +#include "syck.h" + +#define YYCTYPE char +#define YYCURSOR cursor +#define YYMARKER marker +#define YYLIMIT limit +#define YYFILL(n) (void)0 + +void +try_tag_implicit( SyckNode *n, int taguri ) +{ + const char *tid = ""; + switch ( n->kind ) + { + case syck_str_kind: + tid = syck_match_implicit( n->data.str->ptr, n->data.str->len ); + break; + + case syck_seq_kind: + tid = "seq"; + break; + + case syck_map_kind: + tid = "map"; + break; + } + if ( n->type_id != NULL ) S_FREE( n->type_id ); + if ( taguri == 1 ) + { + n->type_id = syck_taguri( YAML_DOMAIN, tid, strlen( tid ) ); + } else { + n->type_id = syck_strndup( tid, strlen( tid ) ); + } +} + +const char * +syck_match_implicit( const char *str, size_t len ) +{ + const char *cursor, *limit, *marker = 0; + cursor = str; + limit = str + len; + + +#line 55 "" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy0; + ++YYCURSOR; +yy0: + if((YYLIMIT - YYCURSOR) < 26) YYFILL(26); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy6; + case '+': goto yy16; + case '-': goto yy17; + case '.': goto yy20; + case '0': goto yy18; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy19; + case '<': goto yy22; + case '=': goto yy21; + case 'F': goto yy15; + case 'N': goto yy5; + case 'O': goto yy13; + case 'T': goto yy11; + case 'Y': goto yy9; + case 'f': goto yy14; + case 'n': goto yy4; + case 'o': goto yy12; + case 't': goto yy10; + case 'y': goto yy8; + case '~': goto yy2; + default: goto yy23; + } +yy2: ++YYCURSOR; + if((yych = *YYCURSOR) <= 0x00) goto yy6; + goto yy3; +yy3: +#line 123 "implicit.re" +{ return "str"; } +#line 100 "" +yy4: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'o': goto yy172; + case 'u': goto yy200; + default: goto yy3; + } +yy5: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'O': case 'o': goto yy172; + case 'U': goto yy195; + case 'u': goto yy196; + default: goto yy3; + } +yy6: ++YYCURSOR; + goto yy7; +yy7: +#line 85 "implicit.re" +{ return "null"; } +#line 121 "" +yy8: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'e': goto yy194; + default: goto yy3; + } +yy9: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'E': goto yy192; + case 'e': goto yy193; + default: goto yy3; + } +yy10: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'r': goto yy190; + default: goto yy3; + } +yy11: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'R': goto yy186; + case 'r': goto yy187; + default: goto yy3; + } +yy12: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'f': goto yy185; + case 'n': goto yy182; + default: goto yy3; + } +yy13: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'F': goto yy180; + case 'N': case 'n': goto yy182; + case 'f': goto yy181; + default: goto yy3; + } +yy14: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'a': goto yy177; + default: goto yy3; + } +yy15: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'A': goto yy168; + case 'a': goto yy169; + default: goto yy3; + } +yy16: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '.': goto yy167; + case '0': goto yy158; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy47; + default: goto yy3; + } +yy17: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '.': goto yy157; + case '0': goto yy158; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy47; + default: goto yy3; + } +yy18: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x00: goto yy52; + case ',': goto yy142; + case '.': goto yy50; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': goto yy140; + case '8': + case '9': goto yy141; + case ':': goto yy49; + case 'x': goto yy144; + default: goto yy3; + } +yy19: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x00: goto yy52; + case ',': goto yy47; + case '.': goto yy50; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy46; + case ':': goto yy49; + default: goto yy3; + } +yy20: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 'I': goto yy33; + case 'N': goto yy31; + case 'i': goto yy32; + case 'n': goto yy30; + default: goto yy3; + } +yy21: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy28; + goto yy3; +yy22: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '<': goto yy24; + default: goto yy3; + } +yy23: yych = *++YYCURSOR; + goto yy3; +yy24: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy26; + goto yy25; +yy25: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy3; + } +yy26: ++YYCURSOR; + goto yy27; +yy27: +#line 121 "implicit.re" +{ return "merge"; } +#line 279 "" +yy28: ++YYCURSOR; + goto yy29; +yy29: +#line 119 "implicit.re" +{ return "default"; } +#line 285 "" +yy30: yych = *++YYCURSOR; + switch(yych){ + case 'a': goto yy45; + default: goto yy25; + } +yy31: yych = *++YYCURSOR; + switch(yych){ + case 'A': goto yy40; + case 'a': goto yy41; + default: goto yy25; + } +yy32: yych = *++YYCURSOR; + switch(yych){ + case 'n': goto yy39; + default: goto yy25; + } +yy33: yych = *++YYCURSOR; + switch(yych){ + case 'N': goto yy34; + case 'n': goto yy35; + default: goto yy25; + } +yy34: yych = *++YYCURSOR; + switch(yych){ + case 'F': goto yy36; + default: goto yy25; + } +yy35: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy36; + default: goto yy25; + } +yy36: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy37; +yy37: ++YYCURSOR; + goto yy38; +yy38: +#line 105 "implicit.re" +{ return "float#inf"; } +#line 326 "" +yy39: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy36; + default: goto yy25; + } +yy40: yych = *++YYCURSOR; + switch(yych){ + case 'N': goto yy42; + default: goto yy25; + } +yy41: yych = *++YYCURSOR; + switch(yych){ + case 'N': goto yy42; + default: goto yy25; + } +yy42: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy43; +yy43: ++YYCURSOR; + goto yy44; +yy44: +#line 109 "implicit.re" +{ return "float#nan"; } +#line 350 "" +yy45: yych = *++YYCURSOR; + switch(yych){ + case 'n': goto yy42; + default: goto yy25; + } +yy46: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy74; + default: goto yy48; + } +yy47: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy48; +yy48: switch(yych){ + case 0x00: goto yy52; + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy47; + case '.': goto yy50; + case ':': goto yy49; + default: goto yy25; + } +yy49: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': goto yy66; + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy25; + } +yy50: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + goto yy51; +yy51: switch(yych){ + case 0x00: goto yy56; + case ',': goto yy54; + case '.': goto yy58; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy50; + case 'E': case 'e': goto yy60; + default: goto yy25; + } +yy52: ++YYCURSOR; + goto yy53; +yy53: +#line 97 "implicit.re" +{ return "int"; } +#line 432 "" +yy54: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy55; +yy55: switch(yych){ + case 0x00: goto yy56; + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy54; + default: goto yy25; + } +yy56: ++YYCURSOR; + goto yy57; +yy57: +#line 99 "implicit.re" +{ return "float#fix"; } +#line 456 "" +yy58: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + goto yy59; +yy59: switch(yych){ + case '.': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy58; + case 'E': case 'e': goto yy60; + default: goto yy25; + } +yy60: yych = *++YYCURSOR; + switch(yych){ + case '+': case '-': goto yy61; + default: goto yy25; + } +yy61: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy25; + goto yy63; +yy62: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy63; +yy63: switch(yych){ + case 0x00: goto yy64; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy62; + default: goto yy25; + } +yy64: ++YYCURSOR; + goto yy65; +yy65: +#line 101 "implicit.re" +{ return "float#exp"; } +#line 506 "" +yy66: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy70; + case '.': goto yy68; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + case ':': goto yy49; + default: goto yy25; + } +yy67: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy70; + case '.': goto yy68; + case ':': goto yy49; + default: goto yy25; + } +yy68: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy69; +yy69: switch(yych){ + case 0x00: goto yy72; + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy68; + default: goto yy25; + } +yy70: ++YYCURSOR; + goto yy71; +yy71: +#line 95 "implicit.re" +{ return "int#base60"; } +#line 558 "" +yy72: ++YYCURSOR; + goto yy73; +yy73: +#line 103 "implicit.re" +{ return "float#base60"; } +#line 564 "" +yy74: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy75; + default: goto yy48; + } +yy75: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy76; + default: goto yy48; + } +yy76: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy77; + default: goto yy25; + } +yy77: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy78; + default: goto yy25; + } +yy78: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy79; + default: goto yy25; + } +yy79: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy80; + default: goto yy25; + } +yy80: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy81; + default: goto yy25; + } +yy81: yych = *++YYCURSOR; + switch(yych){ + case 0x00: goto yy82; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy25; + case 'T': goto yy84; + case 't': goto yy85; + default: goto yy87; + } +yy82: ++YYCURSOR; + goto yy83; +yy83: +#line 111 "implicit.re" +{ return "timestamp#ymd"; } +#line 667 "" +yy84: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy126; + default: goto yy25; + } +yy85: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy108; + default: goto yy25; + } +yy86: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 9) YYFILL(9); + yych = *YYCURSOR; + goto yy87; +yy87: switch(yych){ + case 0x09: case ' ': goto yy86; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy88; + default: goto yy25; + } +yy88: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy89; + default: goto yy25; + } +yy89: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy90; + default: goto yy25; + } +yy90: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy91; + default: goto yy25; + } +yy91: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy92; + default: goto yy25; + } +yy92: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy93; + default: goto yy25; + } +yy93: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy94; + default: goto yy25; + } +yy94: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy95; + default: goto yy25; + } +yy95: yych = *++YYCURSOR; + switch(yych){ + case 0x09: case ' ': goto yy98; + case '.': goto yy96; + default: goto yy25; + } +yy96: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy97; +yy97: switch(yych){ + case 0x09: case ' ': goto yy98; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy96; + default: goto yy25; + } +yy98: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + goto yy99; +yy99: switch(yych){ + case 0x09: case ' ': goto yy98; + case '+': case '-': goto yy101; + case 'Z': goto yy100; + default: goto yy25; + } +yy100: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy105; + goto yy25; +yy101: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy102; + default: goto yy25; + } +yy102: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy103; + default: goto yy25; + } +yy103: yych = *++YYCURSOR; + switch(yych){ + case 0x00: goto yy105; + case ':': goto yy104; + default: goto yy25; + } +yy104: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy107; + default: goto yy25; + } +yy105: ++YYCURSOR; + goto yy106; +yy106: +#line 115 "implicit.re" +{ return "timestamp#spaced"; } +#line 884 "" +yy107: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy100; + default: goto yy25; + } +yy108: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy109; + default: goto yy25; + } +yy109: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy110; + default: goto yy25; + } +yy110: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy111; + default: goto yy25; + } +yy111: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy112; + default: goto yy25; + } +yy112: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy113; + default: goto yy25; + } +yy113: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy114; + default: goto yy25; + } +yy114: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy115; + default: goto yy25; + } +yy115: yych = *++YYCURSOR; + switch(yych){ + case '.': goto yy116; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy25; + default: goto yy117; + } +yy116: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + goto yy117; +yy117: switch(yych){ + case '+': case '-': goto yy119; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy116; + case 'Z': goto yy118; + default: goto yy25; + } +yy118: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy123; + goto yy25; +yy119: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy120; + default: goto yy25; + } +yy120: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy121; + default: goto yy25; + } +yy121: yych = *++YYCURSOR; + switch(yych){ + case 0x00: goto yy123; + case ':': goto yy122; + default: goto yy25; + } +yy122: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy125; + default: goto yy25; + } +yy123: ++YYCURSOR; + goto yy124; +yy124: +#line 113 "implicit.re" +{ return "timestamp#iso8601"; } +#line 1069 "" +yy125: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy118; + default: goto yy25; + } +yy126: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy127; + default: goto yy25; + } +yy127: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy128; + default: goto yy25; + } +yy128: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy129; + default: goto yy25; + } +yy129: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy130; + default: goto yy25; + } +yy130: yych = *++YYCURSOR; + switch(yych){ + case ':': goto yy131; + default: goto yy25; + } +yy131: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy132; + default: goto yy25; + } +yy132: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy133; + default: goto yy25; + } +yy133: yych = *++YYCURSOR; + switch(yych){ + case '.': goto yy134; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy25; + case 'Z': goto yy136; + default: goto yy135; + } +yy134: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + goto yy135; +yy135: switch(yych){ + case '+': case '-': goto yy119; + case '0': goto yy134; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy138; + case 'Z': goto yy118; + default: goto yy25; + } +yy136: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy137; +yy137: yych = *++YYCURSOR; + goto yy124; +yy138: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + goto yy139; +yy139: switch(yych){ + case '+': case '-': goto yy119; + case '0': goto yy134; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy138; + case 'Z': goto yy136; + default: goto yy25; + } +yy140: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': goto yy155; + case '8': + case '9': goto yy153; + default: goto yy143; + } +yy141: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy153; + default: goto yy152; + } +yy142: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy143; +yy143: switch(yych){ + case 0x00: goto yy149; + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': goto yy142; + case '.': goto yy50; + case '8': + case '9': goto yy151; + case ':': goto yy49; + default: goto yy25; + } +yy144: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy25; + goto yy146; +yy145: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy146; +yy146: switch(yych){ + case 0x00: goto yy147; + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': goto yy145; + default: goto yy25; + } +yy147: ++YYCURSOR; + goto yy148; +yy148: +#line 91 "implicit.re" +{ return "int#hex"; } +#line 1307 "" +yy149: ++YYCURSOR; + goto yy150; +yy150: +#line 93 "implicit.re" +{ return "int#oct"; } +#line 1313 "" +yy151: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy152; +yy152: switch(yych){ + case ',': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy151; + case '.': goto yy50; + case ':': goto yy49; + default: goto yy25; + } +yy153: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy154; + default: goto yy152; + } +yy154: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy76; + default: goto yy152; + } +yy155: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': goto yy156; + case '8': + case '9': goto yy154; + default: goto yy143; + } +yy156: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy76; + default: goto yy143; + } +yy157: yych = *++YYCURSOR; + switch(yych){ + case 'I': goto yy160; + case 'i': goto yy159; + default: goto yy25; + } +yy158: yych = *++YYCURSOR; + switch(yych){ + case 0x00: goto yy52; + case 'x': goto yy144; + default: goto yy143; + } +yy159: yych = *++YYCURSOR; + switch(yych){ + case 'n': goto yy166; + default: goto yy25; + } +yy160: yych = *++YYCURSOR; + switch(yych){ + case 'N': goto yy161; + case 'n': goto yy162; + default: goto yy25; + } +yy161: yych = *++YYCURSOR; + switch(yych){ + case 'F': goto yy163; + default: goto yy25; + } +yy162: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy163; + default: goto yy25; + } +yy163: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy164; +yy164: ++YYCURSOR; + goto yy165; +yy165: +#line 107 "implicit.re" +{ return "float#neginf"; } +#line 1412 "" +yy166: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy163; + default: goto yy25; + } +yy167: yych = *++YYCURSOR; + switch(yych){ + case 'I': goto yy33; + case 'i': goto yy32; + default: goto yy25; + } +yy168: yych = *++YYCURSOR; + switch(yych){ + case 'L': goto yy175; + default: goto yy25; + } +yy169: yych = *++YYCURSOR; + switch(yych){ + case 'l': goto yy170; + default: goto yy25; + } +yy170: yych = *++YYCURSOR; + switch(yych){ + case 's': goto yy171; + default: goto yy25; + } +yy171: yych = *++YYCURSOR; + switch(yych){ + case 'e': goto yy172; + default: goto yy25; + } +yy172: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy173; +yy173: ++YYCURSOR; + goto yy174; +yy174: +#line 89 "implicit.re" +{ return "bool#no"; } +#line 1452 "" +yy175: yych = *++YYCURSOR; + switch(yych){ + case 'S': goto yy176; + default: goto yy25; + } +yy176: yych = *++YYCURSOR; + switch(yych){ + case 'E': goto yy172; + default: goto yy25; + } +yy177: yych = *++YYCURSOR; + switch(yych){ + case 'l': goto yy178; + default: goto yy25; + } +yy178: yych = *++YYCURSOR; + switch(yych){ + case 's': goto yy179; + default: goto yy25; + } +yy179: yych = *++YYCURSOR; + switch(yych){ + case 'e': goto yy172; + default: goto yy25; + } +yy180: yych = *++YYCURSOR; + switch(yych){ + case 'F': goto yy172; + default: goto yy25; + } +yy181: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy172; + default: goto yy25; + } +yy182: yych = *++YYCURSOR; + if(yych >= 0x01) goto yy25; + goto yy183; +yy183: ++YYCURSOR; + goto yy184; +yy184: +#line 87 "implicit.re" +{ return "bool#yes"; } +#line 1496 "" +yy185: yych = *++YYCURSOR; + switch(yych){ + case 'f': goto yy172; + default: goto yy25; + } +yy186: yych = *++YYCURSOR; + switch(yych){ + case 'U': goto yy189; + default: goto yy25; + } +yy187: yych = *++YYCURSOR; + switch(yych){ + case 'u': goto yy188; + default: goto yy25; + } +yy188: yych = *++YYCURSOR; + switch(yych){ + case 'e': goto yy182; + default: goto yy25; + } +yy189: yych = *++YYCURSOR; + switch(yych){ + case 'E': goto yy182; + default: goto yy25; + } +yy190: yych = *++YYCURSOR; + switch(yych){ + case 'u': goto yy191; + default: goto yy25; + } +yy191: yych = *++YYCURSOR; + switch(yych){ + case 'e': goto yy182; + default: goto yy25; + } +yy192: yych = *++YYCURSOR; + switch(yych){ + case 'S': goto yy182; + default: goto yy25; + } +yy193: yych = *++YYCURSOR; + switch(yych){ + case 's': goto yy182; + default: goto yy25; + } +yy194: yych = *++YYCURSOR; + switch(yych){ + case 's': goto yy182; + default: goto yy25; + } +yy195: yych = *++YYCURSOR; + switch(yych){ + case 'L': goto yy199; + default: goto yy25; + } +yy196: yych = *++YYCURSOR; + switch(yych){ + case 'l': goto yy197; + default: goto yy25; + } +yy197: yych = *++YYCURSOR; + switch(yych){ + case 'l': goto yy198; + default: goto yy25; + } +yy198: yych = *++YYCURSOR; + if(yych <= 0x00) goto yy6; + goto yy25; +yy199: yych = *++YYCURSOR; + switch(yych){ + case 'L': goto yy198; + default: goto yy25; + } +yy200: yych = *++YYCURSOR; + switch(yych){ + case 'l': goto yy201; + default: goto yy25; + } +yy201: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 'l': goto yy198; + default: goto yy25; + } +} +#line 125 "implicit.re" + + +} + +/* Remove ending fragment and compare types */ +int +syck_tagcmp( const char *tag1, const char *tag2 ) +{ + if ( tag1 == tag2 ) return 1; + if ( tag1 == NULL || tag2 == NULL ) return 0; + else { + int i; + char *othorpe; + char *tmp1 = syck_strndup( tag1, strlen( tag1 ) ); + char *tmp2 = syck_strndup( tag2, strlen( tag2 ) ); + othorpe = strstr( tmp1, "#" ); + if ( othorpe != NULL ) { + othorpe[0] = '\0'; + } + othorpe = strstr( tmp2, "#" ); + if ( othorpe != NULL ) { + othorpe[0] = '\0'; + } + i = strcmp( tmp1, tmp2 ); + S_FREE( tmp1 ); S_FREE( tmp2 ); + return i; + } +} + +char * +syck_type_id_to_uri( const char *type_id ) +{ + const char *cursor, *limit, *marker = 0; + + cursor = type_id; + limit = type_id + strlen( type_id ); + + +#line 1620 "" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + goto yy202; + ++YYCURSOR; +yy202: + if((YYLIMIT - YYCURSOR) < 11) YYFILL(11); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy204; + case '!': goto yy208; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': case 'u': + case 'v': + case 'w': case 'y': + case 'z': goto yy210; + case 't': goto yy205; + case 'x': goto yy207; + default: goto yy211; + } +yy204: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy206; + } +yy205: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case ',': goto yy216; + case '-': goto yy212; + case '.': goto yy217; + case '/': goto yy218; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy214; + case 'a': goto yy246; + default: goto yy206; + } +yy206: +#line 202 "implicit.re" +{ return syck_taguri( YAML_DOMAIN, type_id, strlen( type_id ) ); } +#line 1768 "" +yy207: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case ',': case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy215; + case '-': goto yy236; + default: goto yy206; + } +yy208: ++YYCURSOR; + goto yy209; +yy209: +#line 176 "implicit.re" +{ return syck_xprivate( type_id + 1, strlen( type_id ) - 1 ); } +#line 1842 "" +yy210: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case ',': goto yy216; + case '-': goto yy212; + case '.': goto yy217; + case '/': goto yy218; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy214; + default: goto yy206; + } +yy211: yych = *++YYCURSOR; + goto yy206; +yy212: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy213; +yy213: switch(yych){ + case '-': goto yy212; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy214; + default: goto yy204; + } +yy214: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy215; +yy215: switch(yych){ + case ',': goto yy216; + case '-': goto yy212; + case '.': goto yy217; + case '/': goto yy218; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy214; + default: goto yy204; + } +yy216: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy224; + default: goto yy204; + } +yy217: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy220; + default: goto yy204; + } +yy218: ++YYCURSOR; + goto yy219; +yy219: +#line 178 "implicit.re" +{ char *domain = S_ALLOC_N( char, ( YYCURSOR - type_id ) + 15 ); + char *uri; + + domain[0] = '\0'; + strncat( domain, type_id, ( YYCURSOR - type_id ) - 1 ); + strcat( domain, "." ); + strcat( domain, YAML_DOMAIN ); + uri = syck_taguri( domain, YYCURSOR, YYLIMIT - YYCURSOR ); + + S_FREE( domain ); + return uri; + } +#line 2149 "" +yy220: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 12) YYFILL(12); + yych = *YYCURSOR; + goto yy221; +yy221: switch(yych){ + case ',': goto yy216; + case '-': goto yy222; + case '.': goto yy217; + case '/': goto yy218; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy220; + default: goto yy204; + } +yy222: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy223; +yy223: switch(yych){ + case '-': goto yy222; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy220; + default: goto yy204; + } +yy224: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy225; + default: goto yy204; + } +yy225: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy226; + default: goto yy204; + } +yy226: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy227; + default: goto yy204; + } +yy227: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy228; + case '/': goto yy229; + default: goto yy204; + } +yy228: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy231; + default: goto yy204; + } +yy229: ++YYCURSOR; + goto yy230; +yy230: +#line 191 "implicit.re" +{ char *domain = S_ALLOC_N( char, YYCURSOR - type_id ); + char *uri; + + domain[0] = '\0'; + strncat( domain, type_id, ( YYCURSOR - type_id ) - 1 ); + uri = syck_taguri( domain, YYCURSOR, YYLIMIT - YYCURSOR ); + + S_FREE( domain ); + return uri; + } +#line 2365 "" +yy231: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy232; + default: goto yy204; + } +yy232: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy233; + case '/': goto yy229; + default: goto yy204; + } +yy233: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy234; + default: goto yy204; + } +yy234: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy235; + default: goto yy204; + } +yy235: yych = *++YYCURSOR; + switch(yych){ + case '/': goto yy229; + default: goto yy204; + } +yy236: yych = *++YYCURSOR; + switch(yych){ + case 'p': goto yy237; + default: goto yy213; + } +yy237: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'r': goto yy238; + default: goto yy213; + } +yy238: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'i': goto yy239; + default: goto yy213; + } +yy239: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'v': goto yy240; + default: goto yy213; + } +yy240: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'a': goto yy241; + default: goto yy213; + } +yy241: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 't': goto yy242; + default: goto yy213; + } +yy242: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'e': goto yy243; + default: goto yy213; + } +yy243: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case ':': goto yy244; + default: goto yy213; + } +yy244: ++YYCURSOR; + goto yy245; +yy245: +#line 174 "implicit.re" +{ return syck_strndup( type_id, strlen( type_id ) ); } +#line 2485 "" +yy246: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case 'g': goto yy247; + default: goto yy213; + } +yy247: yych = *++YYCURSOR; + switch(yych){ + case ',': goto yy216; + case '.': goto yy217; + case '/': goto yy218; + case ':': goto yy248; + default: goto yy213; + } +yy248: yych = *++YYCURSOR; + switch(yych){ + case ',': + case '-': + case '.': goto yy204; + default: goto yy250; + } +yy249: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy250; +yy250: switch(yych){ + case ',': goto yy253; + case '-': goto yy251; + case '.': goto yy254; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy249; + default: goto yy204; + } +yy251: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy252; +yy252: switch(yych){ + case '-': goto yy251; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy249; + default: goto yy204; + } +yy253: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy259; + default: goto yy204; + } +yy254: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy255; + default: goto yy204; + } +yy255: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 12) YYFILL(12); + yych = *YYCURSOR; + goto yy256; +yy256: switch(yych){ + case ',': goto yy253; + case '-': goto yy257; + case '.': goto yy254; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy255; + default: goto yy204; + } +yy257: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy258; +yy258: switch(yych){ + case '-': goto yy257; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy255; + default: goto yy204; + } +yy259: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy260; + default: goto yy204; + } +yy260: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy261; + default: goto yy204; + } +yy261: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy262; + default: goto yy204; + } +yy262: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy263; + case ':': goto yy264; + default: goto yy204; + } +yy263: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy266; + default: goto yy204; + } +yy264: ++YYCURSOR; + goto yy265; +yy265: +#line 172 "implicit.re" +{ return syck_strndup( type_id, strlen( type_id ) ); } +#line 2932 "" +yy266: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy267; + default: goto yy204; + } +yy267: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy268; + case ':': goto yy264; + default: goto yy204; + } +yy268: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy269; + default: goto yy204; + } +yy269: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy270; + default: goto yy204; + } +yy270: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case ':': goto yy264; + default: goto yy204; + } +} +#line 204 "implicit.re" + + +} diff --git a/lib/19/syck/ext/mkmf.log b/lib/19/syck/ext/mkmf.log new file mode 100644 index 0000000000..45ab6d0275 --- /dev/null +++ b/lib/19/syck/ext/mkmf.log @@ -0,0 +1,15 @@ +-------------------- + +for st.h... -------------------- no + +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: +20: #include +/* end */ + +nd */ + +"gcc -E -I/source/rubinius/rubinius/vm/capi/19/include -I/source/rubinius/rubinius/vm/capi/19/include/ruby/backward -I/source/rubinius/rubinius/vm/capi/19/include -I. -ggdb3 -fPIC -O2 conftest.c -o conftest.i" +conftest.c:3:16: error: st.h: No such file or directory diff --git a/lib/19/syck/ext/node.c b/lib/19/syck/ext/node.c new file mode 100644 index 0000000000..0b8d39b6e7 --- /dev/null +++ b/lib/19/syck/ext/node.c @@ -0,0 +1,407 @@ +/* + * node.c + * + * $Author: nobu $ + * + * Copyright (C) 2003 why the lucky stiff + */ + +#include "ruby/ruby.h" +#include "syck.h" + +/* + * Node allocation functions + */ +SyckNode * +syck_alloc_node( enum syck_kind_tag type ) +{ + SyckNode *s; + + s = S_ALLOC( SyckNode ); + s->kind = type; + s->id = 0; + s->type_id = NULL; + s->anchor = NULL; + s->shortcut = NULL; + + return s; +} + +void +syck_free_node( SyckNode *n ) +{ + syck_free_members( n ); + if ( n->type_id != NULL ) + { + S_FREE( n->type_id ); + n->type_id = NULL; + } + if ( n->anchor != NULL ) + { + S_FREE( n->anchor ); + n->anchor = NULL; + } + S_FREE( n ); +} + +SyckNode * +syck_alloc_map(void) +{ + SyckNode *n; + struct SyckMap *m; + + m = S_ALLOC( struct SyckMap ); + m->style = map_none; + m->idx = 0; + m->capa = ALLOC_CT; + m->keys = S_ALLOC_N( SYMID, m->capa ); + m->values = S_ALLOC_N( SYMID, m->capa ); + + n = syck_alloc_node( syck_map_kind ); + n->data.pairs = m; + + return n; +} + +SyckNode * +syck_alloc_seq(void) +{ + SyckNode *n; + struct SyckSeq *s; + + s = S_ALLOC( struct SyckSeq ); + s->style = seq_none; + s->idx = 0; + s->capa = ALLOC_CT; + s->items = S_ALLOC_N( SYMID, s->capa ); + + n = syck_alloc_node( syck_seq_kind ); + n->data.list = s; + + return n; +} + +SyckNode * +syck_alloc_str(void) +{ + SyckNode *n; + struct SyckStr *s; + + s = S_ALLOC( struct SyckStr ); + s->len = 0; + s->ptr = NULL; + s->style = scalar_none; + + n = syck_alloc_node( syck_str_kind ); + n->data.str = s; + + return n; +} + +SyckNode * +syck_new_str( const char *str, enum scalar_style style ) +{ + return syck_new_str2( str, strlen( str ), style ); +} + +SyckNode * +syck_new_str2( const char *str, long len, enum scalar_style style ) +{ + SyckNode *n; + + n = syck_alloc_str(); + n->data.str->ptr = S_ALLOC_N( char, len + 1 ); + n->data.str->len = len; + n->data.str->style = style; + memcpy( n->data.str->ptr, str, len ); + n->data.str->ptr[len] = '\0'; + + return n; +} + +void +syck_replace_str( SyckNode *n, char *str, enum scalar_style style ) +{ + syck_replace_str2( n, str, strlen( str ), style ); +} + +void +syck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style ) +{ + if ( n->data.str->ptr != NULL ) + { + S_FREE( n->data.str->ptr ); + n->data.str->ptr = NULL; + n->data.str->len = 0; + } + n->data.str->ptr = S_ALLOC_N( char, len + 1 ); + n->data.str->len = len; + n->data.str->style = style; + memcpy( n->data.str->ptr, str, len ); + n->data.str->ptr[len] = '\0'; +} + +void +syck_str_blow_away_commas( SyckNode *n ) +{ + char *go, *end; + + go = n->data.str->ptr; + end = go + n->data.str->len; + while ( *(++go) != '\0' ) + { + if ( *go == ',' ) + { + n->data.str->len -= 1; + memmove( go, go + 1, end - go ); + end -= 1; + } + } +} + +char * +syck_str_read( SyckNode *n ) +{ + ASSERT( n != NULL ); + return n->data.str->ptr; +} + +SyckNode * +syck_new_map( SYMID key, SYMID value ) +{ + SyckNode *n; + + n = syck_alloc_map(); + syck_map_add( n, key, value ); + + return n; +} + +void +syck_map_empty( SyckNode *n ) +{ + struct SyckMap *m; + ASSERT( n != NULL ); + ASSERT( n->data.list != NULL ); + + S_FREE( n->data.pairs->keys ); + S_FREE( n->data.pairs->values ); + m = n->data.pairs; + m->idx = 0; + m->capa = ALLOC_CT; + m->keys = S_ALLOC_N( SYMID, m->capa ); + m->values = S_ALLOC_N( SYMID, m->capa ); +} + +void +syck_map_add( SyckNode *map, SYMID key, SYMID value ) +{ + struct SyckMap *m; + long idx; + + ASSERT( map != NULL ); + ASSERT( map->data.pairs != NULL ); + + m = map->data.pairs; + idx = m->idx; + m->idx += 1; + if ( m->idx > m->capa ) + { + m->capa += ALLOC_CT; + S_REALLOC_N( m->keys, SYMID, m->capa ); + S_REALLOC_N( m->values, SYMID, m->capa ); + } + m->keys[idx] = key; + m->values[idx] = value; +} + +void +syck_map_update( SyckNode *map1, SyckNode *map2 ) +{ + struct SyckMap *m1, *m2; + long new_idx, new_capa; + ASSERT( map1 != NULL ); + ASSERT( map2 != NULL ); + + m1 = map1->data.pairs; + m2 = map2->data.pairs; + if ( m2->idx < 1 ) return; + + new_idx = m1->idx; + new_idx += m2->idx; + new_capa = m1->capa; + while ( new_idx > new_capa ) + { + new_capa += ALLOC_CT; + } + if ( new_capa > m1->capa ) + { + m1->capa = new_capa; + S_REALLOC_N( m1->keys, SYMID, m1->capa ); + S_REALLOC_N( m1->values, SYMID, m1->capa ); + } + for ( new_idx = 0; new_idx < m2->idx; m1->idx++, new_idx++ ) + { + m1->keys[m1->idx] = m2->keys[new_idx]; + m1->values[m1->idx] = m2->values[new_idx]; + } +} + +long +syck_map_count( SyckNode *map ) +{ + ASSERT( map != NULL ); + ASSERT( map->data.pairs != NULL ); + return map->data.pairs->idx; +} + +void +syck_map_assign( SyckNode *map, enum map_part p, long idx, SYMID id ) +{ + struct SyckMap *m; + + ASSERT( map != NULL ); + m = map->data.pairs; + ASSERT( m != NULL ); + if ( p == map_key ) + { + m->keys[idx] = id; + } + else + { + m->values[idx] = id; + } +} + +SYMID +syck_map_read( SyckNode *map, enum map_part p, long idx ) +{ + struct SyckMap *m; + + ASSERT( map != NULL ); + m = map->data.pairs; + ASSERT( m != NULL ); + if ( p == map_key ) + { + return m->keys[idx]; + } + else + { + return m->values[idx]; + } +} + +SyckNode * +syck_new_seq( SYMID value ) +{ + SyckNode *n; + + n = syck_alloc_seq(); + syck_seq_add( n, value ); + + return n; +} + +void +syck_seq_empty( SyckNode *n ) +{ + struct SyckSeq *s; + ASSERT( n != NULL ); + ASSERT( n->data.list != NULL ); + + S_FREE( n->data.list->items ); + s = n->data.list; + s->idx = 0; + s->capa = ALLOC_CT; + s->items = S_ALLOC_N( SYMID, s->capa ); +} + +void +syck_seq_add( SyckNode *arr, SYMID value ) +{ + struct SyckSeq *s; + long idx; + + ASSERT( arr != NULL ); + ASSERT( arr->data.list != NULL ); + + s = arr->data.list; + idx = s->idx; + s->idx += 1; + if ( s->idx > s->capa ) + { + s->capa += ALLOC_CT; + S_REALLOC_N( s->items, SYMID, s->capa ); + } + s->items[idx] = value; +} + +long +syck_seq_count( SyckNode *seq ) +{ + ASSERT( seq != NULL ); + ASSERT( seq->data.list != NULL ); + return seq->data.list->idx; +} + +void +syck_seq_assign( SyckNode *seq, long idx, SYMID id ) +{ + struct SyckSeq *s; + + ASSERT( map != NULL ); + s = seq->data.list; + ASSERT( m != NULL ); + s->items[idx] = id; +} + +SYMID +syck_seq_read( SyckNode *seq, long idx ) +{ + struct SyckSeq *s; + + ASSERT( seq != NULL ); + s = seq->data.list; + ASSERT( s != NULL ); + return s->items[idx]; +} + +void +syck_free_members( SyckNode *n ) +{ + if ( n == NULL ) return; + + switch ( n->kind ) + { + case syck_str_kind: + if ( n->data.str != NULL ) + { + S_FREE( n->data.str->ptr ); + n->data.str->ptr = NULL; + n->data.str->len = 0; + S_FREE( n->data.str ); + n->data.str = NULL; + } + break; + + case syck_seq_kind: + if ( n->data.list != NULL ) + { + S_FREE( n->data.list->items ); + S_FREE( n->data.list ); + n->data.list = NULL; + } + break; + + case syck_map_kind: + if ( n->data.pairs != NULL ) + { + S_FREE( n->data.pairs->keys ); + S_FREE( n->data.pairs->values ); + S_FREE( n->data.pairs ); + n->data.pairs = NULL; + } + break; + } +} + diff --git a/lib/19/syck/ext/rubyext.c b/lib/19/syck/ext/rubyext.c new file mode 100644 index 0000000000..cd95339ac1 --- /dev/null +++ b/lib/19/syck/ext/rubyext.c @@ -0,0 +1,2324 @@ +/* -*- indent-tabs-mode: nil -*- */ +/* + * rubyext.c + * + * $Author: yugui $ + * + * Copyright (C) 2003-2005 why the lucky stiff + */ + +#include "ruby/ruby.h" +#include "ruby/encoding.h" +#include "syck.h" +#include +#include + +typedef struct RVALUE { + union { +#if 0 + struct { + unsigned long flags; /* always 0 for freed obj */ + struct RVALUE *next; + } free; +#endif + struct RBasic basic; + struct RObject object; + struct RClass klass; + /*struct RFloat flonum;*/ + /*struct RString string;*/ + struct RArray array; + /*struct RRegexp regexp;*/ + struct RHash hash; + /*struct RData data;*/ + struct RStruct rstruct; + /*struct RBignum bignum;*/ + /*struct RFile file;*/ + } as; +} RVALUE; + +typedef struct { + long hash; + char *buffer; + long length; + long remaining; + int printed; +} bytestring_t; + +#define RUBY_DOMAIN "ruby.yaml.org,2002" + +/* + * symbols and constants + */ +static ID s_new, s_utc, s_at, s_to_f, s_to_i, s_read, s_binmode, s_call, s_cmp, s_transfer, s_update, s_dup, s_haskey, s_match, s_keys, s_unpack, s_tr_bang, s_default_set, s_tag_read_class, s_tag_subclasses, s_resolver, s_push, s_emitter, s_level, s_detect_implicit, s_node_import, s_out, s_input, s_intern, s_transform, s_yaml_new, s_yaml_initialize, s_node_export, s_to_yaml, s_write, s_set_resolver, s_each; +static ID s_tags, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, s_style_set, s_value, s_value_set, s_parse; +static VALUE sym_model, sym_generic, sym_input, sym_bytecode; +static VALUE sym_scalar, sym_seq, sym_map; +static VALUE sym_1quote, sym_2quote, sym_fold, sym_literal, sym_plain, sym_inline; +static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter, cDateTime; +static VALUE oDefaultResolver, oGenericResolver; + +/* + * my private collection of numerical oddities. + */ +static double S_zero(void) { return 0.0; } +static double S_one(void) { return 1.0; } +static double S_inf(void) { return S_one() / S_zero(); } +static double S_nan(void) { return S_zero() / S_zero(); } + +static VALUE syck_node_transform( VALUE ); + +/* + * handler prototypes + */ +SYMID rb_syck_load_handler _((SyckParser *, SyckNode *)); +void rb_syck_err_handler _((SyckParser *, const char *)); +SyckNode * rb_syck_bad_anchor_handler _((SyckParser *, char *)); +void rb_syck_output_handler _((SyckEmitter *, char *, long)); +void rb_syck_emitter_handler _((SyckEmitter *, st_data_t)); +int syck_parser_assign_io _((SyckParser *, VALUE *)); +VALUE syck_scalar_alloc _((VALUE class)); +VALUE syck_seq_alloc _((VALUE class)); +VALUE syck_map_alloc _((VALUE class)); + +struct parser_xtra { + VALUE data; /* Borrowed this idea from marshal.c to fix [ruby-core:8067] problem */ + VALUE proc; + VALUE resolver; + int taint; +}; + +struct emitter_xtra { + VALUE oid; + VALUE data; + VALUE port; +}; + +/* + * Convert YAML to bytecode + */ +VALUE +rb_syck_compile(VALUE self, VALUE port) +{ + SYMID oid; + int taint; + char *ret; + VALUE bc; + bytestring_t *sav = NULL; + void *data = NULL; + + SyckParser *parser = syck_new_parser(); + taint = syck_parser_assign_io(parser, &port); + syck_parser_handler( parser, syck_yaml2byte_handler ); + syck_parser_error_handler( parser, NULL ); + syck_parser_implicit_typing( parser, 0 ); + syck_parser_taguri_expansion( parser, 0 ); + oid = syck_parse( parser ); + if (!syck_lookup_sym( parser, oid, &data )) { + rb_raise(rb_eSyntaxError, "root node <%lx> not found", oid); + } + sav = data; + + ret = S_ALLOCA_N( char, strlen( sav->buffer ) + 3 ); + ret[0] = '\0'; + strcat( ret, "D\n" ); + strcat( ret, sav->buffer ); + + syck_free_parser( parser ); + + bc = rb_str_new2( ret ); + if ( taint ) OBJ_TAINT( bc ); + return bc; +} + +/* + * read from io. + */ +long +rb_syck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip ) +{ + long len = 0; + + ASSERT( str != NULL ); + max_size -= skip; + + if ( max_size <= 0 ) max_size = 0; + else + { + /* + * call io#read. + */ + VALUE src = (VALUE)str->ptr; + VALUE n = LONG2NUM(max_size); + VALUE str2 = rb_funcall2(src, s_read, 1, &n); + if (!NIL_P(str2)) + { + StringValue(str2); + len = RSTRING_LEN(str2); + memcpy( buf + skip, RSTRING_PTR(str2), len ); + } + } + len += skip; + buf[len] = '\0'; + return len; +} + +/* + * determine: are we reading from a string or io? + * (returns tainted? boolean) + */ +int +syck_parser_assign_io(SyckParser *parser, VALUE *pport) +{ + int taint = Qtrue; + VALUE tmp, port = *pport; + if (!NIL_P(tmp = rb_check_string_type(port))) { + taint = OBJ_TAINTED(port); /* original taintedness */ + port = tmp; + syck_parser_str( parser, RSTRING_PTR(port), RSTRING_LEN(port), NULL ); + } + else if (rb_respond_to(port, s_read)) { + if (rb_respond_to(port, s_binmode)) { + rb_funcall2(port, s_binmode, 0, 0); + } + syck_parser_str( parser, (char *)port, 0, rb_syck_io_str_read ); + } + else { + rb_raise(rb_eTypeError, "instance of IO needed"); + } + *pport = port; + return taint; +} + +/* + * Get value in hash by key, forcing an empty hash if nil. + */ +VALUE +syck_get_hash_aref(VALUE hsh, VALUE key) +{ + VALUE val = rb_hash_aref( hsh, key ); + if ( NIL_P( val ) ) + { + val = rb_hash_new(); + rb_hash_aset(hsh, key, val); + } + return val; +} + +/* + * creating timestamps + */ +struct mktime_arg { + char *str; + long len; +}; + +SYMID +mktime_do(struct mktime_arg *arg) +{ + VALUE time; + char *str = arg->str; + long len = arg->len; + char *ptr = str; + VALUE year = INT2FIX(0); + VALUE mon = INT2FIX(0); + VALUE day = INT2FIX(0); + VALUE hour = INT2FIX(0); + VALUE min = INT2FIX(0); + VALUE sec = INT2FIX(0); + double usec; + + /* Year*/ + if ( ptr[0] != '\0' && len > 0 ) { + year = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Month*/ + ptr += 4; + if ( ptr[0] != '\0' && len > ptr - str ) { + while ( !ISDIGIT( *ptr ) ) ptr++; + mon = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Day*/ + ptr += 2; + if ( ptr[0] != '\0' && len > ptr - str ) { + while ( !ISDIGIT( *ptr ) ) ptr++; + day = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Hour*/ + ptr += 2; + if ( ptr[0] != '\0' && len > ptr - str ) { + while ( !ISDIGIT( *ptr ) ) ptr++; + hour = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Minute */ + ptr += 2; + if ( ptr[0] != '\0' && len > ptr - str ) { + while ( !ISDIGIT( *ptr ) ) ptr++; + min = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Second */ + ptr += 2; + if ( ptr[0] != '\0' && len > ptr - str ) { + while ( !ISDIGIT( *ptr ) ) ptr++; + sec = INT2FIX(strtol(ptr, NULL, 10)); + } + + /* Millisecond */ + ptr += 2; + if ( len > ptr - str && *ptr == '.' ) + { + char padded[] = "000000.000000"; + const int padding = 6; + const int offset = padding + 1; + const char *end = ptr + 1; + const char *begin = end; + int length; + while ( isdigit( *end ) ) end++; + length = (int)(end - begin) <= padding ? (int)(end - begin) : padding; + MEMCPY(padded, begin, char, length); + usec = strtod(padded, NULL); + } + else + { + usec = 0.0; + } + + /* Time Zone*/ + while ( len > ptr - str && *ptr != 'Z' && *ptr != '+' && *ptr != '-' && *ptr != '\0' ) ptr++; + if ( len > ptr - str && ( *ptr == '-' || *ptr == '+' ) ) + { + time_t tz_offset = strtol(ptr, NULL, 10) * 3600; + VALUE tmp; + + while ( *ptr != ':' && *ptr != '\0' ) ptr++; + if ( *ptr == ':' ) + { + ptr += 1; + if ( tz_offset < 0 ) + { + tz_offset -= strtol(ptr, NULL, 10) * 60; + } + else + { + tz_offset += strtol(ptr, NULL, 10) * 60; + } + } + + /* Make TZ time*/ + time = rb_funcall(rb_cTime, s_utc, 6, year, mon, day, hour, min, sec); + tmp = rb_funcall(time, s_to_i, 0); + tmp = rb_funcall(tmp, '-', 1, LONG2FIX(tz_offset)); + return rb_funcall(rb_cTime, s_at, 2, tmp, rb_float_new(usec)); + } + else + { + /* Make UTC time*/ + return rb_funcall(rb_cTime, s_utc, 7, year, mon, day, hour, min, sec, rb_float_new(usec)); + } +} + +SYMID +mktime_r(struct mktime_arg *arg) +{ + if (!cDateTime) { + /* + * Load Date module + */ + rb_require("date"); + cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime")); + } + return rb_funcall(cDateTime, s_parse, 1, rb_str_new(arg->str, arg->len)); +} + +SYMID +rb_syck_mktime(char *str, long len) +{ + struct mktime_arg a; + + a.str = str; + a.len = len; + return rb_rescue2(mktime_do, (VALUE)&a, mktime_r, (VALUE)&a, rb_eArgError, NULL); +} + +/* + * handles merging of an array of hashes + * (see http://www.yaml.org/type/merge/) + */ +VALUE +syck_merge_i(VALUE entry, VALUE hsh ) +{ + VALUE tmp; + if ( !NIL_P(tmp = rb_check_convert_type(entry, T_HASH, "Hash", "to_hash")) ) + { + entry = tmp; + rb_funcall( hsh, s_update, 1, entry ); + } + return Qnil; +} + +/* + * default handler for ruby.yaml.org types + */ +int +yaml_org_handler( SyckNode *n, VALUE *ref ) +{ + char *type_id = n->type_id; + int transferred = 0; + long i = 0; + VALUE obj = Qnil; + + if ( type_id != NULL && strncmp( type_id, "tag:yaml.org,2002:", 18 ) == 0 ) + { + type_id += 18; + } + + switch (n->kind) + { + case syck_str_kind: + transferred = 1; + if ( type_id == NULL ) + { + obj = rb_str_new( n->data.str->ptr, n->data.str->len ); + } + else if ( strcmp( type_id, "null" ) == 0 ) + { + obj = Qnil; + } + else if ( strcmp( type_id, "binary" ) == 0 ) + { + VALUE arr; + obj = rb_str_new( n->data.str->ptr, n->data.str->len ); + rb_funcall( obj, s_tr_bang, 2, rb_str_new2( "\n\t " ), rb_str_new2( "" ) ); + arr = rb_funcall( obj, s_unpack, 1, rb_str_new2( "m" ) ); + obj = rb_ary_shift( arr ); + } + else if ( strcmp( type_id, "bool#yes" ) == 0 ) + { + obj = Qtrue; + } + else if ( strcmp( type_id, "bool#no" ) == 0 ) + { + obj = Qfalse; + } + else if ( strcmp( type_id, "int#hex" ) == 0 ) + { + syck_str_blow_away_commas( n ); + obj = rb_cstr2inum( n->data.str->ptr, 16 ); + } + else if ( strcmp( type_id, "int#oct" ) == 0 ) + { + syck_str_blow_away_commas( n ); + obj = rb_cstr2inum( n->data.str->ptr, 8 ); + } + else if ( strcmp( type_id, "int#base60" ) == 0 ) + { + char *ptr, *end; + long sixty = 1; + long total = 0; + syck_str_blow_away_commas( n ); + ptr = n->data.str->ptr; + end = n->data.str->ptr + n->data.str->len; + while ( end > ptr ) + { + long bnum = 0; + char *colon = end - 1; + while ( colon >= ptr && *colon != ':' ) + { + colon--; + } + if ( colon >= ptr && *colon == ':' ) *colon = '\0'; + + bnum = strtol( colon + 1, NULL, 10 ); + total += bnum * sixty; + sixty *= 60; + end = colon; + } + obj = INT2FIX(total); + } + else if ( strncmp( type_id, "int", 3 ) == 0 ) + { + syck_str_blow_away_commas( n ); + obj = rb_cstr2inum( n->data.str->ptr, 10 ); + } + else if ( strcmp( type_id, "float#base60" ) == 0 ) + { + char *ptr, *end; + long sixty = 1; + double total = 0.0; + syck_str_blow_away_commas( n ); + ptr = n->data.str->ptr; + end = n->data.str->ptr + n->data.str->len; + while ( end > ptr ) + { + double bnum = 0; + char *colon = end - 1; + while ( colon >= ptr && *colon != ':' ) + { + colon--; + } + if ( colon >= ptr && *colon == ':' ) *colon = '\0'; + + bnum = strtod( colon + 1, NULL ); + total += bnum * sixty; + sixty *= 60; + end = colon; + } + obj = rb_float_new( total ); + } + else if ( strcmp( type_id, "float#nan" ) == 0 ) + { + obj = rb_float_new( S_nan() ); + } + else if ( strcmp( type_id, "float#inf" ) == 0 ) + { + obj = rb_float_new( S_inf() ); + } + else if ( strcmp( type_id, "float#neginf" ) == 0 ) + { + obj = rb_float_new( -S_inf() ); + } + else if ( strncmp( type_id, "float", 5 ) == 0 ) + { + double f; + syck_str_blow_away_commas( n ); + f = strtod( n->data.str->ptr, NULL ); + obj = rb_float_new( f ); + } + else if ( strcmp( type_id, "timestamp#iso8601" ) == 0 ) + { + obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len ); + } + else if ( strcmp( type_id, "timestamp#spaced" ) == 0 ) + { + obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len ); + } + else if ( strcmp( type_id, "timestamp#ymd" ) == 0 ) + { + char *ptr = n->data.str->ptr; + VALUE year, mon, day; + + /* Year*/ + ptr[4] = '\0'; + year = INT2FIX(strtol(ptr, NULL, 10)); + + /* Month*/ + ptr += 4; + while ( !ISDIGIT( *ptr ) ) ptr++; + mon = INT2FIX(strtol(ptr, NULL, 10)); + + /* Day*/ + ptr += 2; + while ( !ISDIGIT( *ptr ) ) ptr++; + day = INT2FIX(strtol(ptr, NULL, 10)); + + if ( !cDate ) { + /* + * Load Date module + */ + rb_require( "date" ); + cDate = rb_const_get( rb_cObject, rb_intern("Date") ); + } + + obj = rb_funcall( cDate, s_new, 3, year, mon, day ); + } + else if ( strncmp( type_id, "timestamp", 9 ) == 0 ) + { + obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len ); + } + else if ( strncmp( type_id, "merge", 5 ) == 0 ) + { + obj = rb_funcall( cMergeKey, s_new, 0 ); + } + else if ( strncmp( type_id, "default", 7 ) == 0 ) + { + obj = rb_funcall( cDefaultKey, s_new, 0 ); + } + else if ( n->data.str->style == scalar_plain && + n->data.str->len > 1 && + strncmp( n->data.str->ptr, ":", 1 ) == 0 ) + { + obj = rb_funcall( oDefaultResolver, s_transfer, 2, + rb_str_new2( "tag:ruby.yaml.org,2002:sym" ), + rb_str_new( n->data.str->ptr + 1, n->data.str->len - 1 ) ); + } + else if ( strcmp( type_id, "str" ) == 0 ) + { + obj = rb_str_new( n->data.str->ptr, n->data.str->len ); + rb_enc_associate(obj, rb_utf8_encoding()); + } + else + { + transferred = 0; + obj = rb_str_new( n->data.str->ptr, n->data.str->len ); + } + break; + + case syck_seq_kind: + if ( type_id == NULL || strcmp( type_id, "seq" ) == 0 ) + { + transferred = 1; + } + obj = rb_ary_new2( n->data.list->idx ); + for ( i = 0; i < n->data.list->idx; i++ ) + { + rb_ary_store( obj, i, syck_seq_read( n, i ) ); + } + break; + + case syck_map_kind: + if ( type_id == NULL || strcmp( type_id, "map" ) == 0 ) + { + transferred = 1; + } + obj = rb_hash_new(); + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + VALUE k = syck_map_read( n, map_key, i ); + VALUE v = syck_map_read( n, map_value, i ); + int skip_aset = 0; + + /* + * Handle merge keys + */ + if ( rb_obj_is_kind_of( k, cMergeKey ) ) + { + VALUE tmp; + if ( !NIL_P(tmp = rb_check_convert_type(v, T_HASH, "Hash", "to_hash")) ) + { + VALUE dup = rb_funcall( tmp, s_dup, 0 ); + rb_funcall( dup, s_update, 1, obj ); + obj = dup; + skip_aset = 1; + } + else if ( !NIL_P(tmp = rb_check_array_type(v)) ) + { + VALUE end = rb_ary_pop( tmp ); + VALUE tmph = rb_check_convert_type(end, T_HASH, "Hash", "to_hash"); + if ( !NIL_P(tmph) ) + { + VALUE dup = rb_funcall( tmph, s_dup, 0 ); + tmp = rb_ary_reverse( tmp ); + rb_ary_push( tmp, obj ); + rb_block_call( tmp, s_each, 0, 0, syck_merge_i, dup ); + obj = dup; + skip_aset = 1; + } + } + } + else if ( rb_obj_is_kind_of( k, cDefaultKey ) ) + { + rb_funcall( obj, s_default_set, 1, v ); + skip_aset = 1; + } + + if ( ! skip_aset ) + { + rb_hash_aset( obj, k, v ); + } + } + break; + } + + *ref = obj; + return transferred; +} + +static void syck_node_mark( SyckNode *n ); + +/* + * {native mode} node handler + * - Converts data into native Ruby types + */ +SYMID +rb_syck_load_handler(SyckParser *p, SyckNode *n) +{ + VALUE obj = Qnil; + struct parser_xtra *bonus = (struct parser_xtra *)p->bonus; + VALUE resolver = bonus->resolver; + if ( NIL_P( resolver ) ) + { + resolver = oDefaultResolver; + } + + /* + * Create node, + */ + obj = rb_funcall( resolver, s_node_import, 1, Data_Wrap_Struct( cNode, NULL, NULL, n ) ); + + /* + * ID already set, let's alter the symbol table to accept the new object + */ + if (n->id > 0 && !NIL_P(obj)) + { + MEMCPY((void *)n->id, (void *)obj, RVALUE, 1); + MEMZERO((void *)obj, RVALUE, 1); + obj = n->id; + } + + if ( bonus->taint) OBJ_TAINT( obj ); + if ( bonus->proc != 0 ) rb_funcall(bonus->proc, s_call, 1, obj); + + rb_hash_aset(bonus->data, INT2FIX(RHASH_SIZE(bonus->data)), obj); + return obj; +} + +/* + * friendly errors. + */ +void +rb_syck_err_handler(SyckParser *p, const char *msg) +{ + char *endl = p->cursor; + + while ( *endl != '\0' && *endl != '\n' ) + endl++; + + endl[0] = '\0'; + rb_raise(rb_eArgError, "%s on line %d, col %"PRIdPTRDIFF": `%s'", + msg, + p->linect, + p->cursor - p->lineptr, + p->lineptr); +} + +/* + * provide bad anchor object to the parser. + */ +SyckNode * +rb_syck_bad_anchor_handler(SyckParser *p, char *a) +{ + VALUE anchor_name = rb_str_new2( a ); + SyckNode *badanc = syck_new_map( rb_str_new2( "name" ), anchor_name ); + badanc->type_id = syck_strndup( "tag:ruby.yaml.org,2002:object:YAML::Syck::BadAlias", 53 ); + return badanc; +} + +/* + * data loaded based on the model requested. + */ +void +syck_set_model(VALUE p, VALUE input, VALUE model) +{ + SyckParser *parser; + Data_Get_Struct(p, SyckParser, parser); + syck_parser_handler( parser, rb_syck_load_handler ); + /* WARN: gonna be obsoleted soon!! */ + if ( model == sym_generic ) + { + rb_funcall( p, s_set_resolver, 1, oGenericResolver ); + } + syck_parser_implicit_typing( parser, 1 ); + syck_parser_taguri_expansion( parser, 1 ); + + if ( NIL_P( input ) ) + { + input = rb_ivar_get( p, s_input ); + } + if ( input == sym_bytecode ) + { + syck_parser_set_input_type( parser, syck_bytecode_utf8 ); + } + else + { + syck_parser_set_input_type( parser, syck_yaml_utf8 ); + } + syck_parser_error_handler( parser, rb_syck_err_handler ); + syck_parser_bad_anchor_handler( parser, rb_syck_bad_anchor_handler ); +} + +static int +syck_st_mark_nodes( char *key, SyckNode *n, char *arg ) +{ + if ( n != (void *)1 ) syck_node_mark( n ); + return ST_CONTINUE; +} + +/* + * mark parser nodes + */ +static void +syck_mark_parser(SyckParser *parser) +{ + struct parser_xtra *bonus = (struct parser_xtra *)parser->bonus; + rb_gc_mark_maybe(parser->root); + rb_gc_mark_maybe(parser->root_on_error); + rb_gc_mark( bonus->data ); + rb_gc_mark( bonus->proc ); + rb_gc_mark( bonus->resolver ); + + if ( parser->anchors != NULL ) + { + st_foreach( parser->anchors, syck_st_mark_nodes, 0 ); + } + if ( parser->bad_anchors != NULL ) + { + st_foreach( parser->bad_anchors, syck_st_mark_nodes, 0 ); + } +} + +/* + * Free the parser and any bonus attachment. + */ +void +rb_syck_free_parser(SyckParser *p) +{ + S_FREE( p->bonus ); + syck_free_parser(p); +} + +/* + * YAML::Syck::Parser.allocate + */ +VALUE syck_parser_s_alloc _((VALUE)); +VALUE +syck_parser_s_alloc(VALUE class) +{ + VALUE pobj; + SyckParser *parser = syck_new_parser(); + + parser->bonus = S_ALLOC( struct parser_xtra ); + S_MEMZERO( parser->bonus, struct parser_xtra, 1 ); + + pobj = Data_Wrap_Struct( class, syck_mark_parser, rb_syck_free_parser, parser ); + + syck_parser_set_root_on_error( parser, Qnil ); + + return pobj; +} + +/* + * YAML::Syck::Parser.initialize( resolver, options ) + */ +static VALUE +syck_parser_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE options; + if (rb_scan_args(argc, argv, "01", &options) == 0) + { + options = rb_hash_new(); + } + else + { + Check_Type(options, T_HASH); + } + rb_ivar_set(self, s_options, options); + rb_ivar_set(self, s_input, Qnil); + return self; +} + +/* + * YAML::Syck::Parser.bufsize = Integer + */ +static VALUE +syck_parser_bufsize_set(VALUE self, VALUE size) +{ + SyckParser *parser; + + if ( rb_respond_to( size, s_to_i ) ) { + int n = NUM2INT(rb_funcall(size, s_to_i, 0)); + Data_Get_Struct(self, SyckParser, parser); + parser->bufsize = n; + } + return self; +} + +/* + * YAML::Syck::Parser.bufsize => Integer + */ +static VALUE +syck_parser_bufsize_get(VALUE self) +{ + SyckParser *parser; + + Data_Get_Struct(self, SyckParser, parser); + return INT2FIX( parser->bufsize ); +} + +/* + * YAML::Syck::Parser.load( IO or String ) + */ +VALUE +syck_parser_load(int argc, VALUE *argv, VALUE self) +{ + VALUE port, proc, model, input; + SyckParser *parser; + struct parser_xtra *bonus; + + rb_scan_args(argc, argv, "11", &port, &proc); + + input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input ); + model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model ); + Data_Get_Struct(self, SyckParser, parser); + syck_set_model( self, input, model ); + + bonus = (struct parser_xtra *)parser->bonus; + bonus->taint = syck_parser_assign_io(parser, &port); + bonus->data = rb_hash_new(); + bonus->resolver = rb_attr_get( self, s_resolver ); + if ( NIL_P( proc ) ) bonus->proc = 0; + else bonus->proc = proc; + + return syck_parse( parser ); +} + +/* + * YAML::Syck::Parser.load_documents( IO or String ) { |doc| } + */ +VALUE +syck_parser_load_documents(int argc, VALUE *argv, VALUE self) +{ + VALUE port, proc, v, input, model; + SyckParser *parser; + struct parser_xtra *bonus; + + rb_scan_args(argc, argv, "1&", &port, &proc); + + input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input ); + model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model ); + Data_Get_Struct(self, SyckParser, parser); + syck_set_model( self, input, model ); + + bonus = (struct parser_xtra *)parser->bonus; + bonus->taint = syck_parser_assign_io(parser, &port); + bonus->resolver = rb_attr_get( self, s_resolver ); + bonus->proc = 0; + + while ( 1 ) + { + /* Reset hash for tracking nodes */ + bonus->data = rb_hash_new(); + + /* Parse a document */ + v = syck_parse( parser ); + if ( parser->eof == 1 ) + { + break; + } + + /* Pass document to block */ + rb_funcall( proc, s_call, 1, v ); + } + + return Qnil; +} + +/* + * YAML::Syck::Parser#set_resolver + */ +VALUE +syck_parser_set_resolver(VALUE self, VALUE resolver) +{ + rb_ivar_set( self, s_resolver, resolver ); + return self; +} + +/* + * YAML::Syck::Resolver.initialize + */ +static VALUE +syck_resolver_initialize(VALUE self) +{ + rb_ivar_set(self, s_tags, rb_hash_new()); + return self; +} + +/* + * YAML::Syck::Resolver#add_type + */ +VALUE +syck_resolver_add_type(VALUE self, VALUE taguri, VALUE cls) +{ + VALUE tags = rb_attr_get(self, s_tags); + rb_hash_aset( tags, taguri, cls ); + return Qnil; +} + +/* + * YAML::Syck::Resolver#use_types_at + */ +VALUE +syck_resolver_use_types_at(VALUE self, VALUE hsh) +{ + rb_ivar_set( self, s_tags, hsh ); + return Qnil; +} + +/* + * YAML::Syck::Resolver#detect_implicit + */ +VALUE +syck_resolver_detect_implicit(VALUE self, VALUE val) +{ + return rb_str_new2( "" ); +} + +/* + * YAML::Syck::Resolver#node_import + */ +VALUE +syck_resolver_node_import(VALUE self, VALUE node) +{ + SyckNode *n; + VALUE obj = Qnil; + int i = 0; + Data_Get_Struct(node, SyckNode, n); + + switch (n->kind) + { + case syck_str_kind: + obj = rb_str_new( n->data.str->ptr, n->data.str->len ); + break; + + case syck_seq_kind: + obj = rb_ary_new2( n->data.list->idx ); + for ( i = 0; i < n->data.list->idx; i++ ) + { + rb_ary_store( obj, i, syck_seq_read( n, i ) ); + } + break; + + case syck_map_kind: + obj = rb_hash_new(); + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + VALUE k = syck_map_read( n, map_key, i ); + VALUE v = syck_map_read( n, map_value, i ); + int skip_aset = 0; + + /* + * Handle merge keys + */ + if ( rb_obj_is_kind_of( k, cMergeKey ) ) + { + if ( rb_obj_is_kind_of( v, rb_cHash ) ) + { + VALUE dup = rb_funcall( v, s_dup, 0 ); + rb_funcall( dup, s_update, 1, obj ); + obj = dup; + skip_aset = 1; + } + else if ( rb_obj_is_kind_of( v, rb_cArray ) ) + { + VALUE end = rb_ary_pop( v ); + if ( rb_obj_is_kind_of( end, rb_cHash ) ) + { + VALUE dup = rb_funcall( end, s_dup, 0 ); + v = rb_ary_reverse( v ); + rb_ary_push( v, obj ); + rb_block_call( v, s_each, 0, 0, syck_merge_i, dup ); + obj = dup; + skip_aset = 1; + } + } + } + else if ( rb_obj_is_kind_of( k, cDefaultKey ) ) + { + rb_funcall( obj, s_default_set, 1, v ); + skip_aset = 1; + } + + if ( ! skip_aset ) + { + rb_hash_aset( obj, k, v ); + } + } + break; + } + + if ( n->type_id != NULL ) + { + obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj ); + } + return obj; +} + +/* + * Set instance variables + */ +VALUE +syck_set_ivars(VALUE vars, VALUE obj) +{ + VALUE ivname = rb_ary_entry( vars, 0 ); + char *ivn; + StringValue( ivname ); + ivn = S_ALLOCA_N( char, RSTRING_LEN(ivname) + 2 ); + ivn[0] = '@'; + ivn[1] = '\0'; + strncat( ivn, RSTRING_PTR(ivname), RSTRING_LEN(ivname) ); + rb_iv_set( obj, ivn, rb_ary_entry( vars, 1 ) ); + return Qnil; +} + +/* + * YAML::Syck::Resolver#const_find + */ +VALUE +syck_const_find(VALUE const_name) +{ + VALUE tclass = rb_cObject; + VALUE tparts = rb_str_split( const_name, "::" ); + int i = 0; + for ( i = 0; i < RARRAY_LEN(tparts); i++ ) { + VALUE tpart = rb_to_id( rb_ary_entry( tparts, i ) ); + if ( !rb_const_defined( tclass, tpart ) ) return Qnil; + tclass = rb_const_get( tclass, tpart ); + } + return tclass; +} + +/* + * YAML::Syck::Resolver#transfer + */ +VALUE +syck_resolver_transfer(VALUE self, VALUE type, VALUE val) +{ + if (NIL_P(type) || RSTRING_LEN(StringValue(type)) == 0) + { + type = rb_funcall( self, s_detect_implicit, 1, val ); + } + + if ( ! (NIL_P(type) || RSTRING_LEN(StringValue(type)) == 0) ) + { + VALUE str_xprivate = rb_str_new2( "x-private" ); + VALUE colon = rb_str_new2( ":" ); + VALUE tags = rb_attr_get(self, s_tags); + VALUE target_class = rb_hash_aref( tags, type ); + VALUE subclass = target_class; + VALUE obj = Qnil; + + /* + * Should no tag match exactly, check for subclass format + */ + if ( NIL_P( target_class ) ) + { + VALUE subclass_parts = rb_ary_new(); + VALUE parts = rb_str_split( type, ":" ); + + while ( RARRAY_LEN(parts) > 1 ) + { + VALUE partial; + rb_ary_unshift( subclass_parts, rb_ary_pop( parts ) ); + partial = rb_ary_join( parts, colon ); + target_class = rb_hash_aref( tags, partial ); + if ( NIL_P( target_class ) ) + { + rb_str_append( partial, colon ); + target_class = rb_hash_aref( tags, partial ); + } + + /* + * Possible subclass found, see if it supports subclassing + */ + if ( ! NIL_P( target_class ) ) + { + subclass = target_class; + if ( RARRAY_LEN(subclass_parts) > 0 && rb_respond_to( target_class, s_tag_subclasses ) && + RTEST( rb_funcall( target_class, s_tag_subclasses, 0 ) ) ) + { + VALUE subclass_v; + subclass = rb_ary_join( subclass_parts, colon ); + subclass = rb_funcall( target_class, s_tag_read_class, 1, subclass ); + subclass_v = syck_const_find( subclass ); + + if ( subclass_v != Qnil ) + { + subclass = subclass_v; + } + else if ( rb_cObject == target_class && subclass_v == Qnil ) + { + target_class = cYObject; + type = subclass; + subclass = cYObject; + } + else /* workaround for SEGV. real fix please */ + { + rb_raise( rb_eTypeError, "invalid subclass" ); + } + } + break; + } + } + } + + /* rb_raise(rb_eTypeError, "invalid typing scheme: %s given", + * scheme); + */ + + if ( rb_respond_to( target_class, s_call ) ) + { + obj = rb_funcall( target_class, s_call, 2, type, val ); + } + else + { + if ( rb_respond_to( target_class, s_yaml_new ) ) + { + obj = rb_funcall( target_class, s_yaml_new, 3, subclass, type, val ); + } + else if ( !NIL_P( target_class ) ) + { + if ( subclass == rb_cBignum ) + { + obj = rb_str2inum( val, 10 ); /* for yaml dumped by 1.8.3 [ruby-core:6159] */ + } + else + { + obj = rb_obj_alloc( subclass ); + } + + if ( rb_respond_to( obj, s_yaml_initialize ) ) + { + rb_funcall( obj, s_yaml_initialize, 2, type, val ); + } + else if ( !NIL_P( obj ) && rb_obj_is_instance_of( val, rb_cHash ) ) + { + rb_block_call( val, s_each, 0, 0, syck_set_ivars, obj ); + } + } + else + { + VALUE parts = rb_str_split( type, ":" ); + VALUE scheme = rb_ary_shift( parts ); + if ( rb_str_cmp( scheme, str_xprivate ) == 0 ) + { + VALUE name = rb_ary_join( parts, colon ); + obj = rb_funcall( cPrivateType, s_new, 2, name, val ); + } + else + { + VALUE domain = rb_ary_shift( parts ); + VALUE name = rb_ary_join( parts, colon ); + obj = rb_funcall( cDomainType, s_new, 3, domain, name, val ); + } + } + } + val = obj; + } + + return val; +} + +/* + * YAML::Syck::Resolver#tagurize + */ +VALUE +syck_resolver_tagurize(VALUE self, VALUE val) +{ + VALUE tmp = rb_check_string_type(val); + + if ( !NIL_P(tmp) ) + { + char *taguri = syck_type_id_to_uri( RSTRING_PTR(tmp) ); + val = rb_str_new2( taguri ); + S_FREE( taguri ); + } + + return val; +} + +/* + * YAML::Syck::DefaultResolver#detect_implicit + */ +VALUE +syck_defaultresolver_detect_implicit(VALUE self, VALUE val) +{ + const char *type_id; + VALUE tmp = rb_check_string_type(val); + + if ( !NIL_P(tmp) ) + { + val = tmp; + type_id = syck_match_implicit( RSTRING_PTR(val), RSTRING_LEN(val) ); + return rb_str_new2( type_id ); + } + + return rb_str_new2( "" ); +} + +/* + * YAML::Syck::DefaultResolver#node_import + */ +VALUE +syck_defaultresolver_node_import(VALUE self, VALUE node) +{ + SyckNode *n; + VALUE obj; + Data_Get_Struct( node, SyckNode, n ); + if ( !yaml_org_handler( n, &obj ) ) + { + obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj ); + } + return obj; +} + +/* + * YAML::Syck::GenericResolver#node_import + */ +VALUE +syck_genericresolver_node_import(VALUE self, VALUE node) +{ + SyckNode *n; + int i = 0; + VALUE t = Qnil, obj = Qnil, v = Qnil, style = Qnil; + Data_Get_Struct(node, SyckNode, n); + + if ( n->type_id != NULL ) + { + t = rb_str_new2(n->type_id); + } + + switch (n->kind) + { + case syck_str_kind: + { + v = rb_str_new( n->data.str->ptr, n->data.str->len ); + rb_enc_associate(v, rb_utf8_encoding()); + if ( n->data.str->style == scalar_1quote ) + { + style = sym_1quote; + } + else if ( n->data.str->style == scalar_2quote ) + { + style = sym_2quote; + } + else if ( n->data.str->style == scalar_fold ) + { + style = sym_fold; + } + else if ( n->data.str->style == scalar_literal ) + { + style = sym_literal; + } + else if ( n->data.str->style == scalar_plain ) + { + style = sym_plain; + } + obj = rb_funcall( cScalar, s_new, 3, t, v, style ); + } + break; + + case syck_seq_kind: + v = rb_ary_new2( syck_seq_count( n ) ); + for ( i = 0; i < syck_seq_count( n ); i++ ) + { + rb_ary_store( v, i, syck_seq_read( n, i ) ); + } + if ( n->data.list->style == seq_inline ) + { + style = sym_inline; + } + obj = rb_funcall( cSeq, s_new, 3, t, v, style ); + rb_iv_set(obj, "@kind", sym_seq); + break; + + case syck_map_kind: + v = rb_hash_new(); + for ( i = 0; i < syck_map_count( n ); i++ ) + { + rb_hash_aset( v, syck_map_read( n, map_key, i ), syck_map_read( n, map_value, i ) ); + } + if ( n->data.pairs->style == map_inline ) + { + style = sym_inline; + } + obj = rb_funcall( cMap, s_new, 3, t, v, style ); + rb_iv_set(obj, "@kind", sym_map); + break; + } + + return obj; +} + +/* + * YAML::Syck::BadAlias.initialize + */ +VALUE +syck_badalias_initialize(VALUE self, VALUE val) +{ + rb_iv_set( self, "@name", val ); + return self; +} + +/* + * YAML::Syck::BadAlias.<=> + */ +VALUE +syck_badalias_cmp(VALUE alias1, VALUE alias2) +{ + VALUE str1 = rb_ivar_get( alias1, s_name ); + VALUE str2 = rb_ivar_get( alias2, s_name ); + VALUE val = rb_funcall( str1, s_cmp, 1, str2 ); + return val; +} + +/* + * YAML::DomainType.initialize + */ +VALUE +syck_domaintype_initialize(VALUE self, VALUE domain, VALUE type_id, VALUE val) +{ + rb_iv_set( self, "@domain", domain ); + rb_iv_set( self, "@type_id", type_id ); + rb_iv_set( self, "@value", val ); + return self; +} + +/* + * YAML::Object.initialize + */ +VALUE +syck_yobject_initialize(VALUE self, VALUE klass, VALUE ivars) +{ + rb_iv_set( self, "@class", klass ); + rb_iv_set( self, "@ivars", ivars ); + return self; +} + +/* + * YAML::PrivateType.initialize + */ +VALUE +syck_privatetype_initialize(VALUE self, VALUE type_id, VALUE val) +{ + rb_iv_set( self, "@type_id", type_id ); + rb_iv_set( self, "@value", val ); + return self; +} + +/* + * Mark node contents. + */ +static void +syck_node_mark(SyckNode *n) +{ + int i; + rb_gc_mark_maybe( n->id ); + switch ( n->kind ) + { + case syck_seq_kind: + for ( i = 0; i < n->data.list->idx; i++ ) + { + rb_gc_mark( syck_seq_read( n, i ) ); + } + break; + + case syck_map_kind: + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + rb_gc_mark( syck_map_read( n, map_key, i ) ); + rb_gc_mark( syck_map_read( n, map_value, i ) ); + } + break; + + case syck_str_kind: + default: + /* nothing */ + break; + } +#if 0 /* maybe needed */ + if ( n->shortcut ) syck_node_mark( n->shortcut ); /* caution: maybe cyclic */ +#endif +} + +/* + * YAML::Syck::Scalar.allocate + */ +VALUE +syck_scalar_alloc(VALUE class) +{ + SyckNode *node = syck_alloc_str(); + VALUE obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node ); + node->id = obj; + return obj; +} + +/* + * YAML::Syck::Scalar.initialize + */ +VALUE +syck_scalar_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style) +{ + rb_iv_set( self, "@kind", sym_scalar ); + rb_funcall( self, s_type_id_set, 1, type_id ); + rb_funcall( self, s_value_set, 1, val ); + rb_funcall( self, s_style_set, 1, style ); + return self; +} + +/* + * YAML::Syck::Scalar.style= + */ +VALUE +syck_scalar_style_set(VALUE self, VALUE style) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + if ( NIL_P( style ) ) + { + node->data.str->style = scalar_none; + } + else if ( style == sym_1quote ) + { + node->data.str->style = scalar_1quote; + } + else if ( style == sym_2quote ) + { + node->data.str->style = scalar_2quote; + } + else if ( style == sym_fold ) + { + node->data.str->style = scalar_fold; + } + else if ( style == sym_literal ) + { + node->data.str->style = scalar_literal; + } + else if ( style == sym_plain ) + { + node->data.str->style = scalar_plain; + } + + rb_iv_set( self, "@style", style ); + return self; +} + +/* + * YAML::Syck::Scalar.value= + */ +VALUE +syck_scalar_value_set(VALUE self, VALUE val) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + StringValue( val ); + node->data.str->ptr = syck_strndup( RSTRING_PTR(val), RSTRING_LEN(val) ); + node->data.str->len = RSTRING_LEN(val); + node->data.str->style = scalar_none; + + rb_iv_set( self, "@value", val ); + return val; +} + +/* + * YAML::Syck::Seq.allocate + */ +VALUE +syck_seq_alloc(VALUE class) +{ + SyckNode *node; + VALUE obj; + node = syck_alloc_seq(); + obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node ); + node->id = obj; + return obj; +} + +/* + * YAML::Syck::Seq.initialize + */ +VALUE +syck_seq_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + rb_iv_set( self, "@kind", sym_seq ); + rb_funcall( self, s_type_id_set, 1, type_id ); + rb_funcall( self, s_value_set, 1, val ); + rb_funcall( self, s_style_set, 1, style ); + return self; +} + +/* + * YAML::Syck::Seq.value= + */ +VALUE +syck_seq_value_set(VALUE self, VALUE val) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + val = rb_check_array_type( val ); + if ( !NIL_P( val ) ) { + int i; + syck_seq_empty( node ); + for ( i = 0; i < RARRAY_LEN( val ); i++ ) + { + syck_seq_add( node, rb_ary_entry(val, i) ); + } + } + + rb_iv_set( self, "@value", val ); + return val; +} + +/* + * YAML::Syck::Seq.add + */ +VALUE +syck_seq_add_m(VALUE self, VALUE val) +{ + SyckNode *node; + VALUE emitter = rb_ivar_get( self, s_emitter ); + Data_Get_Struct( self, SyckNode, node ); + + if ( rb_respond_to( emitter, s_node_export ) ) { + val = rb_funcall( emitter, s_node_export, 1, val ); + } + syck_seq_add( node, val ); + rb_ary_push( rb_ivar_get( self, s_value ), val ); + + return self; +} + +/* + * YAML::Syck::Seq.style= + */ +VALUE +syck_seq_style_set(VALUE self, VALUE style) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + if ( style == sym_inline ) + { + node->data.list->style = seq_inline; + } + else + { + node->data.list->style = seq_none; + } + + rb_iv_set( self, "@style", style ); + return self; +} + +/* + * YAML::Syck::Map.allocate + */ +VALUE +syck_map_alloc(VALUE class) +{ + SyckNode *node; + VALUE obj; + node = syck_alloc_map(); + obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node ); + node->id = obj; + return obj; +} + +/* + * YAML::Syck::Map.initialize + */ +VALUE +syck_map_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + if ( !NIL_P( val ) ) + { + VALUE hsh = rb_check_convert_type(val, T_HASH, "Hash", "to_hash"); + VALUE keys; + int i; + if ( NIL_P(hsh) ) + { + rb_raise( rb_eTypeError, "wrong argument type" ); + } + + keys = rb_funcall( hsh, s_keys, 0 ); + for ( i = 0; i < RARRAY_LEN(keys); i++ ) + { + VALUE key = rb_ary_entry(keys, i); + syck_map_add( node, key, rb_hash_aref(hsh, key) ); + } + } + + rb_iv_set( self, "@kind", sym_seq ); + rb_funcall( self, s_type_id_set, 1, type_id ); + rb_funcall( self, s_value_set, 1, val ); + rb_funcall( self, s_style_set, 1, style ); + return self; +} + +/* + * YAML::Syck::Map.value= + */ +VALUE +syck_map_value_set(VALUE self, VALUE val) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + if ( !NIL_P( val ) ) + { + VALUE hsh = rb_check_convert_type(val, T_HASH, "Hash", "to_hash"); + VALUE keys; + int i; + if ( NIL_P(hsh) ) + { + rb_raise( rb_eTypeError, "wrong argument type" ); + } + + syck_map_empty( node ); + keys = rb_funcall( hsh, s_keys, 0 ); + for ( i = 0; i < RARRAY_LEN(keys); i++ ) + { + VALUE key = rb_ary_entry(keys, i); + syck_map_add( node, key, rb_hash_aref(hsh, key) ); + } + } + + rb_iv_set( self, "@value", val ); + return val; +} + +/* + * YAML::Syck::Map.add + */ +VALUE +syck_map_add_m(VALUE self, VALUE key, VALUE val) +{ + SyckNode *node; + VALUE emitter = rb_ivar_get( self, s_emitter ); + Data_Get_Struct( self, SyckNode, node ); + + if ( rb_respond_to( emitter, s_node_export ) ) { + key = rb_funcall( emitter, s_node_export, 1, key ); + val = rb_funcall( emitter, s_node_export, 1, val ); + } + syck_map_add( node, key, val ); + rb_hash_aset( rb_ivar_get( self, s_value ), key, val ); + + return self; +} + +/* + * YAML::Syck::Map.style= + */ +VALUE +syck_map_style_set(VALUE self, VALUE style) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + if ( style == sym_inline ) + { + node->data.pairs->style = map_inline; + } + else + { + node->data.pairs->style = map_none; + } + + rb_iv_set( self, "@style", style ); + return self; +} + +/* + * Cloning method for all node types + */ +VALUE +syck_node_init_copy(VALUE copy, VALUE orig) +{ + SyckNode *copy_n; + SyckNode *orig_n; + + if ( copy == orig ) + return copy; + + if ( TYPE( orig ) != T_DATA ) + { + rb_raise( rb_eTypeError, "wrong argument type" ); + } + + Data_Get_Struct( orig, SyckNode, orig_n ); + Data_Get_Struct( copy, SyckNode, copy_n ); + MEMCPY( copy_n, orig_n, SyckNode, 1 ); + return copy; +} + +/* + * YAML::Syck::Node#type_id= + */ +VALUE +syck_node_type_id_set(VALUE self, VALUE type_id) +{ + SyckNode *node; + Data_Get_Struct( self, SyckNode, node ); + + S_FREE( node->type_id ); + + if ( !NIL_P( type_id ) ) { + StringValue( type_id ); + node->type_id = syck_strndup( RSTRING_PTR(type_id), RSTRING_LEN(type_id) ); + } + + rb_iv_set( self, "@type_id", type_id ); + return type_id; +} + +/* + * YAML::Syck::Node.transform + */ +VALUE +syck_node_transform(VALUE self) +{ + VALUE t; + SyckNode *n = NULL; + SyckNode *orig_n; + Data_Get_Struct(self, SyckNode, orig_n); + t = Data_Wrap_Struct( cNode, syck_node_mark, syck_free_node, 0 ); + + switch (orig_n->kind) + { + case syck_map_kind: + { + int i; + DATA_PTR(t) = n = syck_alloc_map(); + for ( i = 0; i < orig_n->data.pairs->idx; i++ ) + { + syck_map_add( n, rb_funcall( syck_map_read( orig_n, map_key, i ), s_transform, 0 ), + rb_funcall( syck_map_read( orig_n, map_value, i ), s_transform, 0 ) ); + } + } + break; + + case syck_seq_kind: + { + int i; + DATA_PTR(t) = n = syck_alloc_seq(); + for ( i = 0; i < orig_n->data.list->idx; i++ ) + { + syck_seq_add( n, rb_funcall( syck_seq_read( orig_n, i ), s_transform, 0 ) ); + } + } + break; + + case syck_str_kind: + DATA_PTR(t) = n = syck_new_str2( orig_n->data.str->ptr, orig_n->data.str->len, orig_n->data.str->style ); + break; + } + + if ( orig_n->type_id != NULL ) + { + n->type_id = syck_strndup( orig_n->type_id, strlen( orig_n->type_id ) ); + } + if ( orig_n->anchor != NULL ) + { + n->anchor = syck_strndup( orig_n->anchor, strlen( orig_n->anchor ) ); + } + n->id = t; + return rb_funcall( oDefaultResolver, s_node_import, 1, t ); +} + +/* + * Emitter callback: assembles YAML document events from + * Ruby symbols. This is a brilliant way to do it. + * No one could possibly object. + */ +void +rb_syck_emitter_handler(SyckEmitter *e, st_data_t data) +{ + SyckNode *n; + Data_Get_Struct((VALUE)data, SyckNode, n); + + switch (n->kind) + { + case syck_map_kind: + { + int i; + syck_emit_map( e, n->type_id, n->data.pairs->style ); + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + syck_emit_item( e, syck_map_read( n, map_key, i ) ); + syck_emit_item( e, syck_map_read( n, map_value, i ) ); + } + syck_emit_end( e ); + } + break; + + case syck_seq_kind: + { + int i; + syck_emit_seq( e, n->type_id, n->data.list->style ); + for ( i = 0; i < n->data.list->idx; i++ ) + { + syck_emit_item( e, syck_seq_read( n, i ) ); + } + syck_emit_end( e ); + } + break; + + case syck_str_kind: + { + syck_emit_scalar( e, n->type_id, n->data.str->style, 0, 0, 0, n->data.str->ptr, n->data.str->len ); + } + break; + } +} + +/* + * Handle output from the emitter + */ +void +rb_syck_output_handler(SyckEmitter * emitter, char *str, long len) +{ + struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus; + VALUE dest = bonus->port; + if (TYPE(dest) == T_STRING) { + rb_str_cat( dest, str, len ); + } else { + rb_io_write( dest, rb_str_new( str, len ) ); + } +} + +/* + * Helper function for marking nodes in the anchor + * symbol table. + */ +void +syck_out_mark(VALUE emitter, VALUE node) +{ + SyckEmitter *emitterPtr; + struct emitter_xtra *bonus; + Data_Get_Struct(emitter, SyckEmitter, emitterPtr); + bonus = (struct emitter_xtra *)emitterPtr->bonus; + rb_ivar_set( node, s_emitter, emitter ); + /* syck_emitter_mark_node( emitterPtr, (st_data_t)node ); */ + if ( !NIL_P( bonus->oid ) ) { + rb_hash_aset( bonus->data, bonus->oid, node ); + } +} + +/* + * Mark emitter values. + */ +static void +syck_mark_emitter(SyckEmitter *emitter) +{ + struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus; + rb_gc_mark( bonus->oid ); + rb_gc_mark( bonus->data ); + rb_gc_mark( bonus->port ); +} + +/* + * Free the emitter and any bonus attachment. + */ +void +rb_syck_free_emitter(SyckEmitter *e) +{ + S_FREE( e->bonus ); + syck_free_emitter(e); +} + +/* + * YAML::Syck::Emitter.allocate + */ +VALUE syck_emitter_s_alloc _((VALUE)); +VALUE +syck_emitter_s_alloc(VALUE class) +{ + VALUE pobj; + SyckEmitter *emitter = syck_new_emitter(); + + emitter->bonus = S_ALLOC( struct emitter_xtra ); + S_MEMZERO( emitter->bonus, struct emitter_xtra, 1 ); + + pobj = Data_Wrap_Struct( class, syck_mark_emitter, rb_syck_free_emitter, emitter ); + syck_emitter_handler( emitter, rb_syck_emitter_handler ); + syck_output_handler( emitter, rb_syck_output_handler ); + + rb_ivar_set( pobj, s_out, rb_funcall( cOut, s_new, 1, pobj ) ); + return pobj; +} + +static VALUE +id_hash_new(void) +{ + VALUE hash; + hash = rb_hash_new(); + rb_funcall(hash, rb_intern("compare_by_identity"), 0); + return hash; +} + +/* + * YAML::Syck::Emitter.reset( options ) + */ +VALUE +syck_emitter_reset(int argc, VALUE *argv, VALUE self) +{ + VALUE options, tmp; + SyckEmitter *emitter; + struct emitter_xtra *bonus; + + Data_Get_Struct(self, SyckEmitter, emitter); + bonus = (struct emitter_xtra *)emitter->bonus; + + bonus->oid = Qnil; + bonus->port = rb_str_new2( "" ); + bonus->data = id_hash_new(); + + if (rb_scan_args(argc, argv, "01", &options) == 0) + { + options = rb_hash_new(); + rb_ivar_set(self, s_options, options); + } + else if ( !NIL_P(tmp = rb_check_string_type(options)) ) + { + bonus->port = tmp; + } + else if ( rb_respond_to( options, s_write ) ) + { + bonus->port = options; + } + else + { + Check_Type(options, T_HASH); + rb_ivar_set(self, s_options, options); + } + + emitter->headless = 0; + rb_ivar_set(self, s_level, INT2FIX(0)); + rb_ivar_set(self, s_resolver, Qnil); + return self; +} + +/* + * YAML::Syck::Emitter.emit( object_id ) { |out| ... } + */ +VALUE +syck_emitter_emit(int argc, VALUE *argv, VALUE self) +{ + VALUE oid, proc; + SyckEmitter *emitter; + struct emitter_xtra *bonus; + SYMID symple; + int level = FIX2INT(rb_ivar_get(self, s_level)) + 1; + rb_ivar_set(self, s_level, INT2FIX(level)); + + rb_scan_args(argc, argv, "1&", &oid, &proc); + Data_Get_Struct(self, SyckEmitter, emitter); + bonus = (struct emitter_xtra *)emitter->bonus; + + /* Calculate anchors, normalize nodes, build a simpler symbol table */ + bonus->oid = oid; + if ( !NIL_P( oid ) && RTEST( rb_funcall( bonus->data, s_haskey, 1, oid ) ) ) { + symple = rb_hash_aref( bonus->data, oid ); + } else { + symple = rb_funcall( proc, s_call, 1, rb_ivar_get( self, s_out ) ); + } + syck_emitter_mark_node( emitter, (st_data_t)symple ); + + /* Second pass, build emitted string */ + level -= 1; + rb_ivar_set(self, s_level, INT2FIX(level)); + if ( level == 0 ) + { + syck_emit(emitter, (st_data_t)symple); + syck_emitter_flush(emitter, 0); + + return bonus->port; + } + + return symple; +} + +/* + * YAML::Syck::Emitter#node_export + */ +VALUE +syck_emitter_node_export(VALUE self, VALUE node) +{ + return rb_funcall( node, s_to_yaml, 1, self ); +} + +/* + * YAML::Syck::Emitter#set_resolver + */ +VALUE +syck_emitter_set_resolver(VALUE self, VALUE resolver) +{ + rb_ivar_set( self, s_resolver, resolver ); + return self; +} + +/* + * YAML::Syck::Out::initialize + */ +VALUE +syck_out_initialize(VALUE self, VALUE emitter) +{ + rb_ivar_set( self, s_emitter, emitter ); + return self; +} + +/* + * YAML::Syck::Out::map + */ +VALUE +syck_out_map(int argc, VALUE *argv, VALUE self) +{ + VALUE type_id, style, map; + if (rb_scan_args(argc, argv, "11", &type_id, &style) == 1) { + style = Qnil; + } + map = rb_funcall( cMap, s_new, 3, type_id, rb_hash_new(), style ); + syck_out_mark( rb_ivar_get( self, s_emitter ), map ); + rb_yield( map ); + return map; +} + +/* + * YAML::Syck::Out::seq + */ +VALUE +syck_out_seq(int argc, VALUE *argv, VALUE self) +{ + VALUE type_id, style, seq; + if (rb_scan_args(argc, argv, "11", &type_id, &style) == 1) { + style = Qnil; + } + seq = rb_funcall( cSeq, s_new, 3, type_id, rb_ary_new(), style ); + syck_out_mark( rb_ivar_get( self, s_emitter ), seq ); + rb_yield( seq ); + return seq; +} + +/* + * YAML::Syck::Out::scalar +syck_out_scalar( self, type_id, str, style ) + VALUE self, type_id, str, style; + */ +VALUE +syck_out_scalar(int argc, VALUE *argv, VALUE self) +{ + VALUE type_id, str, style, scalar; + rb_scan_args(argc, argv, "21", &type_id, &str, &style); + scalar = rb_funcall( cScalar, s_new, 3, type_id, str, style ); + syck_out_mark( rb_ivar_get( self, s_emitter ), scalar ); + return scalar; +} + +/* + * Initialize Syck extension + */ +void +Init_syck() +{ + VALUE rb_syck = rb_define_module_under( rb_cObject, "Syck" ); + rb_define_module_function( rb_syck, "compile", rb_syck_compile, 1 ); + + /* + * Global symbols + */ + s_new = rb_intern("new"); + s_utc = rb_intern("utc"); + s_at = rb_intern("at"); + s_to_f = rb_intern("to_f"); + s_to_i = rb_intern("to_i"); + s_read = rb_intern("read"); + s_binmode = rb_intern("binmode"); + s_transfer = rb_intern("transfer"); + s_call = rb_intern("call"); + s_cmp = rb_intern("<=>"); + s_intern = rb_intern("intern"); + s_update = rb_intern("update"); + s_detect_implicit = rb_intern("detect_implicit"); + s_dup = rb_intern("dup"); + s_default_set = rb_intern("default="); + s_match = rb_intern("match"); + s_push = rb_intern("push"); + s_haskey = rb_intern("has_key?"); + s_keys = rb_intern("keys"); + s_node_import = rb_intern("node_import"); + s_tr_bang = rb_intern("tr!"); + s_unpack = rb_intern("unpack"); + s_write = rb_intern("write"); + s_tag_read_class = rb_intern( "yaml_tag_read_class" ); + s_tag_subclasses = rb_intern( "yaml_tag_subclasses?" ); + s_emitter = rb_intern( "emitter" ); + s_set_resolver = rb_intern( "set_resolver" ); + s_node_export = rb_intern( "node_export" ); + s_to_yaml = rb_intern( "to_yaml" ); + s_transform = rb_intern( "transform" ); + s_yaml_new = rb_intern("yaml_new"); + s_yaml_initialize = rb_intern("yaml_initialize"); + s_each = rb_intern("each"); + s_parse = rb_intern("parse"); + + s_tags = rb_intern("@tags"); + s_name = rb_intern("@name"); + s_options = rb_intern("@options"); + s_kind = rb_intern("@kind"); + s_type_id = rb_intern("@type_id"); + s_type_id_set = rb_intern("type_id="); + s_resolver = rb_intern("@resolver"); + s_level = rb_intern( "@level" ); + s_style = rb_intern("@style"); + s_style_set = rb_intern("style="); + s_value = rb_intern("@value"); + s_value_set = rb_intern("value="); + s_out = rb_intern("@out"); + s_input = rb_intern("@input"); + + sym_model = ID2SYM(rb_intern("Model")); + sym_generic = ID2SYM(rb_intern("Generic")); + sym_bytecode = ID2SYM(rb_intern("bytecode")); + sym_map = ID2SYM(rb_intern("map")); + sym_scalar = ID2SYM(rb_intern("scalar")); + sym_seq = ID2SYM(rb_intern("seq")); + sym_1quote = ID2SYM(rb_intern("quote1")); + sym_2quote = ID2SYM(rb_intern("quote2")); + sym_fold = ID2SYM(rb_intern("fold")); + sym_literal = ID2SYM(rb_intern("literal")); + sym_plain = ID2SYM(rb_intern("plain")); + sym_inline = ID2SYM(rb_intern("inline")); + + /* + * Define YAML::Syck::Resolver class + */ + cResolver = rb_define_class_under( rb_syck, "Resolver", rb_cObject ); + rb_define_attr( cResolver, "tags", 1, 1 ); + rb_define_method( cResolver, "initialize", syck_resolver_initialize, 0 ); + rb_define_method( cResolver, "add_type", syck_resolver_add_type, 2 ); + rb_define_method( cResolver, "use_types_at", syck_resolver_use_types_at, 1 ); + rb_define_method( cResolver, "detect_implicit", syck_resolver_detect_implicit, 1 ); + rb_define_method( cResolver, "transfer", syck_resolver_transfer, 2 ); + rb_define_method( cResolver, "node_import", syck_resolver_node_import, 1 ); + rb_define_method( cResolver, "tagurize", syck_resolver_tagurize, 1 ); + + rb_global_variable( &oDefaultResolver ); + oDefaultResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 ); + rb_define_singleton_method( oDefaultResolver, "node_import", syck_defaultresolver_node_import, 1 ); + rb_define_singleton_method( oDefaultResolver, "detect_implicit", syck_defaultresolver_detect_implicit, 1 ); + rb_define_const( rb_syck, "DefaultResolver", oDefaultResolver ); + rb_global_variable( &oGenericResolver ); + oGenericResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 ); + rb_define_singleton_method( oGenericResolver, "node_import", syck_genericresolver_node_import, 1 ); + rb_define_const( rb_syck, "GenericResolver", oGenericResolver ); + + /* + * Define YAML::Syck::Parser class + */ + cParser = rb_define_class_under( rb_syck, "Parser", rb_cObject ); + rb_define_attr( cParser, "options", 1, 1 ); + rb_define_attr( cParser, "resolver", 1, 1 ); + rb_define_attr( cParser, "input", 1, 1 ); + rb_define_alloc_func( cParser, syck_parser_s_alloc ); + rb_define_method(cParser, "initialize", syck_parser_initialize, -1 ); + rb_define_method(cParser, "bufsize=", syck_parser_bufsize_set, 1 ); + rb_define_method(cParser, "bufsize", syck_parser_bufsize_get, 0 ); + rb_define_method(cParser, "load", syck_parser_load, -1); + rb_define_method(cParser, "load_documents", syck_parser_load_documents, -1); + rb_define_method(cParser, "set_resolver", syck_parser_set_resolver, 1); + + /* + * Define YAML::Syck::Node class + */ + cNode = rb_define_class_under( rb_syck, "Node", rb_cObject ); + rb_define_method( cNode, "initialize_copy", syck_node_init_copy, 1 ); + rb_define_attr( cNode, "emitter", 1, 1 ); + rb_define_attr( cNode, "resolver", 1, 1 ); + rb_define_attr( cNode, "kind", 1, 0 ); + rb_define_attr( cNode, "type_id", 1, 0 ); + rb_define_attr( cNode, "value", 1, 0 ); + rb_define_method( cNode, "type_id=", syck_node_type_id_set, 1 ); + rb_define_method( cNode, "transform", syck_node_transform, 0); + + /* + * Define YAML::Syck::Scalar, YAML::Syck::Seq, YAML::Syck::Map -- + * all are the publicly usable variants of YAML::Syck::Node + */ + cScalar = rb_define_class_under( rb_syck, "Scalar", cNode ); + rb_define_alloc_func( cScalar, syck_scalar_alloc ); + rb_define_method( cScalar, "initialize", syck_scalar_initialize, 3 ); + rb_define_method( cScalar, "value=", syck_scalar_value_set, 1 ); + rb_define_method( cScalar, "style=", syck_scalar_style_set, 1 ); + cSeq = rb_define_class_under( rb_syck, "Seq", cNode ); + rb_define_alloc_func( cSeq, syck_seq_alloc ); + rb_define_method( cSeq, "initialize", syck_seq_initialize, 3 ); + rb_define_method( cSeq, "value=", syck_seq_value_set, 1 ); + rb_define_method( cSeq, "add", syck_seq_add_m, 1 ); + rb_define_method( cSeq, "style=", syck_seq_style_set, 1 ); + cMap = rb_define_class_under( rb_syck, "Map", cNode ); + rb_define_alloc_func( cMap, syck_map_alloc ); + rb_define_method( cMap, "initialize", syck_map_initialize, 3 ); + rb_define_method( cMap, "value=", syck_map_value_set, 1 ); + rb_define_method( cMap, "add", syck_map_add_m, 2 ); + rb_define_method( cMap, "style=", syck_map_style_set, 1 ); + + /* + * Define YAML::PrivateType class + */ + cPrivateType = rb_define_class_under( rb_syck, "PrivateType", rb_cObject ); + rb_define_attr( cPrivateType, "type_id", 1, 1 ); + rb_define_attr( cPrivateType, "value", 1, 1 ); + rb_define_method( cPrivateType, "initialize", syck_privatetype_initialize, 2); + + /* + * Define YAML::DomainType class + */ + cDomainType = rb_define_class_under( rb_syck, "DomainType", rb_cObject ); + rb_define_attr( cDomainType, "domain", 1, 1 ); + rb_define_attr( cDomainType, "type_id", 1, 1 ); + rb_define_attr( cDomainType, "value", 1, 1 ); + rb_define_method( cDomainType, "initialize", syck_domaintype_initialize, 3); + + /* + * Define YAML::Object class + */ + cYObject = rb_define_class_under( rb_syck, "Object", rb_cObject ); + rb_define_attr( cYObject, "class", 1, 1 ); + rb_define_attr( cYObject, "ivars", 1, 1 ); + rb_define_method( cYObject, "initialize", syck_yobject_initialize, 2); + rb_define_method( cYObject, "yaml_initialize", syck_yobject_initialize, 2); + + /* + * Define YAML::Syck::BadAlias class + */ + cBadAlias = rb_define_class_under( rb_syck, "BadAlias", rb_cObject ); + rb_define_attr( cBadAlias, "name", 1, 1 ); + rb_define_method( cBadAlias, "initialize", syck_badalias_initialize, 1); + rb_define_method( cBadAlias, "<=>", syck_badalias_cmp, 1); + rb_include_module( cBadAlias, rb_const_get( rb_cObject, rb_intern("Comparable") ) ); + + /* + * Define YAML::Syck::MergeKey class + */ + cMergeKey = rb_define_class_under( rb_syck, "MergeKey", rb_cObject ); + + /* + * Define YAML::Syck::DefaultKey class + */ + cDefaultKey = rb_define_class_under( rb_syck, "DefaultKey", rb_cObject ); + + /* + * Define YAML::Syck::Out classes + */ + cOut = rb_define_class_under( rb_syck, "Out", rb_cObject ); + rb_define_attr( cOut, "emitter", 1, 1 ); + rb_define_method( cOut, "initialize", syck_out_initialize, 1 ); + rb_define_method( cOut, "map", syck_out_map, -1 ); + rb_define_method( cOut, "seq", syck_out_seq, -1 ); + rb_define_method( cOut, "scalar", syck_out_scalar, -1 ); + + /* + * Define YAML::Syck::Emitter class + */ + cEmitter = rb_define_class_under( rb_syck, "Emitter", rb_cObject ); + rb_define_attr( cEmitter, "level", 1, 1 ); + rb_define_alloc_func( cEmitter, syck_emitter_s_alloc ); + rb_define_method( cEmitter, "initialize", syck_emitter_reset, -1 ); + rb_define_method( cEmitter, "reset", syck_emitter_reset, -1 ); + rb_define_method( cEmitter, "emit", syck_emitter_emit, -1 ); + rb_define_method( cEmitter, "set_resolver", syck_emitter_set_resolver, 1); + rb_define_method( cEmitter, "node_export", syck_emitter_node_export, 1); +} + diff --git a/lib/19/syck/ext/syck.c b/lib/19/syck/ext/syck.c new file mode 100644 index 0000000000..8b4947aaf8 --- /dev/null +++ b/lib/19/syck/ext/syck.c @@ -0,0 +1,524 @@ +/* + * syck.c + * + * $Author: nobu $ + * + * Copyright (C) 2003 why the lucky stiff + */ +#include "ruby/ruby.h" + +#include +#include + +#include "syck.h" + +void syck_parser_pop_level( SyckParser * ); + +/* + * Custom assert + */ +void +syck_assert( const char *file_name, unsigned line_num, const char *expr ) +{ + fflush( NULL ); + fprintf( stderr, "\nAssertion failed: %s, line %u: %s\n", + file_name, line_num, expr ); + fflush( stderr ); + abort(); +} + +/* + * Allocates and copies a string + */ +char * +syck_strndup( const char *buf, long len ) +{ + char *new = S_ALLOC_N( char, len + 1 ); + S_MEMZERO( new, char, len + 1 ); + S_MEMCPY( new, buf, char, len ); + return new; +} + +/* + * Default FILE IO function + */ +long +syck_io_file_read( char *buf, SyckIoFile *file, long max_size, long skip ) +{ + long len = 0; + + ASSERT( file != NULL ); + + max_size -= skip; + len = fread( buf + skip, sizeof( char ), max_size, file->ptr ); + len += skip; + buf[len] = '\0'; + + return len; +} + +/* + * Default string IO function + */ +long +syck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip ) +{ + char *beg; + long len = 0; + + ASSERT( str != NULL ); + beg = str->ptr; + if ( max_size >= 0 ) + { + max_size -= skip; + if ( max_size <= 0 ) max_size = 0; + else str->ptr += max_size; + + if ( str->ptr > str->end ) + { + str->ptr = str->end; + } + } + else + { + /* Use exact string length */ + while ( str->ptr < str->end ) { + if (*(str->ptr++) == '\n') break; + } + } + if ( beg < str->ptr ) + { + len = ( str->ptr - beg ); + S_MEMCPY( buf + skip, beg, char, len ); + } + len += skip; + buf[len] = '\0'; + + return len; +} + +void +syck_parser_reset_levels( SyckParser *p ) +{ + while ( p->lvl_idx > 1 ) + { + syck_parser_pop_level( p ); + } + + if ( p->lvl_idx < 1 ) + { + p->lvl_idx = 1; + p->levels[0].spaces = -1; + p->levels[0].ncount = 0; + p->levels[0].domain = syck_strndup( "", 0 ); + } + p->levels[0].status = syck_lvl_header; +} + +void +syck_parser_reset_cursor( SyckParser *p ) +{ + if ( p->buffer == NULL ) + { + p->buffer = S_ALLOC_N( char, p->bufsize ); + S_MEMZERO( p->buffer, char, p->bufsize ); + } + p->buffer[0] = '\0'; + + p->cursor = NULL; + p->lineptr = NULL; + p->linectptr = NULL; + p->token = NULL; + p->toktmp = NULL; + p->marker = NULL; + p->limit = NULL; + + p->root = 0; + p->root_on_error = 0; + p->linect = 0; + p->eof = 0; + p->last_token = 0; + p->force_token = 0; +} + +/* + * Value to return on a parse error + */ +void +syck_parser_set_root_on_error( SyckParser *p, SYMID roer ) +{ + p->root_on_error = roer; +} + +/* + * Allocate the parser + */ +SyckParser * +syck_new_parser(void) +{ + SyckParser *p; + p = S_ALLOC( SyckParser ); + S_MEMZERO( p, SyckParser, 1 ); + p->lvl_capa = ALLOC_CT; + p->levels = S_ALLOC_N( SyckLevel, p->lvl_capa ); + p->input_type = syck_yaml_utf8; + p->io_type = syck_io_str; + p->io.str = NULL; + p->syms = NULL; + p->anchors = NULL; + p->bad_anchors = NULL; + p->implicit_typing = 1; + p->taguri_expansion = 0; + p->bufsize = SYCK_BUFFERSIZE; + p->buffer = NULL; + p->lvl_idx = 0; + syck_parser_reset_levels( p ); + return p; +} + +int +syck_add_sym( SyckParser *p, void *data ) +{ + SYMID id = 0; + if ( p->syms == NULL ) + { + p->syms = st_init_numtable(); + } + id = p->syms->num_entries + 1; + st_insert( p->syms, id, (st_data_t)data ); + return id; +} + +int +syck_lookup_sym( SyckParser *p, SYMID id, void **datap ) +{ + st_data_t data; + int ret; + if ( p->syms == NULL ) return 0; + ret = st_lookup( p->syms, id, &data ); + if(ret) *datap = (void *)data; + return ret; +} + +int +syck_st_free_nodes( char *key, SyckNode *n, char *arg ) +{ + if ( n != (void *)1 ) syck_free_node( n ); + n = NULL; + return ST_CONTINUE; +} + +void +syck_st_free( SyckParser *p ) +{ + /* + * Free the anchor tables + */ + if ( p->anchors != NULL ) + { + st_foreach( p->anchors, syck_st_free_nodes, 0 ); + st_free_table( p->anchors ); + p->anchors = NULL; + } + + if ( p->bad_anchors != NULL ) + { + st_foreach( p->bad_anchors, syck_st_free_nodes, 0 ); + st_free_table( p->bad_anchors ); + p->bad_anchors = NULL; + } +} + +typedef struct { + long hash; + char *buffer; + long length; + long remaining; + int printed; +} bytestring_t; + +int +syck_st_free_syms( void *key, bytestring_t *sav, void *dummy ) +{ + S_FREE(sav->buffer); + S_FREE(sav); + return ST_CONTINUE; +} + +void +syck_free_parser( SyckParser *p ) +{ + /* + * Free the adhoc symbol table + */ + if ( p->syms != NULL ) + { + st_foreach( p->syms, syck_st_free_syms, 0 ); + st_free_table( p->syms ); + p->syms = NULL; + } + + /* + * Free tables, levels + */ + syck_st_free( p ); + syck_parser_reset_levels( p ); + S_FREE( p->levels[0].domain ); + S_FREE( p->levels ); + + if ( p->buffer != NULL ) + { + S_FREE( p->buffer ); + } + free_any_io( p ); + S_FREE( p ); +} + +void +syck_parser_handler( SyckParser *p, SyckNodeHandler hdlr ) +{ + ASSERT( p != NULL ); + p->handler = hdlr; +} + +void +syck_parser_implicit_typing( SyckParser *p, int flag ) +{ + p->implicit_typing = ( flag == 0 ? 0 : 1 ); +} + +void +syck_parser_taguri_expansion( SyckParser *p, int flag ) +{ + p->taguri_expansion = ( flag == 0 ? 0 : 1 ); +} + +void +syck_parser_error_handler( SyckParser *p, SyckErrorHandler hdlr ) +{ + ASSERT( p != NULL ); + p->error_handler = hdlr; +} + +void +syck_parser_bad_anchor_handler( SyckParser *p, SyckBadAnchorHandler hdlr ) +{ + ASSERT( p != NULL ); + p->bad_anchor_handler = hdlr; +} + +void +syck_parser_set_input_type( SyckParser *p, enum syck_parser_input input_type ) +{ + ASSERT( p != NULL ); + p->input_type = input_type; +} + +void +syck_parser_file( SyckParser *p, FILE *fp, SyckIoFileRead read ) +{ + ASSERT( p != NULL ); + free_any_io( p ); + syck_parser_reset_cursor( p ); + p->io_type = syck_io_file; + p->io.file = S_ALLOC( SyckIoFile ); + p->io.file->ptr = fp; + if ( read != NULL ) + { + p->io.file->read = read; + } + else + { + p->io.file->read = syck_io_file_read; + } +} + +void +syck_parser_str( SyckParser *p, char *ptr, long len, SyckIoStrRead read ) +{ + ASSERT( p != NULL ); + free_any_io( p ); + syck_parser_reset_cursor( p ); + p->io_type = syck_io_str; + p->io.str = S_ALLOC( SyckIoStr ); + p->io.str->beg = ptr; + p->io.str->ptr = ptr; + p->io.str->end = ptr + len; + if ( read != NULL ) + { + p->io.str->read = read; + } + else + { + p->io.str->read = syck_io_str_read; + } +} + +void +syck_parser_str_auto( SyckParser *p, char *ptr, SyckIoStrRead read ) +{ + syck_parser_str( p, ptr, strlen( ptr ), read ); +} + +SyckLevel * +syck_parser_current_level( SyckParser *p ) +{ + return &p->levels[p->lvl_idx-1]; +} + +void +syck_parser_pop_level( SyckParser *p ) +{ + ASSERT( p != NULL ); + + /* The root level should never be popped */ + if ( p->lvl_idx <= 1 ) return; + + p->lvl_idx -= 1; + free( p->levels[p->lvl_idx].domain ); +} + +void +syck_parser_add_level( SyckParser *p, int len, enum syck_level_status status ) +{ + ASSERT( p != NULL ); + if ( p->lvl_idx + 1 > p->lvl_capa ) + { + p->lvl_capa += ALLOC_CT; + S_REALLOC_N( p->levels, SyckLevel, p->lvl_capa ); + } + + ASSERT( len > p->levels[p->lvl_idx-1].spaces ); + p->levels[p->lvl_idx].spaces = len; + p->levels[p->lvl_idx].ncount = 0; + p->levels[p->lvl_idx].domain = syck_strndup( p->levels[p->lvl_idx-1].domain, strlen( p->levels[p->lvl_idx-1].domain ) ); + p->levels[p->lvl_idx].status = status; + p->lvl_idx += 1; +} + +void +free_any_io( SyckParser *p ) +{ + ASSERT( p != NULL ); + switch ( p->io_type ) + { + case syck_io_str: + if ( p->io.str != NULL ) + { + S_FREE( p->io.str ); + p->io.str = NULL; + } + break; + + case syck_io_file: + if ( p->io.file != NULL ) + { + S_FREE( p->io.file ); + p->io.file = NULL; + } + break; + } +} + +long +syck_move_tokens( SyckParser *p ) +{ + long count, skip; + ASSERT( p->buffer != NULL ); + + if ( p->token == NULL ) + return 0; + + skip = p->limit - p->token; + if ( ( count = p->token - p->buffer ) ) + { + if (skip > 0) + S_MEMMOVE( p->buffer, p->token, char, skip ); + p->token = p->buffer; + p->marker -= count; + p->cursor -= count; + p->toktmp -= count; + p->limit -= count; + p->lineptr -= count; + p->linectptr -= count; + } + return skip; +} + +void +syck_check_limit( SyckParser *p, long len ) +{ + if ( p->cursor == NULL ) + { + p->cursor = p->buffer; + p->lineptr = p->buffer; + p->linectptr = p->buffer; + p->marker = p->buffer; + } + p->limit = p->buffer + len; +} + +long +syck_parser_read( SyckParser *p ) +{ + long len = 0; + long skip = 0; + ASSERT( p != NULL ); + switch ( p->io_type ) + { + case syck_io_str: + skip = syck_move_tokens( p ); + len = (p->io.str->read)( p->buffer, p->io.str, SYCK_BUFFERSIZE - 1, skip ); + break; + + case syck_io_file: + skip = syck_move_tokens( p ); + len = (p->io.file->read)( p->buffer, p->io.file, SYCK_BUFFERSIZE - 1, skip ); + break; + } + syck_check_limit( p, len ); + return len; +} + +long +syck_parser_readlen( SyckParser *p, long max_size ) +{ + long len = 0; + long skip = 0; + ASSERT( p != NULL ); + switch ( p->io_type ) + { + case syck_io_str: + skip = syck_move_tokens( p ); + len = (p->io.str->read)( p->buffer, p->io.str, max_size, skip ); + break; + + case syck_io_file: + skip = syck_move_tokens( p ); + len = (p->io.file->read)( p->buffer, p->io.file, max_size, skip ); + break; + } + syck_check_limit( p, len ); + return len; +} + +SYMID +syck_parse( SyckParser *p ) +{ + ASSERT( p != NULL ); + + syck_st_free( p ); + syck_parser_reset_levels( p ); + syckparse( p ); + return p->root; +} + +void +syck_default_error_handler( SyckParser *p, const char *msg ) +{ + printf( "Error at [Line %d, Col %"PRIdPTRDIFF"]: %s\n", + p->linect, + p->cursor - p->lineptr, + msg ); +} + diff --git a/lib/19/syck/ext/syck.h b/lib/19/syck/ext/syck.h new file mode 100644 index 0000000000..2c9d13812d --- /dev/null +++ b/lib/19/syck/ext/syck.h @@ -0,0 +1,453 @@ +/* + * syck.h + * + * $Author: nobu $ + * + * Copyright (C) 2003 why the lucky stiff + */ + +#ifndef SYCK_H +#define SYCK_H + +#define SYCK_YAML_MAJOR 1 +#define SYCK_YAML_MINOR 0 + +#define YAML_DOMAIN "yaml.org,2002" + +#include +#include +#include +#include "ruby/st.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Memory Allocation + */ +#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__) +#include +#endif + +#if DEBUG +void syck_assert( const char *, unsigned, const char * ); +# define ASSERT(f) \ + (( f ) ? (void)0 : syck_assert( __FILE__, __LINE__, #f )) +#else +# define ASSERT(f) ((void)0) +#endif + +#ifndef NULL +# define NULL (void *)0 +#endif + +#define ALLOC_CT 8 +#define SYCK_BUFFERSIZE 4096 +#define S_ALLOC_N(type,n) (type*)malloc(sizeof(type)*(n)) +#define S_ALLOC(type) (type*)malloc(sizeof(type)) +#define S_REALLOC_N(var,type,n) (var)=(type*)realloc((char*)(var),sizeof(type)*(n)) +#define S_FREE(n) if (n) { free(n); n = NULL; } + +#define S_ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n)) + +#define S_MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n)) +#define S_MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n)) +#define S_MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n)) +#define S_MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n)) + +#define BLOCK_FOLD 10 +#define BLOCK_LIT 20 +#define BLOCK_PLAIN 30 +#define NL_CHOMP 40 +#define NL_KEEP 50 + +/* + * Node definitions + */ +#ifndef ST_DATA_T_DEFINED +typedef long st_data_t; +#endif + +#define SYMID unsigned long + +typedef struct _syck_node SyckNode; + +enum syck_kind_tag { + syck_map_kind, + syck_seq_kind, + syck_str_kind +}; + +enum map_part { + map_key, + map_value +}; + +enum map_style { + map_none, + map_inline +}; + +enum seq_style { + seq_none, + seq_inline +}; + +enum scalar_style { + scalar_none, + scalar_1quote, + scalar_2quote, + scalar_fold, + scalar_literal, + scalar_plain +}; + +/* + * Node metadata struct + */ +struct _syck_node { + /* Symbol table ID */ + SYMID id; + /* Underlying kind */ + enum syck_kind_tag kind; + /* Fully qualified tag-uri for type */ + char *type_id; + /* Anchor name */ + char *anchor; + union { + /* Storage for map data */ + struct SyckMap { + enum map_style style; + SYMID *keys; + SYMID *values; + long capa; + long idx; + } *pairs; + /* Storage for sequence data */ + struct SyckSeq { + enum seq_style style; + SYMID *items; + long capa; + long idx; + } *list; + /* Storage for string data */ + struct SyckStr { + enum scalar_style style; + char *ptr; + long len; + } *str; + } data; + /* Shortcut node */ + void *shortcut; +}; + +/* + * Parser definitions + */ +typedef struct _syck_parser SyckParser; +typedef struct _syck_file SyckIoFile; +typedef struct _syck_str SyckIoStr; +typedef struct _syck_level SyckLevel; + +typedef SYMID (*SyckNodeHandler)(SyckParser *, SyckNode *); +typedef void (*SyckErrorHandler)(SyckParser *, const char *); +typedef SyckNode * (*SyckBadAnchorHandler)(SyckParser *, char *); +typedef long (*SyckIoFileRead)(char *, SyckIoFile *, long, long); +typedef long (*SyckIoStrRead)(char *, SyckIoStr *, long, long); + +enum syck_io_type { + syck_io_str, + syck_io_file +}; + +enum syck_parser_input { + syck_yaml_utf8, + syck_yaml_utf16, + syck_yaml_utf32, + syck_bytecode_utf8 +}; + +enum syck_level_status { + syck_lvl_header, + syck_lvl_doc, + syck_lvl_open, + syck_lvl_seq, + syck_lvl_map, + syck_lvl_block, + syck_lvl_str, + syck_lvl_iseq, + syck_lvl_imap, + syck_lvl_end, + syck_lvl_pause, + syck_lvl_anctag, + syck_lvl_mapx, + syck_lvl_seqx +}; + +/* + * Parser structs + */ +struct _syck_file { + /* File pointer */ + FILE *ptr; + /* Function which FILE -> buffer */ + SyckIoFileRead read; +}; + +struct _syck_str { + /* String buffer pointers */ + char *beg, *ptr, *end; + /* Function which string -> buffer */ + SyckIoStrRead read; +}; + +struct _syck_level { + /* Indent */ + int spaces; + /* Counts nodes emitted at this level, useful for parsing + * keys and pairs in bytecode */ + int ncount; + /* Does node have anchors or tags? */ + int anctag; + /* Domain prefixing at the given level */ + char *domain; + /* Keeps a node status */ + enum syck_level_status status; +}; + +struct _syck_parser { + /* Root node */ + SYMID root, root_on_error; + /* Implicit typing flag */ + int implicit_typing, taguri_expansion; + /* Scripting language function to handle nodes */ + SyckNodeHandler handler; + /* Error handler */ + SyckErrorHandler error_handler; + /* InvalidAnchor handler */ + SyckBadAnchorHandler bad_anchor_handler; + /* Parser input type */ + enum syck_parser_input input_type; + /* IO type */ + enum syck_io_type io_type; + /* Custom buffer size */ + size_t bufsize; + /* Buffer pointers */ + char *buffer, *linectptr, *lineptr, *toktmp, *token, *cursor, *marker, *limit; + /* Line counter */ + int linect; + /* Last token from yylex() */ + int last_token; + /* Force a token upon next call to yylex() */ + int force_token; + /* EOF flag */ + int eof; + union { + SyckIoFile *file; + SyckIoStr *str; + } io; + /* Symbol table for anchors */ + st_table *anchors, *bad_anchors; + /* Optional symbol table for SYMIDs */ + st_table *syms; + /* Levels of indentation */ + SyckLevel *levels; + int lvl_idx; + int lvl_capa; + /* Pointer for extension's use */ + void *bonus; +}; + +/* + * Emitter definitions + */ +typedef struct _syck_emitter SyckEmitter; +typedef struct _syck_emitter_node SyckEmitterNode; + +typedef void (*SyckOutputHandler)(SyckEmitter *, char *, long); +typedef void (*SyckEmitterHandler)(SyckEmitter *, st_data_t); + +enum doc_stage { + doc_open, + doc_processing +}; + +/* + * Emitter struct + */ +struct _syck_emitter { + /* Headerless doc flag */ + int headless; + /* Force header? */ + int use_header; + /* Force version? */ + int use_version; + /* Sort hash keys */ + int sort_keys; + /* Anchor format */ + char *anchor_format; + /* Explicit typing on all collections? */ + int explicit_typing; + /* Best width on folded scalars */ + int best_width; + /* Use literal[1] or folded[2] blocks on all text? */ + enum scalar_style style; + /* Stage of written document */ + enum doc_stage stage; + /* Level counter */ + int level; + /* Default indentation */ + int indent; + /* Object ignore ID */ + SYMID ignore_id; + /* Symbol table for anchors */ + st_table *markers, *anchors, *anchored; + /* Custom buffer size */ + size_t bufsize; + /* Buffer */ + char *buffer, *marker; + /* Absolute position of the buffer */ + long bufpos; + /* Handler for emitter nodes */ + SyckEmitterHandler emitter_handler; + /* Handler for output */ + SyckOutputHandler output_handler; + /* Levels of indentation */ + SyckLevel *levels; + int lvl_idx; + int lvl_capa; + /* Pointer for extension's use */ + void *bonus; +}; + +/* + * Emitter node metadata struct + */ +struct _syck_emitter_node { + /* Node buffer position */ + long pos; + /* Current indent */ + long indent; + /* Collection? */ + int is_shortcut; +}; + +/* + * Handler prototypes + */ +SYMID syck_hdlr_add_node( SyckParser *, SyckNode * ); +SyckNode *syck_hdlr_add_anchor( SyckParser *, char *, SyckNode * ); +void syck_hdlr_remove_anchor( SyckParser *, char * ); +SyckNode *syck_hdlr_get_anchor( SyckParser *, char * ); +void syck_add_transfer( char *, SyckNode *, int ); +char *syck_xprivate( const char *, int ); +char *syck_taguri( const char *, const char *, int ); +int syck_tagcmp( const char *, const char * ); +int syck_add_sym( SyckParser *, void * ); +int syck_lookup_sym( SyckParser *, SYMID, void ** ); +int syck_try_implicit( SyckNode * ); +char *syck_type_id_to_uri( const char * ); +void try_tag_implicit( SyckNode *, int ); +const char *syck_match_implicit( const char *, size_t ); + +/* + * API prototypes + */ +char *syck_strndup( const char *, long ); +long syck_io_file_read( char *, SyckIoFile *, long, long ); +long syck_io_str_read( char *, SyckIoStr *, long, long ); +char *syck_base64enc( char *, long ); +char *syck_base64dec( char *, long ); +SyckEmitter *syck_new_emitter(void); +SYMID syck_emitter_mark_node( SyckEmitter *, st_data_t ); +void syck_emitter_ignore_id( SyckEmitter *, SYMID ); +void syck_output_handler( SyckEmitter *, SyckOutputHandler ); +void syck_emitter_handler( SyckEmitter *, SyckEmitterHandler ); +void syck_free_emitter( SyckEmitter * ); +void syck_emitter_clear( SyckEmitter * ); +void syck_emitter_write( SyckEmitter *, const char *, long ); +void syck_emitter_escape( SyckEmitter *, const char *, long ); +void syck_emitter_flush( SyckEmitter *, long ); +void syck_emit( SyckEmitter *, st_data_t ); +void syck_emit_scalar( SyckEmitter *, const char *, enum scalar_style, int, int, char, const char *, long ); +void syck_emit_1quoted( SyckEmitter *, int, const char *, long ); +void syck_emit_2quoted( SyckEmitter *, int, const char *, long ); +void syck_emit_folded( SyckEmitter *, int, char, const char *, long ); +void syck_emit_literal( SyckEmitter *, char, const char *, long ); +void syck_emit_seq( SyckEmitter *, const char *, enum seq_style ); +void syck_emit_item( SyckEmitter *, st_data_t ); +void syck_emit_map( SyckEmitter *, const char *, enum map_style ); +void syck_emit_end( SyckEmitter * ); +void syck_emit_tag( SyckEmitter *, const char *, const char * ); +void syck_emit_indent( SyckEmitter * ); +SyckLevel *syck_emitter_current_level( SyckEmitter * ); +SyckLevel *syck_emitter_parent_level( SyckEmitter * ); +void syck_emitter_pop_level( SyckEmitter * ); +void syck_emitter_add_level( SyckEmitter *, int, enum syck_level_status ); +void syck_emitter_reset_levels( SyckEmitter * ); +SyckParser *syck_new_parser(void); +void syck_free_parser( SyckParser * ); +void syck_parser_set_root_on_error( SyckParser *, SYMID ); +void syck_parser_implicit_typing( SyckParser *, int ); +void syck_parser_taguri_expansion( SyckParser *, int ); +int syck_scan_scalar( int, const char *, long ); +void syck_parser_handler( SyckParser *, SyckNodeHandler ); +void syck_parser_error_handler( SyckParser *, SyckErrorHandler ); +void syck_parser_bad_anchor_handler( SyckParser *, SyckBadAnchorHandler ); +void syck_parser_set_input_type( SyckParser *, enum syck_parser_input ); +void syck_parser_file( SyckParser *, FILE *, SyckIoFileRead ); +void syck_parser_str( SyckParser *, char *, long, SyckIoStrRead ); +void syck_parser_str_auto( SyckParser *, char *, SyckIoStrRead ); +SyckLevel *syck_parser_current_level( SyckParser * ); +void syck_parser_add_level( SyckParser *, int, enum syck_level_status ); +void syck_parser_pop_level( SyckParser * ); +void free_any_io( SyckParser * ); +long syck_parser_read( SyckParser * ); +long syck_parser_readlen( SyckParser *, long ); +SYMID syck_parse( SyckParser * ); +void syck_default_error_handler( SyckParser *, const char * ); +SYMID syck_yaml2byte_handler( SyckParser *, SyckNode * ); +char *syck_yaml2byte( char * ); + +/* + * Allocation prototypes + */ +SyckNode *syck_alloc_map(void); +SyckNode *syck_alloc_seq(void); +SyckNode *syck_alloc_str(void); +void syck_free_node( SyckNode * ); +void syck_free_members( SyckNode * ); +SyckNode *syck_new_str( const char *, enum scalar_style ); +SyckNode *syck_new_str2( const char *, long, enum scalar_style ); +void syck_replace_str( SyckNode *, char *, enum scalar_style ); +void syck_replace_str2( SyckNode *, char *, long, enum scalar_style ); +void syck_str_blow_away_commas( SyckNode * ); +char *syck_str_read( SyckNode * ); +SyckNode *syck_new_map( SYMID, SYMID ); +void syck_map_empty( SyckNode * ); +void syck_map_add( SyckNode *, SYMID, SYMID ); +SYMID syck_map_read( SyckNode *, enum map_part, long ); +void syck_map_assign( SyckNode *, enum map_part, long, SYMID ); +long syck_map_count( SyckNode * ); +void syck_map_update( SyckNode *, SyckNode * ); +SyckNode *syck_new_seq( SYMID ); +void syck_seq_empty( SyckNode * ); +void syck_seq_add( SyckNode *, SYMID ); +void syck_seq_assign( SyckNode *, long, SYMID ); +SYMID syck_seq_read( SyckNode *, long ); +long syck_seq_count( SyckNode * ); + +/* + * Lexer prototypes + */ +void syckerror( const char * ); +int syckparse( void * ); +union YYSTYPE; +int sycklex( union YYSTYPE *, SyckParser * ); + +#if defined(__cplusplus) +} /* extern "C" { */ +#endif + +#endif /* ifndef SYCK_H */ diff --git a/lib/19/syck/ext/token.c b/lib/19/syck/ext/token.c new file mode 100644 index 0000000000..cca5dbff31 --- /dev/null +++ b/lib/19/syck/ext/token.c @@ -0,0 +1,2724 @@ +/* Generated by re2c 0.9.10 on Tue Sep 20 17:46:17 2005 */ +#line 1 "token.re" +/* + * token.re + * + * $Author: nobu $ + * + * Copyright (C) 2003 why the lucky stiff + */ +#include "ruby/ruby.h" +#include "syck.h" +#include "gram.h" + +/* + * Allocate quoted strings in chunks + */ +#define QUOTELEN 1024 + +/* + * They do my bidding... + */ +#define YYCTYPE char +#define YYCURSOR parser->cursor +#define YYMARKER parser->marker +#define YYLIMIT parser->limit +#define YYTOKEN parser->token +#define YYTOKTMP parser->toktmp +#define YYLINEPTR parser->lineptr +#define YYLINECTPTR parser->linectptr +#define YYLINE parser->linect +#define YYFILL(n) syck_parser_read(parser) + +/* + * Repositions the cursor at `n' offset from the token start. + * Only works in `Header' and `Document' sections. + */ +#define YYPOS(n) YYCURSOR = YYTOKEN + n + +/* + * Track line numbers + */ +#define NEWLINE(ptr) YYLINEPTR = ptr + newline_len(ptr); if ( YYLINEPTR > YYLINECTPTR ) { YYLINE++; YYLINECTPTR = YYLINEPTR; } + +/* + * I like seeing the level operations as macros... + */ +#define ADD_LEVEL(len, status) syck_parser_add_level( parser, len, status ) +#define POP_LEVEL() syck_parser_pop_level( parser ) +#define CURRENT_LEVEL() syck_parser_current_level( parser ) + +/* + * Force a token next time around sycklex() + */ +#define FORCE_NEXT_TOKEN(tok) parser->force_token = tok; + +/* + * Nice little macro to ensure we're YAML_IOPENed to the current level. + * * Only use this macro in the "Document" section * + */ +#define ENSURE_YAML_IOPEN(last_lvl, to_len, reset) \ + if ( last_lvl->spaces < to_len ) \ + { \ + if ( last_lvl->status == syck_lvl_iseq || last_lvl->status == syck_lvl_imap ) \ + { \ + goto Document; \ + } \ + else \ + { \ + ADD_LEVEL( to_len, syck_lvl_doc ); \ + if ( reset == 1 ) YYPOS(0); \ + return YAML_IOPEN; \ + } \ + } + +/* + * Nice little macro to ensure closure of levels. + * * Only use this macro in the "Document" section * + */ +#define ENSURE_YAML_IEND(last_lvl, to_len) \ + if ( last_lvl->spaces > to_len ) \ + { \ + syck_parser_pop_level( parser ); \ + YYPOS(0); \ + return YAML_IEND; \ + } + +/* + * Concatenates quoted string items and manages allocation + * to the quoted string + */ +#define QUOTECAT(s, c, i, l) \ + { \ + if ( i + 1 >= c ) \ + { \ + c += QUOTELEN; \ + S_REALLOC_N( s, char, c ); \ + } \ + s[i++] = l; \ + s[i] = '\0'; \ + } + +#define QUOTECATS(s, c, i, cs, cl) \ + { \ + while ( i + cl >= c ) \ + { \ + c += QUOTELEN; \ + S_REALLOC_N( s, char, c ); \ + } \ + S_MEMCPY( s + i, cs, char, cl ); \ + i += cl; \ + s[i] = '\0'; \ + } + +/* + * Tags a plain scalar with a transfer method + * * Use only in "Plain" section * + */ +#define RETURN_IMPLICIT() \ + { \ + SyckNode *n = syck_alloc_str(); \ + YYCURSOR = YYTOKEN; \ + n->data.str->ptr = qstr; \ + n->data.str->len = qidx; \ + n->data.str->style = scalar_plain; \ + sycklval->nodeData = n; \ + if ( parser->implicit_typing == 1 ) \ + { \ + try_tag_implicit( sycklval->nodeData, parser->taguri_expansion ); \ + } \ + return YAML_PLAIN; \ + } + +/* concat the inline characters to the plain scalar */ +#define PLAIN_NOT_INL() \ + if ( *(YYCURSOR - 1) == ' ' || is_newline( YYCURSOR - 1 ) ) \ + { \ + YYCURSOR--; \ + } \ + QUOTECATS(qstr, qcapa, qidx, YYTOKEN, YYCURSOR - YYTOKEN); \ + goto Plain2; + +/* trim spaces off the end in case of indent */ +#define PLAIN_IS_INL() \ + char *walker = qstr + qidx - 1; \ + while ( walker > qstr && ( *walker == '\n' || *walker == ' ' || *walker == '\t' ) ) \ + { \ + qidx--; \ + walker[0] = '\0'; \ + walker--; \ + } + +/* + * Keep or chomp block? + * * Use only in "ScalarBlock" section * + */ +#define RETURN_YAML_BLOCK() \ + { \ + SyckNode *n = syck_alloc_str(); \ + if ( ((SyckParser *)parser)->taguri_expansion == 1 ) \ + { \ + n->type_id = syck_taguri( YAML_DOMAIN, "str", 3 ); \ + } \ + else \ + { \ + n->type_id = syck_strndup( "str", 3 ); \ + } \ + n->data.str->ptr = qstr; \ + n->data.str->len = qidx; \ + if ( blockType == BLOCK_LIT ) { \ + n->data.str->style = scalar_literal; \ + } else { \ + n->data.str->style = scalar_fold; \ + } \ + if ( qidx > 0 ) \ + { \ + if ( nlDoWhat != NL_KEEP ) \ + { \ + char *fc = n->data.str->ptr + n->data.str->len - 1; \ + while ( is_newline( fc ) ) fc--; \ + if ( nlDoWhat != NL_CHOMP && fc < n->data.str->ptr + n->data.str->len - 1 ) \ + fc += 1; \ + n->data.str->len = fc - n->data.str->ptr + 1; \ + } \ + } \ + sycklval->nodeData = n; \ + return YAML_BLOCK; \ + } + +/* + * Handles newlines, calculates indent + */ +#define GOBBLE_UP_YAML_INDENT( ict, start ) \ + char *indent = start; \ + NEWLINE(indent); \ + while ( indent < YYCURSOR ) \ + { \ + if ( is_newline( ++indent ) ) \ + { \ + NEWLINE(indent); \ + } \ + } \ + ict = 0; \ + if ( *YYCURSOR == '\0' ) \ + { \ + ict = -1; \ + start = YYCURSOR - 1; \ + } \ + else if ( *YYLINEPTR == ' ' ) \ + { \ + ict = YYCURSOR - YYLINEPTR; \ + } + +/* + * If an indent exists at the current level, back up. + */ +#define GET_TRUE_YAML_INDENT(indt_len) \ + { \ + SyckLevel *lvl_deep = CURRENT_LEVEL(); \ + indt_len = lvl_deep->spaces; \ + if ( lvl_deep->status == syck_lvl_seq || ( indt_len == YYCURSOR - YYLINEPTR && lvl_deep->status != syck_lvl_map ) ) \ + { \ + SyckLevel *lvl_over; \ + parser->lvl_idx--; \ + lvl_over = CURRENT_LEVEL(); \ + indt_len = lvl_over->spaces; \ + parser->lvl_idx++; \ + } \ + } + +/* + * Argjh! I hate globals! Here for syckerror() only! + */ +SyckParser *syck_parser_ptr = NULL; + +/* + * Accessory funcs later in this file. + */ +void eat_comments( SyckParser * ); +char escape_seq( char ); +int is_newline( char *ptr ); +int newline_len( char *ptr ); +int sycklex_yaml_utf8( YYSTYPE *, SyckParser * ); +int sycklex_bytecode_utf8( YYSTYPE *, SyckParser * ); +int syckwrap(); + +/* + * My own re-entrant sycklex() using re2c. + * You really get used to the limited regexp. + * It's really nice to not rely on backtracking and such. + */ +int +sycklex( YYSTYPE *sycklval, SyckParser *parser ) +{ + switch ( parser->input_type ) + { + case syck_yaml_utf8: + return sycklex_yaml_utf8( sycklval, parser ); + + case syck_yaml_utf16: + syckerror( "UTF-16 is not currently supported in Syck.\nPlease contribute code to help this happen!" ); + break; + + case syck_yaml_utf32: + syckerror( "UTF-32 is not currently supported in Syck.\nPlease contribute code to help this happen!" ); + break; + + case syck_bytecode_utf8: + return sycklex_bytecode_utf8( sycklval, parser ); + } + return YAML_DOCSEP; +} + +/* + * Parser for standard YAML [UTF-8] + */ +int +sycklex_yaml_utf8( YYSTYPE *sycklval, SyckParser *parser ) +{ + int doc_level = 0; + syck_parser_ptr = parser; + if ( YYCURSOR == NULL ) + { + syck_parser_read( parser ); + } + + if ( parser->force_token != 0 ) + { + int t = parser->force_token; + parser->force_token = 0; + return t; + } + +#line 315 "token.re" + + + if ( YYLINEPTR != YYCURSOR ) + { + goto Document; + } + +Header: + + YYTOKEN = YYCURSOR; + + +#line 307 "" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy0; + ++YYCURSOR; +yy0: + if((YYLIMIT - YYCURSOR) < 5) YYFILL(5); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy7; + case 0x09: case ' ': goto yy12; + case 0x0A: goto yy9; + case 0x0D: goto yy11; + case '#': goto yy5; + case '-': goto yy2; + case '.': goto yy4; + default: goto yy14; + } +yy2: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '-': goto yy28; + default: goto yy3; + } +yy3: +#line 374 "token.re" +{ YYPOS(0); + goto Document; + } +#line 337 "" +yy4: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '.': goto yy21; + default: goto yy3; + } +yy5: ++YYCURSOR; + goto yy6; +yy6: +#line 356 "token.re" +{ eat_comments( parser ); + goto Header; + } +#line 351 "" +yy7: ++YYCURSOR; + goto yy8; +yy8: +#line 360 "token.re" +{ SyckLevel *lvl = CURRENT_LEVEL(); + ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } +#line 361 "" +yy9: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + goto yy18; +yy10: +#line 366 "token.re" +{ GOBBLE_UP_YAML_INDENT( doc_level, YYTOKEN ); + goto Header; + } +#line 370 "" +yy11: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy17; + default: goto yy3; + } +yy12: ++YYCURSOR; + yych = *YYCURSOR; + goto yy16; +yy13: +#line 370 "token.re" +{ doc_level = YYCURSOR - YYLINEPTR; + goto Header; + } +#line 384 "" +yy14: yych = *++YYCURSOR; + goto yy3; +yy15: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy16; +yy16: switch(yych){ + case 0x09: case ' ': goto yy15; + default: goto yy13; + } +yy17: yyaccept = 1; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy18; +yy18: switch(yych){ + case 0x0A: case ' ': goto yy17; + case 0x0D: goto yy19; + default: goto yy10; + } +yy19: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy17; + default: goto yy20; + } +yy20: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 1: goto yy10; + case 0: goto yy3; + } +yy21: yych = *++YYCURSOR; + switch(yych){ + case '.': goto yy22; + default: goto yy20; + } +yy22: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy23; + case 0x0D: goto yy27; + case ' ': goto yy25; + default: goto yy20; + } +yy23: ++YYCURSOR; + goto yy24; +yy24: +#line 342 "token.re" +{ SyckLevel *lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_header ) + { + goto Header; + } + else + { + ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } + return 0; + } +#line 446 "" +yy25: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy26; +yy26: switch(yych){ + case ' ': goto yy25; + default: goto yy24; + } +yy27: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy23; + default: goto yy20; + } +yy28: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy29; + default: goto yy20; + } +yy29: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy30; + case 0x0D: goto yy34; + case ' ': goto yy32; + default: goto yy20; + } +yy30: ++YYCURSOR; + goto yy31; +yy31: +#line 328 "token.re" +{ SyckLevel *lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_header ) + { + YYPOS(3); + goto Directive; + } + else + { + ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } + } +#line 489 "" +yy32: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy33; +yy33: switch(yych){ + case ' ': goto yy32; + default: goto yy31; + } +yy34: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy30; + default: goto yy20; + } +} +#line 378 "token.re" + + +Document: + { + SyckLevel *lvl = CURRENT_LEVEL(); + if ( lvl->status == syck_lvl_header ) + { + lvl->status = syck_lvl_doc; + } + + YYTOKEN = YYCURSOR; + + +#line 518 "" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy35; + ++YYCURSOR; +yy35: + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy62; + case 0x09: case ' ': goto yy60; + case 0x0A: goto yy37; + case 0x0D: goto yy39; + case '!': goto yy51; + case '"': goto yy55; + case '#': goto yy58; + case '&': goto yy49; + case '\'': goto yy53; + case '*': goto yy50; + case ',': case ':': goto yy47; + case '-': case '?': goto yy48; + case '>': case '|': goto yy57; + case '[': goto yy41; + case ']': case '}': goto yy45; + case '{': goto yy43; + default: goto yy64; + } +yy37: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy92; +yy38: +#line 392 "token.re" +{ /* Isolate spaces */ + int indt_len; + GOBBLE_UP_YAML_INDENT( indt_len, YYTOKEN ); + lvl = CURRENT_LEVEL(); + doc_level = 0; + + /* XXX: Comment lookahead */ + if ( *YYCURSOR == '#' ) + { + goto Document; + } + + /* Ignore indentation inside inlines */ + if ( lvl->status == syck_lvl_iseq || lvl->status == syck_lvl_imap ) + { + goto Document; + } + + /* Check for open indent */ + ENSURE_YAML_IEND(lvl, indt_len); + ENSURE_YAML_IOPEN(lvl, indt_len, 0); + if ( indt_len == -1 ) + { + return 0; + } + return YAML_INDENT; + } +#line 578 "" +yy39: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy91; + default: goto yy40; + } +yy40: +#line 497 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + goto Plain; + } +#line 589 "" +yy41: ++YYCURSOR; + goto yy42; +yy42: +#line 420 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + lvl = CURRENT_LEVEL(); + ADD_LEVEL(lvl->spaces + 1, syck_lvl_iseq); + return YYTOKEN[0]; + } +#line 599 "" +yy43: ++YYCURSOR; + goto yy44; +yy44: +#line 426 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + lvl = CURRENT_LEVEL(); + ADD_LEVEL(lvl->spaces + 1, syck_lvl_imap); + return YYTOKEN[0]; + } +#line 609 "" +yy45: ++YYCURSOR; + goto yy46; +yy46: +#line 432 "token.re" +{ POP_LEVEL(); + return YYTOKEN[0]; + } +#line 617 "" +yy47: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy86; + case 0x0D: goto yy90; + case ' ': goto yy88; + default: goto yy40; + } +yy48: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy81; + case 0x0D: goto yy85; + case ' ': goto yy83; + default: goto yy40; + } +yy49: yych = *++YYCURSOR; + switch(yych){ + case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy78; + default: goto yy40; + } +yy50: yych = *++YYCURSOR; + switch(yych){ + case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy75; + default: goto yy40; + } +yy51: ++YYCURSOR; + goto yy52; +yy52: +#line 471 "token.re" +{ goto TransferMethod; } +#line 767 "" +yy53: ++YYCURSOR; + goto yy54; +yy54: +#line 473 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + goto SingleQuote; } +#line 774 "" +yy55: ++YYCURSOR; + goto yy56; +yy56: +#line 476 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + goto DoubleQuote; } +#line 781 "" +yy57: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy70; + case 0x0D: goto yy74; + case ' ': goto yy72; + case '+': case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy40; + } +yy58: ++YYCURSOR; + goto yy59; +yy59: +#line 486 "token.re" +{ eat_comments( parser ); + goto Document; + } +#line 807 "" +yy60: ++YYCURSOR; + yych = *YYCURSOR; + goto yy66; +yy61: +#line 490 "token.re" +{ goto Document; } +#line 814 "" +yy62: ++YYCURSOR; + goto yy63; +yy63: +#line 492 "token.re" +{ ENSURE_YAML_IEND(lvl, -1); + YYPOS(0); + return 0; + } +#line 823 "" +yy64: yych = *++YYCURSOR; + goto yy40; +yy65: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy66; +yy66: switch(yych){ + case 0x09: case ' ': goto yy65; + default: goto yy61; + } +yy67: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy68; +yy68: switch(yych){ + case 0x0A: goto yy70; + case 0x0D: goto yy74; + case ' ': goto yy72; + case '+': case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy69; + } +yy69: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy38; + case 1: goto yy40; + } +yy70: ++YYCURSOR; + goto yy71; +yy71: +#line 479 "token.re" +{ if ( is_newline( YYCURSOR - 1 ) ) + { + YYCURSOR--; + } + goto ScalarBlock; + } +#line 869 "" +yy72: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy73; +yy73: switch(yych){ + case ' ': goto yy72; + default: goto yy71; + } +yy74: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy70; + default: goto yy69; + } +yy75: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy76; +yy76: switch(yych){ + case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy75; + default: goto yy77; + } +yy77: +#line 466 "token.re" +{ ENSURE_YAML_IOPEN(lvl, doc_level, 1); + sycklval->name = syck_strndup( YYTOKEN + 1, YYCURSOR - YYTOKEN - 1 ); + return YAML_ALIAS; + } +#line 956 "" +yy78: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy79; +yy79: switch(yych){ + case '-': case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy78; + default: goto yy80; + } +yy80: +#line 455 "token.re" +{ sycklval->name = syck_strndup( YYTOKEN + 1, YYCURSOR - YYTOKEN - 1 ); + + /* + * Remove previous anchors of the same name. Since the parser will likely + * construct deeper nodes first, we want those nodes to be placed in the + * queue for matching at a higher level of indentation. + */ + syck_hdlr_remove_anchor(parser, sycklval->name); + return YAML_ANCHOR; + } +#line 1036 "" +yy81: ++YYCURSOR; + goto yy82; +yy82: +#line 441 "token.re" +{ ENSURE_YAML_IOPEN(lvl, YYTOKEN - YYLINEPTR, 1); + FORCE_NEXT_TOKEN(YAML_IOPEN); + if ( *YYCURSOR == '#' || is_newline( YYCURSOR ) || is_newline( YYCURSOR - 1 ) ) + { + YYCURSOR--; + ADD_LEVEL((YYTOKEN + 1) - YYLINEPTR, syck_lvl_seq); + } + else /* spaces followed by content uses the space as indentation */ + { + ADD_LEVEL(YYCURSOR - YYLINEPTR, syck_lvl_seq); + } + return YYTOKEN[0]; + } +#line 1054 "" +yy83: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy84; +yy84: switch(yych){ + case ' ': goto yy83; + default: goto yy82; + } +yy85: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy81; + default: goto yy69; + } +yy86: ++YYCURSOR; + goto yy87; +yy87: +#line 436 "token.re" +{ if ( *YYTOKEN == ':' && lvl->status != syck_lvl_imap ) lvl->status = syck_lvl_map; + YYPOS(1); + return YYTOKEN[0]; + } +#line 1076 "" +yy88: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy89; +yy89: switch(yych){ + case ' ': goto yy88; + default: goto yy87; + } +yy90: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy86; + default: goto yy69; + } +yy91: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy92; +yy92: switch(yych){ + case 0x0A: case ' ': goto yy91; + case 0x0D: goto yy93; + default: goto yy38; + } +yy93: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy91; + default: goto yy69; + } +} +#line 501 "token.re" + + } + +Directive: + { + YYTOKTMP = YYCURSOR; + + +#line 1117 "" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + goto yy94; + ++YYCURSOR; +yy94: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy96; + case 0x09: case ' ': goto yy99; + case '%': goto yy97; + default: goto yy101; + } +yy96: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy98; + } +yy97: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy104; + default: goto yy98; + } +yy98: +#line 514 "token.re" +{ YYCURSOR = YYTOKTMP; + return YAML_DOCSEP; + } +#line 1221 "" +yy99: ++YYCURSOR; + yych = *YYCURSOR; + goto yy103; +yy100: +#line 512 "token.re" +{ goto Directive; } +#line 1228 "" +yy101: yych = *++YYCURSOR; + goto yy98; +yy102: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy103; +yy103: switch(yych){ + case 0x09: case ' ': goto yy102; + default: goto yy100; + } +yy104: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy105; +yy105: switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy104; + case ':': goto yy106; + default: goto yy96; + } +yy106: yych = *++YYCURSOR; + switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy107; + default: goto yy96; + } +yy107: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy108; +yy108: switch(yych){ + case '.': + case '/': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '[': + case '\\': + case ']': + case '^': + case '_': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy107; + default: goto yy109; + } +yy109: +#line 510 "token.re" +{ goto Directive; } +#line 1484 "" +} +#line 517 "token.re" + + + } + +Plain: + { + int qidx = 0; + int qcapa = 100; + char *qstr = S_ALLOC_N( char, qcapa ); + SyckLevel *plvl; + int parentIndent; + + YYCURSOR = YYTOKEN; + plvl = CURRENT_LEVEL(); + GET_TRUE_YAML_INDENT(parentIndent); + +Plain2: + YYTOKEN = YYCURSOR; + +Plain3: + + +#line 1509 "" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy110; + ++YYCURSOR; +yy110: + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy124; + case 0x09: goto yy126; + case 0x0A: goto yy112; + case 0x0D: goto yy114; + case ' ': goto yy122; + case ',': goto yy117; + case ':': goto yy116; + case ']': goto yy120; + case '}': goto yy118; + default: goto yy127; + } +yy112: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy142; +yy113: +#line 540 "token.re" +{ int indt_len, nl_count = 0; + SyckLevel *lvl; + char *tok = YYTOKEN; + GOBBLE_UP_YAML_INDENT( indt_len, tok ); + lvl = CURRENT_LEVEL(); + + if ( indt_len <= parentIndent ) + { + RETURN_IMPLICIT(); + } + + while ( YYTOKEN < YYCURSOR ) + { + int nl_len = newline_len( YYTOKEN++ ); + if ( nl_len ) + { + nl_count++; + YYTOKEN += nl_len - 1; + } + } + if ( nl_count <= 1 ) + { + QUOTECAT(qstr, qcapa, qidx, ' '); + } + else + { + int i; + for ( i = 0; i < nl_count - 1; i++ ) + { + QUOTECAT(qstr, qcapa, qidx, '\n'); + } + } + + goto Plain2; + } +#line 1570 "" +yy114: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy141; + default: goto yy115; + } +yy115: +#line 627 "token.re" +{ QUOTECATS(qstr, qcapa, qidx, YYTOKEN, YYCURSOR - YYTOKEN); + goto Plain2; + } +#line 1581 "" +yy116: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy136; + case 0x0D: goto yy140; + case ' ': goto yy138; + default: goto yy115; + } +yy117: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy130; + case 0x0D: goto yy134; + case ' ': goto yy132; + default: goto yy115; + } +yy118: ++YYCURSOR; + goto yy119; +yy119: +#line 589 "token.re" +{ if ( plvl->status != syck_lvl_imap ) + { + PLAIN_NOT_INL(); + } + else + { + PLAIN_IS_INL(); + } + RETURN_IMPLICIT(); + } +#line 1612 "" +yy120: ++YYCURSOR; + goto yy121; +yy121: +#line 600 "token.re" +{ if ( plvl->status != syck_lvl_iseq ) + { + PLAIN_NOT_INL(); + } + else + { + PLAIN_IS_INL(); + } + RETURN_IMPLICIT(); + } +#line 1627 "" +yy122: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case '#': goto yy128; + default: goto yy123; + } +yy123: +#line 617 "token.re" +{ if ( qidx == 0 ) + { + goto Plain2; + } + else + { + goto Plain3; + } + } +#line 1644 "" +yy124: ++YYCURSOR; + goto yy125; +yy125: +#line 615 "token.re" +{ RETURN_IMPLICIT(); } +#line 1650 "" +yy126: yych = *++YYCURSOR; + goto yy123; +yy127: yych = *++YYCURSOR; + goto yy115; +yy128: ++YYCURSOR; + goto yy129; +yy129: +#line 611 "token.re" +{ eat_comments( parser ); + RETURN_IMPLICIT(); + } +#line 1662 "" +yy130: ++YYCURSOR; + goto yy131; +yy131: +#line 578 "token.re" +{ if ( plvl->status != syck_lvl_iseq && plvl->status != syck_lvl_imap ) + { + PLAIN_NOT_INL(); + } + else + { + PLAIN_IS_INL(); + } + RETURN_IMPLICIT(); + } +#line 1677 "" +yy132: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy133; +yy133: switch(yych){ + case ' ': goto yy132; + default: goto yy131; + } +yy134: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy130; + default: goto yy135; + } +yy135: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy113; + case 1: goto yy115; + } +yy136: ++YYCURSOR; + goto yy137; +yy137: +#line 576 "token.re" +{ RETURN_IMPLICIT(); } +#line 1701 "" +yy138: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy139; +yy139: switch(yych){ + case ' ': goto yy138; + default: goto yy137; + } +yy140: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy136; + default: goto yy135; + } +yy141: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy142; +yy142: switch(yych){ + case 0x0A: case ' ': goto yy141; + case 0x0D: goto yy143; + default: goto yy113; + } +yy143: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy141; + default: goto yy135; + } +} +#line 631 "token.re" + + } + +SingleQuote: + { + int qidx = 0; + int qcapa = 100; + char *qstr = S_ALLOC_N( char, qcapa ); + +SingleQuote2: + YYTOKEN = YYCURSOR; + + +#line 1747 "" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy144; + ++YYCURSOR; +yy144: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy152; + case 0x0A: goto yy146; + case 0x0D: goto yy148; + case '\'': goto yy150; + default: goto yy153; + } +yy146: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy157; +yy147: +#line 645 "token.re" +{ int indt_len; + int nl_count = 0; + SyckLevel *lvl; + GOBBLE_UP_YAML_INDENT( indt_len, YYTOKEN ); + lvl = CURRENT_LEVEL(); + + if ( lvl->status != syck_lvl_str ) + { + ADD_LEVEL( indt_len, syck_lvl_str ); + } + else if ( indt_len < lvl->spaces ) + { + /* Error! */ + } + + while ( YYTOKEN < YYCURSOR ) + { + int nl_len = newline_len( YYTOKEN++ ); + if ( nl_len ) + { + nl_count++; + YYTOKEN += nl_len - 1; + } + } + if ( nl_count <= 1 ) + { + QUOTECAT(qstr, qcapa, qidx, ' '); + } + else + { + int i; + for ( i = 0; i < nl_count - 1; i++ ) + { + QUOTECAT(qstr, qcapa, qidx, '\n'); + } + } + + goto SingleQuote2; + } +#line 1807 "" +yy148: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy156; + default: goto yy149; + } +yy149: +#line 712 "token.re" +{ QUOTECAT(qstr, qcapa, qidx, *(YYCURSOR - 1)); + goto SingleQuote2; + } +#line 1818 "" +yy150: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case '\'': goto yy154; + default: goto yy151; + } +yy151: +#line 689 "token.re" +{ SyckLevel *lvl; + SyckNode *n = syck_alloc_str(); + lvl = CURRENT_LEVEL(); + + if ( lvl->status == syck_lvl_str ) + { + POP_LEVEL(); + } + if ( ((SyckParser *)parser)->taguri_expansion == 1 ) + { + n->type_id = syck_taguri( YAML_DOMAIN, "str", 3 ); + } + else + { + n->type_id = syck_strndup( "str", 3 ); + } + n->data.str->ptr = qstr; + n->data.str->len = qidx; + n->data.str->style = scalar_1quote; + sycklval->nodeData = n; + return YAML_PLAIN; + } +#line 1848 "" +yy152: yych = *++YYCURSOR; + goto yy151; +yy153: yych = *++YYCURSOR; + goto yy149; +yy154: ++YYCURSOR; + goto yy155; +yy155: +#line 685 "token.re" +{ QUOTECAT(qstr, qcapa, qidx, '\''); + goto SingleQuote2; + } +#line 1860 "" +yy156: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy157; +yy157: switch(yych){ + case 0x0A: case ' ': goto yy156; + case 0x0D: goto yy158; + default: goto yy147; + } +yy158: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy156; + default: goto yy159; + } +yy159: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy147; + } +} +#line 716 "token.re" + + + } + + +DoubleQuote: + { + int keep_nl = 1; + int qidx = 0; + int qcapa = 100; + char *qstr = S_ALLOC_N( char, qcapa ); + +DoubleQuote2: + YYTOKEN = YYCURSOR; + + + +#line 1901 "" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy160; + ++YYCURSOR; +yy160: + if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy167; + case 0x0A: goto yy162; + case 0x0D: goto yy164; + case '"': goto yy169; + case '\\': goto yy166; + default: goto yy170; + } +yy162: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy184; +yy163: +#line 734 "token.re" +{ int indt_len; + int nl_count = 0; + SyckLevel *lvl; + GOBBLE_UP_YAML_INDENT( indt_len, YYTOKEN ); + lvl = CURRENT_LEVEL(); + + if ( lvl->status != syck_lvl_str ) + { + ADD_LEVEL( indt_len, syck_lvl_str ); + } + else if ( indt_len < lvl->spaces ) + { + /* FIXME */ + } + + if ( keep_nl == 1 ) + { + while ( YYTOKEN < YYCURSOR ) + { + int nl_len = newline_len( YYTOKEN++ ); + if ( nl_len ) + { + nl_count++; + YYTOKEN += nl_len - 1; + } + } + if ( nl_count <= 1 ) + { + QUOTECAT(qstr, qcapa, qidx, ' '); + } + else + { + int i; + for ( i = 0; i < nl_count - 1; i++ ) + { + QUOTECAT(qstr, qcapa, qidx, '\n'); + } + } + } + + keep_nl = 1; + goto DoubleQuote2; + } +#line 1966 "" +yy164: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy183; + default: goto yy165; + } +yy165: +#line 820 "token.re" +{ QUOTECAT(qstr, qcapa, qidx, *(YYCURSOR - 1)); + goto DoubleQuote2; + } +#line 1977 "" +yy166: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case 0x0A: goto yy174; + case 0x0D: goto yy176; + case ' ': goto yy171; + case '"': case '0': case '\\': case 'a': + case 'b': case 'e': + case 'f': case 'n': case 'r': case 't': case 'v': goto yy178; + case 'x': goto yy177; + default: goto yy165; + } +yy167: ++YYCURSOR; + goto yy168; +yy168: +#line 797 "token.re" +{ SyckLevel *lvl; + SyckNode *n = syck_alloc_str(); + lvl = CURRENT_LEVEL(); + + if ( lvl->status == syck_lvl_str ) + { + POP_LEVEL(); + } + if ( ((SyckParser *)parser)->taguri_expansion == 1 ) + { + n->type_id = syck_taguri( YAML_DOMAIN, "str", 3 ); + } + else + { + n->type_id = syck_strndup( "str", 3 ); + } + n->data.str->ptr = qstr; + n->data.str->len = qidx; + n->data.str->style = scalar_2quote; + sycklval->nodeData = n; + return YAML_PLAIN; + } +#line 2016 "" +yy169: yych = *++YYCURSOR; + goto yy168; +yy170: yych = *++YYCURSOR; + goto yy165; +yy171: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + goto yy172; +yy172: switch(yych){ + case 0x0A: goto yy174; + case 0x0D: goto yy176; + case ' ': goto yy171; + default: goto yy173; + } +yy173: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy163; + case 1: goto yy165; + } +yy174: ++YYCURSOR; + goto yy175; +yy175: +#line 792 "token.re" +{ keep_nl = 0; + YYCURSOR--; + goto DoubleQuote2; + } +#line 2044 "" +yy176: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy174; + default: goto yy173; + } +yy177: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': goto yy180; + default: goto yy173; + } +yy178: ++YYCURSOR; + goto yy179; +yy179: +#line 778 "token.re" +{ char ch = *( YYCURSOR - 1 ); + QUOTECAT(qstr, qcapa, qidx, escape_seq( ch )); + goto DoubleQuote2; + } +#line 2082 "" +yy180: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': goto yy181; + default: goto yy173; + } +yy181: ++YYCURSOR; + goto yy182; +yy182: +#line 783 "token.re" +{ long ch; + char *chr_text = syck_strndup( YYTOKEN, 4 ); + chr_text[0] = '0'; + ch = strtol( chr_text, NULL, 16 ); + free( chr_text ); + QUOTECAT(qstr, qcapa, qidx, ch); + goto DoubleQuote2; + } +#line 2119 "" +yy183: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy184; +yy184: switch(yych){ + case 0x0A: case ' ': goto yy183; + case 0x0D: goto yy185; + default: goto yy163; + } +yy185: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy183; + default: goto yy173; + } +} +#line 824 "token.re" + + } + +TransferMethod: + { + int qidx = 0; + int qcapa = 100; + char *qstr = S_ALLOC_N( char, qcapa ); + +TransferMethod2: + YYTOKTMP = YYCURSOR; + + +#line 2152 "" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy186; + ++YYCURSOR; +yy186: + if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy188; + case 0x0A: goto yy190; + case 0x0D: goto yy192; + case ' ': goto yy191; + case '\\': goto yy194; + default: goto yy195; + } +yy188: ++YYCURSOR; + goto yy189; +yy189: +#line 838 "token.re" +{ SyckLevel *lvl; + YYCURSOR = YYTOKTMP; + if ( YYCURSOR == YYTOKEN + 1 ) + { + free( qstr ); + return YAML_ITRANSFER; + } + + lvl = CURRENT_LEVEL(); + + /* + * URL Prefixing + */ + if ( *qstr == '^' ) + { + sycklval->name = S_ALLOC_N( char, qidx + strlen( lvl->domain ) ); + sycklval->name[0] = '\0'; + strcat( sycklval->name, lvl->domain ); + strncat( sycklval->name, qstr + 1, qidx - 1 ); + free( qstr ); + } + else + { + char *carat = qstr; + char *qend = qstr + qidx; + while ( (++carat) < qend ) + { + if ( *carat == '^' ) + break; + } + + if ( carat < qend ) + { + free( lvl->domain ); + lvl->domain = syck_strndup( qstr, carat - qstr ); + sycklval->name = S_ALLOC_N( char, ( qend - carat ) + strlen( lvl->domain ) ); + sycklval->name[0] = '\0'; + strcat( sycklval->name, lvl->domain ); + strncat( sycklval->name, carat + 1, ( qend - carat ) - 1 ); + free( qstr ); + } + else + { + sycklval->name = qstr; + } + } + + return YAML_TRANSFER; + } +#line 2222 "" +yy190: yych = *++YYCURSOR; + goto yy189; +yy191: yych = *++YYCURSOR; + goto yy204; +yy192: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy188; + default: goto yy193; + } +yy193: +#line 905 "token.re" +{ QUOTECAT(qstr, qcapa, qidx, *(YYCURSOR - 1)); + goto TransferMethod2; + } +#line 2237 "" +yy194: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '"': case '0': case '\\': case 'a': + case 'b': case 'e': + case 'f': case 'n': case 'r': case 't': case 'v': goto yy198; + case 'x': goto yy196; + default: goto yy193; + } +yy195: yych = *++YYCURSOR; + goto yy193; +yy196: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': goto yy200; + default: goto yy197; + } +yy197: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy193; + } +yy198: ++YYCURSOR; + goto yy199; +yy199: +#line 891 "token.re" +{ char ch = *( YYCURSOR - 1 ); + QUOTECAT(qstr, qcapa, qidx, escape_seq( ch )); + goto TransferMethod2; + } +#line 2285 "" +yy200: yych = *++YYCURSOR; + switch(yych){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': goto yy201; + default: goto yy197; + } +yy201: ++YYCURSOR; + goto yy202; +yy202: +#line 896 "token.re" +{ long ch; + char *chr_text = syck_strndup( YYTOKTMP, 4 ); + chr_text[0] = '0'; + ch = strtol( chr_text, NULL, 16 ); + free( chr_text ); + QUOTECAT(qstr, qcapa, qidx, ch); + goto TransferMethod2; + } +#line 2322 "" +yy203: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy204; +yy204: switch(yych){ + case ' ': goto yy203; + default: goto yy189; + } +} +#line 910 "token.re" + + } + +ScalarBlock: + { + int qidx = 0; + int qcapa = 100; + char *qstr = S_ALLOC_N( char, qcapa ); + int blockType = 0; + int nlDoWhat = 0; + int lastIndent = 0; + int forceIndent = -1; + char *yyt = YYTOKEN; + SyckLevel *lvl = CURRENT_LEVEL(); + int parentIndent = -1; + + switch ( *yyt ) + { + case '|': blockType = BLOCK_LIT; break; + case '>': blockType = BLOCK_FOLD; break; + } + + while ( ++yyt <= YYCURSOR ) + { + if ( *yyt == '-' ) + { + nlDoWhat = NL_CHOMP; + } + else if ( *yyt == '+' ) + { + nlDoWhat = NL_KEEP; + } + else if ( isdigit( *yyt ) ) + { + forceIndent = strtol( yyt, NULL, 10 ); + } + } + + qstr[0] = '\0'; + YYTOKEN = YYCURSOR; + +ScalarBlock2: + YYTOKEN = YYCURSOR; + + +#line 2378 "" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy205; + ++YYCURSOR; +yy205: + if((YYLIMIT - YYCURSOR) < 5) YYFILL(5); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy213; + case 0x0A: goto yy207; + case 0x0D: goto yy209; + case '#': goto yy211; + case '-': goto yy215; + default: goto yy216; + } +yy207: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy226; +yy208: +#line 956 "token.re" +{ char *pacer; + char *tok = YYTOKEN; + int indt_len = 0, nl_count = 0, fold_nl = 0, nl_begin = 0; + GOBBLE_UP_YAML_INDENT( indt_len, tok ); + lvl = CURRENT_LEVEL(); + + if ( lvl->status != syck_lvl_block ) + { + GET_TRUE_YAML_INDENT(parentIndent); + if ( forceIndent > 0 ) forceIndent += parentIndent; + if ( indt_len > parentIndent ) + { + int new_spaces = forceIndent > 0 ? forceIndent : indt_len; + ADD_LEVEL( new_spaces, syck_lvl_block ); + lastIndent = indt_len - new_spaces; + nl_begin = 1; + lvl = CURRENT_LEVEL(); + } + else + { + YYCURSOR = YYTOKEN; + RETURN_YAML_BLOCK(); + } + } + + /* + * Fold only in the event of two lines being on the leftmost + * indentation. + */ + if ( blockType == BLOCK_FOLD && lastIndent == 0 && ( indt_len - lvl->spaces ) == 0 ) + { + fold_nl = 1; + } + + pacer = YYTOKEN; + while ( pacer < YYCURSOR ) + { + int nl_len = newline_len( pacer++ ); + if ( nl_len ) + { + nl_count++; + pacer += nl_len - 1; + } + } + + if ( fold_nl == 1 || nl_begin == 1 ) + { + nl_count--; + } + + if ( nl_count < 1 && nl_begin == 0 ) + { + QUOTECAT(qstr, qcapa, qidx, ' '); + } + else + { + int i; + for ( i = 0; i < nl_count; i++ ) + { + QUOTECAT(qstr, qcapa, qidx, '\n'); + } + } + + lastIndent = indt_len - lvl->spaces; + YYCURSOR -= lastIndent; + + if ( indt_len < lvl->spaces ) + { + POP_LEVEL(); + YYCURSOR = YYTOKEN; + RETURN_YAML_BLOCK(); + } + goto ScalarBlock2; + } +#line 2474 "" +yy209: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy225; + default: goto yy210; + } +yy210: +#line 1070 "token.re" +{ QUOTECAT(qstr, qcapa, qidx, *YYTOKEN); + goto ScalarBlock2; + } +#line 2485 "" +yy211: ++YYCURSOR; + goto yy212; +yy212: +#line 1032 "token.re" +{ lvl = CURRENT_LEVEL(); + if ( lvl->status != syck_lvl_block ) + { + eat_comments( parser ); + YYTOKEN = YYCURSOR; + } + else + { + QUOTECAT(qstr, qcapa, qidx, *YYTOKEN); + } + goto ScalarBlock2; + } +#line 2502 "" +yy213: ++YYCURSOR; + goto yy214; +yy214: +#line 1046 "token.re" +{ YYCURSOR--; + POP_LEVEL(); + RETURN_YAML_BLOCK(); + } +#line 2511 "" +yy215: yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + switch(yych){ + case '-': goto yy217; + default: goto yy210; + } +yy216: yych = *++YYCURSOR; + goto yy210; +yy217: yych = *++YYCURSOR; + switch(yych){ + case '-': goto yy219; + default: goto yy218; + } +yy218: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy208; + case 1: goto yy210; + } +yy219: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy220; + case 0x0D: goto yy224; + case ' ': goto yy222; + default: goto yy218; + } +yy220: ++YYCURSOR; + goto yy221; +yy221: +#line 1051 "token.re" +{ if ( YYTOKEN == YYLINEPTR ) + { + if ( blockType == BLOCK_FOLD && qidx > 0 ) + { + qidx -= 1; + } + QUOTECAT(qstr, qcapa, qidx, '\n'); + POP_LEVEL(); + YYCURSOR = YYTOKEN; + RETURN_YAML_BLOCK(); + } + else + { + QUOTECAT(qstr, qcapa, qidx, *YYTOKEN); + YYCURSOR = YYTOKEN + 1; + goto ScalarBlock2; + } + } +#line 2559 "" +yy222: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy223; +yy223: switch(yych){ + case ' ': goto yy222; + default: goto yy221; + } +yy224: yych = *++YYCURSOR; + switch(yych){ + case 0x0A: goto yy220; + default: goto yy218; + } +yy225: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy226; +yy226: switch(yych){ + case 0x0A: case ' ': goto yy225; + case 0x0D: goto yy227; + default: goto yy208; + } +yy227: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy225; + default: goto yy218; + } +} +#line 1075 "token.re" + + } + + return 0; + +} + +void +eat_comments( SyckParser *parser ) +{ +Comment: + { + YYTOKEN = YYCURSOR; + + +#line 2607 "" +{ + YYCTYPE yych; + unsigned int yyaccept; + goto yy228; + ++YYCURSOR; +yy228: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + switch(yych){ + case 0x00: goto yy230; + case 0x0A: goto yy232; + case 0x0D: goto yy233; + default: goto yy235; + } +yy230: ++YYCURSOR; + goto yy231; +yy231: +#line 1091 "token.re" +{ YYCURSOR = YYTOKEN; + return; + } +#line 2629 "" +yy232: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy237; +yy233: ++YYCURSOR; + switch((yych = *YYCURSOR)) { + case 0x0A: goto yy236; + default: goto yy234; + } +yy234: +#line 1095 "token.re" +{ goto Comment; + } +#line 2642 "" +yy235: yych = *++YYCURSOR; + goto yy234; +yy236: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy237; +yy237: switch(yych){ + case 0x0A: goto yy236; + case 0x0D: goto yy238; + default: goto yy231; + } +yy238: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + switch(yych){ + case 0x0A: goto yy236; + default: goto yy239; + } +yy239: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy231; + } +} +#line 1098 "token.re" + + + } + +} + +char +escape_seq( char ch ) +{ + switch ( ch ) + { + case '0': return '\0'; + case 'a': return 7; + case 'b': return '\010'; + case 'e': return '\033'; + case 'f': return '\014'; + case 'n': return '\n'; + case 'r': return '\015'; + case 't': return '\t'; + case 'v': return '\013'; + default: return ch; + } +} + +int +is_newline( char *ptr ) +{ + return newline_len( ptr ); +} + +int +newline_len( char *ptr ) +{ + if ( *ptr == '\n' ) + return 1; + + if ( *ptr == '\r' && *( ptr + 1 ) == '\n' ) + return 2; + + return 0; +} + +int +syckwrap() +{ + return 1; +} + +void +syckerror( const char *msg ) +{ + if ( syck_parser_ptr->error_handler == NULL ) + syck_parser_ptr->error_handler = syck_default_error_handler; + + syck_parser_ptr->root = syck_parser_ptr->root_on_error; + (syck_parser_ptr->error_handler)(syck_parser_ptr, msg); +} + diff --git a/lib/19/syck/ext/yaml2byte.c b/lib/19/syck/ext/yaml2byte.c new file mode 100644 index 0000000000..d137d92d2f --- /dev/null +++ b/lib/19/syck/ext/yaml2byte.c @@ -0,0 +1,259 @@ +/* + * yaml2byte.c + * + * $Author: nobu $ + * + * Copyright (C) 2003 why the lucky stiff, clark evans + * + * WARNING WARNING WARNING --- THIS IS *NOT JUST* PLAYING + * ANYMORE! -- WHY HAS EMBRACED THIS AS THE REAL THING! + */ +#include "ruby/ruby.h" +#include +#include +#define YAMLBYTE_UTF8 +#include "yamlbyte.h" + +#include +#define TRACE0(a) \ + do { printf(a); printf("\n"); fflush(stdout); } while(0) +#define TRACE1(a,b) \ + do { printf(a,b); printf("\n"); fflush(stdout); } while(0) +#define TRACE2(a,b,c) \ + do { printf(a,b,c); printf("\n"); fflush(stdout); } while(0) +#define TRACE3(a,b,c,d) \ + do { printf(a,b,c,d); printf("\n"); fflush(stdout); } while(0) + +/* Reinvent the wheel... */ +#define CHUNKSIZE 64 +#define HASH ((long)0xCAFECAFE) +typedef struct { + long hash; + char *buffer; + long length; + long remaining; + int printed; +} bytestring_t; +bytestring_t *bytestring_alloc(void) { + bytestring_t *ret; + /*TRACE0("bytestring_alloc()");*/ + ret = S_ALLOC(bytestring_t); + ret->hash = HASH; + ret->length = CHUNKSIZE; + ret->remaining = ret->length; + ret->buffer = S_ALLOC_N(char, ret->length + 1 ); + ret->buffer[0] = 0; + ret->printed = 0; + return ret; +} +void bytestring_append(bytestring_t *str, char code, + char *start, char *finish) +{ + long grow; + long length = 2; /* CODE + LF */ + char *curr; + assert(str && HASH == str->hash); + /*TRACE0("bytestring_append()");*/ + if(start) { + if(!finish) + finish = start + strlen(start); + length += (finish-start); + } + if(length > str->remaining) { + grow = (length - str->remaining) + CHUNKSIZE; + str->remaining += grow; + str->length += grow; + S_REALLOC_N( str->buffer, char, str->length + 1 ); + assert(str->buffer); + } + curr = str->buffer + (str->length - str->remaining); + *curr = code; + curr += 1; + if(start) + while(start < finish) + *curr ++ = *start ++; + *curr = '\n'; + curr += 1; + *curr = 0; + str->remaining = str->remaining - length; + assert( (str->buffer + str->length) - str->remaining ); +} +void bytestring_extend(bytestring_t *str, bytestring_t *ext) +{ + char *from; + char *curr; + char *stop; + long grow; + long length; + assert(str && HASH == str->hash); + assert(ext && HASH == ext->hash); + if(ext->printed) { + assert(ext->buffer[0] ==YAMLBYTE_ANCHOR); + curr = ext->buffer; + while( '\n' != *curr) + curr++; + bytestring_append(str, YAMLBYTE_ALIAS, ext->buffer + 1, curr); + } else { + ext->printed = 1; + length = (ext->length - ext->remaining); + if(length > str->remaining) { + grow = (length - str->remaining) + CHUNKSIZE; + str->remaining += grow; + str->length += grow; + S_REALLOC_N( str->buffer, char, str->length + 1 ); + } + curr = str->buffer + (str->length - str->remaining); + from = ext->buffer; + stop = ext->buffer + length; + while( from < stop ) + *curr ++ = *from ++; + *curr = 0; + str->remaining = str->remaining - length; + assert( (str->buffer + str->length) - str->remaining ); + } +} + +/* convert SyckNode into yamlbyte_buffer_t objects */ +SYMID +syck_yaml2byte_handler(p, n) + SyckParser *p; + SyckNode *n; +{ + SYMID oid; + long i; + char ch; + char nextcode; + char *start; + char *current; + char *finish; + bytestring_t *val = NULL; + bytestring_t *sav = NULL; + void *data; + /*TRACE0("syck_yaml2byte_handler()");*/ + val = bytestring_alloc(); + if(n->anchor) bytestring_append(val,YAMLBYTE_ANCHOR, n->anchor, NULL); + if ( n->type_id ) + { + if ( p->taguri_expansion ) + { + bytestring_append(val,YAMLBYTE_TRANSFER, n->type_id, NULL); + } + else + { + char *type_tag = S_ALLOC_N( char, strlen( n->type_id ) + 1 ); + type_tag[0] = '\0'; + strcat( type_tag, "!" ); + strcat( type_tag, n->type_id ); + bytestring_append( val, YAMLBYTE_TRANSFER, type_tag, NULL); + S_FREE(type_tag); + } + } + switch (n->kind) + { + case syck_str_kind: + nextcode = YAMLBYTE_SCALAR; + start = n->data.str->ptr; + finish = start + n->data.str->len - 1; + current = start; + /*TRACE2("SCALAR: %s %d", start, n->data.str->len); */ + while(1) { + ch = *current; + if('\n' == ch || 0 == ch || current > finish) { + if(current >= start) { + bytestring_append(val, nextcode, start, current); + nextcode = YAMLBYTE_CONTINUE; + } + start = current + 1; + if(current > finish) + { + break; + } + else if('\n' == ch ) + { + bytestring_append(val,YAMLBYTE_NEWLINE,NULL,NULL); + } + else if(0 == ch) + { + bytestring_append(val,YAMLBYTE_NULLCHAR,NULL,NULL); + } + else + { + assert("oops"); + } + } + current += 1; + } + break; + case syck_seq_kind: + bytestring_append(val,YAMLBYTE_SEQUENCE,NULL,NULL); + for ( i = 0; i < n->data.list->idx; i++ ) + { + oid = syck_seq_read( n, i ); + if (syck_lookup_sym( p, oid, &data )) sav = data; + bytestring_extend(val, sav); + } + bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL); + break; + case syck_map_kind: + bytestring_append(val,YAMLBYTE_MAPPING,NULL,NULL); + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + oid = syck_map_read( n, map_key, i ); + if (syck_lookup_sym( p, oid, &data )) sav = data; + bytestring_extend(val, sav); + oid = syck_map_read( n, map_value, i ); + if (syck_lookup_sym( p, oid, &data )) sav = data; + bytestring_extend(val, sav); + } + bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL); + break; + } + oid = syck_add_sym( p, (char *) val ); + /*TRACE1("Saving: %s", val->buffer );*/ + return oid; +} + +char * +syck_yaml2byte(char *yamlstr) +{ + SYMID oid; + char *ret; + bytestring_t *sav; + void *data; + + SyckParser *parser = syck_new_parser(); + syck_parser_str_auto( parser, yamlstr, NULL ); + syck_parser_handler( parser, syck_yaml2byte_handler ); + syck_parser_error_handler( parser, NULL ); + syck_parser_implicit_typing( parser, 1 ); + syck_parser_taguri_expansion( parser, 1 ); + oid = syck_parse( parser ); + + if ( syck_lookup_sym( parser, oid, &data ) ) { + sav = data; + ret = S_ALLOC_N( char, strlen( sav->buffer ) + 3 ); + ret[0] = '\0'; + strcat( ret, "D\n" ); + strcat( ret, sav->buffer ); + } + else + { + ret = NULL; + } + + syck_free_parser( parser ); + return ret; +} + +#ifdef TEST_YBEXT +#include +int main() { + char *yaml = "test: 1\nand: \"with new\\nline\\n\"\nalso: &3 three\nmore: *3"; + printf("--- # YAML \n"); + printf(yaml); + printf("\n...\n"); + printf(syck_yaml2byte(yaml)); + return 0; +} +#endif + diff --git a/lib/19/syck/ext/yamlbyte.h b/lib/19/syck/ext/yamlbyte.h new file mode 100644 index 0000000000..16ca3d70de --- /dev/null +++ b/lib/19/syck/ext/yamlbyte.h @@ -0,0 +1,171 @@ +/* yamlbyte.h + * + * The YAML bytecode "C" interface header file. See the YAML bytecode + * reference for bytecode sequence rules and for the meaning of each + * bytecode. + */ + +#ifndef YAMLBYTE_H +#define YAMLBYTE_H +#include + +/* define what a character is */ +typedef unsigned char yamlbyte_utf8_t; +typedef unsigned short yamlbyte_utf16_t; +#ifdef YAMLBYTE_UTF8 + #ifdef YAMLBYTE_UTF16 + #error Must only define YAMLBYTE_UTF8 or YAMLBYTE_UTF16 + #endif + typedef yamlbyte_utf8_t yamlbyte_char_t; +#else + #ifdef YAMLBYTE_UTF16 + typedef yamlbyte_utf16_t yamlbyte_char_t; + #else + #error Must define YAMLBYTE_UTF8 or YAMLBYTE_UTF16 + #endif +#endif + +/* specify list of bytecodes */ +#define YAMLBYTE_FINISH ((yamlbyte_char_t) 0) +#define YAMLBYTE_DOCUMENT ((yamlbyte_char_t)'D') +#define YAMLBYTE_DIRECTIVE ((yamlbyte_char_t)'V') +#define YAMLBYTE_PAUSE ((yamlbyte_char_t)'P') +#define YAMLBYTE_MAPPING ((yamlbyte_char_t)'M') +#define YAMLBYTE_SEQUENCE ((yamlbyte_char_t)'Q') +#define YAMLBYTE_END_BRANCH ((yamlbyte_char_t)'E') +#define YAMLBYTE_SCALAR ((yamlbyte_char_t)'S') +#define YAMLBYTE_CONTINUE ((yamlbyte_char_t)'C') +#define YAMLBYTE_NEWLINE ((yamlbyte_char_t)'N') +#define YAMLBYTE_NULLCHAR ((yamlbyte_char_t)'Z') +#define YAMLBYTE_ANCHOR ((yamlbyte_char_t)'A') +#define YAMLBYTE_ALIAS ((yamlbyte_char_t)'R') +#define YAMLBYTE_TRANSFER ((yamlbyte_char_t)'T') +/* formatting bytecodes */ +#define YAMLBYTE_COMMENT ((yamlbyte_char_t)'c') +#define YAMLBYTE_INDENT ((yamlbyte_char_t)'i') +#define YAMLBYTE_STYLE ((yamlbyte_char_t)'s') +/* other bytecodes */ +#define YAMLBYTE_LINE_NUMBER ((yamlbyte_char_t)'#') +#define YAMLBYTE_WHOLE_SCALAR ((yamlbyte_char_t)'<') +#define YAMLBYTE_NOTICE ((yamlbyte_char_t)'!') +#define YAMLBYTE_SPAN ((yamlbyte_char_t)')') +#define YAMLBYTE_ALLOC ((yamlbyte_char_t)'@') + +/* second level style bytecodes, ie "s>" */ +#define YAMLBYTE_FLOW ((yamlbyte_char_t)'>') +#define YAMLBYTE_LITERAL ((yamlbyte_char_t)'|') +#define YAMLBYTE_BLOCK ((yamlbyte_char_t)'b') +#define YAMLBYTE_PLAIN ((yamlbyte_char_t)'p') +#define YAMLBYTE_INLINE_MAPPING ((yamlbyte_char_t)'{') +#define YAMLBYTE_INLINE_SEQUENCE ((yamlbyte_char_t)'[') +#define YAMLBYTE_SINGLE_QUOTED ((yamlbyte_char_t)39) +#define YAMLBYTE_DOUBLE_QUOTED ((yamlbyte_char_t)'"') + +/* + * The "C" API has two variants, one based on instructions, + * with events delivered via pointers; and the other one + * is character based where one or more instructions are + * serialized into a buffer. + * + * Note: In the instruction based API, WHOLE_SCALAR does + * not have the ' {}, + 'ruby.yaml.org,2002' => {} + } + PRIVATE_TYPES = {} + IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ] + end +end diff --git a/lib/19/syck/rubytypes.rb b/lib/19/syck/rubytypes.rb new file mode 100644 index 0000000000..b47045504d --- /dev/null +++ b/lib/19/syck/rubytypes.rb @@ -0,0 +1,465 @@ +# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4 +require 'date' + +class Class + def to_yaml( opts = {} ) + raise TypeError, "can't dump anonymous class %s" % self.class + end +end + +class Object + yaml_as "tag:ruby.yaml.org,2002:object" + def to_yaml_style; end + def to_yaml_properties; instance_variables.sort; end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, to_yaml_style ) do |map| + to_yaml_properties.each do |m| + map.add( m[1..-1], instance_variable_get( m ) ) + end + end + end + end + alias :syck_to_yaml :to_yaml +end + +class Hash + yaml_as "tag:ruby.yaml.org,2002:hash" + yaml_as "tag:yaml.org,2002:map" + def yaml_initialize( tag, val ) + if Array === val + update Hash.[]( *val ) # Convert the map to a sequence + elsif Hash === val + update val + else + raise YAML::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, to_yaml_style ) do |map| + each do |k, v| + map.add( k, v ) + end + end + end + end +end + +class Struct + yaml_as "tag:ruby.yaml.org,2002:struct" + def self.yaml_tag_class_name; self.name.gsub( "Struct::", "" ); end + def self.yaml_tag_read_class( name ); "Struct::#{ name }"; end + def self.yaml_new( klass, tag, val ) + if Hash === val + struct_type = nil + + # + # Use existing Struct if it exists + # + props = {} + val.delete_if { |k,v| props[k] = v if k =~ /^@/ } + begin + struct_name, struct_type = YAML.read_type_class( tag, Struct ) + rescue NameError + end + if not struct_type + struct_def = [ tag.split( ':', 4 ).last ] + struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) ) + end + + # + # Set the Struct properties + # + st = YAML::object_maker( struct_type, {} ) + st.members.each do |m| + st.send( "#{m}=", val[m.to_s] ) + end + props.each do |k,v| + st.instance_variable_set(k, v) + end + st + else + raise YAML::TypeError, "Invalid Ruby Struct: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + # + # Basic struct is passed as a YAML map + # + out.map( taguri, to_yaml_style ) do |map| + self.members.each do |m| + map.add( m.to_s, self[m.to_s] ) + end + self.to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end +end + +class Array + yaml_as "tag:ruby.yaml.org,2002:array" + yaml_as "tag:yaml.org,2002:seq" + def yaml_initialize( tag, val ); concat( val.to_a ); end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.seq( taguri, to_yaml_style ) do |seq| + each do |x| + seq.add( x ) + end + end + end + end +end + +class Exception + yaml_as "tag:ruby.yaml.org,2002:exception" + def Exception.yaml_new( klass, tag, val ) + o = YAML.object_maker( klass, { 'mesg' => val.delete( 'message' ) } ) + val.each_pair do |k,v| + o.instance_variable_set("@#{k}", v) + end + o + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, to_yaml_style ) do |map| + map.add( 'message', message ) + to_yaml_properties.each do |m| + map.add( m[1..-1], instance_variable_get( m ) ) + end + end + end + end +end + +class String + yaml_as "tag:ruby.yaml.org,2002:string" + yaml_as "tag:yaml.org,2002:binary" + yaml_as "tag:yaml.org,2002:str" + def is_complex_yaml? + to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/ + end + def is_binary_data? + self.count("\x00-\x7F", "^ -~\t\r\n").fdiv(self.size) > 0.3 || self.index("\x00") unless self.empty? + end + def String.yaml_new( klass, tag, val ) + val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary" + val = { 'str' => val } if String === val + if Hash === val + s = klass.allocate + # Thank you, NaHi + String.instance_method(:initialize). + bind(s). + call( val.delete( 'str' ) ) + val.each { |k,v| s.instance_variable_set( k, v ) } + s + else + raise YAML::TypeError, "Invalid String: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out| + if is_binary_data? + out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal ) + elsif to_yaml_properties.empty? + out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style ) + else + out.map( taguri, to_yaml_style ) do |map| + map.add( 'str', "#{self}" ) + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end + end +end + +class Symbol + yaml_as "tag:ruby.yaml.org,2002:symbol" + yaml_as "tag:ruby.yaml.org,2002:sym" + def Symbol.yaml_new( klass, tag, val ) + if String === val + val = YAML::load( val ) if val =~ /\A(["']).*\1\z/ + val.intern + else + raise YAML::TypeError, "Invalid Symbol: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + out.scalar( "tag:yaml.org,2002:str", self.inspect, :plain ) + end + end +end + +class Range + yaml_as "tag:ruby.yaml.org,2002:range" + def Range.yaml_new( klass, tag, val ) + inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")' + opts = {} + if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o + r1, rdots, r2 = $1, $2, $3 + opts = { + 'begin' => YAML.load( "--- #{r1}" ), + 'end' => YAML.load( "--- #{r2}" ), + 'excl' => rdots.length == 3 + } + val = {} + elsif Hash === val + opts['begin'] = val.delete('begin') + opts['end'] = val.delete('end') + opts['excl'] = val.delete('excl') + end + if Hash === opts + r = YAML::object_maker( klass, {} ) + # Thank you, NaHi + Range.instance_method(:initialize). + bind(r). + call( opts['begin'], opts['end'], opts['excl'] ) + val.each { |k,v| r.instance_variable_set( k, v ) } + r + else + raise YAML::TypeError, "Invalid Range: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + # if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or + # self.end.is_complex_yaml? or self.end.respond_to? :to_str or + # not to_yaml_properties.empty? + out.map( taguri, to_yaml_style ) do |map| + map.add( 'begin', self.begin ) + map.add( 'end', self.end ) + map.add( 'excl', self.exclude_end? ) + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + # else + # out.scalar( taguri ) do |sc| + # sc.embed( self.begin ) + # sc.concat( self.exclude_end? ? "..." : ".." ) + # sc.embed( self.end ) + # end + # end + end + end +end + +class Regexp + yaml_as "tag:ruby.yaml.org,2002:regexp" + def Regexp.yaml_new( klass, tag, val ) + if String === val and val =~ /^\/(.*)\/([mixn]*)$/ + val = { 'regexp' => $1, 'mods' => $2 } + end + if Hash === val + mods = nil + unless val['mods'].to_s.empty? + mods = 0x00 + mods |= Regexp::EXTENDED if val['mods'].include?( 'x' ) + mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' ) + mods |= Regexp::MULTILINE if val['mods'].include?( 'm' ) + mods |= 32 if val['mods'].include?( 'n' ) + end + val.delete( 'mods' ) + r = YAML::object_maker( klass, {} ) + Regexp.instance_method(:initialize). + bind(r). + call( val.delete( 'regexp' ), mods ) + val.each { |k,v| r.instance_variable_set( k, v ) } + r + else + raise YAML::TypeError, "Invalid Regular expression: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + if to_yaml_properties.empty? + out.scalar( taguri, self.inspect, :plain ) + else + out.map( taguri, to_yaml_style ) do |map| + src = self.inspect + if src =~ /\A\/(.*)\/([a-z]*)\Z/ + map.add( 'regexp', $1 ) + map.add( 'mods', $2 ) + else + raise YAML::TypeError, "Invalid Regular expression: " + src + end + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end + end +end + +class Time + yaml_as "tag:ruby.yaml.org,2002:time" + yaml_as "tag:yaml.org,2002:timestamp" + def Time.yaml_new( klass, tag, val ) + if Hash === val + t = val.delete( 'at' ) + val.each { |k,v| t.instance_variable_set( k, v ) } + t + else + raise YAML::TypeError, "Invalid Time: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + tz = "Z" + # from the tidy Tobias Peters Thanks! + unless self.utc? + utc_same_instant = self.dup.utc + utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec) + difference_to_utc = utc_same_writing - utc_same_instant + if (difference_to_utc < 0) + difference_sign = '-' + absolute_difference = -difference_to_utc + else + difference_sign = '+' + absolute_difference = difference_to_utc + end + difference_minutes = (absolute_difference/60).round + tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60] + end + standard = self.strftime( "%Y-%m-%d %H:%M:%S" ) + standard += ".%06d" % [usec] if usec.nonzero? + standard += " %s" % [tz] + if to_yaml_properties.empty? + out.scalar( taguri, standard, :plain ) + else + out.map( taguri, to_yaml_style ) do |map| + map.add( 'at', standard ) + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end + end +end + +class Date + yaml_as "tag:yaml.org,2002:timestamp#ymd" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain ) + end + end +end + +class Integer + yaml_as "tag:yaml.org,2002:int" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + out.scalar( "tag:yaml.org,2002:int", self.to_s, :plain ) + end + end +end + +class Float + yaml_as "tag:yaml.org,2002:float" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + str = self.to_s + if str == "Infinity" + str = ".Inf" + elsif str == "-Infinity" + str = "-.Inf" + elsif str == "NaN" + str = ".NaN" + end + out.scalar( "tag:yaml.org,2002:float", str, :plain ) + end + end +end + +class Rational + yaml_as "tag:ruby.yaml.org,2002:object:Rational" + def Rational.yaml_new( klass, tag, val ) + if val.is_a? String + Rational( val ) + else + Rational( val['numerator'], val['denominator'] ) + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, nil ) do |map| + map.add( 'denominator', denominator ) + map.add( 'numerator', numerator ) + end + end + end +end + +class Complex + yaml_as "tag:ruby.yaml.org,2002:object:Complex" + def Complex.yaml_new( klass, tag, val ) + if val.is_a? String + Complex( val ) + else + Complex( val['real'], val['image'] ) + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, nil ) do |map| + map.add( 'image', imaginary ) + map.add( 'real', real ) + end + end + end +end + +class TrueClass + yaml_as "tag:yaml.org,2002:bool#yes" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + out.scalar( taguri, "true", :plain ) + end + end +end + +class FalseClass + yaml_as "tag:yaml.org,2002:bool#no" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + out.scalar( taguri, "false", :plain ) + end + end +end + +class NilClass + yaml_as "tag:yaml.org,2002:null" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + out.scalar( taguri, "", :plain ) + end + end +end + diff --git a/lib/19/syck/stream.rb b/lib/19/syck/stream.rb new file mode 100644 index 0000000000..cd77a033c6 --- /dev/null +++ b/lib/19/syck/stream.rb @@ -0,0 +1,41 @@ +module Syck + + # + # YAML::Stream -- for emitting many documents + # + class Stream + + attr_accessor :documents, :options + + def initialize( opts = {} ) + @options = opts + @documents = [] + end + + def []( i ) + @documents[ i ] + end + + def add( doc ) + @documents << doc + end + + def edit( doc_num, doc ) + warn "#{caller[0]}: edit is deprecated" if $VERBOSE + @documents[ doc_num ] = doc + end + + def emit( io = nil ) + # opts = @options.dup + # opts[:UseHeader] = true if @documents.length > 1 + out = Syck.emitter + out.reset( io || io2 = StringIO.new ) + @documents.each { |v| + v.to_yaml( out ) + } + io || ( io2.rewind; io2.read ) + end + + end + +end diff --git a/lib/19/syck/stringio.rb b/lib/19/syck/stringio.rb new file mode 100644 index 0000000000..77a2b827e5 --- /dev/null +++ b/lib/19/syck/stringio.rb @@ -0,0 +1,85 @@ +warn "#{caller[0]}: yaml/stringio is deprecated" if $VERBOSE + +# +# Limited StringIO if no core lib is available +# +begin +require 'stringio' +rescue LoadError + # StringIO based on code by MoonWolf + class StringIO + def initialize(string="") + @string=string + @pos=0 + @eof=(string.size==0) + end + def pos + @pos + end + def eof + @eof + end + alias eof? eof + def readline(rs=$/) + if @eof + raise EOFError + else + if p = @string[@pos..-1]=~rs + line = @string[@pos,p+1] + else + line = @string[@pos..-1] + end + @pos+=line.size + @eof =true if @pos==@string.size + $_ = line + end + end + def rewind + seek(0,0) + end + def seek(offset,whence) + case whence + when 0 + @pos=offset + when 1 + @pos+=offset + when 2 + @pos=@string.size+offset + end + @eof=(@pos>=@string.size) + 0 + end + end + + # + # Class method for creating streams + # + def Syck.make_stream( io ) + if String === io + io = StringIO.new( io ) + elsif not IO === io + raise Syck::Error, "YAML stream must be an IO or String object." + end + if Syck::unicode + def io.readline + Syck.utf_to_internal( readline( @ln_sep ), @utf_encoding ) + end + def io.check_unicode + @utf_encoding = Syck.sniff_encoding( read( 4 ) ) + @ln_sep = Syck.enc_separator( @utf_encoding ) + seek( -4, IO::SEEK_CUR ) + end + def io.utf_encoding + @utf_encoding + end + io.check_unicode + else + def io.utf_encoding + :None + end + end + io + end + +end + diff --git a/lib/19/syck/syck.rb b/lib/19/syck/syck.rb new file mode 100644 index 0000000000..10e5023f46 --- /dev/null +++ b/lib/19/syck/syck.rb @@ -0,0 +1,16 @@ +# +# YAML::Syck module +# .. glues syck and yaml.rb together .. +# +require 'syck/basenode' + +module Syck + + # + # Mixin BaseNode functionality + # + class Node + include Syck::BaseNode + end + +end diff --git a/lib/19/syck/tag.rb b/lib/19/syck/tag.rb new file mode 100644 index 0000000000..62f12c30b4 --- /dev/null +++ b/lib/19/syck/tag.rb @@ -0,0 +1,95 @@ +# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4 +# $Id: tag.rb 27365 2010-04-16 20:31:59Z tenderlove $ +# +# = yaml/tag.rb: methods for associating a taguri to a class. +# +# Author:: why the lucky stiff +# +module Syck + # A dictionary of taguris which map to + # Ruby classes. + @@tagged_classes = {} + + # + # Associates a taguri _tag_ with a Ruby class _cls_. The taguri is used to give types + # to classes when loading YAML. Taguris are of the form: + # + # tag:authorityName,date:specific + # + # The +authorityName+ is a domain name or email address. The +date+ is the date the type + # was issued in YYYY or YYYY-MM or YYYY-MM-DD format. The +specific+ is a name for + # the type being added. + # + # For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the + # +date+. The +specific+ is simply the name of the type: + # + # tag:yaml.org,2002:int + # tag:yaml.org,2002:float + # tag:yaml.org,2002:timestamp + # + # The domain must be owned by you on the +date+ declared. If you don't own any domains on the + # date you declare the type, you can simply use an e-mail address. + # + # tag:why@ruby-lang.org,2004:notes/personal + # + def self.tag_class( tag, cls ) + if @@tagged_classes.has_key? tag + warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag" + end + @@tagged_classes[tag] = cls + end + + # Returns the complete dictionary of taguris, paired with classes. The key for + # the dictionary is the full taguri. The value for each key is the class constant + # associated to that taguri. + # + # YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer + # + def self.tagged_classes + @@tagged_classes + end +end + +class Module + # :stopdoc: + + # Adds a taguri _tag_ to a class, used when dumping or loading the class + # in YAML. See YAML::tag_class for detailed information on typing and + # taguris. + def syck_yaml_as( tag, sc = true ) + verbose, $VERBOSE = $VERBOSE, nil + class_eval <<-"END", __FILE__, __LINE__+1 + attr_writer :taguri + def taguri + if respond_to? :to_yaml_type + Syck.tagurize( to_yaml_type[1..-1] ) + else + return @taguri if defined?(@taguri) and @taguri + tag = #{ tag.dump } + if self.class.yaml_tag_subclasses? and self.class != Syck.tagged_classes[tag] + tag = "\#{ tag }:\#{ self.class.yaml_tag_class_name }" + end + tag + end + end + def self.yaml_tag_subclasses?; #{ sc ? 'true' : 'false' }; end + END + Syck.tag_class tag, self + ensure + $VERBOSE = verbose + end + remove_method :yaml_as rescue nil + alias :yaml_as :syck_yaml_as + + # Transforms the subclass name into a name suitable for display + # in a subclassed tag. + def yaml_tag_class_name + self.name + end + # Transforms the subclass name found in the tag into a Ruby + # constant name. + def yaml_tag_read_class( name ) + name + end + # :startdoc: +end diff --git a/lib/19/syck/types.rb b/lib/19/syck/types.rb new file mode 100644 index 0000000000..5c129acba4 --- /dev/null +++ b/lib/19/syck/types.rb @@ -0,0 +1,192 @@ +# -*- mode: ruby; ruby-indent-level: 4 -*- vim: sw=4 +# +# Classes required by the full core typeset +# + +module Syck + + # + # Default private type + # + class PrivateType + def self.tag_subclasses?; false; end + verbose, $VERBOSE = $VERBOSE, nil + def initialize( type, val ) + @type_id = type; @value = val + @value.taguri = "x-private:#{ @type_id }" + end + def to_yaml( opts = {} ) + @value.to_yaml( opts ) + end + ensure + $VERBOSE = verbose + end + + # + # Default domain type + # + class DomainType + def self.tag_subclasses?; false; end + verbose, $VERBOSE = $VERBOSE, nil + def initialize( domain, type, val ) + @domain = domain; @type_id = type; @value = val + @value.taguri = "tag:#{ @domain }:#{ @type_id }" + end + def to_yaml( opts = {} ) + @value.to_yaml( opts ) + end + ensure + $VERBOSE = verbose + end + + # + # Unresolved objects + # + class Object + def self.tag_subclasses?; false; end + def to_yaml( opts = {} ) + Syck.quick_emit( self, opts ) do |out| + out.map( "tag:ruby.yaml.org,2002:object:#{ @class }", to_yaml_style ) do |map| + @ivars.each do |k,v| + map.add( k, v ) + end + end + end + end + end + + # + # YAML Hash class to support comments and defaults + # + class SpecialHash < ::Hash + attr_accessor :default + def inspect + self.default.to_s + end + def to_s + self.default.to_s + end + def update( h ) + if Syck::SpecialHash === h + @default = h.default if h.default + end + super( h ) + end + def to_yaml( opts = {} ) + opts[:DefaultKey] = self.default + super( opts ) + end + end + + # + # Builtin collection: !omap + # + class Omap < ::Array + yaml_as "tag:yaml.org,2002:omap" + def yaml_initialize( tag, val ) + if Array === val + val.each do |v| + if Hash === v + concat( v.to_a ) # Convert the map to a sequence + else + raise Syck::Error, "Invalid !omap entry: " + val.inspect + end + end + else + raise Syck::Error, "Invalid !omap: " + val.inspect + end + self + end + def self.[]( *vals ) + o = Omap.new + 0.step( vals.length - 1, 2 ) do |i| + o[vals[i]] = vals[i+1] + end + o + end + def []( k ) + self.assoc( k ).to_a[1] + end + def []=( k, *rest ) + val, set = rest.reverse + if ( tmp = self.assoc( k ) ) and not set + tmp[1] = val + else + self << [ k, val ] + end + val + end + def has_key?( k ) + self.assoc( k ) ? true : false + end + def is_complex_yaml? + true + end + def to_yaml( opts = {} ) + Syck.quick_emit( self, opts ) do |out| + out.seq( taguri, to_yaml_style ) do |seq| + self.each do |v| + seq.add( Hash[ *v ] ) + end + end + end + end + end + + # + # Builtin collection: !pairs + # + class Pairs < ::Array + yaml_as "tag:yaml.org,2002:pairs" + def yaml_initialize( tag, val ) + if Array === val + val.each do |v| + if Hash === v + concat( v.to_a ) # Convert the map to a sequence + else + raise Syck::Error, "Invalid !pairs entry: " + val.inspect + end + end + else + raise Syck::Error, "Invalid !pairs: " + val.inspect + end + self + end + def self.[]( *vals ) + p = Pairs.new + 0.step( vals.length - 1, 2 ) { |i| + p[vals[i]] = vals[i+1] + } + p + end + def []( k ) + self.assoc( k ).to_a + end + def []=( k, val ) + self << [ k, val ] + val + end + def has_key?( k ) + self.assoc( k ) ? true : false + end + def is_complex_yaml? + true + end + def to_yaml( opts = {} ) + Syck.quick_emit( self, opts ) do |out| + out.seq( taguri, to_yaml_style ) do |seq| + self.each do |v| + seq.add( Hash[ *v ] ) + end + end + end + end + end + + # + # Builtin collection: !set + # + class Set < ::Hash + yaml_as "tag:yaml.org,2002:set" + end +end diff --git a/lib/19/syck/yamlnode.rb b/lib/19/syck/yamlnode.rb new file mode 100644 index 0000000000..2fa57b1f97 --- /dev/null +++ b/lib/19/syck/yamlnode.rb @@ -0,0 +1,54 @@ +# +# YAML::YamlNode class +# +require 'syck/basenode' + +module Syck + + # + # YAML Generic Model container + # + class YamlNode + include BaseNode + attr_accessor :kind, :type_id, :value, :anchor + def initialize(t, v) + @type_id = t + if Hash === v + @kind = 'map' + @value = {} + v.each {|key,val| + @value[key.transform] = [key, val] + } + elsif Array === v + @kind = 'seq' + @value = v + elsif String === v + @kind = 'scalar' + @value = v + end + end + + # + # Transform this node fully into a native type + # + def transform + t = nil + if @value.is_a? Hash + t = {} + @value.each { |k,v| + t[ k ] = v[1].transform + } + elsif @value.is_a? Array + t = [] + @value.each { |v| + t.push v.transform + } + else + t = @value + end + Syck.transfer_method( @type_id, t ) + end + + end + +end diff --git a/lib/19/syck/ypath.rb b/lib/19/syck/ypath.rb new file mode 100644 index 0000000000..024dcb7f4e --- /dev/null +++ b/lib/19/syck/ypath.rb @@ -0,0 +1,54 @@ +# +# YAML::YPath +# + +warn "#{caller[0]}: YAML::YPath is deprecated" if $VERBOSE + +module Syck + + class YPath + attr_accessor :segments, :predicates, :flags + def initialize( str ) + @segments = [] + @predicates = [] + @flags = nil + while str =~ /^\/?(\/|[^\/\[]+)(?:\[([^\]]+)\])?/ + @segments.push $1 + @predicates.push $2 + str = $' + end + unless str.to_s.empty? + @segments += str.split( "/" ) + end + if @segments.length == 0 + @segments.push "." + end + end + def self.each_path( str ) + # + # Find choices + # + paths = [] + str = "(#{ str })" + while str.sub!( /\(([^()]+)\)/, "\n#{ paths.length }\n" ) + paths.push $1.split( '|' ) + end + + # + # Construct all possible paths + # + all = [ str ] + ( paths.length - 1 ).downto( 0 ) do |i| + all = all.collect do |a| + paths[i].collect do |p| + a.gsub( /\n#{ i }\n/, p ) + end + end.flatten.uniq + end + all.collect do |path| + yield YPath.new( path ) + end + end + end + +end diff --git a/lib/19/yaml/syck.rb b/lib/19/yaml/syck.rb new file mode 100644 index 0000000000..b695967c8b --- /dev/null +++ b/lib/19/yaml/syck.rb @@ -0,0 +1,14 @@ +# $Id$ +# +# = yaml/syck.rb: +# + +require 'stringio' +require 'syck/ext/syck' +require 'syck/error' +require 'syck/syck' +require 'syck/tag' +require 'syck/stream' +require 'syck/constants' +require 'syck/rubytypes' +require 'syck/types' diff --git a/rakelib/extensions.rake b/rakelib/extensions.rake index fe4a7634d8..d531d04623 100644 --- a/rakelib/extensions.rake +++ b/rakelib/extensions.rake @@ -119,9 +119,11 @@ compile_ext "digest:rmd160" compile_ext "digest:sha1" compile_ext "digest:sha2" compile_ext "digest:bubblebabble" -compile_ext "syck", :dir => "lib/18/syck/ext" + compile_ext "melbourne", :task => "rbx", :doc => "for Rubinius" compile_ext "melbourne", :task => "build", :doc => "for bootstrapping" + +compile_ext "syck", :dir => "lib/18/syck/ext" compile_ext "nkf" if BUILD_CONFIG[:readline] == :c_readline @@ -133,6 +135,8 @@ end if BUILD_CONFIG[:libyaml] compile_ext "psych", :deps => ["Makefile"], :dir => "lib/19/psych/ext" +else + compile_ext "syck", :deps => ["Makefile"], :dir => "lib/19/syck/ext", :env => "-X19" end # rbx must be able to run to build these because they use From 7766cf5ca48bdad36e54d6c0b536df8d100e9d85 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Thu, 10 Nov 2011 16:01:51 -0800 Subject: [PATCH 10/67] Clean new-style C-exts. --- rakelib/extensions.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakelib/extensions.rake b/rakelib/extensions.rake index d531d04623..fc919f43fd 100644 --- a/rakelib/extensions.rake +++ b/rakelib/extensions.rake @@ -10,7 +10,7 @@ desc "Build extensions from lib/ext" task :extensions def clean_extension(name) - rm_f FileList["lib/ext/#{name}/*.{o,#{$dlext}}"], :verbose => $verbose + rm_f FileList["lib/**/ext/#{name}/*.{o,#{$dlext}}"], :verbose => $verbose end namespace :extensions do From f64a975af87b07321ed9338a1fc34c82902a4702 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Thu, 10 Nov 2011 16:02:13 -0800 Subject: [PATCH 11/67] Port 1.8 Syck changes to build 1.9 Syck. --- lib/19/syck/ext/rubyext.c | 84 +++++++++++++++------------------------ lib/19/syck/ext/syck.c | 2 +- lib/19/yaml/syck.rb | 39 ++++++++++++++++++ 3 files changed, 73 insertions(+), 52 deletions(-) diff --git a/lib/19/syck/ext/rubyext.c b/lib/19/syck/ext/rubyext.c index cd95339ac1..47436d805a 100644 --- a/lib/19/syck/ext/rubyext.c +++ b/lib/19/syck/ext/rubyext.c @@ -13,6 +13,18 @@ #include #include +#ifdef HAVE_RB_STR_COPIED_PTR +#define syck_copy_string(str) rb_str_copied_ptr(str) +#else +#define syck_copy_string(val) syck_strndup(RSTRING(val)->ptr, RSTRING_LEN(val)) +#endif + +#ifdef HAVE_RB_STR_PTR_READONLY +#define RSTRING_PTR_RO(ptr) rb_str_ptr_readonly(ptr) +#else +#define RSTRING_PTR_RO(ptr) RSTRING_PTR(ptr) +#endif + typedef struct RVALUE { union { #if 0 @@ -21,6 +33,8 @@ typedef struct RVALUE { struct RVALUE *next; } free; #endif + +#if 0 struct RBasic basic; struct RObject object; struct RClass klass; @@ -33,6 +47,7 @@ typedef struct RVALUE { struct RStruct rstruct; /*struct RBignum bignum;*/ /*struct RFile file;*/ +#endif } as; } RVALUE; @@ -54,8 +69,9 @@ static ID s_tags, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, static VALUE sym_model, sym_generic, sym_input, sym_bytecode; static VALUE sym_scalar, sym_seq, sym_map; static VALUE sym_1quote, sym_2quote, sym_fold, sym_literal, sym_plain, sym_inline; -static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter, cDateTime; +static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter; static VALUE oDefaultResolver, oGenericResolver; +static VALUE rb_syck; /* * my private collection of numerical oddities. @@ -321,27 +337,10 @@ mktime_do(struct mktime_arg *arg) } } -SYMID -mktime_r(struct mktime_arg *arg) -{ - if (!cDateTime) { - /* - * Load Date module - */ - rb_require("date"); - cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime")); - } - return rb_funcall(cDateTime, s_parse, 1, rb_str_new(arg->str, arg->len)); -} - SYMID rb_syck_mktime(char *str, long len) { - struct mktime_arg a; - - a.str = str; - a.len = len; - return rb_rescue2(mktime_do, (VALUE)&a, mktime_r, (VALUE)&a, rb_eArgError, NULL); + return rb_funcall(rb_syck, rb_intern("mktime"), 1, rb_str_new(str, len)); } /* @@ -603,7 +602,7 @@ yaml_org_handler( SyckNode *n, VALUE *ref ) VALUE dup = rb_funcall( tmph, s_dup, 0 ); tmp = rb_ary_reverse( tmp ); rb_ary_push( tmp, obj ); - rb_block_call( tmp, s_each, 0, 0, syck_merge_i, dup ); + rb_funcall( rb_syck, rb_intern("merge_i"), tmp, dup ); obj = dup; skip_aset = 1; } @@ -662,7 +661,7 @@ rb_syck_load_handler(SyckParser *p, SyckNode *n) if ( bonus->taint) OBJ_TAINT( obj ); if ( bonus->proc != 0 ) rb_funcall(bonus->proc, s_call, 1, obj); - rb_hash_aset(bonus->data, INT2FIX(RHASH_SIZE(bonus->data)), obj); + rb_hash_aset(bonus->data, rb_hash_size(bonus->data), obj); return obj; } @@ -678,7 +677,7 @@ rb_syck_err_handler(SyckParser *p, const char *msg) endl++; endl[0] = '\0'; - rb_raise(rb_eArgError, "%s on line %d, col %"PRIdPTRDIFF": `%s'", + rb_raise(rb_eArgError, "%s on line %d, col %d: `%s'", msg, p->linect, p->cursor - p->lineptr, @@ -1009,7 +1008,7 @@ syck_resolver_node_import(VALUE self, VALUE node) VALUE dup = rb_funcall( end, s_dup, 0 ); v = rb_ary_reverse( v ); rb_ary_push( v, obj ); - rb_block_call( v, s_each, 0, 0, syck_merge_i, dup ); + rb_funcall( rb_syck, rb_intern("merge_i"), v, dup ); obj = dup; skip_aset = 1; } @@ -1036,23 +1035,6 @@ syck_resolver_node_import(VALUE self, VALUE node) return obj; } -/* - * Set instance variables - */ -VALUE -syck_set_ivars(VALUE vars, VALUE obj) -{ - VALUE ivname = rb_ary_entry( vars, 0 ); - char *ivn; - StringValue( ivname ); - ivn = S_ALLOCA_N( char, RSTRING_LEN(ivname) + 2 ); - ivn[0] = '@'; - ivn[1] = '\0'; - strncat( ivn, RSTRING_PTR(ivname), RSTRING_LEN(ivname) ); - rb_iv_set( obj, ivn, rb_ary_entry( vars, 1 ) ); - return Qnil; -} - /* * YAML::Syck::Resolver#const_find */ @@ -1062,7 +1044,7 @@ syck_const_find(VALUE const_name) VALUE tclass = rb_cObject; VALUE tparts = rb_str_split( const_name, "::" ); int i = 0; - for ( i = 0; i < RARRAY_LEN(tparts); i++ ) { + for ( i = 0; i < rb_ary_size(tparts); i++ ) { VALUE tpart = rb_to_id( rb_ary_entry( tparts, i ) ); if ( !rb_const_defined( tclass, tpart ) ) return Qnil; tclass = rb_const_get( tclass, tpart ); @@ -1116,7 +1098,7 @@ syck_resolver_transfer(VALUE self, VALUE type, VALUE val) if ( ! NIL_P( target_class ) ) { subclass = target_class; - if ( RARRAY_LEN(subclass_parts) > 0 && rb_respond_to( target_class, s_tag_subclasses ) && + if ( rb_ary_size(subclass_parts) > 0 && rb_respond_to( target_class, s_tag_subclasses ) && RTEST( rb_funcall( target_class, s_tag_subclasses, 0 ) ) ) { VALUE subclass_v; @@ -1175,7 +1157,7 @@ syck_resolver_transfer(VALUE self, VALUE type, VALUE val) } else if ( !NIL_P( obj ) && rb_obj_is_instance_of( val, rb_cHash ) ) { - rb_block_call( val, s_each, 0, 0, syck_set_ivars, obj ); + rb_funcall( rb_syck, rb_intern("set_ivars"), 2, val, obj ); } } else @@ -1211,7 +1193,7 @@ syck_resolver_tagurize(VALUE self, VALUE val) if ( !NIL_P(tmp) ) { - char *taguri = syck_type_id_to_uri( RSTRING_PTR(tmp) ); + char *taguri = syck_type_id_to_uri( RSTRING_PTR_RO(tmp) ); val = rb_str_new2( taguri ); S_FREE( taguri ); } @@ -1231,7 +1213,7 @@ syck_defaultresolver_detect_implicit(VALUE self, VALUE val) if ( !NIL_P(tmp) ) { val = tmp; - type_id = syck_match_implicit( RSTRING_PTR(val), RSTRING_LEN(val) ); + type_id = syck_match_implicit( RSTRING_PTR_RO(val), RSTRING_LEN(val) ); return rb_str_new2( type_id ); } @@ -1496,7 +1478,7 @@ syck_scalar_value_set(VALUE self, VALUE val) Data_Get_Struct( self, SyckNode, node ); StringValue( val ); - node->data.str->ptr = syck_strndup( RSTRING_PTR(val), RSTRING_LEN(val) ); + node->data.str->ptr = syck_copy_string(val); node->data.str->len = RSTRING_LEN(val); node->data.str->style = scalar_none; @@ -1632,7 +1614,7 @@ syck_map_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style) } keys = rb_funcall( hsh, s_keys, 0 ); - for ( i = 0; i < RARRAY_LEN(keys); i++ ) + for ( i = 0; i < rb_ary_size(keys); i++ ) { VALUE key = rb_ary_entry(keys, i); syck_map_add( node, key, rb_hash_aref(hsh, key) ); @@ -1667,7 +1649,7 @@ syck_map_value_set(VALUE self, VALUE val) syck_map_empty( node ); keys = rb_funcall( hsh, s_keys, 0 ); - for ( i = 0; i < RARRAY_LEN(keys); i++ ) + for ( i = 0; i < rb_ary_size(keys); i++ ) { VALUE key = rb_ary_entry(keys, i); syck_map_add( node, key, rb_hash_aref(hsh, key) ); @@ -1756,7 +1738,7 @@ syck_node_type_id_set(VALUE self, VALUE type_id) if ( !NIL_P( type_id ) ) { StringValue( type_id ); - node->type_id = syck_strndup( RSTRING_PTR(type_id), RSTRING_LEN(type_id) ); + node->type_id = syck_copy_string(type_id); } rb_iv_set( self, "@type_id", type_id ); @@ -2012,7 +1994,7 @@ syck_emitter_emit(int argc, VALUE *argv, VALUE self) if ( !NIL_P( oid ) && RTEST( rb_funcall( bonus->data, s_haskey, 1, oid ) ) ) { symple = rb_hash_aref( bonus->data, oid ); } else { - symple = rb_funcall( proc, s_call, 1, rb_ivar_get( self, s_out ) ); + symple = rb_yield(rb_ivar_get( self, s_out )); } syck_emitter_mark_node( emitter, (st_data_t)symple ); @@ -2112,7 +2094,7 @@ syck_out_scalar(int argc, VALUE *argv, VALUE self) void Init_syck() { - VALUE rb_syck = rb_define_module_under( rb_cObject, "Syck" ); + rb_syck = rb_define_module_under( rb_cObject, "Syck" ); rb_define_module_function( rb_syck, "compile", rb_syck_compile, 1 ); /* diff --git a/lib/19/syck/ext/syck.c b/lib/19/syck/ext/syck.c index 8b4947aaf8..0d50cbadb1 100644 --- a/lib/19/syck/ext/syck.c +++ b/lib/19/syck/ext/syck.c @@ -516,7 +516,7 @@ syck_parse( SyckParser *p ) void syck_default_error_handler( SyckParser *p, const char *msg ) { - printf( "Error at [Line %d, Col %"PRIdPTRDIFF"]: %s\n", + printf( "Error at [Line %d, Col %d]: %s\n", p->linect, p->cursor - p->lineptr, msg ); diff --git a/lib/19/yaml/syck.rb b/lib/19/yaml/syck.rb index b695967c8b..d1f241665c 100644 --- a/lib/19/yaml/syck.rb +++ b/lib/19/yaml/syck.rb @@ -12,3 +12,42 @@ require 'syck/constants' require 'syck/rubytypes' require 'syck/types' + +module Syck + #-- + # For Rubinius, replaces the rb_iterate call to syck_set_ivars. + #++ + def self.set_ivars(hsh, obj) + hsh.each do |key, value| + obj.instance_variable_set :"@#{key}", value + end + end + + #-- + # For Rubinius, replaces the rb_iterate call to syck_merge_i. + #++ + def self.merge_i(ary, hsh) + ary.each do |entry| + begin + entry = Rubinius::Type.coerce_to entry, Hash, :to_hash + hsh.update entry + rescue + # ignore coercion errors + end + end + + nil + end + + #-- + # For Rubinius, replaces rb_syck_mktime. + #++ + def self.mktime(str) + require "date" + begin + DateTime.parse str + rescue ArgumentError + # nothing + end + end +end From a948d93fdf0c1dafd38874f76148bfa712cbe6e7 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Thu, 10 Nov 2011 16:07:55 -0800 Subject: [PATCH 12/67] Enable yaml specs in 1.9 mode and tag failures. --- spec/rbx.1.9.mspec | 1 - spec/tags/19/ruby/library/yaml/load_tags.txt | 2 ++ spec/tags/19/ruby/library/yaml/to_yaml_tags.txt | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 spec/tags/19/ruby/library/yaml/load_tags.txt create mode 100644 spec/tags/19/ruby/library/yaml/to_yaml_tags.txt diff --git a/spec/rbx.1.9.mspec b/spec/rbx.1.9.mspec index 0908ea2d98..ee4a1edec3 100644 --- a/spec/rbx.1.9.mspec +++ b/spec/rbx.1.9.mspec @@ -97,7 +97,6 @@ class MSpecScript '^spec/ruby/library/logger', '^spec/ruby/library/net', '^spec/ruby/library/uri', - '^spec/ruby/library/yaml', '^spec/ruby/library/zlib', '^spec/ruby/optional/capi/class', diff --git a/spec/tags/19/ruby/library/yaml/load_tags.txt b/spec/tags/19/ruby/library/yaml/load_tags.txt new file mode 100644 index 0000000000..66b7f19b28 --- /dev/null +++ b/spec/tags/19/ruby/library/yaml/load_tags.txt @@ -0,0 +1,2 @@ +fails:YAML.load with iso8601 timestamp computes the microseconds +fails:YAML.load with iso8601 timestamp rounds values smaller than 1 usec to 0 diff --git a/spec/tags/19/ruby/library/yaml/to_yaml_tags.txt b/spec/tags/19/ruby/library/yaml/to_yaml_tags.txt new file mode 100644 index 0000000000..380530d80d --- /dev/null +++ b/spec/tags/19/ruby/library/yaml/to_yaml_tags.txt @@ -0,0 +1 @@ +fails:Object#to_yaml returns the YAML representation of a Error object From ff83beacc5cc3d1e109da3494b91af7e6ef97281 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Thu, 10 Nov 2011 16:31:59 -0800 Subject: [PATCH 13/67] More 1337 h4x for installing C-exts. --- rakelib/install.rake | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/rakelib/install.rake b/rakelib/install.rake index 6d75f471c7..17a29d567a 100644 --- a/rakelib/install.rake +++ b/rakelib/install.rake @@ -133,8 +133,16 @@ namespace :install do end # New C extensions - FileList["lib/{18,19}/readline/ext/*.#{$dlext}"].each do |name| - install_file name, /^lib/, BUILD_CONFIG[:lib_path] + ["readline", "syck"].each do |lib| + FileList["lib/18/#{lib}/ext/*.#{$dlext}"].each do |name| + install_file name, /^lib/, BUILD_CONFIG[:lib_path] + end + end + + ["psych", "readline", "syck"].each do |lib| + FileList["lib/19/#{lib}/ext/*.#{$dlext}"].each do |name| + install_file name, /^lib/, BUILD_CONFIG[:lib_path] + end end # Install pre-installed gems From 8e81ab4e738785e96da18143654ee5213f767a07 Mon Sep 17 00:00:00 2001 From: Gaston Ramos Date: Thu, 10 Nov 2011 21:58:59 -0300 Subject: [PATCH 14/67] - fix-a-failing-spec spanish translation done --- web/doc/es/how-to/fix-a-failing-spec.markdown | 39 ++++++++----------- web/doc/es/how-to/write-a-ruby-spec.markdown | 1 - 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/web/doc/es/how-to/fix-a-failing-spec.markdown b/web/doc/es/how-to/fix-a-failing-spec.markdown index 04f4721776..7c62d2ba18 100644 --- a/web/doc/es/how-to/fix-a-failing-spec.markdown +++ b/web/doc/es/how-to/fix-a-failing-spec.markdown @@ -8,32 +8,25 @@ next_url: how-to/write-a-blog-post translated: true --- -Make sure you have read: +Asegúrese de haber leido: * [Getting Started](/doc/es/getting-started/) * [Specs](/doc/es/specs/) -Then, follow these steps to fix a failing spec: +Luego, siga estos pasos para arreglar una spec que falla: - 1. Run `rake` to ensure that all CI specs are passing. - 2. Run `bin/mspec spec/some/spec_file.rb` to confirm the spec fails. - 3. Edit a file somewhere in Rubinius (probably under the kernel directory). - 4. Run `rake build` to build your change. - 5. Run `bin/mspec spec/some/spec_file.rb` to see if your change makes the - spec pass. - 6. Repeat until your spec passes. - 7. Run `rake` to ensure there are no regressions. - 8. Change directory to Rubinius root if not already there. - 9. Run `git status, git add, git commit`, etc. Any changes made to the spec - files under the spec/ruby directory must be in a different commit from - changes made to other Rubinius source code files. - 10. Run `git format-patch origin`, which will extract commits that the current - branch accumulated since the last pull from origin, or `git format-patch - -N', where N is the number (1, 2, etc.) of commits for which you want to - generate patches. - 11. Create a gist with your patch and link to it in a ticket on the issue - tracker at http://github.com/rubinius/rubinius/issues. You can add multiple - patches to one ticket. + 1. Ejecute `rake` para asegurarse que todas las specs de CI están pasando. + 2. Ejecute `bin/mspec spec/some/spec_file.rb` para confirmar que la spec falla. + 3. Edite un archivo en algún lugar en Rubinius (probablemente en el directorio kernel). + 4. Ejecute `rake build` para construir su cambio. + 5. Ejecute `bin/mspec spec/some/spec_file.rb` para ver que su cambio hace que las spec pasen. + 6. Repita hasta que su spec pase. + 7. Ejecute `rake` para asegurarse que no hay regresiones. + 8. Cambie al directorio raíz de Rubinius si todavía no está en él. + 9. Ejecute `git status, git add, git commit`, etc. Cualquier cambio hecho a los archivos de spec en el directorio spec/ruby debe estar en un commit diferente al de los cambios hechos en los demás archivos del código de Rubinius. + 10. Ejecute `git format-patch origin`, el cual extraerá los commits del branch actual acumulados desde el último pull desde origin, o `git format-patch + -N', donde N es el número (1, 2, etc.) de commits con los que ud. quiere generar los parches. + 11. Cree un gist con su patch y linkeelo en el ticket del issue tracker en http://github.com/rubinius/rubinius/issues. Puede agregar múltiples parches a un ticket. -When your patch is accepted by the Rubinius project, you'll get a commit bit -for the Rubinius repository. Let Evan know what your Github username is. +Cuando su parche es aceptado en el project Rubinius, va a obtener commit bit +para el repositorio de Rubinius. Hágale saber a Evan cual es su usuario de Github. diff --git a/web/doc/es/how-to/write-a-ruby-spec.markdown b/web/doc/es/how-to/write-a-ruby-spec.markdown index 471f39482a..7017f83ac8 100644 --- a/web/doc/es/how-to/write-a-ruby-spec.markdown +++ b/web/doc/es/how-to/write-a-ruby-spec.markdown @@ -5,7 +5,6 @@ previous: Escribir un ticket previous_url: how-to/write-a-ticket next: Fix a Failing Spec next_url: how-to/fix-a-failing-spec -translated: true --- Asegúrese de haber leído: From fb64f53088f142dd3e9b3540809b7e41c6f3cc2f Mon Sep 17 00:00:00 2001 From: Gaston Ramos Date: Thu, 10 Nov 2011 22:01:30 -0300 Subject: [PATCH 15/67] - I forgot to remove translated: true --- web/doc/es/how-to/fix-a-failing-spec.markdown | 1 - 1 file changed, 1 deletion(-) diff --git a/web/doc/es/how-to/fix-a-failing-spec.markdown b/web/doc/es/how-to/fix-a-failing-spec.markdown index 7c62d2ba18..7bcce6f3bb 100644 --- a/web/doc/es/how-to/fix-a-failing-spec.markdown +++ b/web/doc/es/how-to/fix-a-failing-spec.markdown @@ -5,7 +5,6 @@ previous: Write a Ruby Spec previous_url: how-to/write-a-ruby-spec next: Write a Blog Post next_url: how-to/write-a-blog-post -translated: true --- Asegúrese de haber leido: From 978ee887d303cc96046858538690d65252ad2e04 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Thu, 10 Nov 2011 17:54:42 -0800 Subject: [PATCH 16/67] Build Syck even if Psych is available because Syck is still 1.9 default. --- Rakefile | 2 +- configure | 2 +- rakelib/extensions.rake | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Rakefile b/Rakefile index 7e4a57b169..f33e4a1f22 100644 --- a/Rakefile +++ b/Rakefile @@ -33,7 +33,7 @@ end require config_rb BUILD_CONFIG = Rubinius::BUILD_CONFIG -unless BUILD_CONFIG[:config_version] == 142 +unless BUILD_CONFIG[:config_version] == 143 STDERR.puts "Your configuration is outdated, please run ./configure first" exit 1 end diff --git a/configure b/configure index 740cd32979..76314152d4 100755 --- a/configure +++ b/configure @@ -115,7 +115,7 @@ class Configure @libversion = "2.0" @version = "#{@libversion}.0dev" @release_date = "yyyy-mm-dd" - @config_version = 142 + @config_version = 143 # TODO: add conditionals for platforms if RbConfig::CONFIG["build_os"] =~ /darwin/ diff --git a/rakelib/extensions.rake b/rakelib/extensions.rake index fc919f43fd..9b7975f1b6 100644 --- a/rakelib/extensions.rake +++ b/rakelib/extensions.rake @@ -134,11 +134,11 @@ if BUILD_CONFIG[:readline] == :c_readline end if BUILD_CONFIG[:libyaml] - compile_ext "psych", :deps => ["Makefile"], :dir => "lib/19/psych/ext" -else - compile_ext "syck", :deps => ["Makefile"], :dir => "lib/19/syck/ext", :env => "-X19" + compile_ext "psych", :deps => ["Makefile"], :dir => "lib/19/psych/ext", :env => "-X19" end +compile_ext "syck", :deps => ["Makefile"], :dir => "lib/19/syck/ext", :env => "-X19" + # rbx must be able to run to build these because they use # extconf.rb, so they must be after melbourne for Rubinius. compile_ext "openssl", :deps => ["Makefile", "extconf.h"] From b2825d2da10dd8f7803f90dd890da83e6714677a Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Thu, 10 Nov 2011 18:20:00 -0800 Subject: [PATCH 17/67] Removed 1.9 Syck Makefile. --- lib/19/syck/ext/Makefile | 181 --------------------------------------- 1 file changed, 181 deletions(-) delete mode 100644 lib/19/syck/ext/Makefile diff --git a/lib/19/syck/ext/Makefile b/lib/19/syck/ext/Makefile deleted file mode 100644 index c768a8fa4b..0000000000 --- a/lib/19/syck/ext/Makefile +++ /dev/null @@ -1,181 +0,0 @@ - -SHELL = /bin/sh - -#### Start of system configuration section. #### - -srcdir = . -topdir = /source/rubinius/rubinius/vm/capi/19/include -hdrdir = /source/rubinius/rubinius/vm/capi/19/include -arch_hdrdir = /source/rubinius/rubinius/vm/capi/19/include -VPATH = $(srcdir):$(hdrdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby -prefix = $(DESTDIR)/source/rubinius/rubinius -install_prefix = $(DESTDIR) -exec_prefix = $(prefix) -bindir = $(DESTDIR)/source/rubinius/rubinius/bin -sbindir = $(exec_prefix)/sbin -libexecdir = $(exec_prefix)/libexec -datarootdir = $(prefix)/share -datadir = $(datarootdir) -sysconfdir = $(prefix)/etc -sharedstatedir = $(prefix)/com -localstatedir = $(prefix)/var -includedir = $(prefix)/include -oldincludedir = $(DESTDIR)/usr/include -docdir = $(datarootdir)/doc/$(PACKAGE) -infodir = $(datarootdir)/info -htmldir = $(docdir) -dvidir = $(docdir) -pdfdir = $(docdir) -psdir = $(docdir) -libdir = $(exec_prefix)/lib -localedir = $(datarootdir)/locale -mandir = $(datarootdir)/man -rubyhdrdir = $(DESTDIR)/source/rubinius/rubinius/vm/capi/19/include -sitedir = $(DESTDIR)/source/rubinius/rubinius/lib/site -sitelibdir = $(DESTDIR)/source/rubinius/rubinius/lib/site -rubylibdir = $(DESTDIR)/source/rubinius/rubinius/lib/site -archdir = $(DESTDIR)/source/rubinius/rubinius/lib/site/x86_64-darwin10.8.0 -sitearchdir = $(DESTDIR)/source/rubinius/rubinius/lib/site/x86_64-darwin10.8.0 - -CC = gcc -CXX = g++ -LIBRUBY = $(LIBRUBY_SO) -LIBRUBY_A = -LIBRUBYARG_SHARED = -LIBRUBYARG_STATIC = -OUTFLAG = -o -COUTFLAG = -o - -RUBY_EXTCONF_H = -cflags = -optflags = -debugflags = -warnflags = -CFLAGS = -fPIC -ggdb3 -fPIC -O2 -INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) -DEFS = -CPPFLAGS = -CXXFLAGS = $(CFLAGS) -ldflags = -dldflags = -ARCH_FLAG = -DLDFLAGS = $(ldflags) $(dldflags) -LDSHARED = gcc -bundle -undefined suppress -flat_namespace -LDSHAREDXX = $(LDSHARED) -AR = ar -EXEEXT = - -RUBY_BASE_NAME = -RUBY_INSTALL_NAME = rbx -RUBY_SO_NAME = rubinius-2.0.0dev -arch = x86_64-darwin10.8.0 -sitearch = x86_64-darwin10.8.0 -ruby_version = 1.9 -ruby = /source/rubinius/rubinius/bin/rbx -RUBY = $(ruby) -RM = rm -f -RM_RF = $(RUBY) -run -e rm -- -rf -RMDIRS = $(RUBY) -run -e rmdir -- -p -MAKEDIRS = mkdir -p -INSTALL = install -c -INSTALL_PROG = $(INSTALL) -m 0755 -INSTALL_DATA = $(INSTALL) -m 644 -COPY = cp - -#### End of system configuration section. #### - -preload = - -libpath = . $(libdir) -LIBPATH = -L. -L$(libdir) -DEFFILE = - -CLEANFILES = mkmf.log -DISTCLEANFILES = -DISTCLEANDIRS = - -extout = -extout_prefix = -target_prefix = -LOCAL_LIBS = -LIBS = $(LIBRUBYARG_STATIC) -SRCS = bytecode.c emitter.c gram.c handler.c implicit.c node.c rubyext.c syck.c token.c yaml2byte.c -OBJS = bytecode.o emitter.o gram.o handler.o implicit.o node.o rubyext.o syck.o token.o yaml2byte.o -TARGET = syck -DLLIB = $(TARGET).bundle -EXTSTATIC = -STATIC_LIB = - -BINDIR = $(bindir) -RUBYCOMMONDIR = $(sitedir)$(target_prefix) -RUBYLIBDIR = $(sitelibdir)$(target_prefix) -RUBYARCHDIR = $(sitearchdir)$(target_prefix) -HDRDIR = $(rubyhdrdir)/ruby$(target_prefix) -ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix) - -TARGET_SO = $(DLLIB) -CLEANLIBS = $(TARGET).bundle -CLEANOBJS = *.o *.bak - -all: $(DLLIB) -static: $(STATIC_LIB) -.PHONY: all install static install-so install-rb -.PHONY: clean clean-so clean-rb - -clean-rb-default:: -clean-rb:: -clean-so:: -clean: clean-so clean-rb-default clean-rb - @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) - -distclean-rb-default:: -distclean-rb:: -distclean-so:: -distclean: clean distclean-so distclean-rb-default distclean-rb - @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log - @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) - @-$(RMDIRS) $(DISTCLEANDIRS) - -realclean: distclean -install: install-so install-rb - -install-so: $(RUBYARCHDIR) -install-so: $(RUBYARCHDIR)/$(DLLIB) -$(RUBYARCHDIR)/$(DLLIB): $(DLLIB) - @-$(MAKEDIRS) $(@D) - $(INSTALL_PROG) $(DLLIB) $(@D) -install-rb: pre-install-rb install-rb-default -install-rb-default: pre-install-rb-default -pre-install-rb: Makefile -pre-install-rb-default: Makefile -$(RUBYARCHDIR): - $(MAKEDIRS) $@ - -site-install: site-install-so site-install-rb -site-install-so: install-so -site-install-rb: install-rb - -.SUFFIXES: .c .m .cc .cxx .cpp .C .o - -.cc.o: - $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< - -.cxx.o: - $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< - -.cpp.o: - $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< - -.C.o: - $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< - -.c.o: - $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $< - -$(DLLIB): $(OBJS) Makefile - @-$(RM) $(@) - $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) - - - -$(OBJS): $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/config.h From 45c4c249197146f13ed1b51403a4e45618e13b4d Mon Sep 17 00:00:00 2001 From: Karol Hosiawa Date: Fri, 28 Oct 2011 17:53:59 +0200 Subject: [PATCH 18/67] Updated Date specs --- spec/ruby/library/date/civil_spec.rb | 63 ---------- spec/ruby/library/date/commercial_spec.rb | 64 ---------- spec/ruby/library/date/constants_spec.rb | 18 +-- spec/ruby/library/date/exist1_spec.rb | 7 +- spec/ruby/library/date/exist2_spec.rb | 7 +- spec/ruby/library/date/exist3_spec.rb | 7 +- spec/ruby/library/date/exist_spec.rb | 7 +- spec/ruby/library/date/existw_spec.rb | 7 +- spec/ruby/library/date/gregorian_leap_spec.rb | 14 ++- spec/ruby/library/date/gregorian_spec.rb | 35 ++---- spec/ruby/library/date/jd_spec.rb | 9 +- spec/ruby/library/date/julian_leap_spec.rb | 11 +- spec/ruby/library/date/julian_spec.rb | 75 ++---------- spec/ruby/library/date/minus_spec.rb | 8 +- spec/ruby/library/date/new0_spec.rb | 7 +- spec/ruby/library/date/new1_spec.rb | 7 +- spec/ruby/library/date/new2_spec.rb | 7 +- spec/ruby/library/date/new3_spec.rb | 7 +- spec/ruby/library/date/new_spec.rb | 15 +-- spec/ruby/library/date/newsg_spec.rb | 6 +- spec/ruby/library/date/neww_spec.rb | 6 +- spec/ruby/library/date/ns_spec.rb | 12 +- spec/ruby/library/date/ordinal_spec.rb | 111 +----------------- spec/ruby/library/date/os_spec.rb | 12 +- spec/ruby/library/date/plus_spec.rb | 16 ++- spec/ruby/library/date/sg_spec.rb | 6 +- spec/ruby/library/date/shared/civil.rb | 4 +- spec/ruby/library/date/shared/jd.rb | 14 +++ spec/ruby/library/date/shared/new_bang.rb | 14 +++ spec/ruby/library/date/shared/ordinal.rb | 42 +++++++ spec/ruby/library/date/shared/valid_civil.rb | 69 +++++++++++ .../library/date/shared/valid_commercial.rb | 66 +++++++++++ spec/ruby/library/date/shared/valid_jd.rb | 36 ++++++ .../ruby/library/date/shared/valid_ordinal.rb | 60 ++++++++++ spec/ruby/library/date/valid_civil_spec.rb | 8 +- .../library/date/valid_commercial_spec.rb | 8 +- spec/ruby/library/date/valid_date_spec.rb | 2 +- spec/ruby/library/date/valid_jd_spec.rb | 6 +- spec/ruby/library/date/valid_ordinal_spec.rb | 6 +- 39 files changed, 484 insertions(+), 395 deletions(-) create mode 100644 spec/ruby/library/date/shared/jd.rb create mode 100644 spec/ruby/library/date/shared/new_bang.rb create mode 100644 spec/ruby/library/date/shared/ordinal.rb create mode 100644 spec/ruby/library/date/shared/valid_civil.rb create mode 100644 spec/ruby/library/date/shared/valid_commercial.rb create mode 100644 spec/ruby/library/date/shared/valid_jd.rb create mode 100644 spec/ruby/library/date/shared/valid_ordinal.rb diff --git a/spec/ruby/library/date/civil_spec.rb b/spec/ruby/library/date/civil_spec.rb index f0fc747ae3..36e790aecd 100644 --- a/spec/ruby/library/date/civil_spec.rb +++ b/spec/ruby/library/date/civil_spec.rb @@ -6,69 +6,6 @@ it_behaves_like(:date_civil, :civil) end -# reference: -# October 1582 (the Gregorian calendar, Civil Date) -# S M Tu W Th F S -# 1 2 3 4 15 16 -# 17 18 19 20 21 22 23 -# 24 25 26 27 28 29 30 -# 31 - -describe "Date#valid_civil?" do - - ruby_version_is "" ... "1.9" do - it "should be able to determine if a date is valid" do - Date.valid_civil?(1582, 10, 14).should == nil - Date.valid_civil?(1582, 10, 15).should == Date.civil(1582, 10, 15).jd - Date.valid_civil?(1582, 10, 14, Date::ENGLAND).should_not == nil - Date.valid_civil?(1582, 10, 14, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND).jd - end - - it "should be able to handle negative months and days" do - # October 1582 (the Gregorian calendar, Civil Date in 1.8) - # S M Tu W Th F S - # -31 -30 -29 -28 -17 -16 - # -15 -14 -13 -12 -11 -10 -9 - # -8 -7 -6 -5 -4 -3 -2 - # -1 - Date.valid_civil?(1582, -3, -31).should == Date.civil(1582, 10, 1).jd - Date.valid_civil?(1582, -3, -28).should == Date.civil(1582, 10, 4).jd - Date.valid_civil?(1582, -3, -27).should == nil - Date.valid_civil?(1582, -3, -22).should == nil - Date.valid_civil?(1582, -3, -21).should == nil - Date.valid_civil?(1582, -3, -18).should == nil - Date.valid_civil?(1582, -3, -17).should == Date.civil(1582, 10, 15).jd - - Date.valid_civil?(2007, -11, -10).should == Date.civil(2007, 2, 19).jd - Date.valid_civil?(2008, -11, -10).should == Date.civil(2008, 2, 20).jd - end - end - - ruby_version_is "1.9" do - it "should be able to determine if a date is valid" do - Date.valid_civil?(1582, 10, 14).should == false - Date.valid_civil?(1582, 10, 15).should == true - Date.valid_civil?(1582, 10, 14, Date::ENGLAND).should == true - end - - it "should be able to handle negative months and days" do - # October 1582 (the Gregorian calendar, Civil Date in 1.9) - # S M Tu W Th F S - # -21 -20 -19 -18 -17 -16 - # -15 -14 -13 -12 -11 -10 -9 - # -8 -7 -6 -5 -4 -3 -2 - # -1 - Date.valid_civil?(1582, -3, -22).should == false - Date.valid_civil?(1582, -3, -21).should == true - Date.valid_civil?(1582, -3, -18).should == true - Date.valid_civil?(1582, -3, -17).should == true - - Date.valid_civil?(2007, -11, -10).should == true - Date.valid_civil?(2008, -11, -10).should == true - end - end - -end describe "Date.civil" do it "needs to be reviewed for spec completeness" diff --git a/spec/ruby/library/date/commercial_spec.rb b/spec/ruby/library/date/commercial_spec.rb index 4d5c7954e0..bb6671eda1 100644 --- a/spec/ruby/library/date/commercial_spec.rb +++ b/spec/ruby/library/date/commercial_spec.rb @@ -16,67 +16,3 @@ # 24 25 26 27 28 29 30 # 31 -describe "Date#valid_commercial?" do - - ruby_version_is "" ... "1.9" do - it "should be able to determine if the date is a valid commercial date" do - # October 1582 (the Gregorian calendar, Commercial Date in 1.8) - # M Tu W Th F Sa Su - # 41: - - - - 5 6 7 - # 42: 1 2 3 4 5 6 7 - # 43: 1 2 3 4 5 6 7 - Date.valid_commercial?(1582, 41, 4).should == nil - Date.valid_commercial?(1582, 41, 5).should == Date.civil(1582, 10, 15).jd - # valid_commercial? can't handle dates before the Gregorian calendar - Date.valid_commercial?(1582, 41, 4, Date::ENGLAND).should == nil - Date.valid_commercial?(1752, 37, 4, Date::ENGLAND).should == Date.civil(1752, 9, 14, Date::ENGLAND).jd - end - - it "should be able to handle negative week and day numbers" do - # October 1582 (the Gregorian calendar, Commercial Date in 1.8) - # M Tu W Th F Sa Su - # -12: - - - - -3 -2 -1 - # -11: -7 -6 -5 -4 -3 -2 -1 - # -10: -7 -6 -5 -4 -3 -2 -1 - Date.valid_commercial?(1582, -12, -4).should == nil - Date.valid_commercial?(1582, -12, -3).should == Date.civil(1582, 10, 15).jd - - Date.valid_commercial?(2007, -44, -2).should == Date.civil(2007, 3, 3).jd - Date.valid_commercial?(2008, -44, -2).should == Date.civil(2008, 3, 1).jd - end - end - - ruby_version_is "1.9" do - it "should be able to determine if the date is a valid commercial date" do - # October 1582 (the Gregorian calendar, Commercial Date in 1.9) - # M Tu W Th F Sa Su - # 39: 1 2 3 4 5 6 7 - # 40: 1 2 3 4 5 6 7 - # 41: 1 2 3 4 5 6 7 - Date.valid_commercial?(1582, 39, 4).should == true - Date.valid_commercial?(1582, 39, 5).should == true - Date.valid_commercial?(1582, 41, 4).should == true - Date.valid_commercial?(1582, 41, 5).should == true - Date.valid_commercial?(1582, 41, 4, Date::ENGLAND).should == true - Date.valid_commercial?(1752, 37, 4, Date::ENGLAND).should == true - end - - it "should be able to handle negative week and day numbers" do - # October 1582 (the Gregorian calendar, Commercial Date in 1.9) - # M Tu W Th F Sa Su - # -12: -7 -6 -5 -4 -3 -2 -1 - # -11: -7 -6 -5 -4 -3 -2 -1 - # -10: -7 -6 -5 -4 -3 -2 -1 - Date.valid_commercial?(1582, -12, -4).should == true - Date.valid_commercial?(1582, -12, -3).should == true - - Date.valid_commercial?(2007, -44, -2).should == true - Date.valid_commercial?(2008, -44, -2).should == true - end - end - -end - -describe "Date.commercial" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/library/date/constants_spec.rb b/spec/ruby/library/date/constants_spec.rb index e9dfe0e219..b552bdb722 100644 --- a/spec/ruby/library/date/constants_spec.rb +++ b/spec/ruby/library/date/constants_spec.rb @@ -3,14 +3,6 @@ describe "Date constants" do - it "defines ITALY" do - Date::ITALY.should == 2299161 # 1582-10-15 - end - - it "defines ENGLAND" do - Date::ENGLAND.should == 2361222 # 1752-09-14 - end - # Fixes in 1.8.7 ruby_bug "#", "1.8.6" do it "defines JULIAN" do @@ -25,6 +17,14 @@ end end + it "defines ITALY" do + Date::ITALY.should == 2299161 # 1582-10-15 + end + + it "defines ENGLAND" do + Date::ENGLAND.should == 2361222 # 1752-09-14 + end + it "defines MONTHNAMES" do Date::MONTHNAMES.should == [nil] + %w(January February March April May June July August September October November December) @@ -53,7 +53,7 @@ end end - ruby_version_is '1.8.7' do + ruby_version_is "1.8.7" ... "1.9.3"do it "defines HALF_DAYS_IN_DAY" do Date::HALF_DAYS_IN_DAY.should == Rational(1, 2) diff --git a/spec/ruby/library/date/exist1_spec.rb b/spec/ruby/library/date/exist1_spec.rb index 4421f2bce2..27174ff728 100644 --- a/spec/ruby/library/date/exist1_spec.rb +++ b/spec/ruby/library/date/exist1_spec.rb @@ -1,6 +1,9 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/valid_jd', __FILE__) require 'date' -describe "Date.exist1?" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date.exist1?" do + it_behaves_like :date_valid_jd?, :exist1? + end end diff --git a/spec/ruby/library/date/exist2_spec.rb b/spec/ruby/library/date/exist2_spec.rb index 04bb033fee..8bc6ad583f 100644 --- a/spec/ruby/library/date/exist2_spec.rb +++ b/spec/ruby/library/date/exist2_spec.rb @@ -1,6 +1,9 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/valid_ordinal', __FILE__) require 'date' -describe "Date.exist2?" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date.exist2?" do + it_behaves_like :date_valid_ordinal?, :exist2? + end end diff --git a/spec/ruby/library/date/exist3_spec.rb b/spec/ruby/library/date/exist3_spec.rb index f12a0ea5d5..611675a1df 100644 --- a/spec/ruby/library/date/exist3_spec.rb +++ b/spec/ruby/library/date/exist3_spec.rb @@ -1,6 +1,9 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/valid_civil', __FILE__) require 'date' -describe "Date.exist3?" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date.exist3?" do + it_behaves_like :date_valid_civil?, :exist3? + end end diff --git a/spec/ruby/library/date/exist_spec.rb b/spec/ruby/library/date/exist_spec.rb index 75ee38e5aa..9b8a08f16a 100644 --- a/spec/ruby/library/date/exist_spec.rb +++ b/spec/ruby/library/date/exist_spec.rb @@ -1,6 +1,9 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/valid_civil', __FILE__) require 'date' -describe "Date.exist?" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date.exist?" do + it_behaves_like :date_valid_civil?, :exist? + end end diff --git a/spec/ruby/library/date/existw_spec.rb b/spec/ruby/library/date/existw_spec.rb index 7759a36e99..6a3ba0715b 100644 --- a/spec/ruby/library/date/existw_spec.rb +++ b/spec/ruby/library/date/existw_spec.rb @@ -1,6 +1,9 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/valid_commercial', __FILE__) require 'date' -describe "Date.existw?" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date.existw?" do + it_behaves_like :date_valid_commercial?, :existw? + end end diff --git a/spec/ruby/library/date/gregorian_leap_spec.rb b/spec/ruby/library/date/gregorian_leap_spec.rb index f05d5e5c05..043d57aa93 100644 --- a/spec/ruby/library/date/gregorian_leap_spec.rb +++ b/spec/ruby/library/date/gregorian_leap_spec.rb @@ -1,6 +1,16 @@ require File.expand_path('../../../spec_helper', __FILE__) require 'date' -describe "Date.gregorian_leap?" do - it "needs to be reviewed for spec completeness" +describe "Date#gregorian_leap?" do + it "returns true if a year is a leap year in the Gregorian calendar" do + Date.gregorian_leap?(2000).should be_true + Date.gregorian_leap?(2004).should be_true + end + + it "returns false if a year is not a leap year in the Gregorian calendar" do + Date.gregorian_leap?(1900).should be_false + Date.gregorian_leap?(1999).should be_false + Date.gregorian_leap?(2002).should be_false + end end + diff --git a/spec/ruby/library/date/gregorian_spec.rb b/spec/ruby/library/date/gregorian_spec.rb index 543d8d58f3..e78f39de7e 100644 --- a/spec/ruby/library/date/gregorian_spec.rb +++ b/spec/ruby/library/date/gregorian_spec.rb @@ -4,55 +4,42 @@ describe "Date#gregorian?" do it "marks a day before the calendar reform as Julian" do - Date.civil(1007, 2, 27).gregorian?.should == false - Date.civil(1907, 2, 27, Date.civil(1930, 1, 1).jd).gregorian?.should == false + Date.civil(1007, 2, 27).gregorian?.should be_false + Date.civil(1907, 2, 27, Date.civil(1930, 1, 1).jd).gregorian?.should be_false end it "marks a day after the calendar reform as Julian" do Date.civil(2007, 2, 27).gregorian?.should == true - Date.civil(1607, 2, 27, Date.civil(1582, 1, 1).jd).gregorian?.should == true + Date.civil(1607, 2, 27, Date.civil(1582, 1, 1).jd).gregorian?.should be_true end end -describe "Date#gregorian_leap?" do - it "returns true if a year is a leap year in the Gregorian calendar" do - Date.gregorian_leap?(2000).should == true - Date.gregorian_leap?(2004).should == true - end - - it "returns false if a year is not a leap year in the Gregorian calendar" do - Date.gregorian_leap?(1900).should == false - Date.gregorian_leap?(1999).should == false - Date.gregorian_leap?(2002).should == false - end -end - -describe "Date.gregorian?" do - ruby_version_is "" ... "1.9" do +ruby_version_is "" ... "1.9" do + describe "Date.gregorian?" do it "marks the date as Gregorian if using the Gregorian calendar" do - Date.gregorian?(Date.civil(1007, 2, 27).jd, Date::GREGORIAN).should == true + Date.gregorian?(Date.civil(1007, 2, 27).jd, Date::GREGORIAN).should be_true end it "marks the date as not Gregorian if using the Julian calendar" do - Date.gregorian?(Date.civil(1007, 2, 27).jd, Date::JULIAN).should == false + Date.gregorian?(Date.civil(1007, 2, 27).jd, Date::JULIAN).should be_false end it "marks the date before the English Day of Calendar Reform as not Gregorian" do - Date.gregorian?(Date.civil(1752, 9, 13).jd, Date::ENGLAND).should == false + Date.gregorian?(Date.civil(1752, 9, 13).jd, Date::ENGLAND).should be_false end it "marks the date after the English Day of Calendar Reform as Gregorian" do - Date.gregorian?(Date.civil(1752, 9, 14).jd, Date::ENGLAND).should == true + Date.gregorian?(Date.civil(1752, 9, 14).jd, Date::ENGLAND).should be_true end it "marks the date before the Italian Day of Calendar Reform as not Gregorian" do - Date.gregorian?(Date.civil(1582, 10, 4).jd, Date::ITALY).should == false + Date.gregorian?(Date.civil(1582, 10, 4).jd, Date::ITALY).should be_false end it "marks the date after the Italian Day of Calendar Reform as Gregorian" do - Date.gregorian?(Date.civil(1582, 10, 15).jd, Date::ITALY).should == true + Date.gregorian?(Date.civil(1582, 10, 15).jd, Date::ITALY).should be_true end end diff --git a/spec/ruby/library/date/jd_spec.rb b/spec/ruby/library/date/jd_spec.rb index 41507f9532..ccf6b93e06 100644 --- a/spec/ruby/library/date/jd_spec.rb +++ b/spec/ruby/library/date/jd_spec.rb @@ -1,10 +1,15 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/jd', __FILE__) require 'date' describe "Date#jd" do - it "needs to be reviewed for spec completeness" + + it "determines the Julian day for a Date object" do + Date.civil(2008, 1, 16).jd.should == 2454482 + end + end describe "Date.jd" do - it "needs to be reviewed for spec completeness" + it_behaves_like :date_jd, :jd end diff --git a/spec/ruby/library/date/julian_leap_spec.rb b/spec/ruby/library/date/julian_leap_spec.rb index d0874b890d..3915f97693 100644 --- a/spec/ruby/library/date/julian_leap_spec.rb +++ b/spec/ruby/library/date/julian_leap_spec.rb @@ -2,5 +2,14 @@ require 'date' describe "Date.julian_leap?" do - it "needs to be reviewed for spec completeness" + it "determines whether a year is a leap year in the Julian calendar" do + Date.julian_leap?(1900).should be_true + Date.julian_leap?(2000).should be_true + Date.julian_leap?(2004).should be_true + end + + it "determines whether a year is not a leap year in the Julian calendar" do + Date.julian_leap?(1999).should be_false + Date.julian_leap?(2002).should be_false + end end diff --git a/spec/ruby/library/date/julian_spec.rb b/spec/ruby/library/date/julian_spec.rb index fd47cc1773..7b4d7ac93d 100644 --- a/spec/ruby/library/date/julian_spec.rb +++ b/spec/ruby/library/date/julian_spec.rb @@ -1,103 +1,48 @@ require 'date' require File.expand_path('../../../spec_helper', __FILE__) -describe "Date#jd" do - - it "constructs a Date object based on the Julian day" do - Date.jd(2454482).should == Date.civil(2008, 1, 16) - end - - it "determines the Julian day for a Date object" do - Date.civil(2008, 1, 16).jd.should == 2454482 - end - -end - describe "Date#julian?" do it "marks a day before the calendar reform as Julian" do Date.civil(1007, 2, 27).julian?.should == true - Date.civil(1907, 2, 27, Date.civil(1930, 1, 1).jd).julian?.should == true + Date.civil(1907, 2, 27, Date.civil(1930, 1, 1).jd).julian?.should be_true end it "marks a day after the calendar reform as Julian" do Date.civil(2007, 2, 27).julian?.should == false - Date.civil(1607, 2, 27, Date.civil(1582, 1, 1).jd).julian?.should == false + Date.civil(1607, 2, 27, Date.civil(1582, 1, 1).jd).julian?.should be_false end end -describe "Date#julian_leap?" do - - it "determines whether a year is a leap year in the Julian calendar" do - Date.julian_leap?(1900).should == true - Date.julian_leap?(1999).should == false - Date.julian_leap?(2000).should == true - Date.julian_leap?(2002).should == false - Date.julian_leap?(2004).should == true - end - -end - -describe "Date#valid_jd?" do - ruby_version_is "" ... "1.9" do - - it "determines if a day number is a valid Julian day number, true for all numbers" do - # This might need to check the type of the jd parameter. Date.valid_jd?(:number) is of course - # bogus but returns itself with the current implementation - Date.valid_jd?(-100).should == -100 - Date.valid_jd?(0).should == 0 - Date.valid_jd?(100).should == 100 - end - end - -end - -describe "Date.julian?" do - ruby_version_is "" ... "1.9" do +ruby_version_is "" ... "1.9" do + describe "Date.julian?" do it "marks the date as not Julian if using the Gregorian calendar" do - Date.julian?(Date.civil(1007, 2, 27).jd, Date::GREGORIAN).should == false + Date.julian?(Date.civil(1007, 2, 27).jd, Date::GREGORIAN).should be_false end it "marks the date as Julian if using the Julian calendar" do - Date.julian?(Date.civil(1007, 2, 27).jd, Date::JULIAN).should == true + Date.julian?(Date.civil(1007, 2, 27).jd, Date::JULIAN).should be_true end it "marks the date before the English Day of Calendar Reform as Julian" do - Date.julian?(Date.civil(1752, 9, 13).jd, Date::ENGLAND).should == true + Date.julian?(Date.civil(1752, 9, 13).jd, Date::ENGLAND).should be_true end it "marks the date after the English Day of Calendar Reform as not Julian" do - Date.julian?(Date.civil(1752, 9, 14).jd, Date::ENGLAND).should == false + Date.julian?(Date.civil(1752, 9, 14).jd, Date::ENGLAND).should be_false end it "marks the date before the Italian Day of Calendar Reform as Julian" do - Date.julian?(Date.civil(1582, 10, 4).jd, Date::ITALY).should == true + Date.julian?(Date.civil(1582, 10, 4).jd, Date::ITALY).should be_true end it "marks the date after the Italian Day of Calendar Reform as not Julian" do - Date.julian?(Date.civil(1582, 10, 15).jd, Date::ITALY).should == false + Date.julian?(Date.civil(1582, 10, 15).jd, Date::ITALY).should be_false end end end -describe "Date#valid_jd?" do - ruby_version_is "1.9" do - - it "determines if a day number is a valid Julian day number, true for all numbers" do - # This might need to check the type of the jd parameter. Date.valid_jd?(:number) is of course - # bogus but returns itself with the current implementation - Date.valid_jd?(-100).should == true - Date.valid_jd?(0).should == true - Date.valid_jd?(100).should == true - end - - end -end - -describe "Date.julian?" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/library/date/minus_spec.rb b/spec/ruby/library/date/minus_spec.rb index 44b94c02fe..09da595872 100644 --- a/spec/ruby/library/date/minus_spec.rb +++ b/spec/ruby/library/date/minus_spec.rb @@ -3,17 +3,17 @@ describe "Date#-" do - it "should substract a number of days from a Date" do + it "substracts a number of days from a Date" do d = Date.civil(2007, 5 ,2) - 13 d.should == Date.civil(2007, 4, 19) end - it "should substract a negative number of days from a Date" do + it "substracts a negative number of days from a Date" do d = Date.civil(2007, 4, 19).-(-13) d.should == Date.civil(2007, 5 ,2) end - it "should be able to compute the different between two dates" do + it "computes the difference between two dates" do (Date.civil(2007,2,27) - Date.civil(2007,2,27)).should == 0 (Date.civil(2007,2,27) - Date.civil(2007,2,26)).should == 1 (Date.civil(2006,2,27) - Date.civil(2007,2,27)).should == -365 @@ -21,7 +21,7 @@ end - it "should raise an error on non numeric parameters" do + it "raises an error for non Numeric arguments" do lambda { Date.civil(2007,2,27) - :hello }.should raise_error(TypeError) lambda { Date.civil(2007,2,27) - "hello" }.should raise_error(TypeError) lambda { Date.civil(2007,2,27) - Object.new }.should raise_error(TypeError) diff --git a/spec/ruby/library/date/new0_spec.rb b/spec/ruby/library/date/new0_spec.rb index 03a8d660be..b9d80505d2 100644 --- a/spec/ruby/library/date/new0_spec.rb +++ b/spec/ruby/library/date/new0_spec.rb @@ -1,6 +1,9 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/new_bang', __FILE__) require 'date' -describe "Date.new0" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date.new0" do + it_behaves_like :date_new_bang, :new0 + end end diff --git a/spec/ruby/library/date/new1_spec.rb b/spec/ruby/library/date/new1_spec.rb index 48cc2d0b79..d6fd708258 100644 --- a/spec/ruby/library/date/new1_spec.rb +++ b/spec/ruby/library/date/new1_spec.rb @@ -1,6 +1,9 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/jd', __FILE__) require 'date' -describe "Date.new1" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date.new1" do + it_behaves_like :date_jd, :new1 + end end diff --git a/spec/ruby/library/date/new2_spec.rb b/spec/ruby/library/date/new2_spec.rb index d96163aaab..dd8fe77b34 100644 --- a/spec/ruby/library/date/new2_spec.rb +++ b/spec/ruby/library/date/new2_spec.rb @@ -1,6 +1,9 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/ordinal', __FILE__) require 'date' -describe "Date.new2" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date.new2" do + it_behaves_like :date_ordinal, :new2 + end end diff --git a/spec/ruby/library/date/new3_spec.rb b/spec/ruby/library/date/new3_spec.rb index f21f0984c8..7445b3b824 100644 --- a/spec/ruby/library/date/new3_spec.rb +++ b/spec/ruby/library/date/new3_spec.rb @@ -1,6 +1,9 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/civil', __FILE__) require 'date' -describe "Date.new3" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date.new3" do + it_behaves_like :date_civil, :new3 + end end diff --git a/spec/ruby/library/date/new_spec.rb b/spec/ruby/library/date/new_spec.rb index 7bb13d5c25..d7b3fc9fc9 100644 --- a/spec/ruby/library/date/new_spec.rb +++ b/spec/ruby/library/date/new_spec.rb @@ -1,17 +1,14 @@ require 'date' require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../shared/civil', __FILE__) - -describe "Date#new" do - - it_behaves_like(:date_civil, :new) - -end +require File.expand_path('../shared/new_bang', __FILE__) describe "Date.new" do - it "needs to be reviewed for spec completeness" + it_behaves_like(:date_civil, :new) end -describe "Date.new!" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9.3" do + describe "Date.new!" do + it_behaves_like(:date_new_bang, :new!) + end end diff --git a/spec/ruby/library/date/newsg_spec.rb b/spec/ruby/library/date/newsg_spec.rb index 41e139f2e4..c7e539e2b4 100644 --- a/spec/ruby/library/date/newsg_spec.rb +++ b/spec/ruby/library/date/newsg_spec.rb @@ -1,6 +1,8 @@ require File.expand_path('../../../spec_helper', __FILE__) require 'date' -describe "Date#newsg" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date#newsg" do + it "needs to be reviewed for spec completeness" + end end diff --git a/spec/ruby/library/date/neww_spec.rb b/spec/ruby/library/date/neww_spec.rb index b87f10a83c..92ed899224 100644 --- a/spec/ruby/library/date/neww_spec.rb +++ b/spec/ruby/library/date/neww_spec.rb @@ -1,6 +1,8 @@ require File.expand_path('../../../spec_helper', __FILE__) require 'date' -describe "Date.neww" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date.neww" do + it_behaves_like :date_commercial, :neww + end end diff --git a/spec/ruby/library/date/ns_spec.rb b/spec/ruby/library/date/ns_spec.rb index 1ee61a0597..4cb264fbef 100644 --- a/spec/ruby/library/date/ns_spec.rb +++ b/spec/ruby/library/date/ns_spec.rb @@ -1,10 +1,12 @@ require File.expand_path('../../../spec_helper', __FILE__) require 'date' -describe "Date#ns?" do - it "needs to be reviewed for spec completeness" -end +ruby_version_is "" ... "1.9" do + describe "Date#ns?" do + it "needs to be reviewed for spec completeness" + end -describe "Date.ns?" do - it "needs to be reviewed for spec completeness" + describe "Date.ns?" do + it "needs to be reviewed for spec completeness" + end end diff --git a/spec/ruby/library/date/ordinal_spec.rb b/spec/ruby/library/date/ordinal_spec.rb index c2b13d7750..a373692a7b 100644 --- a/spec/ruby/library/date/ordinal_spec.rb +++ b/spec/ruby/library/date/ordinal_spec.rb @@ -1,113 +1,8 @@ require 'date' require File.expand_path('../../../spec_helper', __FILE__) -require File.expand_path('../shared/commercial', __FILE__) - -# reference: -# October 1582 (the Gregorian calendar, Civil Date) -# S M Tu W Th F S -# 1 2 3 4 15 16 -# 17 18 19 20 21 22 23 -# 24 25 26 27 28 29 30 -# 31 - -describe "Date#ordinal" do - - ruby_version_is "" ... "1.9" do - it "should be able to construct a Date object from an ordinal date" do - # October 1582 (the Gregorian calendar, Ordinal Date in 1.8) - # S M Tu W Th F S - # 274 275 276 277 288 289 - # 290 291 292 293 294 295 296 - # 297 298 299 300 301 302 303 - # 304 - Date.ordinal(1582, 274).should == Date.civil(1582, 10, 1) - Date.ordinal(1582, 277).should == Date.civil(1582, 10, 4) - lambda { Date.ordinal(1582, 278) }.should raise_error(ArgumentError) - lambda { Date.ordinal(1582, 287) }.should raise_error(ArgumentError) - Date.ordinal(1582, 288).should == Date.civil(1582, 10, 15) - Date.ordinal(1582, 287, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND) - end - end - - ruby_version_is "1.9" do - it "should be able to construct a Date object from an ordinal date" do - # October 1582 (the Gregorian calendar, Ordinal Date in 1.9) - # S M Tu W Th F S - # 274 275 276 277 278 279 - # 280 281 282 283 284 285 286 - # 287 288 289 290 291 292 293 - # 294 - Date.ordinal(1582, 274).should == Date.civil(1582, 10, 1) - Date.ordinal(1582, 277).should == Date.civil(1582, 10, 4) - Date.ordinal(1582, 278).should == Date.civil(1582, 10, 15) - Date.ordinal(1582, 287, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND) - end - end - -end - -describe "Date#valid_ordinal?" do - - ruby_version_is "" ... "1.9" do - it "should be able to determine if the date is a valid ordinal date" do - # October 1582 (the Gregorian calendar, Ordinal Date in 1.8) - # S M Tu W Th F S - # 274 275 276 277 278 279 - # 280 281 282 283 284 285 286 - # 287 288 289 290 291 292 293 - # 294 - Date.valid_ordinal?(1582, 277).should == Date.civil(1582, 10, 4).jd - Date.valid_ordinal?(1582, 278).should == nil - Date.valid_ordinal?(1582, 287).should == nil - Date.valid_ordinal?(1582, 288).should == Date.civil(1582, 10, 15).jd - Date.valid_ordinal?(1582, 287, Date::ENGLAND).should_not == nil - Date.valid_ordinal?(1582, 287, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND).jd - end - - it "should be able to handle negative day numbers" do - # October 1582 (the Gregorian calendar, Ordinal Date in 1.8) - # S M Tu W Th F S - # -92 -91 -90 -89 -78 -77 - # -76 -75 -74 -73 -72 -71 -70 - # -69 -68 -67 -66 -65 -64 -63 - # -62 - Date.valid_ordinal?(1582, -89).should == Date.civil(1582, 10, 4).jd - Date.valid_ordinal?(1582, -88).should == nil - Date.valid_ordinal?(1582, -79).should == nil - Date.valid_ordinal?(1582, -78).should == Date.civil(1582, 10, 15).jd - Date.valid_ordinal?(2007, -100).should == Date.valid_ordinal?(2007, 266) - end - end - - ruby_version_is "1.9" do - it "should be able to determine if the date is a valid ordinal date" do - # October 1582 (the Gregorian calendar, Ordinal Date in 1.9) - # S M Tu W Th F S - # 274 275 276 277 278 279 - # 280 281 282 283 284 285 286 - # 287 288 289 290 291 292 293 - # 294 - Date.valid_ordinal?(1582, 277).should == true - Date.valid_ordinal?(1582, 278).should == true - Date.valid_ordinal?(1582, 287).should == true - Date.valid_ordinal?(1582, 288).should == true - end - - it "should be able to handle negative day numbers" do - # October 1582 (the Gregorian calendar, Ordinal Date in 1.9) - # S M Tu W Th F S - # -82 -81 -80 -79 -78 -77 - # -76 -75 -74 -73 -72 -71 -70 - # -69 -68 -67 -66 -65 -64 -63 - # -62 - Date.valid_ordinal?(1582, -79).should == true - Date.valid_ordinal?(1582, -78).should == true - Date.valid_ordinal?(2007, -100).should == true - end - end - -end +require File.expand_path('../shared/ordinal', __FILE__) describe "Date.ordinal" do - it "needs to be reviewed for spec completeness" + it_behaves_like :date_ordinal, :ordinal end + diff --git a/spec/ruby/library/date/os_spec.rb b/spec/ruby/library/date/os_spec.rb index 469576af7e..5a3cae8c3d 100644 --- a/spec/ruby/library/date/os_spec.rb +++ b/spec/ruby/library/date/os_spec.rb @@ -1,10 +1,12 @@ require File.expand_path('../../../spec_helper', __FILE__) require 'date' -describe "Date#os?" do - it "needs to be reviewed for spec completeness" -end +ruby_version_is "" ... "1.9" do + describe "Date#os?" do + it "needs to be reviewed for spec completeness" + end -describe "Date.os?" do - it "needs to be reviewed for spec completeness" + describe "Date.os?" do + it "needs to be reviewed for spec completeness" + end end diff --git a/spec/ruby/library/date/plus_spec.rb b/spec/ruby/library/date/plus_spec.rb index a731386461..e33fb199eb 100644 --- a/spec/ruby/library/date/plus_spec.rb +++ b/spec/ruby/library/date/plus_spec.rb @@ -2,5 +2,19 @@ require 'date' describe "Date#+" do - it "needs to be reviewed for spec completeness" + before :all do + @date = Date.civil(2000, 1, 1) + end + + it "returns a new Date object that is n days later than the current one" do + (@date + 31).should == Date.civil(2000, 2, 1) + end + + it "accepts a negative argument and returns a new Date that is earlier than the current one" do + (@date + -1).should == Date.civil(1999, 12, 31) + end + + it "raises TypeError if argument is not Numeric" do + lambda { Date.today + Date.today }.should raise_error(TypeError) + end end diff --git a/spec/ruby/library/date/sg_spec.rb b/spec/ruby/library/date/sg_spec.rb index 22d08baf7d..da9a9ec5c1 100644 --- a/spec/ruby/library/date/sg_spec.rb +++ b/spec/ruby/library/date/sg_spec.rb @@ -1,6 +1,8 @@ require File.expand_path('../../../spec_helper', __FILE__) require 'date' -describe "Date#sg" do - it "needs to be reviewed for spec completeness" +ruby_version_is "" ... "1.9" do + describe "Date#sg" do + it "needs to be reviewed for spec completeness" + end end diff --git a/spec/ruby/library/date/shared/civil.rb b/spec/ruby/library/date/shared/civil.rb index 46a4e0177e..d738f6307b 100644 --- a/spec/ruby/library/date/shared/civil.rb +++ b/spec/ruby/library/date/shared/civil.rb @@ -47,7 +47,7 @@ end - it "creats a Date for different calendar reform dates" do + it "creates a Date for different calendar reform dates" do d1 = Date.send(@method, 1582, 10, 4) d1.succ.day.should == 15 @@ -56,7 +56,7 @@ end ruby_version_is ""..."1.9.3" do - it "choose an arbitrary reform date" do + it "chooses an arbitrary reform date" do r = Date.send(@method, 2000, 2, 3) d3 = Date.send(@method, 2000, 2, 3, r.jd) diff --git a/spec/ruby/library/date/shared/jd.rb b/spec/ruby/library/date/shared/jd.rb new file mode 100644 index 0000000000..aaa33adae0 --- /dev/null +++ b/spec/ruby/library/date/shared/jd.rb @@ -0,0 +1,14 @@ +describe :date_jd, :shared => true do + it "constructs a Date object if passed a Julian day" do + Date.send(@method, 2454482).should == Date.civil(2008, 1, 16) + end + + it "returns a Date object representing Julian day 0 (-4712-01-01) if no arguments passed"do + Date.send(@method).should == Date.civil(-4712, 1, 1) + end + + it "constructs a Date object if passed a negative number" do + Date.send(@method, -1).should == Date.civil(-4713, 12, 31) + end + +end diff --git a/spec/ruby/library/date/shared/new_bang.rb b/spec/ruby/library/date/shared/new_bang.rb new file mode 100644 index 0000000000..0407f1c115 --- /dev/null +++ b/spec/ruby/library/date/shared/new_bang.rb @@ -0,0 +1,14 @@ +describe :date_new_bang, :shared => true do + + it "returns a new Date object set to Astronomical Julian Day 0 if no arguments passed" do + d = Date.send(@method) + d.ajd.should == 0 + end + + it "accepts astronomical julian day number, offset as a fraction of a day and returns a new Date object" do + d = Date.send(@method, 10, 0.5) + d.ajd.should == 10 + d.jd.should == 11 + end + +end diff --git a/spec/ruby/library/date/shared/ordinal.rb b/spec/ruby/library/date/shared/ordinal.rb new file mode 100644 index 0000000000..258c6ec3bd --- /dev/null +++ b/spec/ruby/library/date/shared/ordinal.rb @@ -0,0 +1,42 @@ +# reference: +# October 1582 (the Gregorian calendar, Civil Date) +# S M Tu W Th F S +# 1 2 3 4 15 16 +# 17 18 19 20 21 22 23 +# 24 25 26 27 28 29 30 +# 31 + +describe :date_ordinal, :shared => true do + + ruby_version_is "" ... "1.9" do + it "should be able to construct a Date object from an ordinal date" do + # October 1582 (the Gregorian calendar, Ordinal Date in 1.8) + # S M Tu W Th F S + # 274 275 276 277 288 289 + # 290 291 292 293 294 295 296 + # 297 298 299 300 301 302 303 + # 304 + Date.send(@method, 1582, 274).should == Date.civil(1582, 10, 1) + Date.send(@method, 1582, 277).should == Date.civil(1582, 10, 4) + lambda { Date.send(@method, 1582, 278) }.should raise_error(ArgumentError) + lambda { Date.send(@method, 1582, 287) }.should raise_error(ArgumentError) + Date.send(@method, 1582, 288).should == Date.civil(1582, 10, 15) + Date.send(@method, 1582, 287, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND) + end + end + + ruby_version_is "1.9" do + it "should be able to construct a Date object from an ordinal date" do + # October 1582 (the Gregorian calendar, Ordinal Date in 1.9) + # S M Tu W Th F S + # 274 275 276 277 278 279 + # 280 281 282 283 284 285 286 + # 287 288 289 290 291 292 293 + # 294 + Date.send(@method, 1582, 274).should == Date.civil(1582, 10, 1) + Date.send(@method, 1582, 277).should == Date.civil(1582, 10, 4) + Date.send(@method, 1582, 278).should == Date.civil(1582, 10, 15) + Date.send(@method, 1582, 287, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND) + end + end +end diff --git a/spec/ruby/library/date/shared/valid_civil.rb b/spec/ruby/library/date/shared/valid_civil.rb new file mode 100644 index 0000000000..c7796b1644 --- /dev/null +++ b/spec/ruby/library/date/shared/valid_civil.rb @@ -0,0 +1,69 @@ +describe :date_valid_civil?, :shared => true do + + # reference: + # October 1582 (the Gregorian calendar, Civil Date) + # S M Tu W Th F S + # 1 2 3 4 15 16 + # 17 18 19 20 21 22 23 + # 24 25 26 27 28 29 30 + # 31 + + ruby_version_is "" ... "1.9" do + it "returns the corresponding Julian Day Number if it is a valid civil date" do + Date.send(@method, 1582, 10, 15).should == Date.civil(1582, 10, 15).jd + Date.send(@method, 1582, 10, 14, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND).jd + end + + it "returns nil if it is not a valid civil date" do + Date.send(@method, 1582, 10, 14).should be_nil + Date.send(@method, 1582, 10, 14, Date::ENGLAND).should_not be_nil + end + + it "handles negative months and days" do + # October 1582 (the Gregorian calendar, Civil Date in 1.8) + # S M Tu W Th F S + # -31 -30 -29 -28 -17 -16 + # -15 -14 -13 -12 -11 -10 -9 + # -8 -7 -6 -5 -4 -3 -2 + # -1 + Date.send(@method, 1582, -3, -31).should == Date.civil(1582, 10, 1).jd + Date.send(@method, 1582, -3, -28).should == Date.civil(1582, 10, 4).jd + Date.send(@method, 1582, -3, -27).should be_nil + Date.send(@method, 1582, -3, -22).should be_nil + Date.send(@method, 1582, -3, -21).should be_nil + Date.send(@method, 1582, -3, -18).should be_nil + Date.send(@method, 1582, -3, -17).should == Date.civil(1582, 10, 15).jd + + Date.send(@method, 2007, -11, -10).should == Date.civil(2007, 2, 19).jd + Date.send(@method, 2008, -11, -10).should == Date.civil(2008, 2, 20).jd + end + end + + ruby_version_is "1.9" do + it "returns true if it is a valid civil date" do + Date.send(@method, 1582, 10, 15).should be_true + Date.send(@method, 1582, 10, 14, Date::ENGLAND).should be_true + end + + it "returns false if it is not a valid civil date" do + Date.send(@method, 1582, 10, 14).should == false + end + + it "handles negative months and days" do + # October 1582 (the Gregorian calendar, Civil Date in 1.9) + # S M Tu W Th F S + # -21 -20 -19 -18 -17 -16 + # -15 -14 -13 -12 -11 -10 -9 + # -8 -7 -6 -5 -4 -3 -2 + # -1 + Date.send(@method, 1582, -3, -22).should be_false + Date.send(@method, 1582, -3, -21).should be_true + Date.send(@method, 1582, -3, -18).should be_true + Date.send(@method, 1582, -3, -17).should be_true + + Date.send(@method, 2007, -11, -10).should be_true + Date.send(@method, 2008, -11, -10).should be_true + end + end + +end diff --git a/spec/ruby/library/date/shared/valid_commercial.rb b/spec/ruby/library/date/shared/valid_commercial.rb new file mode 100644 index 0000000000..15a24fade5 --- /dev/null +++ b/spec/ruby/library/date/shared/valid_commercial.rb @@ -0,0 +1,66 @@ +describe :date_valid_commercial?, :shared => true do + ruby_version_is "" ... "1.9" do + it "returns the corresponding Julian Day Number if it is a valid commercial date" do + # October 1582 (the Gregorian calendar, Commercial Date in 1.8) + # M Tu W Th F Sa Su + # 41: - - - - 5 6 7 + # 42: 1 2 3 4 5 6 7 + # 43: 1 2 3 4 5 6 7 + Date.send(@method, 1582, 41, 5).should == Date.civil(1582, 10, 15).jd + Date.send(@method, 1752, 37, 4, Date::ENGLAND).should == Date.civil(1752, 9, 14, Date::ENGLAND).jd + end + + it "returns nil if it is not a valid commercial date" do + Date.send(@method, 1582, 41, 4).should be_nil + # valid_commercial? can't handle dates before the Gregorian calendar + Date.send(@method, 1582, 41, 4, Date::ENGLAND).should be_nil + end + + it "handles negative week and day numbers" do + # October 1582 (the Gregorian calendar, Commercial Date in 1.8) + # M Tu W Th F Sa Su + # -12: - - - - -3 -2 -1 + # -11: -7 -6 -5 -4 -3 -2 -1 + # -10: -7 -6 -5 -4 -3 -2 -1 + Date.send(@method, 1582, -12, -4).should be_nil + Date.send(@method, 1582, -12, -3).should == Date.civil(1582, 10, 15).jd + + Date.send(@method, 2007, -44, -2).should == Date.civil(2007, 3, 3).jd + Date.send(@method, 2008, -44, -2).should == Date.civil(2008, 3, 1).jd + end + end + + ruby_version_is "1.9" do + it "returns true if it is a valid commercial date" do + # October 1582 (the Gregorian calendar, Commercial Date in 1.9) + # M Tu W Th F Sa Su + # 39: 1 2 3 4 5 6 7 + # 40: 1 2 3 4 5 6 7 + # 41: 1 2 3 4 5 6 7 + Date.send(@method, 1582, 39, 4).should be_true + Date.send(@method, 1582, 39, 5).should be_true + Date.send(@method, 1582, 41, 4).should be_true + Date.send(@method, 1582, 41, 5).should be_true + Date.send(@method, 1582, 41, 4, Date::ENGLAND).should be_true + Date.send(@method, 1752, 37, 4, Date::ENGLAND).should be_true + end + + it "returns false it is not a valid commercial date" do + Date.send(@method, 1999, 53, 1).should be_false + end + + it "handles negative week and day numbers" do + # October 1582 (the Gregorian calendar, Commercial Date in 1.9) + # M Tu W Th F Sa Su + # -12: -7 -6 -5 -4 -3 -2 -1 + # -11: -7 -6 -5 -4 -3 -2 -1 + # -10: -7 -6 -5 -4 -3 -2 -1 + Date.send(@method, 1582, -12, -4).should be_true + Date.send(@method, 1582, -12, -3).should be_true + Date.send(@method, 2007, -44, -2).should be_true + Date.send(@method, 2008, -44, -2).should be_true + Date.send(@method, 1999, -53, -1).should be_false + end + end + +end diff --git a/spec/ruby/library/date/shared/valid_jd.rb b/spec/ruby/library/date/shared/valid_jd.rb new file mode 100644 index 0000000000..f1bbd93e17 --- /dev/null +++ b/spec/ruby/library/date/shared/valid_jd.rb @@ -0,0 +1,36 @@ +describe :date_valid_jd?, :shared => true do + ruby_version_is "" ... "1.9" do + it "returns passed argument" do + Date.send(@method, -100).should == -100 + Date.send(@method, :number).should == :number + Date.send(@method, nil).should == nil + end + + end + + ruby_version_is "1.9" do + it "returns true if passed any value other than nil" do + Date.send(@method, -100).should be_true + Date.send(@method, :number).should be_true + Date.send(@method, Rational(1,2)).should be_true + end + end + + ruby_version_is "1.9" do + it "returns false if passed nil" do + Date.send(@method, nil).should be_false + end + end + + ruby_version_is "1.9" ... "1.9.3" do + it "returns false if passed false" do + Date.send(@method, false).should be_false + end + end + + ruby_version_is "1.9.3" do + it "returns true if passed false" do + Date.send(@method, false).should be_true + end + end +end diff --git a/spec/ruby/library/date/shared/valid_ordinal.rb b/spec/ruby/library/date/shared/valid_ordinal.rb new file mode 100644 index 0000000000..d17f2aff02 --- /dev/null +++ b/spec/ruby/library/date/shared/valid_ordinal.rb @@ -0,0 +1,60 @@ +describe :date_valid_ordinal?, :shared => true do + ruby_version_is "" ... "1.9" do + it "should be able to determine if the date is a valid ordinal date" do + # October 1582 (the Gregorian calendar, Ordinal Date in 1.8) + # S M Tu W Th F S + # 274 275 276 277 278 279 + # 280 281 282 283 284 285 286 + # 287 288 289 290 291 292 293 + # 294 + Date.send(@method, 1582, 277).should == Date.civil(1582, 10, 4).jd + Date.send(@method, 1582, 278).should == nil + Date.send(@method, 1582, 287).should == nil + Date.send(@method, 1582, 288).should == Date.civil(1582, 10, 15).jd + Date.send(@method, 1582, 287, Date::ENGLAND).should_not == nil + Date.send(@method, 1582, 287, Date::ENGLAND).should == Date.civil(1582, 10, 14, Date::ENGLAND).jd + end + + it "should be able to handle negative day numbers" do + # October 1582 (the Gregorian calendar, Ordinal Date in 1.8) + # S M Tu W Th F S + # -92 -91 -90 -89 -78 -77 + # -76 -75 -74 -73 -72 -71 -70 + # -69 -68 -67 -66 -65 -64 -63 + # -62 + Date.send(@method, 1582, -89).should == Date.civil(1582, 10, 4).jd + Date.send(@method, 1582, -88).should == nil + Date.send(@method, 1582, -79).should == nil + Date.send(@method, 1582, -78).should == Date.civil(1582, 10, 15).jd + Date.send(@method, 2007, -100).should == Date.send(@method, 2007, 266) + end + end + + ruby_version_is "1.9" do + it "should be able to determine if the date is a valid ordinal date" do + # October 1582 (the Gregorian calendar, Ordinal Date in 1.9) + # S M Tu W Th F S + # 274 275 276 277 278 279 + # 280 281 282 283 284 285 286 + # 287 288 289 290 291 292 293 + # 294 + Date.send(@method, 1582, 277).should == true + Date.send(@method, 1582, 278).should == true + Date.send(@method, 1582, 287).should == true + Date.send(@method, 1582, 288).should == true + end + + it "should be able to handle negative day numbers" do + # October 1582 (the Gregorian calendar, Ordinal Date in 1.9) + # S M Tu W Th F S + # -82 -81 -80 -79 -78 -77 + # -76 -75 -74 -73 -72 -71 -70 + # -69 -68 -67 -66 -65 -64 -63 + # -62 + Date.send(@method, 1582, -79).should == true + Date.send(@method, 1582, -78).should == true + Date.send(@method, 2007, -100).should == true + end + end + +end diff --git a/spec/ruby/library/date/valid_civil_spec.rb b/spec/ruby/library/date/valid_civil_spec.rb index accce5672a..09185674ee 100644 --- a/spec/ruby/library/date/valid_civil_spec.rb +++ b/spec/ruby/library/date/valid_civil_spec.rb @@ -1,6 +1,10 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/valid_civil', __FILE__) require 'date' -describe "Date.valid_civil?" do - it "needs to be reviewed for spec completeness" +describe "Date#valid_civil?" do + + it_behaves_like :date_valid_civil?, :valid_civil? + end + diff --git a/spec/ruby/library/date/valid_commercial_spec.rb b/spec/ruby/library/date/valid_commercial_spec.rb index 20ef146841..187d818233 100644 --- a/spec/ruby/library/date/valid_commercial_spec.rb +++ b/spec/ruby/library/date/valid_commercial_spec.rb @@ -1,6 +1,10 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/valid_commercial', __FILE__) require 'date' -describe "Date.valid_commercial?" do - it "needs to be reviewed for spec completeness" +describe "Date#valid_commercial?" do + + it_behaves_like :date_valid_commercial?, :valid_commercial? end + + diff --git a/spec/ruby/library/date/valid_date_spec.rb b/spec/ruby/library/date/valid_date_spec.rb index 6f059aab3f..8d8d22756a 100644 --- a/spec/ruby/library/date/valid_date_spec.rb +++ b/spec/ruby/library/date/valid_date_spec.rb @@ -2,5 +2,5 @@ require 'date' describe "Date.valid_date?" do - it "needs to be reviewed for spec completeness" + it_behaves_like :date_valid_civil?, :valid_date? end diff --git a/spec/ruby/library/date/valid_jd_spec.rb b/spec/ruby/library/date/valid_jd_spec.rb index 8e0999ba10..9764c02f2b 100644 --- a/spec/ruby/library/date/valid_jd_spec.rb +++ b/spec/ruby/library/date/valid_jd_spec.rb @@ -1,6 +1,10 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/valid_jd', __FILE__) require 'date' describe "Date.valid_jd?" do - it "needs to be reviewed for spec completeness" + + it_behaves_like :date_valid_jd?, :valid_jd? + end + diff --git a/spec/ruby/library/date/valid_ordinal_spec.rb b/spec/ruby/library/date/valid_ordinal_spec.rb index b222ff85e7..e197bb2051 100644 --- a/spec/ruby/library/date/valid_ordinal_spec.rb +++ b/spec/ruby/library/date/valid_ordinal_spec.rb @@ -1,6 +1,10 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../shared/valid_ordinal', __FILE__) require 'date' describe "Date.valid_ordinal?" do - it "needs to be reviewed for spec completeness" + + it_behaves_like :date_valid_ordinal?, :valid_ordinal? + end + From 372c3a7629abd67473d7dc91641c618d77212582 Mon Sep 17 00:00:00 2001 From: Karol Hosiawa Date: Fri, 11 Nov 2011 21:40:09 +0100 Subject: [PATCH 19/67] Added missing Date method aliases in 1.8 --- lib/18/date.rb | 76 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/lib/18/date.rb b/lib/18/date.rb index 3d7080018b..a6e412e2e7 100644 --- a/lib/18/date.rb +++ b/lib/18/date.rb @@ -1110,7 +1110,7 @@ def hour() time[0] end # Get the minute of this date. def min() time[1] end - + # Get the second of this date. def sec() time[2] end @@ -1689,3 +1689,77 @@ def to_datetime() self end public_class_method :now end + +class Date + + class << self + + def deprecated_class_method_alias(old, new) # :nodoc: + module_eval <<-"end;" + class << self + def #{old}(*args, &block) + if $VERBOSE + warn("\#{caller.shift.sub(/:in .*/, '')}: " \ + "warning: \#{self}::#{old} is deprecated; " \ + "use \#{self}::#{new}") + end + #{new}(*args, &block) + end + end + end; + end + + private :deprecated_class_method_alias + + def deprecated_alias(old, new) # :nodoc: + module_eval <<-"end;" + def #{old}(*args, &block) + if $VERBOSE + warn("\#{caller.shift.sub(/:in .*/, '')}: " \ + "warning: \#{self.class}\##{old} is deprecated; " \ + "use \#{self.class}\##{new}") + end + #{new}(*args, &block) + end + end; + end + + private :deprecated_alias + + end + + [ %w(os? julian?), + %w(ns? gregorian?), + %w(exist1? valid_jd?), + %w(exist2? valid_ordinal?), + %w(exist3? valid_date?), + %w(exist? valid_date?), + %w(existw? valid_commercial?), + %w(new0 new!), + %w(new1 jd), + %w(new2 ordinal), + %w(new3 new), + %w(neww commercial) + ].each do |old, new| + deprecated_class_method_alias(old, new) + end + + [ %w(os? julian?), + %w(ns? gregorian?), + %w(sg start), + %w(newsg new_start), + %w(of offset), + %w(newof new_offset) + ].each do |old, new| + deprecated_alias(old, new) + end + + private :of, :newof + +end + +class DateTime < Date + + public :of, :newof + +end From 9af54f3cf8251e0744ca0cf676376e306067be63 Mon Sep 17 00:00:00 2001 From: Karol Hosiawa Date: Fri, 11 Nov 2011 21:51:27 +0100 Subject: [PATCH 20/67] remove tag for passing Date#valid_jd in 1.9 --- spec/tags/19/ruby/library/date/valid_jd_tags.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 spec/tags/19/ruby/library/date/valid_jd_tags.txt diff --git a/spec/tags/19/ruby/library/date/valid_jd_tags.txt b/spec/tags/19/ruby/library/date/valid_jd_tags.txt new file mode 100644 index 0000000000..441c531402 --- /dev/null +++ b/spec/tags/19/ruby/library/date/valid_jd_tags.txt @@ -0,0 +1,2 @@ +fails:Date.valid_jd? returns true if passed any value other than false and nil +fails:Date.valid_jd? returns false if passed nil or false From 49fb5912bc7b20b06b32c5c8d5f4af62f8aa232f Mon Sep 17 00:00:00 2001 From: Guilherme Lima Bernal Date: Fri, 11 Nov 2011 23:25:22 -0200 Subject: [PATCH 21/67] Updated Portuguese translation of "What is Rubinius". --- web/doc/pt-br/what-is-rubinius.markdown | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/web/doc/pt-br/what-is-rubinius.markdown b/web/doc/pt-br/what-is-rubinius.markdown index 8178903289..b278ea9679 100644 --- a/web/doc/pt-br/what-is-rubinius.markdown +++ b/web/doc/pt-br/what-is-rubinius.markdown @@ -6,36 +6,36 @@ next_url: getting-started ## O que é Rubinius -Rubinius é uma implementação da [linguagem de programação Ruby] -(http://ruby-lang.org). +Rubinius é uma implementação da [linguagem de programação +Ruby](http://ruby-lang.org). +Rubinius include uma máquina virtual de bytecode, um parser da sintaxe Ruby, um +compilador de bytecode, um coletor de lixo de gerações, compilador de código de +maquina nativo just-in-time (JIT) e as bibliotecas de núcleo e padrões do Ruby. -Rubinius inclue uma máquina virtual de bytecodes, parser de sintax Ruby, -compilador de bytecode, gerenciador de garbage collector, compilador de -de código nativo just-in-time (JIT), e o Ruby Core e Bibliotecas padrão. Rubinius implementa atualmente a versão 1.8.7 do Ruby. ## Licença -Rubinius usa a licença BDS. Veja o arquivo de LICENCA no código-fonte. +Rubinius usa a licença BDS. Veja o arquivo LICENSE no código-fonte. + ## Instalação -Rubinius executa em Mac OS X e muitos sistemas Unix/Linux. Microsoft Windows + +Rubinius executa em Mac OS X e em muitos sistemas Unix/Linux. Microsoft Windows terá suporte em breve. -Para instalar Rubinius, siga os passos abaixo. Para informação mais detalhada +Para instalar Rubinius siga os passos abaixo. Para informações mais detalhadas veja [Começando](/doc/pt-br/getting-started/). - 1. `git clone git://github.com/rubinius/rubinius.git` -1. `cd rubinius` -1. `./configure --prefix=/path/to/install/dir` -1. `rake install` +2. `cd rubinius` +3. `./configure --prefix=/path/to/install/dir` +4. `rake install` -Quando o processo de instalação terminar, adicione o diretório executável -do Ruby (bin) ao seu PATH. +Quando o processo de instalação terminar, adicione o diretório do executável do +Rubinius (bin) ao seu PATH. -Rubinius vem com RubyGems e tem as gems rake e rdoc pré-instaladas. +Rubinius vem com RubyGems embutido e com as gems rake e rdoc pré-instaladas. Para instalar a gem nokogiri, por exemplo, rode `rbx gem install nokogiri` - From 85219e5653b844b7e5c38fc1221d4f955f8778cd Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Fri, 11 Nov 2011 13:51:52 +0100 Subject: [PATCH 22/67] Remove Syck build log file --- lib/19/syck/ext/mkmf.log | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 lib/19/syck/ext/mkmf.log diff --git a/lib/19/syck/ext/mkmf.log b/lib/19/syck/ext/mkmf.log deleted file mode 100644 index 45ab6d0275..0000000000 --- a/lib/19/syck/ext/mkmf.log +++ /dev/null @@ -1,15 +0,0 @@ --------------------- - -for st.h... -------------------- no - -checked program was: -/* begin */ - 1: #include "ruby.h" - 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: -20: #include -/* end */ - -nd */ - -"gcc -E -I/source/rubinius/rubinius/vm/capi/19/include -I/source/rubinius/rubinius/vm/capi/19/include/ruby/backward -I/source/rubinius/rubinius/vm/capi/19/include -I. -ggdb3 -fPIC -O2 conftest.c -o conftest.i" -conftest.c:3:16: error: st.h: No such file or directory From 11eff64353ce0f57bc024ac51be39a6053f382d2 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sat, 12 Nov 2011 13:44:53 +0100 Subject: [PATCH 23/67] Detect available of struct tm members On Solaris this is also not available, so just simply checking for Windows doesn't work. Detecting these struct members during configure time is a more robust solution so we can use if it's available. --- configure | 37 +++++++++++++++++++++++++++++++++++++ vm/builtin/time.cpp | 4 +++- vm/ffi_util.cpp | 2 ++ vm/util/time.c | 10 +++------- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/configure b/configure index 76314152d4..d04daf8cc1 100755 --- a/configure +++ b/configure @@ -821,6 +821,35 @@ int main() { return tgetnum(""); } @log.write @curses ? @curses : "not found" end + def has_struct_member(struct, member, includes = []) + @log.print "Checking whether struct #{struct} has member #{member}: " + tf = Tempfile.new("rbx-test") + includes.each do |i| + src = "#include <#{i}>" + tf.puts src + @log.log src + end + + src = "int main() { struct #{struct} st; st.#{member}; }" + tf.puts src + @log.log src + + tf.close + + system "#{@cxx} -S -o - -x c #{c_includes} #{env('CFLAGS')} #{tf.path} >>#{@log.path} 2>&1" + status = ($?.exitstatus == 0) + + tf.unlink + + if status + @log.write "found!" + else + @log.write "not found." + end + + return status + end + def has_function(name, includes=[]) @log.print "Checking for function '#{name}': " tf = Tempfile.new("rbx-test") @@ -867,6 +896,14 @@ int main() { return tgetnum(""); } @libyaml = true end + if has_struct_member("tm", "tm_gmtoff", ["time.h"]) + @defines << "HAVE_TM_GMTOFF" + end + + if has_struct_member("tm", "tm_zone", ["time.h"]) + @defines << "HAVE_TM_ZONE" + end + @vendor_zlib = true if @features["vendor-zlib"] end diff --git a/vm/builtin/time.cpp b/vm/builtin/time.cpp index 4168ae27ff..72eb42964f 100644 --- a/vm/builtin/time.cpp +++ b/vm/builtin/time.cpp @@ -110,8 +110,10 @@ namespace rubinius { } tm.tm_wday = -1; -#ifndef RBX_WINDOWS +#ifdef HAVE_TM_GMTOFF tm.tm_gmtoff = 0; +#endif +#ifdef HAVE_TM_ZONE tm.tm_zone = 0; #endif tm.tm_year = year->to_native() - 1900; diff --git a/vm/ffi_util.cpp b/vm/ffi_util.cpp index a1550c6dc7..23168847b5 100644 --- a/vm/ffi_util.cpp +++ b/vm/ffi_util.cpp @@ -40,6 +40,7 @@ time_t ffi_timezone() { return timezone; } #else +#ifdef HAVE_TM_GMTOFF // try FreeBSD extensions to struct tm time_t ffi_timezone() { struct tm *lt; @@ -51,6 +52,7 @@ time_t ffi_timezone() { return lt->tm_gmtoff; } #endif +#endif char* ffi_tzname(int dst) { if(dst) { diff --git a/vm/util/time.c b/vm/util/time.c index d217c66553..5e18b69444 100644 --- a/vm/util/time.c +++ b/vm/util/time.c @@ -415,10 +415,6 @@ mktime_extended(struct tm* tptr, int utc_p, int* err) { #include "vm/config.h" -#ifndef RBX_WINDOWS -#define HAVE_TM_ZONE 1 -#endif - /* defaults: season to taste */ #define SYSV_EXT 1 /* stuff in System V ascftime routine */ #define SUNOS_EXT 1 /* stuff in SunOS strftime routine */ @@ -817,10 +813,10 @@ strftime_extended(char *s, size_t maxsize, const char *format, const struct tm * * Systems with tm_zone probably have tm_gmtoff as * secs east of GMT. Convert to mins east of GMT. */ -#ifdef RBX_WINDOWS - off = _timezone / 60; +#ifdef HAVE_TM_GMTOFF + off = timeptr->tm_gmtoff / 60; #else - off = timeptr->tm_gmtoff / 60; + off = _timezone / 60; #endif #else /* !HAVE_TM_ZONE */ #if HAVE_VAR_TIMEZONE From 29ff80aa989dbffcfb8254cfa0c68f228ccad2b3 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sat, 12 Nov 2011 14:00:24 +0100 Subject: [PATCH 24/67] Solaris build fixes --- lib/ext/melbourne/grammar19.cpp | 1 + lib/ext/melbourne/grammar19.y | 1 + lib/zlib.rb.ffi | 8 ++++---- rakelib/blueprint.rb | 8 ++++++++ rakelib/ext_helper.rb | 3 ++- rakelib/platform.rake | 2 +- rakelib/rubinius.rb | 2 +- vm/environment.cpp | 2 +- vm/ffi_util.cpp | 5 ----- vm/llvm/state.cpp | 2 +- vm/oop.hpp | 1 + 11 files changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/ext/melbourne/grammar19.cpp b/lib/ext/melbourne/grammar19.cpp index 09a8c9908c..1f8109a8e7 100644 --- a/lib/ext/melbourne/grammar19.cpp +++ b/lib/ext/melbourne/grammar19.cpp @@ -306,6 +306,7 @@ #include #include #include +#include #include "ruby.h" diff --git a/lib/ext/melbourne/grammar19.y b/lib/ext/melbourne/grammar19.y index 2d40bb3703..be4694decf 100644 --- a/lib/ext/melbourne/grammar19.y +++ b/lib/ext/melbourne/grammar19.y @@ -25,6 +25,7 @@ #include #include #include +#include #include "ruby.h" diff --git a/lib/zlib.rb.ffi b/lib/zlib.rb.ffi index 867816ef87..e02d1b9ed5 100644 --- a/lib/zlib.rb.ffi +++ b/lib/zlib.rb.ffi @@ -83,7 +83,7 @@ module Zlib @@@ constants :required => true do |c| - c.include_dir 'vendor/zlib' + c.include_dir 'vendor/zlib' if BUILD_CONFIG[:vendor_zlib] c.include 'zlib.h' c.const 'ZLIB_VERSION', '%s', '(char *)', nil, to_s @@ -122,7 +122,7 @@ module Zlib @@@ constants do |c| - c.include_dir 'vendor/zlib' + c.include_dir 'vendor/zlib' if BUILD_CONFIG[:vendor_zlib] c.include 'zconf.h' c.const 'MAX_WBITS' @@ -150,7 +150,7 @@ module Zlib @@@ constants do |c| - c.include_dir 'vendor/zlib' + c.include_dir 'vendor/zlib' if BUILD_CONFIG[:vendor_zlib] c.include 'zlib.h' c.const 'OS_CODE' @@ -243,7 +243,7 @@ module Zlib def self.use_zstream_layout @@@ struct do |s| - s.include_dir 'vendor/zlib' + s.include_dir 'vendor/zlib' if BUILD_CONFIG[:vendor_zlib] s.include "zlib.h" s.name "struct z_stream_s" diff --git a/rakelib/blueprint.rb b/rakelib/blueprint.rb index 44f9a38ab4..f62e50ad9b 100644 --- a/rakelib/blueprint.rb +++ b/rakelib/blueprint.rb @@ -6,6 +6,8 @@ gcc.cflags << "-ggdb3 -Werror" gcc.cflags << "-DRBX_PROFILER" gcc.cflags << "-D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS" + gcc.cflags << "-D_LARGEFILE_SOURCE" + gcc.cflags << "-D_FILE_OFFSET_BITS=64" gcc.cflags << Rubinius::BUILD_CONFIG[:user_cflags] @@ -30,6 +32,8 @@ end if RUBY_PLATFORM =~ /darwin/i + gcc.cflags << "-D_DARWIN_USE_64_BIT_INODE" + if `sw_vers` =~ /10\.4/ gcc.cflags << "-DHAVE_STRLCAT -DHAVE_STRLCPY" end @@ -67,6 +71,10 @@ make = "gmake" when /mingw|win32/i gcc.ldflags << "-lws2_32" + when /solaris/ + gcc.cflags << "-fPIC" + gcc.ldflags << "-lsocket" << "-lnsl" << "-fPIC" << "-G" + make = "gmake" else gcc.ldflags << "-ldl" << "-lpthread" end diff --git a/rakelib/ext_helper.rb b/rakelib/ext_helper.rb index 95cd952b18..8a973a86f8 100644 --- a/rakelib/ext_helper.rb +++ b/rakelib/ext_helper.rb @@ -167,6 +167,7 @@ def add_rbx_capi when /solaris/ add_define "OS_SOLARIS8" + add_flag "-fPIC" if $CC == "cc" and `cc -flags 2>&1` =~ /Sun/ # detect SUNWspro compiler # SUN CHAIN @@ -176,7 +177,7 @@ def add_rbx_capi else # GNU CHAIN # on Unix we need a g++ link, not gcc. - $LDSHARED = "#{$CXX} -shared" + $LDSHARED = "#{$CXX} -shared -G -fPIC" end when /openbsd/ diff --git a/rakelib/platform.rake b/rakelib/platform.rake index 3038ce013b..e8fb841542 100644 --- a/rakelib/platform.rake +++ b/rakelib/platform.rake @@ -559,7 +559,7 @@ file 'runtime/platform.conf' => deps do |task| end.write_constants(f) FFI::Generators::Constants.new 'rbx.platform.zlib' do |cg| - cg.include_dir 'vendor/zlib' + cg.include_dir 'vendor/zlib' if BUILD_CONFIG[:vendor_zlib] cg.include 'zlib.h' zlib_constants = %w[ZLIB_VERSION] diff --git a/rakelib/rubinius.rb b/rakelib/rubinius.rb index 026ddb2807..d7c0999ed7 100644 --- a/rakelib/rubinius.rb +++ b/rakelib/rubinius.rb @@ -11,7 +11,7 @@ def expand(path) end def make(args = nil) - if RUBY_PLATFORM =~ /bsd/ + if RUBY_PLATFORM =~ /bsd/ || RUBY_PLATFORM =~ /solaris/ gmake = 'gmake' else gmake = 'make' diff --git a/vm/environment.cpp b/vm/environment.cpp index 0588e49bcf..2863bd8bb8 100644 --- a/vm/environment.cpp +++ b/vm/environment.cpp @@ -57,7 +57,7 @@ namespace rubinius { // Used by the segfault reporter. Calculated up front to avoid // crashing inside the crash handler. - static utsname machine_info; + static struct utsname machine_info; static char report_path[1024]; static const char* report_file_name = ".rubinius_last_error"; diff --git a/vm/ffi_util.cpp b/vm/ffi_util.cpp index 23168847b5..08c166961b 100644 --- a/vm/ffi_util.cpp +++ b/vm/ffi_util.cpp @@ -1,8 +1,3 @@ -// HACK constants so that we use the 64bit version of stat -#define _DARWIN_USE_64_BIT_INODE 1 -#define _LARGEFILE_SOURCE 1 -#define _FILE_OFFSET_BITS 64 - #include "config.h" #include diff --git a/vm/llvm/state.cpp b/vm/llvm/state.cpp index 1d65993d9f..ba34e7d2cc 100644 --- a/vm/llvm/state.cpp +++ b/vm/llvm/state.cpp @@ -1012,7 +1012,7 @@ namespace rubinius { std::cout << " ; " << addr; if(ud.mnemonic == UD_Icall) { Dl_info info; - if(dladdr(addr, &info)) { + if(dladdr((void*)addr, &info)) { int status = 0; char* cpp_name = abi::__cxa_demangle(info.dli_sname, 0, 0, &status); if(status >= 0) { diff --git a/vm/oop.hpp b/vm/oop.hpp index e29286fc52..d92c434749 100644 --- a/vm/oop.hpp +++ b/vm/oop.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "config.h" #include "object_types.hpp" From 0988e0499a0d412c360ab8393762074f778256af Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sat, 12 Nov 2011 14:08:01 +0100 Subject: [PATCH 25/67] Also include alloca.h for extensions --- vm/capi/18/include/ruby.h | 1 + vm/capi/19/include/ruby/ruby.h | 1 + 2 files changed, 2 insertions(+) diff --git a/vm/capi/18/include/ruby.h b/vm/capi/18/include/ruby.h index d4c81db00c..df6f566c02 100644 --- a/vm/capi/18/include/ruby.h +++ b/vm/capi/18/include/ruby.h @@ -31,6 +31,7 @@ #include #include #include +#include #include "intern.h" #include "defines.h" diff --git a/vm/capi/19/include/ruby/ruby.h b/vm/capi/19/include/ruby/ruby.h index 95a84930be..1d8ba98b17 100644 --- a/vm/capi/19/include/ruby/ruby.h +++ b/vm/capi/19/include/ruby/ruby.h @@ -34,6 +34,7 @@ extern "C" { #include #include #include +#include #include "intern.h" #include "defines.h" From 0659d96b9b1bea07374091fd965b83978b484679 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sat, 12 Nov 2011 17:01:34 +0100 Subject: [PATCH 26/67] Don't use -G on Solaris for the executable This option is only needed for shared libraries, not for an executable. --- rakelib/blueprint.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakelib/blueprint.rb b/rakelib/blueprint.rb index f62e50ad9b..26c74e4118 100644 --- a/rakelib/blueprint.rb +++ b/rakelib/blueprint.rb @@ -73,7 +73,7 @@ gcc.ldflags << "-lws2_32" when /solaris/ gcc.cflags << "-fPIC" - gcc.ldflags << "-lsocket" << "-lnsl" << "-fPIC" << "-G" + gcc.ldflags << "-lsocket" << "-lnsl" << "-fPIC" make = "gmake" else gcc.ldflags << "-ldl" << "-lpthread" From fb55bdc090cafdcd2b0f05d5bad904f8c628ab59 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sun, 13 Nov 2011 14:04:24 +0100 Subject: [PATCH 27/67] Allow using a different linker in Daedalus Not on all platforms (e.g. Solaris) you can link with gcc and expect all c++ features to work. If you don't use g++ on Solaris, c++ exceptions won't work and this Rubinius crashes. This changes allows Daedalus for using a different linker and sets it up to use g++ by default so we link the Rubinius binary with g++. --- projects/daedalus/daedalus.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/projects/daedalus/daedalus.rb b/projects/daedalus/daedalus.rb index cd8c143477..306d4bc44b 100644 --- a/projects/daedalus/daedalus.rb +++ b/projects/daedalus/daedalus.rb @@ -139,8 +139,9 @@ def stop end class Compiler - def initialize(path, logger, blueprint) - @path = path + def initialize(compiler, linker, logger, blueprint) + @compiler = compiler + @linker = linker @cflags = [] @ldflags = [] @libraries = [] @@ -207,12 +208,12 @@ def sha1(path) def compile(source, object) @log.show "CC" , source - @log.command "#{@path} #{@cflags.join(' ')} -c -o #{object} #{source}" + @log.command "#{@compiler} #{@cflags.join(' ')} -c -o #{object} #{source}" end def link(path, files) @log.show "LD", path - @log.command "#{@path} -o #{path} #{files.join(' ')} #{@libraries.join(' ')} #{@ldflags.join(' ')}" + @log.command "#{@linker} -o #{path} #{files.join(' ')} #{@libraries.join(' ')} #{@ldflags.join(' ')}" end def calculate_deps(path) @@ -733,7 +734,9 @@ def external_lib(path) end def gcc! - @compiler = Compiler.new(ENV['CC'] || "gcc", Logger.new, self) + @compiler = Compiler.new(ENV['CC'] || "gcc", + ENV['CXX'] || "g++", + Logger.new, self) end def source_files(*patterns) From aace867907c543258d81ba46e0c478b0207f5386 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sun, 13 Nov 2011 14:06:06 +0100 Subject: [PATCH 28/67] On Solaris getcwd allocates a buffer of the given size If you use getcwd on Solaris with a NULL pointer as the first argument, it will only allocate a buffer the size of the second argument when creating it. By giving a value larger than 0 as the argument, we make sure that enough space can be allocated for actually returning a String in this test. --- vm/test/test_nativefunction.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/test/test_nativefunction.hpp b/vm/test/test_nativefunction.hpp index 61ff529276..824d679314 100644 --- a/vm/test/test_nativefunction.hpp +++ b/vm/test/test_nativefunction.hpp @@ -157,7 +157,7 @@ class TestNativeFunction : public CxxTest::TestSuite, public VMTest { Array* input = Array::create(state, 2); input->set(state, 0, Qnil); - input->set(state, 1, Fixnum::from(0)); + input->set(state, 1, Fixnum::from(255)); Arguments args_obj(state->symbol("blah"), input); From 68973200279e8e475c81be53cff0afa01259245a Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sun, 13 Nov 2011 14:19:49 +0100 Subject: [PATCH 29/67] Remove unused types generator --- rakelib/types_generator.rb | 99 -------------------------------------- 1 file changed, 99 deletions(-) delete mode 100644 rakelib/types_generator.rb diff --git a/rakelib/types_generator.rb b/rakelib/types_generator.rb deleted file mode 100644 index 2b80b031ee..0000000000 --- a/rakelib/types_generator.rb +++ /dev/null @@ -1,99 +0,0 @@ -class TypesGenerator - - def self.generate - # Type maps that maps different C types to the C type representations we use - type_map = { - "char" => :char, - "signed char" => :char, - "__signed char" => :char, - "unsigned char" => :uchar, - "short" => :short, - "signed short" => :short, - "signed short int" => :short, - "unsigned short" => :ushort, - "unsigned short int" => :ushort, - "int" => :int, - "signed int" => :int, - "unsigned int" => :uint, - "long" => :long, - "long int" => :long, - "signed long" => :long, - "signed long int" => :long, - "unsigned long" => :ulong, - "unsigned long int" => :ulong, - "long unsigned int" => :ulong, - "long long" => :long_long, - "long long int" => :long_long, - "signed long long" => :long_long, - "signed long long int" => :long_long, - "unsigned long long" => :ulong_long, - "unsigned long long int" => :ulong_long, - "char *" => :string, - "void *" => :pointer - } - - typedefs = `echo "#include \n#include \n#include " | cpp -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64` - code = "" - typedefs.each do |type| - # We only care about single line typedef - next unless type =~ /typedef/ - # Ignore unions or structs - next if type =~ /union|struct/ - - # strip off the starting typedef and ending ; - type.gsub!(/^(.*typedef\s*)/, "") - type.gsub!(/\s*;\s*$/,"") - - parts = type.split(/\s+/) - def_type = parts.join(" ") - # GCC does mapping with __attribute__ stuf, also see - # http://hal.cs.berkeley.edu/cil/cil016.html section 16.2.7. - # Problem with this is that the __attribute__ stuff can either - # occur before or after the new type that is defined... - if type =~ /__attribute__/ - if parts.last =~ /__QI__|__HI__|__SI__|__DI__|__word__/ - # In this case, the new type is BEFORE __attribute__ - # we need to find the final_type as the type before the - # part that starts with __attribute__ - final_type = "" - parts.each do |p| - break if p =~ /__attribute__/ - final_type = p - end - else - final_type = parts.pop - end - - def_type = "int" - if type =~ /__QI__/ - def_type = "char" - elsif type =~ /__HI__/ - def_type = "short" - elsif type =~ /__SI__/ - def_type = "int" - elsif type =~ /__DI__/ - def_type = "long long" - elsif type =~ /__word__/ - def_type = "long" - end - def_type = "unsigned #{def_type}" if type =~ /unsigned/ - else - final_type = parts.pop - def_type = parts.join(" ") - end - - if type = type_map[def_type] - code << "rbx.platform.typedef.#{final_type} = #{type}\n" - type_map[final_type] = type_map[def_type] - else - # Fallback to an ordinary pointer if we don't know the type - if def_type =~ /\*/ - code << "rbx.platform.typedef.#{final_type} = pointer\n" - type_map[final_type] = :pointer - end - end - end - code - end -end - From 915495012a8d436ac576e20a0e1a679635f275ca Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sun, 13 Nov 2011 14:20:03 +0100 Subject: [PATCH 30/67] We need to check stdint.h for types too --- lib/ffi/generators/types.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ffi/generators/types.rb b/lib/ffi/generators/types.rb index 64cbe2fdc8..3ef1adb7fb 100644 --- a/lib/ffi/generators/types.rb +++ b/lib/ffi/generators/types.rb @@ -49,6 +49,7 @@ def initialize end def source(io) + io.puts "#include " io.puts "#include " unless @platform.windows? io.puts "#include " From a93adb46eac78b58a341ca993fe2bf67ee5f8669 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sun, 13 Nov 2011 14:20:24 +0100 Subject: [PATCH 31/67] Use the correct type for htons according to the man page This actually breaks otherwise on Solaris, since there is no type u_int16_t on that platform. The man page for htons also names uint16_t as the type for the argument and return value so we should adhere to that type. The previous commit makes sure this type is actually discovered on OS X, since on that platform apparently including sys/types.h doesn't make this type available. --- lib/socket.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/socket.rb b/lib/socket.rb index fb752c37f9..06e5ec3702 100644 --- a/lib/socket.rb +++ b/lib/socket.rb @@ -222,8 +222,8 @@ class AddrInfo < FFI::Struct attach_function :gethostname, [:pointer, :size_t], :int attach_function :getservbyname, [:pointer, :pointer], :pointer - attach_function :htons, [:u_int16_t], :u_int16_t - attach_function :ntohs, [:u_int16_t], :u_int16_t + attach_function :htons, [:uint16_t], :uint16_t + attach_function :ntohs, [:uint16_t], :uint16_t attach_function :_getnameinfo, "getnameinfo", [:pointer, :socklen_t, :pointer, :socklen_t, From 1968a3e4a4f9629ab0906452e2d88917f314e1e8 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sun, 13 Nov 2011 16:53:45 +0100 Subject: [PATCH 32/67] Use O2 for libtommath instead of O3 -O2 seems to break on Solaris and running Bignum benchmarks show no performance degradations when switching to this flag. In other places in Rubinius we also use O2, so using it should be fine here too if performance for Bignums is not affected. --- vendor/libtommath/makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/libtommath/makefile b/vendor/libtommath/makefile index 055d5c8547..628b236cce 100644 --- a/vendor/libtommath/makefile +++ b/vendor/libtommath/makefile @@ -18,7 +18,7 @@ endif ifndef IGNORE_SPEED #for speed -CFLAGS += -O3 -funroll-loops -ggdb3 +CFLAGS += -O2 -funroll-loops -ggdb3 #for size #CFLAGS += -Os From 3c24ba7d57ded52fe0a24f1ef69f791b027a1423 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sun, 13 Nov 2011 16:55:34 +0100 Subject: [PATCH 33/67] Use the HAVE_TM_ZONE define that is now available --- vm/builtin/time.cpp | 2 +- vm/builtin/time.hpp | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/vm/builtin/time.cpp b/vm/builtin/time.cpp index 72eb42964f..8c5cc2b741 100644 --- a/vm/builtin/time.cpp +++ b/vm/builtin/time.cpp @@ -179,7 +179,7 @@ namespace rubinius { ary->set(state, 7, Integer::from(state, tm.tm_yday + 1)); ary->set(state, 8, tm.tm_isdst ? Qtrue : Qfalse); -#ifdef HAVE_STRUCT_TM_TM_ZONE +#ifdef HAVE_TM_ZONE ary->set(state, 9, String::create(state, tm.tm_zone)); #else ary->set(state, 9, Qnil); diff --git a/vm/builtin/time.hpp b/vm/builtin/time.hpp index f5030b3856..12f3a56c29 100644 --- a/vm/builtin/time.hpp +++ b/vm/builtin/time.hpp @@ -7,11 +7,6 @@ #include "builtin/tuple.hpp" #include "builtin/integer.hpp" -#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) -# define HAVE_STRUCT_TM_TM_GMTOFF -# define HAVE_STRUCT_TM_TM_ZONE -#endif - namespace rubinius { class Array; class String; From c20e2cae4580b7175f1505e41d628b93f7739a25 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sun, 13 Nov 2011 18:43:55 +0100 Subject: [PATCH 34/67] Add configure option for globals and properly check for tzname etc. This allows us to know when we have tzname available as a fallback to finding the timezone name for platforms that don't have tm.tm_zone. --- configure | 41 +++++++++++++++++++++++++++++++++++++++++ vm/builtin/time.cpp | 11 ++++++----- vm/ffi_util.cpp | 2 +- vm/util/time.c | 10 ++++++++++ vm/util/time.h | 1 + 5 files changed, 59 insertions(+), 6 deletions(-) diff --git a/configure b/configure index d04daf8cc1..9a7618d56e 100755 --- a/configure +++ b/configure @@ -850,6 +850,35 @@ int main() { return tgetnum(""); } return status end + def has_global(name, includes=[]) + @log.print "Checking for global '#{name}': " + tf = Tempfile.new("rbx-test") + includes.each do |i| + src = "#include <#{i}>" + tf.puts src + @log.log src + end + + src = "int main() { #{name}; }" + tf.puts src + @log.log src + + tf.close + + system "#{@cxx} -S -o - -x c #{c_includes} #{env('CFLAGS')} #{tf.path} >>#{@log.path} 2>&1" + status = ($?.exitstatus == 0) + + tf.unlink + + if status + @log.write "found!" + else + @log.write "not found." + end + + return status + end + def has_function(name, includes=[]) @log.print "Checking for function '#{name}': " tf = Tempfile.new("rbx-test") @@ -904,6 +933,18 @@ int main() { return tgetnum(""); } @defines << "HAVE_TM_ZONE" end + if has_global("timezone", ["time.h"]) + @defines << "HAVE_TIMEZONE" + end + + if has_global("tzname", ["time.h"]) + @defines << "HAVE_TZNAME" + end + + if has_global("daylight", ["time.h"]) + @defines << "HAVE_DAYLIGHT" + end + @vendor_zlib = true if @features["vendor-zlib"] end diff --git a/vm/builtin/time.cpp b/vm/builtin/time.cpp index 8c5cc2b741..89a240a73f 100644 --- a/vm/builtin/time.cpp +++ b/vm/builtin/time.cpp @@ -179,11 +179,12 @@ namespace rubinius { ary->set(state, 7, Integer::from(state, tm.tm_yday + 1)); ary->set(state, 8, tm.tm_isdst ? Qtrue : Qfalse); -#ifdef HAVE_TM_ZONE - ary->set(state, 9, String::create(state, tm.tm_zone)); -#else - ary->set(state, 9, Qnil); -#endif + const char* tmzone = timezone_extended(&tm); + if(tmzone) { + ary->set(state, 9, String::create(state, tmzone)); + } else { + ary->set(state, 9, Qnil); + } // Cache it. decomposed(state, ary); diff --git a/vm/ffi_util.cpp b/vm/ffi_util.cpp index 08c166961b..44b4b09103 100644 --- a/vm/ffi_util.cpp +++ b/vm/ffi_util.cpp @@ -30,7 +30,7 @@ void ffi_set_errno(int n) { errno = n; } -#ifdef timezone +#ifdef HAVE_TIMEZONE time_t ffi_timezone() { return timezone; } diff --git a/vm/util/time.c b/vm/util/time.c index 5e18b69444..5c6c3e89f9 100644 --- a/vm/util/time.c +++ b/vm/util/time.c @@ -100,6 +100,16 @@ typedef unsigned long unsigned_time_t; // lifted from MRI's configure on OS X, probably right on most unix platforms? #define NEGATIVE_TIME_T 1 +const char* timezone_extended(struct tm* tptr) { +#ifdef HAVE_TM_ZONE + return tptr->tm_zone; +#elif HAVE_TZNAME && HAVE_DAYLIGHT + return tzname[daylight && tptr->tm_isdst]; +#else + return NULL; +#endif +} + time_t mktime_extended(struct tm* tptr, int utc_p, int* err) { time_t guess, guess_lo, guess_hi; diff --git a/vm/util/time.h b/vm/util/time.h index 0fe17b6d90..cc4049e64b 100644 --- a/vm/util/time.h +++ b/vm/util/time.h @@ -6,6 +6,7 @@ extern "C" { #endif #include +const char* timezone_extended(struct tm* tptr); time_t mktime_extended(struct tm* tptr, int utc_p, int* err); size_t strftime_extended(char *s, size_t maxsize, const char *format, const struct tm *timeptr, const struct timespec *ts, int gmt); From 73951ff3d7b483fbdf214342f6cb2e5f3402cdcf Mon Sep 17 00:00:00 2001 From: Karol Hosiawa Date: Sun, 13 Nov 2011 21:55:44 +0100 Subject: [PATCH 35/67] Added String#byteslice spec --- spec/ruby/core/string/byteslice_spec.rb | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 spec/ruby/core/string/byteslice_spec.rb diff --git a/spec/ruby/core/string/byteslice_spec.rb b/spec/ruby/core/string/byteslice_spec.rb new file mode 100644 index 0000000000..4f8ae7fa7b --- /dev/null +++ b/spec/ruby/core/string/byteslice_spec.rb @@ -0,0 +1,30 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/classes.rb', __FILE__) +require File.expand_path('../shared/slice.rb', __FILE__) + +ruby_version_is "1.9.3" do + describe "String#byteslice" do + it "needs to reviewed for spec completeness" + + it_behaves_like :string_slice, :byteslice + end + + describe "String#byteslice with index, length" do + it_behaves_like :string_slice_index_length, :byteslice + end + + describe "String#byteslice with Range" do + it_behaves_like :string_slice_range, :byteslice + end + + with_feature :encoding do + describe "String#byteslice on on non ASCII strings" do + it "returns byteslice of unicode strings" do + "\u3042".byteslice(1).should == "\x81".force_encoding("UTF-8") + "\u3042".byteslice(1, 2).should == "\x81\x82".force_encoding("UTF-8") + "\u3042".byteslice(1..2).should == "\x81\x82".force_encoding("UTF-8") + end + end + end +end + From 5f510d93a8a1f0b590714ed4453af7479a94b3c5 Mon Sep 17 00:00:00 2001 From: Mike Gehard Date: Sun, 13 Nov 2011 17:07:31 -0700 Subject: [PATCH 36/67] Fix RubySpec for StringIO#readbyte. --- lib/19/stringio.rb | 4 +++- spec/tags/19/ruby/library/stringio/readbyte_tags.txt | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 spec/tags/19/ruby/library/stringio/readbyte_tags.txt diff --git a/lib/19/stringio.rb b/lib/19/stringio.rb index fbace5c190..0302ac32c4 100644 --- a/lib/19/stringio.rb +++ b/lib/19/stringio.rb @@ -314,7 +314,9 @@ def readchar getc end - alias_method :readbyte, :readchar + def readbyte + readchar.getbyte(0) + end def readline(sep = $/) raise IO::EOFError, "end of file reached" if eof? diff --git a/spec/tags/19/ruby/library/stringio/readbyte_tags.txt b/spec/tags/19/ruby/library/stringio/readbyte_tags.txt deleted file mode 100644 index ad4574e447..0000000000 --- a/spec/tags/19/ruby/library/stringio/readbyte_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:StringIO#readbyte reads the next 8-bit byte from self's current position From b3794d8e5eb132ea48089b3cca6495dcb02e5eba Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Mon, 14 Nov 2011 10:56:10 -0800 Subject: [PATCH 37/67] Bump config version. --- Rakefile | 2 +- configure | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index f33e4a1f22..6e31d6003d 100644 --- a/Rakefile +++ b/Rakefile @@ -33,7 +33,7 @@ end require config_rb BUILD_CONFIG = Rubinius::BUILD_CONFIG -unless BUILD_CONFIG[:config_version] == 143 +unless BUILD_CONFIG[:config_version] == 144 STDERR.puts "Your configuration is outdated, please run ./configure first" exit 1 end diff --git a/configure b/configure index 9a7618d56e..8a7fa3f5c7 100755 --- a/configure +++ b/configure @@ -115,7 +115,7 @@ class Configure @libversion = "2.0" @version = "#{@libversion}.0dev" @release_date = "yyyy-mm-dd" - @config_version = 143 + @config_version = 144 # TODO: add conditionals for platforms if RbConfig::CONFIG["build_os"] =~ /darwin/ From f90fe0e1403c6c02cdbe2528091dea2cc60ba9bd Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Mon, 14 Nov 2011 11:03:51 -0800 Subject: [PATCH 38/67] Regenerate site with liquid 2.2.2. --- .../2010/12/15/rubinius-has-a-blog/index.html | 22 +- .../02/17/rubinius-what-s-next/index.html | 63 +- .../index.html | 6 +- .../02/23/introduction-to-fancy/index.html | 110 ++- .../2011/02/25/why-use-rubinius/index.html | 132 ++-- .../index.html | 24 +- .../17/running-ruby-with-no-ruby/index.html | 46 +- .../rubinius-t-shirts-and-stickers/index.html | 34 +- .../05/22/adam-prescott-on-scopes/index.html | 4 +- .../2011/05/26/rubinius-rewards/index.html | 52 +- .../07/inside-rubinius-20-preview/index.html | 8 +- .../01/rubinius-summit-in-pictures/index.html | 8 +- .../07/03/all-around-the-world/index.html | 4 +- .../07/05/whats-the-status-kenneth/index.html | 22 +- web/_site/2011/07/07/rbxday/index.html | 14 +- .../2011/07/29/rbxday-at-outright/index.html | 8 +- .../2011/07/31/rbxday-at-80beans/index.html | 12 +- .../2011/08/03/rbxday-in-real-life/index.html | 16 +- .../2011/08/05/rbxday-blog-posts/index.html | 24 +- web/_site/2011/08/30/rubinius-3d/index.html | 6 +- .../retiring-some-rubinius-rewards/index.html | 12 +- .../index.html | 2 +- .../10/18/contributing-to-rubinius/index.html | 88 ++- web/_site/about/1.1.1/index.html | 28 +- web/_site/about/one_one/index.html | 26 +- web/_site/about/one_point_oh/index.html | 20 +- web/_site/about/one_point_one/index.html | 30 +- web/_site/blog/index.html | 108 +-- .../doc/de/appendix-a-glossary/index.html | 16 +- .../doc/de/appendix-b-reading-list/index.html | 4 +- web/_site/doc/de/build-system/index.html | 8 +- .../transformations/index.html | 4 +- web/_site/doc/de/contributing/index.html | 8 +- .../de/contributing/style-guide/index.html | 20 +- .../running-rubinius/index.html | 2 +- .../de/how-to/fix-a-failing-spec/index.html | 2 +- .../doc/de/how-to/write-a-ticket/index.html | 22 +- web/_site/doc/de/ruby/index.html | 4 +- web/_site/doc/de/specs/index.html | 6 +- web/_site/doc/de/tools/profiler/index.html | 8 +- .../virtual-machine/instructions/index.html | 14 +- .../doc/en/appendix-a-glossary/index.html | 20 +- .../doc/en/appendix-b-reading-list/index.html | 8 +- web/_site/doc/en/build-system/index.html | 8 +- .../doc/en/bytecode-compiler/ast/index.html | 8 +- .../en/bytecode-compiler/generator/index.html | 2 +- .../en/bytecode-compiler/parser/index.html | 2 +- .../transformations/index.html | 4 +- web/_site/doc/en/contributing/index.html | 4 +- .../en/contributing/style-guide/index.html | 16 +- .../mature-generation/index.html | 2 +- .../en/garbage-collector/nursery/index.html | 4 +- .../getting-started/requirements/index.html | 2 +- .../running-rubinius/index.html | 2 +- .../doc/en/how-to/commit-to-github/index.html | 6 +- .../en/how-to/fix-a-failing-spec/index.html | 10 +- .../how-to/translate-documentation/index.html | 20 +- .../doc/en/how-to/write-a-ticket/index.html | 20 +- .../doc/en/how-to/write-benchmarks/index.html | 4 +- web/_site/doc/en/ruby/index.html | 2 +- web/_site/doc/en/specs/index.html | 6 +- .../doc/en/systems/concurrency/index.html | 2 +- .../doc/en/tools/memory-analysis/index.html | 10 +- web/_site/doc/en/tools/profiler/index.html | 24 +- .../virtual-machine/instructions/index.html | 14 +- .../doc/es/appendix-a-glossary/index.html | 10 +- .../doc/es/appendix-b-reading-list/index.html | 4 +- web/_site/doc/es/build-system/index.html | 6 +- .../transformations/index.html | 4 +- web/_site/doc/es/contributing/index.html | 4 +- .../es/contributing/style-guide/index.html | 14 +- .../running-rubinius/index.html | 2 +- .../troubleshooting/index.html | 4 +- .../doc/es/how-to/commit-to-github/index.html | 4 +- .../es/how-to/fix-a-failing-spec/index.html | 48 +- .../es/how-to/write-a-ruby-spec/index.html | 25 +- .../doc/es/how-to/write-a-ticket/index.html | 107 ++- .../doc/es/how-to/write-benchmarks/index.html | 4 +- web/_site/doc/es/specs/index.html | 6 +- web/_site/doc/es/tools/debugger/index.html | 2 +- web/_site/doc/es/tools/profiler/index.html | 20 +- .../virtual-machine/instructions/index.html | 14 +- .../doc/fr/appendix-a-glossary/index.html | 20 +- .../doc/fr/appendix-b-reading-list/index.html | 8 +- web/_site/doc/fr/build-system/index.html | 8 +- .../fr/bytecode-compiler/generator/index.html | 2 +- .../fr/bytecode-compiler/parser/index.html | 2 +- .../transformations/index.html | 4 +- web/_site/doc/fr/contributing/index.html | 4 +- .../fr/contributing/style-guide/index.html | 16 +- .../fr/getting-started/building/index.html | 22 +- .../getting-started/requirements/index.html | 20 +- .../running-rubinius/index.html | 6 +- .../troubleshooting/index.html | 16 +- .../fr/how-to/fix-a-failing-spec/index.html | 16 +- .../how-to/translate-documentation/index.html | 4 +- .../fr/how-to/write-a-blog-post/index.html | 8 +- .../fr/how-to/write-a-ruby-spec/index.html | 6 +- .../doc/fr/how-to/write-a-ticket/index.html | 44 +- .../doc/fr/how-to/write-benchmarks/index.html | 4 +- web/_site/doc/fr/index.html | 14 +- web/_site/doc/fr/ruby/index.html | 2 +- web/_site/doc/fr/specs/index.html | 6 +- .../doc/fr/systems/concurrency/index.html | 2 +- .../doc/fr/tools/memory-analysis/index.html | 10 +- web/_site/doc/fr/tools/profiler/index.html | 22 +- .../virtual-machine/instructions/index.html | 14 +- web/_site/doc/fr/what-is-rubinius/index.html | 8 +- .../doc/ja/appendix-a-glossary/index.html | 20 +- .../doc/ja/appendix-b-reading-list/index.html | 8 +- web/_site/doc/ja/build-system/index.html | 8 +- .../transformations/index.html | 4 +- web/_site/doc/ja/contributing/index.html | 4 +- .../ja/contributing/style-guide/index.html | 16 +- .../ja/getting-started/building/index.html | 4 +- .../running-rubinius/index.html | 2 +- .../ja/how-to/fix-a-failing-spec/index.html | 4 +- .../doc/ja/how-to/write-a-ticket/index.html | 20 +- .../ja/how-to/write-documentation/index.html | 10 +- web/_site/doc/ja/specs/index.html | 6 +- web/_site/doc/ja/tools/profiler/index.html | 20 +- .../virtual-machine/instructions/index.html | 14 +- .../doc/pl/appendix-a-glossary/index.html | 20 +- .../doc/pl/appendix-b-reading-list/index.html | 8 +- web/_site/doc/pl/build-system/index.html | 8 +- .../pl/bytecode-compiler/generator/index.html | 2 +- .../pl/bytecode-compiler/parser/index.html | 2 +- .../transformations/index.html | 2 +- .../pl/contributing/style-guide/index.html | 16 +- .../pl/getting-started/building/index.html | 4 +- .../getting-started/requirements/index.html | 2 +- .../running-rubinius/index.html | 2 +- .../pl/how-to/fix-a-failing-spec/index.html | 4 +- .../doc/pl/how-to/write-a-ticket/index.html | 20 +- web/_site/doc/pl/ruby/index.html | 2 +- web/_site/doc/pl/specs/index.html | 6 +- .../doc/pl/tools/memory-analysis/index.html | 2 +- web/_site/doc/pl/tools/profiler/index.html | 22 +- .../virtual-machine/instructions/index.html | 14 +- .../doc/pt-br/appendix-a-glossary/index.html | 14 +- .../pt-br/appendix-b-reading-list/index.html | 4 +- web/_site/doc/pt-br/build-system/index.html | 8 +- .../bytecode-compiler/generator/index.html | 2 +- .../pt-br/bytecode-compiler/parser/index.html | 2 +- .../transformations/index.html | 4 +- web/_site/doc/pt-br/contributing/index.html | 4 +- .../pt-br/contributing/style-guide/index.html | 16 +- .../running-rubinius/index.html | 2 +- .../how-to/fix-a-failing-spec/index.html | 4 +- .../pt-br/how-to/write-a-ticket/index.html | 20 +- .../pt-br/how-to/write-benchmarks/index.html | 4 +- web/_site/doc/pt-br/ruby/index.html | 2 +- web/_site/doc/pt-br/specs/index.html | 6 +- .../pt-br/tools/memory-analysis/index.html | 10 +- web/_site/doc/pt-br/tools/profiler/index.html | 22 +- .../virtual-machine/instructions/index.html | 14 +- .../doc/pt-br/what-is-rubinius/index.html | 27 +- .../doc/ru/appendix-a-glossary/index.html | 18 +- .../doc/ru/appendix-b-reading-list/index.html | 8 +- web/_site/doc/ru/bootstrapping/index.html | 12 +- .../ru/bytecode-compiler/parser/index.html | 8 +- .../transformations/index.html | 6 +- .../ru/contributing/communication/index.html | 2 +- web/_site/doc/ru/contributing/index.html | 14 +- .../ru/contributing/style-guide/index.html | 18 +- .../mature-generation/index.html | 2 +- .../ru/getting-started/building/index.html | 4 +- .../getting-started/requirements/index.html | 2 +- .../running-rubinius/index.html | 2 +- .../doc/ru/how-to/commit-to-github/index.html | 8 +- .../ru/how-to/fix-a-failing-spec/index.html | 2 +- .../how-to/translate-documentation/index.html | 16 +- .../ru/how-to/write-a-blog-post/index.html | 2 +- .../doc/ru/how-to/write-a-ticket/index.html | 18 +- .../doc/ru/how-to/write-benchmarks/index.html | 2 +- .../ru/how-to/write-documentation/index.html | 2 +- web/_site/doc/ru/index.html | 2 +- .../doc/ru/ruby/global-variables/index.html | 2 +- web/_site/doc/ru/ruby/index.html | 18 +- web/_site/doc/ru/specs/index.html | 16 +- .../doc/ru/systems/concurrency/index.html | 12 +- web/_site/doc/ru/tools/profiler/index.html | 22 +- .../virtual-machine/instructions/index.html | 14 +- web/_site/doc/ru/what-is-rubinius/index.html | 4 +- web/_site/feed/atom.xml | 717 ++++++++++-------- web/_site/projects/index.html | 2 +- web/_site/releases/1.0.0/index.html | 20 +- web/_site/releases/1.0.1/index.html | 30 +- web/_site/releases/1.1.0/index.html | 26 +- web/_site/releases/1.1.1/index.html | 28 +- web/_site/releases/1.2.0/index.html | 6 +- web/_site/releases/1.2.1/index.html | 18 +- web/_site/releases/1.2.2/index.html | 2 +- web/_site/releases/1.2.3/index.html | 12 +- web/_site/releases/1.2.4/index.html | 24 +- 195 files changed, 1764 insertions(+), 1611 deletions(-) diff --git a/web/_site/2010/12/15/rubinius-has-a-blog/index.html b/web/_site/2010/12/15/rubinius-has-a-blog/index.html index 65c04c25b7..b3b9dbe0dd 100644 --- a/web/_site/2010/12/15/rubinius-has-a-blog/index.html +++ b/web/_site/2010/12/15/rubinius-has-a-blog/index.html @@ -71,24 +71,24 @@

Rubinius Has a Blog!

-

Many thought the day would never come, but Rubinius finally has a blog. That’s +

Many thought the day would never come, but Rubinius finally has a blog. That’s not all, though: We have integrated the website, blog, and documentation using Jekyll. The source code for it all is in the main Rubinius repository.

People have often requested that we write more about the awesome features in -Rubinius. We hear you and we’d love to do this. However, there is always a +Rubinius. We hear you and we’d love to do this. However, there is always a trade-off between working on those awesome features and writing about them. -Until now, it’s been rather painful to write docs or blog posts because we did -not have good infrastructure in place. Now, I think we do. I’m sure there are +Until now, it’s been rather painful to write docs or blog posts because we did +not have good infrastructure in place. Now, I think we do. I’m sure there are still a lot of improvements we can make, but we have a good place to start. -I’d like to give a brief tour of our new system.

+I’d like to give a brief tour of our new system.

The primary goal was to improve collaboration and reduce friction for writing -new documentation and blog posts. That’s right, improve collaboration. There +new documentation and blog posts. That’s right, improve collaboration. There are many people who have experience developing Rubinius and running their applications on it. We love how people have collaborated with source code -commits. Now anyone has the ability to write a blog post as well. I’ve written +commits. Now anyone has the ability to write a blog post as well. I’ve written a basic How-To - Write a Blog Post document. If you have an idea for a blog post, just let us know. We will exercise a bit of editorial control just to ensure the topics are appropriate @@ -108,13 +108,13 @@

Rubinius Has a Blog!

Spanish, so we are again depending on your help. I started the translation effort by passing the existing English docs through Google translate. We have a beginning guide for How-To - Translate -Documentation. I’ve been told by -kronos_vano in our #rubinius IRC channel that he’s already working on a +Documentation. I’ve been told by +kronos_vano in our #rubinius IRC channel that he’s already working on a Russian translation. I personally would love to see Japanese and Chinese translations.

-

So that’s a brief introduction to our new infrastructure for documenting and -explaining Rubinius. It’s been such a joy to see so many people contribute to +

So that’s a brief introduction to our new infrastructure for documenting and +explaining Rubinius. It’s been such a joy to see so many people contribute to the Rubinius source code over the years. We hope that the blog, documentation, and translations will further empower people to contribute and benefit from the value that Rubinius has to offer the Ruby community.

diff --git a/web/_site/2011/02/17/rubinius-what-s-next/index.html b/web/_site/2011/02/17/rubinius-what-s-next/index.html index 6025624f34..8d32da0cb6 100644 --- a/web/_site/2011/02/17/rubinius-what-s-next/index.html +++ b/web/_site/2011/02/17/rubinius-what-s-next/index.html @@ -78,8 +78,8 @@

Rubinius, What's Next?

us test it.

While we were working on 1.2.1, we were also working on a Top Secret project -that we’ve craftily hidden in plain -sight. I’d like to introduce +that we’ve craftily hidden in plain +sight. I’d like to introduce the work we are doing on the hydra branch and the features you can expect to see in Rubinius soon.

@@ -130,7 +130,7 @@

Daedalus - A new build system

  • With a multi-core system, builds can be done faster if they are done in parallel. If the build system can accurately determine dependencies, it can execute build sub-steps in parallel. Of course, this can cut into YouTube -and Twitter browsing time, but that’s a risk we are willing to take.
  • +and Twitter browsing time, but that’s a risk we are willing to take.
  • While parallel sub-processes during the build are excellent, the supervising process benefits from running as a single process from start to finish. Otherwise, configuration data needs to be re-parsed. To support a single @@ -141,7 +141,7 @@

    Daedalus - A new build system

  • Use-aware configuration values know that the user has set the value and can intelligently merge with newer configuration variables that we create without requiring the user to reconfigure. Ultimately, we are aiming for a -single command build. Just run ‘daedalus’ and done. There is no step 2.
  • +single command build. Just run ‘daedalus’ and done. There is no step 2.

    Full-on Concurrency

    @@ -156,7 +156,7 @@

    Full-on Concurrency

    are so many multi-core CPUs around these days, our programs should be getting stuff done in parallel.

    -

    Unfortunately, there’s a twist. Even with native threads on a multi-core CPU, +

    Unfortunately, there’s a twist. Even with native threads on a multi-core CPU, the amount of parallelism you get depends on how well you manage locks around shared data and resources. Sometimes managing these locks is complex and you opt for one big lock, essentially only allowing one thread at a time to run. @@ -192,7 +192,7 @@

    Performance

    fronts on which we are attacking performance issues: 1) improving the algorithms in the Ruby code that implements the core library; 2) continuing to tune the VM and garbage collector; and 3) improving the JIT compiler. Which -leads me to one of the most exciting things we are working on…

    +leads me to one of the most exciting things we are working on…

    JIT Intermediate Representation (IR)

    @@ -201,7 +201,25 @@

    JIT Intermediate Representation (IR) actually being invoked when a message is sent to an object. Consider the following code:

    -

    Liquid error: undefined method `join’ for #

    +
     1 class A
    + 2   def m(x)
    + 3     ...
    + 4   end
    + 5 end
    + 6 
    + 7 class B
    + 8   def m(x)
    + 9     ...
    +10   end
    +11 end
    +12 
    +13 class C
    +14   def work(obj)
    +15     obj.m(y)
    +16   end
    +17 end
    +
    +

    What method is being invoked by obj.m(y)? There is no way to definitively know this by looking at the source code. However, when the program is actually @@ -220,8 +238,8 @@

    JIT Intermediate Representation (IR)

    This new IR will help us to express Ruby semantics in a way that enables many powerful optimizations and will ultimately allow LLVM to generate even better machine code. Put another way, Rubinius loves Ruby code! Right down to the -metal. There’s no fighting a foreign type system or the semantics of a -language at odds with Ruby’s rosy view of the world.

    +metal. There’s no fighting a foreign type system or the semantics of a +language at odds with Ruby’s rosy view of the world.

    Ruby 1.9

    @@ -249,7 +267,7 @@

    Tools of Information

    Presently, Rubinius has a built-in debugger, precise method profiler, memory analysis tool, and Agent interface that permits querying a running Rubinius -VM–even one running on a remote machine–for a variety of information.

    +VM–even one running on a remote machine–for a variety of information.

    We will be adding the ability to track the location where objects are allocated to assist finding object leaks or code that is creating unusually @@ -266,11 +284,11 @@

    Tools of Information

    gathering VM data. Later the two data sets could easily be merged.

    When you find yourself manually instrumenting some code, consider what data -you are trying to get your hands on and let us know the scenario. We’ll +you are trying to get your hands on and let us know the scenario. We’ll likely be able to build a tool that will open up new vistas into the behavior of your Ruby programs.

    -

    Windows®

    +

    Windows®

    However one may feel about Windows as an operating system, it is undeniable that the vast majority of people in the world use Windows. We believe those @@ -302,7 +320,18 @@

    Multi-language-ualization

    Hopefully, Evan will introduce us to all this in a future blog post, but here is a taste of what you can do:

    -

    Liquid error: undefined method `join’ for #

    +
     1 class Hello
    + 2   dynamic_method :world do |g|
    + 3     g.push :self
    + 4     g.push_literal "Hello, world"
    + 5     g.send :puts, 1, true
    + 6     g.ret
    + 7   end
    + 8 end
    + 9 
    +10 Hello.new.world
    +
    +

    Of course, that is much more concisely written in Ruby, but combine this ability with a built-in PEG parser and you can be experimenting with your own @@ -315,14 +344,14 @@

    Multi-language-ualization

    Documentation

    -

    One the one hand, Rubinius just runs Ruby code, and you shouldn’t need any +

    One the one hand, Rubinius just runs Ruby code, and you shouldn’t need any special knowledge to run your application on Rubinius. On the other hand, as -I’ve discussed above, there are some specific Rubinius features that may be +I’ve discussed above, there are some specific Rubinius features that may be very helpful to you. However, they can only be as helpful as the documentation we have for them.

    Before we released 1.2.0 in December last year, I spent quite a bit of time -getting a new documentation system in place. Since then, we’ve had +getting a new documentation system in place. Since then, we’ve had contributors help with translations to Russian, Polish, Spanish, and German. Adam Gardiner started documenting the garbage collector algorithms. Yehuda Katz (you may have heard the name) has contributed documentation for the @@ -348,7 +377,7 @@

    How you can help

    feedback. Let us know what features or tools would make your life easier. Help us to build them.

    -

    Rubinius adopts Ruby’s rosy view of the world. We want to empower you to solve +

    Rubinius adopts Ruby’s rosy view of the world. We want to empower you to solve your hardest problems with Ruby, and have fun doing it.

    diff --git a/web/_site/2011/02/22/rubinius-multiple-branches-with-rvm/index.html b/web/_site/2011/02/22/rubinius-multiple-branches-with-rvm/index.html index 9835f83cb5..3a62c680a8 100644 --- a/web/_site/2011/02/22/rubinius-multiple-branches-with-rvm/index.html +++ b/web/_site/2011/02/22/rubinius-multiple-branches-with-rvm/index.html @@ -87,11 +87,11 @@

    Named Ruby Installs

    rvm install rbx
     
    -

    What is not widely known (yet) is that there is a “Named Rubies” feature +

    What is not widely known (yet) is that there is a “Named Rubies” feature that allows you to install altered versions of the same Ruby installation along side the original.

    -

    In the case of Rubinius there is this facinating branch called ‘hydra’. +

    In the case of Rubinius there is this facinating branch called ‘hydra’. So let us see how we can have the Rubinius master branch installed as the main rbx with the hydra branch installed along side as well.

    @@ -109,7 +109,7 @@

    Named Ruby Installs

    After we have the mainline head Rubinus branch installed, we now want to use the named rubies feature. This is done using the -n specifier in the Ruby identifier string. So for example to install our hydra branch as an -RVM ruby with the name ‘hydra’ in it we do the following:

    +RVM ruby with the name ‘hydra’ in it we do the following:

    rvm install --branch hydra rbx-nhydra
     
    diff --git a/web/_site/2011/02/23/introduction-to-fancy/index.html b/web/_site/2011/02/23/introduction-to-fancy/index.html index eca1f6b5c8..abeeb36353 100644 --- a/web/_site/2011/02/23/introduction-to-fancy/index.html +++ b/web/_site/2011/02/23/introduction-to-fancy/index.html @@ -75,14 +75,14 @@

    Introduction to Fancy

    Rubinius VM.

    This blog post will give a short introduction to the language, what -kind of problems it’s trying to solve and why I chose Rubinius as the +kind of problems it’s trying to solve and why I chose Rubinius as the VM to run Fancy on.

    What is Fancy?

    Fancy is a new general-purpose, dynamic, pure object-oriented programming language heavily inspired by Ruby, Smalltalk and Erlang -that runs on the Rubinius VM. It’s the first fully bootstrapped +that runs on the Rubinius VM. It’s the first fully bootstrapped language, aside from Ruby, running on Rubinius. This means that the compiler that generates bytecode for Rubinius is written in Fancy itself.

    @@ -118,34 +118,34 @@

    Why Fancy?

    certain things out of the box. Especially when it comes to things like asynchronous and concurrent programming, having proper semantics built into the language can often help developers more than a library can. -Very often it’s not just about the functionality itself but also about +Very often it’s not just about the functionality itself but also about the semantics you want that functionality to have. This can cause -problems particularly if the language’s semantics differ from what +problems particularly if the language’s semantics differ from what your library is trying to solve. A good example is the callback-based approach to asynchronous progamming which leads to code that differs both in semantics as well as how code is structured, compared to -synchronous code. Ideally you’d still want to write code in a +synchronous code. Ideally you’d still want to write code in a synchronous fashion, where exceptions pop up naturally while still being highly asynchronous.

    -

    In that sense Fancy is more flexible than Ruby as there’s not many -special case semantics built in to the core language. Everything’s +

    In that sense Fancy is more flexible than Ruby as there’s not many +special case semantics built in to the core language. Everything’s done via message passing, which fits nicely the actor model approach -to concurrency. Fancy’s syntax is a lot simpler, too.

    +to concurrency. Fancy’s syntax is a lot simpler, too.

    Since all the core control structures are just implemented in Fancy itself and adhere to the message passing protocol, you can easily override them for your personal needs. This is especially interesting when implementing domain specific languages. -Say, you’d want to add some logging to conditional or looping -constructs - it’s as easy as overriding a method in your DSL’s +Say, you’d want to add some logging to conditional or looping +constructs - it’s as easy as overriding a method in your DSL’s classes. Fancy also has class-based mixins, so it makes it easy to share functionality across class hierarchy boundaries.

    Finally, I created Fancy because I wanted a language implementation that was well documented, easy to understand and very flexible to extend. Ruby is a nice language, but it has some inconsistencies and -there’s only so much you can do when you’re bound by backwards +there’s only so much you can do when you’re bound by backwards compatibility. By starting fresh, Fancy has a clean, simple and easy to extend core which allows further exploration of features and abstractions.

    @@ -157,98 +157,130 @@

    Why target Rubinius?

    walker. After moving to Rubinius and writing an initial bootstrap compiler in Ruby, the codebase shrank to about 20% of the original implementation while actually being more performant. This of course is -mostly due to Rubinius’ architecture and JIT compiler but it was a +mostly due to Rubinius’ architecture and JIT compiler but it was a great experience nontheless.

    The nice part about having a common virtual machine and runtime is -that you’re not forced to a completely different platform to get the +that you’re not forced to a completely different platform to get the job done. Fancy and Ruby can coexist in the same application nicely and calling code from one another is dead simple. In fact, as of now, -Rubinius doesn’t know anything about Fancy. And it shouldn’t. As long +Rubinius doesn’t know anything about Fancy. And it shouldn’t. As long as all languages running on top of it adhere to the same interface (in this case the bytecode), it should just work fine.

    -

    Choosing Rubinius as a successor platform for Fancy was easy. It’s -built for Ruby, a language that’s closely related to Fancy. Rubinius, +

    Choosing Rubinius as a successor platform for Fancy was easy. It’s +built for Ruby, a language that’s closely related to Fancy. Rubinius, while having been developed as a VM for running Ruby code, is very -flexible and there are many features that abstract over Ruby’s +flexible and there are many features that abstract over Ruby’s external semantics. It was just a natural choice given the fact that -Rubinius’ architecture and design was heavily influenced by Smalltalk -VMs. Also, it’s a very nice dynamic bytecode virtual machine. The +Rubinius’ architecture and design was heavily influenced by Smalltalk +VMs. Also, it’s a very nice dynamic bytecode virtual machine. The community is very responsive and helpful. Bugs get fixed instantly, -there’s always someone to help out and overall it’s been a great +there’s always someone to help out and overall it’s been a great experience.

    -

    Let’s look at some code!

    +

    Let’s look at some code!

    -

    OK, enough talking. Let’s have a look on how to get some Fancy code up +

    OK, enough talking. Let’s have a look on how to get some Fancy code up and running. Our little sample application will be a simple IRC bot -that connects to Fancy’s irc channel on Freenode and says hello to -everyone that greets it. To make life easier, there’s already a Fancy +that connects to Fancy’s irc channel on Freenode and says hello to +everyone that greets it. To make life easier, there’s already a Fancy package out there that helps with exactly this task: FancyIRC.

    -

    FancyIRC is a simple IRC client library inspired by Ruby’s IRC bot -framework Cinch. It’s much simpler +

    FancyIRC is a simple IRC client library inspired by Ruby’s IRC bot +framework Cinch. It’s much simpler and the code is fairly easy to read, but it gives you a similar interface for writing IRC clients or bots.

    -

    So let’s get going by installing Fancy. You can either use the Fancy +

    So let’s get going by installing Fancy. You can either use the Fancy Rubygem and install it with Rubinius or get the code from GitHub and -run rake in the directory. You’ll also then have to add the bin +run rake in the directory. You’ll also then have to add the bin directory to your $PATH. If you want the latest and greatest version of Fancy I recommend building directly from source, as the Gem might -not be up to date all the time. For demonstration purposes, let’s +not be up to date all the time. For demonstration purposes, let’s install the Rubygem.

    $ rbx -S gem install fancy
     
    -

    To get the FancyIRC package we use Fancy’s built-in package manager, +

    To get the FancyIRC package we use Fancy’s built-in package manager, which knows how to find the code on GitHub and install it locally:

    $ fancy install bakkdoor/fancy_irc
     

    Writing the code

    -

    Liquid error: undefined method `join’ for #

    + +
     1 require: "fancy_irc"
    + 2 
    + 3 greeter_bot = FancyIRC Client new: {
    + 4   configuration: {
    + 5     nickname: "greeter_bot"
    + 6     server: "irc.freenode.net"
    + 7     port: 6667
    + 8     channels: ["#fancy"]
    + 9   }
    +10 
    +11   # greet person back
    +12   on: 'channel pattern: /^[hH]ello greeter_bot/ do: |msg| {
    +13     msg reply: "Hello to you too, #{msg author}!"
    +14   }
    +15 
    +16   # "echo" command
    +17   # invoke with: !echo <text>
    +18   on: 'channel pattern: /^!echo (.*)$/ do: |msg, text| {
    +19     msg reply: "#{msg author} said: #{text}"
    +20   }
    +21 
    +22   # tell bot to shutdown via !shutdown command
    +23   on: 'channel pattern: /^!shutdown/ do: |msg| {
    +24     msg reply: "OK, shutting down"
    +25     System exit
    +26   }
    +27 }
    +28 
    +29 greeter_bot connect
    +30 greeter_bot run
    +
    +

    I think the code is pretty straight forward. This should give you a feeling for what Fancy looks and feels like. There is of course lots more to Fancy than what was shown here. It would not fit into a single blog post.

    -

    A quick list of what’s currently being worked on:

    +

    A quick list of what’s currently being worked on:

    • New pattern matching system: Message passing based pattern matching that preserves encapsulation and is very extensible including pattern literals that allow custom pattern types to be defined by -anyone. There’s an experimental branch for that. I’m happy +anyone. There’s an experimental branch for that. I’m happy to answer questions.
    • Async support using coroutines (Fibers) - Write async code in a more -natural way where exceptions propagate naturally and you don’t have +natural way where exceptions propagate naturally and you don’t have to think about callbacks all the time.
    • First-class support for actors - Asynchronous message sends, Futures and multi-vm messaging built-in.
    • -
    • And much more…
    • +
    • And much more…

    Interested?

    If you got interested in Fancy and want to know where to go next, -here’s a short list of things to check out:

    +here’s a short list of things to check out:

    diff --git a/web/_site/2011/02/25/why-use-rubinius/index.html b/web/_site/2011/02/25/why-use-rubinius/index.html index 3dc1f149b0..a53701f76d 100644 --- a/web/_site/2011/02/25/why-use-rubinius/index.html +++ b/web/_site/2011/02/25/why-use-rubinius/index.html @@ -73,20 +73,20 @@

    Why Use Rubinius

    Why should I use Rubinius? We have been asked that question many, many times over the past four years. It is a great question. It is an important question. -It’s a hard question. I’m not holding out on you. I want to give you an +It’s a hard question. I’m not holding out on you. I want to give you an answer that sates your curiosity, helps you make informed decisions, and -empowers you to speak eloquently when you are inevitably asked, “Why do you -use Rubinius?”

    +empowers you to speak eloquently when you are inevitably asked, “Why do you +use Rubinius?”

    The trouble is, there are many different situations in which people use Ruby and there is simply no answer, however comprehensive, that really speaks to -everyone’s concerns. So rather that boring you at length, I thought a Choose +everyone’s concerns. So rather that boring you at length, I thought a Choose your own adventure style would be a better approach.

    -

    From the list below, select the persona that best describes you. Don’t worry, -if the one you select doesn’t sound right, you can easily backtrack here. Read +

    From the list below, select the persona that best describes you. Don’t worry, +if the one you select doesn’t sound right, you can easily backtrack here. Read as many as interest you. After all, none of us fit easily into any one box. -When you are done exploring all the fascinating reasons to use Rubinius, let’s +When you are done exploring all the fascinating reasons to use Rubinius, let’s meet up at the Conclusion for some parting words.

    @@ -114,26 +114,26 @@

    Rails or Ruby Newby

    You are the empty teacup of the Zen proverb. You are a fresh-faced flower glistening with the morning dew. The sun smiles on you and you smile back. -You seem to like this Ruby language that makes programmers happy and you’ve -come to lend your cheery spirit…

    +You seem to like this Ruby language that makes programmers happy and you’ve +come to lend your cheery spirit…

    Welcome!

    So, you have heard of this thing called Rubinius or rbx or whatever and some folks you respect or admire seem to like it and naturally you want to know -what the big deal is and you’re like, “Yo, why would I use Rubinius?”.

    +what the big deal is and you’re like, “Yo, why would I use Rubinius?”.

    Cool.

    Well, you should use Rubinius because I said so. Try your code on it. Tell us -what worked for you. Tell us if something didn’t work by opening an +what worked for you. Tell us if something didn’t work by opening an issue. Set your imagination loose and tell us what tool you would use if you could.

    Spend some time reading the Rubinius source code. Start at the kernel/ -directory. It’s full of Ruby code! As you read through how Ruby is +directory. It’s full of Ruby code! As you read through how Ruby is implemented, how it actually works, it will give you a level of understanding -of your code that many programmers don’t have in any language.

    +of your code that many programmers don’t have in any language.

    Most of all, hang on to your curiosity and enthusiasm. Those were vital to the creation of the Rubinius project in the beginning and have sustained us @@ -161,7 +161,7 @@

    The Creative

    (Apple's dashboard dictionary widget.)

    -

    Ruby respects creativity. It has an aesthetic. You don’t just write Ruby +

    Ruby respects creativity. It has an aesthetic. You don’t just write Ruby code, you write beautiful Ruby code. It would be unthinkable to do otherwise. Sure, there is more than one way to do many things. This is not some sterile laboratory. We are not automatons; we are people. Of course, @@ -169,7 +169,7 @@

    The Creative

    well covered. There is probably only one right way to implement Python.

    Rubinius has an aesthetic, too: excellence, utility, simplicity, beauty, joy. -Mostly in that order. Useful code that isn’t of very good quality is a drag. +Mostly in that order. Useful code that isn’t of very good quality is a drag. It slows you down. It gives you a headache. It drives you away. We strive to keep it out of Rubinius. On the other hand, we are not just writing sonnets here. This is Serious Business™. We have some hard-core problems to solve. So @@ -181,13 +181,13 @@

    The Creative

    language more beautiful and object-oriented.

    We welcome your artistic perspective. Help us improve the dialog between -Rubinius and the person using it. The command line doesn’t have to be a +Rubinius and the person using it. The command line doesn’t have to be a desolate place of obscure, condescending error messages. Web interfaces to the diagnostic tools deserve a good dose of user-experience and interaction design. You know that feeling you get when looking at an Enterprise web application? That weird plastic-masquerading-as-quality-material feeling? The too much 1996-Enterprise-faux-rounded-corner-wanabe-2006-hip gloss? -Gives me the willies whenever I have to use an app like that. Yeah, we don’t +Gives me the willies whenever I have to use an app like that. Yeah, we don’t want that.

    We want to create tools that are powerful, graceful, easy to use, and @@ -241,16 +241,16 @@

    Experienced programmerIf everything goes well with the tests, you start running some of the benchmarks that you have accumulated while doing performance tuning. Of -course, no sensible person asks for benchmark results from other people’s -code. That defies logic. It’s like asking if your program will run because -your Aunt Mabeline likes decaf coffee. It’s contrary to the very point of +course, no sensible person asks for benchmark results from other people’s +code. That defies logic. It’s like asking if your program will run because +your Aunt Mabeline likes decaf coffee. It’s contrary to the very point of benchmarking, where you are trying to correlate two values that are connected.

    Again, if you note an significant issues, please let us know. Sometimes Rubinius exposes issues in existing code. Performance characteristics of real applications are vital to making Rubinius faster. Also, if you have suggestions for tools you would like to use, tell us. If you just want to -chat about the technology, that’s fine, too. We’re hanging out in the +chat about the technology, that’s fine, too. We’re hanging out in the #rubinius channel on freenode.net.

    Back to personas

    @@ -258,13 +258,13 @@

    Experienced programmerSeasoned programmer

    Well, I am being kind by saying seasoned. You know when you look in the -mirror that jaded and cynical are much more apt. You’ve seen it all and it -has worn you down. You’ve been fighting the good fight, carefully guarding +mirror that jaded and cynical are much more apt. You’ve seen it all and it +has worn you down. You’ve been fighting the good fight, carefully guarding that last flicker of optimism that burns in the secret place deep in your -heart. You’ve programmed Java/.NET/C++ professionally. You’ve even sucked it +heart. You’ve programmed Java/.NET/C++ professionally. You’ve even sucked it up and written some PHP and Python when asked; you are a professional, they -ask and you deliver. You’ve seen attacked servers on fire off the shoulder of -Rackspace…

    +ask and you deliver. You’ve seen attacked servers on fire off the shoulder of +Rackspace…

    Rubinius has a lot to offer you. Remember that little flicker of optimism? It is only the idealists that get ground down by the complete indifference to @@ -274,7 +274,7 @@

    Seasoned programmer

    Rubinius aims to be the best possible implementation of Ruby by putting Ruby itself front and center. We are using modern technology and always improving. We change when there is a better way to do things. We judiciously rewrite and -are not too attached to any code or algorithm. The legacy Enterprise isn’t on +are not too attached to any code or algorithm. The legacy Enterprise isn’t on the steering committee. Our work will be done when you can use Ruby, just Ruby, to solve your thorny problems.

    @@ -288,14 +288,14 @@

    Seasoned programmer

    Academic Researcher

    -

    Forgive me for staring, I know it is impolite. I’m just… intrigued. Of +

    Forgive me for staring, I know it is impolite. I’m just… intrigued. Of course, you know Ruby is a late bound language, every message sent could conceivably fail to find a target, potentially resulting in an uncaught -exception and program termination. There’s shared state, wild orgies of +exception and program termination. There’s shared state, wild orgies of mutation that disallow any reasonable attempt at automated parallelization. -Program proof is as oxymoronic a concept as military intelligence. It’s a very +Program proof is as oxymoronic a concept as military intelligence. It’s a very messy affair of programming and meta-programming and meta-meta-programming, -which, for the love of Lisp, could be done so simply with macros. There’s all +which, for the love of Lisp, could be done so simply with macros. There’s all this eager evaluation and complete disregard for purity. Despite vast odds, somehow programs are written that actually run. You have noted all this with great objectivity but you are nonetheless interested.

    @@ -336,19 +336,19 @@

    Academic Researcher

    Über programmer

    -

    You learned the untyped lambda calculus sitting on your mother’s knee while +

    You learned the untyped lambda calculus sitting on your mother’s knee while she worked on her doctorate in computer science. You were substituting terms -before you even uttered the word, “dada”. You wrote three different Lisp +before you even uttered the word, “dada”. You wrote three different Lisp implementations in Commodore Basic before you were seven. You can write multi-threaded web servers in one pass with no tests and never hit a deadlock or critical data race. You write parsers and compilers for odd languages on a Friday night for the heck of it while waiting for the pizza to arrive before a night out at the karaoke bar where you give an inspiring performance of Laga -Gaga’s Poker Face.

    +Gaga’s Poker Face.

    -

    (Loooong pause. You’re not reading this. You’ve already written one or a few +

    (Loooong pause. You’re not reading this. You’ve already written one or a few languages on Rubinius and posted them to our -Projects page. But anyway, I’ll continue…)

    +Projects page. But anyway, I’ll continue…)

    You are the Luke Skywalker of Ruby; Yoda has nothing more to teach you. Only your fate confronts you now. Use the Source Luke and save the Federation of @@ -363,7 +363,7 @@

    Über programmer

    of hybrid client-server architectures will continue to be the norm. We need software that enables application authors to build a suitable solution to their particular problems rather than trying to stuff their apps into -someone else’s solution with layers of wrapping. +someone else’s solution with layers of wrapping.
  • Concurrency: multi-core is here to stay but it is not only functional programming that is suitable for high-concurrency applications.
  • Graphical user interface: the web browser is also here to stay but it is @@ -400,7 +400,7 @@

    Philosophy Student Seeking

    Like your persona description, you tend to be long winded. You find most descriptions too brief, almost dismissive. There are words and words should be used to delve into the minutiae of minutiae. You, more than anyone, want to -know “Why?” with every fiber of your being. You will continue asking long +know “Why?” with every fiber of your being. You will continue asking long after the supply of hallucinogens has been exhausted and everyone else is drooling in their sleep.

    @@ -411,21 +411,21 @@

    Philosophy Student Seeking simply this: Ruby should be a first class language. What does that mean? Simply that it should be possible to solve problems writing Ruby code.

    -

    Let’s consider libraries: Being first class means not having to wrap a Java +

    Let’s consider libraries: Being first class means not having to wrap a Java library or build a C extension. If wrapping the library were the end of the -story, it wouldn’t be so bad. But that is never the case. Libraries have +story, it wouldn’t be so bad. But that is never the case. Libraries have bugs, weird APIs, incompatibility with other libraries, threading issues, and disappearing maintainers. They may even be incompatible with newer versions of the language in which they are written.

    This list goes on. To address any one of these issues requires delving into a different language with weird and incompatible semantics. If the library is -your core competency, that’s not such a big deal. But I will wager that it is +your core competency, that’s not such a big deal. But I will wager that it is not, which is why you are using the library in the first place. Also, the language in which you are wrapping the library (Ruby here) is not likely the -core competency of the library author, or you probably wouldn’t need to be +core competency of the library author, or you probably wouldn’t need to be wrapping it. So Ruby wrapping one of these libraries will always be a -second-class citizen. Decisions will be made about the library’s API that do +second-class citizen. Decisions will be made about the library’s API that do not give one thought to the Ruby programs using it. Furthermore, the code written in that foreign language does nothing to support the ecosystem of Ruby. The knowledge gained in writing the library and the improved skills of @@ -440,14 +440,14 @@

    Philosophy Student Seeking

    The philosophy of Rubinius is to make Ruby a first-class citizen. Ruby plays second fiddle to no one. There is no other language whose history, semantics, -or vested interests compete with Ruby’s. It is true that there are difficult +or vested interests compete with Ruby’s. It is true that there are difficult problems to solve in making Ruby fast. But much of the technology already exists and we will build what does not. Evan often quips that if we can get Rubinius caught up to the dynamic language technology of ten years ago, Ruby will be light-years ahead. That may be overstating how far behind Ruby is, but it illustrates the focus of Rubinius.

    -

    There’s the saying, In theory, there is no difference between theory and +

    There’s the saying, In theory, there is no difference between theory and practice. In practice, there is. In Rubinius, theory and practice are merging. We are motivated by the desire for Ruby to be a first-class language. But we are also showing real progress in making that a reality. The Rubinius @@ -464,7 +464,7 @@

    Manager

    No, it did not cross my mind to describe this persona as Pointy-haired Boss. Not only would that be unfair to Dilbert, but that persona would be reading an article on Web Scale. No, you are someone who has fought hard battles in the -trenches and learned valuable lessons: it’s about execution and execution +trenches and learned valuable lessons: it’s about execution and execution depends on good technology.

    Rubinius is building solid technology. We started the RubySpec project and @@ -472,7 +472,7 @@

    Manager

    Rubyspec, in just over four years as a public project, we have basically caught up with MRI 1.8.7 in compatibility and performance. For some code, our performance is much better, for other code, it is not as good. However, -Rubinius is built on solid, modern technology and the project’s trajectory and +Rubinius is built on solid, modern technology and the project’s trajectory and velocity are outstanding.

    Rubinius is a completely new implementation of core Ruby. Rubinius did not @@ -495,19 +495,19 @@

    Manager

    Knowledge Seeker

    -

    You thirst for Knowledge. You follow it wherever it leads you. You’ll happily -walk Haskell’s hallowed halls of pure laziness or sit at the feet of the -meta-program gazing raptly at class transmorgrification. You don’t judge. You +

    You thirst for Knowledge. You follow it wherever it leads you. You’ll happily +walk Haskell’s hallowed halls of pure laziness or sit at the feet of the +meta-program gazing raptly at class transmorgrification. You don’t judge. You have more than enough knowledge to be dangerous, enough to know that the universe is amoral and knowledge is the only Truth there is. Nor does any mere -mortal language bind you. All languages are finite. You’ll be here today and +mortal language bind you. All languages are finite. You’ll be here today and gone tomorrow; there is no permanence for the knowledge seeker.

    Rubinius is merely a step along the path you journey. Take what you want, it is all free. As a Ruby implementation, it has much to offer your quest for knowledge. The Ruby code in the core library is accessible and easy to follow. The interface between Ruby and the C++ primitives is consistent. The C++ code -itself is restrained. You won’t need a PhD in Turing-complete template +itself is restrained. You won’t need a PhD in Turing-complete template languages to understand it.

    Rubinius offers extensive opportunities to learn about programming languages @@ -523,12 +523,12 @@

    Knowledge Seeker

    lambdas, etc. Even with fundamental programming knowledge, a particular language can be confusing. When I was learning C, a friend was also studying it. One day he walked over and threw The C Programming Language -book down on my desk and said, “This for loop makes no sense!” He was -quite upset. “Look,” he said, “in this example for (i=0; i < n; i++) how -can i < n get executed after the code in the body?!” It’s easy to laugh +book down on my desk and said, “This for loop makes no sense!” He was +quite upset. “Look,” he said, “in this example for (i=0; i < n; i++) how +can i < n get executed after the code in the body?!” It’s easy to laugh at that confusion, but coming from BASIC, that really threw him. Deepening our understanding to this second level requires confronting some -“counter-intuitive” notions.

  • +“counter-intuitive” notions.
  • Hypothetical implementation: knowing how Ruby works, how might one implement it. I think this is an important layer of understanding and it is easy to miss or gloss over it. By pausing at this layer and thinking how @@ -543,7 +543,7 @@

    Knowledge Seeker

    of Ruby itself.
  • -

    While the Rubinius code itself offers many opportunities for learning, don’t +

    While the Rubinius code itself offers many opportunities for learning, don’t hesitate to drop by the #rubinius channel on freenode.net and ask us questions. Perhaps you already know a lot about another language and are interested in how Rubinius implements some feature. Or you may be relatively @@ -565,8 +565,8 @@

    Knowledge Seeker

    Language Enthusiast

    You like languages for their intrinsic value. Of course the world comes in -many shapes and sizes. You wouldn’t have it any other way. That’s the fun and -spice, joie de vivre, raison d’etre, supermarché… Sometimes you get carried +many shapes and sizes. You wouldn’t have it any other way. That’s the fun and +spice, joie de vivre, raison d’etre, supermarché… Sometimes you get carried away writing a program in another language just because you like how the letters arrange down the screen. Ruby is definitely one of the impressive languages and sometimes you almost notice a tiny bit of favoritism in your @@ -579,7 +579,7 @@

    Language Enthusiast

    way will tell you whether or not Rubinius has value to you.

    If you are most interested in languages themselves, the syntax and arrangement -of features, Rubinius offers you immediate gratification. Look for Evan’s +of features, Rubinius offers you immediate gratification. Look for Evan’s upcoming post on his Language Toolkit or check out the code to prattle, a Smalltalk dialect used to illustrate the ease of building a language on Rubinius. Also look at some of @@ -601,18 +601,18 @@

    Language Enthusiast

    Most of all, experiment. Rubinius is easy to hack on. Are you curious about a particular feature needed in your language? Try adding it to Rubinius. Think Lua is all the rage because it uses a register VM? You could probably write a -register-based bytecode interpreter for Rubinius in an afternoon. That’s just +register-based bytecode interpreter for Rubinius in an afternoon. That’s just an example, of course. The point is to play around with your ideas and have -fun doing it. I think you’ll find Rubinius to be an adventuresome companion.

    +fun doing it. I think you’ll find Rubinius to be an adventuresome companion.

    -

    Be sure to let us know what you’re working on. We like to be inspired, too! +

    Be sure to let us know what you’re working on. We like to be inspired, too! Consider writing a blog post about things that you find interesing, like this recent post by Yehuda Katz.

    @@ -625,8 +625,8 @@

    Conclusion

    everyone. We believe, however, that Rubinius has something to offer to just about everyone interested in Ruby. Most importantly, try it!

    -

    If we didn’t answer your question here, leave us a comment. If you have a -reason for using Rubinius that we didn’t mention, let us know. As always, we +

    If we didn’t answer your question here, leave us a comment. If you have a +reason for using Rubinius that we didn’t mention, let us know. As always, we appreciate your feedback. Chat with us in the #rubinius channel on freenode.net, watch our Github project, and follow us on Twitter.

    diff --git a/web/_site/2011/03/11/making-rubinius-rbc-files-disappear/index.html b/web/_site/2011/03/11/making-rubinius-rbc-files-disappear/index.html index eb7b0e4fa4..412e01f379 100644 --- a/web/_site/2011/03/11/making-rubinius-rbc-files-disappear/index.html +++ b/web/_site/2011/03/11/making-rubinius-rbc-files-disappear/index.html @@ -92,7 +92,7 @@

    Making Rubinius .rbc Files Disappear

    hello.rb hello.rbc -

    That doesn’t look too crazy, but it can get more complicated:

    +

    That doesn’t look too crazy, but it can get more complicated:

    $ mv hello.rb hello
     $ rbx hello
    @@ -115,16 +115,16 @@ 

    Making Rubinius .rbc Files Disappear

    Again, the advantage of the cache file is that you do not have to wait for -Rubinius to recompile the file if you have not changed the source. Let’s see +Rubinius to recompile the file if you have not changed the source. Let’s see if we can get all the advantages with none of the disadvantages. That old saying comes to mind, Having your cake and eating it, too, so we may not be successful, but it is worth a shot.

    -

    First, let’s take a step back. This issue is not unique to Rubinius. Python +

    First, let’s take a step back. This issue is not unique to Rubinius. Python has .pyc and .pyo files. Java has .class files. C/C++ has .o files. Lots of things need a place to store a compiled or cached representation of some data. Every SCM worth mention has some mechanism to ignore the files you -don’t want to track. The same is generally true of editors. So in some sense, +don’t want to track. The same is generally true of editors. So in some sense, this is a solved problem. However, we have always received complaints about the .rbc files, so we thought we would try to make other, hopefully better, solutions available.

    @@ -142,7 +142,7 @@

    Solution 1: No Cache

    hello.rb
    -

    Win! Not one lousy .rbc file in sight. Although, that’s quite the option to +

    Win! Not one lousy .rbc file in sight. Although, that’s quite the option to type. Never fear, we have a solution to that below.

    Here is our scorecard for solution 1:

    @@ -162,7 +162,7 @@

    Solution 2: Cache Database

    What if we could put all the compilation data in a single cache location, something like a database? We have an option for that.

    -

    This option is a little more complex, so let’s take it in two steps.

    +

    This option is a little more complex, so let’s take it in two steps.

    $ ls hello.*
     hello.rb
    @@ -177,7 +177,7 @@ 

    Solution 2: Cache Database

    60c091c3ed34c1b93ffbb33d82d810772902d3f9
    -

    Success! No .rbc files here. But what’s with all the numbers in the .rbx +

    Success! No .rbc files here. But what’s with all the numbers in the .rbx directory and how did that directory get there?

    The -Xrbc.db option without any argument will store the compilation cache in @@ -231,7 +231,7 @@

    Solution 2: Cache Database

    Using RBXOPT for Options

    As mentioned above, the -X options can get a little long and you certainly -don’t want to retype them constantly. We have added support for the RBXOPT +don’t want to retype them constantly. We have added support for the RBXOPT environment variable, which is an analog of the RUBYOPT environment variable that we already support.

    @@ -254,17 +254,17 @@

    Conclusion

    some place to store the cache. Rubinius provides options for omitting the cache altogether or for storing it in a directory of your choosing. Note that the format of the compilation cache is an implementation detail and we reserve -the right to change it at any time, so please don’t rely on it being in any +the right to change it at any time, so please don’t rely on it being in any particular format.

    -

    We have not turned on -Xrbc.db by default yet because we don’t know what a +

    We have not turned on -Xrbc.db by default yet because we don’t know what a good default is. So give us feedback on your use cases and what you would find most useful.

    Finally, whenever we discuss the compilation cache we are inevitably asked if you can run directly from the cache and not use the Ruby source at all after -it has been compiled. The short answer is “Yes”, the long answer is “It -depends”. I will be writing a post exploring this question in detail shortly. +it has been compiled. The short answer is “Yes”, the long answer is “It +depends”. I will be writing a post exploring this question in detail shortly. For now, get out there and write more Ruby code!

    diff --git a/web/_site/2011/03/17/running-ruby-with-no-ruby/index.html b/web/_site/2011/03/17/running-ruby-with-no-ruby/index.html index 8b63f15c62..709ca4ba3c 100644 --- a/web/_site/2011/03/17/running-ruby-with-no-ruby/index.html +++ b/web/_site/2011/03/17/running-ruby-with-no-ruby/index.html @@ -71,7 +71,7 @@

    Running Ruby With No Ruby

    -

    Humans have come a long way since our cave-dwelling days. No, that’s not a +

    Humans have come a long way since our cave-dwelling days. No, that’s not a metaphor for primitive software. I mean literally since we lived in caves. One of the big inventions is the lock. There are birds that bury food and will move it later if they notice they were watched burying it. But they have no @@ -104,7 +104,7 @@

    Running Ruby With No Ruby

    The process that separates the source code from the executable program is typically a compilation step. However, Ruby code is not typically associated -with any sort of compilation. That’s one of the great things about Ruby, +with any sort of compilation. That’s one of the great things about Ruby, right? There is no edit-compile-link-load cycle to wait on. Just edit and run. But if there is no compilation step, how do we separate the source code from the executable code?

    @@ -115,13 +115,13 @@

    Running Ruby With No Ruby

    executes. I also promised to explain how you could run the bytecode directly.

    But first, let me very clearly state that there are a number of caveats. In -fact, I’ve included a whole section on them below. Please read them. We will +fact, I’ve included a whole section on them below. Please read them. We will assume that you have and that you understand them. If you have any questions, please ask.

    Application Distribution Scenario

    -

    Let’s review what we would like to accomplish. We’ll assume affable Abe is a +

    Let’s review what we would like to accomplish. We’ll assume affable Abe is a developer writing an application for customer Cain.

      @@ -133,13 +133,13 @@

      Application Distribution Scenario

      Cain runs the application.
    -

    In this scenario, I’m assuming a very vague definition of application. In +

    In this scenario, I’m assuming a very vague definition of application. In other words, the process below will fit in with a broad spectrum of bundling and distribution schemes.

    Application Layout

    -

    Let’s assume that you have the following application layout. This mirrors what +

    Let’s assume that you have the following application layout. This mirrors what you would expect to see in a gem. You could also consider this as a subtree in your larger project.

    @@ -152,13 +152,27 @@

    Application Layout

    \- green.rb -

    Liquid error: undefined method `join’ for #

    +
    1 # widget.rb
    +2 require 'widget/red'
    +3 require 'widget/blue'
    +4 require 'widget/green'
    +
    +
    -

    Liquid error: undefined method `join’ for “\n# widget/red.rb\nputs "I am red"\n”:String

    +
    1 # widget/red.rb
    +2 puts "I am red"
    +
    +
    -

    Liquid error: undefined method `join’ for “\n# widget/blue.rb\nputs "I am blue"\n”:String

    +
    1 # widget/blue.rb
    +2 puts "I am blue"
    +
    +
    -

    Liquid error: undefined method `join’ for “\n# widget/green.rb\nputs "I am green"\n”:String

    +
    1 # widget/green.rb
    +2 puts "I am green"
    +
    +

    Compiling Ruby Files

    @@ -170,7 +184,7 @@

    Compiling Ruby Files

    rbx compile -s '^widget:widget-compiled' widget/
     
    -

    Let’s dissect this command. The -s option defines a transformation to apply +

    Let’s dissect this command. The -s option defines a transformation to apply to every filename. The transformation has the form <source>:<destination> where <source> can be a Regexp. In our case, we would like to change any path starting with widget to start with widget-compiled. This way, we @@ -194,7 +208,7 @@

    Compiling Ruby Files

    Loading Pre-compiled Files

    Now that we have a separate tree of only compiled files, how do we load them? -Well, first, let’s load our source files so we know what to expect. Note that +Well, first, let’s load our source files so we know what to expect. Note that the technique used in this post should not substitute for a robust test suite.

    $ rbx -Iwidget/lib -e "require 'widget/lib/widget'"
    @@ -213,9 +227,9 @@ 

    Loading Pre-compiled Files

    The crowed erupts with applause and hooting.

    -

    Golly gee, you guys… Blush

    +

    Golly gee, you guys… Blush

    -

    Let’s review. Our goal is to take a tree of Ruby source files and create a +

    Let’s review. Our goal is to take a tree of Ruby source files and create a tree of compiled files that can be sent to a customer and loaded to perform exactly as the Ruby source would if loaded directly. The most direct and simple way to accomplish this is to use the Rubinius compiler command-line @@ -240,7 +254,7 @@

    Caveats

  • We have created this facility to meet a need we had in Rubinius. Since our compiler is written in Ruby, we have to run Ruby to run the compiler. But since we need to compile Ruby to run it, we need to compile the compiler. -But since… To handle this, we build the compiler using a bootstrapping +But since… To handle this, we build the compiler using a bootstrapping version of Ruby. Then we load the pre-compiled compiler files as shown above. The approach is quite general, as demonstrated. However, a better approach may be appropriate for a particular application. In that case, @@ -254,7 +268,7 @@

    Caveats

    disassemblers for our compiled code. We are happy to assist you with direction for implementing a more secure system for your needs.
  • There is no mechanism that is completely safe from cracking when it comes -to software access control. Witness how often Microsoft’s products have +to software access control. Witness how often Microsoft’s products have their security features defeated. Also witness how often attempts at DRM are circumvented. The most secure system I have seen uses a special compiler and a hardware dongle. The compiler takes critical parts of the diff --git a/web/_site/2011/04/29/rubinius-t-shirts-and-stickers/index.html b/web/_site/2011/04/29/rubinius-t-shirts-and-stickers/index.html index 3bbcf57f25..06c085b35a 100644 --- a/web/_site/2011/04/29/rubinius-t-shirts-and-stickers/index.html +++ b/web/_site/2011/04/29/rubinius-t-shirts-and-stickers/index.html @@ -73,15 +73,15 @@

    Rubinius T-Shirts and Stickers

    Allow Myself to Introduce Myself

    -

    Hi. I’m Shane (@veganstraightedge -/ iamshane.com). I’ll be helping out around here now. +

    Hi. I’m Shane (@veganstraightedge +/ iamshane.com). I’ll be helping out around here now. I was recently hired by Engine Yard to be their Open Source Cheerleader. (Yes, there will be costumes at some point.) My primary focus is Rubinius! Rubinius! Rubinius!

    I have lots of big plans for helping get Rubinius used by more people in more places and how to have a better conversation with people who are using -it. For now though, I tell you about just the first thing that I’ve done.

    +it. For now though, I tell you about just the first thing that I’ve done.

    T-Shirts

    @@ -91,12 +91,12 @@

    The First Ever Rubi

    A long time ago (2007) in a city far, far away (Seattle, WA), Evan and I made the first batch of Rubinius t-shirts. There were about two dozen made and given to the handful of contributors at the time. This was at RailsConf in -Portland, OR. Since then there hasn’t been anything made with the Rubinius +Portland, OR. Since then there hasn’t been anything made with the Rubinius logo on it.

    -

    Now is the time to rectify that. We’ve made two different t-shirts. Same +

    Now is the time to rectify that. We’ve made two different t-shirts. Same messaging, slightly different design orientation. Both are the same colors: -white on asphalt. They are available in an assortment of sizes from women’s +white on asphalt. They are available in an assortment of sizes from women’s small to unisex xx-large.

    Use Ruby™ Rubinius T-Shirts from RailsConf 2011

    @@ -104,16 +104,16 @@

    Use Ruby™ Rubinius T-S

    Use Ruby™ Horizontal Ruby T-Shirt from RailsConf 2011

    -

    If you’re going to RailsConf 2011 in Baltimore, MD, stop by the Engine Yard booth -to pick up a free Rubinius t-shirt. After RailsConf we’ll have ways to get one +

    If you’re going to RailsConf 2011 in Baltimore, MD, stop by the Engine Yard booth +to pick up a free Rubinius t-shirt. After RailsConf we’ll have ways to get one from us directly.

    Stickers

    -

    To go along with the t-shirts, we’re making a whole grip of Rubinius stickers. +

    To go along with the t-shirts, we’re making a whole grip of Rubinius stickers. Most of which will also be available for free from the Engine Yard booth at -RailsConf in Baltimore. Again, after RailsConf you’ll be able to get them -directly from us. More on that later. Here’s what we have in store.

    +RailsConf in Baltimore. Again, after RailsConf you’ll be able to get them +directly from us. More on that later. Here’s what we have in store.

    Wide Screen (7in x 3.75in)

    @@ -127,14 +127,14 @@

    Rubinius : r logo diecut sticker

    -

    I’m Committed Merit Sticker

    +

    I’m Committed Merit Sticker

    -

    This one you have to earn. At the end of each quarter, we’ll send out a little +

    This one you have to earn. At the end of each quarter, we’ll send out a little one inch square sticker with a year/quarter combination in its corner to everyone who committed something to Rubinius during that calendar quarter. For -all of the incredible folks who’ve contributed something (however big or small) -already, you’ll get a special sticker. Instead of a date, there’s an asterisk. -Only those of you that’ve committed so far will get that one.

    +all of the incredible folks who’ve contributed something (however big or small) +already, you’ll get a special sticker. Instead of a date, there’s an asterisk. +Only those of you that’ve committed so far will get that one.

    Rubinius : I'm committed past committers sticker

    @@ -142,7 +142,7 @@

    I’m Committed Merit Sticker

    the Rubinius blog and to the Twitter account : @rubinius. We have lots more in store.

    -

    — Use Ruby™

    +

    — Use Ruby™

    diff --git a/web/_site/2011/05/22/adam-prescott-on-scopes/index.html b/web/_site/2011/05/22/adam-prescott-on-scopes/index.html index f605744f3a..bc4af8b1eb 100644 --- a/web/_site/2011/05/22/adam-prescott-on-scopes/index.html +++ b/web/_site/2011/05/22/adam-prescott-on-scopes/index.html @@ -77,14 +77,14 @@

    Adam Prescott on Scopes in Rubinius

    One of the really cool things about the Rubinius implementation of Ruby is that it exposes, by requirement, a level of internals which you can’t find in MRI, including some internals with scopes. Because these internals are exposed in Ruby itself, you can play around with scopes as objects, using VariableScope, including getting access to the available local variables within that scope, with VariableScope.current.locals.

    -

    How are you using Rubinius? What are you doing with it that you couldn’t do before? What is it missing for you to really dive in? Let us know. We’re listening.

    +

    How are you using Rubinius? What are you doing with it that you couldn’t do before? What is it missing for you to really dive in? Let us know. We’re listening.

    -

    — Use Ruby™

    +

    — Use Ruby™

    diff --git a/web/_site/2011/05/26/rubinius-rewards/index.html b/web/_site/2011/05/26/rubinius-rewards/index.html index 6458c7c54d..c261b7600f 100644 --- a/web/_site/2011/05/26/rubinius-rewards/index.html +++ b/web/_site/2011/05/26/rubinius-rewards/index.html @@ -73,7 +73,7 @@

    Announcing Rubinius Rewards

    Update

    -

    See this post about retired shirts/stickers and to see what’s still available.

    +

    See this post about retired shirts/stickers and to see what’s still available.

    tl;dr

    @@ -89,14 +89,14 @@

    We Made T-Shirts and Stickers

    swag.

    Not everyone could be at RailsConf to get the goods, of course. Even some -people who were there didn’t get their shirts/stickers. If you didn’t get one -and want one, we’re very sorry, but don’t you worry. We’ve got you covered.

    +people who were there didn’t get their shirts/stickers. If you didn’t get one +and want one, we’re very sorry, but don’t you worry. We’ve got you covered.

    General Availability Stickers

    A box of Rubinius stickers

    -

    We’ve got a box of stickers in three designs: +

    We’ve got a box of stickers in three designs: square, bumper and @@ -106,8 +106,8 @@

    General Availability Stickers

    General Availability T-Shirt

    -

    We’re printing 500 more grey Rubinius t-shirts in the two different designs -and in a a handful of sizes (women’s small and medium, unisex small – +

    We’re printing 500 more grey Rubinius t-shirts in the two different designs +and in a a handful of sizes (women’s small and medium, unisex small – xx-large).

    Email us and tell us which design / size you want: @@ -115,7 +115,7 @@

    General Availability T-Shirt

    or horizontal in -women’s small, women’s medium, unisex small, unisex medium, unisex large, +women’s small, women’s medium, unisex small, unisex medium, unisex large, unisex x-large or unisex xx-large.

    Rubinius "Use Ruby™" T-Shirts at the Farmhouse in Hollywood, CA

    @@ -126,49 +126,49 @@

    General Availability T-Shirt

    First Commit Sticker

    Going forward, we want to reward everyone who makes a contribution to -Rubinius. As a very small token of our gratitude, we’re mailing a Rubinius +Rubinius. As a very small token of our gratitude, we’re mailing a Rubinius sticker (and a handwritten thank you note from one of us) to everyone after -their first commit. So, if you’ve ever thought about dipping your toe into -Rubinius (or diving headlong into the deep end), now’s the best time ever. -Help us make Rubinius better (in big and small ways) and we’ll send you stuff.

    +their first commit. So, if you’ve ever thought about dipping your toe into +Rubinius (or diving headlong into the deep end), now’s the best time ever. +Help us make Rubinius better (in big and small ways) and we’ll send you stuff.

    Tenth Commit Shirt

    We want you to stick around and keep helping Rubinius to get better and better. -If you make 10 commits to Rubinius, we’ll send you a special shirt only -available to committers. That design is still a secret for now, but it’s just +If you make 10 commits to Rubinius, we’ll send you a special shirt only +available to committers. That design is still a secret for now, but it’s just for 10+ committers.

    -

    Please, don’t try to game the system by intentionally breaking stuff up into -smaller commits just to bump up your count. Let’s keep it honest.

    +

    Please, don’t try to game the system by intentionally breaking stuff up into +smaller commits just to bump up your count. Let’s keep it honest.

    Quarterly Committer Merit Badge Stickers

    In addition to getting a generally available sticker after your first commit, -at the end of each calendar quarter (every three months) we’re sending a +at the end of each calendar quarter (every three months) we’re sending a sticker to everyone who committed to Rubinius during that quarter.

    -

    E.g. after July 1, 2011, we’ll print and ship a sticker to everyone who -committed between April 1 and June 30. Each quarter’s sticker has the year / -quarter in the corner. Keep committing every quarter and you’ll keep +

    E.g. after July 1, 2011, we’ll print and ship a sticker to everyone who +committed between April 1 and June 30. Each quarter’s sticker has the year / +quarter in the corner. Keep committing every quarter and you’ll keep collecting the merit badge stickers.

    -

    One More Thing — I’m Committed* Sticker

    +

    One More Thing — I’m Committed* Sticker

    Rubinius is obviously older than the new Rubinius Rewards program. To backfill for all the contributions people have made over the years up until, we have a -super duper limited edition never to be made again sticker… the asterisk.

    +super duper limited edition never to be made again sticker… the asterisk.

    Rubinius stickers on my laptop

    Get in Touch

    -

    If you’re a past committer, email us your -mailing address get your special merit sticker. If you’re a new committer, -we’ll try to take note and reach out to you. If you don’t hear from us, -don’t be afraid to contact us with your mailing address.

    +

    If you’re a past committer, email us your +mailing address get your special merit sticker. If you’re a new committer, +we’ll try to take note and reach out to you. If you don’t hear from us, +don’t be afraid to contact us with your mailing address.

    -

    Up Next…

    +

    Up Next…

    Rubinius International Outposts.

    diff --git a/web/_site/2011/06/07/inside-rubinius-20-preview/index.html b/web/_site/2011/06/07/inside-rubinius-20-preview/index.html index 2f19f34090..d356725c8e 100644 --- a/web/_site/2011/06/07/inside-rubinius-20-preview/index.html +++ b/web/_site/2011/06/07/inside-rubinius-20-preview/index.html @@ -91,7 +91,7 @@

    Rubinius 2.0 Developer Preview

    We are seeking developers interested in running their Ruby and Rails projects on Rubinius to help us iron out issues as we work toward the final 2.0 -release. Let’s look at the details of the 2.0 developer preview.

    +release. Let’s look at the details of the 2.0 developer preview.

    One of the central features of Rubinius 2.0 is a fundamental change in the threading architecture. In Rubinius 2.0, Ruby threads will run with true @@ -130,7 +130,7 @@

    Installation

    If you are interested in helping develop Rubinius, we suggest you clone the repository directly and build. Rubinius runs fine from the source directory so -you don’t need to install it. For more details about building from a clone, +you don’t need to install it. For more details about building from a clone, see Getting Started.

    Configuration

    @@ -187,7 +187,7 @@

    Building on Windows

    Windows support but the Rubinius VM is currently compiling on Windows 7.

    If you are a bleeding-edge Windows developer interested in diving into -Rubinius, here’s how to get started:

    +Rubinius, here’s how to get started:

    1. Install MRI 1.9 using RubyInstaller.
    2. @@ -202,7 +202,7 @@

      Moving Forward

      In the near future, we will release another version of Rubinius from the current master branch. We hope to merge 2.0.0pre into master as soon as -possible and continue working toward the 2.0 final release. We’ll make that +possible and continue working toward the 2.0 final release. We’ll make that decision based on your reports about how the 2.0.0pre branch is working with existing 1.8.7 applications.

      diff --git a/web/_site/2011/07/01/rubinius-summit-in-pictures/index.html b/web/_site/2011/07/01/rubinius-summit-in-pictures/index.html index 17df566a8c..316956ef1d 100644 --- a/web/_site/2011/07/01/rubinius-summit-in-pictures/index.html +++ b/web/_site/2011/07/01/rubinius-summit-in-pictures/index.html @@ -71,19 +71,19 @@

      Rubinius Summit 062011 in Pictures

      -

      Once a month Evan Phoenix, Brian Ford and I (Shane Beccker) get together for a few days in-person face-time. Usually we meet up in San Francisco at the Engine Yard HQ and spend time with our dear and lovely boss, Dr Nic. We like to call these little get togethers Rubinius Summits. For the June 2011 Rubinius Summit, Brian came down to LA where both Evan and I live. We spent the week working together at The Farmhouse on moving the ball forward toward the 2.0 release. Here’s a few pictures of some of the things that went down.

      +

      Once a month Evan Phoenix, Brian Ford and I (Shane Beccker) get together for a few days in-person face-time. Usually we meet up in San Francisco at the Engine Yard HQ and spend time with our dear and lovely boss, Dr Nic. We like to call these little get togethers Rubinius Summits. For the June 2011 Rubinius Summit, Brian came down to LA where both Evan and I live. We spent the week working together at The Farmhouse on moving the ball forward toward the 2.0 release. Here’s a few pictures of some of the things that went down.

      I Used Rubinius at RailsConf 2011 stickers

      "I Used Rubinius at RailsConf 2011" stickers at The Farmhouse in Hollywood, CA

      -

      These stickers arrived and are ready to be shipped out. If you DMed your address to us on Twitter, we’ve got you. If you never contacted us, but used Rubinius while at RailsConf 2011 in Baltimore, email us at community@rubini.us to get your sticker.

      +

      These stickers arrived and are ready to be shipped out. If you DMed your address to us on Twitter, we’ve got you. If you never contacted us, but used Rubinius while at RailsConf 2011 in Baltimore, email us at community@rubini.us to get your sticker.

      T-Shirts!

      Nearly 600 more @Rubinius shirts just arrived at the @farmhouse in Hollywood, CA

      -

      This is what nearly 600 shirts looks like. We’ve got a huge back log of people all over the world who responded to our offer of free Rubinius t-shirts. Those will all get shipped out over the next week or so.

      +

      This is what nearly 600 shirts looks like. We’ve got a huge back log of people all over the world who responded to our offer of free Rubinius t-shirts. Those will all get shipped out over the next week or so.

      Progress on 1.9 Support

      Serious @rubinius big brain nerdery happening between @brixen and @evanphx at the @farmhouse in Hollywood, CA

      @@ -97,7 +97,7 @@

      Progress on 1.9 Support

      One More Thing

      -

      We came up with an idea this week for how to better communicate outwardly and be more transparent. We built it up real quick and are launching it …really soon. Here’s a little teaser.

      +

      We came up with an idea this week for how to better communicate outwardly and be more transparent. We built it up real quick and are launching it …really soon. Here’s a little teaser.

      Rubinius teaser 1 Rubinius teaser 2

      diff --git a/web/_site/2011/07/03/all-around-the-world/index.html b/web/_site/2011/07/03/all-around-the-world/index.html index 8e08af6359..0df09303c2 100644 --- a/web/_site/2011/07/03/all-around-the-world/index.html +++ b/web/_site/2011/07/03/all-around-the-world/index.html @@ -71,9 +71,9 @@

      Rubinius All Around the World

      -

      As a result of the Rubinius Rewards, people from all over the world have requested Rubinius stickers and t-shirts. That just warms our little hearts and humbles us everyday. Thank you so much. It means the world to us. Keep using Rubinius with passion and excitement. Keep spreading the good word to your friends and anyone who’ll listen and care. And keep telling us how Rubinius is working for you. However good or bad, we want to know.

      +

      As a result of the Rubinius Rewards, people from all over the world have requested Rubinius stickers and t-shirts. That just warms our little hearts and humbles us everyday. Thank you so much. It means the world to us. Keep using Rubinius with passion and excitement. Keep spreading the good word to your friends and anyone who’ll listen and care. And keep telling us how Rubinius is working for you. However good or bad, we want to know.

      -

      Here’s a map of all the places where we’ve sent stickers and/or t-shirts. You can also view it on +

      Here’s a map of all the places where we’ve sent stickers and/or t-shirts. You can also view it on a larger map. Wow.

      diff --git a/web/_site/2011/07/05/whats-the-status-kenneth/index.html b/web/_site/2011/07/05/whats-the-status-kenneth/index.html index 42c2348676..6ffd39d754 100644 --- a/web/_site/2011/07/05/whats-the-status-kenneth/index.html +++ b/web/_site/2011/07/05/whats-the-status-kenneth/index.html @@ -71,38 +71,38 @@

      What’s the Status, Kenneth?

      -

      I’m pretty sure it started like this.

      +

      I’m pretty sure it started like this.

      -

      “Hello, Evan dear.” — Evan’s Grandma Betty

      +

      “Hello, Evan dear.” — Evan’s Grandma Betty

      -

      “Grandma Betty!” — Evan

      +

      “Grandma Betty!” — Evan

      -

      “You know, I was thinking about your little Rubinius thingy while I was gardening today. How’s it doing?” — Evan’s Grandma Betty

      +

      “You know, I was thinking about your little Rubinius thingy while I was gardening today. How’s it doing?” — Evan’s Grandma Betty

      -

      “Oh, Grandma Betty, that’s so sweet of you to think of me and it. It’s coming along still, of course.” — Evan

      +

      “Oh, Grandma Betty, that’s so sweet of you to think of me and it. It’s coming along still, of course.” — Evan

      -

      “That’s good to hear. I was specifically wondering how the 1.9 support is looking.” — Evan’s Grandma Betty

      +

      “That’s good to hear. I was specifically wondering how the 1.9 support is looking.” — Evan’s Grandma Betty

      -

      “Grandma Betty! You do always love the Latest and Greatest™, don’t you? Well, let’s see. I’d say that 1.9 support comes down to 7 main areas: Encoding, String, Regex, Symbol, IO, Argument Processing, Windows Support. Each has varying degrees of progress.” — Evan

      +

      “Grandma Betty! You do always love the Latest and Greatest™, don’t you? Well, let’s see. I’d say that 1.9 support comes down to 7 main areas: Encoding, String, Regex, Symbol, IO, Argument Processing, Windows Support. Each has varying degrees of progress.” — Evan

      -

      “OK. I wish that there was some way for me to keep more up to date on these happenings without needing to calling you. When I call you, I want to hear about that wife and baby of yours.” — Evan’s Grandma Betty

      +

      “OK. I wish that there was some way for me to keep more up to date on these happenings without needing to calling you. When I call you, I want to hear about that wife and baby of yours.” — Evan’s Grandma Betty

      -

      “You got it, Grandma Betty. I’ll get my Top Nerds™ on the case.” — Evan

      +

      “You got it, Grandma Betty. I’ll get my Top Nerds™ on the case.” — Evan

      @@ -110,10 +110,10 @@

      What’s the Status, Kenneth?

      -

      “Alright, Grandma Betty. We made the Rubinius Status Board™ especially just for you. It’s status.rubini.us” — Evan

      +

      “Alright, Grandma Betty. We made the Rubinius Status Board™ especially just for you. It’s status.rubini.us” — Evan

      -

      That conversation may or may not be completely fictionalized. There is one thing that is most emphatically true: Rubinius has a Status Board™ now. If you are ever curious how progress is going on things, go check out status.rubini.us. Tell your friends.

      +

      That conversation may or may not be completely fictionalized. There is one thing that is most emphatically true: Rubinius has a Status Board™ now. If you are ever curious how progress is going on things, go check out status.rubini.us. Tell your friends.

      XOXO RBX.

      diff --git a/web/_site/2011/07/07/rbxday/index.html b/web/_site/2011/07/07/rbxday/index.html index 9357e96bb3..151dd503ee 100644 --- a/web/_site/2011/07/07/rbxday/index.html +++ b/web/_site/2011/07/07/rbxday/index.html @@ -71,25 +71,25 @@

      rbxday

      -

      We’re having a party and you’re invited!

      +

      We’re having a party and you’re invited!

      rbxday.rubini.us

      Friday, August 5, 2011 is #rbxday

      -

      The Rubinius 2.0 Preview Release is still cranking along. We’re feeling good about how things are going. As always, thank you everyone for all of your contributions. The list of authors on the 1.2.4 release is just fantastic.

      +

      The Rubinius 2.0 Preview Release is still cranking along. We’re feeling good about how things are going. As always, thank you everyone for all of your contributions. The list of authors on the 1.2.4 release is just fantastic.

      -

      Moving forward to the 2.0 official release, we need more feedback from you about your code running on Rubinius. Not just what doesn’t work and not just bugs (although both of those are important too), but how is your code performing, where are the bottlenecks, etc.

      +

      Moving forward to the 2.0 official release, we need more feedback from you about your code running on Rubinius. Not just what doesn’t work and not just bugs (although both of those are important too), but how is your code performing, where are the bottlenecks, etc.

      -

      This is what we’re going to do about that. Everyone… everyone all around the world that uses or cares about Rubinius and its progress, all of us on one day are going to run our code, collect performance data / bug reports and send them up to the Rubinius project.

      +

      This is what we’re going to do about that. Everyone… everyone all around the world that uses or cares about Rubinius and its progress, all of us on one day are going to run our code, collect performance data / bug reports and send them up to the Rubinius project.

      -

      #rbxday is a party! Take pictures of you and your buddies on the day of. If you’ve got a Rubinius t-shirt or sticker, get them in there. Tweet about it, now and on the day. Get excited. Tell your friends. Get them excited. Use the hashtag #rbxday in your tweets, blog posts and posts. We’ll repost them all on the #rbxday site.

      +

      #rbxday is a party! Take pictures of you and your buddies on the day of. If you’ve got a Rubinius t-shirt or sticker, get them in there. Tweet about it, now and on the day. Get excited. Tell your friends. Get them excited. Use the hashtag #rbxday in your tweets, blog posts and posts. We’ll repost them all on the #rbxday site.

      -

      Make sure you’re looking your best in your photos because we’ll be picking a winner for our favorite #rbxday glamourshot. Tweet them using the hashtag #rbxday and we’ll announce the winning photo Monday, August 8, 2011 on the Engine Yard Facebook page. We’ll have a nifty prize for the winner too, so make sure your pic is goofy, sultry, or otherwise impressive. Bonus points for creativity.

      +

      Make sure you’re looking your best in your photos because we’ll be picking a winner for our favorite #rbxday glamourshot. Tweet them using the hashtag #rbxday and we’ll announce the winning photo Monday, August 8, 2011 on the Engine Yard Facebook page. We’ll have a nifty prize for the winner too, so make sure your pic is goofy, sultry, or otherwise impressive. Bonus points for creativity.

      Get your party hats on!

      -

      —XOXO RBX

      +

      —XOXO RBX

      diff --git a/web/_site/2011/07/29/rbxday-at-outright/index.html b/web/_site/2011/07/29/rbxday-at-outright/index.html index 403a6f93df..3d2752bc10 100644 --- a/web/_site/2011/07/29/rbxday-at-outright/index.html +++ b/web/_site/2011/07/29/rbxday-at-outright/index.html @@ -74,21 +74,21 @@

      Outright Hacks #rbxday

      Hey Ruby bytecode fans! The first ever International Rubinius Day is next Friday, August 5th. Around the world people will be trying their code on Rubinius and generally having a fun time. Follow the activities on Twitter -under the #rbxday tag and use that to let folks know what you’re up to. Stay +under the #rbxday tag and use that to let folks know what you’re up to. Stay tuned to the rbxday website for details as the day unfolds.

      If you are located in, around, or within traveling distance of beautiful Mountain View, CA, the terrific folks at Outright.com are sponsoring a real live #rbxday event! Come hang out with a bunch of -hardcore Ruby nerds, including Brian Ford (that’s me) from the Rubinius team. +hardcore Ruby nerds, including Brian Ford (that’s me) from the Rubinius team. Plan to be inspired by all the great stuff people are working on. There will be mountains of top-shelf Rubinius schwag, as well as free beer and pizza. -(Just don’t get too trashed as there will also be lightning talks and an IR +(Just don’t get too trashed as there will also be lightning talks and an IR helicopter obstacle course.)

      The party will be from 1:00 pm to 8:00 pm on -Friday August 5th at Outright’s offices in downtown Mountain View. (They have +Friday August 5th at Outright’s offices in downtown Mountain View. (They have an application that does some seriously awesome stuff with small business accounting.) There are plenty of desks, monitors and whiteboards available, so bring your laptop and be ready to jam.

      diff --git a/web/_site/2011/07/31/rbxday-at-80beans/index.html b/web/_site/2011/07/31/rbxday-at-80beans/index.html index bca540380a..fa4f129756 100644 --- a/web/_site/2011/07/31/rbxday-at-80beans/index.html +++ b/web/_site/2011/07/31/rbxday-at-80beans/index.html @@ -71,23 +71,23 @@

      Come hack in Amsterdam for #rbxday

      -

      Not only in the US is #rbxday celebrated, but -we have also something in Amsterdam next Friday. It’s really becoming the +

      Not only in the US is #rbxday celebrated, but +we have also something in Amsterdam next Friday. It’s really becoming the International Rubinius Day that it was set out to be.

      The guys are 80beans are sponsoring the event and have graciously offered their office as the place to hang out and are providing refreshments. The office is located on the Vijzelstraat 72 in -Amsterdam and we’re starting at 3pm.

      +Amsterdam and we’re starting at 3pm.

      -

      If you’re living in the neighborhood, please come and join us. As long +

      If you’re living in the neighborhood, please come and join us. As long term Rubinius contributor Dirkjan Bussink is coming over from the other side of -the country, so don’t feel held back when you’re not living in Amsterdam +the country, so don’t feel held back when you’re not living in Amsterdam itself.

      So be prepared for an afternoon of very interesting hacking. We really want to make it a fun afternoon of experimenting with Rubinius, so anything -goes! Please leave a message on the 80beans blog if you’re planning to come over:

      +goes! Please leave a message on the 80beans blog if you’re planning to come over:

      http://www.80beans.com/en/blog/2011/07/29/rbxday-at-the-80beans-office

      diff --git a/web/_site/2011/08/03/rbxday-in-real-life/index.html b/web/_site/2011/08/03/rbxday-in-real-life/index.html index 02c5d433bd..9a2e870b99 100644 --- a/web/_site/2011/08/03/rbxday-in-real-life/index.html +++ b/web/_site/2011/08/03/rbxday-in-real-life/index.html @@ -84,10 +84,10 @@

      #rbxday In Real Life

      Originally, the idea for #rbxday was a day that people all around the world could have fun experimenting with Ruby and Rubinius. Try your application or pet Ruby project on Rubinius, or -pull out that idea you’ve been wanting to explore, code it up, and run it on +pull out that idea you’ve been wanting to explore, code it up, and run it on Rubinius. We are not asking anyone to contribute to Rubinius, but we would be -most flattered if you wanted to dig into the Rubinius code to see what’s going -on under the hood. To sum up, the motto of the day is “Ruby, Rubinius, Fun Fun Fun Fun”.

      +most flattered if you wanted to dig into the Rubinius code to see what’s going +on under the hood. To sum up, the motto of the day is “Ruby, Rubinius, Fun Fun Fun Fun”.

      Of course, a great way to multiply fun is to share it with others. Several people have taken the initiative of organizing meetups on @@ -131,8 +131,8 @@

      #rbxday In Real Life

      A huge thanks to everyone who has organized one of these events. They did so -on their own initiative and show the true power of a community. If you’re near -one of the events, please do attend. If not, there’s still time to organize +on their own initiative and show the true power of a community. If you’re near +one of the events, please do attend. If not, there’s still time to organize one near you.

      If you are joining #rbxday from the @@ -140,9 +140,9 @@

      #rbxday In Real Life

      the #rubinius IRC channel on freenode.net. We would love to hear from you.

      -

      A final thought about all the ways you can help Rubinius. You don’t have to +

      A final thought about all the ways you can help Rubinius. You don’t have to contribute code directly to help. Each of these activities is just as -valuable, and if you think of any I didn’t include, please let me know:

      +valuable, and if you think of any I didn’t include, please let me know:

      • Wearing your Rubinius shirt
      • @@ -156,7 +156,7 @@

        #rbxday In Real Life

      • Testing your code on Rubinius and submitting bug/performance reports
      -

      Above all, please do have fun. That’s no gimmick. The world needs more fun.

      +

      Above all, please do have fun. That’s no gimmick. The world needs more fun.

      Put a tag on it #rbxday.

      diff --git a/web/_site/2011/08/05/rbxday-blog-posts/index.html b/web/_site/2011/08/05/rbxday-blog-posts/index.html index c288b967ef..368186bdb7 100644 --- a/web/_site/2011/08/05/rbxday-blog-posts/index.html +++ b/web/_site/2011/08/05/rbxday-blog-posts/index.html @@ -74,12 +74,12 @@

      #rbxday Blog Posts

      With just a few hours left in the first #rbxday, I wanted to share a few blog posts that people have written for today. It seems like lots of people are having lots of fun all while using Rubinius. -That’s what really matters.

      +That’s what really matters.

      And I think Andrew W. K. would probably be proud of that.

      -

      Onto the blog posts…

      +

      Onto the blog posts…

      Nathan Engdahl on the Blue Box Group blog @@ -97,18 +97,18 @@

      #rbxday Blog Posts

      from MRI, JRuby and Rubinius:

      -

      Many developers don’t think too much about what’s going on behind the -scenes when they run their Ruby code. That’s the beauty of it, easy to -write code that’s given to Ruby and run for the developer. At some point -the developer may wonder, what’s REALLY going on behind the scenes. How is +

      Many developers don’t think too much about what’s going on behind the +scenes when they run their Ruby code. That’s the beauty of it, easy to +write code that’s given to Ruby and run for the developer. At some point +the developer may wonder, what’s REALLY going on behind the scenes. How is it that something meant to run Ruby can host so many other languages? -The answer lies in what’s known as a VM, or Virtual Machine.

      +The answer lies in what’s known as a VM, or Virtual Machine.

      -

      Finally, there’s the +

      Finally, there’s the Rubysfera blog -that’s not written in a language that I can read. So, I’ll just assume that -they’re talking about Chocolate Rubinius Cake and how to bake it. ;)

      +that’s not written in a language that I can read. So, I’ll just assume that +they’re talking about Chocolate Rubinius Cake and how to bake it. ;)

      Rubiniusa (implementacji Rubiego, napisanej w Rubym) nikomu chyba @@ -121,14 +121,14 @@

      #rbxday Blog Posts

      Seriously though, I have no idea what that post says. If you do, please let me know.

      -

      There’s still time. Go test your app running on Rubinius. Tweet about it. +

      There’s still time. Go test your app running on Rubinius. Tweet about it. Use the hashtag #rbxday, so we notice you and re-share your tweet. If there are bugs, please create an issue on Github. Give us any other feedback you want on the rbxday.rubini.us website.

      -

      — XOXO RBX

      +

      — XOXO RBX

      diff --git a/web/_site/2011/08/30/rubinius-3d/index.html b/web/_site/2011/08/30/rubinius-3d/index.html index 8d7d772d27..d54143c511 100644 --- a/web/_site/2011/08/30/rubinius-3d/index.html +++ b/web/_site/2011/08/30/rubinius-3d/index.html @@ -73,18 +73,18 @@

      Rubinius - Now in The Third Dimension

      A long time ago, Bookis Smuin crafted up a 3-dimensional representation of the little Rubinius r logo. It was used on the Rubinius website and as the avatar for the @Rubinius account. And for awhile, things were good.

      -

      Somewhere along the way, the original files were lost. That left us with only PNG that was 239px wide. That’s no good. To the Twitters!

      +

      Somewhere along the way, the original files were lost. That left us with only PNG that was 239px wide. That’s no good. To the Twitters!

      I lazy tweeted asking for help re-building the logo in 3D based on the work that Bookis did. Lo and behold, I asked and the internet delivered.

      -

      The very smart and good looking Roger Bacardit (@ruxii) from Codegram in Barcelona, España stepped up to tackle the task. Lickity split, he cranked out two versions (white on black and black on white) at super mega huge resolution (~4000px square).

      +

      The very smart and good looking Roger Bacardit (@ruxii) from Codegram in Barcelona, España stepped up to tackle the task. Lickity split, he cranked out two versions (white on black and black on white) at super mega huge resolution (~4000px square).

      Like everything else we do, these logo files are very liberally licensed and available for download and reuse in the Rubinius Collateral repo over on GitHub.

      Thank you, Bookis, for the original. Thank you, Roger, for the rebuild.

      -

      — XOXO RBX

      +

      — XOXO RBX

      diff --git a/web/_site/2011/09/02/retiring-some-rubinius-rewards/index.html b/web/_site/2011/09/02/retiring-some-rubinius-rewards/index.html index d81f0e670c..0b13644eea 100644 --- a/web/_site/2011/09/02/retiring-some-rubinius-rewards/index.html +++ b/web/_site/2011/09/02/retiring-some-rubinius-rewards/index.html @@ -73,21 +73,21 @@

      Retiring (Some) Rubinius Rewards

      Bad News First

      -

      The General Availability shirts are retired. We gave out about 1,000 to people all over the world. That’s very awesome. We’re really happy with the excitement about Rubinius from you all. Thank you, again. But it’s time to move on from these shirts. If you’ve already got one, good on you. If you haven’t yet, sorry. There will be other chances in the future, though.

      +

      The General Availability shirts are retired. We gave out about 1,000 to people all over the world. That’s very awesome. We’re really happy with the excitement about Rubinius from you all. Thank you, again. But it’s time to move on from these shirts. If you’ve already got one, good on you. If you haven’t yet, sorry. There will be other chances in the future, though.

      Likewise, the Square and Bumper Stickers have been retired, too.

      Good News Next

      -

      The Diecut R stickers are still available. Just email us at community@rubini.us if you want one. Committers stickers are still available too. If you committed to Rubinius before May 16, 2011 and haven’t received one of these, email us to get yours. The 2011 Q2 committers stickers are also available.

      +

      The Diecut R stickers are still available. Just email us at community@rubini.us if you want one. Committers stickers are still available too. If you committed to Rubinius before May 16, 2011 and haven’t received one of these, email us to get yours. The 2011 Q2 committers stickers are also available.

      -

      As promised, we have made a special t-shirt for people who have committed 10 or more times. They’re at the printer right now, so no pictures yet. Here’s a hint though: black on black.

      +

      As promised, we have made a special t-shirt for people who have committed 10 or more times. They’re at the printer right now, so no pictures yet. Here’s a hint though: black on black.

      -

      We’ll continue to do free stuff in the future, but it will always be changing. Keep an eye on this blog for updates to what’s available.

      +

      We’ll continue to do free stuff in the future, but it will always be changing. Keep an eye on this blog for updates to what’s available.

      One More Thing

      -

      Rubinius friend of the family, Heather Peterson (@hrrrthrrr) drew up some Rubinius sketches for us to use on upcoming t-shirts and stickers. As a little thing, we’re giving away her original artwork as prize.

      +

      Rubinius friend of the family, Heather Peterson (@hrrrthrrr) drew up some Rubinius sketches for us to use on upcoming t-shirts and stickers. As a little thing, we’re giving away her original artwork as prize.

      Rubinius sketch by Heather Peterson (@hrrrthrrr) on Flickr Rubinius sketch by Heather Peterson (@hrrrthrrr) on Flickr

      @@ -96,7 +96,7 @@

      One More Thing

      Get blogging.

      -

      — XOXO RBX

      +

      — XOXO RBX

      diff --git a/web/_site/2011/10/04/steve-klabnik-thinks-rubinius-is-awesome/index.html b/web/_site/2011/10/04/steve-klabnik-thinks-rubinius-is-awesome/index.html index 50e2248be2..30b3654ad2 100644 --- a/web/_site/2011/10/04/steve-klabnik-thinks-rubinius-is-awesome/index.html +++ b/web/_site/2011/10/04/steve-klabnik-thinks-rubinius-is-awesome/index.html @@ -71,7 +71,7 @@

      Steve Klabnik Thinks Rubinius is Awesome

      -

      Steve Klabnik added support for require_relative to Rubinius. He documents his process and how much fun he had. We’re glad to hear that Steve thinks Rubinius is awesome. Making Rubinius awesome for rubyists has always been one of our core tenets.

      +

      Steve Klabnik added support for require_relative to Rubinius. He documents his process and how much fun he had. We’re glad to hear that Steve thinks Rubinius is awesome. Making Rubinius awesome for rubyists has always been one of our core tenets.

      Even if I didn’t have some code to look at, because Rubinius is just Ruby, diff --git a/web/_site/2011/10/18/contributing-to-rubinius/index.html b/web/_site/2011/10/18/contributing-to-rubinius/index.html index cf214e23c2..1a3d53e109 100644 --- a/web/_site/2011/10/18/contributing-to-rubinius/index.html +++ b/web/_site/2011/10/18/contributing-to-rubinius/index.html @@ -83,7 +83,7 @@

      Contributions

      Before diving into the Rubinius code, I want to emphasize that there are many ways that you can contribute to Rubinius. One of the most valuable for us is -trying your own library or application on Rubinius. We’ve worked super hard to +trying your own library or application on Rubinius. We’ve worked super hard to make using Rubinius in place of MRI as simple as possible. For example, with a typical Rails application, here is all you should need to do to get set up:

      @@ -92,7 +92,7 @@

      Contributions

      gem install bundler
  • -

    Once you’ve got Rubinius and Bundler installed, running your application +

    Once you’ve got Rubinius and Bundler installed, running your application should be this simple:

    cd <my_application>
    @@ -114,8 +114,8 @@ 

    Contributions

    Another way to contribute to Rubinius is talking about the project. If you tried your application and your 50 gems installed without problems, consider tweeting at us or writing up a quick blog post -about your experiences. If you’ve done something -fancy that you’d like to share with us, we’re always +about your experiences. If you’ve done something +fancy that you’d like to share with us, we’re always happy to have guest blog posts, too. We even have documentation on how to write a blog @@ -138,11 +138,11 @@

    Clone & Build

    If you run into any trouble with these steps, see the Getting Started page for more information. -You may need to install libraries required to build Rubinius. If you don’t -find answers there, visit the #rubinius channel on freenode.net and we’ll +You may need to install libraries required to build Rubinius. If you don’t +find answers there, visit the #rubinius channel on freenode.net and we’ll help you out.

    -

    While the build is running, let’s get a quick overview of how Rubinius is +

    While the build is running, let’s get a quick overview of how Rubinius is organized.

    Code Tour

    @@ -157,7 +157,7 @@

    Ruby Core Library

    The Ruby core library is found in the kernel/ directory. The kernel is divided into subdirectories that are loaded in order when Rubinius boots. The divisions were made to help share the Ruby core library with other -implementations. I’ll cover those basic divisions here. For more details about +implementations. I’ll cover those basic divisions here. For more details about how the loading process works, see the Bootstrapping documentation.

    @@ -189,7 +189,7 @@

    Rubinius VM

    One of the important parts of Rubinius are the low-level operations that cannot be defined in Ruby. These are things like adding two Fixnums together. These operations are called primitives and the code for them is in -vm/builtin. Since you will likely encounter these in the core library, we’ll +vm/builtin. Since you will likely encounter these in the core library, we’ll delve into them a bit.

    Primitives

    @@ -197,10 +197,15 @@

    Primitives

    All methods that can be called in Ruby are exposed as, well, Ruby methods. If you open kernel/bootstrap/fixnum.rb, you should see the following code:

    -

    Liquid error: undefined method `join’ for #

    +
    1 def to_f
    +2   Rubinius.primitive :fixnum_to_f
    +3   raise PrimitiveFailure, "Fixnum#to_f primitive failed"
    +4 end
    +
    +

    The Rubinius.primitive :fixnum_to_f code looks like a normal Ruby method -call but it is not. It’s actually a compiler directive to tag this Ruby method +call but it is not. It’s actually a compiler directive to tag this Ruby method as having an associated primitive operation. The name of the primitive is fixnum_to_f. This naming convention is standard, being composed of the class name and the method name. Methods in Ruby that are characters, like +, are @@ -215,7 +220,10 @@

    Primitives

    To see how the Ruby method relates to the primitive code, open vm/builtin/fixnum.hpp:

    -

    Liquid error: undefined method `join’ for “\n// Rubinius.primitive :fixnum_to_f\nFloat* to_f(STATE);\n”:String

    +
    1 // Rubinius.primitive :fixnum_to_f
    +2 Float* to_f(STATE);
    +
    +

    The vm/builtin/*.hpp files are processed by the Rubinius build system to automatically generate C++ code to resolve and bind these primitive @@ -225,7 +233,11 @@

    Primitives

    Finally, the actual implementation of this primitive is found in vm/builtin/fixnum.cpp:

    -

    Liquid error: undefined method `join’ for #

    +
    1 Float* Fixnum::to_f(STATE) {
    +2   return Float::create(state, (double)to_native());
    +3 }
    +
    +

    Here you can see that a new Float object is being created from the value of the Fixnum. Rubinius names the C++ classes that implement the Ruby primitive @@ -233,7 +245,7 @@

    Primitives

    is to build an elegant, easily comprehensible system, and we feel that this consistency has been a great benefit toward that goal.

    -

    Now that we have a basic idea of the structure of Rubinius, let’s look at some +

    Now that we have a basic idea of the structure of Rubinius, let’s look at some aspects of its runtime behavior, in particular, supporting different Ruby language modes.

    @@ -255,7 +267,7 @@

    Language Modes

    The default language mode is 1.8, so if you invoke rbx with no other -options, you’ll be running in 1.8 mode. You can change the default mode with a +options, you’ll be running in 1.8 mode. You can change the default mode with a configure time option as follows:

    ./configure --default-version=1.9
    @@ -264,8 +276,8 @@ 

    Language Modes

    If you configure Rubinius to have a default language mode of 1.9, you can access 1.8 mode with the -X18 runtime option as discussed above.

    -

    Ok, we’ve got the code, we understand something about how it is organized, -we’ve got the runtime behavior down, now let’s look at actually implementing +

    Ok, we’ve got the code, we understand something about how it is organized, +we’ve got the runtime behavior down, now let’s look at actually implementing Ruby. To do that, we need to know how Ruby behaves, and that is what RubySpec is all about.

    @@ -275,7 +287,7 @@

    By the Spec

    implementing Ruby behavior, and we are constantly contributing more to it. Basically, Rubinius does it by the spec. So, any commit to the Ruby core library in Rubinius must either have new specs or make existing specs pass. To -effectively contribute to Rubinius, you’ll need to understand some basics +effectively contribute to Rubinius, you’ll need to understand some basics about RubySpec. I recommend that you have a read through the documentation at rubyspec.org.

    @@ -320,10 +332,10 @@

    Continuous Integration

    One goal of MSpec is to make it as easy as possible to run the specs for the parts of Ruby that have been implemented. It takes a long time to implement all of Ruby correctly, but we want to know that the parts we have implemented -don’t get broken while working on other parts. That is the role of continuous +don’t get broken while working on other parts. That is the role of continuous integration. To use CI effectively, we need to partition the specs into those -that we expect to pass and those we know we don’t pass yet. MSpec provides a -facility for this, called tagging, that we’ll look at shortly. For now, we’ll +that we expect to pass and those we know we don’t pass yet. MSpec provides a +facility for this, called tagging, that we’ll look at shortly. For now, we’ll just look at running the specs in CI mode.

    To run all the Rubinius specs in CI mode under the default language version, @@ -338,7 +350,7 @@

    Continuous Integration

    The bin/mspec ci command runs the mspec-ci script. You should be familiar -with this mechanism from working with Git. It’s the same idea. The mspec +with this mechanism from working with Git. It’s the same idea. The mspec script itself is just a utility to invoke the various specific MSpec scripts. To see the options for mspec, run the following command

    @@ -361,33 +373,33 @@

    Continuous Integration

    mspec core/array ci -

    Now that we’ve got the basics of MSpec down, let’s look at how we find specs -that fail on Rubinius. To do this, we’ll use the mspec tag command.

    +

    Now that we’ve got the basics of MSpec down, let’s look at how we find specs +that fail on Rubinius. To do this, we’ll use the mspec tag command.

    Tagged Specs

    Since Rubinius uses the tagging mechanism to create the set of CI specs to -run, the best way to discover what parts of RubySpec that Rubinius isn’t -passing yet is to list the specs that are tagged. There’s a command for that:

    +run, the best way to discover what parts of RubySpec that Rubinius isn’t +passing yet is to list the specs that are tagged. There’s a command for that:

    bin/mspec tag --list fails -tx19 :ci_files
     
    -

    This command lists all the specs that are tagged as failing. There’s some new +

    This command lists all the specs that are tagged as failing. There’s some new syntax here, namely :ci_files. MSpec has the concept of pseudo-directories. Basically, they are lists of files. The reason for this is that running all the core or standard library specs in RubySpec is not as simple as just -running all the files under spec/ruby/core or spec/ruby/library. It’s more +running all the files under spec/ruby/core or spec/ruby/library. It’s more complicated than that because there are 1.8- and 1.9-specific libraries. Rather than wrapping everything in ruby_version_is guards, MSpec adds version-specific lists and names them, for example, :core and :library.

    -

    In this case, we’re using the list of files specified by :ci_files. This +

    In this case, we’re using the list of files specified by :ci_files. This list excludes some files that are known to cause problems if they are run.

    The list of specs that are currently marked as failing is pretty long. We can reduce the number of tags we are looking at by giving a smaller set of specs -to run. For example, let’s just run the File specs:

    +to run. For example, let’s just run the File specs:

    bin/mspec tag --list fails -tx19 core/file
     
    @@ -399,7 +411,7 @@

    Tagged Specs

    bin/mspec tag --list fails -tx19 core/file/world_writable
     
    -

    If we look into the documentation for File.world_writable?, we’ll find that +

    If we look into the documentation for File.world_writable?, we’ll find that it is a new method introduced in 1.9. Excellent, this gives us an opportunity to talk about language-specific changes in Rubinius.

    @@ -411,7 +423,7 @@

    Language-specific Changes

    create separate runtime kernels for Rubinius. You can see these in the runtime/18 and runtime/19 directories after building.

    -

    Here’s how language-specific features are handled in the Rubinius kernel.

    +

    Here’s how language-specific features are handled in the Rubinius kernel.

    1. If there are no language-specific methods, the name of the file in @@ -439,7 +451,7 @@

      Language-specific Changes

      bin/mspec -tx19 core/file/world_writable
       
      -

      If all the specs pass, then you’re ready to remove the CI tags. To do so, run +

      If all the specs pass, then you’re ready to remove the CI tags. To do so, run the following command:

      bin/mspec tag --del fails -tx19 core/file/world_writable
      @@ -451,8 +463,8 @@ 

      Language-specific Changes

      rake
       
      -

      If everything passes, you’re ready to submit a pull request. All in all, that -wasn’t too bad, right?

      +

      If everything passes, you’re ready to submit a pull request. All in all, that +wasn’t too bad, right?

      One final note, if you are making changes to RubySpec, make separate commits in your pull request for changes to spec/ruby/**/*_specs.rb and another @@ -462,10 +474,10 @@

      Language-specific Changes

      Wrapping Presents

      The information here should give you everything you need to get your feet wet -in Rubinius. By the way, today is Evan’s birthday. If you’re not taking him to -dinner, why don’t you show your appreciation for this fantastic project he +in Rubinius. By the way, today is Evan’s birthday. If you’re not taking him to +dinner, why don’t you show your appreciation for this fantastic project he created by grabbing Rubinius and hacking on some Ruby code. Be safe and have -fun! We can’t wait to hear from you.

      +fun! We can’t wait to hear from you.

      diff --git a/web/_site/about/1.1.1/index.html b/web/_site/about/1.1.1/index.html index 268fbb31a2..e988f1bef7 100644 --- a/web/_site/about/1.1.1/index.html +++ b/web/_site/about/1.1.1/index.html @@ -121,8 +121,8 @@

      Summary

    2. Make Readline library configurable.
    3. Imported pure Ruby Readline (rb-readline at e591463)
    4. Add Array#select via aliasing
    5. -
    6. Handle next’ing out of rescue handlers. Fixes #556
    7. -
    8. Fix Bignum#» to respect 2s complement properly
    9. +
    10. Handle next’ing out of rescue handlers. Fixes #556
    11. +
    12. Fix Bignum#» to respect 2s complement properly
    13. Follow the weird self-in-eval behavior
    14. Add enough delegation to support Method#parameters. Fixes #557
    15. Wipe out CDPATH when building. Fixes #555
    16. @@ -137,9 +137,9 @@

      Summary

    17. Specify the version for FFI::Library::LIBC like ffi-ruby gem. Closes #546.
    18. Create gem cache dir with mkdir_p. Closes #541 again.
    19. Fixed function declarations. Closes #543.
    20. -
    21. Backport add –cxx to configure from multiverse (6596ed7). Closes #542.
    22. +
    23. Backport add –cxx to configure from multiverse (6596ed7). Closes #542.
    24. Add rb_struct_new and rb_ary_freeze. Fixes #540
    25. -
    26. Make sure the user’s gem cache directory exists. Fixes #541
    27. +
    28. Make sure the user’s gem cache directory exists. Fixes #541
    29. Incorporate rubygems loadtime speedup patch
    30. Speed up rubygems gemspec loading via caching
    31. Remove CompiledMethod#compile
    32. @@ -155,7 +155,7 @@

      Summary

    33. Implement rb_exec_recursive (mostly cripped from 1.8.7)
    34. Make rb_gc_force_recycle a noop
    35. Add rb_cmpint, rb_cmperr, and rb_equal
    36. -
    37. Don’t cache on autoload failure. Fixes #529
    38. +
    39. Don’t cache on autoload failure. Fixes #529
    40. Write out a newline for an empty string too. Fixes #525
    41. Add Regexp#search_from. Fixes #524
    42. Use string coersion for filename in class_eval / module_eval
    43. @@ -163,11 +163,11 @@

      Summary

    44. Add missing return value used in Errno.handle checks
    45. Allow for subclassing Thread, fixes #526
    46. Thread#new throws an exception when not given a block
    47. -
    48. Propagate –cc configure setting to CC, CXX env vars. Closes #520.
    49. -
    50. Removed -D from ‘rbx compile’ options. Closes #523.
    51. +
    52. Propagate –cc configure setting to CC, CXX env vars. Closes #520.
    53. +
    54. Removed -D from ‘rbx compile’ options. Closes #523.
    55. Better docs on installing gems with rbx.
    56. Fixed String#casecmp. Closes #518.
    57. -
    58. Fixed –help output.
    59. +
    60. Fixed –help output.
    61. See README for build, install directions. Closes #521.
    62. taking care of rb_ary_to_s for issue 517
    63. new capi method rb_obj_dup
    64. @@ -186,11 +186,11 @@

      Summary

    65. Remove illegal casts. Fixes #509.
    66. Refuse to configure, build if RUBYLIB is set.
    67. Fix OpenBSD complaints about strcpy, sprintf.
    68. -
    69. Don’t enable execinfo by default on OpenBSD.
    70. -
    71. Add -D__STDC_LIMIT_MACROS to CFLAGS if it’s not there.
    72. +
    73. Don’t enable execinfo by default on OpenBSD.
    74. +
    75. Add -D__STDC_LIMIT_MACROS to CFLAGS if it’s not there.
    76. Speed up rb_yield using some type checking tricks
    77. Fixed pack to taint output for tainted directives string.
    78. -
    79. Added configure option to specify ‘rake’ command.
    80. +
    81. Added configure option to specify ‘rake’ command.
    82. Fix for missing pthread functions on OpenBSD.
    83. Fix String#split edge case. Fixes #505
    84. Set __STDC_LIMIT_MACROS for proper C99 compat. Fixes #507
    85. @@ -200,15 +200,15 @@

      Summary

    86. Set the scope of masgn locals early. Fixes #502.
    87. Use same wording/quoting as MRI. Fixes #503
    88. subclassing IO works properly for pipe/popen
    89. -
    90. Enable running docs site with bootstrap Ruby using ‘rake docs’.
    91. +
    92. Enable running docs site with bootstrap Ruby using ‘rake docs’.
    93. Reorganize how the MRI backtrace is rendered. Fixes #501.
    94. Add missing pop to fix stack effect. Fixes #490
    95. -
    96. Return the user’s object, not the coerced one. Fixes #499.
    97. +
    98. Return the user’s object, not the coerced one. Fixes #499.
    99. Add Socket#connect_nonblock. Fixes #498.
    100. Add rb_io_close
    101. Add rb_memerror as a fatal condition. Fixes #496
    102. Add -fPIC to rbconfig CCDLFLAGS like MRI. Closes #492.
    103. -
    104. Don’t allow meta classes to be allocated
    105. +
    106. Don’t allow meta classes to be allocated
    107. Preserve zero length captures. Fixes #495
    108. diff --git a/web/_site/about/one_one/index.html b/web/_site/about/one_one/index.html index bb5c775d81..275e26e7cf 100644 --- a/web/_site/about/one_one/index.html +++ b/web/_site/about/one_one/index.html @@ -102,14 +102,14 @@

      Additions

    109. Implement a new GIL algorithm to prevent starvation
    110. Add Debugger APIs and reference CLI debugger
    111. Overhaul finalizers, support for resurecting finalizers
    112. -
    113. Basic ‘rbx docs’ command support.
    114. -
    115. Add ‘rbx report’ and support for VM and ruby crashes
    116. +
    117. Basic ‘rbx docs’ command support.
    118. +
    119. Add ‘rbx report’ and support for VM and ruby crashes
    120. Add CM::Script#eval_source
    121. Rewrote Array#pack and String#unpack
    122. Add code to detect bad extensions. Recompile your extensions.
    123. Add dbm, sdbm, and gdbm extensions
    124. Implement support for -n, -p, and -a. Fixes #353.
    125. -
    126. Add and use –agent when running the specs
    127. +
    128. Add and use –agent when running the specs
    129. Add String#secure_compare @x-api
    130. Add heapdump capability for memory debugging
    131. Add automatic object ivar packing (improves memory usage)
    132. @@ -129,7 +129,7 @@

      Fixes

    133. Support rb_sys_fail being passed NULL
    134. Verify that the ruby to build with is the one it was configured with
    135. Fixed Module#define_method to return a lambda Proc
    136. -
    137. Add Kernel#type even though it’s deprecated. Fixes #469.
    138. +
    139. Add Kernel#type even though it’s deprecated. Fixes #469.
    140. Move Etc::Passwd and Etc::Group to Struct
    141. Add no-op rubysig.h to make extensions happy
    142. Add unblock support to rb_thread_blocking_region. Credit: kudo. Fixes #461.
    143. @@ -167,10 +167,10 @@

      Fixes

    144. Speed up Kernel#` by using a specialized primitive
    145. Use same function signature as MRI for rb_reg_new
    146. Check for and run #to_ary when passed to yield with 2+ args. Fixes #374.
    147. -
    148. Don’t expand -I paths. Fixes #434.
    149. +
    150. Don’t expand -I paths. Fixes #434.
    151. Remove old, stale minitest
    152. Slight cleanup of Socket and adding Socket.getnameinfo
    153. -
    154. Add support for rb_gv_get(“$~”)
    155. +
    156. Add support for rb_gv_get(“$~”)
    157. Initial version.h for C-API.
    158. Add the C API rb_reg_nth_match method
    159. Add C API function rb_reg_new
    160. @@ -190,17 +190,17 @@

      Fixes

    161. Enhance Rubinius::Fiber
    162. Module#class_variable_set now raises a TypeError when self is frozen
    163. Fix IO.foreach with a nil separator, it should yield the entire contents at once
    164. -
    165. Remove Ar since it’s not used anymore
    166. +
    167. Remove Ar since it’s not used anymore
    168. Allow splat arguments in define_method. Fixes #419.
    169. Preserve path seperators in Dir.glob. Fixes #420.
    170. add rb_need_block() to rbx capi
    171. Kernel.extend now raises a TypeError, when called on a frozen object
    172. Fix profiler graph output and handling of blocks
    173. Cleanup of Bignum#%, significant performance improvement
    174. -
    175. Don’t allow initializing a class twice
    176. +
    177. Don’t allow initializing a class twice
    178. Move Hash#setup to Hash#__setup__ to allow overriding
    179. Cleanup IO.popen and IO::BidirectionalPipe
    180. -
    181. Only run ->dfree if ->data isn’t NULL
    182. +
    183. Only run ->dfree if ->data isn’t NULL
    184. Fix Module#remove_const to not call Module#const_missing
    185. Temporarily disable running finalizers at exit.
    186. Test the proper scope when determining if long return is possible
    187. @@ -209,9 +209,9 @@

      Fixes

    188. Handle block arguments to a lambda specially. Fixes #398.
    189. File#truncate now raises an IOError if file is not opened for writing
    190. Fix R::CompiledMethod#add_metadata to allow multiple keys
    191. -
    192. Don’t use self in a block that might be instance_evald. Fixes #399.
    193. +
    194. Don’t use self in a block that might be instance_evald. Fixes #399.
    195. Expose the SystemExit to at_exit handlers. Fixes #395.
    196. -
    197. Minor performanece fix, don’t initialize an object body twice
    198. +
    199. Minor performanece fix, don’t initialize an object body twice
    200. Have Proc#inspect use the exact same format as MRI
    201. Support -1 as the free function
    202. Add Rubinius specific #__finalize__ API for resurrectable finalizers
    203. @@ -239,7 +239,7 @@

      Fixes

    204. Added rb_set_kcode.
    205. Fix warnings compiling Melbourne ext in 1.9.
    206. Generalize building with MRI 1.8/1.9 or rbx.
    207. -
    208. Add –cc to configure Script, so you can do ‘rvm install rbx -C –cc=clang’, as with MRI and REE.
    209. +
    210. Add –cc to configure Script, so you can do ‘rvm install rbx -C –cc=clang’, as with MRI and REE.
    211. Fix building with gcc 4.4.1.
    212. Run at_exit blocks and finalizers before exiting a fork. Fixes #372.
    213. Add -Xgc.honor_start to control if GC.start is honored
    214. @@ -261,7 +261,7 @@

      Fixes

    215. Dir#new should call #to_str under 1.8 and #to_path under 1.9
    216. Fixed Dir.open to call StringValue. Closes #362.
    217. Dir should be calling to_str on non-String arguments in Ruby 1.8
    218. -
    219. kronos’ fix for Bignum#<<. Closes #350.
    220. +
    221. kronos’ fix for Bignum#<<. Closes #350.
    222. Use correct module namespacing in Numeric specs.
    223. Further conform Numeric to MRI. Closes #349.
    224. More specs for Numeric#<=>.
    225. diff --git a/web/_site/about/one_point_oh/index.html b/web/_site/about/one_point_oh/index.html index b8b2a2f841..e206b4480c 100644 --- a/web/_site/about/one_point_oh/index.html +++ b/web/_site/about/one_point_oh/index.html @@ -73,20 +73,20 @@

      Thanks

      version 1.0. This is a reference to the great defender of Rome. This name was given to Rubinius by Geoffrey Grosenbach, who secured naming rights to version 1.0 many years ago by being the very first person to -provide some financial backing for the project. I can’t thank him enough.

      +provide some financial backing for the project. I can’t thank him enough.

      -

      Tom Mornini and Engine Yard deserve the lion’s share of the thanks. Back in +

      Tom Mornini and Engine Yard deserve the lion’s share of the thanks. Back in 2007 when Tom asked me to come work on Rubinius at Engine Yard, it was a dream -come true. They’ve tirelessly supported the project over the years, even when +come true. They’ve tirelessly supported the project over the years, even when project momentum waned.

      And lastly, thanks to everyone who has contributed to the project. Over the -years, there have been over 200 contributers who’ve given up their free time +years, there have been over 200 contributers who’ve given up their free time to help make Rubinius great.

      - Evan Phoenix

      -

      What’s New Since 1.0rc5

      +

      What’s New Since 1.0rc5

      • Updated README.
      • @@ -99,7 +99,7 @@

        What’s New Since 1.0rc5

      • Include RUBY_EXTCONF_H. Fixes #281.
      • Use _exit() rather than exit() to avoid C++ finalization races
      • Catch and handle a redo passing through a rescue properly (unicorn)
      • -
      • Don’t use Class#ancestors internally
      • +
      • Don’t use Class#ancestors internally
      • Clean up test directory

      • @@ -128,13 +128,13 @@

        Highlights

        Known Issues

          -
        • String#unpack and Array#pack are currently pretty slow. We’re working +
        • String#unpack and Array#pack are currently pretty slow. We’re working on this issue and will release a fix in the near future.
        • A number of String methods are a bit slower than in 1.8. Most of these are known and being addressed.
        • -
        • We’ve added much of the MRI C-API for running Ruby extensions, but -there are some extensions that don’t work yet. Typically, this is because -the extension uses RBASIC(), RHASH(), or RREGEXP(). These depend on MRI’s +
        • We’ve added much of the MRI C-API for running Ruby extensions, but +there are some extensions that don’t work yet. Typically, this is because +the extension uses RBASIC(), RHASH(), or RREGEXP(). These depend on MRI’s internal object memory layout. In most cases, there are regular functions available to use that do not depend on MRI internals. We will help C extension authors to make their code portable. Additionally, extensions diff --git a/web/_site/about/one_point_one/index.html b/web/_site/about/one_point_one/index.html index 7e62082481..fb4b925955 100644 --- a/web/_site/about/one_point_one/index.html +++ b/web/_site/about/one_point_one/index.html @@ -112,7 +112,7 @@

          Fixes

        • Changed libgdtoa g_dfmt() to emit MRI format for minimal, unique String representation of Float.
        • Added to_s_minimal primitive for Float#to_s.
        • Use send to reach private extend_object methods. Closes #324.
        • -
        • Don’t use a increment operation and the original value in the same expression
        • +
        • Don’t use a increment operation and the original value in the same expression
        • Explicitly cast the return value of stack_pop() to void*
        • Initial work to enable compiling with clang
        • Use error state for read / write and print out the message
        • @@ -120,45 +120,45 @@

          Fixes

        • Honor read-only-ness of certain globals. Fixes #283.
        • Escape slashes in Regexp#to_s output. Fixes #308.
        • Disambiguate a vcall send to the send_method opcode. Fixes #293.
        • -
        • Evaluate next’s argument even though it’s ignored. Fixes #307.
        • +
        • Evaluate next’s argument even though it’s ignored. Fixes #307.
        • Report path to script bodies relatively. Fixes #308.
        • Remove Numeric#==
        • Use Kernel.exit! after a forked block returns. Fixes #289.
        • Fix fork to allow SystemExit through properly
        • Be persistant with write(2)
        • -
        • Handle object_id’s for immediates. Fixes #315.
        • +
        • Handle object_id’s for immediates. Fixes #315.
        • Alter protocol for how Proc with a bound method is invoked. Fixes #277.
        • -
        • Teach Signal.trap the rest of it’s tricks. Fixes #314.
        • +
        • Teach Signal.trap the rest of it’s tricks. Fixes #314.
        • Make sure the arguments are Strings. @bugfix
        • Cleanup and speed up Struct
        • Add missing functionality to Signal.trap
        • Introduce -Xprofile to be used instead of -P
        • -
        • Cleanup and fix irb’s save history feature
        • -
        • Search Object’s includes also. Fixes #328
        • +
        • Cleanup and fix irb’s save history feature
        • +
        • Search Object’s includes also. Fixes #328
        • Make sure thet the default vis in a script body is private. Fixes #327
        • Make STDOUT.reopen(path) effect the system fd. Fixes #322.
        • Use the encoding of the Regexp in String#split on characters. Fixes #323
        • Be sure to cleanup any temp modifications during #delete_if
        • -
        • Let –enable-llvm do something. Fixes #336.
        • +
        • Let –enable-llvm do something. Fixes #336.
        • Add flag support to new Dir.glob, always use it
        • Handle write() setting EAGAIN properly
        • Handle ECONNRESET like eof. Fixes #338
        • Add UNIXSocket.pair
        • Add Inliner::fixnum_le, and self recursion cuteness
        • Simplify the Class#to_s of a metaclass (rails fix)
        • -
        • Allow Modules to be dup’d, but not String
        • +
        • Allow Modules to be dup’d, but not String
        • Flip include order so that local LLVM wins
        • Fix left shifting for fixnums
        • Repair Bignum#divmod for cases with negative numbers. Fixes #319.
        • Speed up String#[] and String#=~
        • A Time is not eql? to a non-time.
        • Raise the right exception when alias fails in a module.
        • -
        • method_defined? shouldn’t search Object/Kernel.
        • +
        • method_defined? shouldn’t search Object/Kernel.
        • Print error messages to stderr instead of stdout.
        • Ensure the proper Regexp constant is found when processing literals
        • -
        • Introduce ‘push_rubinius’ instruction and use it like a rented mule
        • +
        • Introduce ‘push_rubinius’ instruction and use it like a rented mule
        • Factor out some jit code from push_cpath_top and push_rubinius
        • -
        • Quit as early as possible if we’re building on an unsupported platform
        • +
        • Quit as early as possible if we’re building on an unsupported platform

        FFI

        @@ -198,13 +198,13 @@

        C-API

      • Check async events and raise an exception via rb_thread_select.
      • Fix INT2NUM to actually take a long, not an int.
      • Implement rb_is_{const,instance_class}_id() in CAPI.
      • -
      • rb_protect’s callback takes a VALUE, not ANYARGS.
      • +
      • rb_protect’s callback takes a VALUE, not ANYARGS.
      • Add apparently-missed prototype for rb_apply()
      • Add rb_f_global_variables() and rb_str_new3().
      • -
      • rb_define_module_under() shouldn’t return a parent’s module.
      • +
      • rb_define_module_under() shouldn’t return a parent’s module.
      • Make rb_num2dbl handle all inputs correctly.
      • -
      • Set rbconfig’s LIBS to “” to to appease mkrf
      • -
      • Set rbconfig’s LIBRUBYARG_SHARED to “”, because we don’t have a shared library yet.
      • +
      • Set rbconfig’s LIBS to “” to to appease mkrf
      • +
      • Set rbconfig’s LIBRUBYARG_SHARED to “”, because we don’t have a shared library yet.
      • Add NativeMethod functors up to a ten-argument version
      diff --git a/web/_site/blog/index.html b/web/_site/blog/index.html index 3aac3a2749..edc6b7f033 100644 --- a/web/_site/blog/index.html +++ b/web/_site/blog/index.html @@ -91,7 +91,7 @@

      Contributions

      Before diving into the Rubinius code, I want to emphasize that there are many ways that you can contribute to Rubinius. One of the most valuable for us is -trying your own library or application on Rubinius. We’ve worked super hard to +trying your own library or application on Rubinius. We’ve worked super hard to make using Rubinius in place of MRI as simple as possible. For example, with a typical Rails application, here is all you should need to do to get set up:

      @@ -100,7 +100,7 @@

      Contributions

      gem install bundler
      -

      Once you’ve got Rubinius and Bundler installed, running your application +

      Once you’ve got Rubinius and Bundler installed, running your application should be this simple:

      cd <my_application>
      @@ -122,8 +122,8 @@ 

      Contributions

      Another way to contribute to Rubinius is talking about the project. If you tried your application and your 50 gems installed without problems, consider tweeting at us or writing up a quick blog post -about your experiences. If you’ve done something -fancy that you’d like to share with us, we’re always +about your experiences. If you’ve done something +fancy that you’d like to share with us, we’re always happy to have guest blog posts, too. We even have documentation on how to write a blog @@ -146,11 +146,11 @@

      Clone & Build

      If you run into any trouble with these steps, see the Getting Started page for more information. -You may need to install libraries required to build Rubinius. If you don’t -find answers there, visit the #rubinius channel on freenode.net and we’ll +You may need to install libraries required to build Rubinius. If you don’t +find answers there, visit the #rubinius channel on freenode.net and we’ll help you out.

      -

      While the build is running, let’s get a quick overview of how Rubinius is +

      While the build is running, let’s get a quick overview of how Rubinius is organized.

      Code Tour

      @@ -165,7 +165,7 @@

      Ruby Core Library

      The Ruby core library is found in the kernel/ directory. The kernel is divided into subdirectories that are loaded in order when Rubinius boots. The divisions were made to help share the Ruby core library with other -implementations. I’ll cover those basic divisions here. For more details about +implementations. I’ll cover those basic divisions here. For more details about how the loading process works, see the Bootstrapping documentation.

      @@ -197,7 +197,7 @@

      Rubinius VM

      One of the important parts of Rubinius are the low-level operations that cannot be defined in Ruby. These are things like adding two Fixnums together. These operations are called primitives and the code for them is in -vm/builtin. Since you will likely encounter these in the core library, we’ll +vm/builtin. Since you will likely encounter these in the core library, we’ll delve into them a bit.

      Primitives

      @@ -205,10 +205,15 @@

      Primitives

      All methods that can be called in Ruby are exposed as, well, Ruby methods. If you open kernel/bootstrap/fixnum.rb, you should see the following code:

      -

      Liquid error: undefined method `join’ for #

      +
      1 def to_f
      +2   Rubinius.primitive :fixnum_to_f
      +3   raise PrimitiveFailure, "Fixnum#to_f primitive failed"
      +4 end
      +
      +

      The Rubinius.primitive :fixnum_to_f code looks like a normal Ruby method -call but it is not. It’s actually a compiler directive to tag this Ruby method +call but it is not. It’s actually a compiler directive to tag this Ruby method as having an associated primitive operation. The name of the primitive is fixnum_to_f. This naming convention is standard, being composed of the class name and the method name. Methods in Ruby that are characters, like +, are @@ -223,7 +228,10 @@

      Primitives

      To see how the Ruby method relates to the primitive code, open vm/builtin/fixnum.hpp:

      -

      Liquid error: undefined method `join’ for “\n// Rubinius.primitive :fixnum_to_f\nFloat* to_f(STATE);\n”:String

      +
      1 // Rubinius.primitive :fixnum_to_f
      +2 Float* to_f(STATE);
      +
      +

      The vm/builtin/*.hpp files are processed by the Rubinius build system to automatically generate C++ code to resolve and bind these primitive @@ -233,7 +241,11 @@

      Primitives

      Finally, the actual implementation of this primitive is found in vm/builtin/fixnum.cpp:

      -

      Liquid error: undefined method `join’ for #

      +
      1 Float* Fixnum::to_f(STATE) {
      +2   return Float::create(state, (double)to_native());
      +3 }
      +
      +

      Here you can see that a new Float object is being created from the value of the Fixnum. Rubinius names the C++ classes that implement the Ruby primitive @@ -241,7 +253,7 @@

      Primitives

      is to build an elegant, easily comprehensible system, and we feel that this consistency has been a great benefit toward that goal.

      -

      Now that we have a basic idea of the structure of Rubinius, let’s look at some +

      Now that we have a basic idea of the structure of Rubinius, let’s look at some aspects of its runtime behavior, in particular, supporting different Ruby language modes.

      @@ -263,7 +275,7 @@

      Language Modes

      The default language mode is 1.8, so if you invoke rbx with no other -options, you’ll be running in 1.8 mode. You can change the default mode with a +options, you’ll be running in 1.8 mode. You can change the default mode with a configure time option as follows:

      ./configure --default-version=1.9
      @@ -272,8 +284,8 @@ 

      Language Modes

      If you configure Rubinius to have a default language mode of 1.9, you can access 1.8 mode with the -X18 runtime option as discussed above.

      -

      Ok, we’ve got the code, we understand something about how it is organized, -we’ve got the runtime behavior down, now let’s look at actually implementing +

      Ok, we’ve got the code, we understand something about how it is organized, +we’ve got the runtime behavior down, now let’s look at actually implementing Ruby. To do that, we need to know how Ruby behaves, and that is what RubySpec is all about.

      @@ -283,7 +295,7 @@

      By the Spec

      implementing Ruby behavior, and we are constantly contributing more to it. Basically, Rubinius does it by the spec. So, any commit to the Ruby core library in Rubinius must either have new specs or make existing specs pass. To -effectively contribute to Rubinius, you’ll need to understand some basics +effectively contribute to Rubinius, you’ll need to understand some basics about RubySpec. I recommend that you have a read through the documentation at rubyspec.org.

      @@ -328,10 +340,10 @@

      Continuous Integration

      One goal of MSpec is to make it as easy as possible to run the specs for the parts of Ruby that have been implemented. It takes a long time to implement all of Ruby correctly, but we want to know that the parts we have implemented -don’t get broken while working on other parts. That is the role of continuous +don’t get broken while working on other parts. That is the role of continuous integration. To use CI effectively, we need to partition the specs into those -that we expect to pass and those we know we don’t pass yet. MSpec provides a -facility for this, called tagging, that we’ll look at shortly. For now, we’ll +that we expect to pass and those we know we don’t pass yet. MSpec provides a +facility for this, called tagging, that we’ll look at shortly. For now, we’ll just look at running the specs in CI mode.

      To run all the Rubinius specs in CI mode under the default language version, @@ -346,7 +358,7 @@

      Continuous Integration

      The bin/mspec ci command runs the mspec-ci script. You should be familiar -with this mechanism from working with Git. It’s the same idea. The mspec +with this mechanism from working with Git. It’s the same idea. The mspec script itself is just a utility to invoke the various specific MSpec scripts. To see the options for mspec, run the following command

      @@ -369,33 +381,33 @@

      Continuous Integration

      mspec core/array ci -

      Now that we’ve got the basics of MSpec down, let’s look at how we find specs -that fail on Rubinius. To do this, we’ll use the mspec tag command.

      +

      Now that we’ve got the basics of MSpec down, let’s look at how we find specs +that fail on Rubinius. To do this, we’ll use the mspec tag command.

      Tagged Specs

      Since Rubinius uses the tagging mechanism to create the set of CI specs to -run, the best way to discover what parts of RubySpec that Rubinius isn’t -passing yet is to list the specs that are tagged. There’s a command for that:

      +run, the best way to discover what parts of RubySpec that Rubinius isn’t +passing yet is to list the specs that are tagged. There’s a command for that:

      bin/mspec tag --list fails -tx19 :ci_files
       
      -

      This command lists all the specs that are tagged as failing. There’s some new +

      This command lists all the specs that are tagged as failing. There’s some new syntax here, namely :ci_files. MSpec has the concept of pseudo-directories. Basically, they are lists of files. The reason for this is that running all the core or standard library specs in RubySpec is not as simple as just -running all the files under spec/ruby/core or spec/ruby/library. It’s more +running all the files under spec/ruby/core or spec/ruby/library. It’s more complicated than that because there are 1.8- and 1.9-specific libraries. Rather than wrapping everything in ruby_version_is guards, MSpec adds version-specific lists and names them, for example, :core and :library.

      -

      In this case, we’re using the list of files specified by :ci_files. This +

      In this case, we’re using the list of files specified by :ci_files. This list excludes some files that are known to cause problems if they are run.

      The list of specs that are currently marked as failing is pretty long. We can reduce the number of tags we are looking at by giving a smaller set of specs -to run. For example, let’s just run the File specs:

      +to run. For example, let’s just run the File specs:

      bin/mspec tag --list fails -tx19 core/file
       
      @@ -407,7 +419,7 @@

      Tagged Specs

      bin/mspec tag --list fails -tx19 core/file/world_writable
       
      -

      If we look into the documentation for File.world_writable?, we’ll find that +

      If we look into the documentation for File.world_writable?, we’ll find that it is a new method introduced in 1.9. Excellent, this gives us an opportunity to talk about language-specific changes in Rubinius.

      @@ -419,7 +431,7 @@

      Language-specific Changes

      create separate runtime kernels for Rubinius. You can see these in the runtime/18 and runtime/19 directories after building.

      -

      Here’s how language-specific features are handled in the Rubinius kernel.

      +

      Here’s how language-specific features are handled in the Rubinius kernel.

      1. If there are no language-specific methods, the name of the file in @@ -447,7 +459,7 @@

        Language-specific Changes

        bin/mspec -tx19 core/file/world_writable
         
        -

        If all the specs pass, then you’re ready to remove the CI tags. To do so, run +

        If all the specs pass, then you’re ready to remove the CI tags. To do so, run the following command:

        bin/mspec tag --del fails -tx19 core/file/world_writable
        @@ -459,8 +471,8 @@ 

        Language-specific Changes

        rake
         
        -

        If everything passes, you’re ready to submit a pull request. All in all, that -wasn’t too bad, right?

        +

        If everything passes, you’re ready to submit a pull request. All in all, that +wasn’t too bad, right?

        One final note, if you are making changes to RubySpec, make separate commits in your pull request for changes to spec/ruby/**/*_specs.rb and another @@ -470,10 +482,10 @@

        Language-specific Changes

        Wrapping Presents

        The information here should give you everything you need to get your feet wet -in Rubinius. By the way, today is Evan’s birthday. If you’re not taking him to -dinner, why don’t you show your appreciation for this fantastic project he +in Rubinius. By the way, today is Evan’s birthday. If you’re not taking him to +dinner, why don’t you show your appreciation for this fantastic project he created by grabbing Rubinius and hacking on some Ruby code. Be safe and have -fun! We can’t wait to hear from you.

        +fun! We can’t wait to hear from you.

        @@ -519,7 +531,7 @@

        -

        Steve Klabnik added support for require_relative to Rubinius. He documents his process and how much fun he had. We’re glad to hear that Steve thinks Rubinius is awesome. Making Rubinius awesome for rubyists has always been one of our core tenets.

        +

        Steve Klabnik added support for require_relative to Rubinius. He documents his process and how much fun he had. We’re glad to hear that Steve thinks Rubinius is awesome. Making Rubinius awesome for rubyists has always been one of our core tenets.

        Even if I didn’t have some code to look at, because Rubinius is just Ruby, @@ -581,21 +593,21 @@

        Bad News First

        -

        The General Availability shirts are retired. We gave out about 1,000 to people all over the world. That’s very awesome. We’re really happy with the excitement about Rubinius from you all. Thank you, again. But it’s time to move on from these shirts. If you’ve already got one, good on you. If you haven’t yet, sorry. There will be other chances in the future, though.

        +

        The General Availability shirts are retired. We gave out about 1,000 to people all over the world. That’s very awesome. We’re really happy with the excitement about Rubinius from you all. Thank you, again. But it’s time to move on from these shirts. If you’ve already got one, good on you. If you haven’t yet, sorry. There will be other chances in the future, though.

        Likewise, the Square and Bumper Stickers have been retired, too.

        Good News Next

        -

        The Diecut R stickers are still available. Just email us at community@rubini.us if you want one. Committers stickers are still available too. If you committed to Rubinius before May 16, 2011 and haven’t received one of these, email us to get yours. The 2011 Q2 committers stickers are also available.

        +

        The Diecut R stickers are still available. Just email us at community@rubini.us if you want one. Committers stickers are still available too. If you committed to Rubinius before May 16, 2011 and haven’t received one of these, email us to get yours. The 2011 Q2 committers stickers are also available.

        -

        As promised, we have made a special t-shirt for people who have committed 10 or more times. They’re at the printer right now, so no pictures yet. Here’s a hint though: black on black.

        +

        As promised, we have made a special t-shirt for people who have committed 10 or more times. They’re at the printer right now, so no pictures yet. Here’s a hint though: black on black.

        -

        We’ll continue to do free stuff in the future, but it will always be changing. Keep an eye on this blog for updates to what’s available.

        +

        We’ll continue to do free stuff in the future, but it will always be changing. Keep an eye on this blog for updates to what’s available.

        One More Thing

        -

        Rubinius friend of the family, Heather Peterson (@hrrrthrrr) drew up some Rubinius sketches for us to use on upcoming t-shirts and stickers. As a little thing, we’re giving away her original artwork as prize.

        +

        Rubinius friend of the family, Heather Peterson (@hrrrthrrr) drew up some Rubinius sketches for us to use on upcoming t-shirts and stickers. As a little thing, we’re giving away her original artwork as prize.

        Rubinius sketch by Heather Peterson (@hrrrthrrr) on Flickr Rubinius sketch by Heather Peterson (@hrrrthrrr) on Flickr

        @@ -604,7 +616,7 @@

        One More Thing

        Get blogging.

        -

        — XOXO RBX

        +

        — XOXO RBX

        @@ -626,18 +638,18 @@

        A long time ago, Bookis Smuin crafted up a 3-dimensional representation of the little Rubinius r logo. It was used on the Rubinius website and as the avatar for the @Rubinius account. And for awhile, things were good.

        -

        Somewhere along the way, the original files were lost. That left us with only PNG that was 239px wide. That’s no good. To the Twitters!

        +

        Somewhere along the way, the original files were lost. That left us with only PNG that was 239px wide. That’s no good. To the Twitters!

        I lazy tweeted asking for help re-building the logo in 3D based on the work that Bookis did. Lo and behold, I asked and the internet delivered.

        -

        The very smart and good looking Roger Bacardit (@ruxii) from Codegram in Barcelona, España stepped up to tackle the task. Lickity split, he cranked out two versions (white on black and black on white) at super mega huge resolution (~4000px square).

        +

        The very smart and good looking Roger Bacardit (@ruxii) from Codegram in Barcelona, España stepped up to tackle the task. Lickity split, he cranked out two versions (white on black and black on white) at super mega huge resolution (~4000px square).

        Like everything else we do, these logo files are very liberally licensed and available for download and reuse in the Rubinius Collateral repo over on GitHub.

        Thank you, Bookis, for the original. Thank you, Roger, for the rebuild.

        -

        — XOXO RBX

        +

        — XOXO RBX

        diff --git a/web/_site/doc/de/appendix-a-glossary/index.html b/web/_site/doc/de/appendix-a-glossary/index.html index 1d3f653ed0..777b51fe7e 100644 --- a/web/_site/doc/de/appendix-a-glossary/index.html +++ b/web/_site/doc/de/appendix-a-glossary/index.html @@ -150,16 +150,16 @@

        Anhang A - Glossar

        Eine Auflistung von Begriffsdefinitionen und Phrasen die in der Programmiersprache Ruby und dieser Implementierung verwendet -werden. Siehe auch “The Ruby Programming Language” von Flanagan und -Matsumoto [O’Reilly 2008] und “Programming Ruby: The Pragmatic -Programmer’s Guide” 2. oder 3. Auflage von Thomas et al [The Pragmatic Programmers +werden. Siehe auch “The Ruby Programming Language” von Flanagan und +Matsumoto [O’Reilly 2008] und “Programming Ruby: The Pragmatic +Programmer’s Guide” 2. oder 3. Auflage von Thomas et al [The Pragmatic Programmers 2005-2008]

        • method lookup oder method resolution

          -

          Es ist ganz einfach: Nimm das Objekt im ‘class slot’ des Objekts +

          Es ist ganz einfach: Nimm das Objekt im ‘class slot’ des Objekts (welches nicht immer dem Rückgabewert von Object#class sein muss; wenn das Objekt eines hat, ist es die Metaklasse) und beginne die Suche.

          @@ -223,7 +223,7 @@

          Anhang A - Glossar

          1. -

            Finde Methode ‘wanker’ – Durchsuche Methodentabellen in:

            +

            Finde Methode ‘wanker’ – Durchsuche Methodentabellen in:

            1. SingletonClass(F)
            2. @@ -252,7 +252,7 @@

              Anhang A - Glossar

            3. MRI

              -

              Matz’s Ruby Interpreter oder Matz’s Ruby Implementation. Eine +

              Matz’s Ruby Interpreter oder Matz’s Ruby Implementation. Eine Abkürzung mit der die offizielle Implementierung von Ruby gemeint ist. Siehe http://ruby-lang.org.

            4. @@ -307,7 +307,7 @@

              Anhang A - Glossar

        Da alle Klassen in Ruby ebenfalls Objekte sind, können diese auch -Metaklassen besitzen. “Klassenmethoden” sind somit lediglich +Metaklassen besitzen. “Klassenmethoden” sind somit lediglich Methoden, die in der Metaklasse einer Klasse definiert (d.h. in der Methodentabelle der Metaklasse eingetragen) sind. Die Methode +honk+ existiert in der Metaklasse der Klasse +Car+.

        @@ -321,7 +321,7 @@

        Anhang A - Glossar

        In Rubinius sind Metaklassen Instanzen der Klasse +SingletonClass+. Die Metaklasse eines Objektes kann durch den Aufruf der +metaclass+ Methode erhalten werden. Insgesamt wird die Anordnung der dabei beteiligten Konzepte -als “Meta-Object Protocol” oder +MOP+ bezeichnet.

        +als “Meta-Object Protocol” oder +MOP+ bezeichnet.

      2. superclass (Superklasse)

        diff --git a/web/_site/doc/de/appendix-b-reading-list/index.html b/web/_site/doc/de/appendix-b-reading-list/index.html index 5685e51c09..0b4d909faa 100644 --- a/web/_site/doc/de/appendix-b-reading-list/index.html +++ b/web/_site/doc/de/appendix-b-reading-list/index.html @@ -168,7 +168,7 @@

        Virtuelle Maschine

        • Smalltalk-80: language and its implementation by Goldberg, Robson, -Harrison (aka “The Blue Book”), Kapitel zur Implementierung der VM +Harrison (aka “The Blue Book”), Kapitel zur Implementierung der VM aus Teil IV sind online verfügbar
        • Virtual machines by Iain D. Craig
        • Sehr gute Posts von Adam Gardiner: introduction, @@ -197,7 +197,7 @@

          FFI

          diff --git a/web/_site/doc/de/build-system/index.html b/web/_site/doc/de/build-system/index.html index 38fe15d2b2..d7845338c0 100644 --- a/web/_site/doc/de/build-system/index.html +++ b/web/_site/doc/de/build-system/index.html @@ -177,7 +177,7 @@

          Development versus Install Builds

          not
          function, even if the executable is in the directory. The executable checks a single, hard-coded path. If this ends up being very painful for some reason, -we’ll revise it.

          +we’ll revise it.

          Installing Rubinius

          @@ -186,11 +186,11 @@

          Installing Rubinius

          ./configure --prefix=/path/to/install/dir
           
          -

          The configure process creates a ‘config.rb’ file that specifies the key file -paths that Rubinius uses. Once configured, run ‘rake install’ to build and +

          The configure process creates a ‘config.rb’ file that specifies the key file +paths that Rubinius uses. Once configured, run ‘rake install’ to build and install. The install procedure builds all the files, including compiling the Ruby standard library files in the lib/ directory, then copies them into the -install location using the ‘install’ program. The install tasks are located in +install location using the ‘install’ program. The install tasks are located in rakelib/install.rake.

          diff --git a/web/_site/doc/de/bytecode-compiler/transformations/index.html b/web/_site/doc/de/bytecode-compiler/transformations/index.html index e70ad0b2b8..f494fa3e93 100644 --- a/web/_site/doc/de/bytecode-compiler/transformations/index.html +++ b/web/_site/doc/de/bytecode-compiler/transformations/index.html @@ -166,7 +166,7 @@

          Safe Math Compiler Transform

          one of its cherished features but it is also truly a double-edged sword in some respects.

          -

          In the standard library the ‘mathn’ library redefines Fixnum#/ in an unsafe +

          In the standard library the ‘mathn’ library redefines Fixnum#/ in an unsafe and incompatible manner. The library aliases Fixnum#/ to Fixnum#quo, which returns a Float by default.

          @@ -176,7 +176,7 @@

          Safe Math Compiler Transform

          define this method.

          The safe math transform is enabled during the compilation of the Core -libraries to enable the plugin. During regular ‘user code’ compilation, the +libraries to enable the plugin. During regular ‘user code’ compilation, the plugin is not enabled. This enables us to support mathn without breaking the core libraries or forcing inconvenient practices.

          diff --git a/web/_site/doc/de/contributing/index.html b/web/_site/doc/de/contributing/index.html index d33b05bee7..0c9ff0744b 100644 --- a/web/_site/doc/de/contributing/index.html +++ b/web/_site/doc/de/contributing/index.html @@ -175,9 +175,9 @@

          Schreibe Specs

          Specs als unvollständig markiert sind. Diese Specs müssen dann häufig nur nachgeprüft werden oder es fehlen einer bestimmten Klasse noch Specs.

          -

          Hinweis: Du kannst auch ein pseudo-Verzeichnis ‘:files’ für <dir> +

          Hinweis: Du kannst auch ein pseudo-Verzeichnis ‘:files’ für <dir> angeben, das für alle auf Rubinius laufenden Specs die Tags anzeigt. Oder -du gibst ein Unterverzeichnis des ‘spec/’ Verzeichnisses an, um nur die +du gibst ein Unterverzeichnis des ‘spec/’ Verzeichnisses an, um nur die Tags für dieses Verzeichnis anzuzeigen.

        • @@ -192,9 +192,9 @@

          Fehlerhafte Specs korrigieren

          Starte bin/mspec tag --list fails <dir> zum Anzeigen von erfolglosen Specs.

          -

          Hinweis: Du kannst auch ein pseudo-Verzeichnis ‘:files’ für <dir> +

          Hinweis: Du kannst auch ein pseudo-Verzeichnis ‘:files’ für <dir> angeben, das für alle auf Rubinius laufenden Specs die Tags anzeigt. Oder -du gibst ein Unterverzeichnis des ‘spec/’ Verzeichnisses an, um nur die +du gibst ein Unterverzeichnis des ‘spec/’ Verzeichnisses an, um nur die Tags für dieses Verzeichnis anzuzeigen.

        • diff --git a/web/_site/doc/de/contributing/style-guide/index.html b/web/_site/doc/de/contributing/style-guide/index.html index 371d2d1acf..b2812ecba9 100644 --- a/web/_site/doc/de/contributing/style-guide/index.html +++ b/web/_site/doc/de/contributing/style-guide/index.html @@ -169,11 +169,11 @@

          C++ Code

        • Alternative Versionen von Funktionen sollten mit einer Erklärung zur -Abweichung benannt werden. Gibt es z.B. eine Funktion ‘person()’ und du +Abweichung benannt werden. Gibt es z.B. eine Funktion ‘person()’ und du möchtest eine Funktion erstellen, die den Namen der Person annimmt, dann -solltest du sie ‘person_with_name(char *name)’ oder -‘person_with_details(char *name, …)’ nennen. -Nicht jedoch ‘person1(char *name)’.

          +solltest du sie ‘person_with_name(char *name)’ oder +‘person_with_details(char *name, …)’ nennen. +Nicht jedoch ‘person1(char *name)’.

        @@ -181,10 +181,10 @@

        Ruby Code

        • -

          Methoden: Versuche deine Methoden kurz zu halten–eine Bildschirmlänge +

          Methoden: Versuche deine Methoden kurz zu halten–eine Bildschirmlänge als Anhaltspunkt und verwende DRY in sinnvollem Maße. Üblicherweise sollten häufig verwendete Funktionen abstrahiert und in Helfer-Methoden -gepackt werden (die dann auch ‘private’ sein können). In manchen Fällen +gepackt werden (die dann auch ‘private’ sein können). In manchen Fällen macht es keinen Sinn sich an DRY zu halten, z.B. wenn es um die Core Klassen geht. In diesen Fällen macht DRY alles nur unnötig kompliziert und man muss auf zu viele Spezialfälle in der Fehlerbehandlung eingehen.

          @@ -192,7 +192,7 @@

          Ruby Code

        • Methodennamen sollten eindeutig, ausdrucksvoll, verständlich (und damit auf Englisch) sein. Verwende, bis auf wenige Ausnahmen, keine -Unterstriche, um Methoden zu schützen (‘__send__’).

          +Unterstriche, um Methoden zu schützen (‘__send__’).

        • Smalltalkartige Methodennamen sind ok, d.h. du kannst Methoden mit @@ -204,11 +204,11 @@

          Ruby Code

        • Variablennamen: Wähle eindeutige und ausdrucksstarke Namen (zu den üblichen Ausnahmen gehören z.B. Zählervariablen wie i). Vermeide es Methodennamen -für Variablen zu verwenden. Üblich sind ‘klass’ an Stelle von ‘class’ oder -‘idx’ innerhalb von Arrays, da ‘index’ bereits als Methodenname existiert.

          +für Variablen zu verwenden. Üblich sind ‘klass’ an Stelle von ‘class’ oder +‘idx’ innerhalb von Arrays, da ‘index’ bereits als Methodenname existiert.

        • -

          Verwende nachgefügte ‘if’ und ‘unless’ nur wenn deine Ausdrücke in eine +

          Verwende nachgefügte ‘if’ und ‘unless’ nur wenn deine Ausdrücke in eine Zeile passen und es nicht zu viele Bedingungen gibt.

        • diff --git a/web/_site/doc/de/getting-started/running-rubinius/index.html b/web/_site/doc/de/getting-started/running-rubinius/index.html index 65b228b807..6dfe2aa4b4 100644 --- a/web/_site/doc/de/getting-started/running-rubinius/index.html +++ b/web/_site/doc/de/getting-started/running-rubinius/index.html @@ -150,7 +150,7 @@

          Rubinius ausführen

          rbx -e 'puts "Hello!"'
           
          -

          Um eine Ruby Datei ‘code.rb’ auszuführen:

          +

          Um eine Ruby Datei ‘code.rb’ auszuführen:

          rbx code.rb
           
          diff --git a/web/_site/doc/de/how-to/fix-a-failing-spec/index.html b/web/_site/doc/de/how-to/fix-a-failing-spec/index.html index b9776f1aca..e357567159 100644 --- a/web/_site/doc/de/how-to/fix-a-failing-spec/index.html +++ b/web/_site/doc/de/how-to/fix-a-failing-spec/index.html @@ -168,7 +168,7 @@

          Anleitung - Einen fehlgeschlagenen Spec reparieren

          Rubinius Quellcode gemacht wurden.
        • Rufe git format-patch origin auf, wodurch alle Commiteinträge, die im aktuellen Zweig seit dem letzten Pull von origin gemacht wurden, -extrahiert werden. Alternativ, rufe `git format-patch -N’ auf, wobei N +extrahiert werden. Alternativ, rufe `git format-patch -N’ auf, wobei N die Zahl der Commiteinträge ist (1, 2 etc.), für die du Patches erstellen willst.
        • Erstelle ein Gist (auf http://gist.github.com) mit deinem Patch und diff --git a/web/_site/doc/de/how-to/write-a-ticket/index.html b/web/_site/doc/de/how-to/write-a-ticket/index.html index 5d5fc497de..61434d4a92 100644 --- a/web/_site/doc/de/how-to/write-a-ticket/index.html +++ b/web/_site/doc/de/how-to/write-a-ticket/index.html @@ -183,8 +183,8 @@

          Genereller Ablauf zur Er

          Doppelte Überprüfung.

            -
          1. Kompiliere Rubinius komplett neu (‘rake clean; rake’) nachdem du -‘git pull’ ausgeführt hast oder einen frischen Klon des Repositories +
          2. Kompiliere Rubinius komplett neu (‘rake clean; rake’) nachdem du +‘git pull’ ausgeführt hast oder einen frischen Klon des Repositories erstellt hast.
          3. Lies Problemlösungen, um zu sehen, ob eine der dortigen Anleitungen das Problem beheben kann.
          4. @@ -204,7 +204,7 @@

            Genereller Ablauf zur Er
          5. Der Kommandozeilenbefehl, um das Programm auszuführen.
          6. Der Backtrace oder das Ergebnis entgegen dem erwarteten Ergebnis.
          7. Informationen über deinen Rechner und System. uname -a ist -normalerweise gut (falls es irgengwelche “unknown” Felder +normalerweise gut (falls es irgengwelche “unknown” Felder gibt, erkläre/beschreibe diese bitte.)

      3. @@ -216,9 +216,9 @@

        Zusätzliche
      4. Einfach nur ein paar Specs.
      5. Patches müssen zusätzlich mit Specs versehen sein, es sei denn die Specs existieren bereits.
      6. -
      7. Relevante Teile der Spec Ausgabe und der exakte ‘bin/mspec’ Aufruf von dem +
      8. Relevante Teile der Spec Ausgabe und der exakte ‘bin/mspec’ Aufruf von dem existierenden oder hinzugefügten Spec vor der Veränderung.
      9. -
      10. Die Spec Ausgabe und der exakte ‘bin/mspec’ Aufruf, bei dem ein +
      11. Die Spec Ausgabe und der exakte ‘bin/mspec’ Aufruf, bei dem ein erfolgreicher Durchlauf nach der Veränderung zu sehen ist.
      12. Zusätzliche Beschreibungen/Kommentare deines Patches und wie er das Problem löst. Insbesondere dann, wenn neue Features hinzugefügt wurden, @@ -227,9 +227,9 @@

        Zusätzliche

        Abgesehen von Fällen, bei denen es aus irgendwelchen Gründen unmöglich ist, -sollte ‘git-format-patch’ benutzt werden, um den Patch zu erstellen. Das macht +sollte ‘git-format-patch’ benutzt werden, um den Patch zu erstellen. Das macht das Einbringen des Patches wesentlich einfacher und er erhält die korrekte -Zuordnung. Ansonsten sollte ein ‘unified diff’ verwendet werden.

        +Zuordnung. Ansonsten sollte ein ‘unified diff’ verwendet werden.

        Beispiel für das Einreichen eines Patches

        @@ -246,17 +246,17 @@

        Beispiel für das Einreichen e
      13. Ticket Titel:

        -

        “[PATCH] No method ‘format’ on Kernel (Module)”

        +

        “[PATCH] No method ‘format’ on Kernel (Module)”

      14. Tags:

        -

        “patch core spec”

        +

        “patch core spec”

      15. Ticket Nachricht (natürlich auf Englisch)

        -

        The method ‘format’ is not available as a module function of Kernel.

        +

        The method ‘format’ is not available as a module function of Kernel.

        $ bin/mspec spec/ruby/core/kernel/format_spec.rb
         Started
        @@ -267,7 +267,7 @@ 

        Beispiel für das Einreichen e No method 'format' on Kernel (Module):

        -

        The method ‘format’ already exists but has not been set as a module +

        The method ‘format’ already exists but has not been set as a module function. This patch does so.

        After the patch is applied:

        diff --git a/web/_site/doc/de/ruby/index.html b/web/_site/doc/de/ruby/index.html index ccd0a288ec..e881b10554 100644 --- a/web/_site/doc/de/ruby/index.html +++ b/web/_site/doc/de/ruby/index.html @@ -180,8 +180,8 @@

        Ruby

        Es wird oft gesagt, dass in Ruby alles ein Objekt sei. Das ist nicht ganz zutreffend. Fast alles ist ein Objekt. Einige Dinge die absolut notwendig sind, um Ruby Code laufen zu lassen, sind nicht notwendigerweise -Objekte, an die du herankommst. Deswegen hängt es in der “ausführenden -Umgebung” stark von der Implementation ab, welche Dinge tatsächlich Objekte +Objekte, an die du herankommst. Deswegen hängt es in der “ausführenden +Umgebung” stark von der Implementation ab, welche Dinge tatsächlich Objekte sind. Der Gültigkeitsbereich ist eines davon.

        Im Wesentlichen ist der Gültigkeitsbereich eine Idee im Kontext von Antworten diff --git a/web/_site/doc/de/specs/index.html b/web/_site/doc/de/specs/index.html index acacc2c8b4..f04ee52207 100644 --- a/web/_site/doc/de/specs/index.html +++ b/web/_site/doc/de/specs/index.html @@ -140,13 +140,13 @@

        Specs

        Im Allgemeinen verwendet das Rubinius Projekt einen TDD/BDD bezogenen Stil, um -die weitere Entwicklung voranzubringen. Das Rubinius ‘spec’ Verzeichnis ist +die weitere Entwicklung voranzubringen. Das Rubinius ‘spec’ Verzeichnis ist konzeptuell in zwei Teile aufgeteilt:

          -
        1. Alle Dateien, die sich im Verzeichnis ‘./spec/ruby’ befinden, beschreiben +
        2. Alle Dateien, die sich im Verzeichnis ‘./spec/ruby’ befinden, beschreiben das Verhalten von MatzRuby.
        3. -
        4. Und alle anderen Dateien, die sich im ‘./spec’ Verzeichnis befinden, +
        5. Und alle anderen Dateien, die sich im ‘./spec’ Verzeichnis befinden, beschreiben das Verhalten von Rubinius.
        diff --git a/web/_site/doc/de/tools/profiler/index.html b/web/_site/doc/de/tools/profiler/index.html index aac63f2d05..b427962e8a 100644 --- a/web/_site/doc/de/tools/profiler/index.html +++ b/web/_site/doc/de/tools/profiler/index.html @@ -213,7 +213,7 @@

        Ruby-Profiler

        Die #profile-Methode startet den Profiler, macht ein yield, hält den Profiler an -und druckt die Profiler-Daten aus. Wird ‘false’ als Argument an #profile +und druckt die Profiler-Daten aus. Wird ‘false’ als Argument an #profile weitergegeben, dann druckt es die Daten nicht aus. Nichtsdestotrotz werden die Profiler-Daten als Rückgabewert von #profile zurückgegeben.

        @@ -277,7 +277,7 @@

        Beispiel einer Flat-Ausgabe

        } -

        Führt man das Skript mit ‘bin/rbx script.rb’ aus, sollte folgende Tabelle +

        Führt man das Skript mit ‘bin/rbx script.rb’ aus, sollte folgende Tabelle ausgegeben werden:

          %   cumulative   self                self     total
        @@ -305,7 +305,7 @@ 

        Wie man die Graphen-Ausgabe auslie

        Mit dem vorhin genannten Skript wird der unten angegebene Graph ausgegeben. -Jeder “Eintrag” im Graphen hat drei Abschnitte: 1) Die Methode für den Eintrag, +Jeder “Eintrag” im Graphen hat drei Abschnitte: 1) Die Methode für den Eintrag, genannt Primärzeile; 2) die Aufrufer der Primärmethode; und 3) die Methoden, die die Primärmethode selber aufrief. Die Felder haben unterschiedliche Bedeutungen in Bezug auf den Ort ihres Eintrags.

        @@ -396,7 +396,7 @@

        name

        Der Name der aufgerufenen Methode gefolgt von ihrem Index [N]. Ist kein Index vorhanden, dann gibt es für diese Methode auch keinen Primäreintrag im Graphen. -Um auch solche Methoden anzeigen zu lassen, wird die ‘-Xprofiler.full_report’ +Um auch solche Methoden anzeigen zu lassen, wird die ‘-Xprofiler.full_report’ Option verwendet, die den vollständigen Graphen generiert.

        index  % time     self  children         called       name
        diff --git a/web/_site/doc/de/virtual-machine/instructions/index.html b/web/_site/doc/de/virtual-machine/instructions/index.html
        index bf2a0c2dbf..47c4f270fe 100644
        --- a/web/_site/doc/de/virtual-machine/instructions/index.html
        +++ b/web/_site/doc/de/virtual-machine/instructions/index.html
        @@ -256,7 +256,7 @@ 

        Notes

        Unlike other literals such as strings and numbers, creating a Regexp literal (i.e. via the /regex/ syntax) is a two step process to create the literal slot for the Regexp, create a literal for the string between the - ‘/’ delimiters and create a new Regexp object passing it the string. Only + ‘/’ delimiters and create a new Regexp object passing it the string. Only then can the literal value be set, using the set_literal opcode.

        push_literal(literal)

        @@ -754,7 +754,7 @@

        pop_unwind()

        Remove the next unused unwind registration from the current invocation. This instruction is paired with setup_unwind to remove registrations - when control exits a section of code that registered a handler but didn’t + when control exits a section of code that registered a handler but didn’t use it. For example, exiting a begin that had a rescue expression.

        @@ -1351,7 +1351,7 @@

        cast_for_multi_block_ the arg is an array.

        If the Proc invoked from was in lambda mode, and one argument is passed: - * and it’s an Array, push it. + * and it’s an Array, push it. * and it responds to #to_ary, try and convert it and push it. * otherwise wrap it in a one element Array and push it.

        @@ -1637,7 +1637,7 @@

        Notes

        runtime to determine which code path is executed.

        For example, a method such as Fixnum#times can be optimised at compile - time, but we can’t know until runtime whether or not the Fixnum#times + time, but we can’t know until runtime whether or not the Fixnum#times method has been overridden. The serial number check is used to determine each time the code is executed, whether or not the standard Fixnum#times has been overridden. It leverages the serial number field on a @@ -1646,7 +1646,7 @@

        Notes

        check_serial_private(literal, serial)

        -

        Checks if the specified method’s serial number matches an expected value. +

        Checks if the specified method’s serial number matches an expected value. Considers private methods too.

        @@ -1934,7 +1934,7 @@

        meta_send_op_tequal(litera

        Notes

        -

        Exactly like equal, except calls #=== if it can’t handle it directly.

        +

        Exactly like equal, except calls #=== if it can’t handle it directly.

        meta_send_call(literal, count)

        @@ -2225,7 +2225,7 @@

        call_custom(literal, count)

        meta_to_s(literal)

        -

        Pop a value off the stack and if it’s not a String, call a method +

        Pop a value off the stack and if it’s not a String, call a method indicated by literal on it. Push the resulting object back on the stack.

        diff --git a/web/_site/doc/en/appendix-a-glossary/index.html b/web/_site/doc/en/appendix-a-glossary/index.html index 3fd1067269..8d16f6be7b 100644 --- a/web/_site/doc/en/appendix-a-glossary/index.html +++ b/web/_site/doc/en/appendix-a-glossary/index.html @@ -149,9 +149,9 @@

        Appendix A - Glossary

        Definitions of terms and phrases used in the Ruby programming language and in -this implementation. See also “The Ruby Programming Language” by Flanagan and -Matsumoto [O’Reilly 2008] and “Programming Ruby: The Pragmatic Programmer’s -Guide” 2nd or 3rd Edition by Thomas et al [The Pragmatic Programmers +this implementation. See also “The Ruby Programming Language” by Flanagan and +Matsumoto [O’Reilly 2008] and “Programming Ruby: The Pragmatic Programmer’s +Guide” 2nd or 3rd Edition by Thomas et al [The Pragmatic Programmers 2005-2008]

          @@ -160,7 +160,7 @@

          Appendix A - Glossary

          The rule is simple: Take the object located in the class slot of the object (which is not always the return value of Object#class; if the object has one, -it’ll be the singleton class) and begin searching.

          +it’ll be the singleton class) and begin searching.

          Searching goes up the superclass chain until the superclass is nil.

          @@ -219,7 +219,7 @@

          Appendix A - Glossary

          1. -

            Resolve method ‘wanker’ – search method_tables in:

            +

            Resolve method ‘wanker’ – search method_tables in:

            1. SingletonClass(F)
            2. @@ -237,7 +237,7 @@

              Appendix A - Glossary

              A data structure in every class (and module) that contains the methods defined for that class.

              -

              In Rubinius, a class’s method_table is an instance of LookupTable.

              +

              In Rubinius, a class’s method_table is an instance of LookupTable.

            3. MatzRuby

              @@ -247,7 +247,7 @@

              Appendix A - Glossary

            4. MRI

              -

              Matz’s Ruby Interpreter or Matz’s Ruby Implementation. A short name to refer +

              Matz’s Ruby Interpreter or Matz’s Ruby Implementation. A short name to refer to the official implementation of Ruby. See http://ruby-lang.org.

            5. @@ -296,8 +296,8 @@

              Appendix A - Glossary

        Since all classes in Ruby are also objects, they can have singleton classes. -The methods called “class methods” are just methods in the method_table of -the class’s singleton class. The method +honk+ exists in the singleton class +The methods called “class methods” are just methods in the method_table of +the class’s singleton class. The method +honk+ exists in the singleton class for the class +Car+.

        class Car
        @@ -309,7 +309,7 @@ 

        Appendix A - Glossary

        In Rubinius, singleton classes are all instances of the class SingletonClass. The singleton class for an object can be obtained by calling the +singleton_class+ method. The overall arrangement of concepts involved -here is sometimes referred to as the ‘Meta-Object Protocol’ or +MOP+.

        +here is sometimes referred to as the ‘Meta-Object Protocol’ or +MOP+.

      16. superclass

        diff --git a/web/_site/doc/en/appendix-b-reading-list/index.html b/web/_site/doc/en/appendix-b-reading-list/index.html index 9035662042..a87517c188 100644 --- a/web/_site/doc/en/appendix-b-reading-list/index.html +++ b/web/_site/doc/en/appendix-b-reading-list/index.html @@ -149,9 +149,9 @@

        Appendix B - Reading List

        Building virtual machines in general and programming language implementations -in particular requires some knowledge. Rubinius’ goal is to lower the barrier +in particular requires some knowledge. Rubinius’ goal is to lower the barrier by keeping as much as possible in Ruby but to hack on the garbage collector you -have to understand what’s going on behind the curtains.

        +have to understand what’s going on behind the curtains.

        This page contains references to books, online lectures, blog posts and any other publications you may find useful for working on Rubinius.

        @@ -162,7 +162,7 @@

        Virtual machine

        • Smalltalk-80: language and its implementation -by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation +by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation chapters from part IV are available online
        • Virtual machines by Iain D. Craig
        • Great posts by Adam Gardiner: introduction, @@ -191,7 +191,7 @@

          FFI

          diff --git a/web/_site/doc/en/build-system/index.html b/web/_site/doc/en/build-system/index.html index 5afd128abe..549fc05ab2 100644 --- a/web/_site/doc/en/build-system/index.html +++ b/web/_site/doc/en/build-system/index.html @@ -177,7 +177,7 @@

          Development versus Install Builds

          not function, even if the executable is in the directory. The executable checks a single, hard-coded path. If this ends up being very painful for some reason, -we’ll revise it.

          +we’ll revise it.

          Installing Rubinius

          @@ -186,11 +186,11 @@

          Installing Rubinius

          ./configure --prefix=/path/to/install/dir
           
          -

          The configure process creates a ‘config.rb’ file that specifies the key file -paths that Rubinius uses. Once configured, run ‘rake install’ to build and +

          The configure process creates a ‘config.rb’ file that specifies the key file +paths that Rubinius uses. Once configured, run ‘rake install’ to build and install. The install procedure builds all the files, including compiling the Ruby standard library files in the lib/ directory, then copies them into the -install location using the ‘install’ program. The install tasks are located in +install location using the ‘install’ program. The install tasks are located in rakelib/install.rake.

          diff --git a/web/_site/doc/en/bytecode-compiler/ast/index.html b/web/_site/doc/en/bytecode-compiler/ast/index.html index f63e0f8c97..96467f8679 100644 --- a/web/_site/doc/en/bytecode-compiler/ast/index.html +++ b/web/_site/doc/en/bytecode-compiler/ast/index.html @@ -201,7 +201,7 @@

          Abstract Syntax Trees

          @line: 1
          -

          Similarily it’s possible to get a representation of the syntax tree as +

          Similarily it’s possible to get a representation of the syntax tree as s-expressions:

          irb(main):002:0> "a = 1".to_sexp
          @@ -219,7 +219,7 @@ 

          Abstract Syntax Trees

          containing Define in its @body which in turns contains FormalArguments in its @arguments and Block in its @body. The Block node contains only the NilLiteral in its @array. The -NilLiteral node is a leaf node, it doesn’t contain other nodes.

          +NilLiteral node is a leaf node, it doesn’t contain other nodes.

          Note that the following if expression:

          @@ -233,9 +233,9 @@

          Abstract Syntax Trees

          [:script, [:if, [:lit, :bar], [:lit, :foo], nil]]
          -

          produce exactly the same syntax tree. Because the tree doesn’t +

          produce exactly the same syntax tree. Because the tree doesn’t represent every detail that appears in the real syntax it is called -“abstract”.

          +“abstract”.

          Files Referenced

          diff --git a/web/_site/doc/en/bytecode-compiler/generator/index.html b/web/_site/doc/en/bytecode-compiler/generator/index.html index e4499cce2c..64b1fa64ae 100644 --- a/web/_site/doc/en/bytecode-compiler/generator/index.html +++ b/web/_site/doc/en/bytecode-compiler/generator/index.html @@ -187,7 +187,7 @@

          Generator Stage

          When generating the bytecode for an AST, Rubinius invokes the method bytecode on each AST node, passing in the current Generator -instance. Here’s the bytecode method for the if node:

          +instance. Here’s the bytecode method for the if node:

          def bytecode(g)
             pos(g)
          diff --git a/web/_site/doc/en/bytecode-compiler/parser/index.html b/web/_site/doc/en/bytecode-compiler/parser/index.html
          index b6ecab16a7..841517b296 100644
          --- a/web/_site/doc/en/bytecode-compiler/parser/index.html
          +++ b/web/_site/doc/en/bytecode-compiler/parser/index.html
          @@ -153,7 +153,7 @@ 

          Ruby Parser

          the next stage of the process, the generator.

          The parser itself (called Melbourne) has a C part, which is essentially -MRI’s parser, and a Ruby part, which is responsible for creating the Ruby +MRI’s parser, and a Ruby part, which is responsible for creating the Ruby AST. The C parser communicates with Ruby by calling a method for each node in the parse tree.

          diff --git a/web/_site/doc/en/bytecode-compiler/transformations/index.html b/web/_site/doc/en/bytecode-compiler/transformations/index.html index 4ff4306843..7eb8e854f7 100644 --- a/web/_site/doc/en/bytecode-compiler/transformations/index.html +++ b/web/_site/doc/en/bytecode-compiler/transformations/index.html @@ -166,7 +166,7 @@

          Safe Math Compiler Transform

          one of its cherished features but it is also truly a double-edged sword in some respects.

          -

          In the standard library the ‘mathn’ library redefines Fixnum#/ in an unsafe +

          In the standard library the ‘mathn’ library redefines Fixnum#/ in an unsafe and incompatible manner. The library aliases Fixnum#/ to Fixnum#quo, which returns a Float by default.

          @@ -176,7 +176,7 @@

          Safe Math Compiler Transform

          define this method.

          The safe math transform is enabled during the compilation of the Core -libraries to enable the plugin. During regular ‘user code’ compilation, the +libraries to enable the plugin. During regular ‘user code’ compilation, the plugin is not enabled. This enables us to support mathn without breaking the core libraries or forcing inconvenient practices.

          diff --git a/web/_site/doc/en/contributing/index.html b/web/_site/doc/en/contributing/index.html index 384b60e7bd..f9718787f1 100644 --- a/web/_site/doc/en/contributing/index.html +++ b/web/_site/doc/en/contributing/index.html @@ -172,7 +172,7 @@

          Write Specs

          tagged as incomplete. These specs may simply need review, or there could be specs missing for a particular class.

          -

          NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will +

          NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will show tags for all the specs that should run on Rubinius. Or you can specify any subdirectory of the spec/ directory to list tags for specs in that subdirectory.

          @@ -189,7 +189,7 @@

          Fix Failing Specs

        • Run bin/mspec tag --list fails <dir> to show specs tagged as failing.

          -

          NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will +

          NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will show tags for all the specs that should run on Rubinius. Or you can specify any subdirectory of the spec/ directory to list tags for specs in that subdirectory.

          diff --git a/web/_site/doc/en/contributing/style-guide/index.html b/web/_site/doc/en/contributing/style-guide/index.html index 8d49c31461..c071df5dfc 100644 --- a/web/_site/doc/en/contributing/style-guide/index.html +++ b/web/_site/doc/en/contributing/style-guide/index.html @@ -170,10 +170,10 @@

          C++ Code

        • Alternate versions of functions should be named why they are different -from the primary. If there is a function ‘person()’ and you want a +from the primary. If there is a function ‘person()’ and you want a version that takes the name of the person, it should be -‘person_with_name(char *name)’ or ‘person_with_details(char *name, …)’. -NOT ‘person1(char *name)’.

          +‘person_with_name(char *name)’ or ‘person_with_details(char *name, …)’. +NOT ‘person1(char *name)’.

        @@ -181,16 +181,16 @@

        Ruby Code

        • -

          Methods: Try to keep your methods short–one screenful and try to adhere +

          Methods: Try to keep your methods short–one screenful and try to adhere to DRY within reason. Generally common functionality should be abstracted -to helper methods (which you can make ‘private’) but in some cases, +to helper methods (which you can make ‘private’) but in some cases, particularly working with Core, sometimes trying to DRY things up is just an obstacle if you have to maneuver around several different error conditions, for example.

        • Method names: should be clear, expressive and meaningful. Avoid using -underscores to ‘protect’ the method (‘__send__’) with some exceptions.

          +underscores to ‘protect’ the method (‘__send__’) with some exceptions.

        • Smalltalk-style method names are OK, meaning that you could have a method @@ -201,8 +201,8 @@

          Ruby Code

        • Variable names: make them clear and meaningful (with some well-known -exceptions like using ‘i’ for a counter.) Try to avoid shadowing method -names, for example within Array use ‘idx’ in favour of ‘index’ because the +exceptions like using ‘i’ for a counter.) Try to avoid shadowing method +names, for example within Array use ‘idx’ in favour of ‘index’ because the latter is also a method name.

        • diff --git a/web/_site/doc/en/garbage-collector/mature-generation/index.html b/web/_site/doc/en/garbage-collector/mature-generation/index.html index 678ab186eb..184fd10848 100644 --- a/web/_site/doc/en/garbage-collector/mature-generation/index.html +++ b/web/_site/doc/en/garbage-collector/mature-generation/index.html @@ -149,7 +149,7 @@

          Mature Generation

          Mature objects are objects that have been promoted from the Young -generation after living past the promotion threshold ‘X’.

          +generation after living past the promotion threshold ‘X’.

          Autotune is the mechanism that is used to dynamic adjust the GC cycles before mature collection occurrs. This can be turned off or a static number may be used diff --git a/web/_site/doc/en/garbage-collector/nursery/index.html b/web/_site/doc/en/garbage-collector/nursery/index.html index fa915885f7..7d5637a90a 100644 --- a/web/_site/doc/en/garbage-collector/nursery/index.html +++ b/web/_site/doc/en/garbage-collector/nursery/index.html @@ -148,8 +148,8 @@

          Nursery

          -

          The first generation in Rubinius’s generational GC is the nursery. -An object’s lifcycle begins in the nursery where it is created (allocated).

          +

          The first generation in Rubinius’s generational GC is the nursery. +An object’s lifcycle begins in the nursery where it is created (allocated).

          Objects live in the nursery until the very next collection. If an object is still alive after one GC cycle then it is moved to the Young generation. diff --git a/web/_site/doc/en/getting-started/requirements/index.html b/web/_site/doc/en/getting-started/requirements/index.html index 0d6b9333dd..92daa0c224 100644 --- a/web/_site/doc/en/getting-started/requirements/index.html +++ b/web/_site/doc/en/getting-started/requirements/index.html @@ -178,7 +178,7 @@

          Debian/Ubuntu

          FreeBSD

          -

          Rubinius has a port in FreeBSD ports tree. It’s called lang/rubinius. You +

          Rubinius has a port in FreeBSD ports tree. It’s called lang/rubinius. You can find information about this port on http://freshports.org. Once being installed the port installs all the dependencies automagically.

          diff --git a/web/_site/doc/en/getting-started/running-rubinius/index.html b/web/_site/doc/en/getting-started/running-rubinius/index.html index 9e88ed96cb..8b01e79ae0 100644 --- a/web/_site/doc/en/getting-started/running-rubinius/index.html +++ b/web/_site/doc/en/getting-started/running-rubinius/index.html @@ -150,7 +150,7 @@

          Running Rubinius

          rbx -e 'puts "Hello!"'
           
          -

          To run a ruby file named ‘code.rb’:

          +

          To run a ruby file named ‘code.rb’:

          rbx code.rb
           
          diff --git a/web/_site/doc/en/how-to/commit-to-github/index.html b/web/_site/doc/en/how-to/commit-to-github/index.html index 2083580423..7dc1b959fe 100644 --- a/web/_site/doc/en/how-to/commit-to-github/index.html +++ b/web/_site/doc/en/how-to/commit-to-github/index.html @@ -140,7 +140,7 @@

          How-To - Commit Changes to Github

          The Rubinius Project does a majority of its work on the master -branch. The goal is to keep master “clean” so that it always builds +branch. The goal is to keep master “clean” so that it always builds a working binary and provides a snapshot of the latest fixes and enhancements.

          @@ -153,7 +153,7 @@

          Committers With behavior under construction while the second commit adds the behavior and allows the spec to pass.

          -

          After committing to the local repository’s branch, the commit +

          After committing to the local repository’s branch, the commit should be merged back to master and pushed to github. To avoid superfluous git merge messages, we ask that the committer first rebase the master branch prior to the merge.

          @@ -168,7 +168,7 @@

          Committers With
        • git add <list of code files>
        • git commit
        • git checkout master
        • -
        • git pull –rebase
        • +
        • git pull –rebase
        • git checkout name-of-fix-branch
        • git rebase master
        • git checkout master
        • diff --git a/web/_site/doc/en/how-to/fix-a-failing-spec/index.html b/web/_site/doc/en/how-to/fix-a-failing-spec/index.html index 86fdf8e5fe..dafc4e09c2 100644 --- a/web/_site/doc/en/how-to/fix-a-failing-spec/index.html +++ b/web/_site/doc/en/how-to/fix-a-failing-spec/index.html @@ -158,8 +158,8 @@

          How-To - Fix a Failing Spec

        • Run rake build to build your change.
        • Run bin/mspec spec/some/spec_file.rb to see if your change makes the spec pass. -Add a “-txVERSION” argument at the end if you’d want to tackle Ruby VERSION. -For example: “-tx19” for Ruby 1.9.
        • +Add a “-txVERSION” argument at the end if you’d want to tackle Ruby VERSION. +For example: “-tx19” for Ruby 1.9.
        • Repeat until your spec passes.
        • Run rake to ensure there are no regressions.
        • Change directory to Rubinius root if not already there.
        • @@ -168,13 +168,13 @@

          How-To - Fix a Failing Spec

          changes made to other Rubinius source code files.
        • Push your new branch to Github.
        • Issue a Pull Request. -To do this, go to your fork on GitHub, change to your new branch and click “Pull Request”. -Next, write a description of your change if required and click “Send pull request”.
        • +To do this, go to your fork on GitHub, change to your new branch and click “Pull Request”. +Next, write a description of your change if required and click “Send pull request”.
        • More commits and discussion may happen with other contributors using the Pull Request interface.
      -

      When your patch is accepted by the Rubinius project, you’ll get a commit bit +

      When your patch is accepted by the Rubinius project, you’ll get a commit bit for the Rubinius repository. Let Evan know what your Github username is.

      diff --git a/web/_site/doc/en/how-to/translate-documentation/index.html b/web/_site/doc/en/how-to/translate-documentation/index.html index b379432e60..8f340f10e6 100644 --- a/web/_site/doc/en/how-to/translate-documentation/index.html +++ b/web/_site/doc/en/how-to/translate-documentation/index.html @@ -172,10 +172,10 @@

      Creating a New Translation

    226. Add a corresponding value to TRANS array in rakelib/web.rake(see below).
    -

    Translator’s Tool

    +

    Translator’s Tool

    -

    We’ve made some tiny tools to aid translators. Technically, there’s only one -such tool yet. It’s Translator Consistency Checker.

    +

    We’ve made some tiny tools to aid translators. Technically, there’s only one +such tool yet. It’s Translator Consistency Checker.

    Short Synopsis

    @@ -215,8 +215,8 @@

    Short Synopsis

    Explanation

    -

    web:translations:check rake task recursively checks “Leader” docs version (which is -now web/doc/en subtree) against the list of translated “followers”. Both +

    web:translations:check rake task recursively checks “Leader” docs version (which is +now web/doc/en subtree) against the list of translated “followers”. Both leader and translations list are defined in rakelib/web.rake:

    # This is the 'leader' version: all is translated from here.
    @@ -235,16 +235,16 @@ 

    Explanation

    For each Leader file the script checks whether the corresponding translation -file exist and has mtime younger (less) than the Leader’s. If translation is -older than the original Leader file or doesn’t exist you’ll see that very nice -annoying message as shown in the example. If all files are OK you’ll see and recognize +file exist and has mtime younger (less) than the Leader’s. If translation is +older than the original Leader file or doesn’t exist you’ll see that very nice +annoying message as shown in the example. If all files are OK you’ll see and recognize that.

    Conclusion

    This mega duper tiny stupid tool was written to help the translator to -understand which files might obviously need alteration. No more. There’s no -intellectual analysis like translation validity check, etc. — at all. If you +understand which files might obviously need alteration. No more. There’s no +intellectual analysis like translation validity check, etc. — at all. If you are the smartest Rubinius contributor ever you are welcome to expand this tool thus helping the society and saving the world!

    diff --git a/web/_site/doc/en/how-to/write-a-ticket/index.html b/web/_site/doc/en/how-to/write-a-ticket/index.html index b6d1ba67a0..85106c08fb 100644 --- a/web/_site/doc/en/how-to/write-a-ticket/index.html +++ b/web/_site/doc/en/how-to/write-a-ticket/index.html @@ -154,7 +154,7 @@

    How-To - Write a Ticket

    the spec runs before and after applying the patch. -

    If your issue doesn’t fit into one of the categories, it is not invalid. It is +

    If your issue doesn’t fit into one of the categories, it is not invalid. It is simply not appropriate for a ticket.

      @@ -173,7 +173,7 @@

      General procedure for submitt

      Double-check.

        -
      1. Do a full rebuild (‘rake clean; rake’) after a ‘git pull’ or fresh clone.
      2. +
      3. Do a full rebuild (‘rake clean; rake’) after a ‘git pull’ or fresh clone.
      4. Read Troubleshooting to see if something there resolves the issue.
      5. Read Specs.
      6. @@ -192,7 +192,7 @@

        General procedure for submitt
      7. The command line for invoking the program
      8. The backtrace or result from the program versus expected result.
      9. Your machine information. uname -a is usually good (if there are any -“unknown” fields in it, please elaborate on those.)
      10. +“unknown” fields in it, please elaborate on those.)

      @@ -202,16 +202,16 @@

      Additional instruction
      • Can be just a set of specs.
      • Patches must be accompanied by specs unless the specs already exist.
      • -
      • Relevant part of spec output and the exact ‘bin/mspec’ invocation from the +
      • Relevant part of spec output and the exact ‘bin/mspec’ invocation from the existing or added spec before the fix.
      • -
      • The spec output and the exact ‘bin/mspec’ invocation showing success +
      • The spec output and the exact ‘bin/mspec’ invocation showing success after the fix.
      • Additional description of your patch and how it fixes the problem. In particular with new functionality please indicate if it was already discussed on #rubinius or ruby-dev.
      -

      Unless for some reason impossible, please use ‘git-format-patch’ to create the +

      Unless for some reason impossible, please use ‘git-format-patch’ to create the patchset. It is much easier to apply and it preserves the correct attribution. Otherwise, a unified diff.

      @@ -230,17 +230,17 @@

      Example of submitting a patch

    1. Ticket Title:

      -

      “[PATCH] No method ‘format’ on Kernel (Module)”

      +

      “[PATCH] No method ‘format’ on Kernel (Module)”

    2. Tags:

      -

      “patch core spec”

      +

      “patch core spec”

    3. Ticket Message:

      -

      The method ‘format’ is not available as a module function of Kernel.

      +

      The method ‘format’ is not available as a module function of Kernel.

      $ bin/mspec spec/ruby/core/kernel/format_spec.rb
       Started
      @@ -251,7 +251,7 @@ 

      Example of submitting a patch

      No method 'format' on Kernel (Module):
      -

      The method ‘format’ already exists but has not been set as a module +

      The method ‘format’ already exists but has not been set as a module function. This patch does so.

      After the patch is applied:

      diff --git a/web/_site/doc/en/how-to/write-benchmarks/index.html b/web/_site/doc/en/how-to/write-benchmarks/index.html index 78a6c362dd..a7e30b4a71 100644 --- a/web/_site/doc/en/how-to/write-benchmarks/index.html +++ b/web/_site/doc/en/how-to/write-benchmarks/index.html @@ -152,9 +152,9 @@

      How-To - Write Benchmarks

      example different ways of deleting keys/values from a Hash.
    4. Use the benchmark framework.
    5. Keep the benchmarks short and simple.
    6. -
    7. The benchmarks are not meant to measure Rubinius. So if you’re writing a +
    8. The benchmarks are not meant to measure Rubinius. So if you’re writing a benchmark for a class with bang and no-bang methods you will want to use -a duplicate of a variable in the bang method but you don’t need to dup +a duplicate of a variable in the bang method but you don’t need to dup in the no-bang method.
    diff --git a/web/_site/doc/en/ruby/index.html b/web/_site/doc/en/ruby/index.html index d9d1a13d6c..655f705ffe 100644 --- a/web/_site/doc/en/ruby/index.html +++ b/web/_site/doc/en/ruby/index.html @@ -176,7 +176,7 @@

    Ruby

    Often it is asserted that everything in Ruby is an object. This is not quite true. Most things in Ruby are objects, but some things that are absolutely essential for running Ruby code are not necessarily objects that you can put -your hands on. Instead, which of these “execution environment” things are +your hands on. Instead, which of these “execution environment” things are objects in Ruby depends heavily on the implementation. Scope is one of these things.

    diff --git a/web/_site/doc/en/specs/index.html b/web/_site/doc/en/specs/index.html index f71857bcab..d2b96f5d06 100644 --- a/web/_site/doc/en/specs/index.html +++ b/web/_site/doc/en/specs/index.html @@ -140,12 +140,12 @@

    Specs

    The Rubinius project generally uses TDD/BDD-style executable specifications to -drive development. The Rubinius ‘spec’ directory is conceptually divided into +drive development. The Rubinius ‘spec’ directory is conceptually divided into two parts:

      -
    1. All the files under ‘./spec/ruby’ that describe the behavior of MatzRuby.
    2. -
    3. And all the other files under the ‘./spec’ directory that describe the +
    4. All the files under ‘./spec/ruby’ that describe the behavior of MatzRuby.
    5. +
    6. And all the other files under the ‘./spec’ directory that describe the behavior of Rubinius.
    diff --git a/web/_site/doc/en/systems/concurrency/index.html b/web/_site/doc/en/systems/concurrency/index.html index 63ec812804..b97088991f 100644 --- a/web/_site/doc/en/systems/concurrency/index.html +++ b/web/_site/doc/en/systems/concurrency/index.html @@ -143,7 +143,7 @@

    Concurrency

    Fibers, along with a new API: Actors. Actors provide concurrency without any mutexes or locking inherent when sharing state between Threads.

    -

    Actors execute concurrently but don’t share state; instead they pass messages to +

    Actors execute concurrently but don’t share state; instead they pass messages to other actors. Here we create two actors using Actor.spawn, ping and pong, who will send messages back and forth until they have collaboratively incremented a variable to 1000:

    diff --git a/web/_site/doc/en/tools/memory-analysis/index.html b/web/_site/doc/en/tools/memory-analysis/index.html index 7d2ae0e59b..08f50fab46 100644 --- a/web/_site/doc/en/tools/memory-analysis/index.html +++ b/web/_site/doc/en/tools/memory-analysis/index.html @@ -212,7 +212,7 @@

    A Sample Program

    puts "received #{messages.size} messages in #{elapsed_usecs / 1_000_000} seconds"
    -

    Wow, this program leaks like a sieve. Let’s figure out why.

    +

    Wow, this program leaks like a sieve. Let’s figure out why.

    Saving A Heap Dump

    @@ -257,7 +257,7 @@

    Analyzing A Heap Dump

    Find the heap_dump tool at its project home page.

    This tool reads the heap dump file and outputs some useful information in 3 columns -corresponding to the number of objects visible in the heap, the object’s class, and +corresponding to the number of objects visible in the heap, the object’s class, and the total number of bytes consumed by all instances of this object.

    Running the tool against a heap dump captured from our leak.rb program, it gives us @@ -287,7 +287,7 @@

    Analyzing A Heap Dump

    The largest footprint is consumed by Rubinius::CompactLookupTable which is a class that the example code never directly instantiates and weighs in at about 20MB. So, some internal Rubinius structures are reported by the heap dump. It is -interesting but doesn’t help pinpoint our particular leak.

    +interesting but doesn’t help pinpoint our particular leak.

  • The ZMQ::Message class listed on line 3 is the first class shown that the example @@ -327,7 +327,7 @@

    Advanced Tools - OSX Only

    After modifying the Ruby code to use a simple counter and let the garbage collector handle all of the ZMQ::Message instances, the program is still leaking like mad. -Taking two snapshots and analyzing them doesn’t give any clue as to the source +Taking two snapshots and analyzing them doesn’t give any clue as to the source though.

    $ rbx -I /path/to/heap_dump/lib /path/to/heap_dump/bin/histo.rb heap3.dump heap4.dump
    @@ -385,7 +385,7 @@ 

    Advanced Tools - OSX Only

    The output shows that at the time of the snapshot we had nearly 172k leaked objects. The call stack output shows that the leak occurs during the call to zmq_msg_init_size -which doesn’t mean anything unless we dig into the implementation of ZMQ::Message`. +which doesn’t mean anything unless we dig into the implementation of ZMQ::Message`. This is where knowledge of the underlying system is critical; without knowing where this particular call is made, it would be much more difficult to track down the problem.

    diff --git a/web/_site/doc/en/tools/profiler/index.html b/web/_site/doc/en/tools/profiler/index.html index 489503f772..a34446a38c 100644 --- a/web/_site/doc/en/tools/profiler/index.html +++ b/web/_site/doc/en/tools/profiler/index.html @@ -154,7 +154,7 @@

    VM Profiler

    The Profiler lives and dies in its own world. The profiler is passed a VM instance when it is created because the profiler needs access to it while it is gathering info. The STATE argument could be passed into all the profiler -methods, but it’s simple enough to pass it in when the profiler is created. +methods, but it’s simple enough to pass it in when the profiler is created. The profiler never manipulates the VM instance. It is important to maintain this separation.

    @@ -210,7 +210,7 @@

    Ruby Profiler

    The #profile method starts the profiler, yields, stops the profiler and prints -the profile data by default. Pass ‘false’ to #profile to not print the data. +the profile data by default. Pass ‘false’ to #profile to not print the data. Either way, the profile data itself is returned by #profile.

    How to Read the Flat Profiler Output

    @@ -233,7 +233,7 @@

    cumulative seconds

    self seconds

    The total time spent in this method less the total time spent in all this -method’s callees.

    +method’s callees.

    calls

    @@ -272,7 +272,7 @@

    Example of Flat Output

    } -

    Running the script with ‘bin/rbx script.rb’ should give the following flat +

    Running the script with ‘bin/rbx script.rb’ should give the following flat output:

      %   cumulative   self                self     total
    @@ -299,7 +299,7 @@ 

    How to Read the Graph Output

    -Xprofiler.graph
     
    -

    Given the same script above, the graph output is shown below. Each “entry” in +

    Given the same script above, the graph output is shown below. Each “entry” in the graph has three sections: 1) the method for the entry, called the primary line; 2) the callers of the primary method; and 3) the methods that the primary method called. The fields have different meanings based on the @@ -320,7 +320,7 @@

    % time

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    @@ -335,16 +335,16 @@

    name

    The name of the method followed by the index number.

    The lines above the primary line are methods that call the primary method. The -callers’ fields have the following interpretation:

    +callers’ fields have the following interpretation:

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    -

    The time spent in the method’s call to the primary method.

    +

    The time spent in the method’s call to the primary method.

    called

    @@ -365,11 +365,11 @@

    name

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    -

    This is an estimate of the amount of time this method’s callees spent when +

    This is an estimate of the amount of time this method’s callees spent when this method was called by the primary method. The estimate is based on the ration of the time this method spent when called by the primary method to the total time spent in this method.

    @@ -384,7 +384,7 @@

    name

    The name of the called method followed by its index number [N]. If there is no index present, there is no primary entry for the method in the graph. Use the -‘-Xprofiler.full_report’ option to print the entire graph if you need to view +‘-Xprofiler.full_report’ option to print the entire graph if you need to view the entry:

    index  % time     self  children         called       name
    diff --git a/web/_site/doc/en/virtual-machine/instructions/index.html b/web/_site/doc/en/virtual-machine/instructions/index.html
    index 6d6018d726..f66ff8ed2c 100644
    --- a/web/_site/doc/en/virtual-machine/instructions/index.html
    +++ b/web/_site/doc/en/virtual-machine/instructions/index.html
    @@ -256,7 +256,7 @@ 

    Notes

    Unlike other literals such as strings and numbers, creating a Regexp literal (i.e. via the /regex/ syntax) is a two step process to create the literal slot for the Regexp, create a literal for the string between the - ‘/’ delimiters and create a new Regexp object passing it the string. Only + ‘/’ delimiters and create a new Regexp object passing it the string. Only then can the literal value be set, using the set_literal opcode.

    push_literal(literal)

    @@ -754,7 +754,7 @@

    pop_unwind()

    Remove the next unused unwind registration from the current invocation. This instruction is paired with setup_unwind to remove registrations - when control exits a section of code that registered a handler but didn’t + when control exits a section of code that registered a handler but didn’t use it. For example, exiting a begin that had a rescue expression.

    @@ -1351,7 +1351,7 @@

    cast_for_multi_block_ the arg is an array.

    If the Proc invoked from was in lambda mode, and one argument is passed: - * and it’s an Array, push it. + * and it’s an Array, push it. * and it responds to #to_ary, try and convert it and push it. * otherwise wrap it in a one element Array and push it.

    @@ -1637,7 +1637,7 @@

    Notes

    runtime to determine which code path is executed.

    For example, a method such as Fixnum#times can be optimised at compile - time, but we can’t know until runtime whether or not the Fixnum#times + time, but we can’t know until runtime whether or not the Fixnum#times method has been overridden. The serial number check is used to determine each time the code is executed, whether or not the standard Fixnum#times has been overridden. It leverages the serial number field on a @@ -1646,7 +1646,7 @@

    Notes

    check_serial_private(literal, serial)

    -

    Checks if the specified method’s serial number matches an expected value. +

    Checks if the specified method’s serial number matches an expected value. Considers private methods too.

    @@ -1934,7 +1934,7 @@

    meta_send_op_tequal(litera

    Notes

    -

    Exactly like equal, except calls #=== if it can’t handle it directly.

    +

    Exactly like equal, except calls #=== if it can’t handle it directly.

    meta_send_call(literal, count)

    @@ -2225,7 +2225,7 @@

    call_custom(literal, count)

    meta_to_s(literal)

    -

    Pop a value off the stack and if it’s not a String, call a method +

    Pop a value off the stack and if it’s not a String, call a method indicated by literal on it. Push the resulting object back on the stack.

    diff --git a/web/_site/doc/es/appendix-a-glossary/index.html b/web/_site/doc/es/appendix-a-glossary/index.html index 8bb4b7f87c..b75182df9a 100644 --- a/web/_site/doc/es/appendix-a-glossary/index.html +++ b/web/_site/doc/es/appendix-a-glossary/index.html @@ -140,8 +140,8 @@

    Apéndice A - Glosario

    Definición de términos y frases usadas en el lenguaje de programación Ruby y en -esta implementación. Vea también “The Ruby Programming Language” por Flanagan y -Matsumoto [O’Reilly 2008] y “Programming Ruby: The Pragmatic Programmer’s Guide” +esta implementación. Vea también “The Ruby Programming Language” por Flanagan y +Matsumoto [O’Reilly 2008] y “Programming Ruby: The Pragmatic Programmer’s Guide” segunda o tercera edición por Thomas et al [The Pragmatic Programmers 2005-2008].

      @@ -211,7 +211,7 @@

      Apéndice A - Glosario

      1. -

        Para la resolución del método ‘wanker’ se hace la búsqueda en las +

        Para la resolución del método ‘wanker’ se hace la búsqueda en las method_tables de:

          @@ -240,7 +240,7 @@

          Apéndice A - Glosario

        1. MRI

          -

          “Matz’s Ruby Interpreter” o “Matz’s Ruby Implementation”. Una abreviación +

          “Matz’s Ruby Interpreter” o “Matz’s Ruby Implementation”. Una abreviación para referirse a la implementación oficial de Ruby. Ver http://ruby-lang.org.

        2. @@ -304,7 +304,7 @@

          Apéndice A - Glosario

          Todas las singleton clases en Rubinius son instancias de la clase SingletonClass. La singleton clase para un objeto puede ser obtenida llamando al método +singleton_class+. Los conceptos mencionados aquí se -conocen como el ‘Meta-Object Protocol’ o +MOP+.

          +conocen como el ‘Meta-Object Protocol’ o +MOP+.

        3. superclass (superclase)

          diff --git a/web/_site/doc/es/appendix-b-reading-list/index.html b/web/_site/doc/es/appendix-b-reading-list/index.html index e968e43145..6346411963 100644 --- a/web/_site/doc/es/appendix-b-reading-list/index.html +++ b/web/_site/doc/es/appendix-b-reading-list/index.html @@ -173,7 +173,7 @@

          Virtual machine

          • Smalltalk-80: language and its implementation -by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation +by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation chapters from part IV are available online
          • Virtual machines by Iain D. Craig
          • Great posts by Adam Gardiner: introduction, @@ -202,7 +202,7 @@

            FFI

            diff --git a/web/_site/doc/es/build-system/index.html b/web/_site/doc/es/build-system/index.html index b2654ef038..50ba71a735 100644 --- a/web/_site/doc/es/build-system/index.html +++ b/web/_site/doc/es/build-system/index.html @@ -190,12 +190,12 @@

            Instalando Rubinius

            ./configure --prefix=/path/to/install/dir
             
            -

            El proceso de configuración crea un archivo ‘config.rb’ que especifica +

            El proceso de configuración crea un archivo ‘config.rb’ que especifica las rutas clave que utiliza Rubinius. Una vez configurado, ejecute -‘rake install’ para construir e instalar. El procedimiento de +‘rake install’ para construir e instalar. El procedimiento de instalación crea todos los archivos, incluyendo el núcleo de Ruby y los archivos de la biblioteca estándar en el directorio lib /, a continuación, los -copia en el ubicación de instalación mediante el programa ‘install’. +copia en el ubicación de instalación mediante el programa ‘install’. Las tareas de instalación se encuentran en rakelib/install.rake.

            diff --git a/web/_site/doc/es/bytecode-compiler/transformations/index.html b/web/_site/doc/es/bytecode-compiler/transformations/index.html index 0ddb948b6a..c26f9dce12 100644 --- a/web/_site/doc/es/bytecode-compiler/transformations/index.html +++ b/web/_site/doc/es/bytecode-compiler/transformations/index.html @@ -170,7 +170,7 @@

            Transformación de matemáticas seg es uno de sus rasgos más apreciados, pero también es una verdadera arma de doble filo en algunos aspectos.

            -

            En la biblioteca estándar, ‘mathn’ redefine Fixnum#/ de una manera +

            En la biblioteca estándar, ‘mathn’ redefine Fixnum#/ de una manera peligrosa e insegura. La biblioteca crea un alias de Fixnum#/ a Fixnum#quo, que regresa un Float de forma predeterminada.

            @@ -181,7 +181,7 @@

            Transformación de matemáticas seg

            Las transformaciones para matemáticas seguras estan habilitadas durante la compilación de las bibliotecas del núcleo. Durante la -compilación de ‘código de usuario’ regular, el plugin es +compilación de ‘código de usuario’ regular, el plugin es deshabilitado. Esto nos permite soportar mathn sin alterar las bibliotecas del núcleo o forzar a prácticas inconvenientes.

            diff --git a/web/_site/doc/es/contributing/index.html b/web/_site/doc/es/contributing/index.html index da05b35536..0ba5cc9358 100644 --- a/web/_site/doc/es/contributing/index.html +++ b/web/_site/doc/es/contributing/index.html @@ -173,7 +173,7 @@

            Escribir Especificaciones

            especificaciones pueden simplemente necesitar una revisión, o podría hacer falta especificaciones para alguna clase en particular.

            -

            NOTA: Se puede especificar el pseudo-directorio ‘:files’ para +

            NOTA: Se puede especificar el pseudo-directorio ‘:files’ para <dir>, lo que mostrará las etiquetas para todas las especificaciones que deben ejecutarse en Rubinius. O puede especificar cualquier subdirectorio de spec/ para listar las etiquetas de las especificaciones @@ -192,7 +192,7 @@

            Corregir una Especificación erronea

            Ejecute bin/mspec tag --list fails <dir> para mostrar las especificaciones que no son exitosas.

            -

            NOTA: Se puede especificar el pseudo-directorio ‘:files’ para +

            NOTA: Se puede especificar el pseudo-directorio ‘:files’ para <dir>, lo que mostrara las etiquetas para todas las especificaciones que deben ejecutarse en Rubinius. O puede especificar cualquier subdirectorio de spec/ para listar las etiquetas de las especificaciones diff --git a/web/_site/doc/es/contributing/style-guide/index.html b/web/_site/doc/es/contributing/style-guide/index.html index efd2c3abc9..a944f6a743 100644 --- a/web/_site/doc/es/contributing/style-guide/index.html +++ b/web/_site/doc/es/contributing/style-guide/index.html @@ -173,10 +173,10 @@

            Código C++

          • Versiones alternativas de las funciones deben ser nombradas por qué son -diferentes de la primera. Si hay una función ‘person()’ y quiere una +diferentes de la primera. Si hay una función ‘person()’ y quiere una versión que tome el nombre de la persona, esta debría de ser -‘person_with_name(char *name)’ o ‘person_with_details(char *name, …)’. -NO ‘person1(char *name)’.

            +‘person_with_name(char *name)’ o ‘person_with_details(char *name, …)’. +NO ‘person1(char *name)’.

          @@ -188,7 +188,7 @@

          Código de Ruby

          visualizar en una sola pantalla y trate de cumplir el principio DRY dentro de lo razonable. En general, la funcionalidad común debe ser extraída a métodos auxiliares (que usted puede hacer -“privados”), +“privados”), pero, en algunos casos, en particular cuando se trabaja con el núcleo de Ruby, a veces tratar de hacer las cosas en un estilo DRY puede ser sólo un @@ -198,7 +198,7 @@

          Código de Ruby

        4. Los nombres de método: deben ser claros, expresivos y significativos. Evite el -uso de guines bajos para “proteger” el método (‘\ __send__’) con algunas +uso de guines bajos para “proteger” el método (‘\ __send__’) con algunas excepciones.

        5. @@ -210,9 +210,9 @@

          Código de Ruby

        6. Los nombres de variables: que sean claros y significativos (con algunas -conocidas excepciones como la utilización de ‘i’ de un contador.) Trate de +conocidas excepciones como la utilización de ‘i’ de un contador.) Trate de evitar las enmacascar los nombres de métodos, por ejemplo dentro -Array utilice ‘idx’ en vez de ‘index’ porque el último es también +Array utilice ‘idx’ en vez de ‘index’ porque el último es también un nombre de método.

        7. diff --git a/web/_site/doc/es/getting-started/running-rubinius/index.html b/web/_site/doc/es/getting-started/running-rubinius/index.html index 53aae5e8dd..b584bac5a5 100644 --- a/web/_site/doc/es/getting-started/running-rubinius/index.html +++ b/web/_site/doc/es/getting-started/running-rubinius/index.html @@ -151,7 +151,7 @@

          Ejecutando Rubinius

          rbx -e 'puts "Hello!"'
           
          -

          Para ejecutar un archivo de Ruby llamado ‘code.rb’:

          +

          Para ejecutar un archivo de Ruby llamado ‘code.rb’:

          rbx code.rb
           
          diff --git a/web/_site/doc/es/getting-started/troubleshooting/index.html b/web/_site/doc/es/getting-started/troubleshooting/index.html index c4b991f976..fd3c523780 100644 --- a/web/_site/doc/es/getting-started/troubleshooting/index.html +++ b/web/_site/doc/es/getting-started/troubleshooting/index.html @@ -174,9 +174,9 @@

          Rubinius no puede enc

          Solución

          -

          Si ha configurado Rubinius con –prefix, ejecute rake install.

          +

          Si ha configurado Rubinius con –prefix, ejecute rake install.

          -

          Si ha configurado Rubinius con –prefix y cambió el nombre del directorio de +

          Si ha configurado Rubinius con –prefix y cambió el nombre del directorio de instalación después de instalar Rubinius, vuelva a configurar Rubinius y vuelva a instalarlo.

          diff --git a/web/_site/doc/es/how-to/commit-to-github/index.html b/web/_site/doc/es/how-to/commit-to-github/index.html index 43fab91a76..14cc2d2953 100644 --- a/web/_site/doc/es/how-to/commit-to-github/index.html +++ b/web/_site/doc/es/how-to/commit-to-github/index.html @@ -140,7 +140,7 @@

          Cómo - enviar cambios a Github

          El proyecto Rubinius hace su trabajo en su mayoría en la rama master. -El objetivo principal es mantener “limpio” de modo que siempre se construya +El objetivo principal es mantener “limpio” de modo que siempre se construya el binario y ofrece un snapshot de lás últimas correciones y mejoras.

          Committers - Acceso con acceso de lectura/escritura del repositorio de Rubinius

          @@ -167,7 +167,7 @@

          -

          This page was machine translated. Please help us improve it.

          - -

          - See How-To - Translate Documentation -

          - - - -

          Make sure you have read:

          +

          Asegúrese de haber leido:

          -

          Then, follow these steps to fix a failing spec:

          +

          Luego, siga estos pasos para arreglar una spec que falla:

            -
          1. Run rake to ensure that all CI specs are passing.
          2. -
          3. Run bin/mspec spec/some/spec_file.rb to confirm the spec fails.
          4. -
          5. Edit a file somewhere in Rubinius (probably under the kernel directory).
          6. -
          7. Run rake build to build your change.
          8. -
          9. Run bin/mspec spec/some/spec_file.rb to see if your change makes the -spec pass.
          10. -
          11. Repeat until your spec passes.
          12. -
          13. Run rake to ensure there are no regressions.
          14. -
          15. Change directory to Rubinius root if not already there.
          16. -
          17. Run git status, git add, git commit, etc. Any changes made to the spec -files under the spec/ruby directory must be in a different commit from -changes made to other Rubinius source code files.
          18. -
          19. Run git format-patch origin, which will extract commits that the current -branch accumulated since the last pull from origin, or `git format-patch --N’, where N is the number (1, 2, etc.) of commits for which you want to -generate patches.
          20. -
          21. Create a gist with your patch and link to it in a ticket on the issue -tracker at http://github.com/rubinius/rubinius/issues. You can add multiple -patches to one ticket.
          22. +
          23. Ejecute rake para asegurarse que todas las specs de CI están pasando.
          24. +
          25. Ejecute bin/mspec spec/some/spec_file.rb para confirmar que la spec falla.
          26. +
          27. Edite un archivo en algún lugar en Rubinius (probablemente en el directorio kernel).
          28. +
          29. Ejecute rake build para construir su cambio.
          30. +
          31. Ejecute bin/mspec spec/some/spec_file.rb para ver que su cambio hace que las spec pasen.
          32. +
          33. Repita hasta que su spec pase.
          34. +
          35. Ejecute rake para asegurarse que no hay regresiones.
          36. +
          37. Cambie al directorio raíz de Rubinius si todavía no está en él.
          38. +
          39. Ejecute git status, git add, git commit, etc. Cualquier cambio hecho a los archivos de spec en el directorio spec/ruby debe estar en un commit diferente al de los cambios hechos en los demás archivos del código de Rubinius.
          40. +
          41. Ejecute git format-patch origin, el cual extraerá los commits del branch actual acumulados desde el último pull desde origin, o `git format-patch +-N’, donde N es el número (1, 2, etc.) de commits con los que ud. quiere generar los parches.
          42. +
          43. Cree un gist con su patch y linkeelo en el ticket del issue tracker en http://github.com/rubinius/rubinius/issues. Puede agregar múltiples parches a un ticket.
          -

          When your patch is accepted by the Rubinius project, you’ll get a commit bit -for the Rubinius repository. Let Evan know what your Github username is.

          +

          Cuando su parche es aceptado en el project Rubinius, va a obtener commit bit +para el repositorio de Rubinius. Hágale saber a Evan cual es su usuario de Github.

          diff --git a/web/_site/doc/es/how-to/write-a-ruby-spec/index.html b/web/_site/doc/es/how-to/write-a-ruby-spec/index.html index ffc1670d5d..38786416ec 100644 --- a/web/_site/doc/es/how-to/write-a-ruby-spec/index.html +++ b/web/_site/doc/es/how-to/write-a-ruby-spec/index.html @@ -2,7 +2,7 @@ - Cómo - escribir una especificación en Ruby - Rubinius + Cómo - escribir una Ruby spec - Rubinius @@ -133,16 +133,7 @@
          -

          Cómo - escribir una especificación en Ruby

          - - -
          -

          This page was machine translated. Please help us improve it.

          - -

          - See How-To - Translate Documentation -

          -
          +

          Cómo - escribir una Ruby spec

          @@ -155,17 +146,15 @@

          Cómo - escribir una especificación en Ruby

        8. Especificaciones
    -

    A continuación, siga estos pasos para escribir la especificación de -un método de Ruby:

    +

    A continuación, siga estos pasos para escribir una spec para un método Ruby:

      -
    1. Editar un archivo bajo spec/ruby/...
    2. +
    3. Editar un archivo en spec/ruby/...
    4. Ejecute bin/mspec -tr spec/ruby/some/spec_file.rb
    5. -
    6. Repita hasta que la especificación pase la MatzRuby
    7. -
    8. Envice sus cambios
    9. +
    10. Repita hasta que la spec pase en MatzRuby
    11. +
    12. Comitee sus cambios
    13. Use git format-patch
    14. -
    15. Crea un gist con su parche y enlace a un billete de incidencia en el -tracker en http://github.com/rubinius/rubinius/issues.
    16. +
    17. Cree un gist con su parche y agregue el enlace a este en un ticket en el issue tracker en en http://github.com/rubinius/rubinius/issues.
    diff --git a/web/_site/doc/es/how-to/write-a-ticket/index.html b/web/_site/doc/es/how-to/write-a-ticket/index.html index caccadeaad..0b46f242b9 100644 --- a/web/_site/doc/es/how-to/write-a-ticket/index.html +++ b/web/_site/doc/es/how-to/write-a-ticket/index.html @@ -11,7 +11,7 @@ - + @@ -126,7 +126,7 @@ Siguiente: - Escribir una especificación en Ruby + Como escribir una especificación en Ruby @@ -139,95 +139,88 @@

    How-To - Write a Ticket

    -

    The Rubinius issue tracker is http://github.com/rubinius/rubinius/issues.

    +

    El issue tracker de Rubinius es http://github.com/rubinius/rubinius/issues.

    -

    Para ser útiles, los boletos deben ser concisas, específicas y acciones -concretas. Si no, el boleto languidecen y se convierten en el desorden. En -consecuencia, los boletos deben caer en uno (o más) de las siguientes +

    Para ser útiles, los tickets deben ser concisos, específicos y acciones +concretas. Si no, el ticket va a languidecer y convertirce en desorden. En +consecuencia, los tickets deben caer en uno (o más) de las siguientes categorías:

      -
    1. Una historia de línea de comandos precisos para demostrar cómo instalar -e invocar el programa y que muestra el seguimiento hacia atrás de una -excepción.
    2. +
    3. Una historia precisa de la línea de comandos para demostrar cómo instalar +e invocar el programa y que muestra el backtrace de una excepción.
    4. Un pequeño fragmento de código que ilustra el problema y la línea de -comandos lo invocan.
    5. -
    6. Un parche, incluyendo especificaciones técnicas, si no existen, y -mostrando la especificación de funcionamiento antes y después de aplicar -el parche.
    7. +comandos que lo invoca. +
    8. Un parche, incluyendo specs, si no existen, y +mostrando la spec funcionando antes y después de aplicar el parche.
    -

    Si el problema no se ajusta a una de las categorías, no es válido. Es -simplemente no es apropiado para un boleto.

    +

    Si el problema no se ajusta a una de las categorías, no es +válido. Simplemente no es apropiado para un ticket.

      -
    1. Si se trata de una función, consideran que trata sobre la lista de -correo. Además, podría tomar una grieta en su aplicación y demostrar -cómo su función es útil.
    2. -
    3. Si se trata de una biblioteca o joya que no está funcionando, tómese un -tiempo para cavar en y ver si se puede crear una reproducción de un tema -y después de que, como Venta de entradas.
    4. +
    5. Si se trata de una característica, considere discutirla en la lista de +correo. Además, podría intentar implementarla y demostrar +cómo su característica es útil.
    6. +
    7. Si se trata de una biblioteca o gema que no está funcionando, tómese un +tiempo para investigar y ver si se puede reproducir +y envíe eso como ticket.
    -

    Procedimiento general para la presentación de un billete

    +

    Procedimiento general para enviar un ticket

    1. -

      Vuelva a comprobar.

      +

      Verifique dos veces.

        -
      1. Hacer una reconstrucción completa (‘rake clean; rake’) después de un -‘git pull’ o clonar fresco.
      2. +
      3. Hacer una reconstrucción completa (‘rake clean; rake’) después de un +‘git pull’ o un clone fresco.
      4. Leer Troubleshooting -ver si algo se resuelve el problema.
      5. +ver si algo resuelve el problema.
      6. Leer Specs.

      7. -

        Dé su billete un título específico, preferentemente corto.

        +

        Dé a su ticket un título específico, preferentemente corto.

      8. -

        Dé a sus etiquetas apropiadas billete.

        +

        Etiquete correctamente su ticket.

      9. Dar suficientes detalles sobre el tema.

        • La línea de comandos para invocar el programa
        • -
        • El seguimiento hacia atrás o resultado del programa en comparación con +
        • El backtrace o resultado del programa en comparación con resultado esperado.
        • -
        • La información de su máquina. uname-a es generalmente bueno (si hay -alguna “desconocido” en campos que, por favor, más detalles sobre -ellos.)
        • +
        • La información de su máquina. uname -a está generalmente bien (si hay +algun “unkown” en cualquiera de los campos, por favor, dar más +detalles sobre ellos.)
    -

    Instrucciones adicionales para las entradas con parches

    +

    Instrucciones adicionales para tickets con parches

      -
    • Puede ser sólo un conjunto de especificaciones técnicas.
    • -
    • Los parches deben ir acompañadas de especificaciones técnicas a menos que -las especificaciones técnicas ya existentes.
    • -
    • La parte pertinente de la producción de especificaciones y la exacta -bin/mspec la invocación de la existentes o agregar especificaciones -antes de la corrección.
    • -
    • La salida de especificaciones y bin/mspec exactamente la invocación -que muestra el éxito después de la revisión.
    • -
    • Descripción adicional de su parche y cómo se soluciona el problema. En -particular, con nuevas funcionalidades por favor, indique si ya estaba -discutido en #rubinius o rubinius-dev.
    • +
    • Puede ser sólo un conjunto de specs.
    • +
    • Los parches deben ir acompañadas de specs a menos que +las specs ya existan.
    • +
    • La parte relevante de la salida de las specs y la exacta invocación de +bin/mspec de la spec agregada o existente antes de la corrección.
    • +
    • La salida de las specs y la invocación exacta de bin/mspec que muestra el éxito después del arreglo.
    • +
    • Una descripción adicional de su parche y cómo este soluciona el problema. En +particular, con nuevas funcionalidades, por favor, indique si ya se ha discutido en #rubinius o rubinius-dev.
    -

    A menos que por alguna razón imposible, por favor use git-format-patch para -crear la patchset. Es mucho más fácil de aplicar y que conserva la atribución -correcta. De lo contrario, un diff unificado.

    +

    A menos que por alguna razón sea imposible, por favor use git-format-patch para crear el patchset. Es mucho más fácil de aplicar y conserva la atribución correcta. De lo contrario, un diff unificado.

    Ejemplo de la presentación de un parche

    -

    Supongamos que la especificación siguiente existe y no es:

    +

    Supongamos que la siguiente spec existe y está fallando:

    describe "Kernel.format" do
       it "is accessible as a module function" do
    @@ -238,19 +231,19 @@ 

    Ejemplo de la presentación de u
    1. -

      Ticket Title:

      +

      Título del ticket:

      -

      “[PATCH] No method ‘format’ on Kernel (Module)”

      +

      “[PATCH] No method ‘format’ on Kernel (Module)”

    2. Tags:

      -

      “patch core spec”

      +

      “patch core spec”

    3. -

      Ticket Message:

      +

      Mensaje del ticket:

      -

      The method ‘format’ is not available as a module function of Kernel.

      +

      The method ‘format’ is not available as a module function of Kernel.

      $ bin/mspec spec/ruby/core/kernel/format_spec.rb
       Started
      @@ -261,7 +254,7 @@ 

      Ejemplo de la presentación de u No method 'format' on Kernel (Module):

      -

      The method ‘format’ already exists but has not been set as a module +

      The method ‘format’ already exists but has not been set as a module function. This patch does so.

      After the patch is applied:

      @@ -280,8 +273,8 @@

      Ejemplo de la presentación de u

    -

    Por último, poner el parche en una esencia y añadir el enlace a la esencia de -su problema. A continuación se reproduce el parche en línea para la integridad:

    +

    Por último, ponga el parche en un gist y agregue el enlace al gist +de su issue. A continuación se reproduce el parche en una línea opor una cuestión de integridad:

    From c61cecce6442347ebbdf1ded7a5c0832c97582c1 Mon Sep 17 00:00:00 2001
     From: Brian Ford <bford@engineyard.com>
    @@ -319,7 +312,7 @@ 

    Ejemplo de la presentación de u Siguiente: - Escribir una especificación en Ruby + Como escribir una especificación en Ruby diff --git a/web/_site/doc/es/how-to/write-benchmarks/index.html b/web/_site/doc/es/how-to/write-benchmarks/index.html index 912af50276..cc1cf81173 100644 --- a/web/_site/doc/es/how-to/write-benchmarks/index.html +++ b/web/_site/doc/es/how-to/write-benchmarks/index.html @@ -152,9 +152,9 @@

    How-To - Write Benchmarks

    example different ways of deleting keys/values from a Hash.

  • Use the benchmark framework.
  • Keep the benchmarks short and simple.
  • -
  • The benchmarks are not meant to measure Rubinius. So if you’re writing a +
  • The benchmarks are not meant to measure Rubinius. So if you’re writing a benchmark for a class with bang and no-bang methods you will want to use -a duplicate of a variable in the bang method but you don’t need to dup +a duplicate of a variable in the bang method but you don’t need to dup in the no-bang method.
  • diff --git a/web/_site/doc/es/specs/index.html b/web/_site/doc/es/specs/index.html index 758644625d..e967f34c70 100644 --- a/web/_site/doc/es/specs/index.html +++ b/web/_site/doc/es/specs/index.html @@ -140,13 +140,13 @@

    Especificaciones

    El proyecto Rubinius utiliza especificaciones ejecutables al estilo -TDD/BDD para impulsar el desarrollo. El directorio ‘spec’ se divide +TDD/BDD para impulsar el desarrollo. El directorio ‘spec’ se divide conceptualmente en dos partes:

      -
    1. Todos los archivos en “./spec/ruby’ que describen el comportamiento de +
    2. Todos los archivos en “./spec/ruby’ que describen el comportamiento de MatzRuby.
    3. -
    4. Y todos los otros archivos dentro del directorio ‘./spec’ que +
    5. Y todos los otros archivos dentro del directorio ‘./spec’ que describen el comportamiento de Rubinius.
    diff --git a/web/_site/doc/es/tools/debugger/index.html b/web/_site/doc/es/tools/debugger/index.html index 3a2bbc4b72..b837b88930 100644 --- a/web/_site/doc/es/tools/debugger/index.html +++ b/web/_site/doc/es/tools/debugger/index.html @@ -207,7 +207,7 @@

    Invocar en el Código

    Como se ve, la ayuda para los comandos de depuración se puede acceder -escribiendo ‘help’.

    +escribiendo ‘help’.

    Invocación desde la línea de comandos

    diff --git a/web/_site/doc/es/tools/profiler/index.html b/web/_site/doc/es/tools/profiler/index.html index 1d8d9b65f3..20b0275dbe 100644 --- a/web/_site/doc/es/tools/profiler/index.html +++ b/web/_site/doc/es/tools/profiler/index.html @@ -214,7 +214,7 @@

    Analizador de Ruby

    El método #profile inicia el analizador, hace la llamada a yield, detiene el analizador e imprime por defecto los datos del análisis. Puede pasar la opción -‘false’ al método #profile para que no se impriman los datos. De cualquier +‘false’ al método #profile para que no se impriman los datos. De cualquier manera, los datos son el valor retornado por la llamada a #profile.

    Cómo Leer la Salida del Analizador

    @@ -229,7 +229,7 @@

    % time

    cumulative seconds

    Si se considera este método como la raíz de un árbol, el resultado de -‘cumulative seconds’ sería el tiempo acumulado de ejecución de este +‘cumulative seconds’ sería el tiempo acumulado de ejecución de este método y de todos los métodos que el mismo ha llamado (hojas del árbol).

    self seconds

    @@ -243,7 +243,7 @@

    calls

    self ms/call

    -

    El tiempo definido en ‘self seconds’ dividido por el número total de llamadas.

    +

    El tiempo definido en ‘self seconds’ dividido por el número total de llamadas.

    total ms/call

    @@ -276,7 +276,7 @@

    Ejemplo de la Salida

    }
    -

    Al ejecutar el script con ‘bin/rbx script.rb’ se obtiene una salida como:

    +

    Al ejecutar el script con ‘bin/rbx script.rb’ se obtiene una salida como:

      %   cumulative   self                self     total
      time   seconds   seconds      calls  ms/call  ms/call  name
    @@ -346,7 +346,7 @@ 

    name

    self

    El tiempo total empleado en este método menos el tiempo total invertido en -todo esto método que el mismo llama. Igual a ‘self seconds’ en la salida plana.

    +todo esto método que el mismo llama. Igual a ‘self seconds’ en la salida plana.

    children

    @@ -354,7 +354,7 @@

    children

    called

    -

    El campo ‘called’ tiene dos partes separadas por una barra diagonal. El número +

    El campo ‘called’ tiene dos partes separadas por una barra diagonal. El número a la izquierda es el número de veces que este método llamó al método primario. El número a la derecha es el número total de llamadas que este método realizó. En otras palabras, estos números representan la relación entre el número de @@ -371,8 +371,8 @@

    name

    self

    El tiempo total empleado en este método menos el tiempo total invertido en -todos los métodos que este método llamó. Este valor es equivalente a ‘self -seconds’ en la salida plana.

    +todos los métodos que este método llamó. Este valor es equivalente a ‘self +seconds’ en la salida plana.

    children

    Este es un estimado del tempo que los métodos llamados por este método se @@ -382,7 +382,7 @@

    children

    called

    -

    El campo “called” tiene dos partes separadas por una barra diagonal. La izquierda +

    El campo “called” tiene dos partes separadas por una barra diagonal. La izquierda es el número de veces que este método fue llamado por el método principal. La derecha es el número total de veces en que este método fue llamado.

    @@ -390,7 +390,7 @@

    name

    El nombre del método llamado seguido de su número de índice [N]. Si no hay un índice presente, no hay ninguna entrada principal para el método en el -gráfico. Utilice el opción –Xprofiler.full_report para imprimir el gráfico +gráfico. Utilice el opción –Xprofiler.full_report para imprimir el gráfico completo si es necesario ver la entrada.

    index  % time     self  children         called       name
    diff --git a/web/_site/doc/es/virtual-machine/instructions/index.html b/web/_site/doc/es/virtual-machine/instructions/index.html
    index 7117797227..372f777c51 100644
    --- a/web/_site/doc/es/virtual-machine/instructions/index.html
    +++ b/web/_site/doc/es/virtual-machine/instructions/index.html
    @@ -256,7 +256,7 @@ 

    Notes

    Unlike other literals such as strings and numbers, creating a Regexp literal (i.e. via the /regex/ syntax) is a two step process to create the literal slot for the Regexp, create a literal for the string between the - ‘/’ delimiters and create a new Regexp object passing it the string. Only + ‘/’ delimiters and create a new Regexp object passing it the string. Only then can the literal value be set, using the set_literal opcode.

    push_literal(literal)

    @@ -754,7 +754,7 @@

    pop_unwind()

    Remove the next unused unwind registration from the current invocation. This instruction is paired with setup_unwind to remove registrations - when control exits a section of code that registered a handler but didn’t + when control exits a section of code that registered a handler but didn’t use it. For example, exiting a begin that had a rescue expression.

    @@ -1351,7 +1351,7 @@

    cast_for_multi_block_ the arg is an array.

    If the Proc invoked from was in lambda mode, and one argument is passed: - * and it’s an Array, push it. + * and it’s an Array, push it. * and it responds to #to_ary, try and convert it and push it. * otherwise wrap it in a one element Array and push it.

    @@ -1637,7 +1637,7 @@

    Notes

    runtime to determine which code path is executed.

    For example, a method such as Fixnum#times can be optimised at compile - time, but we can’t know until runtime whether or not the Fixnum#times + time, but we can’t know until runtime whether or not the Fixnum#times method has been overridden. The serial number check is used to determine each time the code is executed, whether or not the standard Fixnum#times has been overridden. It leverages the serial number field on a @@ -1646,7 +1646,7 @@

    Notes

    check_serial_private(literal, serial)

    -

    Checks if the specified method’s serial number matches an expected value. +

    Checks if the specified method’s serial number matches an expected value. Considers private methods too.

    @@ -1934,7 +1934,7 @@

    meta_send_op_tequal(litera

    Notes

    -

    Exactly like equal, except calls #=== if it can’t handle it directly.

    +

    Exactly like equal, except calls #=== if it can’t handle it directly.

    meta_send_call(literal, count)

    @@ -2225,7 +2225,7 @@

    call_custom(literal, count)

    meta_to_s(literal)

    -

    Pop a value off the stack and if it’s not a String, call a method +

    Pop a value off the stack and if it’s not a String, call a method indicated by literal on it. Push the resulting object back on the stack.

    diff --git a/web/_site/doc/fr/appendix-a-glossary/index.html b/web/_site/doc/fr/appendix-a-glossary/index.html index d7726a5f88..7cdfe833fa 100644 --- a/web/_site/doc/fr/appendix-a-glossary/index.html +++ b/web/_site/doc/fr/appendix-a-glossary/index.html @@ -149,9 +149,9 @@

    Appendix A - Glossary

    Definitions of terms and phrases used in the Ruby programming language and in -this implementation. See also “The Ruby Programming Language” by Flanagan and -Matsumoto [O’Reilly 2008] and “Programming Ruby: The Pragmatic Programmer’s -Guide” 2nd or 3rd Edition by Thomas et al [The Pragmatic Programmers +this implementation. See also “The Ruby Programming Language” by Flanagan and +Matsumoto [O’Reilly 2008] and “Programming Ruby: The Pragmatic Programmer’s +Guide” 2nd or 3rd Edition by Thomas et al [The Pragmatic Programmers 2005-2008]

      @@ -160,7 +160,7 @@

      Appendix A - Glossary

      The rule is simple: Take the object located in the class slot of the object (which is not always the return value of Object#class; if the object has one, -it’ll be the singleton class) and begin searching.

      +it’ll be the singleton class) and begin searching.

      Searching goes up the superclass chain until the superclass is nil.

      @@ -219,7 +219,7 @@

      Appendix A - Glossary

      1. -

        Resolve method ‘wanker’ – search method_tables in:

        +

        Resolve method ‘wanker’ – search method_tables in:

        1. SingletonClass(F)
        2. @@ -237,7 +237,7 @@

          Appendix A - Glossary

          A data structure in every class (and module) that contains the methods defined for that class.

          -

          In Rubinius, a class’s method_table is an instance of LookupTable.

          +

          In Rubinius, a class’s method_table is an instance of LookupTable.

        3. MatzRuby

          @@ -247,7 +247,7 @@

          Appendix A - Glossary

        4. MRI

          -

          Matz’s Ruby Interpreter or Matz’s Ruby Implementation. A short name to refer +

          Matz’s Ruby Interpreter or Matz’s Ruby Implementation. A short name to refer to the official implementation of Ruby. See http://ruby-lang.org.

        5. @@ -296,8 +296,8 @@

          Appendix A - Glossary

    Since all classes in Ruby are also objects, they can have singleton classes. -The methods called “class methods” are just methods in the method_table of -the class’s singleton class. The method +honk+ exists in the singleton class +The methods called “class methods” are just methods in the method_table of +the class’s singleton class. The method +honk+ exists in the singleton class for the class +Car+.

    class Car
    @@ -309,7 +309,7 @@ 

    Appendix A - Glossary

    In Rubinius, singleton classes are all instances of the class SingletonClass. The singleton class for an object can be obtained by calling the +singleton_class+ method. The overall arrangement of concepts involved -here is sometimes referred to as the ‘Meta-Object Protocol’ or +MOP+.

    +here is sometimes referred to as the ‘Meta-Object Protocol’ or +MOP+.

  • superclass

    diff --git a/web/_site/doc/fr/appendix-b-reading-list/index.html b/web/_site/doc/fr/appendix-b-reading-list/index.html index deab2a4acf..e914658895 100644 --- a/web/_site/doc/fr/appendix-b-reading-list/index.html +++ b/web/_site/doc/fr/appendix-b-reading-list/index.html @@ -149,9 +149,9 @@

    Appendix B - Reading List

    Building virtual machines in general and programming language implementations -in particular requires some knowledge. Rubinius’ goal is to lower the barrier +in particular requires some knowledge. Rubinius’ goal is to lower the barrier by keeping as much as possible in Ruby but to hack on the garbage collector you -have to understand what’s going on behind the curtains.

    +have to understand what’s going on behind the curtains.

    This page contains references to books, online lectures, blog posts and any other publications you may find useful for working on Rubinius.

    @@ -162,7 +162,7 @@

    Virtual machine

    • Smalltalk-80: language and its implementation -by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation +by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation chapters from part IV are available online
    • Virtual machines by Iain D. Craig
    • Great posts by Adam Gardiner: introduction, @@ -191,7 +191,7 @@

      FFI

      diff --git a/web/_site/doc/fr/build-system/index.html b/web/_site/doc/fr/build-system/index.html index 26b29c7cf0..058a6505a5 100644 --- a/web/_site/doc/fr/build-system/index.html +++ b/web/_site/doc/fr/build-system/index.html @@ -177,7 +177,7 @@

      Development versus Install Builds

      not
      function, even if the executable is in the directory. The executable checks a single, hard-coded path. If this ends up being very painful for some reason, -we’ll revise it.

      +we’ll revise it.

      Installing Rubinius

      @@ -186,11 +186,11 @@

      Installing Rubinius

      ./configure --prefix=/path/to/install/dir
       
      -

      The configure process creates a ‘config.rb’ file that specifies the key file -paths that Rubinius uses. Once configured, run ‘rake install’ to build and +

      The configure process creates a ‘config.rb’ file that specifies the key file +paths that Rubinius uses. Once configured, run ‘rake install’ to build and install. The install procedure builds all the files, including compiling the Ruby standard library files in the lib/ directory, then copies them into the -install location using the ‘install’ program. The install tasks are located in +install location using the ‘install’ program. The install tasks are located in rakelib/install.rake.

      diff --git a/web/_site/doc/fr/bytecode-compiler/generator/index.html b/web/_site/doc/fr/bytecode-compiler/generator/index.html index 5c985132a1..f65b9ccf59 100644 --- a/web/_site/doc/fr/bytecode-compiler/generator/index.html +++ b/web/_site/doc/fr/bytecode-compiler/generator/index.html @@ -187,7 +187,7 @@

      Generator

      When generating the bytecode for an AST, Rubinius invokes the method bytecode on each AST node, passing in the current Generator -instance. Here’s the bytecode method for the if node:

      +instance. Here’s the bytecode method for the if node:

      def bytecode(g)
         pos(g)
      diff --git a/web/_site/doc/fr/bytecode-compiler/parser/index.html b/web/_site/doc/fr/bytecode-compiler/parser/index.html
      index 896dfc2cdc..df65847c16 100644
      --- a/web/_site/doc/fr/bytecode-compiler/parser/index.html
      +++ b/web/_site/doc/fr/bytecode-compiler/parser/index.html
      @@ -153,7 +153,7 @@ 

      Ruby Parser

      the next stage of the process, the generator.

      The parser itself (called Melbourne) has a C part, which is essentially -MRI’s parser, and a Ruby part, which is responsible for creating the Ruby +MRI’s parser, and a Ruby part, which is responsible for creating the Ruby AST. The C parser communicates with Ruby by calling a method for each node in the parse tree.

      diff --git a/web/_site/doc/fr/bytecode-compiler/transformations/index.html b/web/_site/doc/fr/bytecode-compiler/transformations/index.html index 86fd39182c..e07f3c6297 100644 --- a/web/_site/doc/fr/bytecode-compiler/transformations/index.html +++ b/web/_site/doc/fr/bytecode-compiler/transformations/index.html @@ -166,7 +166,7 @@

      Safe Math Compiler Transform

      one of its cherished features but it is also truly a double-edged sword in some respects.

      -

      In the standard library the ‘mathn’ library redefines Fixnum#/ in an unsafe +

      In the standard library the ‘mathn’ library redefines Fixnum#/ in an unsafe and incompatible manner. The library aliases Fixnum#/ to Fixnum#quo, which returns a Float by default.

      @@ -176,7 +176,7 @@

      Safe Math Compiler Transform

      define this method.

      The safe math transform is enabled during the compilation of the Core -libraries to enable the plugin. During regular ‘user code’ compilation, the +libraries to enable the plugin. During regular ‘user code’ compilation, the plugin is not enabled. This enables us to support mathn without breaking the core libraries or forcing inconvenient practices.

      diff --git a/web/_site/doc/fr/contributing/index.html b/web/_site/doc/fr/contributing/index.html index 5bcf254643..6a875fabef 100644 --- a/web/_site/doc/fr/contributing/index.html +++ b/web/_site/doc/fr/contributing/index.html @@ -172,7 +172,7 @@

      Write Specs

      tagged as incomplete. These specs may simply need review, or there could be specs missing for a particular class.

      -

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will +

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will show tags for all the specs that should run on Rubinius. Or you can specify any subdirectory of the spec/ directory to list tags for specs in that subdirectory.

      @@ -189,7 +189,7 @@

      Fix Failing Specs

    • Run bin/mspec tag --list fails <dir> to show specs tagged as failing.

      -

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will +

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will show tags for all the specs that should run on Rubinius. Or you can specify any subdirectory of the spec/ directory to list tags for specs in that subdirectory.

      diff --git a/web/_site/doc/fr/contributing/style-guide/index.html b/web/_site/doc/fr/contributing/style-guide/index.html index f71336ef4f..3961c74ac1 100644 --- a/web/_site/doc/fr/contributing/style-guide/index.html +++ b/web/_site/doc/fr/contributing/style-guide/index.html @@ -170,10 +170,10 @@

      C++ Code

    • Alternate versions of functions should be named why they are different -from the primary. If there is a function ‘person()’ and you want a +from the primary. If there is a function ‘person()’ and you want a version that takes the name of the person, it should be -‘person_with_name(char *name)’ or ‘person_with_details(char *name, …)’. -NOT ‘person1(char *name)’.

      +‘person_with_name(char *name)’ or ‘person_with_details(char *name, …)’. +NOT ‘person1(char *name)’.

    @@ -181,16 +181,16 @@

    Ruby Code

    • -

      Methods: Try to keep your methods short–one screenful and try to adhere +

      Methods: Try to keep your methods short–one screenful and try to adhere to DRY within reason. Generally common functionality should be abstracted -to helper methods (which you can make ‘private’) but in some cases, +to helper methods (which you can make ‘private’) but in some cases, particularly working with Core, sometimes trying to DRY things up is just an obstacle if you have to maneuver around several different error conditions, for example.

    • Method names: should be clear, expressive and meaningful. Avoid using -underscores to ‘protect’ the method (‘__send__’) with some exceptions.

      +underscores to ‘protect’ the method (‘__send__’) with some exceptions.

    • Smalltalk-style method names are OK, meaning that you could have a method @@ -201,8 +201,8 @@

      Ruby Code

    • Variable names: make them clear and meaningful (with some well-known -exceptions like using ‘i’ for a counter.) Try to avoid shadowing method -names, for example within Array use ‘idx’ in favour of ‘index’ because the +exceptions like using ‘i’ for a counter.) Try to avoid shadowing method +names, for example within Array use ‘idx’ in favour of ‘index’ because the latter is also a method name.

    • diff --git a/web/_site/doc/fr/getting-started/building/index.html b/web/_site/doc/fr/getting-started/building/index.html index 55e5036076..4e7442a643 100644 --- a/web/_site/doc/fr/getting-started/building/index.html +++ b/web/_site/doc/fr/getting-started/building/index.html @@ -140,23 +140,23 @@

      Compiler Rubinius

      Vous pouvez compiler et exécuter Rubinius à partir du répertoire des sources. -Vous n’avez pas besoin d’installer Rubinius pour l’exécuter. +Vous n’avez pas besoin d’installer Rubinius pour l’exécuter. Les instructions ci-dessous détaillent ces deux points, installer Rubinius -et l’exécuter à partir du répertoire des sources.

      +et l’exécuter à partir du répertoire des sources.

      -

      Rubinius utilise LLVM dans son compilateur JIT. Rubinius dépend d’une version +

      Rubinius utilise LLVM dans son compilateur JIT. Rubinius dépend d’une version particulière de LLVM, et LLVM doit être compilé avec les options de RTTI C++ -(“run-time type information”) activées. +(“run-time type information”) activées. Le script configure vérifiera automatiquement ces pré-requis en cherchant une version installée de LLVM. -Si LLVM n’est pas installé ou que Rubinius échoue à l’édition de liens pour une +Si LLVM n’est pas installé ou que Rubinius échoue à l’édition de liens pour une raison quelconque, passez --skip-system au script configure dans les instructions suivantes.

      Récupérer les sources

      -

      Le code source de Rubinius est disponible sous la forme d’une archive et d’un projet sur Github. -Vous pouvez télécharger l’archive ici.

      +

      Le code source de Rubinius est disponible sous la forme d’une archive et d’un projet sur Github. +Vous pouvez télécharger l’archive ici.

      Pour utiliser Git :

      @@ -167,12 +167,12 @@

      Récupérer les sources

      Installer Rubinius

      -

      Si vous prévoyez d’utiliser Rubinius pour exécuter votre application, c’est +

      Si vous prévoyez d’utiliser Rubinius pour exécuter votre application, c’est une bonne solution. Cependant, vous pouvez aussi exécuter Rubinius directement à partir du répertoire des sources. Consultez la section suivante pour plus de détails sur ce sujet.

      -

      Nous recommandons d’installer Rubinius à un emplacement qui ne nécessite pas sudo ou +

      Nous recommandons d’installer Rubinius à un emplacement qui ne nécessite pas sudo ou des privilèges super-utilisateur. Pour installer Rubinius :

        @@ -195,8 +195,8 @@

        Exécuter à partir du répert

        Cependant, si vous développez Rubinius, vous ne devriez PAS ajouter le répertoire bin à votre PATH car le système de construction de Rubinius va utiliser les liens -ruby et rake qui pointent vers l’exécutable Rubinius. -Rubinius nécessite un exécutable Ruby séparé pour s’amorcer lors de la phase de +ruby et rake qui pointent vers l’exécutable Rubinius. +Rubinius nécessite un exécutable Ruby séparé pour s’amorcer lors de la phase de compilation.

        diff --git a/web/_site/doc/fr/getting-started/requirements/index.html b/web/_site/doc/fr/getting-started/requirements/index.html index 827b929d76..b4bddef241 100644 --- a/web/_site/doc/fr/getting-started/requirements/index.html +++ b/web/_site/doc/fr/getting-started/requirements/index.html @@ -139,32 +139,32 @@

        Pré-requis

        -

        Assurez vous d’avoir les programmes et bibliothèques suivants installés. +

        Assurez vous d’avoir les programmes et bibliothèques suivants installés. Consultez aussi les sous-sections ci-dessous pour les pré-requis spécifiques -à votre système d’exploitation.

        +à votre système d’exploitation.

        -

        La liste suivante est un ensemble de suggestions pour avoir plus d’information +

        La liste suivante est un ensemble de suggestions pour avoir plus d’information à propos des programmes et bibliothèques nécessaires pour compiler Rubinius. -Votre système d’exploitation ou gestionnaire de paquets peut avoir -d’autres paquets disponibles.

        +Votre système d’exploitation ou gestionnaire de paquets peut avoir +d’autres paquets disponibles.

        • GCC et G++ 4.x
        • GNU Bison
        • -
        • MRI Ruby 1.8.7+ Si votre système n’a pas +
        • MRI Ruby 1.8.7+ Si votre système n’a pas Ruby 1.8.7 installé, pensez à utiliser RVM -pour l’installer.
        • +pour l’installer.
        • Rubygems
        • Git
        • ZLib
        • -
        • pthread - La bibliothèque pthread devrait être installée par votre système d’exploitation
        • +
        • pthread - La bibliothèque pthread devrait être installée par votre système d’exploitation
        • gmake
        • rake [sudo] gem install rake

        Apple OS X

        -

        Le moyen le plus facile d’obtenir un environnement de build sur Apple OS X est d’installer les +

        Le moyen le plus facile d’obtenir un environnement de build sur Apple OS X est d’installer les Outils et utilitaires XCode. Une fois installés, vous pouvez activer le mode de rapport de plantages développeur ici :

        @@ -181,7 +181,7 @@

        Debian/Ubuntu

        FreeBSD

        -

        Rubinius a un portage dans l’arbre des portages FreeBSD. Il s’appelle lang/rubinius. +

        Rubinius a un portage dans l’arbre des portages FreeBSD. Il s’appelle lang/rubinius. Vous pouvez trouver des informations à propos de ce portage sur http://freshports.org/lang/rubinius/. Lors de son installation, le portage installe toutes les dépendances automagiquement.

        diff --git a/web/_site/doc/fr/getting-started/running-rubinius/index.html b/web/_site/doc/fr/getting-started/running-rubinius/index.html index b17deb7876..9bfa9cd7e7 100644 --- a/web/_site/doc/fr/getting-started/running-rubinius/index.html +++ b/web/_site/doc/fr/getting-started/running-rubinius/index.html @@ -150,7 +150,7 @@

        Exécuter Rubinius

        rbx -e 'puts "Bonjour !"'
         
        -

        Pour exécuter un fichier ruby nommé ‘code.rb’ :

        +

        Pour exécuter un fichier ruby nommé ‘code.rb’ :

        rbx code.rb
         
        @@ -161,11 +161,11 @@

        Exécuter Rubinius

  • Si vous avez ajouté le répertoire bin de Rubinius à votre PATH, -Rubinius devrait se comporter exactement comme vous l’attendriez de MRI. +Rubinius devrait se comporter exactement comme vous l’attendriez de MRI. Vous avez accès aux commandes ruby, rake, gem, irb, ri et rdoc.

    Vous pouvez ajouter le répertoire bin de Rubinius à votre PATH seulement lorsque -vous désirez utiliser Rubinius. Ainsi, il n’interférera pas avec votre installation +vous désirez utiliser Rubinius. Ainsi, il n’interférera pas avec votre installation standard de Ruby lorsque vous ne voulez pas utiliser Rubinius.

    diff --git a/web/_site/doc/fr/getting-started/troubleshooting/index.html b/web/_site/doc/fr/getting-started/troubleshooting/index.html index f43440eb97..f70710acc7 100644 --- a/web/_site/doc/fr/getting-started/troubleshooting/index.html +++ b/web/_site/doc/fr/getting-started/troubleshooting/index.html @@ -140,10 +140,10 @@

    Dépannage

    Cette section rassemble les erreurs que vous pouvez rencontrer lors de la compilation, -de l’installation ou de l’exécution de Rubinius, avec des suggestions de solutions.

    +de l’installation ou de l’exécution de Rubinius, avec des suggestions de solutions.

    -

    Pour chaque erreur, la première étape est de s’assurer que vous avez une copie de travail -à jour et propre de Rubinius. Avant d’aller plus loin, pensez à exécuter les étapes suivantes :

    +

    Pour chaque erreur, la première étape est de s’assurer que vous avez une copie de travail +à jour et propre de Rubinius. Avant d’aller plus loin, pensez à exécuter les étapes suivantes :

    $ git co master
     $ git reset --hard
    @@ -154,8 +154,8 @@ 

    Dépannage

    Rubinius ne trouve pas le répertoire de runtime

    -

    Après la compilation ou l’installation, l’erreur suivant apparaît lors d’une - tentative d’exécution de Rubinius :

    +

    Après la compilation ou l’installation, l’erreur suivant apparaît lors d’une + tentative d’exécution de Rubinius :

    ERROR: unable to find runtime directory
     
    @@ -177,17 +177,17 @@ 

    Solution:

    Si vous avez configuré Rubinius avec un --prefix, exécutez rake install.

    Si vous avez configuré Rubinius avec un --prefix et renommé le répertoire - d’installation après avoir installé Rubinius, reconfigurez Rubinius et réinstallez-le.

    + d’installation après avoir installé Rubinius, reconfigurez Rubinius et réinstallez-le.

    Si vous avez renommé le répertoir des sources après avoir compilé Rubinius, reconfigurez et recompilez-le.

    -

    De manière générale, ne renommez pas le répertoire de compilation ou d’installation après +

    De manière générale, ne renommez pas le répertoire de compilation ou d’installation après avoir compilé ou installé Rubinius.

    Rubinius provoque une erreur de segmentation sur FreeBSD

    -

    Sur FreeBSD, jusqu’à la version 8.1 stable incluse, existe un problème avec execinfo qui +

    Sur FreeBSD, jusqu’à la version 8.1 stable incluse, existe un problème avec execinfo qui provoque une erreur de segmentation lorsque Rubinius se charge.

    Solution:

    diff --git a/web/_site/doc/fr/how-to/fix-a-failing-spec/index.html b/web/_site/doc/fr/how-to/fix-a-failing-spec/index.html index c306b2da97..1f0452c1a5 100644 --- a/web/_site/doc/fr/how-to/fix-a-failing-spec/index.html +++ b/web/_site/doc/fr/how-to/fix-a-failing-spec/index.html @@ -139,7 +139,7 @@

    Comment faire - Corriger un Test En Echec

    -

    Assurez-vous d’avoir lu:

    +

    Assurez-vous d’avoir lu:

    • Démarrer
    • @@ -149,22 +149,22 @@

      Comment faire - Corriger un Test En Echec

      Ensuite, suivez ces étapes pour corriger un test en échec:

        -
      1. Exécutez rake pour vous assurer que tous les tests d’intégration continue sont valides.
      2. +
      3. Exécutez rake pour vous assurer que tous les tests d’intégration continue sont valides.
      4. Exécutez bin/mspec spec/some/spec_file.rb pour confirmer que le test échoue.
      5. -
      6. Corriger le problème où qu’il se trouve dans Rubinius (probablement dans le répertoire kernel).
      7. +
      8. Corriger le problème où qu’il se trouve dans Rubinius (probablement dans le répertoire kernel).
      9. Exécutez rake build pour compiler vos changements.
      10. Exécutez bin/mspec spec/some/spec_file.rb pour vous vérifier si votre changement corrige le test en échec.
      11. -
      12. Répétez jusqu’à ce que le test passe.
      13. -
      14. Exécutez rake pour vous assurer qu’il n’y a pas de régressions.
      15. -
      16. Rendez-vous dans le répertoire racine de Rubinius (si vous n’y êtes pas déjà).
      17. +
      18. Répétez jusqu’à ce que le test passe.
      19. +
      20. Exécutez rake pour vous assurer qu’il n’y a pas de régressions.
      21. +
      22. Rendez-vous dans le répertoire racine de Rubinius (si vous n’y êtes pas déjà).
      23. Exécutez git status, git add, git commit, etc. Tout changement apporté aux fichiers de tests sous le dossier spec/ruby doit être dans un commit différent de celui utilisé pour corriger le code source.
      24. -
      25. Exécutez git format-patch origin, ce qui extraira les commits accumulés dans la branche en cours depuis sa dernière mise à jour depuis origin, ou `git format-patch -N’, ou N (un entier, 1, 2,…) est le nombre de commits que vous souhaitez extraire afin de génerer le patch
      26. +
      27. Exécutez git format-patch origin, ce qui extraira les commits accumulés dans la branche en cours depuis sa dernière mise à jour depuis origin, ou `git format-patch -N’, ou N (un entier, 1, 2,…) est le nombre de commits que vous souhaitez extraire afin de génerer le patch
      28. Créez un gist avec votre patch et liez-le dans un ticket sur le gestionnaire de ticket du projet http://github.com/rubinius/rubinius/issues. Vous pouvez ajoutez plusieurs patchs à un seul ticket.

      Quand votre patch est accepté par le project Rubinius, vous aurez un -droit d’accès au dépôt Rubinius. Communiquez votre nom d’utilisateur +droit d’accès au dépôt Rubinius. Communiquez votre nom d’utilisateur GitHub à Evan.

      diff --git a/web/_site/doc/fr/how-to/translate-documentation/index.html b/web/_site/doc/fr/how-to/translate-documentation/index.html index c92ab60d85..e343b23f51 100644 --- a/web/_site/doc/fr/how-to/translate-documentation/index.html +++ b/web/_site/doc/fr/how-to/translate-documentation/index.html @@ -162,8 +162,8 @@

      Créer de la nouvelle documentationISO-639-1 pour la traduction que vous créez.
    • Editer les liens dans la Table des Matières pour pointer vers la cette traduction. (Notez que le page.base_dir -n’est pas accessible quand ces fichiers sont rendus via Jekyll. Cela mériterait d’être investigué).
    • -
    • Traduire le texte de l’Anglais vers la langue en question.
    • +n’est pas accessible quand ces fichiers sont rendus via Jekyll. Cela mériterait d’être investigué). +
    • Traduire le texte de l’Anglais vers la langue en question.
    • diff --git a/web/_site/doc/fr/how-to/write-a-blog-post/index.html b/web/_site/doc/fr/how-to/write-a-blog-post/index.html index d00abcfe2d..821fa1f823 100644 --- a/web/_site/doc/fr/how-to/write-a-blog-post/index.html +++ b/web/_site/doc/fr/how-to/write-a-blog-post/index.html @@ -141,7 +141,7 @@

      Comment Faire - Ecrire un Billet pour le Blog

      Le blog Rubinius utilise Jekyll et est intégré dans le site web et la documentation. Nous encourageons et apprécions les billets écrits par -des invités concernant vos expériences en tant qu’utilisateur ou +des invités concernant vos expériences en tant qu’utilisateur ou développeur Rubinius.

      Le format préféré pour les billets est le Markdown. Toutefois, si vous @@ -153,7 +153,7 @@

      Comment Faire - Ecrire un Billet pour le Blog

      git clone https://github.com/rubinius/rubinius.git
       
      -

      Pour démarrer, assurez-vous d’avoir installé les gems kramdown et jekyll.

      +

      Pour démarrer, assurez-vous d’avoir installé les gems kramdown et jekyll.

      rbx gem install jekyll kramdown
       
      @@ -187,9 +187,9 @@

      Comment Faire - Ecrire un Billet pour le Blog

    Soumettez un patch, une pull request, ou si vous avez les droits -d’écrire sur le dépôt, poussez sur la branche master.

    +d’écrire sur le dépôt, poussez sur la branche master.

    -

    Prévenez-nous qu’il y a un nouveau billet sur le blog. Nous pourrions +

    Prévenez-nous qu’il y a un nouveau billet sur le blog. Nous pourrions avoir des retour à vous soumettre avant de publier le billet.

    diff --git a/web/_site/doc/fr/how-to/write-a-ruby-spec/index.html b/web/_site/doc/fr/how-to/write-a-ruby-spec/index.html index 00ed00cbf1..0b6d486fdc 100644 --- a/web/_site/doc/fr/how-to/write-a-ruby-spec/index.html +++ b/web/_site/doc/fr/how-to/write-a-ruby-spec/index.html @@ -139,19 +139,19 @@

    Comment Faire - Ecrire un Test Ruby

    -

    Assurez-vous d’avoir lu:

    +

    Assurez-vous d’avoir lu:

    -

    Ensuite, suivez ces étapes pour écrire le test d’une méthode Ruby:

    +

    Ensuite, suivez ces étapes pour écrire le test d’une méthode Ruby:

    1. Editer un fichier dans spec/ruby/...
    2. Lancez bin/mspec -tr spec/ruby/le/fichier/de/test.rb
    3. -
    4. Répétez jusqu’à ce que votre test passe avec l’implémentation +
    5. Répétez jusqu’à ce que votre test passe avec l’implémentation historique MRI (aussi connue sous le nom de MatzRuby)
    6. Committez vos changements
    7. Utilisez git format-patch
    8. diff --git a/web/_site/doc/fr/how-to/write-a-ticket/index.html b/web/_site/doc/fr/how-to/write-a-ticket/index.html index fcc32e40c7..dda4ba6bda 100644 --- a/web/_site/doc/fr/how-to/write-a-ticket/index.html +++ b/web/_site/doc/fr/how-to/write-a-ticket/index.html @@ -139,16 +139,16 @@

      Comment Faire - Ecrire un Ticket

      -

      Le gestionnaire de ticket Rubinius se trouve à l’adresse http://github.com/rubinius/rubinius/issues.

      +

      Le gestionnaire de ticket Rubinius se trouve à l’adresse http://github.com/rubinius/rubinius/issues.

      -

      Pour être utile, un ticket doit être concis, précis et permettre d’agir. -S’il ne l’est pas, le ticket va engendrer des aller-tours, des -discussions, et n’avancera pas. De la même manière, les tickets doivent +

      Pour être utile, un ticket doit être concis, précis et permettre d’agir. +S’il ne l’est pas, le ticket va engendrer des aller-tours, des +discussions, et n’avancera pas. De la même manière, les tickets doivent appartir aux catégories ci-dessous:

      1. Un historique précis de ligne de commande montrant comment -installer, invoquer le programme et afficher une trace d’exécution +installer, invoquer le programme et afficher une trace d’exécution pour une exception.
      2. Un bref bout de code illustrant le problème et la ligne de commande pour le provoquer.
      3. @@ -156,15 +156,15 @@

        Comment Faire - Ecrire un Ticket

        sont toujours valides.
      -

      Si votre problème ne rentrent pas dans une des catégories, il n’est pas -invalide. Pour autant créer un ticket n’est pas approprié.

      +

      Si votre problème ne rentrent pas dans une des catégories, il n’est pas +invalide. Pour autant créer un ticket n’est pas approprié.

        -
      1. S’il s’agit d’une fonctionnalité, venez en discuter sur la +
      2. S’il s’agit d’une fonctionnalité, venez en discuter sur la mailing-list. De plus, vous pourriez également en commencer -l’implémentation afin de démontrer que votre fonctionnalité est utile.
      3. -
      4. S’il s’agit d’une librairie ou d’un gem non fonctionnel, prenez le -temps d’investiguer pour tenter de reproduire le bug et donc, de +l’implémentation afin de démontrer que votre fonctionnalité est utile.
      5. +
      6. S’il s’agit d’une librairie ou d’un gem non fonctionnel, prenez le +temps d’investiguer pour tenter de reproduire le bug et donc, de créer un ticket.
      @@ -175,7 +175,7 @@

      Procédure générale pour sou

      Vérifiez et revérifiez.

        -
      1. Recompiler entièrement (‘rake clean; rake’) après ‘git pull’, ou après avoir clôné.
      2. +
      3. Recompiler entièrement (‘rake clean; rake’) après ‘git pull’, ou après avoir clôné.
      4. Lisez la section Dépannage pour vérifier si vous trouvez une solution au problème.
      5. Lisez Tests.
      @@ -191,9 +191,9 @@

      Procédure générale pour sou
      • La ligne de commande qui invoque le programme
      • -
      • La trace d’exécution ou la différence entre le résultat attendu et le résultat actuel.
      • +
      • La trace d’exécution ou la différence entre le résultat attendu et le résultat actuel.
      • Des informations sur votre machine. uname -a suffit en général -(si toutefois il y a des champs marqués “unknown” dans le +(si toutefois il y a des champs marqués “unknown” dans le résultat de cette commande, merci de nous décrire pourquoi).
      @@ -205,24 +205,24 @@

      Procédure générale pour sou

      Instructions additionelle pour les tickets avec patchs

        -
      • Ils peuvent n’être que des suites de tests.
      • +
      • Ils peuvent n’être que des suites de tests.
      • Les patchs doivent être accompagnés de tests sauf si ces tests existent déjà.
      • Les parties intéressantes des résultats de test et les invocations -exactes des ‘bin/mspec’ à lancer, cela vaut pour les tests +exactes des ‘bin/mspec’ à lancer, cela vaut pour les tests existants comme pour les nouveaux tests.
      • Des descriptions additionnelles sur votre patch et de comment il corrige le problème. Veuillez indiquer également, en particulier pour les nouvelles fonctionnalités, si le sujet a déjà été discuté sur #rubinius ou ruby-dev.
      -

      Sauf si réellement impossible, veuillez utiliser ‘git-format-patch’ pour +

      Sauf si réellement impossible, veuillez utiliser ‘git-format-patch’ pour créer vos ensembles de patchs. Cela les rend plus facile à appliquer et préserve les attributions. Sinon, fournissez un diff.

      Exemple de soumission de patch

      -

      Supposons que la suite de test suivante existe et qu’elle soit en échec:

      +

      Supposons que la suite de test suivante existe et qu’elle soit en échec:

      describe "Kernel.format" do
         it "is accessible as a module function" do
      @@ -235,17 +235,17 @@ 

      Exemple de soumission de patch

    9. Titre du ticket:

      -

      “[PATCH] No method ‘format’ on Kernel (Module)”

      +

      “[PATCH] No method ‘format’ on Kernel (Module)”

    10. Etiquettes / Tags:

      -

      “patch core spec”

      +

      “patch core spec”

    11. Corps du ticket:

      -

      The method ‘format’ is not available as a module function of Kernel.

      +

      The method ‘format’ is not available as a module function of Kernel.

      $ bin/mspec spec/ruby/core/kernel/format_spec.rb
       Started
      @@ -256,7 +256,7 @@ 

      Exemple de soumission de patch

      No method 'format' on Kernel (Module):
      -

      The method ‘format’ already exists but has not been set as a module +

      The method ‘format’ already exists but has not been set as a module function. This patch does so.

      After the patch is applied:

      diff --git a/web/_site/doc/fr/how-to/write-benchmarks/index.html b/web/_site/doc/fr/how-to/write-benchmarks/index.html index f2d49c286e..8096b61c3f 100644 --- a/web/_site/doc/fr/how-to/write-benchmarks/index.html +++ b/web/_site/doc/fr/how-to/write-benchmarks/index.html @@ -142,7 +142,7 @@

      Comment Faire - Ecrire des Benchmarks

      Pourquoi benchmarker?

      Les Benchmarks sont de bons outils pour comparer Rubinius avec le reste -des runtimes Ruby tels que MRI, JRuby, IronRuby, etc. Il n’est pas +des runtimes Ruby tels que MRI, JRuby, IronRuby, etc. Il n’est pas réellement attendu de mesurer les performances de Rubinius lui-même donc si vous souhaitez contribuer aux benchmarks, suivez ces étapes:

      @@ -157,7 +157,7 @@

      Comment Faire - Ecrire des Benchmarks

    12. Les benchmarks ne sont pas censés mesurer Rubinius. Si vous écrivez un benchmark pour une classe avec des méthodes avec et sans !, vous devrez utiliser une variable dupliqué pour la méthode avec ! mais -vous n’aurez pas à dupliquer la variable dans la méthode sans !.
    13. +vous n’aurez pas à dupliquer la variable dans la méthode sans !.

    Si vous voulez tester un benchmark, vous pouvez exécuter

    diff --git a/web/_site/doc/fr/index.html b/web/_site/doc/fr/index.html index fce60454d0..ab5026d744 100644 --- a/web/_site/doc/fr/index.html +++ b/web/_site/doc/fr/index.html @@ -127,7 +127,7 @@

    Table des matières

      -
    1. Qu’est-ce que Rubinius?
    2. +
    3. Qu’est-ce que Rubinius?
    4. *Démarrer
      1. *Prérequis
      2. @@ -150,7 +150,7 @@

        Table des matières

      3. *Classes & Modules
      4. *Blocs & Procs
      5. *Variables locales
      6. -
      7. *Variables d’Instance
      8. +
      9. *Variables d’Instance
      10. *Variables de Classe
      11. *Variables Globales
      @@ -171,12 +171,12 @@

      Table des matières

    5. *Compilateur Bytecode
        -
      1. *Phase d’Analyse
      2. -
      3. *L’Arbre Syntaxique Abstrait
      4. +
      5. *Phase d’Analyse
      6. +
      7. *L’Arbre Syntaxique Abstrait
      8. *Phase de Génération
      9. -
      10. *Phase d’Encodage
      11. +
      12. *Phase d’Encodage
      13. *Phase de Packaging
      14. -
      15. *Phase d’Ecriture
      16. +
      17. *Phase d’Ecriture
      18. Printers
      19. *Transformations
      20. *Personnaliser le Pipeline
      21. @@ -191,7 +191,7 @@

        Table des matières

      22. *Objets Volumineux
    6. -
    7. *L’écosystème Rubinius +
    8. *L’écosystème Rubinius
      1. *Primitives
      2. *FFI
      3. diff --git a/web/_site/doc/fr/ruby/index.html b/web/_site/doc/fr/ruby/index.html index 8427c93881..e930be9f9d 100644 --- a/web/_site/doc/fr/ruby/index.html +++ b/web/_site/doc/fr/ruby/index.html @@ -176,7 +176,7 @@

        Ruby

        Often it is asserted that everything in Ruby is an object. This is not quite true. Most things in Ruby are objects, but some things that are absolutely essential for running Ruby code are not necessarily objects that you can put -your hands on. Instead, which of these “execution environment” things are +your hands on. Instead, which of these “execution environment” things are objects in Ruby depends heavily on the implementation. Scope is one of these things.

        diff --git a/web/_site/doc/fr/specs/index.html b/web/_site/doc/fr/specs/index.html index 58f1d66131..c10f7cfced 100644 --- a/web/_site/doc/fr/specs/index.html +++ b/web/_site/doc/fr/specs/index.html @@ -140,12 +140,12 @@

        Specs

        The Rubinius project generally uses TDD/BDD-style executable specifications to -drive development. The Rubinius ‘spec’ directory is conceptually divided into +drive development. The Rubinius ‘spec’ directory is conceptually divided into two parts:

          -
        1. All the files under ‘./spec/ruby’ that describe the behavior of MatzRuby.
        2. -
        3. And all the other files under the ‘./spec’ directory that describe the +
        4. All the files under ‘./spec/ruby’ that describe the behavior of MatzRuby.
        5. +
        6. And all the other files under the ‘./spec’ directory that describe the behavior of Rubinius.
        diff --git a/web/_site/doc/fr/systems/concurrency/index.html b/web/_site/doc/fr/systems/concurrency/index.html index 7ce7afd9cb..c1a5e48498 100644 --- a/web/_site/doc/fr/systems/concurrency/index.html +++ b/web/_site/doc/fr/systems/concurrency/index.html @@ -141,7 +141,7 @@

        Concurrency

        Rubinius supports the same basic concurrency constructs as Ruby, Threads and Fibers, along with a new API: Actors. Actors provide concurrency without any mutexes or locking inherent when sharing state between Threads.

        -

        Actors execute concurrently but don’t share state; instead they pass messages to other actors. Here we create two actors using Actor.spawn, ping and pong, who will send messages back and forth until they have collaboratively incremented a variable to 1000:

        +

        Actors execute concurrently but don’t share state; instead they pass messages to other actors. Here we create two actors using Actor.spawn, ping and pong, who will send messages back and forth until they have collaboratively incremented a variable to 1000:

        require 'actor'
         pong = nil
        diff --git a/web/_site/doc/fr/tools/memory-analysis/index.html b/web/_site/doc/fr/tools/memory-analysis/index.html
        index a1e35b3320..4f1e3a531b 100644
        --- a/web/_site/doc/fr/tools/memory-analysis/index.html
        +++ b/web/_site/doc/fr/tools/memory-analysis/index.html
        @@ -212,7 +212,7 @@ 

        A Sample Program

        puts "received #{messages.size} messages in #{elapsed_usecs / 1_000_000} seconds"
        -

        Wow, this program leaks like a sieve. Let’s figure out why.

        +

        Wow, this program leaks like a sieve. Let’s figure out why.

        Saving A Heap Dump

        @@ -257,7 +257,7 @@

        Analyzing A Heap Dump

        Find the heap_dump tool at its project home page.

        This tool reads the heap dump file and outputs some useful information in 3 columns -corresponding to the number of objects visible in the heap, the object’s class, and +corresponding to the number of objects visible in the heap, the object’s class, and the total number of bytes consumed by all instances of this object.

        Running the tool against a heap dump captured from our leak.rb program, it gives us @@ -287,7 +287,7 @@

        Analyzing A Heap Dump

        The largest footprint is consumed by Rubinius::CompactLookupTable which is a class that the example code never directly instantiates and weighs in at about 20MB. So, some internal Rubinius structures are reported by the heap dump. It is -interesting but doesn’t help pinpoint our particular leak.

        +interesting but doesn’t help pinpoint our particular leak.

      4. The ZMQ::Message class listed on line 3 is the first class shown that the example @@ -327,7 +327,7 @@

        Advanced Tools - OSX Only

        After modifying the Ruby code to use a simple counter and let the garbage collector handle all of the ZMQ::Message instances, the program is still leaking like mad. -Taking two snapshots and analyzing them doesn’t give any clue as to the source +Taking two snapshots and analyzing them doesn’t give any clue as to the source though.

        $ rbx -I /path/to/heap_dump/lib /path/to/heap_dump/bin/histo.rb heap3.dump heap4.dump
        @@ -385,7 +385,7 @@ 

        Advanced Tools - OSX Only

        The output shows that at the time of the snapshot we had nearly 172k leaked objects. The call stack output shows that the leak occurs during the call to zmq_msg_init_size -which doesn’t mean anything unless we dig into the implementation of ZMQ::Message`. +which doesn’t mean anything unless we dig into the implementation of ZMQ::Message`. This is where knowledge of the underlying system is critical; without knowing where this particular call is made, it would be much more difficult to track down the problem.

        diff --git a/web/_site/doc/fr/tools/profiler/index.html b/web/_site/doc/fr/tools/profiler/index.html index 9f7d018611..937723358b 100644 --- a/web/_site/doc/fr/tools/profiler/index.html +++ b/web/_site/doc/fr/tools/profiler/index.html @@ -154,7 +154,7 @@

        VM Profiler

        The Profiler lives and dies in its own world. The profiler is passed a VM instance when it is created because the profiler needs access to it while it is gathering info. The STATE argument could be passed into all the profiler -methods, but it’s simple enough to pass it in when the profiler is created. +methods, but it’s simple enough to pass it in when the profiler is created. The profiler never manipulates the VM instance. It is important to maintain this separation.

        @@ -210,7 +210,7 @@

        Ruby Profiler

        The #profile method starts the profiler, yields, stops the profiler and prints -the profile data by default. Pass ‘false’ to #profile to not print the data. +the profile data by default. Pass ‘false’ to #profile to not print the data. Either way, the profile data itself is returned by #profile.

        How to Read the Flat Profiler Output

        @@ -233,7 +233,7 @@

        cumulative seconds

        self seconds

        The total time spent in this method less the total time spent in all this -method’s callees.

        +method’s callees.

        calls

        @@ -272,7 +272,7 @@

        Example of Flat Output

        }
    -

    Running the script with ‘bin/rbx script.rb’ should give the following flat +

    Running the script with ‘bin/rbx script.rb’ should give the following flat output.

      %   cumulative   self                self     total
    @@ -299,7 +299,7 @@ 

    How to Read the Graph Output

    -Xprofiler.graph
     
    -

    Given the same script above, the graph output is shown below. Each “entry” in +

    Given the same script above, the graph output is shown below. Each “entry” in the graph has three sections: 1) the method for the entry, called the primary line; 2) the callers of the primary method; and 3) the methods that the primary method called. The fields have different meanings based on the @@ -320,7 +320,7 @@

    % time

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    @@ -335,16 +335,16 @@

    name

    The name of the method followed by the index number.

    The lines above the primary line are methods that call the primary method. The -callers’ fields have the following interpretation:

    +callers’ fields have the following interpretation:

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    -

    The time spent in the method’s call to the primary method.

    +

    The time spent in the method’s call to the primary method.

    called

    @@ -365,11 +365,11 @@

    name

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    -

    This is an estimate of the amount of time this method’s callees spent when +

    This is an estimate of the amount of time this method’s callees spent when this method was called by the primary method. The estimate is based on the ration of the time this method spent when called by the primary method to the total time spent in this method.

    diff --git a/web/_site/doc/fr/virtual-machine/instructions/index.html b/web/_site/doc/fr/virtual-machine/instructions/index.html index 2daeb45232..e08cf177a2 100644 --- a/web/_site/doc/fr/virtual-machine/instructions/index.html +++ b/web/_site/doc/fr/virtual-machine/instructions/index.html @@ -256,7 +256,7 @@

    Notes

    Unlike other literals such as strings and numbers, creating a Regexp literal (i.e. via the /regex/ syntax) is a two step process to create the literal slot for the Regexp, create a literal for the string between the - ‘/’ delimiters and create a new Regexp object passing it the string. Only + ‘/’ delimiters and create a new Regexp object passing it the string. Only then can the literal value be set, using the set_literal opcode.

    push_literal(literal)

    @@ -754,7 +754,7 @@

    pop_unwind()

    Remove the next unused unwind registration from the current invocation. This instruction is paired with setup_unwind to remove registrations - when control exits a section of code that registered a handler but didn’t + when control exits a section of code that registered a handler but didn’t use it. For example, exiting a begin that had a rescue expression.

    @@ -1351,7 +1351,7 @@

    cast_for_multi_block_ the arg is an array.

    If the Proc invoked from was in lambda mode, and one argument is passed: - * and it’s an Array, push it. + * and it’s an Array, push it. * and it responds to #to_ary, try and convert it and push it. * otherwise wrap it in a one element Array and push it.

    @@ -1637,7 +1637,7 @@

    Notes

    runtime to determine which code path is executed.

    For example, a method such as Fixnum#times can be optimised at compile - time, but we can’t know until runtime whether or not the Fixnum#times + time, but we can’t know until runtime whether or not the Fixnum#times method has been overridden. The serial number check is used to determine each time the code is executed, whether or not the standard Fixnum#times has been overridden. It leverages the serial number field on a @@ -1646,7 +1646,7 @@

    Notes

    check_serial_private(literal, serial)

    -

    Checks if the specified method’s serial number matches an expected value. +

    Checks if the specified method’s serial number matches an expected value. Considers private methods too.

    @@ -1934,7 +1934,7 @@

    meta_send_op_tequal(litera

    Notes

    -

    Exactly like equal, except calls #=== if it can’t handle it directly.

    +

    Exactly like equal, except calls #=== if it can’t handle it directly.

    meta_send_call(literal, count)

    @@ -2225,7 +2225,7 @@

    call_custom(literal, count)

    meta_to_s(literal)

    -

    Pop a value off the stack and if it’s not a String, call a method +

    Pop a value off the stack and if it’s not a String, call a method indicated by literal on it. Push the resulting object back on the stack.

    diff --git a/web/_site/doc/fr/what-is-rubinius/index.html b/web/_site/doc/fr/what-is-rubinius/index.html index b8cf66e243..4dbf8f21b1 100644 --- a/web/_site/doc/fr/what-is-rubinius/index.html +++ b/web/_site/doc/fr/what-is-rubinius/index.html @@ -136,7 +136,7 @@

    -

    Qu’est-ce que Rubinius ?

    +

    Qu’est-ce que Rubinius ?

    Rubinius est une implémentation du langage de programmation Ruby.

    @@ -152,7 +152,7 @@

    Licence

    Installer

    -

    Rubinius fonctionne sur Max OS X et de nombreux systèmes d’exploitation Unix/Linux. +

    Rubinius fonctionne sur Max OS X et de nombreux systèmes d’exploitation Unix/Linux. Le support de Microsoft Windows est à venir prochainement.

    Pour installer Rubinius, suivez les instructions suivantes. Pour des informations plus détaillées, @@ -165,8 +165,8 @@

    Installer

  • rake install
  • -

    Quand le processus d’installation se termine, suivez les indications pour ajouter -le répertoire des exécutables Rubinius (bin) à votre variable d’environnement PATH.

    +

    Quand le processus d’installation se termine, suivez les indications pour ajouter +le répertoire des exécutables Rubinius (bin) à votre variable d’environnement PATH.

    Rubinius est fourni avec RubyGems intégré, et les gems rake et rdoc pré-installées. Pour installer la gem nokogiri par exemple, exécutez rbx gem install nokogiri.

    diff --git a/web/_site/doc/ja/appendix-a-glossary/index.html b/web/_site/doc/ja/appendix-a-glossary/index.html index 1bc83bde7c..3a73d1959b 100644 --- a/web/_site/doc/ja/appendix-a-glossary/index.html +++ b/web/_site/doc/ja/appendix-a-glossary/index.html @@ -158,9 +158,9 @@

    Appendix A - Glossary

    Definitions of terms and phrases used in the Ruby programming language and in -this implementation. See also “The Ruby Programming Language” by Flanagan and -Matsumoto [O’Reilly 2008] and “Programming Ruby: The Pragmatic Programmer’s -Guide” 2nd or 3rd Edition by Thomas et al [The Pragmatic Programmers +this implementation. See also “The Ruby Programming Language” by Flanagan and +Matsumoto [O’Reilly 2008] and “Programming Ruby: The Pragmatic Programmer’s +Guide” 2nd or 3rd Edition by Thomas et al [The Pragmatic Programmers 2005-2008]

      @@ -169,7 +169,7 @@

      Appendix A - Glossary

      The rule is simple: Take the object located in the class slot of the object (which is not always the return value of Object#class; if the object has one, -it’ll be the singleton class) and begin searching.

      +it’ll be the singleton class) and begin searching.

      Searching goes up the superclass chain until the superclass is nil.

      @@ -228,7 +228,7 @@

      Appendix A - Glossary

      1. -

        Resolve method ‘wanker’ – search method_tables in:

        +

        Resolve method ‘wanker’ – search method_tables in:

        1. SingletonClass(F)
        2. @@ -246,7 +246,7 @@

          Appendix A - Glossary

          A data structure in every class (and module) that contains the methods defined for that class.

          -

          In Rubinius, a class’s method_table is an instance of LookupTable.

          +

          In Rubinius, a class’s method_table is an instance of LookupTable.

        3. MatzRuby

          @@ -256,7 +256,7 @@

          Appendix A - Glossary

        4. MRI

          -

          Matz’s Ruby Interpreter or Matz’s Ruby Implementation. A short name to refer +

          Matz’s Ruby Interpreter or Matz’s Ruby Implementation. A short name to refer to the official implementation of Ruby. See http://ruby-lang.org.

        5. @@ -305,8 +305,8 @@

          Appendix A - Glossary

    Since all classes in Ruby are also objects, they can have singleton classes. -The methods called “class methods” are just methods in the method_table of -the class’s singleton class. The method +honk+ exists in the singleton class +The methods called “class methods” are just methods in the method_table of +the class’s singleton class. The method +honk+ exists in the singleton class for the class +Car+.

    class Car
    @@ -318,7 +318,7 @@ 

    Appendix A - Glossary

    In Rubinius, singleton classes are all instances of the class SingletonClass. The singleton class for an object can be obtained by calling the +singleton_class+ method. The overall arrangement of concepts involved -here is sometimes referred to as the ‘Meta-Object Protocol’ or +MOP+.

    +here is sometimes referred to as the ‘Meta-Object Protocol’ or +MOP+.

  • superclass

    diff --git a/web/_site/doc/ja/appendix-b-reading-list/index.html b/web/_site/doc/ja/appendix-b-reading-list/index.html index 28234eb543..fbff05ad2f 100644 --- a/web/_site/doc/ja/appendix-b-reading-list/index.html +++ b/web/_site/doc/ja/appendix-b-reading-list/index.html @@ -158,9 +158,9 @@

    Appendix B - Reading List

    Building virtual machines in general and programming language implementations -in particular requires some knowledge. Rubinius’ goal is to lower the barrier +in particular requires some knowledge. Rubinius’ goal is to lower the barrier by keeping as much as possible in Ruby but to hack on the garbage collector you -have to understand what’s going on behind the curtains.

    +have to understand what’s going on behind the curtains.

    This page contains references to books, online lectures, blog posts and any other publications you may find useful for working on Rubinius.

    @@ -171,7 +171,7 @@

    Virtual machine

    • Smalltalk-80: language and its implementation -by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation +by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation chapters from part IV are available online
    • Virtual machines by Iain D. Craig
    • Great posts by Adam Gardiner: introduction, @@ -200,7 +200,7 @@

      FFI

      diff --git a/web/_site/doc/ja/build-system/index.html b/web/_site/doc/ja/build-system/index.html index d8dd5f378f..8d9f4549fe 100644 --- a/web/_site/doc/ja/build-system/index.html +++ b/web/_site/doc/ja/build-system/index.html @@ -186,7 +186,7 @@

      Development versus Install Builds

      not function, even if the executable is in the directory. The executable checks a single, hard-coded path. If this ends up being very painful for some reason, -we’ll revise it.

      +we’ll revise it.

      Installing Rubinius

      @@ -195,11 +195,11 @@

      Installing Rubinius

      ./configure --prefix=/path/to/install/dir
       
      -

      The configure process creates a ‘config.rb’ file that specifies the key file -paths that Rubinius uses. Once configured, run ‘rake install’ to build and +

      The configure process creates a ‘config.rb’ file that specifies the key file +paths that Rubinius uses. Once configured, run ‘rake install’ to build and install. The install procedure builds all the files, including compiling the Ruby standard library files in the lib/ directory, then copies them into the -install location using the ‘install’ program. The install tasks are located in +install location using the ‘install’ program. The install tasks are located in rakelib/install.rake.

      diff --git a/web/_site/doc/ja/bytecode-compiler/transformations/index.html b/web/_site/doc/ja/bytecode-compiler/transformations/index.html index f639f0ab56..d1be9d927b 100644 --- a/web/_site/doc/ja/bytecode-compiler/transformations/index.html +++ b/web/_site/doc/ja/bytecode-compiler/transformations/index.html @@ -175,7 +175,7 @@

      Safe Math Compiler Transform

      その大切な特徴の一つが、それも本当に両刃の剣である いくつかの点。

      -

      In the standard library the ‘mathn’ library redefines Fixnum#/ in an unsafe +

      In the standard library the ‘mathn’ library redefines Fixnum#/ in an unsafe and incompatible manner. The library aliases Fixnum#/ to Fixnum#quo, which returns a Float by default.

      @@ -185,7 +185,7 @@

      Safe Math Compiler Transform

      define this method.

      安全な数学は、コアのコンパイル時に有効になっている変換 -ライブラリは、プラグインを有効にします。通常の’user code’をコンパイル中に、 +ライブラリは、プラグインを有効にします。通常の’user code’をコンパイル中に、 有効になっていないプラグインです。これは、壊すことなく、mathnをサポートすることを可能に コアライブラリや不便な慣行を余儀なくされた。

      diff --git a/web/_site/doc/ja/contributing/index.html b/web/_site/doc/ja/contributing/index.html index 1918fe6c91..eefbfe47e7 100644 --- a/web/_site/doc/ja/contributing/index.html +++ b/web/_site/doc/ja/contributing/index.html @@ -181,7 +181,7 @@

      Write Specs

      tagged as incomplete. These specs may simply need review, or there could be specs missing for a particular class.

      -

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will +

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will show tags for all the specs that should run on Rubinius. Or you can specify any subdirectory of the spec/ directory to list tags for specs in that subdirectory.

      @@ -198,7 +198,7 @@

      Fix Failing Specs

    • Run bin/mspec tag --list fails <dir> to show specs tagged as failing.

      -

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will +

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will show tags for all the specs that should run on Rubinius. Or you can specify any subdirectory of the spec/ directory to list tags for specs in that subdirectory.

      diff --git a/web/_site/doc/ja/contributing/style-guide/index.html b/web/_site/doc/ja/contributing/style-guide/index.html index c342c839eb..63f3043c9a 100644 --- a/web/_site/doc/ja/contributing/style-guide/index.html +++ b/web/_site/doc/ja/contributing/style-guide/index.html @@ -179,10 +179,10 @@

      C++ Code

    • Alternate versions of functions should be named why they are different -from the primary. If there is a function ‘person()’ and you want a +from the primary. If there is a function ‘person()’ and you want a version that takes the name of the person, it should be -‘person_with_name(char *name)’ or ‘person_with_details(char *name, …)’. -NOT ‘person1(char *name)’.

      +‘person_with_name(char *name)’ or ‘person_with_details(char *name, …)’. +NOT ‘person1(char *name)’.

    @@ -190,16 +190,16 @@

    Ruby Code

    • -

      Methods: Try to keep your methods short–one screenful and try to adhere +

      Methods: Try to keep your methods short–one screenful and try to adhere to DRY within reason. Generally common functionality should be abstracted -to helper methods (which you can make ‘private’) but in some cases, +to helper methods (which you can make ‘private’) but in some cases, particularly working with Core, sometimes trying to DRY things up is just an obstacle if you have to maneuver around several different error conditions, for example.

    • Method names: should be clear, expressive and meaningful. Avoid using -underscores to ‘protect’ the method (‘__send__’) with some exceptions.

      +underscores to ‘protect’ the method (‘__send__’) with some exceptions.

    • Smalltalk-style method names are OK, meaning that you could have a method @@ -210,8 +210,8 @@

      Ruby Code

    • Variable names: make them clear and meaningful (with some well-known -exceptions like using ‘i’ for a counter.) Try to avoid shadowing method -names, for example within Array use ‘idx’ in favour of ‘index’ because the +exceptions like using ‘i’ for a counter.) Try to avoid shadowing method +names, for example within Array use ‘idx’ in favour of ‘index’ because the latter is also a method name.

    • diff --git a/web/_site/doc/ja/getting-started/building/index.html b/web/_site/doc/ja/getting-started/building/index.html index d2c8aefa07..bc38eac4c3 100644 --- a/web/_site/doc/ja/getting-started/building/index.html +++ b/web/_site/doc/ja/getting-started/building/index.html @@ -194,10 +194,10 @@

      Running from the Source Directory

      rake
    • -

      あなただけのRubiniusのをしようとしている場合は、_bin_を追加して指示に従ってください +

      あなただけのRubiniusのをしようとしている場合は、binを追加して指示に従ってください PATHにディレクトリを指定します。

      -

      ただし、Rubiniusの開発を行っている場合は、NOTは_bin_を追加する必要があります。 +

      ただし、Rubiniusの開発を行っている場合は、NOTはbinを追加する必要があります。 Rubiniusはシステムを構築するため、PATHにディレクトリをピックアップする rubyのと熊手はRubiniusの実行可能ファイルへのリンクを示します。 Rubiniusは別のを必要とする Rubyは実行可能なプロセスを構築する時に自分自身をブートストラップする。

      diff --git a/web/_site/doc/ja/getting-started/running-rubinius/index.html b/web/_site/doc/ja/getting-started/running-rubinius/index.html index 7dab8c038d..503bf37fb1 100644 --- a/web/_site/doc/ja/getting-started/running-rubinius/index.html +++ b/web/_site/doc/ja/getting-started/running-rubinius/index.html @@ -159,7 +159,7 @@

      Running Rubinius

      rbx -e 'puts "Hello!"'
       
      -

      To run a ruby file named ‘code.rb’:

      +

      To run a ruby file named ‘code.rb’:

      rbx code.rb
       
      diff --git a/web/_site/doc/ja/how-to/fix-a-failing-spec/index.html b/web/_site/doc/ja/how-to/fix-a-failing-spec/index.html index aceb575cb7..5c7971bf15 100644 --- a/web/_site/doc/ja/how-to/fix-a-failing-spec/index.html +++ b/web/_site/doc/ja/how-to/fix-a-failing-spec/index.html @@ -172,14 +172,14 @@

      How-To - Fix a Failing Spec

      changes made to other Rubinius source code files.
    • Run git format-patch origin, which will extract commits that the current branch accumulated since the last pull from origin, or `git format-patch --N’, where N is the number (1, 2, etc.) of commits for which you want to +-N’, where N is the number (1, 2, etc.) of commits for which you want to generate patches.
    • Create a gist with your patch and link to it in a ticket on the issue tracker at http://github.com/rubinius/rubinius/issues. You can add multiple patches to one ticket.
    • -

      When your patch is accepted by the Rubinius project, you’ll get a commit bit +

      When your patch is accepted by the Rubinius project, you’ll get a commit bit for the Rubinius repository. Let Evan know what your Github username is.

      diff --git a/web/_site/doc/ja/how-to/write-a-ticket/index.html b/web/_site/doc/ja/how-to/write-a-ticket/index.html index 4ba3605dfb..40c2248ccd 100644 --- a/web/_site/doc/ja/how-to/write-a-ticket/index.html +++ b/web/_site/doc/ja/how-to/write-a-ticket/index.html @@ -163,7 +163,7 @@

      How-To - Write a Ticket

      the spec runs before and after applying the patch. -

      If your issue doesn’t fit into one of the categories, it is not invalid. It is +

      If your issue doesn’t fit into one of the categories, it is not invalid. It is simply not appropriate for a ticket.

        @@ -182,7 +182,7 @@

        General procedure for submitt

        Double-check.

          -
        1. Do a full rebuild (‘rake clean; rake’) after a ‘git pull’ or fresh clone.
        2. +
        3. Do a full rebuild (‘rake clean; rake’) after a ‘git pull’ or fresh clone.
        4. Read Troubleshooting to see if something there resolves the issue.
        5. Read Specs.
        6. @@ -201,7 +201,7 @@

          General procedure for submitt
        7. The command line for invoking the program
        8. The backtrace or result from the program versus expected result.
        9. Your machine information. uname -a is usually good (if there are any -“unknown” fields in it, please elaborate on those.)
        10. +“unknown” fields in it, please elaborate on those.)

  • @@ -211,16 +211,16 @@

    Additional instruction
    • Can be just a set of specs.
    • Patches must be accompanied by specs unless the specs already exist.
    • -
    • Relevant part of spec output and the exact ‘bin/mspec’ invocation from the +
    • Relevant part of spec output and the exact ‘bin/mspec’ invocation from the existing or added spec before the fix.
    • -
    • The spec output and the exact ‘bin/mspec’ invocation showing success +
    • The spec output and the exact ‘bin/mspec’ invocation showing success after the fix.
    • Additional description of your patch and how it fixes the problem. In particular with new functionality please indicate if it was already discussed on #rubinius or ruby-dev.
    -

    Unless for some reason impossible, please use ‘git-format-patch’ to create the +

    Unless for some reason impossible, please use ‘git-format-patch’ to create the patchset. It is much easier to apply and it preserves the correct attribution. Otherwise, a unified diff.

    @@ -239,17 +239,17 @@

    Example of submitting a patch

  • Ticket Title:

    -

    “[PATCH] No method ‘format’ on Kernel (Module)”

    +

    “[PATCH] No method ‘format’ on Kernel (Module)”

  • Tags:

    -

    “patch core spec”

    +

    “patch core spec”

  • Ticket Message:

    -

    The method ‘format’ is not available as a module function of Kernel.

    +

    The method ‘format’ is not available as a module function of Kernel.

    $ bin/mspec spec/ruby/core/kernel/format_spec.rb
     Started
    @@ -260,7 +260,7 @@ 

    Example of submitting a patch

    No method 'format' on Kernel (Module):
    -

    The method ‘format’ already exists but has not been set as a module +

    The method ‘format’ already exists but has not been set as a module function. This patch does so.

    After the patch is applied:

    diff --git a/web/_site/doc/ja/how-to/write-documentation/index.html b/web/_site/doc/ja/how-to/write-documentation/index.html index 29df0e0237..252b76f1b4 100644 --- a/web/_site/doc/ja/how-to/write-documentation/index.html +++ b/web/_site/doc/ja/how-to/write-documentation/index.html @@ -179,15 +179,15 @@

    How-To - Write Documentation

    ---
  • -

    _layout_の書式設定時に使用するジキルのレイアウトを指定する -ドキュメント。 _layout_は`doc_LANGする必要があります、_LANG_は、ISO- 639- 2です +

    layoutの書式設定時に使用するジキルのレイアウトを指定する +ドキュメント。 layoutは`doc_LANGする必要があります、LANGは、ISO- 639- 2です 言語のコード。

    -

    _title_の上部に表示されている文書のタイトルを指定します。 +

    titleの上部に表示されている文書のタイトルを指定します。 ページを表示します。

    -

    _previous_と_previous_url_属性は、タイトルとリンクを与える -以前のドキュメント。同様に、_next_と_next_url_属性を与える +

    previousprevious_url属性は、タイトルとリンクを与える +以前のドキュメント。同様に、nextnext_url属性を与える タイトルと、次のドキュメントのリンクをクリックします。これらは、閲覧を強化するために使用されている ドキュメントや作業量を再注文部品の必要な制限 マニュアルを参照してください

    diff --git a/web/_site/doc/ja/specs/index.html b/web/_site/doc/ja/specs/index.html index 4bdf5f5516..dd648890c8 100644 --- a/web/_site/doc/ja/specs/index.html +++ b/web/_site/doc/ja/specs/index.html @@ -149,12 +149,12 @@

    Specs

    The Rubinius project generally uses TDD/BDD-style executable specifications to -drive development. The Rubinius ‘spec’ directory is conceptually divided into +drive development. The Rubinius ‘spec’ directory is conceptually divided into two parts:

      -
    1. All the files under ‘./spec/ruby’ that describe the behavior of MatzRuby.
    2. -
    3. And all the other files under the ‘./spec’ directory that describe the +
    4. All the files under ‘./spec/ruby’ that describe the behavior of MatzRuby.
    5. +
    6. And all the other files under the ‘./spec’ directory that describe the behavior of Rubinius.
    diff --git a/web/_site/doc/ja/tools/profiler/index.html b/web/_site/doc/ja/tools/profiler/index.html index ec541630d3..d6833af0aa 100644 --- a/web/_site/doc/ja/tools/profiler/index.html +++ b/web/_site/doc/ja/tools/profiler/index.html @@ -219,7 +219,7 @@

    Rubyのプロファイラを

    #profileはメソッドは、プロファイラを、利回り起動し、プロファイラを停止し、出力 -デフォルトではプロファイルデータ。パスは、’false’にデータを印刷しないように#profileする。 +デフォルトではプロファイルデータ。パスは、’false’にデータを印刷しないように#profileする。 どちらにしても、プロファイルデータ自体は#profileによって返されます。

    How to Read the Flat Profiler Output

    @@ -242,7 +242,7 @@

    cumulative seconds

    self seconds

    The total time spent in this method less the total time spent in all this -method’s callees.

    +method’s callees.

    calls

    @@ -281,7 +281,7 @@

    Example of Flat Output

    } -

    Running the script with ‘bin/rbx script.rb’ should give the following flat +

    Running the script with ‘bin/rbx script.rb’ should give the following flat output.

      %   cumulative   self                self     total
    @@ -308,7 +308,7 @@ 

    How to Read the Graph Output

    -Xprofiler.graph
     
    -

    Given the same script above, the graph output is shown below. Each “entry” in +

    Given the same script above, the graph output is shown below. Each “entry” in the graph has three sections: 1) the method for the entry, called the primary line; 2) the callers of the primary method; and 3) the methods that the primary method called. The fields have different meanings based on the @@ -329,7 +329,7 @@

    % time

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    @@ -344,16 +344,16 @@

    name

    The name of the method followed by the index number.

    The lines above the primary line are methods that call the primary method. The -callers’ fields have the following interpretation:

    +callers’ fields have the following interpretation:

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    -

    The time spent in the method’s call to the primary method.

    +

    The time spent in the method’s call to the primary method.

    called

    @@ -374,11 +374,11 @@

    name

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    -

    This is an estimate of the amount of time this method’s callees spent when +

    This is an estimate of the amount of time this method’s callees spent when this method was called by the primary method. The estimate is based on the ration of the time this method spent when called by the primary method to the total time spent in this method.

    diff --git a/web/_site/doc/ja/virtual-machine/instructions/index.html b/web/_site/doc/ja/virtual-machine/instructions/index.html index 7c41f1bcd1..292d44c641 100644 --- a/web/_site/doc/ja/virtual-machine/instructions/index.html +++ b/web/_site/doc/ja/virtual-machine/instructions/index.html @@ -265,7 +265,7 @@

    Notes

    Unlike other literals such as strings and numbers, creating a Regexp literal (i.e. via the /regex/ syntax) is a two step process to create the literal slot for the Regexp, create a literal for the string between the - ‘/’ delimiters and create a new Regexp object passing it the string. Only + ‘/’ delimiters and create a new Regexp object passing it the string. Only then can the literal value be set, using the set_literal opcode.

    push_literal(literal)

    @@ -763,7 +763,7 @@

    pop_unwind()

    Remove the next unused unwind registration from the current invocation. This instruction is paired with setup_unwind to remove registrations - when control exits a section of code that registered a handler but didn’t + when control exits a section of code that registered a handler but didn’t use it. For example, exiting a begin that had a rescue expression.

    @@ -1360,7 +1360,7 @@

    cast_for_multi_block_ the arg is an array.

    If the Proc invoked from was in lambda mode, and one argument is passed: - * and it’s an Array, push it. + * and it’s an Array, push it. * and it responds to #to_ary, try and convert it and push it. * otherwise wrap it in a one element Array and push it.

    @@ -1646,7 +1646,7 @@

    Notes

    runtime to determine which code path is executed.

    For example, a method such as Fixnum#times can be optimised at compile - time, but we can’t know until runtime whether or not the Fixnum#times + time, but we can’t know until runtime whether or not the Fixnum#times method has been overridden. The serial number check is used to determine each time the code is executed, whether or not the standard Fixnum#times has been overridden. It leverages the serial number field on a @@ -1655,7 +1655,7 @@

    Notes

    check_serial_private(literal, serial)

    -

    Checks if the specified method’s serial number matches an expected value. +

    Checks if the specified method’s serial number matches an expected value. Considers private methods too.

    @@ -1943,7 +1943,7 @@

    meta_send_op_tequal(litera

    Notes

    -

    Exactly like equal, except calls #=== if it can’t handle it directly.

    +

    Exactly like equal, except calls #=== if it can’t handle it directly.

    meta_send_call(literal, count)

    @@ -2234,7 +2234,7 @@

    call_custom(literal, count)

    meta_to_s(literal)

    -

    Pop a value off the stack and if it’s not a String, call a method +

    Pop a value off the stack and if it’s not a String, call a method indicated by literal on it. Push the resulting object back on the stack.

    diff --git a/web/_site/doc/pl/appendix-a-glossary/index.html b/web/_site/doc/pl/appendix-a-glossary/index.html index de168cf816..6a9731bcd2 100644 --- a/web/_site/doc/pl/appendix-a-glossary/index.html +++ b/web/_site/doc/pl/appendix-a-glossary/index.html @@ -149,9 +149,9 @@

    Dodatek A - Słowniczek

    Definitions of terms and phrases used in the Ruby programming language and in -this implementation. See also “The Ruby Programming Language” by Flanagan and -Matsumoto [O’Reilly 2008] and “Programming Ruby: The Pragmatic Programmer’s -Guide” 2nd or 3rd Edition by Thomas et al [The Pragmatic Programmers +this implementation. See also “The Ruby Programming Language” by Flanagan and +Matsumoto [O’Reilly 2008] and “Programming Ruby: The Pragmatic Programmer’s +Guide” 2nd or 3rd Edition by Thomas et al [The Pragmatic Programmers 2005-2008]

      @@ -160,7 +160,7 @@

      Dodatek A - Słowniczek

      The rule is simple: Take the object located in the class slot of the object (which is not always the return value of Object#class; if the object has one, -it’ll be the singleton class) and begin searching.

      +it’ll be the singleton class) and begin searching.

      Searching goes up the superclass chain until the superclass is nil.

      @@ -219,7 +219,7 @@

      Dodatek A - Słowniczek

      1. -

        Resolve method ‘wanker’ – search method_tables in:

        +

        Resolve method ‘wanker’ – search method_tables in:

        1. SingletonClass(F)
        2. @@ -237,7 +237,7 @@

          Dodatek A - Słowniczek

          A data structure in every class (and module) that contains the methods defined for that class.

          -

          In Rubinius, a class’s method_table is an instance of LookupTable.

          +

          In Rubinius, a class’s method_table is an instance of LookupTable.

        3. MatzRuby

          @@ -247,7 +247,7 @@

          Dodatek A - Słowniczek

        4. MRI

          -

          Matz’s Ruby Interpreter or Matz’s Ruby Implementation. A short name to refer +

          Matz’s Ruby Interpreter or Matz’s Ruby Implementation. A short name to refer to the official implementation of Ruby. See http://ruby-lang.org.

        5. @@ -296,8 +296,8 @@

          Dodatek A - Słowniczek

    Since all classes in Ruby are also objects, they can have singleton classes. -The methods called “class methods” are just methods in the method_table of -the class’s singleton class. The method +honk+ exists in the singleton class +The methods called “class methods” are just methods in the method_table of +the class’s singleton class. The method +honk+ exists in the singleton class for the class +Car+.

    class Car
    @@ -309,7 +309,7 @@ 

    Dodatek A - Słowniczek

    In Rubinius, singleton classes are all instances of the class SingletonClass. The singleton class for an object can be obtained by calling the +singleton_class+ method. The overall arrangement of concepts involved -here is sometimes referred to as the ‘Meta-Object Protocol’ or +MOP+.

    +here is sometimes referred to as the ‘Meta-Object Protocol’ or +MOP+.

  • superclass

    diff --git a/web/_site/doc/pl/appendix-b-reading-list/index.html b/web/_site/doc/pl/appendix-b-reading-list/index.html index 1fbdb2f98b..6c1070e431 100644 --- a/web/_site/doc/pl/appendix-b-reading-list/index.html +++ b/web/_site/doc/pl/appendix-b-reading-list/index.html @@ -149,9 +149,9 @@

    Dodatek B - Warte przeczytania

    Building virtual machines in general and programming language implementations -in particular requires some knowledge. Rubinius’ goal is to lower the barrier +in particular requires some knowledge. Rubinius’ goal is to lower the barrier by keeping as much as possible in Ruby but to hack on the garbage collector you -have to understand what’s going on behind the curtains.

    +have to understand what’s going on behind the curtains.

    This page contains references to books, online lectures, blog posts and any other publications you may find useful for working on Rubinius.

    @@ -162,7 +162,7 @@

    Virtual machine

    • Smalltalk-80: language and its implementation -by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation +by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation chapters from part IV are available online
    • Virtual machines by Iain D. Craig
    • Great posts by Adam Gardiner: introduction, @@ -191,7 +191,7 @@

      FFI

      diff --git a/web/_site/doc/pl/build-system/index.html b/web/_site/doc/pl/build-system/index.html index 7dae2fcecb..15ad2f76c2 100644 --- a/web/_site/doc/pl/build-system/index.html +++ b/web/_site/doc/pl/build-system/index.html @@ -177,7 +177,7 @@

      Development versus Install Builds

      not function, even if the executable is in the directory. The executable checks a single, hard-coded path. If this ends up being very painful for some reason, -we’ll revise it.

      +we’ll revise it.

      Installing Rubinius

      @@ -186,11 +186,11 @@

      Installing Rubinius

      ./configure --prefix=/path/to/install/dir
       
      -

      The configure process creates a ‘config.rb’ file that specifies the key file -paths that Rubinius uses. Once configured, run ‘rake install’ to build and +

      The configure process creates a ‘config.rb’ file that specifies the key file +paths that Rubinius uses. Once configured, run ‘rake install’ to build and install. The install procedure builds all the files, including compiling the Ruby standard library files in the lib/ directory, then copies them into the -install location using the ‘install’ program. The install tasks are located in +install location using the ‘install’ program. The install tasks are located in rakelib/install.rake.

      diff --git a/web/_site/doc/pl/bytecode-compiler/generator/index.html b/web/_site/doc/pl/bytecode-compiler/generator/index.html index 045d0a9f89..86b4b8a169 100644 --- a/web/_site/doc/pl/bytecode-compiler/generator/index.html +++ b/web/_site/doc/pl/bytecode-compiler/generator/index.html @@ -155,7 +155,7 @@

      Etap generowania

      i wywołaniu na głównym węźle drzewa AST metody, która wygeneruje bajtkod na obiekcie Generator.

      -

      Klasa Generator zapewnia mini język DSL (napisany w “czystym” Ruby) +

      Klasa Generator zapewnia mini język DSL (napisany w “czystym” Ruby) służący do generowania bajtkodu Rubiniusa. Generator udostępnia metody, które przekładają się bezpośrednio na instrukcje dla maszyny wirtualnej. Dla przykładu aby diff --git a/web/_site/doc/pl/bytecode-compiler/parser/index.html b/web/_site/doc/pl/bytecode-compiler/parser/index.html index 7f7578952c..dcccb4a79b 100644 --- a/web/_site/doc/pl/bytecode-compiler/parser/index.html +++ b/web/_site/doc/pl/bytecode-compiler/parser/index.html @@ -154,7 +154,7 @@

      Etap parsowania

      Sam parser (zwany Melbourne) składa się z części napisanej w C (jest to ten sam parser, który jest używany w MRI Matz Ruby Interpreter - czyli implementacji -referencyjnej Ruby napisanej przez Matz’a) oraz z części napisanej w +referencyjnej Ruby napisanej przez Matz’a) oraz z części napisanej w Ruby, która jest odpowiedzialna za utworzenie Drzewa AST w Ruby. Parser w C komunikuje się z Ruby wywołując metodę dla każdego węzła w drzewie AST.

      diff --git a/web/_site/doc/pl/bytecode-compiler/transformations/index.html b/web/_site/doc/pl/bytecode-compiler/transformations/index.html index 2d84ae6538..5b5bbd9039 100644 --- a/web/_site/doc/pl/bytecode-compiler/transformations/index.html +++ b/web/_site/doc/pl/bytecode-compiler/transformations/index.html @@ -167,7 +167,7 @@

      Transformacja Bezpie będą w stanie na przykład policzyć odpowiedniej długości. Dynamiczna natura Rubiego jest kijem z dwoma końcami w tym przypadku.

      -

      W bibliotece standardowej ‘mathn’ przedefiniowuje Fixnum#/ w sposób +

      W bibliotece standardowej ‘mathn’ przedefiniowuje Fixnum#/ w sposób niebezpieczny i niekompatybilny. Biblioteka ta przypisuje Fixnum#/ to Fixnum#quo, która to metoda zwraca domyślnie Float.

      diff --git a/web/_site/doc/pl/contributing/style-guide/index.html b/web/_site/doc/pl/contributing/style-guide/index.html index ae50f43003..a3807088ca 100644 --- a/web/_site/doc/pl/contributing/style-guide/index.html +++ b/web/_site/doc/pl/contributing/style-guide/index.html @@ -170,10 +170,10 @@

      C++ Code

    • Alternate versions of functions should be named why they are different -from the primary. If there is a function ‘person()’ and you want a +from the primary. If there is a function ‘person()’ and you want a version that takes the name of the person, it should be -‘person_with_name(char *name)’ or ‘person_with_details(char *name, …)’. -NOT ‘person1(char *name)’.

      +‘person_with_name(char *name)’ or ‘person_with_details(char *name, …)’. +NOT ‘person1(char *name)’.

    @@ -181,16 +181,16 @@

    Ruby Code

    • -

      Methods: Try to keep your methods short–one screenful and try to adhere +

      Methods: Try to keep your methods short–one screenful and try to adhere to DRY within reason. Generally common functionality should be abstracted -to helper methods (which you can make ‘private’) but in some cases, +to helper methods (which you can make ‘private’) but in some cases, particularly working with Core, sometimes trying to DRY things up is just an obstacle if you have to maneuver around several different error conditions, for example.

    • Method names: should be clear, expressive and meaningful. Avoid using -underscores to ‘protect’ the method (‘__send__’) with some exceptions.

      +underscores to ‘protect’ the method (‘__send__’) with some exceptions.

    • Smalltalk-style method names are OK, meaning that you could have a method @@ -201,8 +201,8 @@

      Ruby Code

    • Variable names: make them clear and meaningful (with some well-known -exceptions like using ‘i’ for a counter.) Try to avoid shadowing method -names, for example within Array use ‘idx’ in favour of ‘index’ because the +exceptions like using ‘i’ for a counter.) Try to avoid shadowing method +names, for example within Array use ‘idx’ in favour of ‘index’ because the latter is also a method name.

    • diff --git a/web/_site/doc/pl/getting-started/building/index.html b/web/_site/doc/pl/getting-started/building/index.html index 6e35ce44c9..2968e5ca5f 100644 --- a/web/_site/doc/pl/getting-started/building/index.html +++ b/web/_site/doc/pl/getting-started/building/index.html @@ -158,9 +158,9 @@

      Kompilacja Rubiniusa

      Pobieranie kodu źródłowego

      Kod źródłowy Rubiniusa dostępny jest jako archiwum tar oraz jako -projekt na Github’ie. Archiwum tar możesz pobrać tutaj.

      +projekt na Github’ie. Archiwum tar możesz pobrać tutaj.

      -

      Pobieranie źródeł przy pomocy Git’a:

      +

      Pobieranie źródeł przy pomocy Git’a:

      1. cd docelowy_katalog
      2. diff --git a/web/_site/doc/pl/getting-started/requirements/index.html b/web/_site/doc/pl/getting-started/requirements/index.html index f5a90ef03b..9b2ded3426 100644 --- a/web/_site/doc/pl/getting-started/requirements/index.html +++ b/web/_site/doc/pl/getting-started/requirements/index.html @@ -166,7 +166,7 @@

        Apple OS X

        Najprostszym sposobem przygotowania środowiska w systemie Apple OS X jest zainstalowanie narzędzi XCode. Po zainstalowaniu, uaktywnij -“developer mode crash reporting”: /Developer/Applications/Utilities/CrashReporterPrefs.app

        +“developer mode crash reporting”: /Developer/Applications/Utilities/CrashReporterPrefs.app

        Debian/Ubuntu

        diff --git a/web/_site/doc/pl/getting-started/running-rubinius/index.html b/web/_site/doc/pl/getting-started/running-rubinius/index.html index ed301aac79..51cb3c2723 100644 --- a/web/_site/doc/pl/getting-started/running-rubinius/index.html +++ b/web/_site/doc/pl/getting-started/running-rubinius/index.html @@ -150,7 +150,7 @@

        Uruchomienie Rubiniusa

        rbx -e 'puts "Hello!"'
         
        -

        Aby uruchomić plik z kodem Rubiego ‘code.rb’:

        +

        Aby uruchomić plik z kodem Rubiego ‘code.rb’:

        rbx code.rb
         
        diff --git a/web/_site/doc/pl/how-to/fix-a-failing-spec/index.html b/web/_site/doc/pl/how-to/fix-a-failing-spec/index.html index 9f01f1424b..90e01bbaf1 100644 --- a/web/_site/doc/pl/how-to/fix-a-failing-spec/index.html +++ b/web/_site/doc/pl/how-to/fix-a-failing-spec/index.html @@ -163,14 +163,14 @@

        How-To - Fix a Failing Spec

        changes made to other Rubinius source code files.
      3. Run git format-patch origin, which will extract commits that the current branch accumulated since the last pull from origin, or `git format-patch --N’, where N is the number (1, 2, etc.) of commits for which you want to +-N’, where N is the number (1, 2, etc.) of commits for which you want to generate patches.
      4. Create a gist with your patch and link to it in a ticket on the issue tracker at http://github.com/rubinius/rubinius/issues. You can add multiple patches to one ticket.
      -

      When your patch is accepted by the Rubinius project, you’ll get a commit bit +

      When your patch is accepted by the Rubinius project, you’ll get a commit bit for the Rubinius repository. Let Evan know what your Github username is.

      diff --git a/web/_site/doc/pl/how-to/write-a-ticket/index.html b/web/_site/doc/pl/how-to/write-a-ticket/index.html index 857f82812e..13b6189aa6 100644 --- a/web/_site/doc/pl/how-to/write-a-ticket/index.html +++ b/web/_site/doc/pl/how-to/write-a-ticket/index.html @@ -154,7 +154,7 @@

      Jak zgłosić problem.

      the spec runs before and after applying the patch.
    • -

      If your issue doesn’t fit into one of the categories, it is not invalid. It is +

      If your issue doesn’t fit into one of the categories, it is not invalid. It is simply not appropriate for a ticket.

        @@ -173,7 +173,7 @@

        General procedure for submitt

        Double-check.

          -
        1. Do a full rebuild (‘rake clean; rake’) after a ‘git pull’ or fresh clone.
        2. +
        3. Do a full rebuild (‘rake clean; rake’) after a ‘git pull’ or fresh clone.
        4. Read Troubleshooting to see if something there resolves the issue.
        5. Read Spec.
        6. @@ -192,7 +192,7 @@

          General procedure for submitt
        7. The command line for invoking the program
        8. The backtrace or result from the program versus expected result.
        9. Your machine information. uname -a is usually good (if there are any -“unknown” fields in it, please elaborate on those.)
        10. +“unknown” fields in it, please elaborate on those.)

  • @@ -202,16 +202,16 @@

    Additional instruction
    • Can be just a set of specs.
    • Patches must be accompanied by specs unless the specs already exist.
    • -
    • Relevant part of spec output and the exact ‘bin/mspec’ invocation from the +
    • Relevant part of spec output and the exact ‘bin/mspec’ invocation from the existing or added spec before the fix.
    • -
    • The spec output and the exact ‘bin/mspec’ invocation showing success +
    • The spec output and the exact ‘bin/mspec’ invocation showing success after the fix.
    • Additional description of your patch and how it fixes the problem. In particular with new functionality please indicate if it was already discussed on #rubinius or ruby-dev.
    -

    Unless for some reason impossible, please use ‘git-format-patch’ to create the +

    Unless for some reason impossible, please use ‘git-format-patch’ to create the patchset. It is much easier to apply and it preserves the correct attribution. Otherwise, a unified diff.

    @@ -230,17 +230,17 @@

    Example of submitting a patch

  • Ticket Title:

    -

    “[PATCH] No method ‘format’ on Kernel (Module)”

    +

    “[PATCH] No method ‘format’ on Kernel (Module)”

  • Tags:

    -

    “patch core spec”

    +

    “patch core spec”

  • Ticket Message:

    -

    The method ‘format’ is not available as a module function of Kernel.

    +

    The method ‘format’ is not available as a module function of Kernel.

    $ bin/mspec spec/ruby/core/kernel/format_spec.rb
     Started
    @@ -251,7 +251,7 @@ 

    Example of submitting a patch

    No method 'format' on Kernel (Module):
    -

    The method ‘format’ already exists but has not been set as a module +

    The method ‘format’ already exists but has not been set as a module function. This patch does so.

    After the patch is applied:

    diff --git a/web/_site/doc/pl/ruby/index.html b/web/_site/doc/pl/ruby/index.html index 6800f15fe0..1af1d0e44f 100644 --- a/web/_site/doc/pl/ruby/index.html +++ b/web/_site/doc/pl/ruby/index.html @@ -176,7 +176,7 @@

    Ruby

    Often it is asserted that everything in Ruby is an object. This is not quite true. Most things in Ruby are objects, but some things that are absolutely essential for running Ruby code are not necessarily objects that you can put -your hands on. Instead, which of these “execution environment” things are +your hands on. Instead, which of these “execution environment” things are objects in Ruby depends heavily on the implementation. Scope is one of these things.

    diff --git a/web/_site/doc/pl/specs/index.html b/web/_site/doc/pl/specs/index.html index 331687afb4..6ed764fc3c 100644 --- a/web/_site/doc/pl/specs/index.html +++ b/web/_site/doc/pl/specs/index.html @@ -140,12 +140,12 @@

    Specyfikacja

    The Rubinius project generally uses TDD/BDD-style executable specifications to -drive development. The Rubinius ‘spec’ directory is conceptually divided into +drive development. The Rubinius ‘spec’ directory is conceptually divided into two parts:

      -
    1. All the files under ‘./spec/ruby’ that describe the behavior of MatzRuby.
    2. -
    3. And all the other files under the ‘./spec’ directory that describe the +
    4. All the files under ‘./spec/ruby’ that describe the behavior of MatzRuby.
    5. +
    6. And all the other files under the ‘./spec’ directory that describe the behavior of Rubinius.
    diff --git a/web/_site/doc/pl/tools/memory-analysis/index.html b/web/_site/doc/pl/tools/memory-analysis/index.html index 262708fb26..7dce61ccb3 100644 --- a/web/_site/doc/pl/tools/memory-analysis/index.html +++ b/web/_site/doc/pl/tools/memory-analysis/index.html @@ -305,7 +305,7 @@

    Analiza sterty

    Czasami aby lepiej zdiagnozować wyciek nie wystarczy jeden zrzut sterty. W takim wypadku powinniśmy wykonać kilka zrzutów w różnym -czasie działania programu i pozwolić programowi “heap dump” wykonać +czasie działania programu i pozwolić programowi “heap dump” wykonać analizę różnic. Analiza różnic pokazuje które obiekty zmieniły się na stercie przed i po.

    diff --git a/web/_site/doc/pl/tools/profiler/index.html b/web/_site/doc/pl/tools/profiler/index.html index 48d5a254c2..407d305328 100644 --- a/web/_site/doc/pl/tools/profiler/index.html +++ b/web/_site/doc/pl/tools/profiler/index.html @@ -154,7 +154,7 @@

    VM Profiler

    The Profiler lives and dies in its own world. The profiler is passed a VM instance when it is created because the profiler needs access to it while it is gathering info. The STATE argument could be passed into all the profiler -methods, but it’s simple enough to pass it in when the profiler is created. +methods, but it’s simple enough to pass it in when the profiler is created. The profiler never manipulates the VM instance. It is important to maintain this separation.

    @@ -210,7 +210,7 @@

    Ruby Profiler

  • The #profile method starts the profiler, yields, stops the profiler and prints -the profile data by default. Pass ‘false’ to #profile to not print the data. +the profile data by default. Pass ‘false’ to #profile to not print the data. Either way, the profile data itself is returned by #profile.

    How to Read the Flat Profiler Output

    @@ -233,7 +233,7 @@

    cumulative seconds

    self seconds

    The total time spent in this method less the total time spent in all this -method’s callees.

    +method’s callees.

    calls

    @@ -272,7 +272,7 @@

    Example of Flat Output

    } -

    Running the script with ‘bin/rbx script.rb’ should give the following flat +

    Running the script with ‘bin/rbx script.rb’ should give the following flat output.

      %   cumulative   self                self     total
    @@ -299,7 +299,7 @@ 

    How to Read the Graph Output

    -Xprofiler.graph
     
    -

    Given the same script above, the graph output is shown below. Each “entry” in +

    Given the same script above, the graph output is shown below. Each “entry” in the graph has three sections: 1) the method for the entry, called the primary line; 2) the callers of the primary method; and 3) the methods that the primary method called. The fields have different meanings based on the @@ -320,7 +320,7 @@

    % time

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    @@ -335,16 +335,16 @@

    name

    The name of the method followed by the index number.

    The lines above the primary line are methods that call the primary method. The -callers’ fields have the following interpretation:

    +callers’ fields have the following interpretation:

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    -

    The time spent in the method’s call to the primary method.

    +

    The time spent in the method’s call to the primary method.

    called

    @@ -365,11 +365,11 @@

    name

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    -

    This is an estimate of the amount of time this method’s callees spent when +

    This is an estimate of the amount of time this method’s callees spent when this method was called by the primary method. The estimate is based on the ration of the time this method spent when called by the primary method to the total time spent in this method.

    diff --git a/web/_site/doc/pl/virtual-machine/instructions/index.html b/web/_site/doc/pl/virtual-machine/instructions/index.html index d2f1b893b6..9bcb5b64d7 100644 --- a/web/_site/doc/pl/virtual-machine/instructions/index.html +++ b/web/_site/doc/pl/virtual-machine/instructions/index.html @@ -256,7 +256,7 @@

    Notes

    Unlike other literals such as strings and numbers, creating a Regexp literal (i.e. via the /regex/ syntax) is a two step process to create the literal slot for the Regexp, create a literal for the string between the - ‘/’ delimiters and create a new Regexp object passing it the string. Only + ‘/’ delimiters and create a new Regexp object passing it the string. Only then can the literal value be set, using the set_literal opcode.

    push_literal(literal)

    @@ -754,7 +754,7 @@

    pop_unwind()

    Remove the next unused unwind registration from the current invocation. This instruction is paired with setup_unwind to remove registrations - when control exits a section of code that registered a handler but didn’t + when control exits a section of code that registered a handler but didn’t use it. For example, exiting a begin that had a rescue expression.

    @@ -1351,7 +1351,7 @@

    cast_for_multi_block_ the arg is an array.

    If the Proc invoked from was in lambda mode, and one argument is passed: - * and it’s an Array, push it. + * and it’s an Array, push it. * and it responds to #to_ary, try and convert it and push it. * otherwise wrap it in a one element Array and push it.

    @@ -1637,7 +1637,7 @@

    Notes

    runtime to determine which code path is executed.

    For example, a method such as Fixnum#times can be optimised at compile - time, but we can’t know until runtime whether or not the Fixnum#times + time, but we can’t know until runtime whether or not the Fixnum#times method has been overridden. The serial number check is used to determine each time the code is executed, whether or not the standard Fixnum#times has been overridden. It leverages the serial number field on a @@ -1646,7 +1646,7 @@

    Notes

    check_serial_private(literal, serial)

    -

    Checks if the specified method’s serial number matches an expected value. +

    Checks if the specified method’s serial number matches an expected value. Considers private methods too.

    @@ -1934,7 +1934,7 @@

    meta_send_op_tequal(litera

    Notes

    -

    Exactly like equal, except calls #=== if it can’t handle it directly.

    +

    Exactly like equal, except calls #=== if it can’t handle it directly.

    meta_send_call(literal, count)

    @@ -2225,7 +2225,7 @@

    call_custom(literal, count)

    meta_to_s(literal)

    -

    Pop a value off the stack and if it’s not a String, call a method +

    Pop a value off the stack and if it’s not a String, call a method indicated by literal on it. Push the resulting object back on the stack.

    diff --git a/web/_site/doc/pt-br/appendix-a-glossary/index.html b/web/_site/doc/pt-br/appendix-a-glossary/index.html index 5a7b4f33bc..6466bba6d8 100644 --- a/web/_site/doc/pt-br/appendix-a-glossary/index.html +++ b/web/_site/doc/pt-br/appendix-a-glossary/index.html @@ -140,9 +140,9 @@

    Apêndice A - Glossário

    Definições dos termos e frases usadas na linguagem de programação Ruby e nessa -implementação. Veja também “The Ruby Programming Language” by Flanagan and -Matsumoto [O’Reilly 2008] and “Programming Ruby: The Pragmatic Programmer’s -Guide” 2nd or 3rd Edition by Thomas et al [The Pragmatic Programmers +implementação. Veja também “The Ruby Programming Language” by Flanagan and +Matsumoto [O’Reilly 2008] and “Programming Ruby: The Pragmatic Programmer’s +Guide” 2nd or 3rd Edition by Thomas et al [The Pragmatic Programmers 2005-2008]

      @@ -210,7 +210,7 @@

      Apêndice A - Glossário

      1. -

        Resolvendo método ‘wanker’ – procura método nas tabelas:

        +

        Resolvendo método ‘wanker’ – procura método nas tabelas:

        1. SingletonClass(F)
        2. @@ -238,7 +238,7 @@

          Apêndice A - Glossário

        3. MRI

          -

          Matz’s Ruby Interpreter ou implementação do interpretador ruby. O nome da +

          Matz’s Ruby Interpreter ou implementação do interpretador ruby. O nome da implementação oficial do Ruby. Veja http://ruby-lang.org.

        4. @@ -287,7 +287,7 @@

          Apêndice A - Glossário

    Todas as classes em Ruby são também objetos, elas podem ter também sua -classe singleton. Os métodos chamados ‘métodos de classe’ são somente +classe singleton. Os métodos chamados ‘métodos de classe’ são somente métodos na tabela de métodos da classe singleton. O método +honk+ existe na classe singleton para a classe +Car+.

    @@ -300,7 +300,7 @@

    Apêndice A - Glossário

    No Rubiniys, classes singleton são instancias da classe SingletonClass. A classe singleton para um objeto pode ser obtida pela chamada para método +singleton_class+. O arranjo global dos conceitos envolvidos aqui -é as vezes referenciados como o ‘Protocolo Meta-Objeto’ ou +MOP+.

    +é as vezes referenciados como o ‘Protocolo Meta-Objeto’ ou +MOP+.

  • superclass

    diff --git a/web/_site/doc/pt-br/appendix-b-reading-list/index.html b/web/_site/doc/pt-br/appendix-b-reading-list/index.html index 38ff549e4c..b4ee745908 100644 --- a/web/_site/doc/pt-br/appendix-b-reading-list/index.html +++ b/web/_site/doc/pt-br/appendix-b-reading-list/index.html @@ -153,7 +153,7 @@

    Máquina Virtual

    • Smalltalk-80: Linguagem e Implementação -by Goldberg, Robson, Harrison (conhecido como “O livro Azul”), Os capítulos de Implementação +by Goldberg, Robson, Harrison (conhecido como “O livro Azul”), Os capítulos de Implementação são o da parte IV available online
    • Máquinas Virtuais por Iain D. Craig
    • Grandes posts do Adam Gardiner: introdução, @@ -178,7 +178,7 @@

      FFI

      diff --git a/web/_site/doc/pt-br/build-system/index.html b/web/_site/doc/pt-br/build-system/index.html index 361eeb712c..203afeb74a 100644 --- a/web/_site/doc/pt-br/build-system/index.html +++ b/web/_site/doc/pt-br/build-system/index.html @@ -177,7 +177,7 @@

      Development versus Install Builds

      not function, even if the executable is in the directory. The executable checks a single, hard-coded path. If this ends up being very painful for some reason, -we’ll revise it.

      +we’ll revise it.

      Installing Rubinius

      @@ -186,11 +186,11 @@

      Installing Rubinius

      ./configure --prefix=/path/to/install/dir
       
      -

      The configure process creates a ‘config.rb’ file that specifies the key file -paths that Rubinius uses. Once configured, run ‘rake install’ to build and +

      The configure process creates a ‘config.rb’ file that specifies the key file +paths that Rubinius uses. Once configured, run ‘rake install’ to build and install. The install procedure builds all the files, including compiling the Ruby standard library files in the lib/ directory, then copies them into the -install location using the ‘install’ program. The install tasks are located in +install location using the ‘install’ program. The install tasks are located in rakelib/install.rake.

      diff --git a/web/_site/doc/pt-br/bytecode-compiler/generator/index.html b/web/_site/doc/pt-br/bytecode-compiler/generator/index.html index 179e901b38..d2eac83dde 100644 --- a/web/_site/doc/pt-br/bytecode-compiler/generator/index.html +++ b/web/_site/doc/pt-br/bytecode-compiler/generator/index.html @@ -187,7 +187,7 @@

      Generator

      When generating the bytecode for an AST, Rubinius invokes the method bytecode on each AST node, passing in the current Generator -instance. Here’s the bytecode method for the if node:

      +instance. Here’s the bytecode method for the if node:

      def bytecode(g)
         pos(g)
      diff --git a/web/_site/doc/pt-br/bytecode-compiler/parser/index.html b/web/_site/doc/pt-br/bytecode-compiler/parser/index.html
      index 398af8be6c..6d2e6c2601 100644
      --- a/web/_site/doc/pt-br/bytecode-compiler/parser/index.html
      +++ b/web/_site/doc/pt-br/bytecode-compiler/parser/index.html
      @@ -153,7 +153,7 @@ 

      Ruby Parser

      the next stage of the process, the generator.

      The parser itself (called Melbourne) has a C part, which is essentially -MRI’s parser, and a Ruby part, which is responsible for creating the Ruby +MRI’s parser, and a Ruby part, which is responsible for creating the Ruby AST. The C parser communicates with Ruby by calling a method for each node in the parse tree.

      diff --git a/web/_site/doc/pt-br/bytecode-compiler/transformations/index.html b/web/_site/doc/pt-br/bytecode-compiler/transformations/index.html index 0c3938b5f7..1319f51096 100644 --- a/web/_site/doc/pt-br/bytecode-compiler/transformations/index.html +++ b/web/_site/doc/pt-br/bytecode-compiler/transformations/index.html @@ -166,7 +166,7 @@

      Safe Math Compiler Transform

      one of its cherished features but it is also truly a double-edged sword in some respects.

      -

      In the standard library the ‘mathn’ library redefines Fixnum#/ in an unsafe +

      In the standard library the ‘mathn’ library redefines Fixnum#/ in an unsafe and incompatible manner. The library aliases Fixnum#/ to Fixnum#quo, which returns a Float by default.

      @@ -176,7 +176,7 @@

      Safe Math Compiler Transform

      define this method.

      The safe math transform is enabled during the compilation of the Core -libraries to enable the plugin. During regular ‘user code’ compilation, the +libraries to enable the plugin. During regular ‘user code’ compilation, the plugin is not enabled. This enables us to support mathn without breaking the core libraries or forcing inconvenient practices.

      diff --git a/web/_site/doc/pt-br/contributing/index.html b/web/_site/doc/pt-br/contributing/index.html index 8d4188f17e..1ef81c9410 100644 --- a/web/_site/doc/pt-br/contributing/index.html +++ b/web/_site/doc/pt-br/contributing/index.html @@ -172,7 +172,7 @@

      Write Specs

      tagged as incomplete. These specs may simply need review, or there could be specs missing for a particular class.

      -

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will +

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will show tags for all the specs that should run on Rubinius. Or you can specify any subdirectory of the spec/ directory to list tags for specs in that subdirectory.

      @@ -189,7 +189,7 @@

      Fix Failing Specs

    • Run bin/mspec tag --list fails <dir> to show specs tagged as failing.

      -

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will +

      NOTE: You can specify the pseudo-directory ‘:files’ for <dir>, which will show tags for all the specs that should run on Rubinius. Or you can specify any subdirectory of the spec/ directory to list tags for specs in that subdirectory.

      diff --git a/web/_site/doc/pt-br/contributing/style-guide/index.html b/web/_site/doc/pt-br/contributing/style-guide/index.html index 8638e96a01..f172c34769 100644 --- a/web/_site/doc/pt-br/contributing/style-guide/index.html +++ b/web/_site/doc/pt-br/contributing/style-guide/index.html @@ -170,10 +170,10 @@

      C++ Code

    • Alternate versions of functions should be named why they are different -from the primary. If there is a function ‘person()’ and you want a +from the primary. If there is a function ‘person()’ and you want a version that takes the name of the person, it should be -‘person_with_name(char *name)’ or ‘person_with_details(char *name, …)’. -NOT ‘person1(char *name)’.

      +‘person_with_name(char *name)’ or ‘person_with_details(char *name, …)’. +NOT ‘person1(char *name)’.

    @@ -181,16 +181,16 @@

    Ruby Code

    • -

      Methods: Try to keep your methods short–one screenful and try to adhere +

      Methods: Try to keep your methods short–one screenful and try to adhere to DRY within reason. Generally common functionality should be abstracted -to helper methods (which you can make ‘private’) but in some cases, +to helper methods (which you can make ‘private’) but in some cases, particularly working with Core, sometimes trying to DRY things up is just an obstacle if you have to maneuver around several different error conditions, for example.

    • Method names: should be clear, expressive and meaningful. Avoid using -underscores to ‘protect’ the method (‘__send__’) with some exceptions.

      +underscores to ‘protect’ the method (‘__send__’) with some exceptions.

    • Smalltalk-style method names are OK, meaning that you could have a method @@ -201,8 +201,8 @@

      Ruby Code

    • Variable names: make them clear and meaningful (with some well-known -exceptions like using ‘i’ for a counter.) Try to avoid shadowing method -names, for example within Array use ‘idx’ in favour of ‘index’ because the +exceptions like using ‘i’ for a counter.) Try to avoid shadowing method +names, for example within Array use ‘idx’ in favour of ‘index’ because the latter is also a method name.

    • diff --git a/web/_site/doc/pt-br/getting-started/running-rubinius/index.html b/web/_site/doc/pt-br/getting-started/running-rubinius/index.html index 3c2f9ac68f..075117e8c2 100644 --- a/web/_site/doc/pt-br/getting-started/running-rubinius/index.html +++ b/web/_site/doc/pt-br/getting-started/running-rubinius/index.html @@ -150,7 +150,7 @@

      Running Rubinius

      rbx -e 'puts "Hello!"'
       
      -

      To run a ruby file named ‘code.rb’:

      +

      To run a ruby file named ‘code.rb’:

      rbx code.rb
       
      diff --git a/web/_site/doc/pt-br/how-to/fix-a-failing-spec/index.html b/web/_site/doc/pt-br/how-to/fix-a-failing-spec/index.html index 2f8072c3f8..9de766d98c 100644 --- a/web/_site/doc/pt-br/how-to/fix-a-failing-spec/index.html +++ b/web/_site/doc/pt-br/how-to/fix-a-failing-spec/index.html @@ -163,14 +163,14 @@

      How-To - Fix a Failing Spec

      changes made to other Rubinius source code files.
    • Run git format-patch origin, which will extract commits that the current branch accumulated since the last pull from origin, or `git format-patch --N’, where N is the number (1, 2, etc.) of commits for which you want to +-N’, where N is the number (1, 2, etc.) of commits for which you want to generate patches.
    • Create a gist with your patch and link to it in a ticket on the issue tracker at http://github.com/rubinius/rubinius/issues. You can add multiple patches to one ticket.
    • -

      When your patch is accepted by the Rubinius project, you’ll get a commit bit +

      When your patch is accepted by the Rubinius project, you’ll get a commit bit for the Rubinius repository. Let Evan know what your Github username is.

      diff --git a/web/_site/doc/pt-br/how-to/write-a-ticket/index.html b/web/_site/doc/pt-br/how-to/write-a-ticket/index.html index 9fd9b2aa86..3de19c705a 100644 --- a/web/_site/doc/pt-br/how-to/write-a-ticket/index.html +++ b/web/_site/doc/pt-br/how-to/write-a-ticket/index.html @@ -154,7 +154,7 @@

      How-To - Write a Ticket

      the spec runs before and after applying the patch. -

      If your issue doesn’t fit into one of the categories, it is not invalid. It is +

      If your issue doesn’t fit into one of the categories, it is not invalid. It is simply not appropriate for a ticket.

        @@ -173,7 +173,7 @@

        General procedure for submitt

        Double-check.

          -
        1. Do a full rebuild (‘rake clean; rake’) after a ‘git pull’ or fresh clone.
        2. +
        3. Do a full rebuild (‘rake clean; rake’) after a ‘git pull’ or fresh clone.
        4. Read Troubleshooting to see if something there resolves the issue.
        5. Read Specs.
        6. @@ -192,7 +192,7 @@

          General procedure for submitt
        7. The command line for invoking the program
        8. The backtrace or result from the program versus expected result.
        9. Your machine information. uname -a is usually good (if there are any -“unknown” fields in it, please elaborate on those.)
        10. +“unknown” fields in it, please elaborate on those.)

  • @@ -202,16 +202,16 @@

    Additional instruction
    • Can be just a set of specs.
    • Patches must be accompanied by specs unless the specs already exist.
    • -
    • Relevant part of spec output and the exact ‘bin/mspec’ invocation from the +
    • Relevant part of spec output and the exact ‘bin/mspec’ invocation from the existing or added spec before the fix.
    • -
    • The spec output and the exact ‘bin/mspec’ invocation showing success +
    • The spec output and the exact ‘bin/mspec’ invocation showing success after the fix.
    • Additional description of your patch and how it fixes the problem. In particular with new functionality please indicate if it was already discussed on #rubinius or ruby-dev.
    -

    Unless for some reason impossible, please use ‘git-format-patch’ to create the +

    Unless for some reason impossible, please use ‘git-format-patch’ to create the patchset. It is much easier to apply and it preserves the correct attribution. Otherwise, a unified diff.

    @@ -230,17 +230,17 @@

    Example of submitting a patch

  • Ticket Title:

    -

    “[PATCH] No method ‘format’ on Kernel (Module)”

    +

    “[PATCH] No method ‘format’ on Kernel (Module)”

  • Tags:

    -

    “patch core spec”

    +

    “patch core spec”

  • Ticket Message:

    -

    The method ‘format’ is not available as a module function of Kernel.

    +

    The method ‘format’ is not available as a module function of Kernel.

    $ bin/mspec spec/ruby/core/kernel/format_spec.rb
     Started
    @@ -251,7 +251,7 @@ 

    Example of submitting a patch

    No method 'format' on Kernel (Module):
    -

    The method ‘format’ already exists but has not been set as a module +

    The method ‘format’ already exists but has not been set as a module function. This patch does so.

    After the patch is applied:

    diff --git a/web/_site/doc/pt-br/how-to/write-benchmarks/index.html b/web/_site/doc/pt-br/how-to/write-benchmarks/index.html index 6786dee757..ae68bccd1c 100644 --- a/web/_site/doc/pt-br/how-to/write-benchmarks/index.html +++ b/web/_site/doc/pt-br/how-to/write-benchmarks/index.html @@ -152,9 +152,9 @@

    How-To - Write Benchmarks

    example different ways of deleting keys/values from a Hash.
  • Use the benchmark framework.
  • Keep the benchmarks short and simple.
  • -
  • The benchmarks are not meant to measure Rubinius. So if you’re writing a +
  • The benchmarks are not meant to measure Rubinius. So if you’re writing a benchmark for a class with bang and no-bang methods you will want to use -a duplicate of a variable in the bang method but you don’t need to dup +a duplicate of a variable in the bang method but you don’t need to dup in the no-bang method.
  • diff --git a/web/_site/doc/pt-br/ruby/index.html b/web/_site/doc/pt-br/ruby/index.html index 749f61addb..bbde9505c0 100644 --- a/web/_site/doc/pt-br/ruby/index.html +++ b/web/_site/doc/pt-br/ruby/index.html @@ -176,7 +176,7 @@

    Ruby

    Often it is asserted that everything in Ruby is an object. This is not quite true. Most things in Ruby are objects, but some things that are absolutely essential for running Ruby code are not necessarily objects that you can put -your hands on. Instead, which of these “execution environment” things are +your hands on. Instead, which of these “execution environment” things are objects in Ruby depends heavily on the implementation. Scope is one of these things.

    diff --git a/web/_site/doc/pt-br/specs/index.html b/web/_site/doc/pt-br/specs/index.html index 2eaf475362..de4840e2b1 100644 --- a/web/_site/doc/pt-br/specs/index.html +++ b/web/_site/doc/pt-br/specs/index.html @@ -149,12 +149,12 @@

    Specs

    O projeto Rubinius usa especificações executáveis no estilo TDD/BDD para -impulsionar o desenvolvimento. Diretório ‘spec’ é conceitualmente dividida +impulsionar o desenvolvimento. Diretório ‘spec’ é conceitualmente dividida em duas partes:

      -
    1. Todos os arquivos em ‘./spec/ruby’ descrevem o comportamento de MatzRuby.
    2. -
    3. E todos os outros arquivos dentro do diretório ‘./spec’ descrevem o comportamento +
    4. Todos os arquivos em ‘./spec/ruby’ descrevem o comportamento de MatzRuby.
    5. +
    6. E todos os outros arquivos dentro do diretório ‘./spec’ descrevem o comportamento de Rubinius.
    diff --git a/web/_site/doc/pt-br/tools/memory-analysis/index.html b/web/_site/doc/pt-br/tools/memory-analysis/index.html index d71db7a368..502344f38a 100644 --- a/web/_site/doc/pt-br/tools/memory-analysis/index.html +++ b/web/_site/doc/pt-br/tools/memory-analysis/index.html @@ -212,7 +212,7 @@

    A Sample Program

    puts "received #{messages.size} messages in #{elapsed_usecs / 1_000_000} seconds"
    -

    Wow, this program leaks like a sieve. Let’s figure out why.

    +

    Wow, this program leaks like a sieve. Let’s figure out why.

    Saving A Heap Dump

    @@ -257,7 +257,7 @@

    Analyzing A Heap Dump

    Find the heap_dump tool at its project home page.

    This tool reads the heap dump file and outputs some useful information in 3 columns -corresponding to the number of objects visible in the heap, the object’s class, and +corresponding to the number of objects visible in the heap, the object’s class, and the total number of bytes consumed by all instances of this object.

    Running the tool against a heap dump captured from our leak.rb program, it gives us @@ -287,7 +287,7 @@

    Analyzing A Heap Dump

    The largest footprint is consumed by Rubinius::CompactLookupTable which is a class that the example code never directly instantiates and weighs in at about 20MB. So, some internal Rubinius structures are reported by the heap dump. It is -interesting but doesn’t help pinpoint our particular leak.

    +interesting but doesn’t help pinpoint our particular leak.

  • The ZMQ::Message class listed on line 3 is the first class shown that the example @@ -327,7 +327,7 @@

    Advanced Tools - OSX Only

    After modifying the Ruby code to use a simple counter and let the garbage collector handle all of the ZMQ::Message instances, the program is still leaking like mad. -Taking two snapshots and analyzing them doesn’t give any clue as to the source +Taking two snapshots and analyzing them doesn’t give any clue as to the source though.

    $ rbx -I /path/to/heap_dump/lib /path/to/heap_dump/bin/histo.rb heap3.dump heap4.dump
    @@ -385,7 +385,7 @@ 

    Advanced Tools - OSX Only

    The output shows that at the time of the snapshot we had nearly 172k leaked objects. The call stack output shows that the leak occurs during the call to zmq_msg_init_size -which doesn’t mean anything unless we dig into the implementation of ZMQ::Message`. +which doesn’t mean anything unless we dig into the implementation of ZMQ::Message`. This is where knowledge of the underlying system is critical; without knowing where this particular call is made, it would be much more difficult to track down the problem.

    diff --git a/web/_site/doc/pt-br/tools/profiler/index.html b/web/_site/doc/pt-br/tools/profiler/index.html index cf72eb1127..deb6d52e23 100644 --- a/web/_site/doc/pt-br/tools/profiler/index.html +++ b/web/_site/doc/pt-br/tools/profiler/index.html @@ -154,7 +154,7 @@

    VM Profiler

    The Profiler lives and dies in its own world. The profiler is passed a VM instance when it is created because the profiler needs access to it while it is gathering info. The STATE argument could be passed into all the profiler -methods, but it’s simple enough to pass it in when the profiler is created. +methods, but it’s simple enough to pass it in when the profiler is created. The profiler never manipulates the VM instance. It is important to maintain this separation.

    @@ -210,7 +210,7 @@

    Ruby Profiler

    The #profile method starts the profiler, yields, stops the profiler and prints -the profile data by default. Pass ‘false’ to #profile to not print the data. +the profile data by default. Pass ‘false’ to #profile to not print the data. Either way, the profile data itself is returned by #profile.

    How to Read the Flat Profiler Output

    @@ -233,7 +233,7 @@

    cumulative seconds

    self seconds

    The total time spent in this method less the total time spent in all this -method’s callees.

    +method’s callees.

    calls

    @@ -272,7 +272,7 @@

    Example of Flat Output

    } -

    Running the script with ‘bin/rbx script.rb’ should give the following flat +

    Running the script with ‘bin/rbx script.rb’ should give the following flat output.

      %   cumulative   self                self     total
    @@ -299,7 +299,7 @@ 

    How to Read the Graph Output

    -Xprofiler.graph
     
    -

    Given the same script above, the graph output is shown below. Each “entry” in +

    Given the same script above, the graph output is shown below. Each “entry” in the graph has three sections: 1) the method for the entry, called the primary line; 2) the callers of the primary method; and 3) the methods that the primary method called. The fields have different meanings based on the @@ -320,7 +320,7 @@

    % time

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    @@ -335,16 +335,16 @@

    name

    The name of the method followed by the index number.

    The lines above the primary line are methods that call the primary method. The -callers’ fields have the following interpretation:

    +callers’ fields have the following interpretation:

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    -

    The time spent in the method’s call to the primary method.

    +

    The time spent in the method’s call to the primary method.

    called

    @@ -365,11 +365,11 @@

    name

    self

    The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

    +method’s callees. This is the same as self seconds in the flat output.

    children

    -

    This is an estimate of the amount of time this method’s callees spent when +

    This is an estimate of the amount of time this method’s callees spent when this method was called by the primary method. The estimate is based on the ration of the time this method spent when called by the primary method to the total time spent in this method.

    diff --git a/web/_site/doc/pt-br/virtual-machine/instructions/index.html b/web/_site/doc/pt-br/virtual-machine/instructions/index.html index 14ccb55d71..09cf3beff4 100644 --- a/web/_site/doc/pt-br/virtual-machine/instructions/index.html +++ b/web/_site/doc/pt-br/virtual-machine/instructions/index.html @@ -256,7 +256,7 @@

    Notes

    Unlike other literals such as strings and numbers, creating a Regexp literal (i.e. via the /regex/ syntax) is a two step process to create the literal slot for the Regexp, create a literal for the string between the - ‘/’ delimiters and create a new Regexp object passing it the string. Only + ‘/’ delimiters and create a new Regexp object passing it the string. Only then can the literal value be set, using the set_literal opcode.

    push_literal(literal)

    @@ -754,7 +754,7 @@

    pop_unwind()

    Remove the next unused unwind registration from the current invocation. This instruction is paired with setup_unwind to remove registrations - when control exits a section of code that registered a handler but didn’t + when control exits a section of code that registered a handler but didn’t use it. For example, exiting a begin that had a rescue expression.

    @@ -1351,7 +1351,7 @@

    cast_for_multi_block_ the arg is an array.

    If the Proc invoked from was in lambda mode, and one argument is passed: - * and it’s an Array, push it. + * and it’s an Array, push it. * and it responds to #to_ary, try and convert it and push it. * otherwise wrap it in a one element Array and push it.

    @@ -1637,7 +1637,7 @@

    Notes

    runtime to determine which code path is executed.

    For example, a method such as Fixnum#times can be optimised at compile - time, but we can’t know until runtime whether or not the Fixnum#times + time, but we can’t know until runtime whether or not the Fixnum#times method has been overridden. The serial number check is used to determine each time the code is executed, whether or not the standard Fixnum#times has been overridden. It leverages the serial number field on a @@ -1646,7 +1646,7 @@

    Notes

    check_serial_private(literal, serial)

    -

    Checks if the specified method’s serial number matches an expected value. +

    Checks if the specified method’s serial number matches an expected value. Considers private methods too.

    @@ -1934,7 +1934,7 @@

    meta_send_op_tequal(litera

    Notes

    -

    Exactly like equal, except calls #=== if it can’t handle it directly.

    +

    Exactly like equal, except calls #=== if it can’t handle it directly.

    meta_send_call(literal, count)

    @@ -2225,7 +2225,7 @@

    call_custom(literal, count)

    meta_to_s(literal)

    -

    Pop a value off the stack and if it’s not a String, call a method +

    Pop a value off the stack and if it’s not a String, call a method indicated by literal on it. Push the resulting object back on the stack.

    diff --git a/web/_site/doc/pt-br/what-is-rubinius/index.html b/web/_site/doc/pt-br/what-is-rubinius/index.html index e0556b12a1..27b17f6e70 100644 --- a/web/_site/doc/pt-br/what-is-rubinius/index.html +++ b/web/_site/doc/pt-br/what-is-rubinius/index.html @@ -138,23 +138,25 @@

    O que é Rubinius

    -

    Rubinius é uma implementação da [linguagem de programação Ruby] -(http://ruby-lang.org).

    +

    Rubinius é uma implementação da linguagem de programação +Ruby.

    -

    Rubinius inclue uma máquina virtual de bytecodes, parser de sintax Ruby, -compilador de bytecode, gerenciador de garbage collector, compilador de -de código nativo just-in-time (JIT), e o Ruby Core e Bibliotecas padrão. -Rubinius implementa atualmente a versão 1.8.7 do Ruby.

    +

    Rubinius include uma máquina virtual de bytecode, um parser da sintaxe Ruby, um +compilador de bytecode, um coletor de lixo de gerações, compilador de código de +maquina nativo just-in-time (JIT) e as bibliotecas de núcleo e padrões do Ruby.

    + +

    Rubinius implementa atualmente a versão 1.8.7 do Ruby.

    Licença

    -

    Rubinius usa a licença BDS. Veja o arquivo de LICENCA no código-fonte.

    +

    Rubinius usa a licença BDS. Veja o arquivo LICENSE no código-fonte.

    Instalação

    -

    Rubinius executa em Mac OS X e muitos sistemas Unix/Linux. Microsoft Windows + +

    Rubinius executa em Mac OS X e em muitos sistemas Unix/Linux. Microsoft Windows terá suporte em breve.

    -

    Para instalar Rubinius, siga os passos abaixo. Para informação mais detalhada +

    Para instalar Rubinius siga os passos abaixo. Para informações mais detalhadas veja Começando.

      @@ -164,14 +166,13 @@

      Instalação

    1. rake install
    -

    Quando o processo de instalação terminar, adicione o diretório executável -do Ruby (bin) ao seu PATH.

    +

    Quando o processo de instalação terminar, adicione o diretório do executável do +Rubinius (bin) ao seu PATH.

    -

    Rubinius vem com RubyGems e tem as gems rake e rdoc pré-instaladas. +

    Rubinius vem com RubyGems embutido e com as gems rake e rdoc pré-instaladas. Para instalar a gem nokogiri, por exemplo, rode rbx gem install nokogiri

    -
    diff --git a/web/_site/doc/ru/appendix-a-glossary/index.html b/web/_site/doc/ru/appendix-a-glossary/index.html index 476779f605..b0c56018ae 100644 --- a/web/_site/doc/ru/appendix-a-glossary/index.html +++ b/web/_site/doc/ru/appendix-a-glossary/index.html @@ -149,9 +149,9 @@

    Приложение A - Глоссарий

    Здесь даны определения терминов и фраз используемых в языке программирования -Ruby и конкретно в этой реализации. Смотри также книгу “Язык программирования Ruby” -авторов Флэнегана и Мацумото [O’Reilly 2008] и “Programming Ruby: The Pragmatic -Programmer’s Guide” второе или третье издание автора Томаса и др. [The Pragmatic +Ruby и конкретно в этой реализации. Смотри также книгу “Язык программирования Ruby” +авторов Флэнегана и Мацумото [O’Reilly 2008] и “Programming Ruby: The Pragmatic +Programmer’s Guide” второе или третье издание автора Томаса и др. [The Pragmatic Programmers 2005-2008]

      @@ -171,7 +171,7 @@

      Приложение A - Глоссарий

    Так как все классы в Ruby также являются объектами, они тоже могут иметь -метаклассы. Методы, которые называют “методами класса”, являются просто +метаклассы. Методы, которые называют “методами класса”, являются просто методами в таблице методов, принадлежащей метаклассу класса. Метод +honk+ существует в метаклассе класса +Car+.

    @@ -183,7 +183,7 @@

    Приложение A - Глоссарий

    В Rubinius, метаклассы являются объектами класса MetaClass. Доступ к метаклассу объекта можно получить вызовом метода +metaclass+. Схему, -описанную здесь, в целом иногда называют “Метаобъектный протокол” +описанную здесь, в целом иногда называют “Метаобъектный протокол” или +MOP+.

  • @@ -197,7 +197,7 @@

    Приложение A - Глоссарий

    равен nil.

    В этом случае повторяется поиск для метода method_missing. Если и этот -метод не будет найден – трагедия.

    +метод не будет найден – трагедия.

                                          +----------------+
                                           |      nil       |
    @@ -251,7 +251,7 @@ 

    Приложение A - Глоссарий

    1. -

      Поиск метода ‘wanker’ будет произведен в таблицах методов:

      +

      Поиск метода ‘wanker’ будет произведен в таблицах методов:

      1. MetaClass(F)
      2. @@ -269,7 +269,7 @@

        Приложение A - Глоссарий

        Структура данных, присутствующая в каждом классе (и модуле), которая содержит список методов, определенных в этом классе.

        -

        В Rubinius таблица методов класса – это объект класса LookupTable.

        +

        В Rubinius таблица методов класса – это объект класса LookupTable.

      3. MatzRuby

        @@ -279,7 +279,7 @@

        Приложение A - Глоссарий

      4. MRI

        -

        Matz’s Ruby Interpreter или Matz’s Ruby Implementation. Аббревиатура для обозначения +

        Matz’s Ruby Interpreter или Matz’s Ruby Implementation. Аббревиатура для обозначения официальной реализации Ruby. Смотри http://ruby-lang.org.

      5. diff --git a/web/_site/doc/ru/appendix-b-reading-list/index.html b/web/_site/doc/ru/appendix-b-reading-list/index.html index efcd1464d4..013aa170b2 100644 --- a/web/_site/doc/ru/appendix-b-reading-list/index.html +++ b/web/_site/doc/ru/appendix-b-reading-list/index.html @@ -149,9 +149,9 @@

        Приложение B - Список литературы

        Building virtual machines in general and programming language implementations -in particular requires some knowledge. Rubinius’ goal is to lower the barrier +in particular requires some knowledge. Rubinius’ goal is to lower the barrier by keeping as much as possible in Ruby but to hack on garbage collector you -have to understand what’ going on behind the curtains.

        +have to understand what’ going on behind the curtains.

        This page contains references to books, online lectures, blog posts and any other publications you may find useful for working on Rubinius.

        @@ -162,7 +162,7 @@

        Virtual machine

        • Smalltalk-80: language and its implementation -by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation +by Goldberg, Robson, Harrison (aka “The Blue Book”), implementation chapters from part IV are available online
        • Virtual machines by Iain D. Craig
        • Great posts by Adam Gardiner: introduction, @@ -191,7 +191,7 @@

          FFI

          diff --git a/web/_site/doc/ru/bootstrapping/index.html b/web/_site/doc/ru/bootstrapping/index.html index 7b1f57cea5..336615db26 100644 --- a/web/_site/doc/ru/bootstrapping/index.html +++ b/web/_site/doc/ru/bootstrapping/index.html @@ -139,7 +139,7 @@

          Начальная загрузка

          -

          Начальная загрузка — это процесс запуска функций системы, подготавливающий +

          Начальная загрузка — это процесс запуска функций системы, подготавливающий возможность исполнения кода на Ruby. Она проходит семь стадий:

            @@ -149,7 +149,7 @@

            Начальная загрузка

            уже доступны, но еще не видны как методы Ruby.

            Класс Class на этой ранней стадии должен быть явно задан путем объявления -самого себя своим классом, а своим суперклассом — Module. В дополнение +самого себя своим классом, а своим суперклассом — Module. В дополнение к Class и Module здесь же создаются еще несколько базовых классов, включая Object, Tuple, LookupTable и MethodTable.

            @@ -160,7 +160,7 @@

            Начальная загрузка

            В этот момент уже определено поведение, достаточное для того, чтобы начать загружать остальное runtime-ядро, целиком написанное на Ruby. Это, в свою -очередь, также делается в несколько проходов по мере «роста» языка.

            +очередь, также делается в несколько проходов по мере «роста» языка.

          1. Альфа: начало загрузки кода на Ruby. Уже есть возможность открывать @@ -181,7 +181,7 @@

            Начальная загрузка

          2. Бутстрап: продолжается добавление минимального функционала для -поддержки загружающихся «платформы» и «основы» (“platform” и “common”, +поддержки загружающихся «платформы» и «основы» (“platform” и “common”, см. ниже). Функции-примитивы добавляются в большинство классов ядра.

          3. @@ -194,7 +194,7 @@

            Начальная загрузка

            Основа: создается подавляющее большинство классов Основной (core) библиотеки. Основные классы Ruby построены настолько независимо от конкретной реализации, насколько это возможно. На этом же этапе добавляется -бóльшая часть функциональных возможностей Rubinius-специфических +бóльшая часть функциональных возможностей Rubinius-специфических классов.

          4. @@ -235,7 +235,7 @@

            Порядок загрузки

            выполняется вызов #attr_accessor. Для этого требуется, чтобы до файла, содержащего некий код, было загружено все, что вызывается из содержащихся в нем описаний скриптов, классов и модулей. kernel/alpha.rb содержит -бóльшую часть определений, необходимых на уровне скрипта или модуля. +бóльшую часть определений, необходимых на уровне скрипта или модуля. Вместе с тем, между некоторыми файлами платформы, основы, дельты и компилятора существуют и иные зависимости, влияющие на порядок загрузки.

            diff --git a/web/_site/doc/ru/bytecode-compiler/parser/index.html b/web/_site/doc/ru/bytecode-compiler/parser/index.html index 30119de7ea..5b5bb59ed3 100644 --- a/web/_site/doc/ru/bytecode-compiler/parser/index.html +++ b/web/_site/doc/ru/bytecode-compiler/parser/index.html @@ -148,11 +148,11 @@

            Парсер Ruby

            -

            Первая стадия конвейера байткод-компиляции — Ruby-парсер. Парсер получает +

            Первая стадия конвейера байткод-компиляции — Ruby-парсер. Парсер получает файл или String с исходником и передает следующей стадии, генератору, полученное AST (Abstract Syntax Tree, дерево абстрактного синтаксиса).

            -

            Сам парсер (он называется «Melbourne»), состоит из C-части, которая +

            Сам парсер (он называется «Melbourne»), состоит из C-части, которая представляет собой, в сущности, парсер MRI, и Ruby-части, которая отвечает за создание Ruby-AST. C-часть общается с Ruby, вызывая специфический метод для каждого узла дерева.

            @@ -194,11 +194,11 @@

            Файлы для справки

            Настройка

            -

            Существует два способа настройки для этой стадии компиляции. Самый простой — +

            Существует два способа настройки для этой стадии компиляции. Самый простой — это настройка создания AST через преобразования AST

            Еще можно создать субкласс класса Melbourne и определить собственные -обработчики методов process_. Этот способ относится к «продвинутым» и к +обработчики методов process_. Этот способ относится к «продвинутым» и к настоящему времени не документирован.

            diff --git a/web/_site/doc/ru/bytecode-compiler/transformations/index.html b/web/_site/doc/ru/bytecode-compiler/transformations/index.html index 9fbfdafa71..cd91ba9bc5 100644 --- a/web/_site/doc/ru/bytecode-compiler/transformations/index.html +++ b/web/_site/doc/ru/bytecode-compiler/transformations/index.html @@ -149,7 +149,7 @@

            Преобразования в компиляторе

            Безопасная математическая трансформация

            Поскольку базовые (core) библиотеки построены из тех же блоков, что и любой -другой Ruby-код, а Ruby — язык динамический, с открытыми классами и +другой Ruby-код, а Ruby — язык динамический, с открытыми классами и отложенным связыванием, появляется возможность изменять фундаментальные классы вроде Fixnum таким образом, что нарушается семантика, от которой зависят другие классы. К примеру, представьте себе такое нововведение:

            @@ -164,7 +164,7 @@

            Безопасная математическая трансф

            Хотя переопределение арифметического_с_фиксированной_точкой_плюса в остаток_от_деления_на_пять вполне возможно, это действие обязательно заставит некоторый класс вроде Array не смочь в нужный момент вычислить, -например, корректную длину. Динамическая натура Ruby — одна из его любимых +например, корректную длину. Динамическая натура Ruby — одна из его любимых черт, но она же в некотором смысле и палка о двух концах.

            Одна из стандартных библиотек, mathn, переопределяет Fixnum#/ в опасной и @@ -176,7 +176,7 @@

            Безопасная математическая трансф классы Fixnum, Bignum, Float и Numeric все определяют этот метод.

            Для запуска плагина безопасная трансформация математики включается в момент -компиляции Core libraries. Когда компилируется обычный «юзер-код», плагин +компиляции Core libraries. Когда компилируется обычный «юзер-код», плагин выключен. Это делает возможной поддержку mathn без повреждения базовых библиотек и принуждения к использованию прочих нехороших приемов.

            diff --git a/web/_site/doc/ru/contributing/communication/index.html b/web/_site/doc/ru/contributing/communication/index.html index 78fd5b0376..d6788507f1 100644 --- a/web/_site/doc/ru/contributing/communication/index.html +++ b/web/_site/doc/ru/contributing/communication/index.html @@ -149,7 +149,7 @@

            Общение

            Команда Rubinius ценит и вознаграждает ваш вклад в проект. Так как Rubinius -— проект большой, а местами и сложный, общение иногда может быть затруднено. +— проект большой, а местами и сложный, общение иногда может быть затруднено. Мы в наибольшей степени полагаемся на IRC, однако, существуют и другие способы взаимодействия. Ниже следует список мест, где нас можно найти:

            diff --git a/web/_site/doc/ru/contributing/index.html b/web/_site/doc/ru/contributing/index.html index 7566db3245..e54497289f 100644 --- a/web/_site/doc/ru/contributing/index.html +++ b/web/_site/doc/ru/contributing/index.html @@ -152,8 +152,8 @@

            Участие в проекте

            Испытывайте Ваши программы

            Зачастую Ваш код сложнее и запутаннее чем спецификации языка. Запустите свое детище -под Rubinius и сообщите о возникших проблемах. См. главу «Как создать -тикет».

            +под Rubinius и сообщите о возникших проблемах. См. главу «Как создать +тикет».

            Обращайтесь за помощью

            @@ -163,7 +163,7 @@

            Обращайтесь за помощью

            доработать.

            Мы обязательно благодарно примем и простые сообщения об ошибках, но к тикетам, -содержащим способы повторения проблемы, отнесемся с бóльшим вниманием. Еще +содержащим способы повторения проблемы, отнесемся с бóльшим вниманием. Еще лучше, если в тикет будет включен RubySpec, который демонстрирует ошибку и патч, который ее исправляет.

            @@ -176,13 +176,13 @@

            Пишите спецификации

            просто нуждаются в пересмотре, либо они отсутствуют для определенного класса.

            -

            Примечание: Вы можете указать псевдо-директорию ‘:files’ для <папки>, +

            Примечание: Вы можете указать псевдо-директорию ‘:files’ для <папки>, чтобы вывести теги для всех спецификаций, которые должны проходить на Rubinius. Можно также указать любую поддиректорию директории spec/, чтобы вывести теги для спеков из этой поддиректории.

          5. -

            Ищите неспецифическое поведение кода. См. гл. «Написание спецификаций Ruby».

            +

            Ищите неспецифическое поведение кода. См. гл. «Написание спецификаций Ruby».

          @@ -193,7 +193,7 @@

          Исправляйте неудачные специфика

          Выполните bin/mspec tag --list fails <папка>, чтобы увидеть спецификации, помеченные как неработающие.

          -

          Примечание: Вы можете указать псевдо-директорию ‘:files’ для <папки>, +

          Примечание: Вы можете указать псевдо-директорию ‘:files’ для <папки>, чтобы вывести теги для всех спецификаций, которые должны проходить на Rubinius. Можно также указать любую поддиректорию директории spec/, чтобы вывести теги для спеков из этой поддиректории.

          @@ -211,7 +211,7 @@

          Пишите документацию

          Вычищайте код

          -

          Вопросы стиля программирования обсуждаются в гл. «Стиль программирования».

          +

          Вопросы стиля программирования обсуждаются в гл. «Стиль программирования».

          Ухаживайте за тикетами

          diff --git a/web/_site/doc/ru/contributing/style-guide/index.html b/web/_site/doc/ru/contributing/style-guide/index.html index c9c3de1748..8a85d2ab4a 100644 --- a/web/_site/doc/ru/contributing/style-guide/index.html +++ b/web/_site/doc/ru/contributing/style-guide/index.html @@ -156,7 +156,7 @@

          C++

          • Не вставляйте пробел между условием и скобкой. - Пишите “if(1)”, а не “if (1)

            + Пишите “if(1)”, а не “if (1)

          • Открывающую фигурную скобку помещайте на одну строчку с условием или @@ -172,7 +172,7 @@

            C++

            Альтернативные варианты функций должны именоваться таким образом, чтобы было понятно, чем они отличаются от основной. Допустим, есть функция person(), и Вы хотите сделать альтернативную функцию, которая принимает -дополнительный параметр “имя”. В таком случае имя функции должно быть +дополнительный параметр “имя”. В таком случае имя функции должно быть person_with_name(char \*name) или person_with_details(char \*name, ...), а ни в коем случае не person1(char \*name).

          • @@ -182,7 +182,7 @@

            Ruby

            • -

              Методы. Пытайтесь реализовывать Ваши методы кратко — не более 1 экрана +

              Методы. Пытайтесь реализовывать Ваши методы кратко — не более 1 экрана на метод. Придерживайтесь принципа DRY в разумных пределах. Обычно общую функциональность следует абстрагировать в методы-помощники (которые можно сделать приватными), но в некоторых случаях, особенно во время @@ -192,7 +192,7 @@

              Ruby

            • Имена методов должны быть ясными, выразительными и осмысленными. За некоторым исключением, старайтесь не использовать знаки подчеркивания для -“защиты” методов (__send__).

              +“защиты” методов (__send__).

            • Допускается именование методов в стиле Smalltalk. Имеется ввиду, что если @@ -202,9 +202,9 @@

              Ruby

            • Имена переменных должны быть ясными и осмысленными (естественно, можно -использовать имя ‘i’ для счетчика). Пытайтесь не перекрывать названия -методов переменными, например внутри класса Array используйте ‘idx’ -вместо ‘index’, поскольку последнее уже является именем метода.

              +использовать имя ‘i’ для счетчика). Пытайтесь не перекрывать названия +методов переменными, например внутри класса Array используйте ‘idx’ +вместо ‘index’, поскольку последнее уже является именем метода.

            • Используйте модификаторы только в том случае, когда Ваше выражение @@ -234,7 +234,7 @@

              Ruby

              Код ядра

              -

              Первичное требование для всего кода ядра — простота и эффективность. Простой +

              Первичное требование для всего кода ядра — простота и эффективность. Простой код зачастую наиболее эффективен и понятен. В коде, отвечающем за начальную загрузку, не должно быть метапрограммирования. Используйте #attr_xxx методы внутри любых исходников ядра. Также, для задания алиасов методам @@ -254,7 +254,7 @@

              Документация

            • Используйте Markdown для документирования в директории /doc. См. -«Синтаксис Markdown». +«Синтаксис Markdown». Установите ширину текста в 78 символов и используйте жесткие переводы строки.

            • diff --git a/web/_site/doc/ru/garbage-collector/mature-generation/index.html b/web/_site/doc/ru/garbage-collector/mature-generation/index.html index ce1992767d..b9c7dc091e 100644 --- a/web/_site/doc/ru/garbage-collector/mature-generation/index.html +++ b/web/_site/doc/ru/garbage-collector/mature-generation/index.html @@ -158,7 +158,7 @@

              Старое поколение

              Mature objects are objects that have been promoted from the Young -generation after living past the promotion threshold ‘X’.

              +generation after living past the promotion threshold ‘X’.

              Autotune is the mechanism that is used to dynamic adjust the GC cycles before mature collection occurrs. This can be turned off or a static number may be used diff --git a/web/_site/doc/ru/getting-started/building/index.html b/web/_site/doc/ru/getting-started/building/index.html index c17d736498..f8e33971e4 100644 --- a/web/_site/doc/ru/getting-started/building/index.html +++ b/web/_site/doc/ru/getting-started/building/index.html @@ -147,10 +147,10 @@

              Сборка Rubinius

              LLVM для JIT-компиляции. Rubinius зависит от определенной версии LLVM, которая должна быть собрана с включенной RTTI (run-time type -information). Скрипт “configure” автоматически проверит эти условия на стадии +information). Скрипт “configure” автоматически проверит эти условия на стадии поиска LLVM. Если LLVM уже установлена на Вашей системе, а Rubinius не может на нее пролинковаться, передайте флаг ---skip-system скрипту “configure” (см. ниже).

              +--skip-system скрипту “configure” (см. ниже).

              Получение исходного кода

              diff --git a/web/_site/doc/ru/getting-started/requirements/index.html b/web/_site/doc/ru/getting-started/requirements/index.html index 0e1d77e7c6..f7d46a092a 100644 --- a/web/_site/doc/ru/getting-started/requirements/index.html +++ b/web/_site/doc/ru/getting-started/requirements/index.html @@ -164,7 +164,7 @@

              Минимальные требования

              Mac OS X

              -

              Простейший путь для создания сборочного окружения на Mac OS X — +

              Простейший путь для создания сборочного окружения на Mac OS X — установка XCode Tools and Utilities. После установки для формирования отчетов об аварийных завершениях можно использовать приложение /Developer/Applications/Utilities/CrashReporterPrefs.app

              diff --git a/web/_site/doc/ru/getting-started/running-rubinius/index.html b/web/_site/doc/ru/getting-started/running-rubinius/index.html index 1659eb842b..61541a2f62 100644 --- a/web/_site/doc/ru/getting-started/running-rubinius/index.html +++ b/web/_site/doc/ru/getting-started/running-rubinius/index.html @@ -150,7 +150,7 @@

              Запуск Rubinius

              rbx -e 'puts "Hello!"'
               
              -

              Для запуска ruby-файла с именем ‘code.rb’:

              +

              Для запуска ruby-файла с именем ‘code.rb’:

              rbx code.rb
               
              diff --git a/web/_site/doc/ru/how-to/commit-to-github/index.html b/web/_site/doc/ru/how-to/commit-to-github/index.html index 0df881fc2a..a3e1fdf5fa 100644 --- a/web/_site/doc/ru/how-to/commit-to-github/index.html +++ b/web/_site/doc/ru/how-to/commit-to-github/index.html @@ -139,7 +139,7 @@

              Коммиты в Github

              -

              В Rubinius Project основная работа делается в master-ветке. Цель разработчиков — +

              В Rubinius Project основная работа делается в master-ветке. Цель разработчиков — держать master чистым, чтобы в нем всегда можно было и собрать работающий бинарник, и получить копию свежих правок и улучшений.

              @@ -148,7 +148,7 @@

              Коммиттерам, имеющим доступ на зап

              Мы рекомендуем коммиттерам, имеющим доступ на запись в основной репозиторий, выполнять работы в ветви локального репозитория. По достижении стабильности правки должны коммититься в два этапа. В первую очередь следует закоммитить -спек, описывающий поведение проблемного участка, а уже следующим коммитом — +спек, описывающий поведение проблемного участка, а уже следующим коммитом — реализацию этого поведения, при которой спек проходит.

              После фиксации в рабочую ветвь локального репозитория коммиты следует @@ -167,7 +167,7 @@

              Коммиттерам, имеющим доступ на зап
            • git add <list of code files>
            • git commit
            • git checkout master
            • -
            • git pull –rebase
            • +
            • git pull –rebase
            • git checkout name-of-fix-branch
            • git rebase master
            • git checkout master
            • @@ -175,7 +175,7 @@

              Коммиттерам, имеющим доступ на зап
            • git push origin master
      -

      Шаги с 9 по 15-й можно автоматизировать скриптом — чтобы сэкономить время на +

      Шаги с 9 по 15-й можно автоматизировать скриптом — чтобы сэкономить время на наборе.

      Коммиттерам без доступа на запись в основной репозиторий

      diff --git a/web/_site/doc/ru/how-to/fix-a-failing-spec/index.html b/web/_site/doc/ru/how-to/fix-a-failing-spec/index.html index 1cd48948ff..a17c24dd2a 100644 --- a/web/_site/doc/ru/how-to/fix-a-failing-spec/index.html +++ b/web/_site/doc/ru/how-to/fix-a-failing-spec/index.html @@ -165,7 +165,7 @@

      How-To - Исправление неработающей специфика коммитом.

    2. Запустите git format-patch origin, эта команда соберет все коммиты, сделанные в текущей ветке с момента последнего pull-a или git format-patch --N, где N – число (1, 2, и т.п.) коммитов, из которых Вы хотите сделать +-N, где N – число (1, 2, и т.п.) коммитов, из которых Вы хотите сделать патчи.
    3. Создайте gist с Вашим патчем и добавьте ссылку на него в тикет в трекере https://github.com/rubinius/rubinius/issues. В один тикет можно помещать diff --git a/web/_site/doc/ru/how-to/translate-documentation/index.html b/web/_site/doc/ru/how-to/translate-documentation/index.html index 6e61397cd2..51438a7155 100644 --- a/web/_site/doc/ru/how-to/translate-documentation/index.html +++ b/web/_site/doc/ru/how-to/translate-documentation/index.html @@ -146,8 +146,8 @@

      Перевод документации

    4. добавление нового перевода.
    -

    Начните с чтения главы «Написание -документации»

    +

    Начните с чтения главы «Написание +документации»

    Обновление существующего перевода

    @@ -160,10 +160,10 @@

    Добавление нового перевода

    Чтобы создать новую языковую версию перевода, нужно:

      -
    1. Скопировать web/doc/en в web/doc/LANG, где LANG — это +
    2. Скопировать web/doc/en в web/doc/LANG, где LANG — это код стандарта ISO-639-2 для языка, на который делается перевод.
    3. -
    4. Отредактировать ссылки в «Содержании», чтобы они указывали на правильные файлы +
    5. Отредактировать ссылки в «Содержании», чтобы они указывали на правильные файлы перевода. (Внимание: по некоторым причинам атрибут page.base_dir недоступен, когда файлы обрабатываются программой Jekyll. С этим моментом стоит разобраться.)
    6. Переведите английский текст на выбранный вами язык.
    7. @@ -176,8 +176,8 @@

      Добавление нового перевода

      Инструменты переводчика

      Мы создали крошечные программки для облегчения жизни переводчиков. -Точнее, формально программка пока только одна, и называется она «Проверка -соответствия переводов».

      +Точнее, формально программка пока только одна, и называется она «Проверка +соответствия переводов».

      Краткий пример использования

      @@ -246,14 +246,14 @@

      Пояснения

      Если перевод старше оригинала или вообще отсутствует, Вы увидите то ужасно красивое сообщение, которое приведено в нашем примере. Если с файлами все в -порядке, программа сообщит и об этом — Вы заметите.

      +порядке, программа сообщит и об этом — Вы заметите.

      Заключение

      Эта супер-нано-пупер-тупая тулза была написана для того, чтобы напомнить переводчику, какие именно файлы могут нуждаться в немедленной доработке. Никакого интеллектуального анализа, например, на валидность перевода и т.п. -пока не планируется. Если Вы — умнейший контрибутор Rubinius всех времен и +пока не планируется. Если Вы — умнейший контрибутор Rubinius всех времен и народов, мы приглашаем Вас расширить возможности настоящего инструмента, помочь обществу и спасти мир!

      diff --git a/web/_site/doc/ru/how-to/write-a-blog-post/index.html b/web/_site/doc/ru/how-to/write-a-blog-post/index.html index 64daf69fdd..410bd862ab 100644 --- a/web/_site/doc/ru/how-to/write-a-blog-post/index.html +++ b/web/_site/doc/ru/how-to/write-a-blog-post/index.html @@ -196,7 +196,7 @@

      How-To - Написание сообщения в блог

    8. Отправьте патч, пулл-реквест или, если у вас есть право коммита в главный -репозиторий, опубликуйте изменения в нем в ветви «master».

      +репозиторий, опубликуйте изменения в нем в ветви «master».

    9. Сообщите нам о новом посте: возможно перед публикацией мы захотим с Вами diff --git a/web/_site/doc/ru/how-to/write-a-ticket/index.html b/web/_site/doc/ru/how-to/write-a-ticket/index.html index ae092e4f2f..35a16ed4fb 100644 --- a/web/_site/doc/ru/how-to/write-a-ticket/index.html +++ b/web/_site/doc/ru/how-to/write-a-ticket/index.html @@ -174,7 +174,7 @@

      Общая процедура добавления тикета

      Проверьте несколько раз.

        -
      1. Полностью пересоберите Rubinius (‘rake clean; rake’) после ‘git pull’ +
      2. Полностью пересоберите Rubinius (‘rake clean; rake’) после ‘git pull’ или нового git clone.
      3. Прочтите Разрешение проблем, возможно это поможет решить вашу проблему.
      4. @@ -194,7 +194,7 @@

        Общая процедура добавления тикета
      5. Команду в терминале, с помощью которой можно вызвать программу
      6. Стектрейс или результат программы вместе с ожидаемым результатом.
      7. Информацию о вашей машине. uname -a обычно достаточно (если в ней -присутствуют “unknown” поля, пожалуйста, дополните их.)
      8. +присутствуют “unknown” поля, пожалуйста, дополните их.)

      @@ -204,17 +204,17 @@

      Дополнительные указания для тике
      • Тикеты могут состоять просто из набора спецификаций.
      • Патчи должны быть снабжены спецификациями в случае их отсутствия.
      • -
      • Релевантную часть вывода спецификации и точный вывод ‘bin/mspec’, +
      • Релевантную часть вывода спецификации и точный вывод ‘bin/mspec’, вызванной с существующей или добавленной спецификацией перед исправлением.
      • -
      • Вывод спецификации и вывод ‘bin/mspec’ показывающий успех после +
      • Вывод спецификации и вывод ‘bin/mspec’ показывающий успех после исправления.
      • Дополнительное описание вашего патча и того, как он исправляет проблему. В частности, что касается новой функциональности, пожалуйста, указывайте обсуждалось ли это уже на #rubinius или ruby-dev.
      -

      Если возможно, пожалуйста, используйте ‘git-format-path’ для создания набора +

      Если возможно, пожалуйста, используйте ‘git-format-path’ для создания набора патчей. Это и упрощает применение патча и сохраняет его атрибуты. В противном случае используйте унифицированный diff.

      @@ -233,17 +233,17 @@

      Пример отправки патча

    10. Заголовок тикета:

      -

      “[PATCH] No method ‘format’ on Kernel (Module)”

      +

      “[PATCH] No method ‘format’ on Kernel (Module)”

    11. Теги:

      -

      “patch core spec”

      +

      “patch core spec”

    12. Текст в тикете:

      -

      The method ‘format’ is not available as a module function of Kernel.

      +

      The method ‘format’ is not available as a module function of Kernel.

      $ bin/mspec spec/ruby/core/kernel/format_spec.rb
       Started
      @@ -254,7 +254,7 @@ 

      Пример отправки патча

      No method 'format' on Kernel (Module):
      -

      The method ‘format’ already exists but has not been set as a module +

      The method ‘format’ already exists but has not been set as a module function. This patch does so.

      After the patch is applied:

      diff --git a/web/_site/doc/ru/how-to/write-benchmarks/index.html b/web/_site/doc/ru/how-to/write-benchmarks/index.html index c9c4004f12..58ba5f70e9 100644 --- a/web/_site/doc/ru/how-to/write-benchmarks/index.html +++ b/web/_site/doc/ru/how-to/write-benchmarks/index.html @@ -141,7 +141,7 @@

      How-To - Написание бенчмарков

      Зачем они нужны?

      -

      Бенчмарки — превосходный инструмент для сравнения Rubinius с другими +

      Бенчмарки — превосходный инструмент для сравнения Rubinius с другими Ruby-платформами, такими как MRI, JRuby, IronRuby и другие. Мы не задавались целью промерять Rubinius сам по себе, поэтому, если Вы хотите поделиться написанным бенчмарком, соблюдите, пожалуйста, следующее:

      diff --git a/web/_site/doc/ru/how-to/write-documentation/index.html b/web/_site/doc/ru/how-to/write-documentation/index.html index e5656d21a6..78b0041358 100644 --- a/web/_site/doc/ru/how-to/write-documentation/index.html +++ b/web/_site/doc/ru/how-to/write-documentation/index.html @@ -176,7 +176,7 @@

      How-To - Написание Документации

      title указывает заголовок документа, который отображается в начале страницы.

      previous и previous_url представляют из себя название и ссылку на -предыдущий документ. Точно также, next и_next_url_ соответствуют ссылке +предыдущий документ. Точно также, next иnext_url соответствуют ссылке и названию следующего документа. Все это используется для повышения удобства просмотра документацию и сокращению размера работ необходимых для изменения порядка следования документов.

      diff --git a/web/_site/doc/ru/index.html b/web/_site/doc/ru/index.html index 7a5f8963dd..e006a5a868 100644 --- a/web/_site/doc/ru/index.html +++ b/web/_site/doc/ru/index.html @@ -128,7 +128,7 @@

      Содержание

      1. Что такое Rubinius?
      2. -
      3. Для начала… +
      4. Для начала…
        1. Минимальные требования
        2. Сборка
        3. diff --git a/web/_site/doc/ru/ruby/global-variables/index.html b/web/_site/doc/ru/ruby/global-variables/index.html index f6ddf05168..6a299a5b14 100644 --- a/web/_site/doc/ru/ruby/global-variables/index.html +++ b/web/_site/doc/ru/ruby/global-variables/index.html @@ -172,7 +172,7 @@

          Глобальные переменные

          puts $SAFE
    -

    Псевдоглобальные переменные — это ограниченное подмножество имен, +

    Псевдоглобальные переменные — это ограниченное подмножество имен, которые ссылаются не на глобальные значения, а на значения в текущей области видимости, подобно локальным переменным. Их по-прежнему называют глобальными из-за того, что их имена начинаются со значка доллара, что является источником diff --git a/web/_site/doc/ru/ruby/index.html b/web/_site/doc/ru/ruby/index.html index c0e32b4c88..ed0ace1e68 100644 --- a/web/_site/doc/ru/ruby/index.html +++ b/web/_site/doc/ru/ruby/index.html @@ -148,15 +148,15 @@

    Ruby

    -

    Один из способов приблизиться к пониманию Rubinius-реализации языка Ruby — +

    Один из способов приблизиться к пониманию Rubinius-реализации языка Ruby — это умение разобраться в том, как устроены базовые элементы самого Ruby. Смысл -настоящей статьи — представить особенности Rubinius на примере понятий +настоящей статьи — представить особенности Rubinius на примере понятий Ruby, которые, как ожидается, уже известны нашему читателю. В документации Rubinius мы предполагаем, что Вы знакомы либо с Ruby, либо с принципами работы компиляторов и виртуальных машин.

    В центр каждого из последующих разделов поставлено понятие -области видимости. В синтаксисе Ruby область видимости — это, как правило, +области видимости. В синтаксисе Ruby область видимости — это, как правило, производное понятие. Иначе говоря, в языке нет синтаксических элементов, первоначально отвечающих за ограничение или обозначение области видимости. Из-за этого разговор о видимости может оказаться весьма путаным. Возьмем, к @@ -175,17 +175,17 @@

    Ruby

    a = 5 строкой выше не имеет никакого отношения к переменной a в #diligent.

    -

    Принято считать, что в Ruby все сущности — объекты. Это не совсем так. В +

    Принято считать, что в Ruby все сущности — объекты. Это не совсем так. В Ruby большинство сущностей являются объектами, тогда как некоторые вещи, исключительно важные для работы кода, вовсе не есть доступные для манипуляции объекты. Более того, какие именно из этих сущностей среды выполнения программы являются объектами Ruby, кардинально зависит от конкретной -реализации. Область видимости — одна из таких сущностей.

    +реализации. Область видимости — одна из таких сущностей.

    -

    По существу, область видимости как идея — это контекст, в котором возможны -ответы на вопросы из ряда: «Каково сейчас значение self?» «Какие -переменные сейчас локальны?» «Какое значение константа APPLE будет иметь -вот в этой точке кода?»

    +

    По существу, область видимости как идея — это контекст, в котором возможны +ответы на вопросы из ряда: «Каково сейчас значение self?» «Какие +переменные сейчас локальны?» «Какое значение константа APPLE будет иметь +вот в этой точке кода?»

    Каждый из последующих элементов Ruby обсуждается с точки зрения их реализации в Rubinius и того, каким образом принцип видимости в этом участвует.

    diff --git a/web/_site/doc/ru/specs/index.html b/web/_site/doc/ru/specs/index.html index 4ab77eda8e..28d35202c9 100644 --- a/web/_site/doc/ru/specs/index.html +++ b/web/_site/doc/ru/specs/index.html @@ -144,12 +144,12 @@

    Спецификации

    без умысла разделена на две части:

      -
    1. файлы в spec/ruby — описывают поведение традиционной реализации +
    2. файлы в spec/ruby — описывают поведение традиционной реализации от Мацумото;
    3. -
    4. все остальные файлы в директории spec — описывают поведение Rubinius.
    5. +
    6. все остальные файлы в директории spec — описывают поведение Rubinius.
    -

    Спеки1 в spec/ruby — это копия RubySpec +

    Спеки1 в spec/ruby — это копия RubySpec соответствующей ревизии. Они регулярно импортируются из проекта RubySpec, причем сбойные помечаются таким образом, что CI-процесс2 всегда имеет доступ к набору проверенных валидных спецификаций. Такой подход @@ -157,15 +157,15 @@

    Спецификации

    регрессиям.

    Документацию по проектированию и написанию спеков можно найти на сайте -«RubySpec project».

    +«RubySpec project».

    Когда Вы станете писать для Rubinius спеки и соответствующий им код, соблюдайте следующий порядок:

      -
    1. Напишите «сбойный» спек для определенного поведения Ruby. Закоммитьте +
    2. Напишите «сбойный» спек для определенного поведения Ruby. Закоммитьте его в отдельный коммит в подходящем месте в spec/ruby.
    3. -
    4. Создайте код для Rubinius, при выполнении которого спек «пойдет». Затем +
    5. Создайте код для Rubinius, при выполнении которого спек «пойдет». Затем снова закоммитьте: этот коммит должен быть отличным от первого, содержащего сам спек.
    6. Запустите rake, чтобы убедиться, что все CI-спеки выполняются успешно.
    7. @@ -178,8 +178,8 @@

      Спецификации

      Примечания

        -
      1. Спек – от сокр. англ. «spec», спецификация.
      2. -
      3. CI – утилита системы непрерывной интеграции.
      4. +
      5. Спек – от сокр. англ. «spec», спецификация.
      6. +
      7. CI – утилита системы непрерывной интеграции.
      diff --git a/web/_site/doc/ru/systems/concurrency/index.html b/web/_site/doc/ru/systems/concurrency/index.html index 2d27f5fb2d..4f23c75581 100644 --- a/web/_site/doc/ru/systems/concurrency/index.html +++ b/web/_site/doc/ru/systems/concurrency/index.html @@ -171,7 +171,7 @@

      Параллелизм

      Обратите внимание: акторы принимают сообщения посредством Actor.receive. Этот вызов блокирует актор до тех пор, пока сообщение не придет в его -«почтовый ящик». Передавая Actor.receive блок и используя фильтрацию +«почтовый ящик». Передавая Actor.receive блок и используя фильтрацию сообщений, можно учитывать в алгоритме тип сообщения:

      Actor.receive do |filter|
      @@ -189,11 +189,11 @@ 

      Параллелизм

      Фильтры применяют к сообщениям метод ===, поэтому when() можно -передавать, например, регулярные выражения, классы или процедуры — в +передавать, например, регулярные выражения, классы или процедуры — в зависимости от конкретной ситуации.

      -

      Акторы могут приобретать отношения «предок-потомок» посредством -Actor.spawn_link. Если потомок по какой-то причине «умирает», +

      Акторы могут приобретать отношения «предок-потомок» посредством +Actor.spawn_link. Если потомок по какой-то причине «умирает», актор-родитель может получить об этом извещение, если перед запуском потомка переменная Actor.trap_exit была установлена в true. Создадим актор-супервизор, управляющий некоторой очередью при помощи 10 @@ -244,8 +244,8 @@

      Параллелизм

      sleep 1 -

      Приведенный пример — фрагмент кода из -«girl_friday». Если у Вас возникли +

      Приведенный пример — фрагмент кода из +«girl_friday». Если у Вас возникли вопросы, поизучайте этот проект.

      diff --git a/web/_site/doc/ru/tools/profiler/index.html b/web/_site/doc/ru/tools/profiler/index.html index 58110414f8..e7f43d5ff3 100644 --- a/web/_site/doc/ru/tools/profiler/index.html +++ b/web/_site/doc/ru/tools/profiler/index.html @@ -154,7 +154,7 @@

      VM Profiler

      The Profiler lives and dies in its own world. The profiler is passed a VM instance when it is created because the profiler needs access to it while it is gathering info. The STATE argument could be passed into all the profiler -methods, but it’s simple enough to pass it in when the profiler is created. +methods, but it’s simple enough to pass it in when the profiler is created. The profiler never manipulates the VM instance. It is important to maintain this separation.

      @@ -210,7 +210,7 @@

      Ruby Profiler

      The #profile method starts the profiler, yields, stops the profiler and prints -the profile data by default. Pass ‘false’ to #profile to not print the data. +the profile data by default. Pass ‘false’ to #profile to not print the data. Either way, the profile data itself is returned by #profile.

      How to Read the Flat Profiler Output

      @@ -233,7 +233,7 @@

      cumulative seconds

      self seconds

      The total time spent in this method less the total time spent in all this -method’s callees.

      +method’s callees.

      calls

      @@ -272,7 +272,7 @@

      Example of Flat Output

      } -

      Running the script with ‘bin/rbx script.rb’ should give the following flat +

      Running the script with ‘bin/rbx script.rb’ should give the following flat output.

        %   cumulative   self                self     total
      @@ -299,7 +299,7 @@ 

      How to Read the Graph Output

      -Xprofiler.graph
       
      -

      Given the same script above, the graph output is shown below. Each “entry” in +

      Given the same script above, the graph output is shown below. Each “entry” in the graph has three sections: 1) the method for the entry, called the primary line; 2) the callers of the primary method; and 3) the methods that the primary method called. The fields have different meanings based on the @@ -320,7 +320,7 @@

      % time

      self

      The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

      +method’s callees. This is the same as self seconds in the flat output.

      children

      @@ -335,16 +335,16 @@

      name

      The name of the method followed by the index number.

      The lines above the primary line are methods that call the primary method. The -callers’ fields have the following interpretation:

      +callers’ fields have the following interpretation:

      self

      The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

      +method’s callees. This is the same as self seconds in the flat output.

      children

      -

      The time spent in the method’s call to the primary method.

      +

      The time spent in the method’s call to the primary method.

      called

      @@ -365,11 +365,11 @@

      name

      self

      The total time spent in this method less the total time spent in all this -method’s callees. This is the same as self seconds in the flat output.

      +method’s callees. This is the same as self seconds in the flat output.

      children

      -

      This is an estimate of the amount of time this method’s callees spent when +

      This is an estimate of the amount of time this method’s callees spent when this method was called by the primary method. The estimate is based on the ration of the time this method spent when called by the primary method to the total time spent in this method.

      diff --git a/web/_site/doc/ru/virtual-machine/instructions/index.html b/web/_site/doc/ru/virtual-machine/instructions/index.html index 004798e79f..22da25e820 100644 --- a/web/_site/doc/ru/virtual-machine/instructions/index.html +++ b/web/_site/doc/ru/virtual-machine/instructions/index.html @@ -256,7 +256,7 @@

      Notes

      Unlike other literals such as strings and numbers, creating a Regexp literal (i.e. via the /regex/ syntax) is a two step process to create the literal slot for the Regexp, create a literal for the string between the - ‘/’ delimiters and create a new Regexp object passing it the string. Only + ‘/’ delimiters and create a new Regexp object passing it the string. Only then can the literal value be set, using the set_literal opcode.

      push_literal(literal)

      @@ -754,7 +754,7 @@

      pop_unwind()

      Remove the next unused unwind registration from the current invocation. This instruction is paired with setup_unwind to remove registrations - when control exits a section of code that registered a handler but didn’t + when control exits a section of code that registered a handler but didn’t use it. For example, exiting a begin that had a rescue expression.

      @@ -1351,7 +1351,7 @@

      cast_for_multi_block_ the arg is an array.

      If the Proc invoked from was in lambda mode, and one argument is passed: - * and it’s an Array, push it. + * and it’s an Array, push it. * and it responds to #to_ary, try and convert it and push it. * otherwise wrap it in a one element Array and push it.

      @@ -1637,7 +1637,7 @@

      Notes

      runtime to determine which code path is executed.

      For example, a method such as Fixnum#times can be optimised at compile - time, but we can’t know until runtime whether or not the Fixnum#times + time, but we can’t know until runtime whether or not the Fixnum#times method has been overridden. The serial number check is used to determine each time the code is executed, whether or not the standard Fixnum#times has been overridden. It leverages the serial number field on a @@ -1646,7 +1646,7 @@

      Notes

      check_serial_private(literal, serial)

      -

      Checks if the specified method’s serial number matches an expected value. +

      Checks if the specified method’s serial number matches an expected value. Considers private methods too.

      @@ -1934,7 +1934,7 @@

      meta_send_op_tequal(litera

      Notes

      -

      Exactly like equal, except calls #=== if it can’t handle it directly.

      +

      Exactly like equal, except calls #=== if it can’t handle it directly.

      meta_send_call(literal, count)

      @@ -2225,7 +2225,7 @@

      call_custom(literal, count)

      meta_to_s(literal)

      -

      Pop a value off the stack and if it’s not a String, call a method +

      Pop a value off the stack and if it’s not a String, call a method indicated by literal on it. Push the resulting object back on the stack.

      diff --git a/web/_site/doc/ru/what-is-rubinius/index.html b/web/_site/doc/ru/what-is-rubinius/index.html index 534ec1140c..5193597046 100644 --- a/web/_site/doc/ru/what-is-rubinius/index.html +++ b/web/_site/doc/ru/what-is-rubinius/index.html @@ -138,7 +138,7 @@

      Что такое Rubinius

      -

      Rubinius — это реализация языка программирования Ruby.

      +

      Rubinius — это реализация языка программирования Ruby.

      Rubinius состоит из байткодовой виртуальной машины, парсера Ruby, компилятора в байткод, сборщика мусора, основанного на поколениях, JIT-компилятора в @@ -156,7 +156,7 @@

      Установка

      системами семейства Unix/Linux. Вскоре появится и поддержка Microsoft Windows.

      Для установки Rubinius выполните указанные ниже команды. Более подробную -информацию можно найти в разделе «Для начала…».

      +информацию можно найти в разделе «Для начала…».

      1. git clone git://github.com/rubinius/rubinius.git
      2. diff --git a/web/_site/feed/atom.xml b/web/_site/feed/atom.xml index 75ead29e6e..5823904704 100644 --- a/web/_site/feed/atom.xml +++ b/web/_site/feed/atom.xml @@ -29,7 +29,7 @@ your first Rubinius commit.</p> <p>Before diving into the Rubinius code, I want to emphasize that there are many ways that you can contribute to Rubinius. One of the most valuable for us is -trying your own library or application on Rubinius. We’ve worked super hard to +trying your own library or application on Rubinius. We&rsquo;ve worked super hard to make using Rubinius in place of MRI as simple as possible. For example, with a typical Rails application, here is all you should need to do to get set up:</p> @@ -38,7 +38,7 @@ rvm use rbx gem install bundler </code></pre> -<p>Once you’ve got Rubinius and Bundler installed, running your application +<p>Once you&rsquo;ve got Rubinius and Bundler installed, running your application should be this simple:</p> <pre><code>cd &lt;my_application&gt; @@ -60,8 +60,8 @@ Github</a>.</p> <p>Another way to contribute to Rubinius is talking about the project. If you tried your application and your 50 gems installed without problems, consider <a href="https://twitter.com/rubinius">tweeting at us</a> or writing up a quick blog post -about your experiences. If you’ve done something -<a href="http://fancy-lang.org/">fancy</a> that you’d like to share with us, we’re always +about your experiences. If you&rsquo;ve done something +<a href="http://fancy-lang.org/">fancy</a> that you&rsquo;d like to share with us, we&rsquo;re always happy to have <a href="http://rubini.us/2011/02/23/introduction-to-fancy/">guest blog posts</a>, too. We even have documentation on <a href="http://rubini.us/doc/en/how-to/write-a-blog-post/">how to write a blog @@ -84,11 +84,11 @@ install it. We provide symlinks for common commands like <code>gem</cod <p>If you run into any trouble with these steps, see the <a href="http://rubini.us/doc/en/getting-started/">Getting Started</a> page for more information. -You may need to install libraries required to build Rubinius. If you don’t -find answers there, visit the <code>#rubinius</code> channel on freenode.net and we’ll +You may need to install libraries required to build Rubinius. If you don&rsquo;t +find answers there, visit the <code>#rubinius</code> channel on freenode.net and we&rsquo;ll help you out.</p> -<p>While the build is running, let’s get a quick overview of how Rubinius is +<p>While the build is running, let&rsquo;s get a quick overview of how Rubinius is organized.</p> <h3 id="code-tour">Code Tour</h3> @@ -103,7 +103,7 @@ debugger are written mostly or all in Ruby.</p> <p>The Ruby core library is found in the <code>kernel/</code> directory. The kernel is divided into subdirectories that are loaded in order when Rubinius boots. The divisions were made to help share the Ruby core library with other -implementations. I’ll cover those basic divisions here. For more details about +implementations. I&rsquo;ll cover those basic divisions here. For more details about how the loading process works, see the <a href="http://rubini.us/doc/en/bootstrapping/">Bootstrapping</a> documentation.</p> @@ -135,7 +135,7 @@ the JIT compiler (<code>vm/llvm/</code>). The <code>main()< <p>One of the important parts of Rubinius are the low-level operations that cannot be defined in Ruby. These are things like adding two Fixnums together. These operations are called primitives and the code for them is in -<code>vm/builtin</code>. Since you will likely encounter these in the core library, we’ll +<code>vm/builtin</code>. Since you will likely encounter these in the core library, we&rsquo;ll delve into them a bit.</p> <h4 id="primitives">Primitives</h4> @@ -143,10 +143,15 @@ delve into them a bit.</p> <p>All methods that can be called in Ruby are exposed as, well, Ruby methods. If you open <code>kernel/bootstrap/fixnum.rb</code>, you should see the following code:</p> -<p>Liquid error: undefined method `join’ for #<String:0x00000002286fc0 /></p> +<div class="highlight"><pre><code class="ruby"><span class="lineno">1</span> <span class="k">def</span> <span class="nf">to_f</span> +<span class="lineno">2</span> <span class="no">Rubinius</span><span class="o">.</span><span class="n">primitive</span> <span class="ss">:fixnum_to_f</span> +<span class="lineno">3</span> <span class="k">raise</span> <span class="no">PrimitiveFailure</span><span class="p">,</span> <span class="s2">&quot;Fixnum#to_f primitive failed&quot;</span> +<span class="lineno">4</span> <span class="k">end</span> +</code></pre> +</div> <p>The <code>Rubinius.primitive :fixnum_to_f</code> code looks like a normal Ruby method -call but it is not. It’s actually a compiler directive to tag this Ruby method +call but it is not. It&rsquo;s actually a compiler directive to tag this Ruby method as having an associated primitive operation. The name of the primitive is <code>fixnum_to_f</code>. This naming convention is standard, being composed of the class name and the method name. Methods in Ruby that are characters, like <code>+</code>, are @@ -161,7 +166,10 @@ operation is appropriate, the method should raise an exception.</p> <p>To see how the Ruby method relates to the primitive code, open <code>vm/builtin/fixnum.hpp</code>:</p> -<p>Liquid error: undefined method `join’ for “\n// Rubinius.primitive :fixnum_to_f\nFloat* to_f(STATE);\n”:String</p> +<div class="highlight"><pre><code class="cpp"><span class="lineno">1</span> <span class="c1">// Rubinius.primitive :fixnum_to_f</span> +<span class="lineno">2</span> <span class="n">Float</span><span class="o">*</span> <span class="n">to_f</span><span class="p">(</span><span class="n">STATE</span><span class="p">);</span> +</code></pre> +</div> <p>The <code>vm/builtin/*.hpp</code> files are processed by the Rubinius build system to automatically generate C++ code to resolve and bind these primitive @@ -171,7 +179,11 @@ method.</p> <p>Finally, the actual implementation of this primitive is found in <code>vm/builtin/fixnum.cpp</code>:</p> -<p>Liquid error: undefined method `join’ for #<String:0x00000002286610 /></p> +<div class="highlight"><pre><code class="cpp"><span class="lineno">1</span> <span class="n">Float</span><span class="o">*</span> <span class="n">Fixnum</span><span class="o">::</span><span class="n">to_f</span><span class="p">(</span><span class="n">STATE</span><span class="p">)</span> <span class="p">{</span> +<span class="lineno">2</span> <span class="k">return</span> <span class="n">Float</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="p">(</span><span class="kt">double</span><span class="p">)</span><span class="n">to_native</span><span class="p">());</span> +<span class="lineno">3</span> <span class="p">}</span> +</code></pre> +</div> <p>Here you can see that a new Float object is being created from the value of the Fixnum. Rubinius names the C++ classes that implement the Ruby primitive @@ -179,7 +191,7 @@ operations the same as their Ruby counterparts. One of the goals of Rubinius is to build an elegant, easily comprehensible system, and we feel that this consistency has been a great benefit toward that goal.</p> -<p>Now that we have a basic idea of the structure of Rubinius, let’s look at some +<p>Now that we have a basic idea of the structure of Rubinius, let&rsquo;s look at some aspects of its runtime behavior, in particular, supporting different Ruby language modes.</p> @@ -201,7 +213,7 @@ bin/rbx -X19 -v </code></pre> <p>The default language mode is 1.8, so if you invoke <code>rbx</code> with no other -options, you’ll be running in 1.8 mode. You can change the default mode with a +options, you&rsquo;ll be running in 1.8 mode. You can change the default mode with a configure time option as follows:</p> <pre><code>./configure --default-version=1.9 @@ -210,8 +222,8 @@ configure time option as follows:</p> <p>If you configure Rubinius to have a default language mode of 1.9, you can access 1.8 mode with the <code>-X18</code> runtime option as discussed above.</p> -<p>Ok, we’ve got the code, we understand something about how it is organized, -we’ve got the runtime behavior down, now let’s look at actually implementing +<p>Ok, we&rsquo;ve got the code, we understand something about how it is organized, +we&rsquo;ve got the runtime behavior down, now let&rsquo;s look at actually implementing Ruby. To do that, we need to know how Ruby behaves, and that is what RubySpec is all about.</p> @@ -221,7 +233,7 @@ is all about.</p> implementing Ruby behavior, and we are constantly contributing more to it. Basically, Rubinius does it by the spec. So, any commit to the Ruby core library in Rubinius must either have new specs or make existing specs pass. To -effectively contribute to Rubinius, you’ll need to understand some basics +effectively contribute to Rubinius, you&rsquo;ll need to understand some basics about RubySpec. I recommend that you have a read through the documentation at <a href="http://rubyspec.org/">rubyspec.org</a>.</p> @@ -266,10 +278,10 @@ path or the shortened version <code>core/array</code> above.</p&g <p>One goal of MSpec is to make it as easy as possible to run the specs for the parts of Ruby that have been implemented. It takes a long time to implement all of Ruby correctly, but we want to know that the parts we have implemented -don’t get broken while working on other parts. That is the role of continuous +don&rsquo;t get broken while working on other parts. That is the role of continuous integration. To use CI effectively, we need to partition the specs into those -that we expect to pass and those we know we don’t pass yet. MSpec provides a -facility for this, called tagging, that we’ll look at shortly. For now, we’ll +that we expect to pass and those we know we don&rsquo;t pass yet. MSpec provides a +facility for this, called tagging, that we&rsquo;ll look at shortly. For now, we&rsquo;ll just look at running the specs in CI mode.</p> <p>To run all the Rubinius specs in CI mode under the default language version, @@ -284,7 +296,7 @@ use the following command:</p> </code></pre> <p>The <code>bin/mspec ci</code> command runs the <code>mspec-ci</code> script. You should be familiar -with this mechanism from working with Git. It’s the same idea. The <code>mspec</code> +with this mechanism from working with Git. It&rsquo;s the same idea. The <code>mspec</code> script itself is just a utility to invoke the various specific MSpec scripts. To see the options for <code>mspec</code>, run the following command</p> @@ -307,33 +319,33 @@ second command runs <code>mspec-run</code> with <code>core/arr mspec core/array ci </code></pre> -<p>Now that we’ve got the basics of MSpec down, let’s look at how we find specs -that fail on Rubinius. To do this, we’ll use the <code>mspec tag</code> command.</p> +<p>Now that we&rsquo;ve got the basics of MSpec down, let&rsquo;s look at how we find specs +that fail on Rubinius. To do this, we&rsquo;ll use the <code>mspec tag</code> command.</p> <h4 id="tagged-specs">Tagged Specs</h4> <p>Since Rubinius uses the tagging mechanism to create the set of CI specs to -run, the best way to discover what parts of RubySpec that Rubinius isn’t -passing yet is to list the specs that are tagged. There’s a command for that:</p> +run, the best way to discover what parts of RubySpec that Rubinius isn&rsquo;t +passing yet is to list the specs that are tagged. There&rsquo;s a command for that:</p> <pre><code>bin/mspec tag --list fails -tx19 :ci_files </code></pre> -<p>This command lists all the specs that are tagged as failing. There’s some new +<p>This command lists all the specs that are tagged as failing. There&rsquo;s some new syntax here, namely <code>:ci_files</code>. MSpec has the concept of pseudo-directories. Basically, they are lists of files. The reason for this is that running all the core or standard library specs in RubySpec is not as simple as just -running all the files under <code>spec/ruby/core</code> or <code>spec/ruby/library</code>. It’s more +running all the files under <code>spec/ruby/core</code> or <code>spec/ruby/library</code>. It&rsquo;s more complicated than that because there are 1.8- and 1.9-specific libraries. Rather than wrapping everything in <code>ruby_version_is</code> guards, MSpec adds version-specific lists and names them, for example, <code>:core</code> and <code>:library</code>.</p> -<p>In this case, we’re using the list of files specified by <code>:ci_files</code>. This +<p>In this case, we&rsquo;re using the list of files specified by <code>:ci_files</code>. This list excludes some files that are known to cause problems if they are run.</p> <p>The list of specs that are currently marked as failing is pretty long. We can reduce the number of tags we are looking at by giving a smaller set of specs -to run. For example, let’s just run the File specs:</p> +to run. For example, let&rsquo;s just run the File specs:</p> <pre><code>bin/mspec tag --list fails -tx19 core/file </code></pre> @@ -345,7 +357,7 @@ writing this post) that there are several failures in the <pre><code>bin/mspec tag --list fails -tx19 core/file/world_writable </code></pre> -<p>If we look into the documentation for <code>File.world_writable?</code>, we’ll find that +<p>If we look into the documentation for <code>File.world_writable?</code>, we&rsquo;ll find that it is a new method introduced in 1.9. Excellent, this gives us an opportunity to talk about language-specific changes in Rubinius.</p> @@ -357,7 +369,7 @@ and <code>load_order19.txt</code> files. These files are used during create separate runtime kernels for Rubinius. You can see these in the <code>runtime/18</code> and <code>runtime/19</code> directories after building.</p> -<p>Here’s how language-specific features are handled in the Rubinius kernel.</p> +<p>Here&rsquo;s how language-specific features are handled in the Rubinius kernel.</p> <ol> <li>If there are no language-specific methods, the name of the file in @@ -385,7 +397,7 @@ command to do that:</p> <pre><code>bin/mspec -tx19 core/file/world_writable </code></pre> -<p>If all the specs pass, then you’re ready to remove the CI tags. To do so, run +<p>If all the specs pass, then you&rsquo;re ready to remove the CI tags. To do so, run the following command:</p> <pre><code>bin/mspec tag --del fails -tx19 core/file/world_writable @@ -397,8 +409,8 @@ pass. To run all the CI specs in both 1.8 and 1.9 modes, simply do:</p> <pre><code>rake </code></pre> -<p>If everything passes, you’re ready to submit a pull request. All in all, that -wasn’t too bad, right?</p> +<p>If everything passes, you&rsquo;re ready to submit a pull request. All in all, that +wasn&rsquo;t too bad, right?</p> <p>One final note, if you are making changes to RubySpec, make separate commits in your pull request for changes to <code>spec/ruby/**/*_specs.rb</code> and another @@ -408,10 +420,10 @@ with the other Rubinius changes.</p> <h3 id="wrapping-presents">Wrapping Presents</h3> <p>The information here should give you everything you need to get your feet wet -in Rubinius. By the way, today is Evan’s birthday. If you’re not taking him to -dinner, why don’t you show your appreciation for this fantastic project he +in Rubinius. By the way, today is Evan&rsquo;s birthday. If you&rsquo;re not taking him to +dinner, why don&rsquo;t you show your appreciation for this fantastic project he created by grabbing Rubinius and hacking on some Ruby code. Be safe and have -fun! We can’t wait to hear from you.</p> +fun! We can&rsquo;t wait to hear from you.</p> @@ -443,7 +455,7 @@ fun! We can’t wait to hear from you.</p> Shane Becker - <p>Steve Klabnik <a href="https://github.com/rubinius/rubinius/pull/1184">added support for <code>require_relative</code> to Rubinius</a>. He documents his process and <a href="http://blog.steveklabnik.com/2011/10/04/rubinius-is-awesome.html" title="Rubinius Is Awesome - Literate Programming">how much fun he had</a>. We’re glad to hear that Steve thinks Rubinius is awesome. Making Rubinius awesome for rubyists has always been one of our core tenets.</p> + <p>Steve Klabnik <a href="https://github.com/rubinius/rubinius/pull/1184">added support for <code>require_relative</code> to Rubinius</a>. He documents his process and <a href="http://blog.steveklabnik.com/2011/10/04/rubinius-is-awesome.html" title="Rubinius Is Awesome - Literate Programming">how much fun he had</a>. We&rsquo;re glad to hear that Steve thinks Rubinius is awesome. Making Rubinius awesome for rubyists has always been one of our core tenets.</p> <blockquote> <p>Even if I didn’t have some code to look at, because Rubinius is just Ruby, @@ -491,21 +503,21 @@ Installer.</p> <h3 id="bad-news-first">Bad News First</h3> -<p>The <a href="http://www.flickr.com/photos/veganstraightedge/5709097384" title="Rubinius &quot;Use Ruby™&quot; TShirts at the Farmhouse in Hollywood, CA">General Availability shirts</a> are retired. We gave out about 1,000 to people all over the world. That’s very awesome. We’re really happy with the excitement about Rubinius from you all. Thank you, again. But it’s time to move on from these shirts. If you’ve already got one, good on you. If you haven’t yet, sorry. There will be other chances in the future, though.</p> +<p>The <a href="http://www.flickr.com/photos/veganstraightedge/5709097384" title="Rubinius &quot;Use Ruby™&quot; TShirts at the Farmhouse in Hollywood, CA">General Availability shirts</a> are retired. We gave out about 1,000 to people all over the world. That&rsquo;s very awesome. We&rsquo;re really happy with the excitement about Rubinius from you all. Thank you, again. But it&rsquo;s time to move on from these shirts. If you&rsquo;ve already got one, good on you. If you haven&rsquo;t yet, sorry. There will be other chances in the future, though.</p> <p>Likewise, the <a href="http://asset.rubini.us/web/images/blog/rubinius_square_sticker.png">Square</a> and <a href="http://asset.rubini.us/web/images/blog/rubinius_bumper_sticker.png">Bumper Stickers</a> have been retired, too.</p> <h3 id="good-news-next">Good News Next</h3> -<p>The <a href="http://asset.rubini.us/web/images/blog/rubinius_diecut_sticker.png">Diecut R stickers</a> are still available. Just email us at <a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;">&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;</a> if you want one. <a href="http://asset.rubini.us/web/images/blog/rubinius_alumni_sticker.png">Committers stickers</a> are still available too. If you committed to Rubinius before May 16, 2011 and haven’t received one of these, <a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;">&#101;&#109;&#097;&#105;&#108;&#032;&#117;&#115;</a> to get yours. The 2011 Q2 committers stickers are also available.</p> +<p>The <a href="http://asset.rubini.us/web/images/blog/rubinius_diecut_sticker.png">Diecut R stickers</a> are still available. Just email us at <a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;">&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;</a> if you want one. <a href="http://asset.rubini.us/web/images/blog/rubinius_alumni_sticker.png">Committers stickers</a> are still available too. If you committed to Rubinius before May 16, 2011 and haven&rsquo;t received one of these, <a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;">&#101;&#109;&#097;&#105;&#108;&#032;&#117;&#115;</a> to get yours. The 2011 Q2 committers stickers are also available.</p> -<p>As <a href="http://rubini.us/2011/05/26/rubinius-rewards/#tenth-commit-shirt" title="Announcing Rubinius Rewards - Rubinius">promised</a>, we have made a special t-shirt for people who have committed 10 or more times. They’re at the printer right now, so no pictures yet. Here’s a hint though: black on black.</p> +<p>As <a href="http://rubini.us/2011/05/26/rubinius-rewards/#tenth-commit-shirt" title="Announcing Rubinius Rewards - Rubinius">promised</a>, we have made a special t-shirt for people who have committed 10 or more times. They&rsquo;re at the printer right now, so no pictures yet. Here&rsquo;s a hint though: black on black.</p> -<p>We’ll continue to do free stuff in the future, but it will always be changing. Keep an eye on this blog for updates to what’s available.</p> +<p>We&rsquo;ll continue to do free stuff in the future, but it will always be changing. Keep an eye on this blog for updates to what&rsquo;s available.</p> <h3 id="one-more-thing">One More Thing</h3> -<p>Rubinius friend of the family, <a href="http://hrrrthrrr.com" title="hrrrthrrr">Heather Peterson</a> (<a href="http://twitter.com/hrrrthrrr">@hrrrthrrr</a>) drew up some Rubinius sketches for us to use on upcoming t-shirts and stickers. As a little thing, we’re giving away her original artwork as prize.</p> +<p>Rubinius friend of the family, <a href="http://hrrrthrrr.com" title="hrrrthrrr">Heather Peterson</a> (<a href="http://twitter.com/hrrrthrrr">@hrrrthrrr</a>) drew up some Rubinius sketches for us to use on upcoming t-shirts and stickers. As a little thing, we&rsquo;re giving away her original artwork as prize.</p> <p><a href="http://flickr.com/veganstraightedge/6106800183" title="Rubinius sketch by Heather Peterson (@hrrrthrrr)"><img src="http://farm7.static.flickr.com/6186/6106800183_f6bd6918f4_z.jpg" alt="Rubinius sketch by Heather Peterson (@hrrrthrrr) on Flickr" /></a> <a href="http://flickr.com/veganstraightedge/6106803145" title="Rubinius sketch by Heather Peterson (@hrrrthrrr)"><img src="http://farm7.static.flickr.com/6072/6106803145_f565d6738e_z.jpg" alt="Rubinius sketch by Heather Peterson (@hrrrthrrr) on Flickr" /></a></p> @@ -514,7 +526,7 @@ Installer.</p> <p>Get blogging.</p> -<p><em>— XOXO RBX</em></p> +<p><em>&mdash; XOXO RBX</em></p> @@ -529,18 +541,18 @@ Installer.</p> <p>A long time ago, <a href="http://twitter.com/bookis" title="@bookis on Twitter">Bookis Smuin</a> crafted up a 3-dimensional representation of the little Rubinius <em>r</em> logo. It was used on the Rubinius website and as the avatar for the <a href="http://twitter.com/#!/rubinius" title="@Rubinius on Twitter">@Rubinius</a> account. And for awhile, things were good.</p> -<p>Somewhere along the way, the original files were lost. That left us with only PNG that was 239px wide. That’s no good. To the Twitters!</p> +<p>Somewhere along the way, the original files were lost. That left us with only PNG that was 239px wide. That&rsquo;s no good. To the Twitters!</p> <p>I <a href="http://twitter.com/#!/veganstraightedge/status/101149379880157184" title="Plea for 3D Help on Twitter">lazy tweeted</a> asking for help re-building the logo in 3D based on the work that Bookis did. Lo and behold, I asked and the internet delivered.</p> -<p>The very smart and good looking Roger Bacardit (<a href="http://twitter.com/ruxii" title="@ruxii on Twitter">@ruxii</a>) from <a href="http://codegram.com" title="Codegram - Smart Web Apps">Codegram</a> in Barcelona, España stepped up to tackle the task. Lickity split, he cranked out two versions (white on black and black on white) at super mega huge resolution (~4000px square).</p> +<p>The very smart and good looking Roger Bacardit (<a href="http://twitter.com/ruxii" title="@ruxii on Twitter">@ruxii</a>) from <a href="http://codegram.com" title="Codegram - Smart Web Apps">Codegram</a> in Barcelona, Espa&ntilde;a stepped up to tackle the task. Lickity split, he cranked out two versions (white on black and black on white) at super mega huge resolution (~4000px square).</p> <p>Like everything else we do, <a href="https://github.com/rubinius/collateral/tree/master/logos/3D">these logo files</a> are <a href="https://github.com/rubinius/collateral/blob/master/README.md">very liberally licensed</a> and available for download and reuse in the <a href="https://github.com/rubinius/collateral">Rubinius Collateral repo</a> over on GitHub.</p> <p>Thank you, Bookis, for the original. Thank you, Roger, for the rebuild.</p> -<p><em>— XOXO RBX</em></p> +<p><em>&mdash; XOXO RBX</em></p> @@ -556,12 +568,12 @@ Thank you, Roger, for the rebuild.</p> <p>With just a few hours left in the first <a href="http://rbxday.rubini.us">#rbxday</a>, I wanted to share a few blog posts that people have written for today. It seems like lots of people are having lots of fun all while using Rubinius. -That’s what really matters.</p> +That&rsquo;s what really matters.</p> <p>And I think <a href="http://twitter.com/andrewwk">Andrew W. K.</a> would probably be proud of that.</p> -<p>Onto the blog posts…</p> +<p>Onto the blog posts&hellip;</p> <p>Nathan Engdahl on the <a href="http://bluebox.net/news/2011/08/rubinius-day" title="Rubinius Day">Blue Box Group blog</a> @@ -579,18 +591,18 @@ at peak efficiency.</p> from MRI, JRuby and Rubinius:</p> <blockquote> - <p>Many developers don’t think too much about what’s going on behind the -scenes when they run their Ruby code. That’s the beauty of it, easy to -write code that’s given to Ruby and run for the developer. At some point -the developer may wonder, what’s REALLY going on behind the scenes. How is + <p>Many developers don&rsquo;t think too much about what&rsquo;s going on behind the +scenes when they run their Ruby code. That&rsquo;s the beauty of it, easy to +write code that&rsquo;s given to Ruby and run for the developer. At some point +the developer may wonder, what&rsquo;s REALLY going on behind the scenes. How is it that something meant to run Ruby can host <a href="http://rubini.us/projects&quot;">so many other languages</a>? -The answer lies in what’s known as a VM, or Virtual Machine.</p> +The answer lies in what&rsquo;s known as a VM, or Virtual Machine.</p> </blockquote> -<p>Finally, there’s the +<p>Finally, there&rsquo;s the <a href="http://rubysfera.pl/2011/08/kod-zrodlowy-rubiego-w-rubym/" title="Kod źródłowy Rubiego w Rubym">Rubysfera blog</a> -that’s not written in a language that I can read. So, I’ll just assume that -they’re talking about Chocolate Rubinius Cake and how to bake it. ;)</p> +that&rsquo;s not written in a language that I can read. So, I&rsquo;ll just assume that +they&rsquo;re talking about Chocolate Rubinius Cake and how to bake it. ;)</p> <blockquote> <p>Rubiniusa (implementacji Rubiego, napisanej w Rubym) nikomu chyba @@ -603,14 +615,14 @@ zajrzenia do implementacji języka w Rubym.</p> <p><em>Seriously though, I have no idea what that post says. If you do, please let me know.</em></p> -<p>There’s still time. Go test your app running on Rubinius. Tweet about it. +<p>There&rsquo;s still time. Go test your app running on Rubinius. Tweet about it. Use the hashtag <a href="https://twitter.com/#!/search/%23rbxday">#rbxday</a>, so we notice you and re-share your tweet. If there are bugs, please <a href="https://github.com/rubinius/rubinius/issues">create an issue</a> on Github. Give us any other feedback you want on the <a href="http://rbxday.rubini.us/feedback">rbxday.rubini.us</a> website.</p> -<p><em>— XOXO RBX</em></p> +<p><em>&mdash; XOXO RBX</em></p> @@ -636,10 +648,10 @@ updates.</p> <p>Originally, the idea for <a href="https://twitter.com/#!/search/%23rbxday">#rbxday</a> was a day that people all around the world could have fun experimenting with Ruby and Rubinius. Try your application or pet Ruby project on Rubinius, or -pull out that idea you’ve been wanting to explore, code it up, and run it on +pull out that idea you&rsquo;ve been wanting to explore, code it up, and run it on Rubinius. We are not asking anyone to contribute to Rubinius, but we would be -most flattered if you wanted to dig into the Rubinius code to see what’s going -on under the hood. To sum up, the motto of the day is “Ruby, Rubinius, Fun Fun Fun Fun”.</p> +most flattered if you wanted to dig into the Rubinius code to see what&rsquo;s going +on under the hood. To sum up, the motto of the day is &ldquo;Ruby, Rubinius, Fun Fun Fun Fun&rdquo;.</p> <p>Of course, a great way to multiply fun is to share it with others. Several people have taken the initiative of organizing meetups on @@ -683,8 +695,8 @@ co-founder of <a href="http://twitter.com/wyeworks">@wyeworks< </ul> <p>A huge thanks to everyone who has organized one of these events. They did so -on their own initiative and show the true power of a community. If you’re near -one of the events, please do attend. If not, <em>there’s still time to organize +on their own initiative and show the true power of a community. If you&rsquo;re near +one of the events, please do attend. If not, <em>there&rsquo;s still time to organize one near you.</em></p> <p>If you are joining <a href="http://twitter.com/#!/search/%23rbxday">#rbxday</a> from the @@ -692,9 +704,9 @@ comfort of your own home, tweet about it, include pictures, and join us in the <a href="irc://irc.freenode.net#rubinius">#rubinius</a> IRC channel on freenode.net. We would love to hear from you.</p> -<p>A final thought about all the ways you can help Rubinius. You don’t have to +<p>A final thought about all the ways you can help Rubinius. You don&rsquo;t have to contribute code directly to help. Each of these activities is just as -valuable, and if you think of any I didn’t include, please let me know:</p> +valuable, and if you think of any I didn&rsquo;t include, please let me know:</p> <ul> <li>Wearing your <a href="http://rubini.us/2011/05/26/rubinius-rewards">Rubinius shirt</a></li> @@ -708,7 +720,7 @@ to improve those pain points</li> <li>Testing your code on Rubinius and submitting bug/performance reports</li> </ul> -<p>Above all, please do have fun. That’s no gimmick. The world needs more fun.</p> +<p>Above all, please do have fun. That&rsquo;s no gimmick. The world needs more fun.</p> <p>Put a tag on it <a href="http://twitter.com/#!/search/%23rbxday">#rbxday</a>.</p> @@ -723,23 +735,23 @@ to improve those pain points</li> Dirkjan Bussink - <p>Not only in the US is <a href="http://rbxday.rubini.us/">#rbxday</a> celebrated, but -we have also something in Amsterdam next Friday. It’s really becoming the + <p>Not only in the US is <a href="http://rbxday.rubini.us/">&#35;rbxday</a> celebrated, but +we have also something in Amsterdam next Friday. It&rsquo;s really becoming the International Rubinius Day that it was set out to be.</p> <p>The guys are <a href="http://www.80beans.com/">80beans</a> are sponsoring the event and have graciously offered their office as the place to hang out and are providing refreshments. The office is located on the <a href="http://maps.google.com/maps/place?q=80beans,+Amsterdam,+The+Netherlands&amp;hl=en&amp;cid=15251096961071716406">Vijzelstraat 72</a> in -Amsterdam and we’re starting at 3pm.</p> +Amsterdam and we&rsquo;re starting at 3pm.</p> -<p>If you’re living in the neighborhood, please come and join us. As long +<p>If you&rsquo;re living in the neighborhood, please come and join us. As long term Rubinius contributor Dirkjan Bussink is coming over from the other side of -the country, so don’t feel held back when you’re not living in Amsterdam +the country, so don&rsquo;t feel held back when you&rsquo;re not living in Amsterdam itself.</p> <p>So be prepared for an afternoon of very interesting hacking. We really want to make it a fun afternoon of experimenting with Rubinius, so anything -goes! Please leave a message on the <a href="http://www.80beans.com/en/blog">80beans blog</a> if you’re planning to come over:</p> +goes! Please leave a message on the <a href="http://www.80beans.com/en/blog">80beans blog</a> if you&rsquo;re planning to come over:</p> <p><a href="http://www.80beans.com/en/blog/2011/07/29/rbxday-at-the-80beans-office">http://www.80beans.com/en/blog/2011/07/29/rbxday-at-the-80beans-office</a></p> @@ -760,21 +772,21 @@ goes! Please leave a message on the <a href="http://www.80beans.com/en/b <p>Hey Ruby bytecode fans! The first ever <strong>International Rubinius Day</strong> is next Friday, August 5th. Around the world people will be trying their code on Rubinius and generally having a fun time. Follow the activities on Twitter -under the <em>#rbxday</em> tag and use that to let folks know what you’re up to. Stay +under the <em>#rbxday</em> tag and use that to let folks know what you&rsquo;re up to. Stay tuned to the <a href="http://rbxday.rubini.us/">rbxday website</a> for details as the day unfolds.</p> <p>If you are located in, around, or within traveling distance of beautiful Mountain View, CA, the terrific folks at <a href="http://outright.com">Outright.com</a> are sponsoring a real live <em>#rbxday</em> event! Come hang out with a bunch of -hardcore Ruby nerds, including Brian Ford (that’s me) from the Rubinius team. +hardcore Ruby nerds, including Brian Ford (that&rsquo;s me) from the Rubinius team. Plan to be inspired by all the great stuff people are working on. There will be mountains of top-shelf Rubinius schwag, as well as <em>free beer and pizza</em>. -(Just don’t get too trashed as there will also be lightning talks and an IR +(Just don&rsquo;t get too trashed as there will also be lightning talks and an IR helicopter obstacle course.)</p> <p>The <a href="http://rbxday.eventbrite.com/">party</a> will be from 1:00 pm to 8:00 pm on -Friday August 5th at Outright’s offices in downtown Mountain View. (They have +Friday August 5th at Outright&rsquo;s offices in downtown Mountain View. (They have an application that does some seriously awesome stuff with small business accounting.) There are plenty of desks, monitors and whiteboards available, so bring your laptop and be ready to jam.</p> @@ -797,25 +809,25 @@ now</a>!</p> Shane Becker - <h3 id="wersquore-having-a-party-and-yoursquore-invited">We’re having a party and you’re invited!</h3> + <h3 id="wersquore-having-a-party-and-yoursquore-invited">We&rsquo;re having a party and you&rsquo;re invited!</h3> <h3 id="rbxdayrubiniushttprbxdayrubinius"><a href="http://rbxday.rubini.us">rbxday.rubini.us</a></h3> <h4 id="friday-august-5-2011-is-rbxdayhttprbxdayrubinius">Friday, August 5, 2011 is <a href="http://rbxday.rubini.us">#rbxday</a></h4> -<p>The Rubinius 2.0 Preview Release is still cranking along. We’re feeling good about how things are going. As always, thank you everyone for all of your contributions. The <a href="http://rubini.us/releases/1.2.4/#authors" title="Rubinius : Use Ruby&#8482;">list of authors on the 1.2.4 release</a> is just fantastic.</p> +<p>The Rubinius 2.0 Preview Release is still cranking along. We&rsquo;re feeling good about how things are going. As always, thank you everyone for all of your contributions. The <a href="http://rubini.us/releases/1.2.4/#authors" title="Rubinius : Use Ruby&#8482;">list of authors on the 1.2.4 release</a> is just fantastic.</p> -<p>Moving forward to the 2.0 official release, we need more feedback from you about your code running on Rubinius. Not just what doesn’t work and not just bugs (although both of those are important too), but how is your code performing, where are the bottlenecks, etc.</p> +<p>Moving forward to the 2.0 official release, we need more feedback from you about your code running on Rubinius. Not just what doesn&rsquo;t work and not just bugs (although both of those are important too), but how is your code performing, where are the bottlenecks, etc.</p> -<p>This is what we’re going to do about that. Everyone… everyone all around the world that uses or cares about Rubinius and its progress, all of us on one day are going to run our code, collect performance data / bug reports and send them up to the Rubinius project.</p> +<p>This is what we&rsquo;re going to do about that. Everyone&hellip; everyone all around the world that uses or cares about Rubinius and its progress, all of us on one day are going to run our code, collect performance data / bug reports and send them up to the Rubinius project.</p> -<p><a href="https://twitter.com/#!/search/%23rbxday">#rbxday</a> is a party! Take pictures of you and your buddies on the day of. If you’ve got a Rubinius t-shirt or sticker, get them in there. Tweet about it, now and on the day. Get excited. Tell your friends. Get them excited. Use the hashtag #rbxday in your tweets, blog posts and posts. We’ll repost them all on the <a href="http://rbxday.rubini.us">#rbxday</a> site.</p> +<p><a href="https://twitter.com/#!/search/%23rbxday">#rbxday</a> is a party! Take pictures of you and your buddies on the day of. If you&rsquo;ve got a Rubinius t-shirt or sticker, get them in there. Tweet about it, now and on the day. Get excited. Tell your friends. Get them excited. Use the hashtag #rbxday in your tweets, blog posts and posts. We&rsquo;ll repost them all on the <a href="http://rbxday.rubini.us">#rbxday</a> site.</p> -<p>Make sure you’re looking your best in your photos because we’ll be picking a winner for our favorite <a href="http://twitter.com/#!/search/%23rbxday" title="#rbxday search on Twitter">#rbxday</a> glamourshot. Tweet them using the hashtag <a href="http://twitter.com/#!/search/%23rbxday" title="#rbxday search on Twitter">#rbxday</a> and we’ll announce the winning photo Monday, August 8, 2011 on the <a href="http://facebook.com/engineyard">Engine Yard Facebook page</a>. We’ll have a nifty prize for the winner too, so make sure your pic is goofy, sultry, or otherwise impressive. Bonus points for creativity.</p> +<p>Make sure you&rsquo;re looking your best in your photos because we&rsquo;ll be picking a winner for our favorite <a href="http://twitter.com/#!/search/%23rbxday" title="#rbxday search on Twitter">#rbxday</a> glamourshot. Tweet them using the hashtag <a href="http://twitter.com/#!/search/%23rbxday" title="#rbxday search on Twitter">#rbxday</a> and we&rsquo;ll announce the winning photo Monday, August 8, 2011 on the <a href="http://facebook.com/engineyard">Engine Yard Facebook page</a>. We&rsquo;ll have a nifty prize for the winner too, so make sure your pic is goofy, sultry, or otherwise impressive. Bonus points for creativity.</p> <p>Get your party hats on!</p> -<p>—XOXO RBX</p> +<p>&mdash;XOXO RBX</p> @@ -828,38 +840,38 @@ now</a>!</p> Shane Becker - <p>I’m pretty sure it started like this.</p> + <p>I&rsquo;m pretty sure it started like this.</p> <blockquote> - <p>“Hello, Evan dear.” — <em>Evan’s Grandma Betty</em></p> + <p>&ldquo;Hello, Evan dear.&rdquo; &mdash; <em>Evan&rsquo;s Grandma Betty</em></p> </blockquote> <blockquote> - <p>“Grandma Betty!” — <em>Evan</em></p> + <p>&ldquo;Grandma Betty!&rdquo; &mdash; <em>Evan</em></p> </blockquote> <blockquote> - <p>“You know, I was thinking about your little Rubinius thingy while I was gardening today. How’s it doing?” — <em>Evan’s Grandma Betty</em></p> + <p>&ldquo;You know, I was thinking about your little Rubinius thingy while I was gardening today. How&rsquo;s it doing?&rdquo; &mdash; <em>Evan&rsquo;s Grandma Betty</em></p> </blockquote> <blockquote> - <p>“Oh, Grandma Betty, that’s so sweet of you to think of me and it. It’s coming along still, of course.” — <em>Evan</em></p> + <p>&ldquo;Oh, Grandma Betty, that&rsquo;s so sweet of you to think of me and it. It&rsquo;s coming along still, of course.&rdquo; &mdash; <em>Evan</em></p> </blockquote> <blockquote> - <p>“That’s good to hear. I was specifically wondering how the 1.9 support is looking.” — <em>Evan’s Grandma Betty</em></p> + <p>&ldquo;That&rsquo;s good to hear. I was specifically wondering how the 1.9 support is looking.&rdquo; &mdash; <em>Evan&rsquo;s Grandma Betty</em></p> </blockquote> <blockquote> - <p>“Grandma Betty! You do always love the Latest and Greatest™, don’t you? Well, let’s see. I’d say that <em>1.9 support</em> comes down to 7 main areas: Encoding, String, Regex, Symbol, IO, Argument Processing, Windows Support. Each has varying degrees of progress.” — <em>Evan</em></p> + <p>&ldquo;Grandma Betty! You do always love the Latest and Greatest&trade;, don&rsquo;t you? Well, let&rsquo;s see. I&rsquo;d say that <em>1.9 support</em> comes down to 7 main areas: Encoding, String, Regex, Symbol, IO, Argument Processing, Windows Support. Each has varying degrees of progress.&rdquo; &mdash; <em>Evan</em></p> </blockquote> <blockquote> - <p>“OK. I wish that there was some way for me to keep more up to date on these happenings without needing to calling you. When I call you, I want to hear about that wife and baby of yours.” — <em>Evan’s Grandma Betty</em></p> + <p>&ldquo;OK. I wish that there was some way for me to keep more up to date on these happenings without needing to calling you. When I call you, I want to hear about that wife and baby of yours.&rdquo; &mdash; <em>Evan&rsquo;s Grandma Betty</em></p> </blockquote> <blockquote> - <p>“You got it, Grandma Betty. I’ll get my Top Nerds™ on the case.” — <em>Evan</em></p> + <p>&ldquo;You got it, Grandma Betty. I&rsquo;ll get my Top Nerds&trade; on the case.&rdquo; &mdash; <em>Evan</em></p> </blockquote> <blockquote> @@ -867,10 +879,10 @@ now</a>!</p> </blockquote> <blockquote> - <p>“Alright, Grandma Betty. We made the Rubinius Status Board™ especially just for you. It’s <a href="http://status.rubini.us">status.rubini.us</a>” — <em>Evan</em></p> + <p>&ldquo;Alright, Grandma Betty. We made the Rubinius Status Board&trade; especially just for you. It&rsquo;s <a href="http://status.rubini.us">status.rubini.us</a>&rdquo; &mdash; <em>Evan</em></p> </blockquote> -<p>That conversation may or may not be <strong>completely fictionalized</strong>. There is one thing that is most emphatically true: Rubinius has a Status Board™ now. If you are ever curious how progress is going on things, go check out <a href="http://status.rubini.us">status.rubini.us</a>. Tell your friends.</p> +<p>That conversation may or may not be <strong>completely fictionalized</strong>. There is one thing that is most emphatically true: Rubinius has a Status Board&trade; now. If you are ever curious how progress is going on things, go check out <a href="http://status.rubini.us">status.rubini.us</a>. Tell your friends.</p> <p>XOXO RBX.</p> @@ -885,9 +897,9 @@ now</a>!</p> Shane Becker - <p>As a result of the <a href="http://rubini.us/2011/05/26/rubinius-rewards/" title="Announcing Rubinius Rewards - Rubinius">Rubinius Rewards</a>, people from all over the world have requested Rubinius stickers and t-shirts. That just warms our little hearts and humbles us everyday. Thank you so much. It means the world to us. Keep using Rubinius with passion and excitement. Keep spreading the good word to your friends and anyone who’ll listen and care. And keep telling us how Rubinius is working for you. However good or bad, we want to know.</p> + <p>As a result of the <a href="http://rubini.us/2011/05/26/rubinius-rewards/" title="Announcing Rubinius Rewards - Rubinius">Rubinius Rewards</a>, people from all over the world have requested Rubinius stickers and t-shirts. That just warms our little hearts and humbles us everyday. Thank you so much. It means the world to us. Keep using Rubinius with passion and excitement. Keep spreading the good word to your friends and anyone who&rsquo;ll listen and care. And keep telling us how Rubinius is working for you. However good or bad, we want to know.</p> -<p>Here’s a map of all the places where we’ve sent stickers and/or t-shirts. You can also view it on +<p>Here&rsquo;s a map of all the places where we&rsquo;ve sent stickers and/or t-shirts. You can also view it on <a href="http://maps.google.com/maps/ms?msa=0&amp;msid=204706765448868864026.0004a732bcb9b5816e407&amp;ie=UTF8&amp;ll=19.311143,-0.351562&amp;spn=111.602296,333.632812&amp;z=2&amp;source=embed" title="Rubinius Around the World - Google Maps">a larger map</a>. Wow.</p> <iframe width="950" height="400" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.com/maps/ms?msa=0&amp;msid=204706765448868864026.0004a732bcb9b5816e407&amp;ie=UTF8&amp;ll=19.311143,-0.351562&amp;spn=111.602296,333.632812&amp;z=2&amp;output=embed"></iframe> @@ -909,19 +921,19 @@ now</a>!</p> Shane Becker - <p>Once a month Evan Phoenix, Brian Ford and I (Shane Beccker) get together for a few days in-person face-time. Usually we meet up in San Francisco at the <a href="http://engineyard.com">Engine Yard</a> HQ and spend time with our dear and lovely boss, <a href="http://twitter.com/drnic">Dr Nic</a>. We like to call these little get togethers Rubinius Summits. For the June 2011 Rubinius Summit, Brian came down to LA where both Evan and I live. We spent the week working together at <a href="http://farmhouse.la">The Farmhouse</a> on moving the ball forward toward the 2.0 release. Here’s a few pictures of some of the things that went down.</p> + <p>Once a month Evan Phoenix, Brian Ford and I (Shane Beccker) get together for a few days in-person face-time. Usually we meet up in San Francisco at the <a href="http://engineyard.com">Engine Yard</a> HQ and spend time with our dear and lovely boss, <a href="http://twitter.com/drnic">Dr Nic</a>. We like to call these little get togethers Rubinius Summits. For the June 2011 Rubinius Summit, Brian came down to LA where both Evan and I live. We spent the week working together at <a href="http://farmhouse.la">The Farmhouse</a> on moving the ball forward toward the 2.0 release. Here&rsquo;s a few pictures of some of the things that went down.</p> <h3 id="i-used-rubinius-at-railsconf-2011-stickers">I Used Rubinius at RailsConf 2011 stickers</h3> <p><a href="http://flickr.com/photos/veganstraightedge/5885836117"><img src="http://farm7.static.flickr.com/6052/5885836117_ba60ba6408_z.jpg" alt="&quot;I Used Rubinius at RailsConf 2011&quot; stickers at The Farmhouse in Hollywood, CA" title="&quot;I Used Rubinius at RailsConf 2011&quot; stickers at The Farmhouse in Hollywood, CA " /></a></p> -<p>These stickers arrived and are ready to be shipped out. If you DMed your address to <a href="http://twitter.com/rubinius">us on Twitter</a>, we’ve got you. If you never contacted us, but used Rubinius while at RailsConf 2011 in Baltimore, email us at <a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;">&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;</a> to get your sticker.</p> +<p>These stickers arrived and are ready to be shipped out. If you DMed your address to <a href="http://twitter.com/rubinius">us on Twitter</a>, we&rsquo;ve got you. If you never contacted us, but used Rubinius while at RailsConf 2011 in Baltimore, email us at <a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;">&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;</a> to get your sticker.</p> <h3 id="t-shirts">T-Shirts!</h3> <p><a href="http://flickr.com/photos/veganstraightedge/5889084175"><img src="http://farm7.static.flickr.com/6019/5889084175_6414a83e97_z.jpg" alt="Nearly 600 more @Rubinius shirts just arrived at the @farmhouse in Hollywood, CA" title="Nearly 600 more @Rubinius shirts just arrived at the @farmhouse in Hollywood, CA " /></a></p> -<p>This is what nearly 600 shirts looks like. We’ve got a huge back log of people all over the world who responded to our offer of free Rubinius t-shirts. Those will all get shipped out over the next week or so.</p> +<p>This is what nearly 600 shirts looks like. We&rsquo;ve got a huge back log of people all over the world who responded to our offer of free Rubinius t-shirts. Those will all get shipped out over the next week or so.</p> <h3 id="progress-on-19-support">Progress on 1.9 Support</h3> <p><a href="http://flickr.com/photos/veganstraightedge/5888809669"><img src="http://farm6.static.flickr.com/5076/5888809669_134b0d6e23_z.jpg" alt="Serious @rubinius big brain nerdery happening between @brixen and @evanphx at the @farmhouse in Hollywood, CA" title="Serious @rubinius big brain nerdery happening between @brixen and @evanphx at the @farmhouse in Hollywood, CA" /></a></p> @@ -935,7 +947,7 @@ now</a>!</p> <h3 id="one-more-thing">One More Thing</h3> -<p>We came up with an idea this week for how to better communicate outwardly and be more transparent. We built it up real quick and are launching it …<em>really soon</em>. Here’s a little teaser.</p> +<p>We came up with an idea this week for how to better communicate outwardly and be more transparent. We built it up real quick and are launching it &hellip;<em>really soon</em>. Here&rsquo;s a little teaser.</p> <p><a href="http://drbl.in/bxbg"><img src="http://dribbble.com/system/users/1288/screenshots/202858/rubinius_...thing_2.png" alt="Rubinius teaser 1" title="Rubinius teaser 1" /></a> <a href="http://drbl.in/bxbf"><img src="http://dribbble.com/system/users/1288/screenshots/202857/rubinius_...thing_1.png" alt="Rubinius teaser 2" title="Rubinius teaser 2" /></a></p> @@ -973,7 +985,7 @@ contains the beginnings of Ruby 1.9 and Microsoft Windows support.</p> <p>We are seeking developers interested in running their Ruby and Rails projects on Rubinius to help us iron out issues as we work toward the final 2.0 -release. Let’s look at the details of the 2.0 developer preview.</p> +release. Let&rsquo;s look at the details of the 2.0 developer preview.</p> <p>One of the central features of Rubinius 2.0 is a fundamental change in the threading architecture. In Rubinius 2.0, Ruby threads will run with true @@ -1012,7 +1024,7 @@ rvm reload <p>If you are interested in helping develop Rubinius, we suggest you clone the repository directly and build. Rubinius runs fine from the source directory so -you don’t need to install it. For more details about building from a clone, +you don&rsquo;t need to install it. For more details about building from a clone, see <a href="http://rubini.us/doc/en/getting-started/">Getting Started</a>.</p> <h3 id="configuration">Configuration</h3> @@ -1069,7 +1081,7 @@ compiler to build a native application. There remains a lot of work to do for Windows support but the Rubinius VM is currently compiling on Windows 7.</p> <p>If you are a bleeding-edge Windows developer interested in diving into -Rubinius, here’s how to get started:</p> +Rubinius, here&rsquo;s how to get started:</p> <ol> <li>Install <em>MRI 1.9</em> using <a href="http://rubyinstaller.org/">RubyInstaller</a>.</li> @@ -1084,7 +1096,7 @@ Rubinius, here’s how to get started:</p> <p>In the near future, we will release another version of Rubinius from the current master branch. We hope to merge 2.0.0pre into master as soon as -possible and continue working toward the 2.0 final release. We’ll make that +possible and continue working toward the 2.0 final release. We&rsquo;ll make that decision based on your reports about how the 2.0.0pre branch is working with existing 1.8.7 applications.</p> @@ -1113,7 +1125,7 @@ Yard will support Rubinius 2.0.0 after it’s officially released.</p> <h3 id="update">Update</h3> -<p>See <a href="http://rubini.us/2011/09/02/retiring-some-rubinius-rewards/" title="Retiring (Some) Rubinius Rewards - Rubinius">this post</a> about retired shirts/stickers and to see what’s still available.</p> +<p>See <a href="http://rubini.us/2011/09/02/retiring-some-rubinius-rewards/" title="Retiring (Some) Rubinius Rewards - Rubinius">this post</a> about retired shirts/stickers and to see what&rsquo;s still available.</p> <h2 id="tldr">tl;dr</h2> @@ -1129,14 +1141,14 @@ hotcakes. It turns out that there was a lot of pent up demand for Rubinius swag.</p> <p>Not everyone could be at RailsConf to get the goods, of course. Even some -people who were there didn’t get their shirts/stickers. If you didn’t get one -and want one, we’re very sorry, but don’t you worry. We’ve got you covered.</p> +people who were there didn&rsquo;t get their shirts/stickers. If you didn&rsquo;t get one +and want one, we&rsquo;re very sorry, but don&rsquo;t you worry. We&rsquo;ve got you covered.</p> <h2 id="general-availability-stickers">General Availability Stickers</h2> <p><a href="http://www.flickr.com/photos/veganstraightedge/5742057726"><img src="http://farm3.static.flickr.com/2458/5742057726_48c42d5462_z.jpg" alt="A box of Rubinius stickers" title="A box of Rubinius stickers by veganstraightedge, on Flickr" /></a></p> -<p>We’ve got a box of stickers in three designs: +<p>We&rsquo;ve got a box of stickers in three designs: <a href="http://asset.rubini.us/web/images/blog/rubinius_square_sticker.png">square</a>, <a href="http://asset.rubini.us/web/images/blog/rubinius_bumper_sticker.png">bumper</a> and @@ -1146,8 +1158,8 @@ and <h2 id="general-availability-t-shirt">General Availability T-Shirt</h2> -<p>We’re printing 500 more grey Rubinius t-shirts in the two different designs -and in a a handful of sizes (women’s small and medium, unisex small – +<p>We&rsquo;re printing 500 more grey Rubinius t-shirts in the two different designs +and in a a handful of sizes (women&rsquo;s small and medium, unisex small &ndash; xx-large).</p> <p><a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;">&#069;&#109;&#097;&#105;&#108;&#032;&#117;&#115;</a> and tell us which design / size you want: @@ -1155,7 +1167,7 @@ xx-large).</p> or <a href="http://asset.rubini.us/web/images/blog/rubinius_use_ruby_horizontal_shirt.jpg">horizontal</a> in -women’s small, women’s medium, unisex small, unisex medium, unisex large, +women&rsquo;s small, women&rsquo;s medium, unisex small, unisex medium, unisex large, unisex x-large or unisex xx-large.</p> <p><a href="http://www.flickr.com/photos/veganstraightedge/5709097384"><img src="http://farm4.static.flickr.com/3469/5709097384_0bde99e1d3_z.jpg" alt="Rubinius &quot;Use Ruby&trade;&quot; T-Shirts at the Farmhouse in Hollywood, CA" title="Rubinius &quot;Use Ruby&trade;&quot; T-Shirts at the Farmhouse in Hollywood, CA, on Flickr" /></a></p> @@ -1166,49 +1178,49 @@ unisex x-large or unisex xx-large.</p> <h2 id="first-commit-sticker">First Commit Sticker</h2> <p>Going forward, we want to reward everyone who makes a contribution to -Rubinius. As a very small token of our gratitude, we’re mailing a Rubinius +Rubinius. As a very small token of our gratitude, we&rsquo;re mailing a Rubinius sticker (and a handwritten thank you note from one of us) to everyone after -their first commit. So, if you’ve ever thought about dipping your toe into -Rubinius (or diving headlong into the deep end), now’s the best time ever. -Help us make Rubinius better (in big and small ways) and we’ll send you stuff.</p> +their first commit. So, if you&rsquo;ve ever thought about dipping your toe into +Rubinius (or diving headlong into the deep end), now&rsquo;s the best time ever. +Help us make Rubinius better (in big and small ways) and we&rsquo;ll send you stuff.</p> <h2 id="tenth-commit-shirt">Tenth Commit Shirt</h2> <p>We want you to stick around and keep helping Rubinius to get better and better. -If you make 10 commits to Rubinius, we’ll send you a special shirt only -available to committers. That design is still a secret for now, but it’s just +If you make 10 commits to Rubinius, we&rsquo;ll send you a special shirt only +available to committers. That design is still a secret for now, but it&rsquo;s just for 10+ committers.</p> -<p><em>Please, don’t try to game the system by intentionally breaking stuff up into -smaller commits just to bump up your count. Let’s keep it honest.</em></p> +<p><em>Please, don&rsquo;t try to game the system by intentionally breaking stuff up into +smaller commits just to bump up your count. Let&rsquo;s keep it honest.</em></p> <h2 id="quarterly-committer-merit-badge-stickers">Quarterly Committer Merit Badge Stickers</h2> <p>In addition to getting a generally available sticker after your first commit, -at the end of each calendar quarter (every three months) we’re sending a +at the end of each calendar quarter (every three months) we&rsquo;re sending a sticker to everyone who committed to Rubinius <strong>during</strong> that quarter.</p> -<p>E.g. after July 1, 2011, we’ll print and ship a sticker to everyone who -committed between April 1 and June 30. Each quarter’s sticker has the year / -quarter in the corner. Keep committing every quarter and you’ll keep +<p>E.g. after July 1, 2011, we&rsquo;ll print and ship a sticker to everyone who +committed between April 1 and June 30. Each quarter&rsquo;s sticker has the year / +quarter in the corner. Keep committing every quarter and you&rsquo;ll keep collecting the merit badge stickers.</p> -<h2 id="one-more-thing-mdash-im-committed-sticker">One More Thing — I’m Committed* Sticker</h2> +<h2 id="one-more-thing-mdash-im-committed-sticker">One More Thing &mdash; I&rsquo;m Committed* Sticker</h2> <p>Rubinius is obviously older than the new Rubinius Rewards program. To backfill for all the contributions people have made over the years up until, we have a -<em>super duper limited edition never to be made again</em> sticker… the asterisk.</p> +<em>super duper limited edition never to be made again</em> sticker&hellip; the asterisk.</p> <p><a href="http://www.flickr.com/photos/veganstraightedge/5742135762"><img src="http://farm4.static.flickr.com/3187/5742135762_521146bdf9_z.jpg" alt="Rubinius stickers on my laptop" title="The new @Rubinius stickers on my @EngineYard laptop, on Flickr" /></a></p> <h2 id="get-in-touch">Get in Touch</h2> -<p>If you’re a past committer, <a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;">&#101;&#109;&#097;&#105;&#108;&#032;&#117;&#115;</a> your -mailing address get your special merit sticker. If you’re a new committer, -we’ll try to take note and reach out to you. If you don’t hear from us, -don’t be afraid to contact us with your mailing address.</p> +<p>If you&rsquo;re a past committer, <a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#099;&#111;&#109;&#109;&#117;&#110;&#105;&#116;&#121;&#064;&#114;&#117;&#098;&#105;&#110;&#105;&#046;&#117;&#115;">&#101;&#109;&#097;&#105;&#108;&#032;&#117;&#115;</a> your +mailing address get your special merit sticker. If you&rsquo;re a new committer, +we&rsquo;ll try to take note and reach out to you. If you don&rsquo;t hear from us, +don&rsquo;t be afraid to contact us with your mailing address.</p> -<h3 id="up-next">Up Next…</h3> +<h3 id="up-next">Up Next&hellip;</h3> <p>Rubinius International Outposts.</p> @@ -1229,14 +1241,14 @@ don’t be afraid to contact us with your mailing address.</p> <p> One of the really cool things about the <a href="http://en.wikipedia.org/wiki/Rubinius">Rubinius</a> implementation of Ruby is that it exposes, by requirement, a level of internals which you can&rsquo;t find in <abbr title="Matz' Ruby Interpreter">MRI</abbr>, including some internals with scopes. Because these internals are exposed in Ruby itself, you can <a href="http://yehudakatz.com/2011/02/18/getting-comfortable-with-rubinius-pure-ruby-internals/">play around with scopes as objects</a>, using <code>VariableScope</code>, including getting access to the available local variables within that scope, with <code>VariableScope.current.locals</code>. </p> </blockquote> -<p>How are <strong>you</strong> using Rubinius? What are you doing with it that you couldn’t do before? What is it missing for you to really dive in? Let us know. We’re listening.</p> +<p>How are <strong>you</strong> using Rubinius? What are you doing with it that you couldn&rsquo;t do before? What is it missing for you to really dive in? Let us know. We&rsquo;re listening.</p> <ul> <li><a href="community@rubini.us">community@rubini.us</a></li> <li><a href="http://twitter.com/rubinius" title="@rubinius on twitter">@rubinius</a></li> </ul> -<p>— Use Ruby™</p> +<p>&mdash; Use Ruby&trade;</p> @@ -1251,15 +1263,15 @@ don’t be afraid to contact us with your mailing address.</p> <h3 id="allow-myself-to-introduce-myself">Allow Myself to Introduce Myself</h3> -<p>Hi. I’m Shane (<a href="http://twitter.com/veganstraightedge">@veganstraightedge</a> -/ <a href="http://iamshane.com">iamshane.com</a>). I’ll be helping out around here now. +<p>Hi. I&rsquo;m Shane (<a href="http://twitter.com/veganstraightedge">@veganstraightedge</a> +/ <a href="http://iamshane.com">iamshane.com</a>). I&rsquo;ll be helping out around here now. I was recently hired by <a href="http://engineyard.com">Engine Yard</a> to be their Open Source Cheerleader. (Yes, there will be costumes at some point.) My primary focus is <strong>Rubinius! Rubinius! Rubinius!</strong></p> <p>I have lots of big plans for helping get Rubinius used by more people in more places and how to have a better conversation with people who are using -it. For now though, I tell you about just the first thing that I’ve done.</p> +it. For now though, I tell you about just the first thing that I&rsquo;ve done.</p> <h3 id="t-shirts">T-Shirts</h3> @@ -1269,12 +1281,12 @@ it. For now though, I tell you about just the first thing that I’ve done.</ <p>A long time ago (2007) in a city far, far away (Seattle, WA), Evan and I made the first batch of Rubinius t-shirts. There were about two dozen made and given to the handful of contributors at the time. This was at RailsConf in -Portland, OR. Since then there hasn’t been <em>anything</em> made with the Rubinius +Portland, OR. Since then there hasn&rsquo;t been <em>anything</em> made with the Rubinius logo on it.</p> -<p>Now is the time to rectify that. We’ve made two different t-shirts. Same +<p>Now is the time to rectify that. We&rsquo;ve made two different t-shirts. Same messaging, slightly different design orientation. Both are the same colors: -white on asphalt. They are available in an assortment of sizes from women’s +white on asphalt. They are available in an assortment of sizes from women&rsquo;s small to unisex xx-large.</p> <h4 id="use-ruby-rubinius-t-shirts-from-railsconf-2011">Use Ruby™ Rubinius T-Shirts from RailsConf 2011</h4> @@ -1282,16 +1294,16 @@ small to unisex xx-large.</p> <p><img src="http://asset.rubini.us/web/images/blog/rubinius_use_ruby_horizontal_shirt.jpg" alt="Use Ruby™ Horizontal Ruby T-Shirt from RailsConf 2011" /></p> -<p>If you’re going to RailsConf 2011 in Baltimore, MD, stop by the Engine Yard booth -to pick up a free Rubinius t-shirt. After RailsConf we’ll have ways to get one +<p>If you&rsquo;re going to RailsConf 2011 in Baltimore, MD, stop by the Engine Yard booth +to pick up a free Rubinius t-shirt. After RailsConf we&rsquo;ll have ways to get one from us directly.</p> <h3 id="stickers">Stickers</h3> -<p>To go along with the t-shirts, we’re making a whole grip of Rubinius stickers. +<p>To go along with the t-shirts, we&rsquo;re making a whole grip of Rubinius stickers. Most of which will also be available for free from the Engine Yard booth at -RailsConf in Baltimore. Again, after RailsConf you’ll be able to get them -directly from us. More on that later. Here’s what we have in store.</p> +RailsConf in Baltimore. Again, after RailsConf you&rsquo;ll be able to get them +directly from us. More on that later. Here&rsquo;s what we have in store.</p> <h4 id="wide-screen-7in-x-375in">Wide Screen (7in x 3.75in)</h4> @@ -1305,14 +1317,14 @@ directly from us. More on that later. Here’s what we have in store.</p> <p><img src="http://asset.rubini.us/web/images/blog/rubinius_diecut_sticker.png" alt="Rubinius : r logo diecut sticker" /></p> -<h4 id="im-committed-merit-sticker">I’m Committed Merit Sticker</h4> +<h4 id="im-committed-merit-sticker">I&rsquo;m Committed Merit Sticker</h4> -<p>This one you have to earn. At the end of each quarter, we’ll send out a little +<p>This one you have to earn. At the end of each quarter, we&rsquo;ll send out a little one inch square sticker with a year/quarter combination in its corner to everyone who committed something to Rubinius during that calendar quarter. For -all of the incredible folks who’ve contributed something (however big or small) -already, you’ll get a special sticker. Instead of a date, there’s an asterisk. -Only those of you that’ve committed so far will get that one.</p> +all of the incredible folks who&rsquo;ve contributed something (however big or small) +already, you&rsquo;ll get a special sticker. Instead of a date, there&rsquo;s an asterisk. +Only those of you that&rsquo;ve committed so far will get that one.</p> <p><img src="http://asset.rubini.us/web/images/blog/rubinius_alumni_sticker.png" alt="Rubinius : I'm committed past committers sticker" /></p> @@ -1320,7 +1332,7 @@ Only those of you that’ve committed so far will get that one.</p> <a href="http://rubini.us/blog">the Rubinius blog</a> and to the Twitter account : <a href="http://twitter.com/rubinius">@rubinius</a>. We have lots more in store.</p> -<p>— Use Ruby™</p> +<p>&mdash; Use Ruby&trade;</p> @@ -1333,7 +1345,7 @@ Only those of you that’ve committed so far will get that one.</p> Brian Ford - <p>Humans have come a long way since our cave-dwelling days. No, that’s not a + <p>Humans have come a long way since our cave-dwelling days. No, that&rsquo;s not a metaphor for primitive software. I mean literally since we lived in caves. One of the big inventions is the lock. There are birds that bury food and will move it later if they notice they were watched burying it. But they have no @@ -1366,7 +1378,7 @@ white and there may be valid security concerns in the source code.</li> <p>The process that separates the source code from the executable program is typically a compilation step. However, Ruby code is not typically associated -with any sort of compilation. That’s one of the great things about Ruby, +with any sort of compilation. That&rsquo;s one of the great things about Ruby, right? There is no <em>edit-compile-link-load</em> cycle to wait on. Just edit and run. But if there is no compilation step, how do we separate the source code from the executable code?</p> @@ -1377,13 +1389,13 @@ Rubinius does compile Ruby code to a bytecode format that the virtual machine executes. I also promised to explain how you could run the bytecode directly.</p> <p>But first, let me very clearly state that there are a number of caveats. In -fact, I’ve included a whole section on them below. Please read them. We will +fact, I&rsquo;ve included a whole section on them below. Please read them. We will assume that you have and that you understand them. If you have any questions, please ask.</p> <h3 id="application-distribution-scenario">Application Distribution Scenario</h3> -<p>Let’s review what we would like to accomplish. We’ll assume affable Abe is a +<p>Let&rsquo;s review what we would like to accomplish. We&rsquo;ll assume affable Abe is a developer writing an application for customer Cain.</p> <ol> @@ -1395,13 +1407,13 @@ developer writing an application for customer Cain.</p> <li>Cain runs the application.</li> </ol> -<p>In this scenario, I’m assuming a very vague definition of application. In +<p>In this scenario, I&rsquo;m assuming a very vague definition of application. In other words, the process below will fit in with a broad spectrum of bundling and distribution schemes.</p> <h3 id="application-layout">Application Layout</h3> -<p>Let’s assume that you have the following application layout. This mirrors what +<p>Let&rsquo;s assume that you have the following application layout. This mirrors what you would expect to see in a gem. You could also consider this as a subtree in your larger project.</p> @@ -1414,13 +1426,27 @@ your larger project.</p> \- green.rb </code></pre> -<p>Liquid error: undefined method `join’ for #<String:0x00000001eac198 /></p> +<div class="highlight"><pre><code class="ruby"><span class="lineno">1</span> <span class="c1"># widget.rb</span> +<span class="lineno">2</span> <span class="nb">require</span> <span class="s1">&#39;widget/red&#39;</span> +<span class="lineno">3</span> <span class="nb">require</span> <span class="s1">&#39;widget/blue&#39;</span> +<span class="lineno">4</span> <span class="nb">require</span> <span class="s1">&#39;widget/green&#39;</span> +</code></pre> +</div> -<p>Liquid error: undefined method `join’ for “\n# widget/red.rb\nputs "I am red"\n”:String</p> +<div class="highlight"><pre><code class="ruby"><span class="lineno">1</span> <span class="c1"># widget/red.rb</span> +<span class="lineno">2</span> <span class="nb">puts</span> <span class="s2">&quot;I am red&quot;</span> +</code></pre> +</div> -<p>Liquid error: undefined method `join’ for “\n# widget/blue.rb\nputs "I am blue"\n”:String</p> +<div class="highlight"><pre><code class="ruby"><span class="lineno">1</span> <span class="c1"># widget/blue.rb</span> +<span class="lineno">2</span> <span class="nb">puts</span> <span class="s2">&quot;I am blue&quot;</span> +</code></pre> +</div> -<p>Liquid error: undefined method `join’ for “\n# widget/green.rb\nputs "I am green"\n”:String</p> +<div class="highlight"><pre><code class="ruby"><span class="lineno">1</span> <span class="c1"># widget/green.rb</span> +<span class="lineno">2</span> <span class="nb">puts</span> <span class="s2">&quot;I am green&quot;</span> +</code></pre> +</div> <h3 id="compiling-ruby-files">Compiling Ruby Files</h3> @@ -1432,7 +1458,7 @@ every Ruby source file in our source tree.</p> <pre><code>rbx compile -s '^widget:widget-compiled' widget/ </code></pre> -<p>Let’s dissect this command. The <code>-s</code> option defines a transformation to apply +<p>Let&rsquo;s dissect this command. The <code>-s</code> option defines a transformation to apply to every filename. The transformation has the form <code>&lt;source&gt;:&lt;destination&gt;</code> where <code>&lt;source&gt;</code> can be a Regexp. In our case, we would like to change any path starting with <code>widget</code> to start with <code>widget-compiled</code>. This way, we @@ -1456,7 +1482,7 @@ files.</p> <h3 id="loading-pre-compiled-files">Loading Pre-compiled Files</h3> <p>Now that we have a separate tree of only compiled files, how do we load them? -Well, first, let’s load our source files so we know what to expect. Note that +Well, first, let&rsquo;s load our source files so we know what to expect. Note that the technique used in this post should not substitute for a robust test suite.</p> <pre><code>$ rbx -Iwidget/lib -e "require 'widget/lib/widget'" @@ -1475,9 +1501,9 @@ I am green <p><em>The crowed erupts with applause and hooting</em>.</p> -<p>Golly gee, you guys… <em>Blush</em></p> +<p>Golly gee, you guys&hellip; <em>Blush</em></p> -<p>Let’s review. Our goal is to take a tree of Ruby source files and create a +<p>Let&rsquo;s review. Our goal is to take a tree of Ruby source files and create a tree of compiled files that can be sent to a customer and loaded to perform exactly as the Ruby source would if loaded directly. The most direct and simple way to accomplish this is to use the Rubinius compiler command-line @@ -1502,7 +1528,7 @@ change the format of the compiled output.</li> <li>We have created this facility to meet a need we had in Rubinius. Since our compiler is written in Ruby, we have to run Ruby to run the compiler. But since we need to compile Ruby to run it, we need to compile the compiler. -But since… To handle this, we build the compiler using a bootstrapping +But since&hellip; To handle this, we build the compiler using a bootstrapping version of Ruby. Then we load the pre-compiled compiler files as shown above. The approach is quite general, as demonstrated. However, a better approach may be appropriate for a particular application. In that case, @@ -1516,7 +1542,7 @@ changed. The compiled format is simple. We reserve the right to provide disassemblers for our compiled code. We are happy to assist you with direction for implementing a more secure system for your needs.</li> <li>There is no mechanism that is completely safe from cracking when it comes -to software access control. Witness how often Microsoft’s products have +to software access control. Witness how often Microsoft&rsquo;s products have their security features defeated. Also witness how often attempts at DRM are circumvented. The most secure system I have seen uses a special compiler and a hardware dongle. The compiler takes critical parts of the @@ -1574,7 +1600,7 @@ $ ls hello.* hello.rb hello.rbc </code></pre> -<p>That doesn’t look too crazy, but it can get more complicated:</p> +<p>That doesn&rsquo;t look too crazy, but it can get more complicated:</p> <pre><code>$ mv hello.rb hello $ rbx hello @@ -1597,16 +1623,16 @@ cache file with the source and not clash with other names.</li> </ol> <p>Again, the advantage of the cache file is that you do not have to wait for -Rubinius to recompile the file if you have not changed the source. Let’s see +Rubinius to recompile the file if you have not changed the source. Let&rsquo;s see if we can get all the advantages with none of the disadvantages. That old saying comes to mind, <em>Having your cake and eating it, too</em>, so we may not be successful, but it is worth a shot.</p> -<p>First, let’s take a step back. This issue is not unique to Rubinius. Python +<p>First, let&rsquo;s take a step back. This issue is not unique to Rubinius. Python has <code>.pyc</code> and <code>.pyo</code> files. Java has <code>.class</code> files. C/C++ has <code>.o</code> files. Lots of things need a place to store a compiled or cached representation of some data. Every SCM worth mention has some mechanism to ignore the files you -don’t want to track. The same is generally true of editors. So in some sense, +don&rsquo;t want to track. The same is generally true of editors. So in some sense, this is a solved problem. However, we have always received complaints about the <code>.rbc</code> files, so we thought we would try to make other, hopefully better, solutions available.</p> @@ -1624,7 +1650,7 @@ $ ls hello.* hello.rb </code></pre> -<p>Win! Not one lousy <code>.rbc</code> file in sight. Although, that’s quite the option to +<p>Win! Not one lousy <code>.rbc</code> file in sight. Although, that&rsquo;s quite the option to type. Never fear, we have a solution to that below.</p> <p>Here is our scorecard for solution 1:</p> @@ -1644,7 +1670,7 @@ couple years ago so it may not be an issue for you.</p> <p>What if we could put all the compilation data in a single cache location, something like a database? We have an option for that.</p> -<p>This option is a little more complex, so let’s take it in two steps.</p> +<p>This option is a little more complex, so let&rsquo;s take it in two steps.</p> <pre><code>$ ls hello.* hello.rb @@ -1659,7 +1685,7 @@ $ ls -R .rbx 60c091c3ed34c1b93ffbb33d82d810772902d3f9 </code></pre> -<p>Success! No <code>.rbc</code> files here. But what’s with all the numbers in the <code>.rbx</code> +<p>Success! No <code>.rbc</code> files here. But what&rsquo;s with all the numbers in the <code>.rbx</code> directory and how did that directory get there?</p> <p>The <code>-Xrbc.db</code> option without any argument will store the compilation cache in @@ -1713,7 +1739,7 @@ directory. However, you can easily specify where to put that directory.</p> <h3 id="using-rbxopt-for-options">Using RBXOPT for Options</h3> <p>As mentioned above, the <code>-X</code> options can get a little long and you certainly -don’t want to retype them constantly. We have added support for the <code>RBXOPT</code> +don&rsquo;t want to retype them constantly. We have added support for the <code>RBXOPT</code> environment variable, which is an analog of the <code>RUBYOPT</code> environment variable that we already support.</p> @@ -1736,17 +1762,17 @@ time and resources recompiling source that has not changed. However, we need some place to store the cache. Rubinius provides options for omitting the cache altogether or for storing it in a directory of your choosing. Note that the format of the compilation cache is an implementation detail and we reserve -the right to change it at any time, so please don’t rely on it being in any +the right to change it at any time, so please don&rsquo;t rely on it being in any particular format.</p> -<p>We have not turned on <code>-Xrbc.db</code> by default yet because we don’t know what a +<p>We have not turned on <code>-Xrbc.db</code> by default yet because we don&rsquo;t know what a good default is. So give us feedback on your use cases and what you would find most useful.</p> <p>Finally, whenever we discuss the compilation cache we are inevitably asked if you can run directly from the cache and not use the Ruby source at all after -it has been compiled. The short answer is “Yes”, the long answer is “It -depends”. I will be writing a post exploring this question in detail shortly. +it has been compiled. The short answer is &ldquo;Yes&rdquo;, the long answer is &ldquo;It +depends&rdquo;. I will be writing a post exploring this question in detail shortly. For now, get out there and write more Ruby code!</p> @@ -1762,20 +1788,20 @@ For now, get out there and write more Ruby code!</p> <p><em>Why should I use Rubinius?</em> We have been asked that question many, many times over the past four years. It is a great question. It is an important question. -It’s a <em>hard</em> question. I’m not holding out on you. I want to give you an +It&rsquo;s a <em>hard</em> question. I&rsquo;m not holding out on you. I want to give you an answer that sates your curiosity, helps you make informed decisions, and -empowers you to speak eloquently when <em>you</em> are inevitably asked, “Why do you -use Rubinius?”</p> +empowers you to speak eloquently when <em>you</em> are inevitably asked, &ldquo;Why do you +use Rubinius?&rdquo;</p> <p>The trouble is, there are many different situations in which people use Ruby and there is simply no answer, however comprehensive, that really speaks to -everyone’s concerns. So rather that boring you at length, I thought a <em>Choose +everyone&rsquo;s concerns. So rather that boring you at length, I thought a <em>Choose your own adventure</em> style would be a better approach.</p> -<p>From the list below, select the persona that best describes you. Don’t worry, -if the one you select doesn’t sound right, you can easily backtrack here. Read +<p>From the list below, select the persona that best describes you. Don&rsquo;t worry, +if the one you select doesn&rsquo;t sound right, you can easily backtrack here. Read as many as interest you. After all, none of us fit easily into any one box. -When you are done exploring all the fascinating reasons to use Rubinius, let’s +When you are done exploring all the fascinating reasons to use Rubinius, let&rsquo;s meet up at the <a href="#wur-conclusion">Conclusion</a> for some parting words.</p> @@ -1803,26 +1829,26 @@ watched a screencast and made a website. You are curious and enthusiastic.</p <p>You are the empty teacup of the Zen proverb. You are a fresh-faced flower glistening with the morning dew. The sun smiles on you and you smile back. -You seem to like this Ruby language that makes programmers happy and you’ve -come to lend your cheery spirit…</p> +You seem to like this Ruby language that makes programmers happy and you&rsquo;ve +come to lend your cheery spirit&hellip;</p> <p>Welcome!</p> <p>So, you have heard of this thing called Rubinius or rbx or whatever and some folks you respect or admire seem to like it and naturally you want to know -what the big deal is and you’re like, “Yo, why would I use Rubinius?”.</p> +what the big deal is and you&rsquo;re like, &ldquo;Yo, why would I use Rubinius?&rdquo;.</p> <p>Cool.</p> <p>Well, you should use Rubinius because I said so. Try your code on it. Tell us -what worked for you. Tell us if something didn’t work by opening an +what worked for you. Tell us if something didn&rsquo;t work by opening an <a href="https://github.com/rubinius/rubinius/issues/">issue</a>. Set your imagination loose and tell us what tool you would use if you could.</p> <p>Spend some time reading the Rubinius source code. Start at the <code>kernel/</code> -directory. It’s full of Ruby code! As you read through how Ruby is +directory. It&rsquo;s full of Ruby code! As you read through how Ruby is implemented, how it actually works, it will give you a level of understanding -of your code that many programmers don’t have in <em>any</em> language.</p> +of your code that many programmers don&rsquo;t have in <em>any</em> language.</p> <p>Most of all, hang on to your curiosity and enthusiasm. Those were vital to the creation of the Rubinius project in the beginning and have sustained us @@ -1850,7 +1876,7 @@ himself</em></li> <p>(Apple's dashboard dictionary widget.)</p> </blockquote> -<p>Ruby respects creativity. It has an <em>aesthetic</em>. You don’t just write Ruby +<p>Ruby respects creativity. It has an <em>aesthetic</em>. You don&rsquo;t just write Ruby code, you write <em>beautiful</em> Ruby code. It would be unthinkable to do otherwise. Sure, there is more than one way to do many things. This is not some sterile laboratory. We are not automatons; we are people. Of course, @@ -1858,7 +1884,7 @@ being utilitarian is not bad. But other languages have that angle pretty well covered. There is probably only one right way to implement Python.</p> <p>Rubinius has an aesthetic, too: excellence, utility, simplicity, beauty, joy. -Mostly in that order. Useful code that isn’t of very good quality is a drag. +Mostly in that order. Useful code that isn&rsquo;t of very good quality is a drag. It slows you down. It gives you a headache. It drives you away. We strive to keep it out of Rubinius. On the other hand, we are not just writing sonnets here. This is Serious Business™. We have some hard-core problems to solve. So @@ -1870,13 +1896,13 @@ perspective on making the implementation of this beautiful object-oriented language more beautiful and object-oriented.</p> <p>We welcome your artistic perspective. Help us improve the dialog between -Rubinius and the person using it. The command line doesn’t have to be a +Rubinius and the person using it. The command line doesn&rsquo;t have to be a desolate place of obscure, condescending error messages. Web interfaces to the diagnostic tools deserve a good dose of user-experience and interaction design. You know that feeling you get when looking at an Enterprise web application? That weird plastic-masquerading-as-quality-material feeling? The too much 1996-Enterprise-faux-rounded-corner-wanabe-2006-hip gloss? -Gives me the willies whenever I have to use an app like that. Yeah, we don’t +Gives me the willies whenever I have to use an app like that. Yeah, we don&rsquo;t want that.</p> <p>We want to create tools that are powerful, graceful, easy to use, and @@ -1930,16 +1956,16 @@ to let us know.</p> <p>If everything goes well with the tests, you start running some of the benchmarks that you have accumulated while doing performance tuning. Of -course, no sensible person asks for benchmark results from <em>other</em> people’s -code. That defies logic. It’s like asking if your program will run because -your Aunt Mabeline likes decaf coffee. It’s contrary to the very point of +course, no sensible person asks for benchmark results from <em>other</em> people&rsquo;s +code. That defies logic. It&rsquo;s like asking if your program will run because +your Aunt Mabeline likes decaf coffee. It&rsquo;s contrary to the very point of benchmarking, where you are trying to correlate two values that are connected.</p> <p>Again, if you note an significant issues, please let us know. Sometimes Rubinius exposes issues in existing code. Performance characteristics of real applications are vital to making Rubinius faster. Also, if you have suggestions for tools you would like to use, tell us. If you just want to -chat about the technology, that’s fine, too. We’re hanging out in the +chat about the technology, that&rsquo;s fine, too. We&rsquo;re hanging out in the #rubinius channel on freenode.net.</p> <p><a href="#wur-personas"><strong>Back to personas</strong></a></p> @@ -1947,13 +1973,13 @@ chat about the technology, that’s fine, too. We’re hanging out in the <h4><a class="anchor_title" name="wur-seasoned">Seasoned programmer</a></h4> <p>Well, I am being kind by saying <em>seasoned</em>. You know when you look in the -mirror that <em>jaded</em> and <em>cynical</em> are much more apt. You’ve seen it all and it -has worn you down. You’ve been fighting the good fight, carefully guarding +mirror that <em>jaded</em> and <em>cynical</em> are much more apt. You&rsquo;ve seen it all and it +has worn you down. You&rsquo;ve been fighting the good fight, carefully guarding that last flicker of optimism that burns in the secret place deep in your -heart. You’ve programmed Java/.NET/C++ professionally. You’ve even sucked it +heart. You&rsquo;ve programmed Java/.NET/C++ professionally. You&rsquo;ve even sucked it up and written some PHP and Python when asked; you are a professional, they -ask and you deliver. You’ve seen attacked servers on fire off the shoulder of -Rackspace…</p> +ask and you deliver. You&rsquo;ve seen attacked servers on fire off the shoulder of +Rackspace&hellip;</p> <p>Rubinius has a lot to offer you. Remember that little flicker of optimism? It is only the idealists that get ground down by the complete indifference to @@ -1963,7 +1989,7 @@ and you will find plenty to refresh you here.</p> <p>Rubinius aims to be the best possible implementation of Ruby by putting Ruby itself front and center. We are using modern technology and always improving. We change when there is a better way to do things. We judiciously rewrite and -are not too attached to any code or algorithm. The legacy Enterprise isn’t on +are not too attached to any code or algorithm. The legacy Enterprise isn&rsquo;t on the steering committee. Our work will be done when you can use Ruby, just Ruby, to solve your thorny problems.</p> @@ -1977,14 +2003,14 @@ all that hard-earned wisdom you have gained to use for the betterment of Ruby.&l <h4><a class="anchor_title" name="wur-academic">Academic Researcher</a></h4> -<p>Forgive me for staring, I know it is impolite. I’m just… intrigued. Of +<p>Forgive me for staring, I know it is impolite. I&rsquo;m just&hellip; intrigued. Of course, you know Ruby is a late bound language, every message sent could conceivably fail to find a target, potentially resulting in an uncaught -exception and program termination. There’s shared state, wild orgies of +exception and program termination. There&rsquo;s shared state, wild orgies of mutation that disallow any reasonable attempt at automated parallelization. -Program proof is as oxymoronic a concept as military intelligence. It’s a very +Program proof is as oxymoronic a concept as military intelligence. It&rsquo;s a very messy affair of programming and meta-programming and meta-meta-programming, -which, for the love of Lisp, could be done so simply with macros. There’s all +which, for the love of Lisp, could be done so simply with macros. There&rsquo;s all this eager evaluation and complete disregard for purity. Despite vast odds, somehow programs are written that actually run. You have noted all this with great objectivity but you are nonetheless interested.</p> @@ -2025,19 +2051,19 @@ is an great project to consider. We look forward to hearing from you.</p> <h4><a class="anchor_title" name="wur-uber">Über programmer</a></h4> -<p>You learned the untyped lambda calculus sitting on your mother’s knee while +<p>You learned the untyped lambda calculus sitting on your mother&rsquo;s knee while she worked on her doctorate in computer science. You were substituting terms -before you even uttered the word, “dada”. You wrote three different Lisp +before you even uttered the word, &ldquo;dada&rdquo;. You wrote three different Lisp implementations in Commodore Basic before you were seven. You can write multi-threaded web servers in one pass with no tests and never hit a deadlock or critical data race. You write parsers and compilers for odd languages on a Friday night for the heck of it while waiting for the pizza to arrive before a night out at the karaoke bar where you give an inspiring performance of Laga -Gaga’s <em>Poker Face</em>.</p> +Gaga&rsquo;s <em>Poker Face</em>.</p> -<p>(<em>Loooong pause</em>. You’re not reading this. You’ve already written one or a few +<p>(<em>Loooong pause</em>. You&rsquo;re not reading this. You&rsquo;ve already written one or a few languages on Rubinius and posted them to our -<a href="http://rubini.us/projects/">Projects</a> page. But anyway, I’ll continue…)</p> +<a href="http://rubini.us/projects/">Projects</a> page. But anyway, I&rsquo;ll continue&hellip;)</p> <p>You are the Luke Skywalker of Ruby; Yoda has nothing more to teach you. Only your fate confronts you now. Use the Source Luke and save the Federation of @@ -2052,7 +2078,7 @@ applications are going to be in Javascript on the client is not valid. A variety of hybrid client-server architectures will continue to be the norm. We need software that enables application authors to build a suitable solution to their particular problems rather than trying to stuff their apps into -someone else’s solution with layers of wrapping.</li> +someone else&rsquo;s solution with layers of wrapping.</li> <li><strong>Concurrency</strong>: multi-core is here to stay but it is not only functional programming that is suitable for high-concurrency applications.</li> <li><strong>Graphical user interface</strong>: the web browser is also here to stay but it is @@ -2089,7 +2115,7 @@ your cup of tea, Rubinius offers an excellent platform for experimentation.</ <p>Like your persona description, you tend to be long winded. You find most descriptions too brief, almost dismissive. There are words and words should be used to delve into the minutiae of minutiae. You, more than anyone, want to -know “Why?” with every fiber of your being. You will continue asking long +know &ldquo;Why?&rdquo; with every fiber of your being. You will continue asking long after the supply of hallucinogens has been exhausted and everyone else is drooling in their sleep.</p> @@ -2100,21 +2126,21 @@ we already have MRI, why build Rubinius?</p> simply this: <em>Ruby should be a first class language</em>. What does that mean? Simply that it should be possible to solve problems writing Ruby code.</p> -<p>Let’s consider libraries: Being first class means not having to wrap a Java +<p>Let&rsquo;s consider libraries: Being first class means not having to wrap a Java library or build a C extension. If wrapping the library were the end of the -story, it wouldn’t be so bad. But that is <em>never</em> the case. Libraries have +story, it wouldn&rsquo;t be so bad. But that is <em>never</em> the case. Libraries have bugs, weird APIs, incompatibility with other libraries, threading issues, and disappearing maintainers. They may even be incompatible with newer versions of the language in which they are written.</p> <p>This list goes on. To address any one of these issues requires delving into a different language with weird and incompatible semantics. If the library is -your core competency, that’s not such a big deal. But I will wager that it is +your core competency, that&rsquo;s not such a big deal. But I will wager that it is not, which is why you are using the library in the first place. Also, the language in which you are wrapping the library (Ruby here) is not likely the -core competency of the library author, or you probably wouldn’t need to be +core competency of the library author, or you probably wouldn&rsquo;t need to be wrapping it. So Ruby wrapping one of these libraries will always be a -second-class citizen. Decisions will be made about the library’s API that do +second-class citizen. Decisions will be made about the library&rsquo;s API that do not give one thought to the Ruby programs using it. Furthermore, the code written in that foreign language does nothing to support the ecosystem of Ruby. The knowledge gained in writing the library and the improved skills of @@ -2129,14 +2155,14 @@ problems more effectively in Ruby itself.</p> <p>The philosophy of Rubinius is to make Ruby a first-class citizen. Ruby plays second fiddle to no one. There is no other language whose history, semantics, -or vested interests compete with Ruby’s. It is true that there are difficult +or vested interests compete with Ruby&rsquo;s. It is true that there are difficult problems to solve in making Ruby fast. But much of the technology already exists and we will build what does not. Evan often quips that if we can get Rubinius caught up to the dynamic language technology of ten years ago, Ruby will be light-years ahead. That may be overstating how far behind Ruby is, but it illustrates the focus of Rubinius.</p> -<p>There’s the saying, <em>In theory, there is no difference between theory and +<p>There&rsquo;s the saying, <em>In theory, there is no difference between theory and practice. In practice, there is</em>. In Rubinius, theory and practice are merging. We are motivated by the desire for Ruby to be a first-class language. But we are also showing real progress in making that a reality. The Rubinius @@ -2153,7 +2179,7 @@ and speed is constantly improving.</p> <p>No, it did not cross my mind to describe this persona as Pointy-haired Boss. Not only would that be unfair to Dilbert, but that persona would be reading an article on Web Scale. No, you are someone who has fought hard battles in the -trenches and learned valuable lessons: it’s about execution and execution +trenches and learned valuable lessons: it&rsquo;s about execution and execution depends on good technology.</p> <p>Rubinius is building solid technology. We started the RubySpec project and @@ -2161,7 +2187,7 @@ have contributed tens of thousands of lines of code to it. With the support of Rubyspec, in just over four years as a public project, we have basically caught up with MRI 1.8.7 in compatibility and performance. For some code, our performance is much better, for other code, it is not as good. However, -Rubinius is built on solid, modern technology and the project’s trajectory and +Rubinius is built on solid, modern technology and the project&rsquo;s trajectory and velocity are outstanding.</p> <p>Rubinius is a completely new implementation of core Ruby. Rubinius did not @@ -2184,19 +2210,19 @@ the feedback and look forward to solving challenging engineering problems.</p <h4><a class="anchor_title" name="wur-knowledge">Knowledge Seeker</a></h4> -<p>You thirst for Knowledge. You follow it wherever it leads you. You’ll happily -walk Haskell’s hallowed halls of pure laziness or sit at the feet of the -meta-program gazing raptly at class transmorgrification. You don’t judge. You +<p>You thirst for Knowledge. You follow it wherever it leads you. You&rsquo;ll happily +walk Haskell&rsquo;s hallowed halls of pure laziness or sit at the feet of the +meta-program gazing raptly at class transmorgrification. You don&rsquo;t judge. You have more than enough knowledge to be dangerous, enough to know that the universe is amoral and knowledge is the only Truth there is. Nor does any mere -mortal language bind you. All languages are finite. You’ll be here today and +mortal language bind you. All languages are finite. You&rsquo;ll be here today and gone tomorrow; there is no permanence for the knowledge seeker.</p> <p>Rubinius is merely a step along the path you journey. Take what you want, it is all free. As a Ruby implementation, it has much to offer your quest for knowledge. The Ruby code in the core library is accessible and easy to follow. The interface between Ruby and the C++ primitives is consistent. The C++ code -itself is restrained. You won’t need a PhD in Turing-complete template +itself is restrained. You won&rsquo;t need a PhD in Turing-complete template languages to understand it.</p> <p>Rubinius offers extensive opportunities to learn about programming languages @@ -2212,12 +2238,12 @@ looping and iteration, recursion, references and values, etc.</li> lambdas, etc. Even with fundamental programming knowledge, a particular language can be confusing. When I was learning C, a friend was also studying it. One day he walked over and threw <em>The C Programming Language</em> -book down on my desk and said, “This <code>for</code> loop makes no sense!” He was -quite upset. “Look,” he said, “in this example <code>for (i=0; i &lt; n; i++)</code> how -can <code>i &lt; n</code> get executed <em>after</em> the code in the body?!” It’s easy to laugh +book down on my desk and said, &ldquo;This <code>for</code> loop makes no sense!&rdquo; He was +quite upset. &ldquo;Look,&rdquo; he said, &ldquo;in this example <code>for (i=0; i &lt; n; i++)</code> how +can <code>i &lt; n</code> get executed <em>after</em> the code in the body?!&rdquo; It&rsquo;s easy to laugh at that confusion, but coming from BASIC, that really threw him. Deepening our understanding to this second level requires confronting some -“counter-intuitive” notions.</li> +&ldquo;counter-intuitive&rdquo; notions.</li> <li><strong>Hypothetical implementation</strong>: knowing how Ruby works, how might one implement it. I think this is an important layer of understanding and it is easy to miss or gloss over it. By pausing at this layer and thinking how @@ -2232,7 +2258,7 @@ bring the beauty of Ruby as an object-oriented language deep into the core of Ruby itself.</li> </ol> -<p>While the Rubinius code itself offers many opportunities for learning, don’t +<p>While the Rubinius code itself offers many opportunities for learning, don&rsquo;t hesitate to drop by the #rubinius channel on freenode.net and ask us questions. Perhaps you already know a lot about another language and are interested in how Rubinius implements some feature. Or you may be relatively @@ -2254,8 +2280,8 @@ what you learn about Rubinius. Or, help us <a href="http://rubini.us/doc <h4><a class="anchor_title" name="wur-enthusiast">Language Enthusiast</a></h4> <p>You like languages for their intrinsic value. Of course the world comes in -many shapes and sizes. You wouldn’t have it any other way. That’s the fun and -spice, joie de vivre, raison d’etre, supermarché… Sometimes you get carried +many shapes and sizes. You wouldn&rsquo;t have it any other way. That&rsquo;s the fun and +spice, joie de vivre, raison d&rsquo;etre, supermarché&hellip; Sometimes you get carried away writing a program in another language just because you like how the letters arrange down the screen. Ruby is definitely one of the impressive languages and sometimes you almost notice a tiny bit of favoritism in your @@ -2268,7 +2294,7 @@ fascinating subjects. We can merely suggest a path; your experiences along the way will tell you whether or not Rubinius has value to you.</p> <p>If you are most interested in languages themselves, the syntax and arrangement -of features, Rubinius offers you immediate gratification. Look for Evan’s +of features, Rubinius offers you immediate gratification. Look for Evan&rsquo;s upcoming post on his Language Toolkit or check out the code to <a href="https://github.com/evanphx/prattle">prattle</a>, a Smalltalk dialect used to illustrate the ease of building a language on Rubinius. Also look at some of @@ -2290,18 +2316,18 @@ adding content is easy.</p> <ul> <li><a href="http://www.engineyard.com/blog/2010/rubinius-wants-to-help-you-make-ruby-better/">Rubinius wants to help YOU make Ruby better</a></li> - <li><a href="http://www.engineyard.com/blog/2009/5-things-youll-love-about-rubinius/">5 Things You’ll Love About Rubinius</a></li> + <li><a href="http://www.engineyard.com/blog/2009/5-things-youll-love-about-rubinius/">5 Things You&rsquo;ll Love About Rubinius</a></li> <li><a href="http://www.engineyard.com/blog/2009/rubinius-the-book-tour/">Rubinius: The Book Tour</a></li> </ul> <p>Most of all, experiment. Rubinius is easy to hack on. Are you curious about a particular feature needed in your language? Try adding it to Rubinius. Think Lua is all the rage because it uses a register VM? You could probably write a -register-based bytecode interpreter for Rubinius in an afternoon. That’s just +register-based bytecode interpreter for Rubinius in an afternoon. That&rsquo;s just an example, of course. The point is to play around with your ideas and have -fun doing it. I think you’ll find Rubinius to be an adventuresome companion.</p> +fun doing it. I think you&rsquo;ll find Rubinius to be an adventuresome companion.</p> -<p>Be sure to let us know what you’re working on. We like to be inspired, too! +<p>Be sure to let us know what you&rsquo;re working on. We like to be inspired, too! Consider writing a blog post about things that you find interesing, like this <a href="http://yehudakatz.com/2011/02/18/getting-comfortable-with-rubinius-pure-ruby-internals/">recent post</a> by Yehuda Katz.</p> @@ -2314,8 +2340,8 @@ many different reasons to use Rubinius. Not all those reasons make sense to everyone. We believe, however, that Rubinius has something to offer to just about everyone interested in Ruby. Most importantly, try it!</p> -<p>If we didn’t answer your question here, leave us a comment. If you have a -reason for using Rubinius that we didn’t mention, let us know. As always, we +<p>If we didn&rsquo;t answer your question here, leave us a comment. If you have a +reason for using Rubinius that we didn&rsquo;t mention, let us know. As always, we appreciate your feedback. Chat with us in the #rubinius channel on freenode.net, <a href="https://github.com/rubinius/rubinius">watch our Github project</a>, and <a href="http://twitter.com/rubinius">follow us on Twitter</a>.</p> @@ -2338,14 +2364,14 @@ Enthusiast personas, I always forget those!</p> Rubinius VM.</p> <p>This blog post will give a short introduction to the language, what -kind of problems it’s trying to solve and why I chose Rubinius as the +kind of problems it&rsquo;s trying to solve and why I chose Rubinius as the VM to run Fancy on.</p> <h3 id="what-is-fancy">What is Fancy?</h3> <p>Fancy is a new general-purpose, dynamic, pure object-oriented programming language heavily inspired by Ruby, Smalltalk and Erlang -that runs on the Rubinius VM. It’s the first fully bootstrapped +that runs on the Rubinius VM. It&rsquo;s the first fully bootstrapped language, aside from Ruby, running on Rubinius. This means that the compiler that generates bytecode for Rubinius is written in Fancy itself.</p> @@ -2381,34 +2407,34 @@ than in traditional systems.</p> certain things out of the box. Especially when it comes to things like asynchronous and concurrent programming, having proper semantics built into the language can often help developers more than a library can. -Very often it’s not just about the functionality itself but also about +Very often it&rsquo;s not just about the functionality itself but also about the semantics you want that functionality to have. This can cause -problems particularly if the language’s semantics differ from what +problems particularly if the language&rsquo;s semantics differ from what your library is trying to solve. A good example is the callback-based approach to asynchronous progamming which leads to code that differs both in semantics as well as how code is structured, compared to -synchronous code. Ideally you’d still want to write code in a +synchronous code. Ideally you&rsquo;d still want to write code in a synchronous fashion, where exceptions pop up naturally while still being highly asynchronous.</p> -<p>In that sense Fancy is more flexible than Ruby as there’s not many -special case semantics built in to the core language. Everything’s +<p>In that sense Fancy is more flexible than Ruby as there&rsquo;s not many +special case semantics built in to the core language. Everything&rsquo;s done via message passing, which fits nicely the actor model approach -to concurrency. Fancy’s syntax is a lot simpler, too.</p> +to concurrency. Fancy&rsquo;s syntax is a lot simpler, too.</p> <p>Since all the core control structures are just implemented in Fancy itself and adhere to the message passing protocol, you can easily override them for your personal needs. This is especially interesting when implementing domain specific languages. -Say, you’d want to add some logging to conditional or looping -constructs - it’s as easy as overriding a method in your DSL’s +Say, you&rsquo;d want to add some logging to conditional or looping +constructs - it&rsquo;s as easy as overriding a method in your DSL&rsquo;s classes. Fancy also has class-based mixins, so it makes it easy to share functionality across class hierarchy boundaries.</p> <p>Finally, I created Fancy because I wanted a language implementation that was well documented, easy to understand and very flexible to extend. Ruby is a nice language, but it has some inconsistencies and -there’s only so much you can do when you’re bound by backwards +there&rsquo;s only so much you can do when you&rsquo;re bound by backwards compatibility. By starting fresh, Fancy has a clean, simple and easy to extend core which allows further exploration of features and abstractions.</p> @@ -2420,98 +2446,130 @@ in C++, similar to how Ruby 1.8 (MRI) works. It was a simple AST walker. After moving to Rubinius and writing an initial bootstrap compiler in Ruby, the codebase shrank to about 20% of the original implementation while actually being more performant. This of course is -mostly due to Rubinius’ architecture and JIT compiler but it was a +mostly due to Rubinius&rsquo; architecture and JIT compiler but it was a great experience nontheless.</p> <p>The nice part about having a common virtual machine and runtime is -that you’re not forced to a completely different platform to get the +that you&rsquo;re not forced to a completely different platform to get the job done. Fancy and Ruby can coexist in the same application nicely and calling code from one another is dead simple. In fact, as of now, -Rubinius doesn’t know anything about Fancy. And it shouldn’t. As long +Rubinius doesn&rsquo;t know anything about Fancy. And it shouldn&rsquo;t. As long as all languages running on top of it adhere to the same interface (in this case the bytecode), it should just work fine.</p> -<p>Choosing Rubinius as a successor platform for Fancy was easy. It’s -built for Ruby, a language that’s closely related to Fancy. Rubinius, +<p>Choosing Rubinius as a successor platform for Fancy was easy. It&rsquo;s +built for Ruby, a language that&rsquo;s closely related to Fancy. Rubinius, while having been developed as a VM for running Ruby code, is very -flexible and there are many features that abstract over Ruby’s +flexible and there are many features that abstract over Ruby&rsquo;s external semantics. It was just a natural choice given the fact that -Rubinius’ architecture and design was heavily influenced by Smalltalk -VMs. Also, it’s a very nice dynamic bytecode virtual machine. The +Rubinius&rsquo; architecture and design was heavily influenced by Smalltalk +VMs. Also, it&rsquo;s a very nice dynamic bytecode virtual machine. The community is very responsive and helpful. Bugs get fixed instantly, -there’s always someone to help out and overall it’s been a great +there&rsquo;s always someone to help out and overall it&rsquo;s been a great experience.</p> -<h3 id="lets-look-at-some-code">Let’s look at some code!</h3> +<h3 id="lets-look-at-some-code">Let&rsquo;s look at some code!</h3> -<p>OK, enough talking. Let’s have a look on how to get some Fancy code up +<p>OK, enough talking. Let&rsquo;s have a look on how to get some Fancy code up and running. Our little sample application will be a simple IRC bot -that connects to Fancy’s irc channel on Freenode and says hello to -everyone that greets it. To make life easier, there’s already a Fancy +that connects to Fancy&rsquo;s irc channel on Freenode and says hello to +everyone that greets it. To make life easier, there&rsquo;s already a Fancy package out there that helps with exactly this task: <a href="https://github.com/bakkdoor/fancy_irc">FancyIRC</a>.</p> -<p>FancyIRC is a simple IRC client library inspired by Ruby’s IRC bot -framework <a href="https://github.com/cinchrb/cinch">Cinch</a>. It’s much simpler +<p>FancyIRC is a simple IRC client library inspired by Ruby&rsquo;s IRC bot +framework <a href="https://github.com/cinchrb/cinch">Cinch</a>. It&rsquo;s much simpler and the code is fairly easy to read, but it gives you a similar interface for writing IRC clients or bots.</p> -<p>So let’s get going by installing Fancy. You can either use the Fancy +<p>So let&rsquo;s get going by installing Fancy. You can either use the Fancy Rubygem and install it with Rubinius or get the code from GitHub and -run <code>rake</code> in the directory. You’ll also then have to add the <code>bin</code> +run <code>rake</code> in the directory. You&rsquo;ll also then have to add the <code>bin</code> directory to your <code>$PATH</code>. If you want the latest and greatest version of Fancy I recommend building directly from source, as the Gem might -not be up to date all the time. For demonstration purposes, let’s +not be up to date all the time. For demonstration purposes, let&rsquo;s install the Rubygem.</p> <pre><code>$ rbx -S gem install fancy </code></pre> -<p>To get the FancyIRC package we use Fancy’s built-in package manager, +<p>To get the FancyIRC package we use Fancy&rsquo;s built-in package manager, which knows how to find the code on GitHub and install it locally:</p> <pre><code>$ fancy install bakkdoor/fancy_irc </code></pre> <h4 id="writing-the-code">Writing the code</h4> -<p>Liquid error: undefined method `join’ for #<String:0x000000013dc948 /></p> + +<div class="highlight"><pre><code class="fancy"><span class="lineno"> 1</span> <span class="nf">require:</span> <span class="s">&quot;fancy_irc&quot;</span> +<span class="lineno"> 2</span> +<span class="lineno"> 3</span> <span class="n">greeter_bot</span> <span class="o">=</span> <span class="no">FancyIRC</span> <span class="no">Client</span> <span class="nf">new:</span> <span class="p">{</span> +<span class="lineno"> 4</span> <span class="nf">configuration:</span> <span class="p">{</span> +<span class="lineno"> 5</span> <span class="nf">nickname:</span> <span class="s">&quot;greeter_bot&quot;</span> +<span class="lineno"> 6</span> <span class="nf">server:</span> <span class="s">&quot;irc.freenode.net&quot;</span> +<span class="lineno"> 7</span> <span class="nf">port:</span> <span class="mi">6667</span> +<span class="lineno"> 8</span> <span class="nf">channels:</span> <span class="o">[</span><span class="s">&quot;#fancy&quot;</span><span class="o">]</span> +<span class="lineno"> 9</span> <span class="p">}</span> +<span class="lineno">10</span> +<span class="lineno">11</span> <span class="c1"># greet person back</span> +<span class="lineno">12</span> <span class="nf">on:</span> <span class="ss">&#39;channel</span> <span class="nf">pattern:</span> <span class="sr">/^[hH]ello greeter_bot/</span> <span class="nf">do:</span> <span class="p">|</span><span class="n">msg</span><span class="p">|</span> <span class="p">{</span> +<span class="lineno">13</span> <span class="n">msg</span> <span class="nf">reply:</span> <span class="s">&quot;Hello to you too, #{msg author}!&quot;</span> +<span class="lineno">14</span> <span class="p">}</span> +<span class="lineno">15</span> +<span class="lineno">16</span> <span class="c1"># &quot;echo&quot; command</span> +<span class="lineno">17</span> <span class="c1"># invoke with: !echo &lt;text&gt;</span> +<span class="lineno">18</span> <span class="nf">on:</span> <span class="ss">&#39;channel</span> <span class="nf">pattern:</span> <span class="sr">/^!echo (.*)$/</span> <span class="nf">do:</span> <span class="p">|</span><span class="n">msg</span><span class="p">,</span> <span class="n">text</span><span class="p">|</span> <span class="p">{</span> +<span class="lineno">19</span> <span class="n">msg</span> <span class="nf">reply:</span> <span class="s">&quot;#{msg author} said: #{text}&quot;</span> +<span class="lineno">20</span> <span class="p">}</span> +<span class="lineno">21</span> +<span class="lineno">22</span> <span class="c1"># tell bot to shutdown via !shutdown command</span> +<span class="lineno">23</span> <span class="nf">on:</span> <span class="ss">&#39;channel</span> <span class="nf">pattern:</span> <span class="sr">/^!shutdown/</span> <span class="nf">do:</span> <span class="p">|</span><span class="n">msg</span><span class="p">|</span> <span class="p">{</span> +<span class="lineno">24</span> <span class="n">msg</span> <span class="nf">reply:</span> <span class="s">&quot;OK, shutting down&quot;</span> +<span class="lineno">25</span> <span class="no">System</span> <span class="n">exit</span> +<span class="lineno">26</span> <span class="p">}</span> +<span class="lineno">27</span> <span class="p">}</span> +<span class="lineno">28</span> +<span class="lineno">29</span> <span class="n">greeter_bot</span> <span class="n">connect</span> +<span class="lineno">30</span> <span class="n">greeter_bot</span> <span class="n">run</span> +</code></pre> +</div> <p>I think the code is pretty straight forward. This should give you a feeling for what Fancy looks and feels like. There is of course lots more to Fancy than what was shown here. It would not fit into a single blog post.</p> -<p>A quick list of what’s currently being worked on:</p> +<p>A quick list of what&rsquo;s currently being worked on:</p> <ul> <li>New pattern matching system: Message passing based pattern matching that preserves encapsulation and is very extensible including pattern literals that allow custom pattern types to be defined by -anyone. There’s an experimental branch for that. I’m happy +anyone. There&rsquo;s an experimental branch for that. I&rsquo;m happy to answer questions.</li> <li>Async support using coroutines (Fibers) - Write async code in a more -natural way where exceptions propagate naturally and you don’t have +natural way where exceptions propagate naturally and you don&rsquo;t have to think about callbacks all the time.</li> <li>First-class support for actors - Asynchronous message sends, Futures and multi-vm messaging built-in.</li> - <li>And much more…</li> + <li>And much more&hellip;</li> </ul> <h3 id="interested">Interested?</h3> <p>If you got interested in Fancy and want to know where to go next, -here’s a short list of things to check out:</p> +here&rsquo;s a short list of things to check out:</p> <ul> - <li><a href="https://github.com/bakkdoor/fancy">Fancy’s GitHub repository</a>. + <li><a href="https://github.com/bakkdoor/fancy">Fancy&rsquo;s GitHub repository</a>. The standard library is completely written in Fancy and most classes and methods have docstrings. It should be fairly easy to understand.</li> <li><a href="https://github.com/fancy-lang/infancy">Programming InFancy</a> An open source tutorial on learning Fancy. Work in progress.</li> <li><a href="http://api.fancy-lang.org">http://api.fancy-lang.org</a> -A work in progress page containing Fancy’s standard library class +A work in progress page containing Fancy&rsquo;s standard library class and method documentation.</li> - <li><a href="https://groups.google.com/forum/#!forum/fancy-lang">Fancy’s Google Group mailinglist</a></li> + <li><a href="https://groups.google.com/forum/#!forum/fancy-lang">Fancy&rsquo;s Google Group mailinglist</a></li> <li>IRC Channel: #fancy @ irc.freenode.net</li> <li>Website: <a href="http://www.fancy-lang.org">http://www.fancy-lang.org</a></li> </ul> @@ -2543,11 +2601,11 @@ example,</p> <pre><code>rvm install rbx </code></pre> -<p>What is not widely known (yet) is that there is a “Named Rubies” feature +<p>What is not widely known (yet) is that there is a &ldquo;Named Rubies&rdquo; feature that allows you to install altered versions of the same Ruby installation along side the original.</p> -<p>In the case of Rubinius there is this facinating branch called ‘hydra’. +<p>In the case of Rubinius there is this facinating branch called &lsquo;hydra&rsquo;. So let us see how we can have the Rubinius master branch installed as the main rbx with the hydra branch installed along side as well.</p> @@ -2565,7 +2623,7 @@ version so</p> <p>After we have the mainline head Rubinus branch installed, we now want to use the named rubies feature. This is done using the -n specifier in the Ruby identifier string. So for example to install our hydra branch as an -RVM ruby with the name ‘hydra’ in it we do the following:</p> +RVM ruby with the name &lsquo;hydra&rsquo; in it we do the following:</p> <pre><code>rvm install --branch hydra rbx-nhydra </code></pre> @@ -2629,8 +2687,8 @@ commits and 21 tickets closed in the 56 calendar days since the release of us test it.</p> <p>While we were working on 1.2.1, we were also working on a Top Secret project -that we’ve craftily <a href="https://github.com/evanphx/rubinius/tree/hydra">hidden in plain -sight</a>. I’d like to introduce +that we&rsquo;ve craftily <a href="https://github.com/evanphx/rubinius/tree/hydra">hidden in plain +sight</a>. I&rsquo;d like to introduce the work we are doing on the hydra branch and the features you can expect to see in Rubinius soon.</p> @@ -2681,7 +2739,7 @@ global warming.</li> <li>With a multi-core system, builds can be done faster if they are done in parallel. If the build system can accurately determine dependencies, it can execute build sub-steps in parallel. Of course, this can cut into YouTube -and Twitter browsing time, but that’s a risk we are willing to take.</li> +and Twitter browsing time, but that&rsquo;s a risk we are willing to take.</li> <li>While parallel sub-processes during the build are excellent, the supervising process benefits from running as a single process from start to finish. Otherwise, configuration data needs to be re-parsed. To support a single @@ -2692,7 +2750,7 @@ simply impossible in Rake.</li> <li>Use-aware configuration values know that the user has set the value and can intelligently merge with newer configuration variables that we create without requiring the user to reconfigure. Ultimately, we are aiming for a -<em>single</em> command build. Just run ‘daedalus’ and done. There is no step 2.</li> +<em>single</em> command build. Just run &lsquo;daedalus&rsquo; and done. There is no step 2.</li> </ul> <h3 id="full-on-concurrency">Full-on Concurrency</h3> @@ -2707,7 +2765,7 @@ both), the apparent concurrency will still be executing serially. Since there are so many multi-core CPUs around these days, our programs should be getting stuff done in parallel.</p> -<p>Unfortunately, there’s a twist. Even with native threads on a multi-core CPU, +<p>Unfortunately, there&rsquo;s a twist. Even with native threads on a multi-core CPU, the amount of parallelism you get depends on how well you manage locks around shared data and resources. Sometimes managing these locks is complex and you opt for one big lock, essentially only allowing one thread at a time to run. @@ -2743,7 +2801,7 @@ involve core libraries that are implemented in C in MRI. There are three main fronts on which we are attacking performance issues: 1) improving the algorithms in the Ruby code that implements the core library; 2) continuing to tune the VM and garbage collector; and 3) improving the JIT compiler. Which -leads me to one of the most exciting things we are working on…</p> +leads me to one of the most exciting things we are working on&hellip;</p> <h3 id="jit-intermediate-representation-ir">JIT Intermediate Representation (IR)</h3> @@ -2752,7 +2810,25 @@ biggest challenges with a dynamic language like Ruby is knowing what method is actually being invoked when a message is sent to an object. Consider the following code:</p> -<p>Liquid error: undefined method `join’ for #<String:0x00000001fc5980 /></p> +<div class="highlight"><pre><code class="ruby"><span class="lineno"> 1</span> <span class="k">class</span> <span class="nc">A</span> +<span class="lineno"> 2</span> <span class="k">def</span> <span class="nf">m</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> +<span class="lineno"> 3</span> <span class="o">.</span><span class="n">.</span><span class="o">.</span> +<span class="lineno"> 4</span> <span class="k">end</span> +<span class="lineno"> 5</span> <span class="k">end</span> +<span class="lineno"> 6</span> +<span class="lineno"> 7</span> <span class="k">class</span> <span class="nc">B</span> +<span class="lineno"> 8</span> <span class="k">def</span> <span class="nf">m</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> +<span class="lineno"> 9</span> <span class="o">.</span><span class="n">.</span><span class="o">.</span> +<span class="lineno">10</span> <span class="k">end</span> +<span class="lineno">11</span> <span class="k">end</span> +<span class="lineno">12</span> +<span class="lineno">13</span> <span class="k">class</span> <span class="nc">C</span> +<span class="lineno">14</span> <span class="k">def</span> <span class="nf">work</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> +<span class="lineno">15</span> <span class="n">obj</span><span class="o">.</span><span class="n">m</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> +<span class="lineno">16</span> <span class="k">end</span> +<span class="lineno">17</span> <span class="k">end</span> +</code></pre> +</div> <p>What method is being invoked by <code>obj.m(y)</code>? There is no way to definitively know this by looking at the source code. However, when the program is actually @@ -2771,8 +2847,8 @@ intermediate representation. So Evan has started work on a new JIT IR.</p> <p>This new IR will help us to express Ruby semantics in a way that enables many powerful optimizations and will ultimately allow LLVM to generate even better machine code. Put another way, <em>Rubinius loves Ruby code!</em> Right down to the -metal. There’s no fighting a foreign type system or the semantics of a -language at odds with Ruby’s rosy view of the world.</p> +metal. There&rsquo;s no fighting a foreign type system or the semantics of a +language at odds with Ruby&rsquo;s rosy view of the world.</p> <h3 id="ruby-19">Ruby 1.9</h3> @@ -2800,7 +2876,7 @@ manually instrumenting our code.</p> <p>Presently, Rubinius has a built-in debugger, precise method profiler, memory analysis tool, and Agent interface that permits querying a running Rubinius -VM–even one running on a remote machine–for a variety of information.</p> +VM&ndash;even one running on a remote machine&ndash;for a variety of information.</p> <p>We will be adding the ability to track the location where objects are allocated to assist finding object leaks or code that is creating unusually @@ -2817,11 +2893,11 @@ ID before running each spec and the Agent monitor would request the ID when gathering VM data. Later the two data sets could easily be merged.</p> <p>When you find yourself manually instrumenting some code, consider what data -you are trying to get your hands on and let us know the scenario. We’ll +you are trying to get your hands on and let us know the scenario. We&rsquo;ll likely be able to build a tool that will open up new vistas into the behavior of your Ruby programs.</p> -<h3 id="windowssupregsup">Windows<sup>®</sup></h3> +<h3 id="windowssupregsup">Windows<sup>&reg;</sup></h3> <p>However one may feel about Windows as an operating system, it is undeniable that the vast majority of people in the world use Windows. We believe those @@ -2853,7 +2929,18 @@ bytecode, and decoupling method dispatch from Ruby semantics.</p> <p>Hopefully, Evan will introduce us to all this in a future blog post, but here is a taste of what you can do:</p> -<p>Liquid error: undefined method `join’ for #<String:0x00000001fc54d0 /></p> +<div class="highlight"><pre><code class="ruby"><span class="lineno"> 1</span> <span class="k">class</span> <span class="nc">Hello</span> +<span class="lineno"> 2</span> <span class="n">dynamic_method</span> <span class="ss">:world</span> <span class="k">do</span> <span class="o">|</span><span class="n">g</span><span class="o">|</span> +<span class="lineno"> 3</span> <span class="n">g</span><span class="o">.</span><span class="n">push</span> <span class="ss">:self</span> +<span class="lineno"> 4</span> <span class="n">g</span><span class="o">.</span><span class="n">push_literal</span> <span class="s2">&quot;Hello, world&quot;</span> +<span class="lineno"> 5</span> <span class="n">g</span><span class="o">.</span><span class="n">send</span> <span class="ss">:puts</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="kp">true</span> +<span class="lineno"> 6</span> <span class="n">g</span><span class="o">.</span><span class="n">ret</span> +<span class="lineno"> 7</span> <span class="k">end</span> +<span class="lineno"> 8</span> <span class="k">end</span> +<span class="lineno"> 9</span> +<span class="lineno">10</span> <span class="no">Hello</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">world</span> +</code></pre> +</div> <p>Of course, that is much more concisely written in Ruby, but combine this ability with a built-in PEG parser and you can be experimenting with your own @@ -2866,14 +2953,14 @@ the Fancy compiler is now written in Fancy) on Rubinius.</p> <h3 id="documentation">Documentation</h3> -<p>One the one hand, Rubinius just runs Ruby code, and you shouldn’t need any +<p>One the one hand, Rubinius just runs Ruby code, and you shouldn&rsquo;t need any special knowledge to run your application on Rubinius. On the other hand, as -I’ve discussed above, there are some specific Rubinius features that may be +I&rsquo;ve discussed above, there are some specific Rubinius features that may be very helpful to you. However, they can only be as helpful as the documentation we have for them.</p> <p>Before we released 1.2.0 in December last year, I spent quite a bit of time -getting a new documentation system in place. Since then, we’ve had +getting a new documentation system in place. Since then, we&rsquo;ve had contributors help with translations to Russian, Polish, Spanish, and German. Adam Gardiner started documenting the garbage collector algorithms. Yehuda Katz (you may have heard the name) has contributed documentation for <a href="http://rubini.us/doc/en/bytecode-compiler/">the @@ -2899,7 +2986,7 @@ most important thing you can do is try running your Ruby code. Give us feedback. Let us know what features or tools would make your life easier. Help us to build them.</p> -<p>Rubinius adopts Ruby’s rosy view of the world. We want to empower you to solve +<p>Rubinius adopts Ruby&rsquo;s rosy view of the world. We want to empower you to solve your hardest problems with Ruby, and have fun doing it.</p> @@ -2913,24 +3000,24 @@ your hardest problems with Ruby, and have fun doing it.</p> Brian Ford - <p>Many thought the day would never come, but Rubinius finally has a blog. That’s + <p>Many thought the day would never come, but Rubinius finally has a blog. That&rsquo;s not all, though: We have integrated the website, blog, and documentation using Jekyll. The source code for it all is in the main <a href="http://github.com/rubinius/rubinius">Rubinius repository</a>.</p> <p>People have often requested that we write more about the <em>awesome</em> features in -Rubinius. We hear you and we’d love to do this. However, there is always a +Rubinius. We hear you and we&rsquo;d love to do this. However, there is always a trade-off between working on those awesome features and writing about them. -Until now, it’s been rather painful to write docs or blog posts because we did -not have good infrastructure in place. Now, I think we do. I’m sure there are +Until now, it&rsquo;s been rather painful to write docs or blog posts because we did +not have good infrastructure in place. Now, I think we do. I&rsquo;m sure there are still a lot of improvements we can make, but we have a good place to start. -I’d like to give a brief tour of our new system.</p> +I&rsquo;d like to give a brief tour of our new system.</p> <p>The primary goal was to improve collaboration and reduce friction for writing -new documentation and blog posts. That’s right, improve collaboration. There +new documentation and blog posts. That&rsquo;s right, improve collaboration. There are many people who have experience developing Rubinius and running their applications on it. We love how people have collaborated with source code -commits. Now anyone has the ability to write a blog post as well. I’ve written +commits. Now anyone has the ability to write a blog post as well. I&rsquo;ve written a basic <a href="/doc/en/how-to/write-a-blog-post/">How-To - Write a Blog Post</a> document. If you have an idea for a blog post, just let us know. We will exercise a bit of editorial control just to ensure the topics are appropriate @@ -2950,13 +3037,13 @@ are not native English speakers. Alas, I only have a fair ability to write in Spanish, so we are again depending on your help. I started the translation effort by passing the existing English docs through Google translate. We have a beginning guide for <a href="/doc/en/how-to/translate-documentation">How-To - Translate -Documentation</a>. I’ve been told by -<em>kronos_vano</em> in our #rubinius IRC channel that he’s already working on a +Documentation</a>. I&rsquo;ve been told by +<em>kronos_vano</em> in our #rubinius IRC channel that he&rsquo;s already working on a Russian translation. I personally would love to see Japanese and Chinese translations.</p> -<p>So that’s a brief introduction to our new infrastructure for documenting and -explaining Rubinius. It’s been such a joy to see so many people contribute to +<p>So that&rsquo;s a brief introduction to our new infrastructure for documenting and +explaining Rubinius. It&rsquo;s been such a joy to see so many people contribute to the Rubinius source code over the years. We hope that the blog, documentation, and translations will further empower people to contribute and benefit from the value that Rubinius has to offer the Ruby community.</p> diff --git a/web/_site/projects/index.html b/web/_site/projects/index.html index bd96099812..1d0955211d 100644 --- a/web/_site/projects/index.html +++ b/web/_site/projects/index.html @@ -111,7 +111,7 @@

        Pegarus

        Poison

        github.com/brixen/poison

        -

        An interpretation of _why’s Potion programming language.

        +

        An interpretation of _why’s Potion programming language.

        Rasp

        github.com/matthewd/rasp

        diff --git a/web/_site/releases/1.0.0/index.html b/web/_site/releases/1.0.0/index.html index b8b2a2f841..e206b4480c 100644 --- a/web/_site/releases/1.0.0/index.html +++ b/web/_site/releases/1.0.0/index.html @@ -73,20 +73,20 @@

        Thanks

        version 1.0. This is a reference to the great defender of Rome. This name was given to Rubinius by Geoffrey Grosenbach, who secured naming rights to version 1.0 many years ago by being the very first person to -provide some financial backing for the project. I can’t thank him enough.

        +provide some financial backing for the project. I can’t thank him enough.

        -

        Tom Mornini and Engine Yard deserve the lion’s share of the thanks. Back in +

        Tom Mornini and Engine Yard deserve the lion’s share of the thanks. Back in 2007 when Tom asked me to come work on Rubinius at Engine Yard, it was a dream -come true. They’ve tirelessly supported the project over the years, even when +come true. They’ve tirelessly supported the project over the years, even when project momentum waned.

        And lastly, thanks to everyone who has contributed to the project. Over the -years, there have been over 200 contributers who’ve given up their free time +years, there have been over 200 contributers who’ve given up their free time to help make Rubinius great.

        - Evan Phoenix

        -

        What’s New Since 1.0rc5

        +

        What’s New Since 1.0rc5

        • Updated README.
        • @@ -99,7 +99,7 @@

          What’s New Since 1.0rc5

        • Include RUBY_EXTCONF_H. Fixes #281.
        • Use _exit() rather than exit() to avoid C++ finalization races
        • Catch and handle a redo passing through a rescue properly (unicorn)
        • -
        • Don’t use Class#ancestors internally
        • +
        • Don’t use Class#ancestors internally
        • Clean up test directory

        • @@ -128,13 +128,13 @@

          Highlights

          Known Issues

            -
          • String#unpack and Array#pack are currently pretty slow. We’re working +
          • String#unpack and Array#pack are currently pretty slow. We’re working on this issue and will release a fix in the near future.
          • A number of String methods are a bit slower than in 1.8. Most of these are known and being addressed.
          • -
          • We’ve added much of the MRI C-API for running Ruby extensions, but -there are some extensions that don’t work yet. Typically, this is because -the extension uses RBASIC(), RHASH(), or RREGEXP(). These depend on MRI’s +
          • We’ve added much of the MRI C-API for running Ruby extensions, but +there are some extensions that don’t work yet. Typically, this is because +the extension uses RBASIC(), RHASH(), or RREGEXP(). These depend on MRI’s internal object memory layout. In most cases, there are regular functions available to use that do not depend on MRI internals. We will help C extension authors to make their code portable. Additionally, extensions diff --git a/web/_site/releases/1.0.1/index.html b/web/_site/releases/1.0.1/index.html index 7e62082481..fb4b925955 100644 --- a/web/_site/releases/1.0.1/index.html +++ b/web/_site/releases/1.0.1/index.html @@ -112,7 +112,7 @@

            Fixes

          • Changed libgdtoa g_dfmt() to emit MRI format for minimal, unique String representation of Float.
          • Added to_s_minimal primitive for Float#to_s.
          • Use send to reach private extend_object methods. Closes #324.
          • -
          • Don’t use a increment operation and the original value in the same expression
          • +
          • Don’t use a increment operation and the original value in the same expression
          • Explicitly cast the return value of stack_pop() to void*
          • Initial work to enable compiling with clang
          • Use error state for read / write and print out the message
          • @@ -120,45 +120,45 @@

            Fixes

          • Honor read-only-ness of certain globals. Fixes #283.
          • Escape slashes in Regexp#to_s output. Fixes #308.
          • Disambiguate a vcall send to the send_method opcode. Fixes #293.
          • -
          • Evaluate next’s argument even though it’s ignored. Fixes #307.
          • +
          • Evaluate next’s argument even though it’s ignored. Fixes #307.
          • Report path to script bodies relatively. Fixes #308.
          • Remove Numeric#==
          • Use Kernel.exit! after a forked block returns. Fixes #289.
          • Fix fork to allow SystemExit through properly
          • Be persistant with write(2)
          • -
          • Handle object_id’s for immediates. Fixes #315.
          • +
          • Handle object_id’s for immediates. Fixes #315.
          • Alter protocol for how Proc with a bound method is invoked. Fixes #277.
          • -
          • Teach Signal.trap the rest of it’s tricks. Fixes #314.
          • +
          • Teach Signal.trap the rest of it’s tricks. Fixes #314.
          • Make sure the arguments are Strings. @bugfix
          • Cleanup and speed up Struct
          • Add missing functionality to Signal.trap
          • Introduce -Xprofile to be used instead of -P
          • -
          • Cleanup and fix irb’s save history feature
          • -
          • Search Object’s includes also. Fixes #328
          • +
          • Cleanup and fix irb’s save history feature
          • +
          • Search Object’s includes also. Fixes #328
          • Make sure thet the default vis in a script body is private. Fixes #327
          • Make STDOUT.reopen(path) effect the system fd. Fixes #322.
          • Use the encoding of the Regexp in String#split on characters. Fixes #323
          • Be sure to cleanup any temp modifications during #delete_if
          • -
          • Let –enable-llvm do something. Fixes #336.
          • +
          • Let –enable-llvm do something. Fixes #336.
          • Add flag support to new Dir.glob, always use it
          • Handle write() setting EAGAIN properly
          • Handle ECONNRESET like eof. Fixes #338
          • Add UNIXSocket.pair
          • Add Inliner::fixnum_le, and self recursion cuteness
          • Simplify the Class#to_s of a metaclass (rails fix)
          • -
          • Allow Modules to be dup’d, but not String
          • +
          • Allow Modules to be dup’d, but not String
          • Flip include order so that local LLVM wins
          • Fix left shifting for fixnums
          • Repair Bignum#divmod for cases with negative numbers. Fixes #319.
          • Speed up String#[] and String#=~
          • A Time is not eql? to a non-time.
          • Raise the right exception when alias fails in a module.
          • -
          • method_defined? shouldn’t search Object/Kernel.
          • +
          • method_defined? shouldn’t search Object/Kernel.
          • Print error messages to stderr instead of stdout.
          • Ensure the proper Regexp constant is found when processing literals
          • -
          • Introduce ‘push_rubinius’ instruction and use it like a rented mule
          • +
          • Introduce ‘push_rubinius’ instruction and use it like a rented mule
          • Factor out some jit code from push_cpath_top and push_rubinius
          • -
          • Quit as early as possible if we’re building on an unsupported platform
          • +
          • Quit as early as possible if we’re building on an unsupported platform

          FFI

          @@ -198,13 +198,13 @@

          C-API

        • Check async events and raise an exception via rb_thread_select.
        • Fix INT2NUM to actually take a long, not an int.
        • Implement rb_is_{const,instance_class}_id() in CAPI.
        • -
        • rb_protect’s callback takes a VALUE, not ANYARGS.
        • +
        • rb_protect’s callback takes a VALUE, not ANYARGS.
        • Add apparently-missed prototype for rb_apply()
        • Add rb_f_global_variables() and rb_str_new3().
        • -
        • rb_define_module_under() shouldn’t return a parent’s module.
        • +
        • rb_define_module_under() shouldn’t return a parent’s module.
        • Make rb_num2dbl handle all inputs correctly.
        • -
        • Set rbconfig’s LIBS to “” to to appease mkrf
        • -
        • Set rbconfig’s LIBRUBYARG_SHARED to “”, because we don’t have a shared library yet.
        • +
        • Set rbconfig’s LIBS to “” to to appease mkrf
        • +
        • Set rbconfig’s LIBRUBYARG_SHARED to “”, because we don’t have a shared library yet.
        • Add NativeMethod functors up to a ten-argument version
        diff --git a/web/_site/releases/1.1.0/index.html b/web/_site/releases/1.1.0/index.html index bb5c775d81..275e26e7cf 100644 --- a/web/_site/releases/1.1.0/index.html +++ b/web/_site/releases/1.1.0/index.html @@ -102,14 +102,14 @@

        Additions

      3. Implement a new GIL algorithm to prevent starvation
      4. Add Debugger APIs and reference CLI debugger
      5. Overhaul finalizers, support for resurecting finalizers
      6. -
      7. Basic ‘rbx docs’ command support.
      8. -
      9. Add ‘rbx report’ and support for VM and ruby crashes
      10. +
      11. Basic ‘rbx docs’ command support.
      12. +
      13. Add ‘rbx report’ and support for VM and ruby crashes
      14. Add CM::Script#eval_source
      15. Rewrote Array#pack and String#unpack
      16. Add code to detect bad extensions. Recompile your extensions.
      17. Add dbm, sdbm, and gdbm extensions
      18. Implement support for -n, -p, and -a. Fixes #353.
      19. -
      20. Add and use –agent when running the specs
      21. +
      22. Add and use –agent when running the specs
      23. Add String#secure_compare @x-api
      24. Add heapdump capability for memory debugging
      25. Add automatic object ivar packing (improves memory usage)
      26. @@ -129,7 +129,7 @@

        Fixes

      27. Support rb_sys_fail being passed NULL
      28. Verify that the ruby to build with is the one it was configured with
      29. Fixed Module#define_method to return a lambda Proc
      30. -
      31. Add Kernel#type even though it’s deprecated. Fixes #469.
      32. +
      33. Add Kernel#type even though it’s deprecated. Fixes #469.
      34. Move Etc::Passwd and Etc::Group to Struct
      35. Add no-op rubysig.h to make extensions happy
      36. Add unblock support to rb_thread_blocking_region. Credit: kudo. Fixes #461.
      37. @@ -167,10 +167,10 @@

        Fixes

      38. Speed up Kernel#` by using a specialized primitive
      39. Use same function signature as MRI for rb_reg_new
      40. Check for and run #to_ary when passed to yield with 2+ args. Fixes #374.
      41. -
      42. Don’t expand -I paths. Fixes #434.
      43. +
      44. Don’t expand -I paths. Fixes #434.
      45. Remove old, stale minitest
      46. Slight cleanup of Socket and adding Socket.getnameinfo
      47. -
      48. Add support for rb_gv_get(“$~”)
      49. +
      50. Add support for rb_gv_get(“$~”)
      51. Initial version.h for C-API.
      52. Add the C API rb_reg_nth_match method
      53. Add C API function rb_reg_new
      54. @@ -190,17 +190,17 @@

        Fixes

      55. Enhance Rubinius::Fiber
      56. Module#class_variable_set now raises a TypeError when self is frozen
      57. Fix IO.foreach with a nil separator, it should yield the entire contents at once
      58. -
      59. Remove Ar since it’s not used anymore
      60. +
      61. Remove Ar since it’s not used anymore
      62. Allow splat arguments in define_method. Fixes #419.
      63. Preserve path seperators in Dir.glob. Fixes #420.
      64. add rb_need_block() to rbx capi
      65. Kernel.extend now raises a TypeError, when called on a frozen object
      66. Fix profiler graph output and handling of blocks
      67. Cleanup of Bignum#%, significant performance improvement
      68. -
      69. Don’t allow initializing a class twice
      70. +
      71. Don’t allow initializing a class twice
      72. Move Hash#setup to Hash#__setup__ to allow overriding
      73. Cleanup IO.popen and IO::BidirectionalPipe
      74. -
      75. Only run ->dfree if ->data isn’t NULL
      76. +
      77. Only run ->dfree if ->data isn’t NULL
      78. Fix Module#remove_const to not call Module#const_missing
      79. Temporarily disable running finalizers at exit.
      80. Test the proper scope when determining if long return is possible
      81. @@ -209,9 +209,9 @@

        Fixes

      82. Handle block arguments to a lambda specially. Fixes #398.
      83. File#truncate now raises an IOError if file is not opened for writing
      84. Fix R::CompiledMethod#add_metadata to allow multiple keys
      85. -
      86. Don’t use self in a block that might be instance_evald. Fixes #399.
      87. +
      88. Don’t use self in a block that might be instance_evald. Fixes #399.
      89. Expose the SystemExit to at_exit handlers. Fixes #395.
      90. -
      91. Minor performanece fix, don’t initialize an object body twice
      92. +
      93. Minor performanece fix, don’t initialize an object body twice
      94. Have Proc#inspect use the exact same format as MRI
      95. Support -1 as the free function
      96. Add Rubinius specific #__finalize__ API for resurrectable finalizers
      97. @@ -239,7 +239,7 @@

        Fixes

      98. Added rb_set_kcode.
      99. Fix warnings compiling Melbourne ext in 1.9.
      100. Generalize building with MRI 1.8/1.9 or rbx.
      101. -
      102. Add –cc to configure Script, so you can do ‘rvm install rbx -C –cc=clang’, as with MRI and REE.
      103. +
      104. Add –cc to configure Script, so you can do ‘rvm install rbx -C –cc=clang’, as with MRI and REE.
      105. Fix building with gcc 4.4.1.
      106. Run at_exit blocks and finalizers before exiting a fork. Fixes #372.
      107. Add -Xgc.honor_start to control if GC.start is honored
      108. @@ -261,7 +261,7 @@

        Fixes

      109. Dir#new should call #to_str under 1.8 and #to_path under 1.9
      110. Fixed Dir.open to call StringValue. Closes #362.
      111. Dir should be calling to_str on non-String arguments in Ruby 1.8
      112. -
      113. kronos’ fix for Bignum#<<. Closes #350.
      114. +
      115. kronos’ fix for Bignum#<<. Closes #350.
      116. Use correct module namespacing in Numeric specs.
      117. Further conform Numeric to MRI. Closes #349.
      118. More specs for Numeric#<=>.
      119. diff --git a/web/_site/releases/1.1.1/index.html b/web/_site/releases/1.1.1/index.html index 268fbb31a2..e988f1bef7 100644 --- a/web/_site/releases/1.1.1/index.html +++ b/web/_site/releases/1.1.1/index.html @@ -121,8 +121,8 @@

        Summary

      120. Make Readline library configurable.
      121. Imported pure Ruby Readline (rb-readline at e591463)
      122. Add Array#select via aliasing
      123. -
      124. Handle next’ing out of rescue handlers. Fixes #556
      125. -
      126. Fix Bignum#» to respect 2s complement properly
      127. +
      128. Handle next’ing out of rescue handlers. Fixes #556
      129. +
      130. Fix Bignum#» to respect 2s complement properly
      131. Follow the weird self-in-eval behavior
      132. Add enough delegation to support Method#parameters. Fixes #557
      133. Wipe out CDPATH when building. Fixes #555
      134. @@ -137,9 +137,9 @@

        Summary

      135. Specify the version for FFI::Library::LIBC like ffi-ruby gem. Closes #546.
      136. Create gem cache dir with mkdir_p. Closes #541 again.
      137. Fixed function declarations. Closes #543.
      138. -
      139. Backport add –cxx to configure from multiverse (6596ed7). Closes #542.
      140. +
      141. Backport add –cxx to configure from multiverse (6596ed7). Closes #542.
      142. Add rb_struct_new and rb_ary_freeze. Fixes #540
      143. -
      144. Make sure the user’s gem cache directory exists. Fixes #541
      145. +
      146. Make sure the user’s gem cache directory exists. Fixes #541
      147. Incorporate rubygems loadtime speedup patch
      148. Speed up rubygems gemspec loading via caching
      149. Remove CompiledMethod#compile
      150. @@ -155,7 +155,7 @@

        Summary

      151. Implement rb_exec_recursive (mostly cripped from 1.8.7)
      152. Make rb_gc_force_recycle a noop
      153. Add rb_cmpint, rb_cmperr, and rb_equal
      154. -
      155. Don’t cache on autoload failure. Fixes #529
      156. +
      157. Don’t cache on autoload failure. Fixes #529
      158. Write out a newline for an empty string too. Fixes #525
      159. Add Regexp#search_from. Fixes #524
      160. Use string coersion for filename in class_eval / module_eval
      161. @@ -163,11 +163,11 @@

        Summary

      162. Add missing return value used in Errno.handle checks
      163. Allow for subclassing Thread, fixes #526
      164. Thread#new throws an exception when not given a block
      165. -
      166. Propagate –cc configure setting to CC, CXX env vars. Closes #520.
      167. -
      168. Removed -D from ‘rbx compile’ options. Closes #523.
      169. +
      170. Propagate –cc configure setting to CC, CXX env vars. Closes #520.
      171. +
      172. Removed -D from ‘rbx compile’ options. Closes #523.
      173. Better docs on installing gems with rbx.
      174. Fixed String#casecmp. Closes #518.
      175. -
      176. Fixed –help output.
      177. +
      178. Fixed –help output.
      179. See README for build, install directions. Closes #521.
      180. taking care of rb_ary_to_s for issue 517
      181. new capi method rb_obj_dup
      182. @@ -186,11 +186,11 @@

        Summary

      183. Remove illegal casts. Fixes #509.
      184. Refuse to configure, build if RUBYLIB is set.
      185. Fix OpenBSD complaints about strcpy, sprintf.
      186. -
      187. Don’t enable execinfo by default on OpenBSD.
      188. -
      189. Add -D__STDC_LIMIT_MACROS to CFLAGS if it’s not there.
      190. +
      191. Don’t enable execinfo by default on OpenBSD.
      192. +
      193. Add -D__STDC_LIMIT_MACROS to CFLAGS if it’s not there.
      194. Speed up rb_yield using some type checking tricks
      195. Fixed pack to taint output for tainted directives string.
      196. -
      197. Added configure option to specify ‘rake’ command.
      198. +
      199. Added configure option to specify ‘rake’ command.
      200. Fix for missing pthread functions on OpenBSD.
      201. Fix String#split edge case. Fixes #505
      202. Set __STDC_LIMIT_MACROS for proper C99 compat. Fixes #507
      203. @@ -200,15 +200,15 @@

        Summary

      204. Set the scope of masgn locals early. Fixes #502.
      205. Use same wording/quoting as MRI. Fixes #503
      206. subclassing IO works properly for pipe/popen
      207. -
      208. Enable running docs site with bootstrap Ruby using ‘rake docs’.
      209. +
      210. Enable running docs site with bootstrap Ruby using ‘rake docs’.
      211. Reorganize how the MRI backtrace is rendered. Fixes #501.
      212. Add missing pop to fix stack effect. Fixes #490
      213. -
      214. Return the user’s object, not the coerced one. Fixes #499.
      215. +
      216. Return the user’s object, not the coerced one. Fixes #499.
      217. Add Socket#connect_nonblock. Fixes #498.
      218. Add rb_io_close
      219. Add rb_memerror as a fatal condition. Fixes #496
      220. Add -fPIC to rbconfig CCDLFLAGS like MRI. Closes #492.
      221. -
      222. Don’t allow meta classes to be allocated
      223. +
      224. Don’t allow meta classes to be allocated
      225. Preserve zero length captures. Fixes #495
      226. diff --git a/web/_site/releases/1.2.0/index.html b/web/_site/releases/1.2.0/index.html index 1f895ba0dc..7d4424c69b 100644 --- a/web/_site/releases/1.2.0/index.html +++ b/web/_site/releases/1.2.0/index.html @@ -136,7 +136,7 @@
        Documentation
      227. Add new docs/website setup
      228. Add documentation on VM instructions
      229. Begin German and Spanish translations of docs
      230. -
      231. Fix ‘rbx report’ to use HTTPS
      232. +
      233. Fix ‘rbx report’ to use HTTPS
      234. Bug fixes
        @@ -147,14 +147,14 @@
        Bug fixes
      235. Add meta_to_s for use in string interpolation
      236. Add/fix/improve instruction documentation
      237. Fix crashing bug in string_build instruction
      238. -
      239. Fix edge case in Bignum#»
      240. +
      241. Fix edge case in Bignum#»
      242. Fixed MatchData#names to return strings
      243. Fixed Hash#initialize to return self
      244. Fixed Bignum#<=> with an object instance
      245. Conform to MRI behavior for strings with malformed characters
      246. Fix heap dump to walk Data objects properly from the Query Agent
      247. Sort out proper logic for Proc.new relating to C-API.
      248. -
      249. Don’t call Module.append_features from Kernel#extend
      250. +
      251. Don’t call Module.append_features from Kernel#extend
      252. C-API
        diff --git a/web/_site/releases/1.2.1/index.html b/web/_site/releases/1.2.1/index.html index 8f7e1f0cc2..1358a8507b 100644 --- a/web/_site/releases/1.2.1/index.html +++ b/web/_site/releases/1.2.1/index.html @@ -116,12 +116,12 @@
        Closed Issues
      253. 103e254 FFI: Check for libs by prepending lib too. Fixes #663
      254. 837ec63 Make set_superclass private to declare intent. Fixes #659
      255. ab13e56 Return nil for no ip instead of -1, -1 means definition line. Fixes #668
      256. -
      257. c3119da Don’t allow nils, so use num2long. Fixes #668
      258. +
      259. c3119da Don’t allow nils, so use num2long. Fixes #668
      260. a42f403 Avoid long DelegatedMethod chains. Fixes #679
      261. ee5f6b6 Flush data in IO finalizers, run on process exit. Fixes #674
      262. f276455 Fix lexical scoping issue in eval methods. Fixes #672. Fixes #671
      263. e473089 Set the proper bytecode position of a when. Fixes #661
      264. -
      265. 2758a31 Doesn’t dup & freeze already frozen keys in Hash#[]=. Fixes #665
      266. +
      267. 2758a31 Doesn’t dup & freeze already frozen keys in Hash#[]=. Fixes #665
      268. 9222e56 msg_controllen should be initialized with CMSG_SPACE, fixes a spec failure on FreeBSD
      269. dc98d19 Add io/wait. Fixes #648
      270. a792da8 Remove bunk macro guards. Fixes #655
      271. @@ -129,8 +129,8 @@
        Closed Issues
      272. 3feeacc Support Proc subclasses properly. Fixes #645. Fixes #646.
      273. 38cfb72 Time.now creates an instance of subclasses if needed. Fixes #644.
      274. 68f7f11 Use StringValue coercion in String#casecmp. Fixes #626
      275. -
      276. c1b4674 Don’t accidently add a nil finalizer. Fixes #643
      277. -
      278. f33f88c Descending ranges in String#tr’s to_str aren’t empty. Fixes #620.
      279. +
      280. c1b4674 Don’t accidently add a nil finalizer. Fixes #643
      281. +
      282. f33f88c Descending ranges in String#tr’s to_str aren’t empty. Fixes #620.
      283. 047a8f4 Added subcommand docs to loader help. Closes #662.
      284. c3a27b1 String#strip should only remove consecutive null bytes. Closes #625
      285. ef4166d Use _p in predicates like everywhere else. Closes #658.
      286. @@ -150,11 +150,11 @@
        Bug fixes
      287. Fix Array#rindex. It returns an Enumerator when passed no block or argument.
      288. Fix Array#flatten to ignore nil return from #to_ary.
      289. Fix Array#product to check the result size first.
      290. -
      291. Fix ‘ruby -S gem’ by checking for a gem wrapper before searching PATH.
      292. +
      293. Fix ‘ruby -S gem’ by checking for a gem wrapper before searching PATH.
      294. Fix Array#[]= from incorrectly changing @start.
      295. Fix a very broken Array#each_index.
      296. Ensure Array#shift adjusts indices properly.
      297. -
      298. Fix Fixnum#» bit width boundary.
      299. +
      300. Fix Fixnum#» bit width boundary.
      301. Create full-named generator methods from insns and aliases for short names.
      302. Workaround for tr1/unordered_map including on OSX 10.5 GCC 4.0.1.
      303. Write Agent discovery file to /tmp if possible when TMPDIR not set.
      304. @@ -168,8 +168,8 @@
        Bug fixes
      305. Add Marshal.restore as an alias for Marshal.load.
      306. Add UNIXSocket#send_io/recv_io.
      307. Rename Process.spawn to Process.replace to avoid naming conflict.
      308. -
      309. Allow ‘@@’ and ‘@’ to be a valid argument for instance_variable_set.
      310. -
      311. Properly mark a thread as dying when it’s killed
      312. +
      313. Allow ‘@@’ and ‘@’ to be a valid argument for instance_variable_set.
      314. +
      315. Properly mark a thread as dying when it’s killed
      316. Minor additions
        @@ -186,7 +186,7 @@
        Performance
        • Fixed melbourne perf regression due to C-API caching.
        • Handle String#splice! requests better
        • -
        • Improve perf of String#[]= ‘’
        • +
        • Improve perf of String#[]= ‘’
        System
        diff --git a/web/_site/releases/1.2.2/index.html b/web/_site/releases/1.2.2/index.html index e3269457df..9c2c9464f8 100644 --- a/web/_site/releases/1.2.2/index.html +++ b/web/_site/releases/1.2.2/index.html @@ -115,7 +115,7 @@
        Bug Fixes
      317. (CRASH) Allow a CM to have no StaticScope (alexsuraci)
      318. (CRASH) Update the current call_frame when waiting on the GIL.
      319. (CRITICAL) Enforce compiler signature check (and install the signature).
      320. -
      321. Fix EBADF errors by being more careful with fd’s and IO objects
      322. +
      323. Fix EBADF errors by being more careful with fd’s and IO objects
      324. Ignore spurious wakeups in Thread#join
      325. Fixed Kernel#private_methods, #public_methods.
      326. Fixed Kernel#singleton_methods.
      327. diff --git a/web/_site/releases/1.2.3/index.html b/web/_site/releases/1.2.3/index.html index bc32a24dca..0bd2f79188 100644 --- a/web/_site/releases/1.2.3/index.html +++ b/web/_site/releases/1.2.3/index.html @@ -113,7 +113,7 @@
        Closed Issues
        • 678ac9d Use Type.obj_kind_of? to a mocked #kind_of? Fixes #762
        • acfa7b7 Module#include should return the target include is called on, Fixes #756
        • -
        • a6fa69b Revert “Use empty binding to eval gemspecs for caching. Fixes #725”
        • +
        • a6fa69b Revert “Use empty binding to eval gemspecs for caching. Fixes #725”
        • ee0c62a Use empty binding to eval gemspecs for caching. Fixes #725
        • dda607b Handle last_match in an inline block properly. Fixes #720
        • f92ec4e Bound the C-API cache for a String when first creating it. Fixes #702
        • @@ -154,7 +154,7 @@
          C-API
          Platform
            -
          • FreeBSD doesn’t need -ldl and OpenBSD already explicitly has it
          • +
          • FreeBSD doesn’t need -ldl and OpenBSD already explicitly has it
          • Store the make to use in a variable and default to gmake on BSD platforms
          • Modify configuration and VM to support both LLVM 2.8 and 2.9 (rc)
          @@ -164,14 +164,14 @@
          Bug Fixes
          • (CRASH) Handle break and return in various scopes properly
          • (CRASH) Fix reading the number of slots a tuple has
          • -
          • (CRASH) Ensure VM doesn’t improperly unwind into a process exit.
          • +
          • (CRASH) Ensure VM doesn’t improperly unwind into a process exit.
          • JIT: Fix returning from a lambda closure
          • JIT: Be sure to sign extend the result of an FFI call
          • Remove bad $~ assignment code
          • Use correct constness for strings returned from the C API
          • Update the -v build rev hash every build.
          • Fix Hash marshal dump
          • -
          • Fix YARD bug, don’t use the custom classes #initialize
          • +
          • Fix YARD bug, don’t use the custom classes #initialize
          • Fixed Kernel#abort to coerce non-String arguments.
          • JIT: Handle raise_return in all contexts properly (fancy)
          • Clarify language/break specs for non-compliant rbx behavior.
          • @@ -179,13 +179,13 @@
            Bug Fixes
          • Fix for Exception#backtrace returning nil when @locations are missing.
          • Fix URI() to return the argument if it is a URI object
          • Remove old references to Rubinius::Scheduler
          • -
          • Run IO finalizers after we’ve shut down all other threads
          • +
          • Run IO finalizers after we’ve shut down all other threads
          • Eval the gemspec cache in an empty binding.
          • Fix how and where eval locals are created
          • Fixing Hash[] method when passing an array
          • Properly detect a constant directory in Dir::Glob
          • Permit inspecting a Method having NativeMethod.
          • -
          • Reset allocations_ so we don’t keep recontributing them
          • +
          • Reset allocations_ so we don’t keep recontributing them
          • JIT: Use the custom static scope in a block (dbussink)
          • Fixed Kernel#singleton_methods to return a unique list.
          • Added Module#define_method with block specs for arity checking.
          • diff --git a/web/_site/releases/1.2.4/index.html b/web/_site/releases/1.2.4/index.html index 10754e2a68..9abed40ae1 100644 --- a/web/_site/releases/1.2.4/index.html +++ b/web/_site/releases/1.2.4/index.html @@ -165,17 +165,17 @@
            Closed Issues
            • 47c3b17 Move prototypes to util to mitigate nokogiri bug. Fixes #1061
            • 45e0601 Add HAVE_ macros for blocking region stuff. Fixes #977
            • -
            • f6567b8 Don’t use Kernel#sleep to know how much time has past. Fixes #986
            • +
            • f6567b8 Don’t use Kernel#sleep to know how much time has past. Fixes #986
            • ee2bdc2 Make sure that a local addrinfo side is found. Fixes #989
            • 3fa02ec Fix CompiledMethod#locate_line. Fixes #1040
            • -
            • f6ac3c8 Include stdint.h where it’s needed. Fixes #1036
            • +
            • f6ac3c8 Include stdint.h where it’s needed. Fixes #1036
            • ecadf56 Fix []= with splats and all that jazz. Fixes #1021
            • 57b1181 Fix Method#parameters for non-CompiledMethods. Fixes #925
            • 6e3be13 Fix Thread.new, .start, and .fork. Fixes #945
            • 5637a52 Guard all NME operations that need an NMF. Fixes #935
            • aeced68 Add rb_check_to_integer, Fixes #933
            • 38a5f97 Add support for -s on the cli. Fixes #879
            • -
            • 52532b0 Don’t count a space leader request against the total width. Fixes #893
            • +
            • 52532b0 Don’t count a space leader request against the total width. Fixes #893
            • bef7f50 Handle certain operator symbol values specially. Fixes #895
            • 06da168 Handle STDIN being closed by default. Fixes #916
            • a81a80d Only check frozen if there is modification in Array#delete. Fixes #913
            • @@ -192,10 +192,10 @@
              Closed Issues
            • c401af1 Add Rubinius.current_file. Fixes #841
            • 944a6d1 Fix build on FreeBSD - Fixes #844
            • 9c72fba Conditional SSLv2 usage. Fixes #818
            • -
            • f079e72 Handle Marshal’ing a Mutex and Channel better. Fixes #821
            • +
            • f079e72 Handle Marshal’ing a Mutex and Channel better. Fixes #821
            • 9f3d790 Add rb_cMethod. Fixes #816
            • f1c6d65 Remove duplicate local names from #local_variables. Fixes #772
            • -
            • 9693227 Don’t screw with vcall new. Fixes #777
            • +
            • 9693227 Don’t screw with vcall new. Fixes #777
            • e70c097 Disable fibers on >= 10.7. Fixes #815
            • 29e5f49 Apply StringScanner speedup patch. Fixes #716
            • 0640ece Apply patch for todo. Fixes #810
            • @@ -234,7 +234,7 @@
              Documentation
              Platform Fixes
                -
              • Add a bunch of errno’s from FreeBSD
              • +
              • Add a bunch of errno’s from FreeBSD
              Performance Fixes
              @@ -272,7 +272,7 @@
              Additions
            • Add rb_ary_to_ary to CAPI
            • BIG improvement for Time#<=>, credit should go to meadow
            • Add tool for rendering call graph as HTML
            • -
            • Add @avibryant’s protobuf decoding benchmark
            • +
            • Add @avibryant’s protobuf decoding benchmark
            • Update to latest OpenSSL extension from 1.8.7
            • Add ability to disable inlining a method preemptively
            @@ -290,7 +290,7 @@
            Bug Fixes
          • Add spec for File.owned? and fix a bug
          • Fixed memory leak, memory allocated by new[] was freed by delete instead of delete[]
          • Removed characters accessor from String.
          • -
          • Add ‘more correct’ -S flag for running gem commands in README
          • +
          • Add ‘more correct’ -S flag for running gem commands in README
          • Add support for -i CLI option
          • Pick the proper local address to bind with
          • Stop currently running methods to fix profiler results
          • @@ -299,14 +299,14 @@
            Bug Fixes
          • Fixed rb_num2long, rb_num2ulong.
          • Reenter managed mode BEFORE creating an FFI result object
          • Honor Time subclasses in the right places
          • -
          • rbx report should not fail silently when Gist submission didn’t work
          • -
          • Add bounds checking to to_chars and make sure it’s 0 terminated
          • +
          • rbx report should not fail silently when Gist submission didn’t work
          • +
          • Add bounds checking to to_chars and make sure it’s 0 terminated
          • Add dummy P rules for pack/unpack
          • Have libc include a version number to deal with gentoo
          • Fixed File.directory?.
          • Allow rbx_meta_to_s to raise an exception
          • Make Module#const_get the proper arity (rails fix)
          • -
          • Fix Kernel#binding and it’s self(ish) rules
          • +
          • Fix Kernel#binding and it’s self(ish) rules
          • Freeze strings returned by ENV.[].
          • Fix <=, ==, >= comparisons to avoid trivial object identity comparisons.
          • Bounds check and avoid c_str() in Regexp prims
          • @@ -314,7 +314,7 @@
            Bug Fixes
          • Add workaround for setting ruby_verbose / ruby_debug in C extensions
          • Fix render_profile, scripts, and thread runtimes
          • Use Type.object_kind_of? instead of Class.===.
          • -
          • Use object’s #respond_to? in Type.try_convert.
          • +
          • Use object’s #respond_to? in Type.try_convert.
          • Add additional safety checks to using the data of a String in the vm
          • Correct mistaken usage of $stdin instead of $stdout in putc
          • Fix #source_location for methods defined using define_method.
          • From 66ab1b56f95acc5e4837355b331e76c5dd951742 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Mon, 14 Nov 2011 11:54:01 -0800 Subject: [PATCH 39/67] Validate a MCE in all check_cache functions IC::execute_backend_ and IC::cache_ are mutated seperately but their values are intertwinned. Without this fix, a cache_ that points to Array#inspect could be used for a Fixnum because check_cache_fixnum didn't validate that the mce was actually for a Fixnum method. This happens because multiple threads mutate the IC at the same time. This obviously causes crashes. This fix at least makes sure that the shortcut check_cache_* functions are using a cache thats allocated with the proper check_cache_* function. --- vm/inline_cache.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vm/inline_cache.cpp b/vm/inline_cache.cpp index 61fd5349fd..de38415853 100644 --- a/vm/inline_cache.cpp +++ b/vm/inline_cache.cpp @@ -512,7 +512,8 @@ namespace rubinius { MethodCacheEntry* mce = cache->cache_; args.set_name(cache->name); - if(likely(mce && args.recv()->fixnum_p())) { + if(likely(mce && mce->receiver_class() == G(fixnum_class) + && args.recv()->fixnum_p())) { Executable* meth = mce->method(); Module* mod = mce->stored_module(); @@ -529,7 +530,8 @@ namespace rubinius { MethodCacheEntry* mce = cache->cache_; args.set_name(cache->name); - if(likely(mce && args.recv()->symbol_p())) { + if(likely(mce && mce->receiver_class() == G(symbol) + && args.recv()->symbol_p())) { Executable* meth = mce->method(); Module* mod = mce->stored_module(); From 3ee2074c38a5ec18ddd8b5ba55ad46b6b16ef382 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Mon, 14 Nov 2011 15:01:59 -0800 Subject: [PATCH 40/67] Code cleanup --- vm/globals.hpp | 32 ++++++--------------- vm/ontology.cpp | 8 ++---- vm/test/test_channel.hpp | 61 ---------------------------------------- vm/vm.cpp | 4 --- vm/vm.hpp | 1 - 5 files changed, 11 insertions(+), 95 deletions(-) diff --git a/vm/globals.hpp b/vm/globals.hpp index 19c16d5e79..cbcd29dc2e 100644 --- a/vm/globals.hpp +++ b/vm/globals.hpp @@ -46,15 +46,15 @@ namespace rubinius { * the constructor for Globals, again, at the END of the list. */ /* classes for the core 'types' */ - TypedRoot blokctx, cmethod, tuple, module, basicobject, object, array; - TypedRoot klass, methtbl, bytearray, chararray, methctx, blank; + TypedRoot cmethod, tuple, module, basicobject, object, array; + TypedRoot klass, methtbl, bytearray, chararray; TypedRoot blokenv, bignum, regexp, matchdata; TypedRoot string, symbol, io; TypedRoot nil_class, true_class, false_class, fixnum_class, undef_class; - TypedRoot floatpoint, fastctx, nmc, task, list, list_node; - TypedRoot channel, thread, staticscope, send_site, selector, lookuptable; + TypedRoot floatpoint, nmc, list, list_node; + TypedRoot channel, thread, staticscope, lookuptable; TypedRoot iseq, executable, native_function, iobuffer; - TypedRoot cmethod_vis, included_module; + TypedRoot included_module; /* the primary symbol table */ TypedRoot sym_method_missing; @@ -67,20 +67,15 @@ namespace rubinius { TypedRoot exception; TypedRoot exc_arg, exc_segfault; TypedRoot exc_loe, exc_type, exc_rex, exc_rte; - TypedRoot exc_stack_explosion; TypedRoot exc_primitive_failure; TypedRoot external_ivars; TypedRoot errno_mapping; - TypedRoot selectors; TypedRoot config; TypedRoot sym_send; TypedRoot sym_public, sym_private, sym_protected, sym_const_missing; TypedRoot sym_object_id, sym_call, sym_undef; - TypedRoot top_scope, on_gc_channel; - TypedRoot vm; - TypedRoot current_thread; TypedRoot main, undefined; TypedRoot dir; TypedRoot compactlookuptable; @@ -114,6 +109,7 @@ namespace rubinius { TypedRoot alias; TypedRoot encoding; TypedRoot type; + TypedRoot vm_class; /* Add new globals above this line. */ @@ -121,7 +117,6 @@ namespace rubinius { TypedRoot special_classes[SPECIAL_CLASS_SIZE]; Globals() : - blokctx(&roots), cmethod(&roots), tuple(&roots), module(&roots), @@ -132,8 +127,6 @@ namespace rubinius { methtbl(&roots), bytearray(&roots), chararray(&roots), - methctx(&roots), - blank(&roots), blokenv(&roots), bignum(&roots), regexp(&roots), @@ -147,21 +140,17 @@ namespace rubinius { fixnum_class(&roots), undef_class(&roots), floatpoint(&roots), - fastctx(&roots), nmc(&roots), list(&roots), list_node(&roots), channel(&roots), thread(&roots), staticscope(&roots), - send_site(&roots), - selector(&roots), lookuptable(&roots), iseq(&roots), executable(&roots), native_function(&roots), iobuffer(&roots), - cmethod_vis(&roots), included_module(&roots), sym_method_missing(&roots), sym_inherited(&roots), @@ -185,11 +174,9 @@ namespace rubinius { exc_type(&roots), exc_rex(&roots), exc_rte(&roots), - exc_stack_explosion(&roots), exc_primitive_failure(&roots), external_ivars(&roots), errno_mapping(&roots), - selectors(&roots), config(&roots), sym_send(&roots), sym_public(&roots), @@ -199,10 +186,6 @@ namespace rubinius { sym_object_id(&roots), sym_call(&roots), sym_undef(&roots), - top_scope(&roots), - on_gc_channel(&roots), - vm(&roots), - current_thread(&roots), main(&roots), undefined(&roots), dir(&roots), @@ -234,7 +217,8 @@ namespace rubinius { fiber(&roots), alias(&roots), encoding(&roots), - type(&roots) + type(&roots), + vm_class(&roots) /* Add initialize of globals above this line. */ { } diff --git a/vm/ontology.cpp b/vm/ontology.cpp index 02bdea0323..4919dc2232 100644 --- a/vm/ontology.cpp +++ b/vm/ontology.cpp @@ -376,8 +376,8 @@ namespace rubinius { Object* undef = new_object(G(object)); GO(undefined).set(undef); - GO(vm).set(ontology::new_class_under(state, "VM", G(rubinius))); - G(vm)->name(state, state->symbol("Rubinius::VM")); + GO(vm_class).set(ontology::new_class_under(state, "VM", G(rubinius))); + G(vm_class)->name(state, state->symbol("Rubinius::VM")); GO(type).set(ontology::new_module(state, "Type", G(rubinius))); G(type)->name(state, state->symbol("Rubinius::Type")); @@ -520,7 +520,7 @@ namespace rubinius { } void VM::bootstrap_exceptions(STATE) { - Class *exc, *scp, *std, *arg, *nam, *loe, *rex, *stk, *sxp, *sce, *type, *lje, *vme; + Class *exc, *scp, *std, *arg, *nam, *loe, *rex, *stk, *sce, *type, *lje, *vme; Class *rng, *rte; #define dexc(name, sup) ontology::new_class(state, #name, sup) @@ -538,7 +538,6 @@ namespace rubinius { rte = dexc(RuntimeError, std); sce = dexc(SystemCallError, std); stk = dexc(StackError, exc); - sxp = dexc(StackExploded, stk); lje = dexc(LocalJumpError, std); rng = dexc(RangeError, std); dexc(FloatDomainError, rng); @@ -568,7 +567,6 @@ namespace rubinius { GO(exc_rex).set(rex); GO(exc_rte).set(rte); - GO(exc_stack_explosion).set(sxp); GO(exc_primitive_failure).set(dexc(PrimitiveFailure, exc)); GO(exc_segfault).set(dexc(MemorySegmentionError, exc)); diff --git a/vm/test/test_channel.hpp b/vm/test/test_channel.hpp index 6fc68d9d82..81ccea330b 100644 --- a/vm/test/test_channel.hpp +++ b/vm/test/test_channel.hpp @@ -50,23 +50,6 @@ class TestChannel : public CxxTest::TestSuite, public VMTest { TS_ASSERT_EQUALS(lst->size(), 0U); } - void test_receive_with_frozen_stack() { - /* - Task* task = Task::create(state, 10); - state->globals.current_task.set(task); - - Thread* thread = Thread::create(state); - state->globals.current_thread.set(thread); - thread->frozen_stack(state, Qtrue); - - task->push(Qfalse); - chan->send(state, Qtrue); - chan->receive(state); - TS_ASSERT_EQUALS(task->calculate_sp(), 0); - TS_ASSERT_EQUALS(task->stack_top(), Qfalse); - */ - } - void compare_interval_in_range(struct timeval start, struct timeval finish, suseconds_t tmin, suseconds_t tmax) { time_t sec = finish.tv_sec - start.tv_sec; @@ -75,48 +58,4 @@ class TestChannel : public CxxTest::TestSuite, public VMTest { TS_ASSERT_LESS_THAN(actual,tmax); } - void test_send_in_microseconds() { - /* - struct timeval start, finish; - - Thread* orig = G(current_thread); - Symbol* done = state->symbol("done"); - gettimeofday(&start, NULL); - - Object** stack = G(current_task)->current_stack(); - - Object* ret = Channel::send_in_microseconds(state, chan, Fixnum::from(100000), done); - usleep(200000); - chan->receive(state); - - gettimeofday(&finish, NULL); - TS_ASSERT(ret->nil_p()); - TS_ASSERT_EQUALS(G(current_thread), orig); - TS_ASSERT_EQUALS(done, stack[0]); - compare_interval_in_range(start,finish,200000U,250000U); - */ - } - - void test_send_in_seconds() { - /* - Float* point_one = Float::create(state, 0.1); - struct timeval start, finish; - - Thread* orig = G(current_thread); - Symbol* done = state->symbol("done"); - gettimeofday(&start, NULL); - - Object** stack = G(current_task)->current_stack(); - - Object* ret = Channel::send_in_seconds(state, chan, point_one, done); - usleep(201000); - chan->receive(state); - - gettimeofday(&finish, NULL); - TS_ASSERT(ret->nil_p()); - TS_ASSERT_EQUALS(G(current_thread), orig); - TS_ASSERT_EQUALS(done, stack[0]); - compare_interval_in_range(start, finish, 201000U, 251000U); - */ - } }; diff --git a/vm/vm.cpp b/vm/vm.cpp index bdc2ff45c3..15d2aaea99 100644 --- a/vm/vm.cpp +++ b/vm/vm.cpp @@ -269,10 +269,6 @@ namespace rubinius { return om->type_info[type]; } - Thread *VM::current_thread() { - return globals().current_thread.get(); - } - void VM::run_gc_soon() { om->collect_young_now = true; om->collect_mature_now = true; diff --git a/vm/vm.hpp b/vm/vm.hpp index 7cc9f7483b..a01b79204d 100644 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -320,7 +320,6 @@ namespace rubinius { void init_ffi(STATE); void init_native_libraries(); - Thread* current_thread(); void collect(GCToken gct, CallFrame* call_frame); /// Check the GC flags in ObjectMemory and collect if we need to. From 6f7022992a72d89cacdfbeaac7c95efc8eb6c1a6 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Mon, 14 Nov 2011 15:43:09 -0800 Subject: [PATCH 41/67] Add VariableScope.synthesize for metaprogramming fun --- kernel/bootstrap/variable_scope.rb | 5 +++++ vm/builtin/variable_scope.cpp | 29 +++++++++++++++++++++++++++++ vm/builtin/variable_scope.hpp | 3 +++ 3 files changed, 37 insertions(+) diff --git a/kernel/bootstrap/variable_scope.rb b/kernel/bootstrap/variable_scope.rb index 3c8dadfc48..c4721e9e34 100644 --- a/kernel/bootstrap/variable_scope.rb +++ b/kernel/bootstrap/variable_scope.rb @@ -10,6 +10,11 @@ def self.current raise PrimitiveFailure, "Unable to get current VariableScope" end + def self.synthesize(method, module_, parent, self_, block, locals) + Rubinius.primitive :variable_scope_synthesize + raise PrimitiveFailure, "Unable to create a new VariableScope object" + end + def locals Rubinius.primitive :variable_scope_locals raise PrimitiveFailure, "Unable to get VariableScope locals" diff --git a/vm/builtin/variable_scope.cpp b/vm/builtin/variable_scope.cpp index 4a64bc74af..c68f91bef3 100644 --- a/vm/builtin/variable_scope.cpp +++ b/vm/builtin/variable_scope.cpp @@ -39,6 +39,35 @@ namespace rubinius { return call_frame->promote_scope(state); } + VariableScope* VariableScope::synthesize(STATE, CompiledMethod* method, + Module* module, Object* parent, + Object* self, Object* block, + Tuple* locals) + { + VariableScope* scope = state->new_object(G(variable_scope)); + + scope->block(state, block); + scope->module(state, module); + scope->method(state, method); + + if(VariableScope* vs = try_as(parent)) { + scope->parent(state, vs); + } else { + scope->parent(state, nil()); + } + + scope->heap_locals(state, locals); + scope->last_match(state, Qnil); + + scope->self(state, self); + scope->number_of_locals_ = locals->num_fields(); + scope->isolated_ = true; + scope->locals_ = 0; + scope->block_as_method_ = 0; + + return scope; + } + Tuple* VariableScope::locals(STATE) { Tuple* tup = Tuple::create(state, number_of_locals_); for(int i = 0; i < number_of_locals_; i++) { diff --git a/vm/builtin/variable_scope.hpp b/vm/builtin/variable_scope.hpp index 8b97b40bce..414d71e58e 100644 --- a/vm/builtin/variable_scope.hpp +++ b/vm/builtin/variable_scope.hpp @@ -110,6 +110,9 @@ namespace rubinius { // Rubinius.primitive :variable_scope_current static VariableScope* current(STATE, CallFrame* calling_environment); + // Rubinius.primitive :variable_scope_synthesize + static VariableScope* synthesize(STATE, CompiledMethod* method, Module* module, Object* parent, Object* self, Object* block, Tuple* locals); + // Rubinius.primitive :variable_scope_locals Tuple* locals(STATE); From a2707e34ea77a64ae5d94b300e83c263f8693a62 Mon Sep 17 00:00:00 2001 From: Karol Hosiawa Date: Tue, 15 Nov 2011 09:18:45 +0100 Subject: [PATCH 42/67] Updated String#prepend spec --- spec/ruby/core/string/prepend_spec.rb | 43 ++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/spec/ruby/core/string/prepend_spec.rb b/spec/ruby/core/string/prepend_spec.rb index 642be32b3f..3211e83c59 100644 --- a/spec/ruby/core/string/prepend_spec.rb +++ b/spec/ruby/core/string/prepend_spec.rb @@ -1,11 +1,46 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/classes.rb', __FILE__) -ruby_version_is '1.9' do - describe :string_prepend do +ruby_version_is '1.9.3' do + describe "String#prepend" do it "prepends the given argument to self and returns self" do - str = 'world' - str.prepend('hello ').should equal(str) + str = "world" + str.prepend("hello ").should equal(str) str.should == "hello world" end + + it "converts the given argument to a String using to_str" do + obj = mock("hello") + obj.should_receive(:to_str).and_return("hello") + a = " world!".prepend(obj) + a.should == "hello world!" + end + + it "raises a TypeError if the given argument can't be converted to a String" do + lambda { a = "hello ".prepend [] }.should raise_error(TypeError) + lambda { a = 'hello '.prepend mock('x') }.should raise_error(TypeError) + end + + it "raises a RuntimeError when self if frozen" do + a = "hello" + a.freeze + + lambda { a.prepend "" }.should raise_error(RuntimeError) + lambda { a.prepend "test" }.should raise_error(RuntimeError) + end + + it "works when given a subclass instance" do + a = " world" + a.prepend StringSpecs::MyString.new("hello") + a.should == "hello world" + end + + it "taints self if other is tainted" do + x = "x" + x.prepend("".taint).tainted?.should be_true + + x = "x" + x.prepend("y".taint).tainted?.should be_true + end end end From 2214c38c20b2f0dbbd0a98bd8cfe27b55cebee42 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Tue, 15 Nov 2011 12:28:10 -0800 Subject: [PATCH 43/67] Fix thread safety issue in the global method cache The GlobalCache was locking on lookup of an entry, but not on the actual reading of it, causing other threads to mutate the entry post lookup, pre read. --- vm/global_cache.cpp | 65 ++++++++++++++++++++++++++++++++++++--------- vm/global_cache.hpp | 33 ++++++++++++----------- vm/inline_cache.cpp | 23 +++------------- 3 files changed, 74 insertions(+), 47 deletions(-) diff --git a/vm/global_cache.cpp b/vm/global_cache.cpp index be0b717425..a77f79a383 100644 --- a/vm/global_cache.cpp +++ b/vm/global_cache.cpp @@ -1,14 +1,16 @@ +#include "vm.hpp" +#include "global_cache.hpp" +#include "object_position.hpp" +#include "objectmemory.hpp" #include "lookup_data.hpp" #include "dispatch.hpp" -#include "vm.hpp" -#include "vm/global_cache.hpp" -#include "vm/object_position.hpp" -#include "vm/objectmemory.hpp" -#include "vm/builtin/module.hpp" -#include "vm/builtin/object.hpp" -#include "vm/builtin/methodtable.hpp" +#include "builtin/class.hpp" +#include "builtin/module.hpp" +#include "builtin/object.hpp" +#include "builtin/methodtable.hpp" #include "builtin/alias.hpp" +#include "builtin/cache.hpp" namespace rubinius { static bool hierarchy_resolve(STATE, Symbol* name, Dispatch& msg, LookupData& lookup, @@ -82,12 +84,49 @@ namespace rubinius { return true; } + + MethodCacheEntry* GlobalCache::lookup_public(STATE, Module* mod, Class* cls, Symbol* name) { + SYNC(state); + + CacheEntry* entry = entries + CPU_CACHE_HASH(mod, name); + if(entry->name == name && + entry->klass == mod && + entry->is_public && + !entry->method_missing) { + + return MethodCacheEntry::create(state, cls, entry->module, + entry->method); + } + + return NULL; + } + + MethodCacheEntry* GlobalCache::lookup_private(STATE, Module* mod, Class* cls, Symbol* name) { + SYNC(state); + + CacheEntry* entry = entries + CPU_CACHE_HASH(mod, name); + if(entry->name == name && + entry->klass == mod && + !entry->method_missing) { + + return MethodCacheEntry::create(state, cls, entry->module, + entry->method); + } + + return NULL; + } + bool GlobalCache::resolve(STATE, Symbol* name, Dispatch& msg, LookupData& lookup) { - struct GlobalCache::cache_entry* entry; + return state->vm()->global_cache()->resolve_i(state, name, msg, lookup); + } + bool GlobalCache::resolve_i(STATE, Symbol* name, Dispatch& msg, LookupData& lookup) { Module* klass = lookup.from; - entry = state->vm()->global_cache()->lookup(state, klass, name); + SYNC(state); + + CacheEntry* entry = this->lookup(state, klass, name); + if(entry) { if(lookup.priv || entry->is_public) { msg.method = entry->method; @@ -100,7 +139,7 @@ namespace rubinius { bool was_private = false; if(hierarchy_resolve(state, name, msg, lookup, &was_private)) { - state->vm()->global_cache()->retain(state, lookup.from, name, + retain(state, lookup.from, name, msg.module, msg.method, msg.method_missing, was_private); return true; } @@ -109,7 +148,8 @@ namespace rubinius { } void GlobalCache::prune_young() { - cache_entry* entry; + CacheEntry* entry; + for(size_t i = 0; i < CPU_CACHE_SIZE; i++) { entry = &entries[i]; bool clear = false; @@ -155,7 +195,8 @@ namespace rubinius { } void GlobalCache::prune_unmarked(int mark) { - cache_entry* entry; + CacheEntry* entry; + for(size_t i = 0; i < CPU_CACHE_SIZE; i++) { entry = &entries[i]; Object* klass = reinterpret_cast(entry->klass); diff --git a/vm/global_cache.hpp b/vm/global_cache.hpp index 70bb93218c..d037ff92e6 100644 --- a/vm/global_cache.hpp +++ b/vm/global_cache.hpp @@ -16,7 +16,7 @@ namespace rubinius { class GlobalCache : public Lockable { public: - struct cache_entry { + struct CacheEntry { Module* klass; Symbol* name; Module* module; @@ -25,28 +25,19 @@ namespace rubinius { bool method_missing; }; - struct cache_entry entries[CPU_CACHE_SIZE]; + CacheEntry entries[CPU_CACHE_SIZE]; public: static bool resolve(STATE, Symbol* name, Dispatch& msg, LookupData& lookup); + bool resolve_i(STATE, Symbol* name, Dispatch& msg, LookupData& lookup); GlobalCache() { clear(); } - /** @todo This does NOT handle null? --rue */ - struct cache_entry* lookup(STATE, Module* cls, Symbol* name) { - struct cache_entry* entry; - - SYNC(state); - entry = entries + CPU_CACHE_HASH(cls, name); - if(entry->name == name && entry->klass == cls) { - return entry; - } - - return NULL; - } + MethodCacheEntry* lookup_public(STATE, Module* mod, Class* cls, Symbol* name); + MethodCacheEntry* lookup_private(STATE, Module* mod, Class* cls, Symbol* name); void clear(STATE, Symbol* name) { SYNC(state); @@ -62,7 +53,7 @@ namespace rubinius { } void clear(STATE, Module* cls, Symbol* name) { - struct cache_entry* entry; + CacheEntry* entry; SYNC(state); entry = entries + CPU_CACHE_HASH(cls, name); if(entry->name == name && entry->klass == cls) { @@ -81,7 +72,7 @@ namespace rubinius { void retain(STATE, Module* cls, Symbol* name, Module* mod, Executable* meth, bool missing, bool was_private = false) { SYNC(state); - struct cache_entry* entry; + CacheEntry* entry; entry = entries + CPU_CACHE_HASH(cls, name); entry->klass = cls; @@ -106,6 +97,16 @@ namespace rubinius { } } + // Must be called with the lock held on +this+ + CacheEntry* lookup(STATE, Module* cls, Symbol* name) { + CacheEntry* entry = entries + CPU_CACHE_HASH(cls, name); + if(entry->name == name && entry->klass == cls) { + return entry; + } + + return NULL; + } + }; }; diff --git a/vm/inline_cache.cpp b/vm/inline_cache.cpp index de38415853..ab0e53c21a 100644 --- a/vm/inline_cache.cpp +++ b/vm/inline_cache.cpp @@ -23,18 +23,9 @@ namespace rubinius { Module* module = klass; // Check the global cache first! - GlobalCache::cache_entry* global_entry = - state->vm()->global_cache()->lookup(state, module, name); + mce = state->vm()->global_cache()->lookup_public(state, module, klass, name); - if(global_entry && - global_entry->is_public && - !global_entry->method_missing) { - - mce = MethodCacheEntry::create(state, klass, global_entry->module, - global_entry->method); - - return eNone; - } + if(mce) return eNone; bool skip_vis_check = false; @@ -135,14 +126,8 @@ namespace rubinius { Module* module = start; // Check the global cache first! - GlobalCache::cache_entry* global_entry = - state->vm()->global_cache()->lookup(state, module, name); - - if(global_entry && !global_entry->method_missing) { - mce = MethodCacheEntry::create(state, klass, global_entry->module, - global_entry->method); - return true; - } + mce = state->vm()->global_cache()->lookup_private(state, start, klass, name); + if(mce) return true; MethodTableBucket* vis_entry = 0; From c4b7c47bc6d6821c511e35d07adb02739dca21f6 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Tue, 15 Nov 2011 13:44:44 -0800 Subject: [PATCH 44/67] locate takes three arguments, not two --- lib/compiler/compiled_file.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compiler/compiled_file.rb b/lib/compiler/compiled_file.rb index 1ca9af396e..35e3054734 100644 --- a/lib/compiler/compiled_file.rb +++ b/lib/compiler/compiled_file.rb @@ -211,7 +211,7 @@ def next_type # Returns the next string in _@data_ including the trailing # "\n" character. def next_string - count = @data.locate "\n", @start + count = @data.locate "\n", @start, @size count = @size unless count str = String.from_chararray @data, @start, count - @start @start = count From 3f4404867399f492906f45dc36c34e1035d8879d Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Tue, 15 Nov 2011 13:45:00 -0800 Subject: [PATCH 45/67] Provide a context for exceptions that happen inside the marshal process --- kernel/common/marshal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/common/marshal.rb b/kernel/common/marshal.rb index 5b0dc7132b..f0d1daba8b 100644 --- a/kernel/common/marshal.rb +++ b/kernel/common/marshal.rb @@ -970,7 +970,7 @@ def self.load(obj, prc = nil) ms.construct rescue NameError => e - raise ArgumentError, e.message + raise ArgumentError, e.message, e end class << self From 43187268bd3e674da1a2125bc80466d965f3db90 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Tue, 15 Nov 2011 22:41:52 +0100 Subject: [PATCH 46/67] Add specs for Process.exit! Checks whether the correct exit status is returned and whether this immediately exits when called from a different thread than the main thread. --- spec/ruby/core/process/exit_spec.rb | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/spec/ruby/core/process/exit_spec.rb b/spec/ruby/core/process/exit_spec.rb index fde6309162..8b9b0d935f 100644 --- a/spec/ruby/core/process/exit_spec.rb +++ b/spec/ruby/core/process/exit_spec.rb @@ -5,5 +5,24 @@ end describe "Process.exit!" do - it "needs to be reviewed for spec completeness" + + platform_is_not :windows do + + it "exits with the given status" do + pid = Process.fork { Process.exit!(1) } + pid, status = Process.waitpid2(pid) + status.exitstatus.should == 1 + end + + it "exits immediately when called from a thread" do + pid = Process.fork do + Thread.new { Process.exit!(1) } + sleep 1 + Process.exit!(2) + end + pid, status = Process.waitpid2(pid) + status.exitstatus.should == 1 + end + + end end From 8dc44f082bb45ab2f62148c7f9d90ee960184b98 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Tue, 15 Nov 2011 22:45:00 +0100 Subject: [PATCH 47/67] Allow for exiting from a different thread --- vm/builtin/thread.cpp | 2 +- vm/drivers/cli.cpp | 4 ++-- vm/environment.cpp | 9 +++++++-- vm/environment.hpp | 6 ++++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/vm/builtin/thread.cpp b/vm/builtin/thread.cpp index bf6aec7c61..cad3c3fc11 100644 --- a/vm/builtin/thread.cpp +++ b/vm/builtin/thread.cpp @@ -132,7 +132,7 @@ namespace rubinius { if(!ret) { if(vm->thread_state()->raise_reason() == cExit) { - vm->shared.env()->halt(); + vm->shared.env()->halt_and_exit(state); } } diff --git a/vm/drivers/cli.cpp b/vm/drivers/cli.cpp index 9c95f9de15..9bd39b1042 100644 --- a/vm/drivers/cli.cpp +++ b/vm/drivers/cli.cpp @@ -110,8 +110,8 @@ int main(int argc, char** argv) { return 1; } - env.halt(); - return env.exit_code(); + env.halt(env.state); + return env.exit_code(env.state); } static void check_directory(std::string runtime) { diff --git a/vm/environment.cpp b/vm/environment.cpp index 2863bd8bb8..f972049fe2 100644 --- a/vm/environment.cpp +++ b/vm/environment.cpp @@ -528,7 +528,12 @@ namespace rubinius { delete cf; } - void Environment::halt() { + void Environment::halt_and_exit(STATE) { + halt(state); + exit(exit_code(state)); + } + + void Environment::halt(STATE) { state->shared().tool_broker()->shutdown(state); if(state->shared().config.ic_stats) { @@ -561,7 +566,7 @@ namespace rubinius { /** * Returns the exit code to use when exiting the rbx process. */ - int Environment::exit_code() { + int Environment::exit_code(STATE) { #ifdef ENABLE_LLVM if(LLVMState* ls = shared->llvm_state) { diff --git a/vm/environment.hpp b/vm/environment.hpp index f52d50490f..d0ae80e6ad 100644 --- a/vm/environment.hpp +++ b/vm/environment.hpp @@ -79,8 +79,10 @@ namespace rubinius { void run_from_filesystem(std::string root); void boot_vm(); - void halt(); - int exit_code(); + void halt(STATE); + void halt_and_exit(STATE); + int exit_code(STATE); + void start_signals(); void start_agent(int port); }; From fe7d84a99b21527fa6f5933d378fdd0a274b6631 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Tue, 15 Nov 2011 23:11:50 +0100 Subject: [PATCH 48/67] Add tags for failing StringIO#gets specs --- spec/tags/19/ruby/library/stringio/gets_tags.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/tags/19/ruby/library/stringio/gets_tags.txt b/spec/tags/19/ruby/library/stringio/gets_tags.txt index 83d1957441..e881baf171 100644 --- a/spec/tags/19/ruby/library/stringio/gets_tags.txt +++ b/spec/tags/19/ruby/library/stringio/gets_tags.txt @@ -7,3 +7,7 @@ fails:StringIO#gets when passed [separator] and [limit] sets $_ to the read cont fails:StringIO#gets when passed [separator] and [limit] updates self's lineno by one fails:StringIO#gets when passed [separator] and [limit] tries to convert the passed separator to a String using #to_str fails:StringIO#gets when passed [separator] and [limit] tries to convert the passed limit to an Integer using #to_int +fails:StringIO#gets when passed [limit] returns the data read until the limit is met +fails:StringIO#gets when passed [limit] sets $_ to the read content +fails:StringIO#gets when passed [limit] updates self's lineno by one +fails:StringIO#gets when passed [limit] tries to convert the passed limit to an Integer using #to_int From c1d8cf6d5eaf1c509190c2f058230c22cdee3fc2 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Tue, 15 Nov 2011 23:33:14 +0100 Subject: [PATCH 49/67] Remove wrongly spelled tag names --- spec/tags/19/ruby/library/stringio/gets_tags.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/tags/19/ruby/library/stringio/gets_tags.txt b/spec/tags/19/ruby/library/stringio/gets_tags.txt index e881baf171..7c6f6234fa 100644 --- a/spec/tags/19/ruby/library/stringio/gets_tags.txt +++ b/spec/tags/19/ruby/library/stringio/gets_tags.txt @@ -1,7 +1,3 @@ -fails:StringIO#gets when passes [limit] returns the data read until the limit is met -fails:StringIO#gets when passes [limit] sets $_ to the read content -fails:StringIO#gets when passes [limit] updates self's lineno by one -fails:StringIO#gets when passes [limit] tries to convert the passed limit to an Integer using #to_int fails:StringIO#gets when passed [separator] and [limit] returns the data read until the limit is consumed or the separator is met fails:StringIO#gets when passed [separator] and [limit] sets $_ to the read content fails:StringIO#gets when passed [separator] and [limit] updates self's lineno by one From 05e2a025e5f1da9c668452026bf8707e67c0dad1 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Tue, 15 Nov 2011 16:49:15 -0800 Subject: [PATCH 50/67] Create fewer objects --- kernel/common/thread.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/common/thread.rb b/kernel/common/thread.rb index d22c5835d8..083538e6fd 100644 --- a/kernel/common/thread.rb +++ b/kernel/common/thread.rb @@ -95,7 +95,7 @@ def self.detect_outermost_recursion(obj, paired_obj=undefined, &block) if rec[:__detect_outermost_recursion__] if detect_recursion(obj, paired_obj, &block) - raise InnerRecursionDetected.new + raise InnerRecursionDetected end false else From b60d6bbc2801a0bd0b6a032880edcff13a6fabdc Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Tue, 15 Nov 2011 16:49:48 -0800 Subject: [PATCH 51/67] Fix and improve Struct specialization None of the specialization was firing before, so that's fixed now. Also added #hash, #to_a, and #length to specialized methods. --- kernel/common/struct.rb | 4 ++-- kernel/delta/struct.rb | 32 ++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/kernel/common/struct.rb b/kernel/common/struct.rb index 38b43c163b..eeafa126f1 100644 --- a/kernel/common/struct.rb +++ b/kernel/common/struct.rb @@ -76,7 +76,7 @@ def self.[](*args) end const_set :STRUCT_ATTRS, attrs - specialize_initialize + _specialize attrs end Struct.const_set klass_name, klass if klass_name @@ -88,7 +88,7 @@ def self.[](*args) # Don't specialize any thing created in the kernel. We hook up # better form of this in delta. - def self.specialize_initialize + def self._specialize(attrs) end def self.make_struct(name, attrs) diff --git a/kernel/delta/struct.rb b/kernel/delta/struct.rb index c10453e59d..c93c6c231d 100644 --- a/kernel/delta/struct.rb +++ b/kernel/delta/struct.rb @@ -13,7 +13,7 @@ def initialize(utime=nil, stime=nil, cutime=nil, cstime=nil, end end - def self.specialize_initialize + def self._specialize(attrs) # Because people are crazy, they subclass Struct directly, ie. # class Craptastic < Struct # @@ -29,9 +29,7 @@ def self.specialize_initialize # the specialize if we're trying new Struct's directly from Struct itself, # not a craptastic Struct subclass. - return unless self.equal? Struct - - attrs = self::STRUCT_ATTRS + return unless superclass.equal? Struct args = [] 0.upto(attrs.size-1) do |i| @@ -43,11 +41,37 @@ def self.specialize_initialize assigns << "@#{attrs[i]} = a#{i}" end + hashes = [] + vars = [] + + 0.upto(attrs.size-1) do |i| + hashes << "@#{attrs[i]}.hash" + vars << "@#{attrs[i]}" + end + code = <<-CODE def initialize(#{args.join(", ")}) #{assigns.join(';')} self end + + def hash + hash = #{hashes.size} + + return hash if Thread.detect_outermost_recursion(self) do + hash = hash ^ #{hashes.join(' ^ ')} + end + + hash + end + + def to_a + [#{vars.join(', ')}] + end + + def length + #{vars.size} + end CODE begin From 0218adfdc8ef762bbc2942d1098168e0da994f8a Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Wed, 16 Nov 2011 14:53:23 -0800 Subject: [PATCH 52/67] Add capi_fast_call to improve rbx specific upcalls --- vm/capi/capi.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ vm/capi/capi.hpp | 3 +++ vm/capi/hash.cpp | 24 ++++++++++++------------ 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/vm/capi/capi.cpp b/vm/capi/capi.cpp index a282543df4..0859d85b3f 100644 --- a/vm/capi/capi.cpp +++ b/vm/capi/capi.cpp @@ -209,6 +209,48 @@ namespace rubinius { return ret_handle; } + VALUE capi_fast_call(VALUE receiver, ID method_name, int arg_count, ...) { + NativeMethodEnvironment* env = NativeMethodEnvironment::get(); + + va_list varargs; + va_start(varargs, arg_count); + + Object** args = reinterpret_cast( + alloca(sizeof(Object*) * arg_count)); + + for(int i = 0; i < arg_count; i++) { + args[i] = env->get_object(va_arg(varargs, VALUE)); + } + + va_end(varargs); + + // Unlock, we're leaving extension code. + env->state()->vm()->shared.leave_capi(env->state()); + + Object* recv = env->get_object(receiver); + Symbol* method = (Symbol*)method_name; + + LookupData lookup(recv, recv->lookup_begin(env->state()), true); + Arguments args_o(method, recv, RBX_Qnil, arg_count, args); + Dispatch dis(method); + + Object* ret = dis.send(env->state(), env->current_call_frame(), + lookup, args_o); + + // We need to get the handle for the return value before getting + // the GEL so that ret isn't accidentally GCd while we wait. + VALUE ret_handle = 0; + if(ret) ret_handle = env->get_handle(ret); + + // Re-entering extension code + env->state()->vm()->shared.enter_capi(env->state()); + + // An exception occurred + if(!ret) env->current_ep()->return_to(env); + + return ret_handle; + } + VALUE capi_yield_backend(NativeMethodEnvironment* env, Object* blk, size_t arg_count, Object** arg_vals) diff --git a/vm/capi/capi.hpp b/vm/capi/capi.hpp index e12d02dcd4..076a4b42a9 100644 --- a/vm/capi/capi.hpp +++ b/vm/capi/capi.hpp @@ -61,6 +61,9 @@ namespace rubinius { /** Wrap a C function in a Proc */ Proc* wrap_c_function(void* func, VALUE cb, int arity); + /** Call a ruby method and ignore cached handles, etc */ + VALUE capi_fast_call(VALUE receiver, ID method_name, int arg_count, ...); + /** Converts a native type (int, uint, long) to a suitable Integer. */ template VALUE capi_native2num(NativeType number) { diff --git a/vm/capi/hash.cpp b/vm/capi/hash.cpp index 4eedfb3904..5bde6615bd 100644 --- a/vm/capi/hash.cpp +++ b/vm/capi/hash.cpp @@ -7,19 +7,19 @@ using namespace rubinius::capi; extern "C" { VALUE rb_hash_new() { - return rb_funcall(rb_cHash, rb_intern("new"), 0); + return capi_fast_call(rb_cHash, rb_intern("new"), 0); } VALUE rb_hash_aref(VALUE self, VALUE key) { - return rb_funcall(self, rb_intern("[]"), 1, key); + return capi_fast_call(self, rb_intern("[]"), 1, key); } VALUE rb_hash_aset(VALUE self, VALUE key, VALUE value) { - return rb_funcall(self, rb_intern("[]="), 2, key, value); + return capi_fast_call(self, rb_intern("[]="), 2, key, value); } VALUE rb_hash_delete(VALUE self, VALUE key) { - return rb_funcall(self, rb_intern("delete"), 1, key); + return capi_fast_call(self, rb_intern("delete"), 1, key); } VALUE rb_hash_delete_if(VALUE self) { @@ -31,13 +31,13 @@ extern "C" { } VALUE rb_hash_size(VALUE self) { - return rb_funcall(self, rb_intern("size"), 0); + return capi_fast_call(self, rb_intern("size"), 0); } VALUE rb_hash_lookup(VALUE self, VALUE key) { - VALUE entry = rb_funcall(self, rb_intern("find_item"), 1, key); + VALUE entry = capi_fast_call(self, rb_intern("find_item"), 1, key); if(entry != Qnil) { - return rb_funcall(entry, rb_intern("value"), 0); + return capi_fast_call(entry, rb_intern("value"), 0); } else { return Qnil; } @@ -47,13 +47,13 @@ extern "C" { int (*func)(ANYARGS), VALUE farg) { - VALUE iter = rb_funcall(self, rb_intern("to_iter"), 0); + VALUE iter = capi_fast_call(self, rb_intern("to_iter"), 0); VALUE entry = Qnil; VALUE to_delete = rb_ary_new(); - while(RTEST(entry = rb_funcall(iter, rb_intern("next"), 1, entry))) { - VALUE key = rb_funcall(entry, rb_intern("key"), 0); - VALUE val = rb_funcall(entry, rb_intern("value"), 0); + while(RTEST(entry = capi_fast_call(iter, rb_intern("next"), 1, entry))) { + VALUE key = capi_fast_call(entry, rb_intern("key"), 0); + VALUE val = capi_fast_call(entry, rb_intern("value"), 0); int ret = (*func)(key, val, farg); switch(ret) { @@ -71,7 +71,7 @@ extern "C" { if (rb_ary_size(to_delete) > 0) { for (size_t i = 0; i < rb_ary_size(to_delete); i++) { - rb_funcall(self, rb_intern("delete"), 1, rb_ary_entry(to_delete, i)); + capi_fast_call(self, rb_intern("delete"), 1, rb_ary_entry(to_delete, i)); } } } From b6bc22d829a779d2591a6b1d1b6aec2105b5356f Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Wed, 16 Nov 2011 14:53:45 -0800 Subject: [PATCH 53/67] Improve the performance of rb_Integer() --- vm/capi/numeric.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/vm/capi/numeric.cpp b/vm/capi/numeric.cpp index cde11abffc..4489febfca 100644 --- a/vm/capi/numeric.cpp +++ b/vm/capi/numeric.cpp @@ -3,6 +3,8 @@ #include "builtin/float.hpp" #include "builtin/object.hpp" +#include "object_utils.hpp" + #include "capi/capi.hpp" #include "capi/18/include/ruby.h" @@ -242,6 +244,21 @@ extern "C" { } VALUE rb_Integer(VALUE object_handle) { + NativeMethodEnvironment* env = NativeMethodEnvironment::get(); + + Object* object = env->get_object(object_handle); + + if(kind_of(object) || kind_of(object)) { + return object_handle; + } else if(String* str = try_as(object)) { + Object* ret = str->to_i(env->state(), Fixnum::from(0), RBX_Qtrue); + if(ret->nil_p()) { + rb_raise(rb_eArgError, "invalid value for Integer"); + } + + return env->get_handle(ret); + } + return rb_convert_type(object_handle, 0, "Integer", "to_i"); } From ccd76c379adaa9541af1b9700aafe52cb0caa87e Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Wed, 16 Nov 2011 14:54:02 -0800 Subject: [PATCH 54/67] Change how often a full GC is triggered to improve CAPI perf --- vm/gc/inflated_headers.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/gc/inflated_headers.hpp b/vm/gc/inflated_headers.hpp index c18e2d4c40..7d3ce3f732 100644 --- a/vm/gc/inflated_headers.hpp +++ b/vm/gc/inflated_headers.hpp @@ -27,7 +27,7 @@ namespace rubinius { /// Storage for InflatedHeader references is allocated in chunks. static const size_t cChunkSize = 1024; - static const size_t cChunkLimit = 16; + static const size_t cChunkLimit = 32; private: VM* state_; From 03c77413200dc7c76c3a150fc14027260637fa04 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Wed, 16 Nov 2011 15:10:05 -0800 Subject: [PATCH 55/67] Remove old Integer#bits method. Fixes #1336 --- kernel/common/integer.rb | 30 ------------------------------ spec/core/integer/bits_spec.rb | 15 --------------- 2 files changed, 45 deletions(-) delete mode 100644 spec/core/integer/bits_spec.rb diff --git a/kernel/common/integer.rb b/kernel/common/integer.rb index ef6226a202..6e17e10336 100644 --- a/kernel/common/integer.rb +++ b/kernel/common/integer.rb @@ -65,36 +65,6 @@ def integer? true end - ## - # Returns the minimum number of bits required for integer in (signed int) - # binary format - #-- - # NOTE: rshift would probably be slightly more efficient but since i'm - # probably going to use this to simplify the complex behavior of - # ruby's << and >> it would defeat the purpose by creating a circular - # dependency. - # - # TODO: convert algorithm to primitive so no circular dependency? - #++ - - def bits(int = self) - num_bits = 1 # sign bit storage - - if int < 0 - int = ~int - - num_bits += 1 - int /= 2 # could use >> in primitive - end - - while int != 0 - num_bits += 1 - int /= 2 # could use >> in primitive - end - - num_bits - end - # Returns true if int is an even number. def even? self & 1 == 0 diff --git a/spec/core/integer/bits_spec.rb b/spec/core/integer/bits_spec.rb deleted file mode 100644 index 5ec89e4de5..0000000000 --- a/spec/core/integer/bits_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require File.expand_path('../../../spec_helper', __FILE__) - -describe "Integer#bits" do - it "returns the minimum bits of storage needed for the number as a signed int" do - 1.bits.should == 2 - -1.bits.should == 2 - -2.bits.should == 2 - 2.bits.should == 3 - 4.bits.should == 4 - 536870911.bits.should == 30 - -536870912.bits.should == 30 - 536870912.bits.should == 31 - -536870913.bits.should == 31 - end -end From 958cf7822f459eb9b2c867dd196ee7db4a056a88 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Wed, 16 Nov 2011 15:31:15 -0800 Subject: [PATCH 56/67] Add support for Method objects with instance_exec. Fixes #1321 --- kernel/common/eval18.rb | 5 +++++ kernel/common/eval19.rb | 4 ++++ spec/ruby/core/object/instance_exec_spec.rb | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/kernel/common/eval18.rb b/kernel/common/eval18.rb index 126b152d42..9db0f18860 100644 --- a/kernel/common/eval18.rb +++ b/kernel/common/eval18.rb @@ -86,6 +86,11 @@ def instance_eval(string=nil, filename="(eval)", line=1, &prc) def instance_exec(*args, &prc) raise LocalJumpError, "Missing block" unless block_given? + + if prc.kind_of? Proc::Method + return prc.bound_method.call(*args) + end + env = prc.block static_scope = env.static_scope diff --git a/kernel/common/eval19.rb b/kernel/common/eval19.rb index 4b51cb8588..1d3b4e4761 100644 --- a/kernel/common/eval19.rb +++ b/kernel/common/eval19.rb @@ -88,6 +88,10 @@ def instance_exec(*args, &prc) raise LocalJumpError, "Missing block" unless block_given? env = prc.block + if prc.kind_of? Proc::Method + return prc.bound_method.call(*args) + end + static_scope = env.static_scope if ImmediateValue === self static_scope = static_scope.using_disabled_scope diff --git a/spec/ruby/core/object/instance_exec_spec.rb b/spec/ruby/core/object/instance_exec_spec.rb index e63a391f7d..5ce8a05c64 100644 --- a/spec/ruby/core/object/instance_exec_spec.rb +++ b/spec/ruby/core/object/instance_exec_spec.rb @@ -54,6 +54,10 @@ def foo ObjectSpecs::IVars.new.instance_exec { @secret }.should == 99 end + it "invokes Method objects wihtout rebinding self" do + 3.instance_exec(4, &5.method(:+)).should == 9 + end + ruby_version_is ""..."1.9" do it "sets class variables in the receiver" do ObjectSpecs::InstExec.class_variables.should include("@@count") From 10c990c4e5486cedea41fa2710cafbf156e50b28 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Wed, 16 Nov 2011 15:43:55 -0800 Subject: [PATCH 57/67] Add --disable-gems. Fixes #1299 --- kernel/loader.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/loader.rb b/kernel/loader.rb index 5069dca092..2a16e6d4d9 100644 --- a/kernel/loader.rb +++ b/kernel/loader.rb @@ -20,6 +20,8 @@ def initialize @simple_options = false @early_option_stop = false + @enable_gems = Rubinius.ruby19? + @gem_bin = File.join Rubinius::GEMS_PATH, "bin" end @@ -285,6 +287,12 @@ def options(argv=ARGV) $DEBUG = true end + if Rubinius.ruby19? + options.on "--disable-gems", "Do not automatically load rubygems on startup" do + @enable_gems = false + end + end + options.on "-e", "CODE", "Compile and execute CODE" do |code| @run_irb = false $0 = "(eval)" @@ -569,7 +577,7 @@ def agent def rubygems @stage = "loading Rubygems" - require "rubygems" if Rubinius.ruby19? + require "rubygems" if @enable_gems end # Require any -r arguments From 6f9bc2b1046efcb5ebc3f61b36a1b3bdefa71817 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Wed, 16 Nov 2011 16:37:58 -0800 Subject: [PATCH 58/67] Stop the world when seeding to traversing the heap. Fixes #1296 --- vm/builtin/find_object.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vm/builtin/find_object.cpp b/vm/builtin/find_object.cpp index 51c1c27fc3..1a4512f2fb 100644 --- a/vm/builtin/find_object.cpp +++ b/vm/builtin/find_object.cpp @@ -289,6 +289,10 @@ namespace rubinius { } } + // Because we're going to look at other threads CallFrame chains, we have + // to stop them first. + state->stop_the_world(); + state->set_call_frame(calling_environment); ObjectWalker walker(state->memory()); GCData gc_data(state->vm()); @@ -296,6 +300,9 @@ namespace rubinius { // Seed it with the root objects. walker.seed(gc_data); + // We've touched other threads now, so we can restart everyone. + state->restart_world(); + Object* obj = walker.next(); while(obj) { From ebf36eea9d1c2ff9fc09db7c86eede16e02fb801 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Wed, 16 Nov 2011 17:06:33 -0800 Subject: [PATCH 59/67] Handle autoloads when accessed via the CAPI. Fixes #1144 --- vm/capi/module.cpp | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/vm/capi/module.cpp b/vm/capi/module.cpp index ebb11519a3..183a453c72 100644 --- a/vm/capi/module.cpp +++ b/vm/capi/module.cpp @@ -1,6 +1,7 @@ #include "builtin/object.hpp" #include "builtin/module.hpp" #include "builtin/symbol.hpp" +#include "builtin/autoload.hpp" #include "helpers.hpp" #include "call_frame.hpp" @@ -50,9 +51,14 @@ extern "C" { bool found = false; Object* val = module->get_const(env->state(), name, &found); - if(found) return env->get_handle(val); - return const_missing(module_handle, id_name); + if(!found) return const_missing(module_handle, id_name); + + if(Autoload* autoload = try_as(val)) { + return capi_fast_call(env->get_handle(autoload), rb_intern("call"), 0); + } + + return env->get_handle(val); } VALUE rb_const_get_from(VALUE module_handle, ID id_name) { @@ -64,7 +70,13 @@ extern "C" { bool found = false; while(!module->nil_p()) { Object* val = module->get_const(env->state(), name, &found); - if(found) return env->get_handle(val); + if(found) { + if(Autoload* autoload = try_as(val)) { + return capi_fast_call(env->get_handle(autoload), rb_intern("call"), 0); + } + + return env->get_handle(val); + } module = module->superclass(); } @@ -81,7 +93,13 @@ extern "C" { bool found = false; while(!module->nil_p()) { Object* val = module->get_const(env->state(), name, &found); - if(found) return env->get_handle(val); + if(found) { + if(Autoload* autoload = try_as(val)) { + return capi_fast_call(env->get_handle(autoload), rb_intern("call"), 0); + } + + return env->get_handle(val); + } module = module->superclass(); } @@ -91,7 +109,13 @@ extern "C" { while(!module->nil_p()) { Object* val = module->get_const(env->state(), name, &found); - if(found) return env->get_handle(val); + if(found) { + if(Autoload* autoload = try_as(val)) { + return capi_fast_call(env->get_handle(autoload), rb_intern("call"), 0); + } + + return env->get_handle(val); + } module = module->superclass(); } From c9b5e18083672255b9c22b602e1191981db29df1 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 9 Nov 2011 20:43:35 -0800 Subject: [PATCH 60/67] Spec Complex#phase --- spec/ruby/core/complex/phase_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/ruby/core/complex/phase_spec.rb b/spec/ruby/core/complex/phase_spec.rb index 7116f027f8..648d283dd7 100644 --- a/spec/ruby/core/complex/phase_spec.rb +++ b/spec/ruby/core/complex/phase_spec.rb @@ -1,7 +1,8 @@ require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../../../shared/complex/arg', __FILE__) ruby_version_is "1.9" do describe "Complex#phase" do - it "needs to be reviewed for spec completeness" + it_behaves_like :complex_arg, :phase end end From e45b615ccd7736b91db784c366bf9129a0b9e2ea Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 9 Nov 2011 20:43:47 -0800 Subject: [PATCH 61/67] Alias Complex#phase to #arg --- kernel/common/complex.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/common/complex.rb b/kernel/common/complex.rb index 6a92cef370..59c6bbe4f5 100644 --- a/kernel/common/complex.rb +++ b/kernel/common/complex.rb @@ -251,7 +251,8 @@ def abs2 def arg Math.atan2(@imag, @real) end - alias angle arg + alias_method :angle, :arg + alias_method :phase, :arg # # Returns the absolute value _and_ the argument. From 9867a8f8b1e32e95617d50cbf32fd320f2530a74 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 9 Nov 2011 20:47:32 -0800 Subject: [PATCH 62/67] Spec Complex#imaginary --- spec/ruby/core/complex/imaginary_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/ruby/core/complex/imaginary_spec.rb b/spec/ruby/core/complex/imaginary_spec.rb index 5f1d0a24e1..3eafe6f2ea 100644 --- a/spec/ruby/core/complex/imaginary_spec.rb +++ b/spec/ruby/core/complex/imaginary_spec.rb @@ -1,7 +1,7 @@ -require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../../../shared/complex/image', __FILE__) ruby_version_is "1.9" do describe "Complex#imaginary" do - it "needs to be reviewed for spec completeness" + it_behaves_like :complex_image, :imaginary end end From 67f03e0600989d55524292116202ba7f72d71c78 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 16 Nov 2011 18:34:36 -0800 Subject: [PATCH 63/67] Clean up Float#arg/angle/phase spec and add them for 1.9 --- spec/ruby/core/float/angle_spec.rb | 4 +- spec/ruby/core/float/arg_spec.rb | 4 +- spec/ruby/core/float/phase_spec.rb | 4 +- spec/ruby/library/complex/float/angle_spec.rb | 9 ++++ spec/ruby/library/complex/float/arg_spec.rb | 9 ++++ spec/ruby/shared/complex/float/arg.rb | 42 +++++++++++++++++++ spec/ruby/shared/complex/numeric/arg.rb | 27 ++---------- 7 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 spec/ruby/library/complex/float/angle_spec.rb create mode 100644 spec/ruby/library/complex/float/arg_spec.rb create mode 100644 spec/ruby/shared/complex/float/arg.rb diff --git a/spec/ruby/core/float/angle_spec.rb b/spec/ruby/core/float/angle_spec.rb index 79563dee7d..f553f74344 100644 --- a/spec/ruby/core/float/angle_spec.rb +++ b/spec/ruby/core/float/angle_spec.rb @@ -1,7 +1,7 @@ -require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../../../shared/complex/float/arg', __FILE__) ruby_version_is "1.9" do describe "Float#angle" do - it "needs to be reviewed for spec completeness" + it_behaves_like :float_arg, :angle end end diff --git a/spec/ruby/core/float/arg_spec.rb b/spec/ruby/core/float/arg_spec.rb index e2ac77c62b..efcb6530d1 100644 --- a/spec/ruby/core/float/arg_spec.rb +++ b/spec/ruby/core/float/arg_spec.rb @@ -1,7 +1,7 @@ -require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../../../shared/complex/float/arg', __FILE__) ruby_version_is "1.9" do describe "Float#arg" do - it "needs to be reviewed for spec completeness" + it_behaves_like :float_arg, :arg end end diff --git a/spec/ruby/core/float/phase_spec.rb b/spec/ruby/core/float/phase_spec.rb index 699909f998..4cb0c21aa3 100644 --- a/spec/ruby/core/float/phase_spec.rb +++ b/spec/ruby/core/float/phase_spec.rb @@ -1,7 +1,7 @@ -require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../../../shared/complex/float/arg', __FILE__) ruby_version_is "1.9" do describe "Float#phase" do - it "needs to be reviewed for spec completeness" + it_behaves_like :float_arg, :phase end end diff --git a/spec/ruby/library/complex/float/angle_spec.rb b/spec/ruby/library/complex/float/angle_spec.rb new file mode 100644 index 0000000000..3863e61ce7 --- /dev/null +++ b/spec/ruby/library/complex/float/angle_spec.rb @@ -0,0 +1,9 @@ +require File.expand_path('../../../../shared/complex/float/arg', __FILE__) + +ruby_version_is ""..."1.9" do + require 'complex' + + describe "Float#angle" do + it_behaves_like :float_arg, :angle + end +end diff --git a/spec/ruby/library/complex/float/arg_spec.rb b/spec/ruby/library/complex/float/arg_spec.rb new file mode 100644 index 0000000000..9b66813403 --- /dev/null +++ b/spec/ruby/library/complex/float/arg_spec.rb @@ -0,0 +1,9 @@ +require File.expand_path('../../../../shared/complex/float/arg', __FILE__) + +ruby_version_is ""..."1.9" do + require 'complex' + + describe "Float#arg" do + it_behaves_like :float_arg, :arg + end +end diff --git a/spec/ruby/shared/complex/float/arg.rb b/spec/ruby/shared/complex/float/arg.rb new file mode 100644 index 0000000000..1a1fc95a5f --- /dev/null +++ b/spec/ruby/shared/complex/float/arg.rb @@ -0,0 +1,42 @@ +require File.expand_path('../../../../spec_helper', __FILE__) + +describe :float_arg, :shared => true do + ruby_bug "#1715", "1.8.6.369" do + it "returns NaN if NaN" do + f = nan_value + f.send(@method).nan?.should be_true + end + end + + ruby_version_is "1.9" do + it "returns self if NaN" do + f = nan_value + f.send(@method).should equal(f) + end + end + + it "returns 0 if positive" do + 1.0.send(@method).should == 0 + end + + it "returns 0 if +0.0" do + 0.0.send(@method).should == 0 + end + + it "returns 0 if +Infinity" do + infinity_value.send(@method).should == 0 + end + + it "returns Pi if negative" do + (-1.0).send(@method).should == Math::PI + end + + # This was established in r23960 + it "returns Pi if -0.0" do + (-0.0).send(@method).should == Math::PI + end + + it "returns Pi if -Infinity" do + (-infinity_value).send(@method).should == Math::PI + end +end diff --git a/spec/ruby/shared/complex/numeric/arg.rb b/spec/ruby/shared/complex/numeric/arg.rb index 1cf640974d..3b730e8bce 100644 --- a/spec/ruby/shared/complex/numeric/arg.rb +++ b/spec/ruby/shared/complex/numeric/arg.rb @@ -3,11 +3,10 @@ describe :numeric_arg, :shared => true do before(:each) do @numbers = [ - 20, # Integer - 398.72, # Float - Rational(3, 4), # Rational - 99999999**99, # Bignum - Float::MAX * 2, # Infinity + 20, + Rational(3, 4), + bignum_value, + infinity_value ] end @@ -17,27 +16,9 @@ end end - ruby_bug "#1715", "1.8.6.369" do - it "returns NaN if self is NaN" do - (-nan_value).send(@method).nan?.should be_true - nan_value.send(@method).nan?.should be_true - end - end - it "returns Pi if negative" do @numbers.each do |number| (0-number).send(@method).should == Math::PI end end - - # This was established in r23960 - it "returns Pi if -0.0" do - (-0.0).send(@method).should == Math::PI - end - - it "raises an ArgumentError if given any arguments" do - @numbers.each do |number| - lambda { number.send(@method, number) }.should raise_error(ArgumentError) - end - end end From e52fb78d5efeb340fffab5083ead8af71a3eed59 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 16 Nov 2011 18:58:19 -0800 Subject: [PATCH 64/67] Fix Float#arg/angle/phase --- kernel/common/float19.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/common/float19.rb b/kernel/common/float19.rb index 71d7512747..3c9533784e 100644 --- a/kernel/common/float19.rb +++ b/kernel/common/float19.rb @@ -33,4 +33,11 @@ def to_r (f * (RADIX ** e)).to_r end + + def arg + return self if nan? + super + end + alias_method :angle, :arg + alias_method :phase, :arg end From def4bc3a2e80c2c2b7aa4ec5c13926d4e05ba842 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 16 Nov 2011 19:06:45 -0800 Subject: [PATCH 65/67] Clean up Numeric#conj spec --- spec/ruby/shared/complex/numeric/conj.rb | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/spec/ruby/shared/complex/numeric/conj.rb b/spec/ruby/shared/complex/numeric/conj.rb index 45528c13f5..1ac6c59088 100644 --- a/spec/ruby/shared/complex/numeric/conj.rb +++ b/spec/ruby/shared/complex/numeric/conj.rb @@ -6,7 +6,7 @@ 20, # Integer 398.72, # Float Rational(3, 4), # Rational - 99999999**99, # Bignum + bignum_value, infinity_value, nan_value ] @@ -14,13 +14,7 @@ it "returns self" do @numbers.each do |number| - number.send(@method).to_s.should == number.to_s + number.send(@method).should equal(number) end end - - it "raises an ArgumentError if given any arguments" do - @numbers.each do |number| - lambda { number.send(@method, number) }.should raise_error(ArgumentError) - end - end end From 3c0c6531234b18780aabd73656ca52b78cbb79a1 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Wed, 16 Nov 2011 21:59:08 -0800 Subject: [PATCH 66/67] Speed up rb_cstr2inum and add Integer::from_cstr --- vm/builtin/integer.cpp | 204 +++++++++++++++++++++++++++++++++++++++++ vm/builtin/integer.hpp | 2 + vm/builtin/string.cpp | 196 +-------------------------------------- vm/capi/numeric.cpp | 14 ++- 4 files changed, 218 insertions(+), 198 deletions(-) diff --git a/vm/builtin/integer.cpp b/vm/builtin/integer.cpp index a9d7057e7d..2dbb0281d7 100644 --- a/vm/builtin/integer.cpp +++ b/vm/builtin/integer.cpp @@ -6,6 +6,8 @@ #include "builtin/bignum.hpp" #include "builtin/float.hpp" +#include "configuration.hpp" + namespace rubinius { native_int Integer::slow_to_native() { if(fixnum_p()) { @@ -102,5 +104,207 @@ namespace rubinius { return (Fixnum*)APPLY_FIXNUM_TAG((native_int)num); } + Integer* Integer::from_cstr(STATE, const char* str, int base, + Object* strict) + { + bool negative = false; + Integer* value = Fixnum::from(0); + + if(base == 1 || base > 36) return nil(); + // Strict mode can only be invoked from Ruby via Kernel#Integer() + // which does not allow bases other than 0. + if(base != 0 && strict == Qtrue && LANGUAGE_18_ENABLED(state)) + return nil(); + + // Skip any combination of leading whitespace and underscores. + // Leading whitespace is OK in strict mode, but underscores are not. + while(isspace(*str) || *str == '_') { + if(*str == '_' && strict == Qtrue) { + return nil(); + } else { + str++; + } + } + + if(*str == '-') { + str++; + negative = true; + } else if(*str == '+') { + str++; + } + + char chr; + int detected_base = 0; + const char* str_start = str; + + // Try and detect a base prefix on the front. We have to do this + // even though we might have been told the base, because we have + // to know if we should discard the bytes that make up the prefix + // if it's redundant with passed in base. + // + // For example, if base == 16 and str == "0xa", we return + // to return 10. But if base == 10 and str == "0xa", we fail + // because we rewind and try to process 0x as part of the + // base 10 string. + // + if(*str == '0') { + str++; + switch(chr = *str++) { + case 'b': case 'B': + detected_base = 2; + break; + case 'o': case 'O': + detected_base = 8; + break; + case 'd': case 'D': + detected_base = 10; + break; + case 'x': case 'X': + detected_base = 16; + break; + default: + // If passed "017" and a base of 0, that is octal 15. + // Otherwise, it is whatever those digits would be in the + // specified base. + str--; + detected_base = 8; + } + } + + // If base is less than 0, then it's just a hint for how to process it + // if there is no base detected. + if(base < 0) { + if(detected_base == 0) { + // Ok, no detected because, use the base hint and start over. + base = -base; + str = str_start; + } else { + base = detected_base; + } + + // If 0 was passed in as the base, we use the detected base. + } else if(base == 0) { + + // Default to 10 if there is no input and no detected base. + if(detected_base == 0) { + base = 10; + str = str_start; + + } else { + base = detected_base; + } + + // If the passed in base and the detected base contradict + // each other, then rewind and process the whole string as + // digits of the passed in base. + } else if(base != detected_base) { + // rewind the stream, and try and consume the prefix as + // digits in the number. + str = str_start; + } + + + bool underscore = false; + + while(*str) { + chr = *str++; + + // If we see space characters + if(chr == ' ' || chr == '\t' || chr == '\n' || chr == '\r') { + + // Eat them all + while(chr == ' ' || chr == '\t' || chr == '\n' || chr == '\r') { + chr = *str++; + } + + // If there is more stuff after the spaces, get out of dodge. + if(chr) { + if(strict == Qtrue) { + return nil(); + } else { + goto return_value; + } + } + + break; + } + + // If it's an underscore, remember that. An underscore is valid iff + // it followed by a valid character for this base. + if(chr == '_') { + if(underscore) { + // Double underscore is forbidden in strict mode. + if(strict == Qtrue) { + return nil(); + } else { + // Stop parse number after two underscores in a row + goto return_value; + } + } + underscore = true; + continue; + } else { + underscore = false; + } + + // We use A-Z (and a-z) here so we support up to base 36. + if(chr >= '0' && chr <= '9') { + chr -= '0'; + } else if(chr >= 'A' && chr <= 'Z') { + chr -= ('A' - 10); + } else if(chr >= 'a' && chr <= 'z') { + chr -= ('a' - 10); + } else { + //Invalid character, stopping right here. + if(strict == Qtrue) { + return nil(); + } else { + break; + } + } + + // Bail if the current chr is greater or equal to the base, + // mean it's invalid. + if(chr >= base) { + if(strict == Qtrue) { + return nil(); + } else { + break; + } + } + + if(value != Fixnum::from(0)) { + if(Fixnum *fix = try_as(value)) { + value = fix->mul(state, Fixnum::from(base)); + } else { + value = as(value)->mul(state, Fixnum::from(base)); + } + } + + if(Fixnum *fix = try_as(value)) { + value = fix->add(state, Fixnum::from(chr)); + } else { + value = as(value)->add(state, Fixnum::from(chr)); + } + } + + // If we last saw an underscore and we're strict, bail. + if(underscore && strict == Qtrue) { + return nil(); + } + +return_value: + if(negative) { + if(Fixnum* fix = try_as(value)) { + value = fix->neg(state); + } else { + value = as(value)->neg(state); + } + } + + return value; + + } + } diff --git a/vm/builtin/integer.hpp b/vm/builtin/integer.hpp index ffc471981c..31a653df4a 100644 --- a/vm/builtin/integer.hpp +++ b/vm/builtin/integer.hpp @@ -28,6 +28,8 @@ namespace rubinius { static Integer* from(STATE, long long i); static Integer* from(STATE, unsigned long long i); + static Integer* from_cstr(STATE, const char* str, int base, Object* strict); + long to_long(); unsigned long to_ulong(); long long to_long_long(); diff --git a/vm/builtin/string.cpp b/vm/builtin/string.cpp index 52277c7070..94c22f08b5 100644 --- a/vm/builtin/string.cpp +++ b/vm/builtin/string.cpp @@ -769,207 +769,13 @@ namespace rubinius { Integer* String::to_i(STATE, Fixnum* fix_base, Object* strict) { const char* str = c_str(state); int base = fix_base->to_native(); - bool negative = false; - Integer* value = Fixnum::from(0); if(strict == Qtrue) { // In strict mode the string can't have null bytes. if(size() > (native_int)strlen(str)) return nil(); } - if(base == 1 || base > 36) return nil(); - // Strict mode can only be invoked from Ruby via Kernel#Integer() - // which does not allow bases other than 0. - if(base != 0 && strict == Qtrue && LANGUAGE_18_ENABLED(state)) - return nil(); - - // Skip any combination of leading whitespace and underscores. - // Leading whitespace is OK in strict mode, but underscores are not. - while(isspace(*str) || *str == '_') { - if(*str == '_' && strict == Qtrue) { - return nil(); - } else { - str++; - } - } - - if(*str == '-') { - str++; - negative = true; - } else if(*str == '+') { - str++; - } - - char chr; - int detected_base = 0; - const char* str_start = str; - - // Try and detect a base prefix on the front. We have to do this - // even though we might have been told the base, because we have - // to know if we should discard the bytes that make up the prefix - // if it's redundant with passed in base. - // - // For example, if base == 16 and str == "0xa", we return - // to return 10. But if base == 10 and str == "0xa", we fail - // because we rewind and try to process 0x as part of the - // base 10 string. - // - if(*str == '0') { - str++; - switch(chr = *str++) { - case 'b': case 'B': - detected_base = 2; - break; - case 'o': case 'O': - detected_base = 8; - break; - case 'd': case 'D': - detected_base = 10; - break; - case 'x': case 'X': - detected_base = 16; - break; - default: - // If passed "017" and a base of 0, that is octal 15. - // Otherwise, it is whatever those digits would be in the - // specified base. - str--; - detected_base = 8; - } - } - - // If base is less than 0, then it's just a hint for how to process it - // if there is no base detected. - if(base < 0) { - if(detected_base == 0) { - // Ok, no detected because, use the base hint and start over. - base = -base; - str = str_start; - } else { - base = detected_base; - } - - // If 0 was passed in as the base, we use the detected base. - } else if(base == 0) { - - // Default to 10 if there is no input and no detected base. - if(detected_base == 0) { - base = 10; - str = str_start; - - } else { - base = detected_base; - } - - // If the passed in base and the detected base contradict - // each other, then rewind and process the whole string as - // digits of the passed in base. - } else if(base != detected_base) { - // rewind the stream, and try and consume the prefix as - // digits in the number. - str = str_start; - } - - - bool underscore = false; - - while(*str) { - chr = *str++; - - // If we see space characters - if(chr == ' ' || chr == '\t' || chr == '\n' || chr == '\r') { - - // Eat them all - while(chr == ' ' || chr == '\t' || chr == '\n' || chr == '\r') { - chr = *str++; - } - - // If there is more stuff after the spaces, get out of dodge. - if(chr) { - if(strict == Qtrue) { - return nil(); - } else { - goto return_value; - } - } - - break; - } - - // If it's an underscore, remember that. An underscore is valid iff - // it followed by a valid character for this base. - if(chr == '_') { - if(underscore) { - // Double underscore is forbidden in strict mode. - if(strict == Qtrue) { - return nil(); - } else { - // Stop parse number after two underscores in a row - goto return_value; - } - } - underscore = true; - continue; - } else { - underscore = false; - } - - // We use A-Z (and a-z) here so we support up to base 36. - if(chr >= '0' && chr <= '9') { - chr -= '0'; - } else if(chr >= 'A' && chr <= 'Z') { - chr -= ('A' - 10); - } else if(chr >= 'a' && chr <= 'z') { - chr -= ('a' - 10); - } else { - //Invalid character, stopping right here. - if(strict == Qtrue) { - return nil(); - } else { - break; - } - } - - // Bail if the current chr is greater or equal to the base, - // mean it's invalid. - if(chr >= base) { - if(strict == Qtrue) { - return nil(); - } else { - break; - } - } - - if(value != Fixnum::from(0)) { - if(Fixnum *fix = try_as(value)) { - value = fix->mul(state, Fixnum::from(base)); - } else { - value = as(value)->mul(state, Fixnum::from(base)); - } - } - - if(Fixnum *fix = try_as(value)) { - value = fix->add(state, Fixnum::from(chr)); - } else { - value = as(value)->add(state, Fixnum::from(chr)); - } - } - - // If we last saw an underscore and we're strict, bail. - if(underscore && strict == Qtrue) { - return nil(); - } - -return_value: - if(negative) { - if(Fixnum* fix = try_as(value)) { - value = fix->neg(state); - } else { - value = as(value)->neg(state); - } - } - - return value; + return Integer::from_cstr(state, str, base, strict); } Integer* String::to_inum_prim(STATE, Fixnum* base, Object* strict) { diff --git a/vm/capi/numeric.cpp b/vm/capi/numeric.cpp index 4489febfca..d8e99a65c7 100644 --- a/vm/capi/numeric.cpp +++ b/vm/capi/numeric.cpp @@ -2,6 +2,7 @@ #include "builtin/fixnum.hpp" #include "builtin/float.hpp" #include "builtin/object.hpp" +#include "builtin/integer.hpp" #include "object_utils.hpp" @@ -131,12 +132,19 @@ extern "C" { } VALUE rb_cstr2inum(const char* string, int base) { - return rb_str2inum(rb_str_new2(string), base); + NativeMethodEnvironment* env = NativeMethodEnvironment::get(); + Integer* i = Integer::from_cstr(env->state(), string, base, Qfalse); + return env->get_handle(i); } VALUE rb_cstr_to_inum(const char* str, int base, int badcheck) { - // TODO don't ignore badcheck - return rb_cstr2inum(str, base); + NativeMethodEnvironment* env = NativeMethodEnvironment::get(); + Integer* i = Integer::from_cstr(env->state(), str, base, + badcheck ? RBX_Qtrue : RBX_Qfalse); + if(i->nil_p()) { + rb_raise(rb_eArgError, "invalid string for Integer"); + } + return env->get_handle(i); } VALUE rb_ll2inum(long long val) { From 4f6ff1c6510ea647f330e77170907581575191ab Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Thu, 17 Nov 2011 14:20:02 +0100 Subject: [PATCH 67/67] Plug a memory leak in the parser that only seems to happen on OS X --- lib/ext/melbourne/grammar18.cpp | 14 +++++++------- lib/ext/melbourne/grammar18.y | 14 +++++++------- lib/ext/melbourne/parser_state18.hpp | 4 ++-- lib/ext/melbourne/quark.cpp | 22 +++++++++++----------- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/lib/ext/melbourne/grammar18.cpp b/lib/ext/melbourne/grammar18.cpp index dd2c53c6da..e65501461d 100644 --- a/lib/ext/melbourne/grammar18.cpp +++ b/lib/ext/melbourne/grammar18.cpp @@ -489,8 +489,8 @@ rb_parser_state *parser_alloc_state() { magic_comments = new std::vector; start_lines = new std::list; - quark_indexes = quark_map(); - quarks = quark_vector(); + quark_indexes = new quark_map(); + quarks = new quark_vector(); return parser_state; } @@ -543,12 +543,12 @@ void pt_free(rb_parser_state *parser_state) { delete magic_comments; delete start_lines; - if(!memory_pools) return; - - for(i = 0; i <= current_pool; i++) { - free(memory_pools[i]); + if(memory_pools) { + for(i = 0; i <= current_pool; i++) { + free(memory_pools[i]); + } + free(memory_pools); } - free(memory_pools); quark_cleanup(parser_state); diff --git a/lib/ext/melbourne/grammar18.y b/lib/ext/melbourne/grammar18.y index e58f790e74..8e8a0329bb 100644 --- a/lib/ext/melbourne/grammar18.y +++ b/lib/ext/melbourne/grammar18.y @@ -218,8 +218,8 @@ rb_parser_state *parser_alloc_state() { magic_comments = new std::vector; start_lines = new std::list; - quark_indexes = quark_map(); - quarks = quark_vector(); + quark_indexes = new quark_map(); + quarks = new quark_vector(); return parser_state; } @@ -272,12 +272,12 @@ void pt_free(rb_parser_state *parser_state) { delete magic_comments; delete start_lines; - if(!memory_pools) return; - - for(i = 0; i <= current_pool; i++) { - free(memory_pools[i]); + if(memory_pools) { + for(i = 0; i <= current_pool; i++) { + free(memory_pools[i]); + } + free(memory_pools); } - free(memory_pools); quark_cleanup(parser_state); diff --git a/lib/ext/melbourne/parser_state18.hpp b/lib/ext/melbourne/parser_state18.hpp index 171d91f82e..8056c0b043 100644 --- a/lib/ext/melbourne/parser_state18.hpp +++ b/lib/ext/melbourne/parser_state18.hpp @@ -108,8 +108,8 @@ typedef VALUE stack_type; std::list* start_lines; // Tracks quarks - quark_map quark_indexes; - quark_vector quarks; + quark_map* quark_indexes; + quark_vector* quarks; } rb_parser_state; diff --git a/lib/ext/melbourne/quark.cpp b/lib/ext/melbourne/quark.cpp index 688e05db36..cf9f85c828 100644 --- a/lib/ext/melbourne/quark.cpp +++ b/lib/ext/melbourne/quark.cpp @@ -12,31 +12,31 @@ quark melbourne::grammar18::quark_from_string(rb_parser_state* parser_state, con } /* attempt to find it in our cache */ - quark_map::iterator it = quark_indexes.find(str); - if (it != quark_indexes.end()) { + quark_map::iterator it = quark_indexes->find(str); + if (it != quark_indexes->end()) { return it->second; } /* otherwise, we need to duplicate and store the string */ const char* new_quark = strdup(str); - quarks.push_back(new_quark); - size_t index = quarks.size() - 1; - quark_indexes.insert(quark_map::value_type(new_quark,index)); + quarks->push_back(new_quark); + size_t index = quarks->size() - 1; + quark_indexes->insert(quark_map::value_type(new_quark,index)); return index; } const char* melbourne::grammar18::quark_to_string(rb_parser_state* parser_state, quark q) { - if (q >= quarks.size()) + if (q >= quarks->size()) return NULL; - return quarks[q]; + return quarks->at(q); } void melbourne::grammar18::quark_cleanup(rb_parser_state* parser_state) { + delete quark_indexes; - for (quark_map::iterator it = quark_indexes.begin(); it != quark_indexes.end(); ++it) { - free((char *)it->first); + for (quark_vector::iterator it = quarks->begin(); it != quarks->end(); ++it) { + free((char *)*it); } - quark_indexes.clear(); - quarks.clear(); + delete quarks; }