diff options
-rw-r--r-- | ext/psych/emitter.c | 6 | ||||
-rw-r--r-- | ext/psych/extconf.rb | 2 | ||||
-rw-r--r-- | ext/psych/parser.c | 44 | ||||
-rw-r--r-- | lib/psych/parser.rb | 10 | ||||
-rw-r--r-- | test/psych/test_parser.rb | 7 |
5 files changed, 48 insertions, 21 deletions
diff --git a/ext/psych/emitter.c b/ext/psych/emitter.c index 14ed6d0..194e732 100644 --- a/ext/psych/emitter.c +++ b/ext/psych/emitter.c @@ -5,7 +5,7 @@ VALUE cPsychEmitter; static void emit(yaml_emitter_t * emitter, yaml_event_t * event) { if(!yaml_emitter_emit(emitter, event)) - rb_raise(rb_eRuntimeError, emitter->problem); + rb_raise(rb_eRuntimeError, "%s", emitter->problem); } static int writer(void *ctx, unsigned char *buffer, size_t size) @@ -97,8 +97,8 @@ static VALUE start_document(VALUE self, VALUE version, VALUE tags, VALUE imp) rb_raise(rb_eRuntimeError, "tag tuple must be of length 2"); } - tail->handle = StringValuePtr(RARRAY_PTR(tuple)[0]); - tail->prefix = StringValuePtr(RARRAY_PTR(tuple)[1]); + tail->handle = (yaml_char_t *)StringValuePtr(RARRAY_PTR(tuple)[0]); + tail->prefix = (yaml_char_t *)StringValuePtr(RARRAY_PTR(tuple)[1]); tail++; } diff --git a/ext/psych/extconf.rb b/ext/psych/extconf.rb index cfada39..5da916b 100644 --- a/ext/psych/extconf.rb +++ b/ext/psych/extconf.rb @@ -1,5 +1,7 @@ require 'mkmf' +RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC'] + $CFLAGS << ' -O3 -Wall -Wcast-qual -Wwrite-strings -Wconversion' << ' -Wmissing-noreturn -Winline' diff --git a/ext/psych/parser.c b/ext/psych/parser.c index 6fe4a67..c51f45c 100644 --- a/ext/psych/parser.c +++ b/ext/psych/parser.c @@ -3,18 +3,46 @@ VALUE cPsychParser; VALUE ePsychSyntaxError; -static VALUE parse_string(VALUE self, VALUE string) +static int io_reader(void * data, unsigned char *buf, size_t size, size_t *read) +{ + VALUE io = (VALUE)data; + VALUE string = rb_funcall(io, rb_intern("read"), 1, INT2NUM(size)); + + *read = 0; + + if(! NIL_P(string)) { + *read = (size_t)RSTRING_LEN(string); + memcpy(buf, StringValuePtr(string), *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; yaml_parser_initialize(&parser); - yaml_parser_set_input_string( - &parser, - (const unsigned char *)StringValuePtr(string), - (size_t)RSTRING_LEN(string) - ); + if(rb_respond_to(yaml, rb_intern("read"))) { + yaml_parser_set_input(&parser, io_reader, (void *)yaml); + } else { + yaml_parser_set_input_string( + &parser, + (const unsigned char *)StringValuePtr(yaml), + (size_t)RSTRING_LEN(yaml) + ); + } int done = 0; @@ -27,7 +55,7 @@ static VALUE parse_string(VALUE self, VALUE string) yaml_parser_delete(&parser); rb_raise(ePsychSyntaxError, "couldn't parse YAML at line %d column %d", - line, column); + (int)line, (int)column); } switch(event.type) { @@ -168,5 +196,5 @@ void Init_psych_parser() cPsychParser = rb_define_class_under(mPsych, "Parser", rb_cObject); ePsychSyntaxError = rb_define_class_under(mPsych, "SyntaxError", rb_eSyntaxError); - rb_define_private_method(cPsychParser, "parse_string", parse_string, 1); + rb_define_method(cPsychParser, "parse", parse, 1); } diff --git a/lib/psych/parser.rb b/lib/psych/parser.rb index caa544c..0e38a4a 100644 --- a/lib/psych/parser.rb +++ b/lib/psych/parser.rb @@ -40,15 +40,5 @@ module Psych def initialize handler = Handler.new @handler = handler end - - ### - # 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 - - def parse yaml - parse_string string - end end end diff --git a/test/psych/test_parser.rb b/test/psych/test_parser.rb index 9c257a3..d6d81ef 100644 --- a/test/psych/test_parser.rb +++ b/test/psych/test_parser.rb @@ -25,6 +25,13 @@ module Psych @parser = Psych::Parser.new EventCatcher.new end + def test_parse_io + @parser.parse StringIO.new("--- a") + assert_called :start_stream + assert_called :scalar + assert_called :end_stream + end + def test_syntax_error assert_raises(Psych::SyntaxError) do @parser.parse("---\n\"foo\"\n\"bar\"\n") |