[macruby-changes] [2181] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Mon Aug 3 10:45:58 PDT 2009


Revision: 2181
          http://trac.macosforge.org/projects/ruby/changeset/2181
Author:   pthomson at apple.com
Date:     2009-08-03 10:45:58 -0700 (Mon, 03 Aug 2009)
Log Message:
-----------
Added parser error handling, and made almost all of the YAML::load specs pass (one is waiting on Date, and one was marked non-compliant, as LibYAML is stricter than Syck.

Modified Paths:
--------------
    MacRuby/branches/experimental/ext/libyaml/rubyext.c
    MacRuby/branches/experimental/lib/yaml/rubytypes.rb
    MacRuby/branches/experimental/spec/frozen/library/yaml/load_spec.rb
    MacRuby/branches/experimental/spec/frozen/tags/macruby/library/yaml/load_tags.txt

Modified: MacRuby/branches/experimental/ext/libyaml/rubyext.c
===================================================================
--- MacRuby/branches/experimental/ext/libyaml/rubyext.c	2009-08-03 17:45:56 UTC (rev 2180)
+++ MacRuby/branches/experimental/ext/libyaml/rubyext.c	2009-08-03 17:45:58 UTC (rev 2181)
@@ -33,8 +33,7 @@
 static VALUE rb_cNode;
 static VALUE rb_cSeqNode;
 static VALUE rb_cMapNode;
-static VALUE rb_cScalar;
-static VALUE rb_cOut;
+static VALUE rb_cScalarNode;
 
 static ID id_plain;
 static ID id_quote2;
@@ -43,8 +42,6 @@
 static ID id_node_id_ivar;
 static ID id_document_ivar;
 
-static SEL selToYAML;
-
 static VALUE rb_oDefaultResolver;
 
 static VALUE
@@ -94,6 +91,36 @@
 }
 
 static VALUE
+rb_yaml_parser_error(VALUE self, SEL sel)
+{
+	yaml_parser_t *parser;
+	Data_Get_Struct(self, yaml_parser_t, parser);
+	VALUE error = Qnil;
+	char *msg = NULL;
+	switch(parser->error)
+	{
+		case YAML_SCANNER_ERROR:
+		case YAML_PARSER_ERROR:
+		{
+			asprintf(&msg, "syntax error on line %d, col %d: %s", parser->problem_mark.line,
+				parser->problem_mark.column, parser->problem);
+			error = rb_exc_new2(rb_eArgError, msg);
+		}
+		
+		case YAML_NO_ERROR:
+		break;
+		
+		default:
+		error = rb_exc_new2(rb_eRuntimeError, parser->problem);
+	}
+	if(msg != NULL)
+	{
+		free(msg);
+	}
+	return error;
+}
+
+static VALUE
 rb_yaml_parser_initialize(VALUE self, SEL sel, int argc, VALUE *argv)
 {
 	VALUE input = Qnil;
@@ -108,7 +135,9 @@
 	yaml_parser_t *parser;
 	Data_Get_Struct(self, yaml_parser_t, parser);
 	yaml_document_t *document = ALLOC(yaml_document_t);
-	yaml_parser_load(parser, document);
+	if(yaml_parser_load(parser, document) == 0) {
+		rb_exc_raise(rb_yaml_parser_error(self, sel));
+	}
 	return Data_Wrap_Struct(rb_cDocument, NULL, NULL, document);
 }
 
@@ -208,6 +237,14 @@
 }
 
 static VALUE
+rb_yaml_document_empty_p(VALUE self, SEL sel)
+{
+	yaml_document_t *document;
+	Data_Get_Struct(self, yaml_document_t, document);
+	return (yaml_document_get_root_node(document) == NULL) ? Qtrue : Qfalse;
+}
+
+static VALUE
 rb_yaml_document_implicit_start_p(VALUE self, SEL sel)
 {
 	yaml_document_t *document;
@@ -306,9 +343,23 @@
 rb_yaml_guess_type_of_plain_node(yaml_node_t *node)
 {
 	const char* v = (char*) node->data.scalar.value;
-	if ((strcmp(v, "true") == 0) || (strcmp(v, "false") == 0))
+	if (node->data.scalar.length == 0)
 	{
-		node->tag = "tag:yaml.org,2002:bool";
+		node->tag = (yaml_char_t*)"tag:yaml.org,2002:null";
+	}
+	// holy cow, this is not a good solution at all.
+	// i should incorporate rb_cstr_to_inum here, or something.
+	else if (strtol(v, NULL, 10) != 0)
+	{
+		node->tag = (yaml_char_t*)"tag:yaml.org,2002:int";
+	}
+	else if (*v == ':')
+	{
+		node->tag = (yaml_char_t*)"tag:ruby.yaml.org,2002:symbol";
+	}
+	else if ((strcmp(v, "true") == 0) || (strcmp(v, "false") == 0))
+	{
+		node->tag = (yaml_char_t*)"tag:yaml.org,2002:bool";
 	} 
 }
 
@@ -387,7 +438,12 @@
 	{
 		yaml_document_t *document;
 		Data_Get_Struct(obj, yaml_document_t, document);
-		return rb_yaml_resolve_node(document->nodes.start, document, tags);
+		yaml_node_t *root = yaml_document_get_root_node(document);
+		if (root == NULL)
+		{
+			return Qnil;
+		}
+		return rb_yaml_resolve_node(root, document, tags);
 	}
 	return Qnil;
 }
@@ -508,6 +564,7 @@
 	rb_objc_define_method(rb_cDocument, "scalar", rb_yaml_document_add_scalar, 3);
 	//rb_objc_define_method(rb_cDocument, "[]", rb_yaml_document_aref, 1);
 	//rb_objc_define_method(rb_cDocument, "version", rb_yaml_document_version, 0);
+	rb_objc_define_method(rb_cDocument, "empty?", rb_yaml_document_empty_p, 0);
 	rb_objc_define_method(rb_cDocument, "implicit_start?", rb_yaml_document_implicit_start_p, 0);
 	rb_objc_define_method(rb_cDocument, "implicit_end?", rb_yaml_document_implicit_end_p, 0);
 	//rb_objc_define_method(rb_cDocument, "implicit_start=", rb_yaml_document_implicit_start_set, 1);
@@ -533,6 +590,8 @@
 	rb_cMapNode = rb_define_class_under(rb_mLibYAML, "Map", rb_cNode);
 	rb_objc_define_method(rb_cMapNode, "add", rb_mapping_node_add, 2);
 	
+	rb_cScalarNode = rb_define_class_under(rb_mLibYAML, "Scalar", rb_cNode);
+	
 	rb_cResolver = rb_define_class_under(rb_mLibYAML, "Resolver", rb_cObject);
 	rb_define_attr(rb_cResolver, "tags", 1, 1);
 	rb_objc_define_method(rb_cResolver, "initialize", rb_yaml_resolver_initialize, 0);

Modified: MacRuby/branches/experimental/lib/yaml/rubytypes.rb
===================================================================
--- MacRuby/branches/experimental/lib/yaml/rubytypes.rb	2009-08-03 17:45:56 UTC (rev 2180)
+++ MacRuby/branches/experimental/lib/yaml/rubytypes.rb	2009-08-03 17:45:58 UTC (rev 2181)
@@ -111,6 +111,16 @@
   end
 end
 
+class Symbol
+  yaml_as "tag:ruby.yaml.org,2002:symbol"
+  
+  def self.yaml_new(val); val[1..-1].to_sym; end
+  
+  def to_yaml(out)
+    out.scalar(taguri, self.to_s[1..-1], :plain)
+  end
+end
+
 class Regexp
   yaml_as "tag:ruby.yaml.org,2002:regexp"
   def to_yaml(out)
@@ -121,6 +131,9 @@
 
 class NilClass 
   yaml_as "tag:yaml.org,2002:null"
+  
+  def self.yaml_new(val); nil; end
+  
 	def to_yaml(out)
     out.scalar(taguri, "", :plain)
 	end
@@ -128,6 +141,9 @@
 
 class TrueClass
   yaml_as "tag:yaml.org,2002:bool"
+  
+  def self.yaml_new(val); true; end
+  
   def to_yaml(out)
     out.scalar(taguri, "true", :plain)
   end
@@ -135,15 +151,14 @@
 
 class FalseClass
   yaml_as "tag:yaml.org,2002:bool"
+  
+  def self.yaml_new(val); false; end
+  
   def to_yaml(out)
     out.scalar(taguri, "false", :plain)
   end
 end
 
-YAML::LibYAML::DEFAULT_RESOLVER.tags["tag:yaml.org,2002:bool"] = lambda {
-  |value|
-  value == "true"
-}
 
 =begin
 

Modified: MacRuby/branches/experimental/spec/frozen/library/yaml/load_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/frozen/library/yaml/load_spec.rb	2009-08-03 17:45:56 UTC (rev 2180)
+++ MacRuby/branches/experimental/spec/frozen/library/yaml/load_spec.rb	2009-08-03 17:45:58 UTC (rev 2181)
@@ -41,7 +41,7 @@
   it "accepts symbols" do
     YAML.load( "--- :locked" ).should == :locked
   end
-
+  
   it "accepts numbers" do
     YAML.load("47").should == 47
     YAML.load("-1").should == -1
@@ -59,19 +59,21 @@
     YAML.load("--- ---\n").should == "---"
     YAML.load("--- abc").should == "abc"
   end
-
-  it "does not escape symbols" do
-    YAML.load("foobar: >= 123").should == { "foobar" => ">= 123"}
-    YAML.load("foobar: |= 567").should == { "foobar" => "|= 567"}
-    YAML.load("--- \n*.rb").should == "*.rb"
-    YAML.load("--- \n&.rb").should == "&.rb"
+  
+  not_compliant_on :macruby do
+    it "does not escape symbols" do
+      YAML.load("foobar: >= 123").should == { "foobar" => ">= 123"}
+      YAML.load("foobar: |= 567").should == { "foobar" => "|= 567"}
+      YAML.load("--- \n*.rb").should == "*.rb"
+      YAML.load("--- \n&.rb").should == "&.rb"
+    end
   end
 
   it "works with block sequence shortcuts" do
     block_seq = "- - - one\n    - two\n    - three"
     YAML.load(block_seq).should == [[["one", "two", "three"]]]
   end
-
+  
   it "works on complex keys" do
     expected = { 
       [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ],
@@ -81,7 +83,7 @@
     }
     YAML.load($complex_key_1).should == expected
   end
-  
+
   it "loads a symbol key that contains spaces" do
     string = ":user name: This is the user name."
     expected = { :"user name" => "This is the user name."}

Modified: MacRuby/branches/experimental/spec/frozen/tags/macruby/library/yaml/load_tags.txt
===================================================================
--- MacRuby/branches/experimental/spec/frozen/tags/macruby/library/yaml/load_tags.txt	2009-08-03 17:45:56 UTC (rev 2180)
+++ MacRuby/branches/experimental/spec/frozen/tags/macruby/library/yaml/load_tags.txt	2009-08-03 17:45:58 UTC (rev 2181)
@@ -1 +1 @@
-critical:YAML.load fails on invalid keys
+fails:YAML.load works on complex keys
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090803/8ea17e45/attachment.html>


More information about the macruby-changes mailing list