ruby-changes:21355
From: tenderlove <ko1@a...>
Date: Wed, 5 Oct 2011 02:54:26 +0900 (JST)
Subject: [ruby-changes:21355] tenderlove:r33404 (trunk): * ext/psych/lib/psych/syntax_error.rb: Add file, line, offset, and
tenderlove 2011-10-05 02:53:41 +0900 (Wed, 05 Oct 2011) New Revision: 33404 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33404 Log: * ext/psych/lib/psych/syntax_error.rb: Add file, line, offset, and message attributes during parse failure. * ext/psych/parser.c: Update parser to raise exception with correct values. * test/psych/test_exception.rb: corresponding tests. Added files: trunk/ext/psych/lib/psych/syntax_error.rb Modified files: trunk/ChangeLog trunk/ext/psych/parser.c trunk/test/psych/test_exception.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 33403) +++ ChangeLog (revision 33404) @@ -1,3 +1,11 @@ +Wed Oct 5 02:50:27 2011 Aaron Patterson <aaron@t...> + + * ext/psych/lib/psych/syntax_error.rb: Add file, line, offset, and + message attributes during parse failure. + * ext/psych/parser.c: Update parser to raise exception with correct + values. + * test/psych/test_exception.rb: corresponding tests. + Wed Oct 5 01:52:16 2011 Aaron Patterson <aaron@t...> * ext/psych/parser.c (parse): Use context_mark for indicating error Index: ext/psych/lib/psych/syntax_error.rb =================================================================== --- ext/psych/lib/psych/syntax_error.rb (revision 0) +++ ext/psych/lib/psych/syntax_error.rb (revision 33404) @@ -0,0 +1,18 @@ +module Psych + class SyntaxError < ::SyntaxError + attr_reader :file, :line, :column, :offset, :problem, :context + + def initialize file, line, col, offset, problem, context + err = [problem, context].compact.join ' ' + message = "(%s): %s at line %d column %d" % [file, err, line, col] + + @file = file + @line = line + @column = col + @offset = offset + @problem = problem + @context = context + super(message) + end + end +end Index: ext/psych/parser.c =================================================================== --- ext/psych/parser.c (revision 33403) +++ ext/psych/parser.c (revision 33404) @@ -59,6 +59,23 @@ return Data_Wrap_Struct(klass, 0, dealloc, parser); } +static VALUE make_exception(yaml_parser_t * parser, VALUE path) +{ + VALUE exception; + size_t line, column; + + line = parser->context_mark.line + 1; + column = parser->context_mark.column + 1; + + return rb_funcall(ePsychSyntaxError, rb_intern("new"), 6, + path, + INT2NUM(line), + INT2NUM(column), + INT2NUM(parser->problem_offset), + parser->problem ? rb_usascii_str_new2(parser->problem) : Qnil, + parser->context ? rb_usascii_str_new2(parser->context) : Qnil); +} + /* * call-seq: * parser.parse(yaml) @@ -98,21 +115,18 @@ while(!done) { if(!yaml_parser_parse(parser, &event)) { - VALUE path; - size_t line = parser->context_mark.line + 1; - size_t column = parser->context_mark.column + 1; + VALUE path, exception; if(rb_respond_to(yaml, id_path)) path = rb_funcall(yaml, id_path, 0); else path = rb_str_new2("<unknown>"); + exception = make_exception(parser, path); yaml_parser_delete(parser); yaml_parser_initialize(parser); - rb_raise(ePsychSyntaxError, "(%s): couldn't parse YAML at line %d column %d", - StringValuePtr(path), - (int)line, (int)column); + rb_exc_raise(exception); } switch(event.type) { @@ -376,6 +390,7 @@ /* UTF-16-BE Encoding with BOM */ rb_define_const(cPsychParser, "UTF16BE", INT2NUM(YAML_UTF16BE_ENCODING)); + rb_require("psych/syntax_error"); ePsychSyntaxError = rb_define_class_under(mPsych, "SyntaxError", rb_eSyntaxError); rb_define_method(cPsychParser, "parse", parse, 1); Index: test/psych/test_exception.rb =================================================================== --- test/psych/test_exception.rb (revision 33403) +++ test/psych/test_exception.rb (revision 33404) @@ -16,6 +16,21 @@ @wups = Wups.new end + def test_attributes + e = assert_raises(Psych::SyntaxError) { + Psych.load '--- `foo' + } + + assert_equal '<unknown>', e.file + assert_equal 1, e.line + assert_equal 5, e.column + # FIXME: offset isn't being set correctly by libyaml + # assert_equal 5, e.offset + + assert e.problem + assert e.context + end + def test_convert w = Psych.load(Psych.dump(@wups)) assert_equal @wups, w -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/