Skip to content

Commit

Permalink
* ext/psych/lib/psych/syntax_error.rb: Add file, line, offset, and
Browse files Browse the repository at this point in the history
  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
  • Loading branch information
tenderlove committed Oct 4, 2011
1 parent 77e58a3 commit 137c547
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 6 deletions.
8 changes: 8 additions & 0 deletions ChangeLog
@@ -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>

* ext/psych/parser.c (parse): Use context_mark for indicating error
Expand Down
18 changes: 18 additions & 0 deletions ext/psych/lib/psych/syntax_error.rb
@@ -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
27 changes: 21 additions & 6 deletions ext/psych/parser.c
Expand Up @@ -59,6 +59,23 @@ static VALUE allocate(VALUE klass)
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)
Expand Down Expand Up @@ -98,21 +115,18 @@ static VALUE parse(VALUE self, VALUE yaml)

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) {
Expand Down Expand Up @@ -376,6 +390,7 @@ void Init_psych_parser()
/* 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);
Expand Down
15 changes: 15 additions & 0 deletions test/psych/test_exception.rb
Expand Up @@ -16,6 +16,21 @@ def setup
@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
Expand Down

0 comments on commit 137c547

Please sign in to comment.