* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33404 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
77e58a3398
commit
137c547c3e
@ -1,3 +1,11 @@
|
|||||||
|
Wed Oct 5 02:50:27 2011 Aaron Patterson <aaron@tenderlovemaking.com>
|
||||||
|
|
||||||
|
* 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@tenderlovemaking.com>
|
Wed Oct 5 01:52:16 2011 Aaron Patterson <aaron@tenderlovemaking.com>
|
||||||
|
|
||||||
* ext/psych/parser.c (parse): Use context_mark for indicating error
|
* ext/psych/parser.c (parse): Use context_mark for indicating error
|
||||||
|
18
ext/psych/lib/psych/syntax_error.rb
Normal file
18
ext/psych/lib/psych/syntax_error.rb
Normal file
@ -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
|
@ -59,6 +59,23 @@ static VALUE allocate(VALUE klass)
|
|||||||
return Data_Wrap_Struct(klass, 0, dealloc, parser);
|
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:
|
* call-seq:
|
||||||
* parser.parse(yaml)
|
* parser.parse(yaml)
|
||||||
@ -98,21 +115,18 @@ static VALUE parse(VALUE self, VALUE yaml)
|
|||||||
|
|
||||||
while(!done) {
|
while(!done) {
|
||||||
if(!yaml_parser_parse(parser, &event)) {
|
if(!yaml_parser_parse(parser, &event)) {
|
||||||
VALUE path;
|
VALUE path, exception;
|
||||||
size_t line = parser->context_mark.line + 1;
|
|
||||||
size_t column = parser->context_mark.column + 1;
|
|
||||||
|
|
||||||
if(rb_respond_to(yaml, id_path))
|
if(rb_respond_to(yaml, id_path))
|
||||||
path = rb_funcall(yaml, id_path, 0);
|
path = rb_funcall(yaml, id_path, 0);
|
||||||
else
|
else
|
||||||
path = rb_str_new2("<unknown>");
|
path = rb_str_new2("<unknown>");
|
||||||
|
|
||||||
|
exception = make_exception(parser, path);
|
||||||
yaml_parser_delete(parser);
|
yaml_parser_delete(parser);
|
||||||
yaml_parser_initialize(parser);
|
yaml_parser_initialize(parser);
|
||||||
|
|
||||||
rb_raise(ePsychSyntaxError, "(%s): couldn't parse YAML at line %d column %d",
|
rb_exc_raise(exception);
|
||||||
StringValuePtr(path),
|
|
||||||
(int)line, (int)column);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
@ -376,6 +390,7 @@ void Init_psych_parser()
|
|||||||
/* UTF-16-BE Encoding with BOM */
|
/* UTF-16-BE Encoding with BOM */
|
||||||
rb_define_const(cPsychParser, "UTF16BE", INT2NUM(YAML_UTF16BE_ENCODING));
|
rb_define_const(cPsychParser, "UTF16BE", INT2NUM(YAML_UTF16BE_ENCODING));
|
||||||
|
|
||||||
|
rb_require("psych/syntax_error");
|
||||||
ePsychSyntaxError = rb_define_class_under(mPsych, "SyntaxError", rb_eSyntaxError);
|
ePsychSyntaxError = rb_define_class_under(mPsych, "SyntaxError", rb_eSyntaxError);
|
||||||
|
|
||||||
rb_define_method(cPsychParser, "parse", parse, 1);
|
rb_define_method(cPsychParser, "parse", parse, 1);
|
||||||
|
@ -16,6 +16,21 @@ module Psych
|
|||||||
@wups = Wups.new
|
@wups = Wups.new
|
||||||
end
|
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
|
def test_convert
|
||||||
w = Psych.load(Psych.dump(@wups))
|
w = Psych.load(Psych.dump(@wups))
|
||||||
assert_equal @wups, w
|
assert_equal @wups, w
|
||||||
|
Loading…
x
Reference in New Issue
Block a user