diff --git a/README b/README index aeaba7d..4501164 100644 --- a/README +++ b/README @@ -3,7 +3,7 @@ libyaml binding for ruby. == Example require 'yaml/libyaml' - + yobj = YAML::LibYAML.load_file('example.yaml') YAML::LibYAML.dump(yobj) #=> yaml format string diff --git a/ext/yaml/construct.c b/ext/yaml/construct.c index 3e04e18..876b922 100644 --- a/ext/yaml/construct.c +++ b/ext/yaml/construct.c @@ -57,45 +57,45 @@ static VALUE wrap_rb_utf8_str_new(const char* str, long length) { static VALUE is_valid_string_as(const char* str, const char** pattern, int length) { int i; - + for (i = 0; i < length; i++) { if (strcmp(str, pattern[i]) == 0) { return Qtrue; } } - + return Qfalse; } static VALUE get_fixed_value_by_name(const char* str) { const char* ptr = NULL; const char* head = NULL; - + if (str == NULL) { return Qundef; } - + if (is_valid_as(str, VALID_NULL_STRINGS)) { return Qnil; } if (is_valid_as(str, VALID_TRUE_STRINGS)) { return Qtrue; } - + if (is_valid_as(str, VALID_FALSE_STRINGS)) { return Qfalse; } - + if (is_valid_as(str, VALID_NAN_STRINGS)) { return rb_float_new(NOT_A_NUMBER); } - + head = str; ptr = (*head == '+' || *head == '-') ? head + 1 : head; if (is_valid_as(ptr, VALID_INFINITY_STRINGS)) { return rb_float_new(*head == '-' ? NEGATIVE_INFINITY : POSITIVE_INFINITY); } - + return Qundef; } @@ -103,16 +103,16 @@ static VALUE get_fixnum_by_regexp(VALUE rstring) { if ( rb_reg_match(rb_const_get(mLibYAML, rb_intern("OCT_REGEX")), rstring) != Qnil ) { return rb_str_to_inum(rstring, 8, Qfalse); } - + if ( rb_reg_match(rb_const_get(mLibYAML, rb_intern("HEX_REGEX")), rstring) != Qnil ) { return rb_str_to_inum(rstring, 16, Qfalse); } - + if ( rb_reg_match(rb_const_get(mLibYAML, rb_intern("NUM_REGEX")), rstring) != Qnil ) { const char* str = RSTRING_PTR(rstring); return (strchr(str, '.') == NULL && strchr(str, 'e') == NULL && strchr(str, 'E') == NULL ) ? rb_str_to_inum(rstring, 10, Qfalse) : rb_Float(rstring); } - + return Qundef; } @@ -120,14 +120,14 @@ static VALUE get_symbol(VALUE rstring) { const char* pattern = "^:.+$"; const VALUE regexp = rb_reg_new(pattern, strlen(pattern), 0); const char* str; - + if (rb_reg_match(regexp, rstring) == Qnil) { return Qundef; } - + str = RSTRING_PTR(rstring); str++; /* length of rstring is determined more than 2 bytes, as it matches regexp above */ - + return ID2SYM(rb_intern(str)); } @@ -137,14 +137,14 @@ static VALUE construct_scalar_node(yaml_document_t* document, yaml_node_t* node) size_t length; VALUE rstring = Qundef; yaml_scalar_style_t style = node->data.scalar.style; - + str = (const char*)(node->data.scalar.value); length = node->data.scalar.length; - + if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE || style == YAML_DOUBLE_QUOTED_SCALAR_STYLE) { goto DEFAULT; } - + value = get_fixed_value_by_name(str); if (value != Qundef) { return value; @@ -156,12 +156,12 @@ static VALUE construct_scalar_node(yaml_document_t* document, yaml_node_t* node) if (value != Qundef) { return value; } - + value = get_fixnum_by_regexp(rstring); if (value != Qundef) { return value; } - + DEFAULT: if (rstring == Qundef) { rstring = wrap_rb_utf8_str_new(str, length); @@ -175,7 +175,7 @@ static VALUE construct_sequence_node(yaml_document_t* document, yaml_node_t* nod yaml_node_item_t* item; VALUE results; int i; - + results = rb_ary_new2(top - start); i = 0; for (item = start; item < top; item++) { @@ -183,7 +183,7 @@ static VALUE construct_sequence_node(yaml_document_t* document, yaml_node_t* nod rb_ary_store(results, i, elements); i++; } - + return results; } @@ -192,14 +192,14 @@ static VALUE construct_mapping_node(yaml_document_t* document, yaml_node_t* node yaml_node_pair_t* top = node->data.mapping.pairs.top; yaml_node_pair_t* pair; VALUE results; - + results = rb_hash_new(); for (pair = start; pair < top; pair++) { VALUE key = construct_node(document, yaml_document_get_node(document, pair->key)); VALUE value = construct_node(document, yaml_document_get_node(document, pair->value)); rb_hash_aset(results, key, value); } - + return results; } diff --git a/ext/yaml/libyaml.c b/ext/yaml/libyaml.c index 5ca483f..c9591e6 100644 --- a/ext/yaml/libyaml.c +++ b/ext/yaml/libyaml.c @@ -38,21 +38,21 @@ void Init_native() const char* oct_reg_char = "^0[0-7]+$"; rb_define_const(mLibYAML, "OCT_REGEX", rb_reg_new(oct_reg_char, strlen(oct_reg_char), 0)); - + const char* hex_reg_char = "^0x[0-9a-fA-F]+"; rb_define_const(mLibYAML, "HEX_REGEX", rb_reg_new(hex_reg_char, strlen(hex_reg_char), 0)); const char* num_reg_char = "^(\\+|-)?([0-9][0-9\\._]*)([eE][\\+-]?\\d+)?$"; rb_define_const(mLibYAML, "NUM_REGEX", rb_reg_new(num_reg_char, strlen(num_reg_char), 0)); - + rb_define_singleton_method(mLibYAML, "load", rb_libyaml_load, 1); rb_define_singleton_method(mLibYAML, "load_file", rb_libyaml_load_file, 1); rb_define_singleton_method(mLibYAML, "load_stream", rb_libyaml_load_stream, 1); rb_define_singleton_method(mLibYAML, "dump", rb_libyaml_dump, 1); - + cLoader = rb_define_class_under(mLibYAML, "Loader", rb_cObject); rb_define_alloc_func(cLoader, loader_alloc); - + cStream = rb_define_class_under(mLibYAML, "Stream", rb_cObject); rb_define_attr(cStream, "documents", TRUE, TRUE); } @@ -83,13 +83,13 @@ static VALUE destroy_context(VALUE loader) { yaml_parser_delete(context->parser); context->parser = NULL; } - + if (context->source_type == STREAM) { if (context->source.stream.close_on_exit && context->source.stream.io != NULL) { context->source.stream.io = NULL; } } - + return Qtrue; } @@ -102,14 +102,14 @@ static VALUE load_single_document(ParsingContext* context) { if (!yaml_parser_load(context->parser, &document)) { return Qundef; /* TODO raise exception */ } - + root = yaml_document_get_root_node(&document); if (root == NULL) { return Qundef; } results = construct_node(&document, root); - + yaml_document_delete(&document); return results; } @@ -122,7 +122,7 @@ static VALUE load_documents(VALUE loader) { ParsingContext* context; Data_Get_Struct(loader, ParsingContext, context); - + parser = context->parser; switch (context->source_type) { case STRING: @@ -132,11 +132,11 @@ static VALUE load_documents(VALUE loader) { yaml_parser_set_input_file(parser, context->source.stream.io); break; } - + if (!context->parse_all_documents) { return load_single_document(context); } - + results = rb_ary_new(); while (TRUE) { doc = load_single_document(context); @@ -145,7 +145,7 @@ static VALUE load_documents(VALUE loader) { } rb_ary_push(results, doc); } - + documents = rb_class_new_instance(0, NULL, cStream); rb_funcall(documents, rb_intern("documents="), 1, results); return documents; @@ -157,7 +157,7 @@ static VALUE load_documents(VALUE loader) { static VALUE rb_libyaml_load(VALUE self, VALUE rstr) { VALUE loader; ParsingContext* context; - + loader = rb_class_new_instance(0, NULL, cLoader); Data_Get_Struct(loader, ParsingContext, context); @@ -177,7 +177,7 @@ static VALUE rb_libyaml_load(VALUE self, VALUE rstr) { context->source.stream.close_on_exit = FALSE; break; } - + default: rb_raise(rb_eTypeError, "1st argument must be String or IO instances"); } @@ -190,7 +190,7 @@ static VALUE rb_libyaml_load_file(VALUE self, VALUE filename) { VALUE loader; const char* name; FILE* file; - + /* parameter filename must be a string object */ Check_Type(filename, T_STRING); @@ -199,24 +199,24 @@ static VALUE rb_libyaml_load_file(VALUE self, VALUE filename) { if (!file) { rb_sys_fail(name); } - + loader = rb_class_new_instance(0, NULL, cLoader); Data_Get_Struct(loader, ParsingContext, context); - + context->source_type = STREAM; context->source.stream.io = file; context->source.stream.close_on_exit = TRUE; - + return rb_ensure(load_documents, loader, destroy_context, loader); } static VALUE rb_libyaml_load_stream(VALUE self, VALUE obj) { ParsingContext* context; VALUE loader; - + loader = rb_class_new_instance(0, NULL, cLoader); Data_Get_Struct(loader, ParsingContext, context); - + switch (TYPE(obj)) { case T_STRING: context->source_type = STRING; @@ -233,12 +233,12 @@ static VALUE rb_libyaml_load_stream(VALUE self, VALUE obj) { context->source.stream.close_on_exit = FALSE; break; } - + default: rb_raise(rb_eTypeError, "1st argument must be String or IO instances"); } context->parse_all_documents = TRUE; - + return rb_ensure(load_documents, loader, destroy_context, loader); } @@ -260,12 +260,12 @@ static FILE* get_iostream(VALUE io) { if (rfile == NULL) { return NULL; } - + open_file = rfile->fptr; if (open_file == NULL) { return NULL; } - + #ifdef RUBY_IO_H return rb_io_stdio_file(open_file); #else diff --git a/ext/yaml/libyaml.h b/ext/yaml/libyaml.h index 26da7a2..824386c 100644 --- a/ext/yaml/libyaml.h +++ b/ext/yaml/libyaml.h @@ -23,9 +23,9 @@ typedef enum { typedef struct { yaml_parser_t* parser; - + InputSourceType source_type; - + union { struct { const unsigned char* str; @@ -36,11 +36,11 @@ typedef struct { FILE* io; BOOL close_on_exit; } stream; - + } source; - + BOOL parse_all_documents; - + } ParsingContext; diff --git a/lib/yaml/libyaml/version.rb b/lib/yaml/libyaml/version.rb index 200097e..c9e3682 100644 --- a/lib/yaml/libyaml/version.rb +++ b/lib/yaml/libyaml/version.rb @@ -4,7 +4,7 @@ module Version MAJOR = 0 MINOR = 0 TINY = 1 - + class << self def to_version [ MAJOR, MINOR, TINY ].join('.') diff --git a/spec/construct_spec.rb b/spec/construct_spec.rb index d3d09eb..878ad9a 100644 --- a/spec/construct_spec.rb +++ b/spec/construct_spec.rb @@ -9,7 +9,7 @@ YAML::LibYAML.load(str).should be_nan end end - + ['.inf', '.Inf', '.INF', '+.inf', '+.Inf', '+.INF'].each do |str| it "should interpret '#{str}' as positive infinity" do YAML::LibYAML.load(str).should be_infinite @@ -21,19 +21,19 @@ YAML::LibYAML.load(str).infinite?.should == -1 end end - + ['~', 'null', 'Null', 'NULL'].each do |str| it "should interpret '#{str}' as nil" do YAML::LibYAML.load(str).should be_nil end end - + ['true', 'True', 'TRUE'].each do |str| it "should interpret '#{str}' as true" do YAML::LibYAML.load(str).should be_true end end - + ['false', 'False', 'FALSE'].each do |str| it "should interpret '#{str}' as false" do YAML::LibYAML.load(str).should be_false @@ -57,7 +57,7 @@ YAML::LibYAML.load(input).should == expect end end - + { ':symbol' => :symbol, ':123' => :"123", diff --git a/spec/libyaml_spec.rb b/spec/libyaml_spec.rb index b4ced18..975ccd1 100644 --- a/spec/libyaml_spec.rb +++ b/spec/libyaml_spec.rb @@ -7,9 +7,9 @@ require File.join(File.dirname(__FILE__), 'spec_helper') describe YAML::LibYAML do - + NON_STRING_OBJECTS = [ nil, 1, 1.23, :filename, ['filename'], {:filename => 'minimum-valid-example.yaml'} ] - + # # Examples which cause some kind of exceptions, while calling YAML::LibYAML.load_file() # @@ -19,7 +19,7 @@ lambda { YAML::LibYAML.load_file(1) }.should raise_error(TypeError) end end - + it 'should raise exception if specified file does not exist' do lambda { YAML::LibYAML.load_file('no-such-file.yaml') }.should raise_error(Errno::ENOENT) end @@ -35,7 +35,7 @@ results.should == 123 end end - + # # Examples which cause some kind of exceptions, while calling YAML::LibYAML.load() @@ -47,7 +47,7 @@ end end end - + # # These are minimum examples, just to check if #load can parse valid YAML expressions. # See construct_spec.rb for parsing and construction details. @@ -56,7 +56,7 @@ it 'should parse strings passed as an argument, into Ruby objects' do YAML::LibYAML.load('123').should == 123 end - + it 'should read stream and parse its contents into Ruby objects' do open(get_pathname('minimum-valid-example.yaml')) { |io| YAML::LibYAML.load(io) }.should == 123 end