psych 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -1,3 +1,9 @@
1
1
  rvm:
2
2
  - 1.9.2
3
3
  - 1.9.3
4
+ - ruby-head
5
+ before_script:
6
+ - gem install isolate
7
+ - gem install hoe
8
+ - gem install rake-compiler
9
+ script: rake isolate test
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,129 @@
1
+ Fri Mar 9 06:29:22 2012 Aaron Patterson <aaron@tenderlovemaking.com>
2
+
3
+ * ext/psych/lib/psych.rb (load, parse): stop parsing or loading after
4
+ the first document has been parsed.
5
+
6
+ * test/psych/test_stream.rb: pertinent tests.
7
+
8
+ Fri Mar 9 06:17:05 2012 Aaron Patterson <aaron@tenderlovemaking.com>
9
+
10
+ * ext/psych/lib/psych.rb (parse_stream, load_stream): if a block is
11
+ given, documents will be yielded to the block as they are parsed.
12
+ [ruby-core:42404] [Bug #5978]
13
+
14
+ * ext/psych/lib/psych/handlers/document_stream.rb: add a handler that
15
+ yields documents as they are parsed
16
+
17
+ * test/psych/test_stream.rb: corresponding tests.
18
+
19
+ Tue Mar 6 02:31:20 2012 Aaron Patterson <aaron@tenderlovemaking.com>
20
+
21
+ * ext/psych/lib/psych/core_ext.rb: only extend Kernel if IRB is loaded
22
+ in order to stop method pollution.
23
+
24
+ Tue Feb 28 10:28:51 2012 Aaron Patterson <aaron@tenderlovemaking.com>
25
+
26
+ * ext/psych/lib/psych.rb: default open YAML files with utf8 external
27
+ encoding. [ruby-core:42967]
28
+ * test/psych/test_tainted.rb: ditto
29
+
30
+ Fri Feb 24 13:54:33 2012 Aaron Patterson <aaron@tenderlovemaking.com>
31
+
32
+ * ext/psych/parser.c: prevent a memory leak by protecting calls to
33
+ handler callbacks.
34
+ * test/psych/test_parser.rb: test to demonstrate leak.
35
+
36
+ Fri Feb 24 08:08:38 2012 Aaron Patterson <aaron@tenderlovemaking.com>
37
+
38
+ * ext/psych/parser.c: set parser encoding based on the YAML input
39
+ rather than user configuration.
40
+ * test/psych/test_encoding.rb: corresponding tests.
41
+ * test/psych/test_parser.rb: ditto
42
+ * test/psych/test_tainted.rb: ditto
43
+
44
+ Fri Feb 10 03:41:31 2012 Aaron Patterson <aaron@tenderlovemaking.com>
45
+
46
+ * ext/psych/parser.c: removed external encoding setter, allow parser
47
+ to be reused.
48
+ * ext/psych/lib/psych/parser.rb: added external encoding setter.
49
+ * test/psych/test_parser.rb: test parser reuse
50
+
51
+ Wed Jan 18 12:49:15 2012 Aaron Patterson <aaron@tenderlovemaking.com>
52
+
53
+ * ext/psych/lib/psych/visitors/to_ruby.rb: Added support for loading
54
+ subclasses of String with ivars
55
+ * ext/psych/lib/psych/visitors/yaml_tree.rb: Added support for dumping
56
+ subclasses of String with ivars
57
+ * test/psych/test_string.rb: corresponding tests
58
+
59
+ Sun Dec 18 12:42:48 2011 Aaron Patterson <aaron@tenderlovemaking.com>
60
+
61
+ * ext/psych/lib/psych/visitors/to_ruby.rb: BigDecimals can be restored
62
+ from YAML.
63
+ * ext/psych/lib/psych/visitors/yaml_tree.rb: BigDecimals can be dumped
64
+ to YAML.
65
+ * test/psych/test_numeric.rb: tests for BigDecimal serialization
66
+
67
+ Sun Dec 18 12:03:13 2011 Aaron Patterson <aaron@tenderlovemaking.com>
68
+
69
+ * ext/psych/lib/psych/scalar_scanner.rb: Strings that look like dates
70
+ should be treated as strings and not dates.
71
+
72
+ * test/psych/test_scalar_scanner.rb: corresponding tests.
73
+
74
+ Wed Dec 7 08:04:31 2011 Aaron Patterson <aaron@tenderlovemaking.com>
75
+
76
+ * ext/psych/lib/psych.rb (module Psych): parse and load methods take
77
+ an optional file name that is used when raising Psych::SyntaxError
78
+ exceptions
79
+ * ext/psych/lib/psych/syntax_error.rb (module Psych): allow nil file
80
+ names and handle nil file names in the exception message
81
+ * test/psych/test_exception.rb (module Psych): Tests for changes.
82
+
83
+ Wed Nov 30 09:09:37 2011 Aaron Patterson <aaron@tenderlovemaking.com>
84
+
85
+ * ext/psych/parser.c (parse): parse method can take an option file
86
+ name for use in exception messages.
87
+ * test/psych/test_parser.rb: corresponding tests.
88
+
89
+ Tue Nov 22 04:46:22 2011 Aaron Patterson <aaron@tenderlovemaking.com>
90
+
91
+ * ext/psych/lib/psych.rb: remove autoload from psych
92
+ * ext/psych/lib/psych/json.rb: ditto
93
+
94
+ Thu Nov 17 10:36:46 2011 Aaron Patterson <aaron@tenderlovemaking.com>
95
+
96
+ * ext/psych/lib/psych.rb (load_file): make sure opened yaml files are
97
+ also closed. [ruby-core:41088]
98
+
99
+ Wed Nov 9 04:52:16 2011 Aaron Patterson <aaron@tenderlovemaking.com>
100
+
101
+ * ext/psych/lib/psych/tree_builder.rb: dump complex numbers,
102
+ rationals, etc with reference ids.
103
+ * ext/psych/lib/psych/visitors/yaml_tree.rb: ditto
104
+ * ext/psych/lib/psych/visitors/to_ruby.rb: loading complex numbers,
105
+ rationals, etc with reference ids.
106
+ * test/psych/test_object_references.rb: corresponding tests
107
+
108
+ Mon Nov 7 20:31:52 2011 Aaron Patterson <aaron@tenderlovemaking.com>
109
+
110
+ * ext/psych/lib/psych/scalar_scanner.rb: make sure strings that look
111
+ like base 60 numbers are serialized as quoted strings.
112
+ * test/psych/test_string.rb: test for change.
113
+
114
+ Wed Oct 5 02:50:27 2011 Aaron Patterson <aaron@tenderlovemaking.com>
115
+
116
+ * ext/psych/lib/psych/syntax_error.rb: Add file, line, offset, and
117
+ message attributes during parse failure.
118
+ * ext/psych/parser.c: Update parser to raise exception with correct
119
+ values.
120
+ * test/psych/test_exception.rb: corresponding tests.
121
+
122
+ Wed Oct 5 01:52:16 2011 Aaron Patterson <aaron@tenderlovemaking.com>
123
+
124
+ * ext/psych/parser.c (parse): Use context_mark for indicating error
125
+ line and column.
126
+
1
127
  Tue Oct 4 06:29:55 2011 Aaron Patterson <aaron@tenderlovemaking.com>
2
128
 
3
129
  * ext/psych/lib/psych.rb: calling `yaml` rather than `to_yaml`.
data/Manifest.txt CHANGED
@@ -1,7 +1,6 @@
1
1
  .autotest
2
2
  .travis.yml
3
3
  CHANGELOG.rdoc
4
- Gemfile
5
4
  Manifest.txt
6
5
  README.rdoc
7
6
  Rakefile
@@ -21,7 +20,7 @@ lib/psych/coder.rb
21
20
  lib/psych/core_ext.rb
22
21
  lib/psych/deprecated.rb
23
22
  lib/psych/handler.rb
24
- lib/psych/json.rb
23
+ lib/psych/handlers/document_stream.rb
25
24
  lib/psych/json/ruby_events.rb
26
25
  lib/psych/json/stream.rb
27
26
  lib/psych/json/tree_builder.rb
@@ -40,6 +39,7 @@ lib/psych/scalar_scanner.rb
40
39
  lib/psych/set.rb
41
40
  lib/psych/stream.rb
42
41
  lib/psych/streaming.rb
42
+ lib/psych/syntax_error.rb
43
43
  lib/psych/tree_builder.rb
44
44
  lib/psych/visitors.rb
45
45
  lib/psych/visitors/depth_first.rb
@@ -70,6 +70,7 @@ test/psych/test_nil.rb
70
70
  test/psych/test_null.rb
71
71
  test/psych/test_numeric.rb
72
72
  test/psych/test_object.rb
73
+ test/psych/test_object_references.rb
73
74
  test/psych/test_omap.rb
74
75
  test/psych/test_parser.rb
75
76
  test/psych/test_psych.rb
data/README.rdoc CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  == Description
6
6
 
7
- Psych is a YAML parser and emitter. Psych leverages libyaml[http://libyaml.org]
7
+ Psych is a YAML parser and emitter. Psych leverages libyaml[http://pyyaml.org/wiki/LibYAML]
8
8
  for its YAML parsing and emitting capabilities. In addition to wrapping
9
9
  libyaml, Psych also knows how to serialize and de-serialize most Ruby objects
10
10
  to and from the YAML format.
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ end
11
11
  gem 'rake-compiler', '>= 0.4.1'
12
12
  require "rake/extensiontask"
13
13
 
14
- Hoe.plugin :debugging, :doofus, :git, :gemspec, :bundler
14
+ Hoe.plugin :doofus, :git, :gemspec, :isolate
15
15
 
16
16
  $hoe = Hoe.spec 'psych' do
17
17
  developer 'Aaron Patterson', 'aaron@tenderlovemaking.com'
data/ext/psych/emitter.c CHANGED
@@ -351,7 +351,7 @@ static VALUE start_mapping(
351
351
  (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)),
352
352
  (yaml_char_t *)(NIL_P(tag) ? NULL : StringValuePtr(tag)),
353
353
  implicit ? 1 : 0,
354
- (yaml_sequence_style_t)NUM2INT(style)
354
+ (yaml_mapping_style_t)NUM2INT(style)
355
355
  );
356
356
 
357
357
  emit(emitter, &event);
data/ext/psych/parser.c CHANGED
@@ -59,6 +59,163 @@ static VALUE allocate(VALUE klass)
59
59
  return Data_Wrap_Struct(klass, 0, dealloc, parser);
60
60
  }
61
61
 
62
+ static VALUE make_exception(yaml_parser_t * parser, VALUE path)
63
+ {
64
+ size_t line, column;
65
+
66
+ line = parser->context_mark.line + 1;
67
+ column = parser->context_mark.column + 1;
68
+
69
+ return rb_funcall(ePsychSyntaxError, rb_intern("new"), 6,
70
+ path,
71
+ INT2NUM(line),
72
+ INT2NUM(column),
73
+ INT2NUM(parser->problem_offset),
74
+ parser->problem ? rb_usascii_str_new2(parser->problem) : Qnil,
75
+ parser->context ? rb_usascii_str_new2(parser->context) : Qnil);
76
+ }
77
+
78
+ #ifdef HAVE_RUBY_ENCODING_H
79
+ static VALUE transcode_string(VALUE src, int * parser_encoding)
80
+ {
81
+ int utf8 = rb_utf8_encindex();
82
+ int utf16le = rb_enc_find_index("UTF16_LE");
83
+ int utf16be = rb_enc_find_index("UTF16_BE");
84
+ int source_encoding = rb_enc_get_index(src);
85
+
86
+ if (source_encoding == utf8) {
87
+ *parser_encoding = YAML_UTF8_ENCODING;
88
+ return src;
89
+ }
90
+
91
+ if (source_encoding == utf16le) {
92
+ *parser_encoding = YAML_UTF16LE_ENCODING;
93
+ return src;
94
+ }
95
+
96
+ if (source_encoding == utf16be) {
97
+ *parser_encoding = YAML_UTF16BE_ENCODING;
98
+ return src;
99
+ }
100
+
101
+ src = rb_str_export_to_enc(src, rb_utf8_encoding());
102
+ RB_GC_GUARD(src);
103
+
104
+ *parser_encoding = YAML_UTF8_ENCODING;
105
+ return src;
106
+ }
107
+
108
+ static VALUE transcode_io(VALUE src, int * parser_encoding)
109
+ {
110
+ VALUE io_external_encoding;
111
+ int io_external_enc_index;
112
+
113
+ io_external_encoding = rb_funcall(src, rb_intern("external_encoding"), 0);
114
+
115
+ /* if no encoding is returned, assume ascii8bit. */
116
+ if (NIL_P(io_external_encoding)) {
117
+ io_external_enc_index = rb_ascii8bit_encindex();
118
+ } else {
119
+ io_external_enc_index = rb_to_encoding_index(io_external_encoding);
120
+ }
121
+
122
+ /* Treat US-ASCII as utf_8 */
123
+ if (io_external_enc_index == rb_usascii_encindex()) {
124
+ *parser_encoding = YAML_UTF8_ENCODING;
125
+ return src;
126
+ }
127
+
128
+ if (io_external_enc_index == rb_utf8_encindex()) {
129
+ *parser_encoding = YAML_UTF8_ENCODING;
130
+ return src;
131
+ }
132
+
133
+ if (io_external_enc_index == rb_enc_find_index("UTF-16LE")) {
134
+ *parser_encoding = YAML_UTF16LE_ENCODING;
135
+ return src;
136
+ }
137
+
138
+ if (io_external_enc_index == rb_enc_find_index("UTF-16BE")) {
139
+ *parser_encoding = YAML_UTF16BE_ENCODING;
140
+ return src;
141
+ }
142
+
143
+ /* Just guess on ASCII-8BIT */
144
+ if (io_external_enc_index == rb_ascii8bit_encindex()) {
145
+ *parser_encoding = YAML_ANY_ENCODING;
146
+ return src;
147
+ }
148
+
149
+ rb_raise(rb_eArgError, "YAML file must be UTF-8, UTF-16LE, or UTF-16BE, not %s",
150
+ rb_enc_name(rb_enc_from_index(io_external_enc_index)));
151
+
152
+ return Qnil;
153
+ }
154
+
155
+ #endif
156
+
157
+ static VALUE protected_start_stream(VALUE pointer)
158
+ {
159
+ VALUE *args = (VALUE *)pointer;
160
+ return rb_funcall(args[0], id_start_stream, 1, args[1]);
161
+ }
162
+
163
+ static VALUE protected_start_document(VALUE pointer)
164
+ {
165
+ VALUE *args = (VALUE *)pointer;
166
+ return rb_funcall3(args[0], id_start_document, 3, args + 1);
167
+ }
168
+
169
+ static VALUE protected_end_document(VALUE pointer)
170
+ {
171
+ VALUE *args = (VALUE *)pointer;
172
+ return rb_funcall(args[0], id_end_document, 1, args[1]);
173
+ }
174
+
175
+ static VALUE protected_alias(VALUE pointer)
176
+ {
177
+ VALUE *args = (VALUE *)pointer;
178
+ return rb_funcall(args[0], id_alias, 1, args[1]);
179
+ }
180
+
181
+ static VALUE protected_scalar(VALUE pointer)
182
+ {
183
+ VALUE *args = (VALUE *)pointer;
184
+ return rb_funcall3(args[0], id_scalar, 6, args + 1);
185
+ }
186
+
187
+ static VALUE protected_start_sequence(VALUE pointer)
188
+ {
189
+ VALUE *args = (VALUE *)pointer;
190
+ return rb_funcall3(args[0], id_start_sequence, 4, args + 1);
191
+ }
192
+
193
+ static VALUE protected_end_sequence(VALUE handler)
194
+ {
195
+ return rb_funcall(handler, id_end_sequence, 0);
196
+ }
197
+
198
+ static VALUE protected_start_mapping(VALUE pointer)
199
+ {
200
+ VALUE *args = (VALUE *)pointer;
201
+ return rb_funcall3(args[0], id_start_mapping, 4, args + 1);
202
+ }
203
+
204
+ static VALUE protected_end_mapping(VALUE handler)
205
+ {
206
+ return rb_funcall(handler, id_end_mapping, 0);
207
+ }
208
+
209
+ static VALUE protected_empty(VALUE handler)
210
+ {
211
+ return rb_funcall(handler, id_empty, 0);
212
+ }
213
+
214
+ static VALUE protected_end_stream(VALUE handler)
215
+ {
216
+ return rb_funcall(handler, id_end_stream, 0);
217
+ }
218
+
62
219
  /*
63
220
  * call-seq:
64
221
  * parser.parse(yaml)
@@ -68,27 +225,48 @@ static VALUE allocate(VALUE klass)
68
225
  *
69
226
  * See Psych::Parser and Psych::Parser#handler
70
227
  */
71
- static VALUE parse(VALUE self, VALUE yaml)
228
+ static VALUE parse(int argc, VALUE *argv, VALUE self)
72
229
  {
230
+ VALUE yaml, path;
73
231
  yaml_parser_t * parser;
74
232
  yaml_event_t event;
75
233
  int done = 0;
76
234
  int tainted = 0;
235
+ int state = 0;
236
+ int parser_encoding = YAML_ANY_ENCODING;
77
237
  #ifdef HAVE_RUBY_ENCODING_H
78
238
  int encoding = rb_utf8_encindex();
79
239
  rb_encoding * internal_enc = rb_default_internal_encoding();
80
240
  #endif
81
241
  VALUE handler = rb_iv_get(self, "@handler");
82
242
 
243
+ if (rb_scan_args(argc, argv, "11", &yaml, &path) == 1) {
244
+ if(rb_respond_to(yaml, id_path))
245
+ path = rb_funcall(yaml, id_path, 0);
246
+ else
247
+ path = rb_str_new2("<unknown>");
248
+ }
249
+
83
250
  Data_Get_Struct(self, yaml_parser_t, parser);
84
251
 
252
+ yaml_parser_delete(parser);
253
+ yaml_parser_initialize(parser);
254
+
85
255
  if (OBJ_TAINTED(yaml)) tainted = 1;
86
256
 
87
- if(rb_respond_to(yaml, id_read)) {
257
+ if (rb_respond_to(yaml, id_read)) {
258
+ #ifdef HAVE_RUBY_ENCODING_H
259
+ yaml = transcode_io(yaml, &parser_encoding);
260
+ yaml_parser_set_encoding(parser, parser_encoding);
261
+ #endif
88
262
  yaml_parser_set_input(parser, io_reader, (void *)yaml);
89
263
  if (RTEST(rb_obj_is_kind_of(yaml, rb_cIO))) tainted = 1;
90
264
  } else {
91
265
  StringValue(yaml);
266
+ #ifdef HAVE_RUBY_ENCODING_H
267
+ yaml = transcode_string(yaml, &parser_encoding);
268
+ yaml_parser_set_encoding(parser, parser_encoding);
269
+ #endif
92
270
  yaml_parser_set_input_string(
93
271
  parser,
94
272
  (const unsigned char *)RSTRING_PTR(yaml),
@@ -98,32 +276,28 @@ static VALUE parse(VALUE self, VALUE yaml)
98
276
 
99
277
  while(!done) {
100
278
  if(!yaml_parser_parse(parser, &event)) {
101
- VALUE path;
102
- size_t line = parser->mark.line;
103
- size_t column = parser->mark.column;
104
-
105
- if(rb_respond_to(yaml, id_path))
106
- path = rb_funcall(yaml, id_path, 0);
107
- else
108
- path = rb_str_new2("<unknown>");
279
+ VALUE exception;
109
280
 
281
+ exception = make_exception(parser, path);
110
282
  yaml_parser_delete(parser);
111
283
  yaml_parser_initialize(parser);
112
284
 
113
- rb_raise(ePsychSyntaxError, "(%s): couldn't parse YAML at line %d column %d",
114
- StringValuePtr(path),
115
- (int)line, (int)column);
285
+ rb_exc_raise(exception);
116
286
  }
117
287
 
118
288
  switch(event.type) {
119
- case YAML_STREAM_START_EVENT:
120
-
121
- rb_funcall(handler, id_start_stream, 1,
122
- INT2NUM((long)event.data.stream_start.encoding)
123
- );
124
- break;
289
+ case YAML_STREAM_START_EVENT:
290
+ {
291
+ VALUE args[2];
292
+
293
+ args[0] = handler;
294
+ args[1] = INT2NUM((long)event.data.stream_start.encoding);
295
+ rb_protect(protected_start_stream, (VALUE)args, &state);
296
+ }
297
+ break;
125
298
  case YAML_DOCUMENT_START_EVENT:
126
299
  {
300
+ VALUE args[4];
127
301
  /* Get a list of tag directives (if any) */
128
302
  VALUE tag_directives = rb_ary_new();
129
303
  /* Grab the document version */
@@ -161,19 +335,25 @@ static VALUE parse(VALUE self, VALUE yaml)
161
335
  rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix));
162
336
  }
163
337
  }
164
- rb_funcall(handler, id_start_document, 3,
165
- version, tag_directives,
166
- event.data.document_start.implicit == 1 ? Qtrue : Qfalse
167
- );
338
+ args[0] = handler;
339
+ args[1] = version;
340
+ args[2] = tag_directives;
341
+ args[3] = event.data.document_start.implicit == 1 ? Qtrue : Qfalse;
342
+ rb_protect(protected_start_document, (VALUE)args, &state);
168
343
  }
169
344
  break;
170
345
  case YAML_DOCUMENT_END_EVENT:
171
- rb_funcall(handler, id_end_document, 1,
172
- event.data.document_end.implicit == 1 ? Qtrue : Qfalse
173
- );
346
+ {
347
+ VALUE args[2];
348
+
349
+ args[0] = handler;
350
+ args[1] = event.data.document_end.implicit == 1 ? Qtrue : Qfalse;
351
+ rb_protect(protected_end_document, (VALUE)args, &state);
352
+ }
174
353
  break;
175
354
  case YAML_ALIAS_EVENT:
176
355
  {
356
+ VALUE args[2];
177
357
  VALUE alias = Qnil;
178
358
  if(event.data.alias.anchor) {
179
359
  alias = rb_str_new2((const char *)event.data.alias.anchor);
@@ -183,11 +363,14 @@ static VALUE parse(VALUE self, VALUE yaml)
183
363
  #endif
184
364
  }
185
365
 
186
- rb_funcall(handler, id_alias, 1, alias);
366
+ args[0] = handler;
367
+ args[1] = alias;
368
+ rb_protect(protected_alias, (VALUE)args, &state);
187
369
  }
188
370
  break;
189
371
  case YAML_SCALAR_EVENT:
190
372
  {
373
+ VALUE args[7];
191
374
  VALUE anchor = Qnil;
192
375
  VALUE tag = Qnil;
193
376
  VALUE plain_implicit, quoted_implicit, style;
@@ -225,12 +408,19 @@ static VALUE parse(VALUE self, VALUE yaml)
225
408
 
226
409
  style = INT2NUM((long)event.data.scalar.style);
227
410
 
228
- rb_funcall(handler, id_scalar, 6,
229
- val, anchor, tag, plain_implicit, quoted_implicit, style);
411
+ args[0] = handler;
412
+ args[1] = val;
413
+ args[2] = anchor;
414
+ args[3] = tag;
415
+ args[4] = plain_implicit;
416
+ args[5] = quoted_implicit;
417
+ args[6] = style;
418
+ rb_protect(protected_scalar, (VALUE)args, &state);
230
419
  }
231
420
  break;
232
421
  case YAML_SEQUENCE_START_EVENT:
233
422
  {
423
+ VALUE args[5];
234
424
  VALUE anchor = Qnil;
235
425
  VALUE tag = Qnil;
236
426
  VALUE implicit, style;
@@ -256,15 +446,21 @@ static VALUE parse(VALUE self, VALUE yaml)
256
446
 
257
447
  style = INT2NUM((long)event.data.sequence_start.style);
258
448
 
259
- rb_funcall(handler, id_start_sequence, 4,
260
- anchor, tag, implicit, style);
449
+ args[0] = handler;
450
+ args[1] = anchor;
451
+ args[2] = tag;
452
+ args[3] = implicit;
453
+ args[4] = style;
454
+
455
+ rb_protect(protected_start_sequence, (VALUE)args, &state);
261
456
  }
262
457
  break;
263
458
  case YAML_SEQUENCE_END_EVENT:
264
- rb_funcall(handler, id_end_sequence, 0);
459
+ rb_protect(protected_end_sequence, handler, &state);
265
460
  break;
266
461
  case YAML_MAPPING_START_EVENT:
267
462
  {
463
+ VALUE args[5];
268
464
  VALUE anchor = Qnil;
269
465
  VALUE tag = Qnil;
270
466
  VALUE implicit, style;
@@ -289,50 +485,33 @@ static VALUE parse(VALUE self, VALUE yaml)
289
485
 
290
486
  style = INT2NUM((long)event.data.mapping_start.style);
291
487
 
292
- rb_funcall(handler, id_start_mapping, 4,
293
- anchor, tag, implicit, style);
488
+ args[0] = handler;
489
+ args[1] = anchor;
490
+ args[2] = tag;
491
+ args[3] = implicit;
492
+ args[4] = style;
493
+
494
+ rb_protect(protected_start_mapping, (VALUE)args, &state);
294
495
  }
295
496
  break;
296
497
  case YAML_MAPPING_END_EVENT:
297
- rb_funcall(handler, id_end_mapping, 0);
498
+ rb_protect(protected_end_mapping, handler, &state);
298
499
  break;
299
500
  case YAML_NO_EVENT:
300
- rb_funcall(handler, id_empty, 0);
501
+ rb_protect(protected_empty, handler, &state);
301
502
  break;
302
503
  case YAML_STREAM_END_EVENT:
303
- rb_funcall(handler, id_end_stream, 0);
504
+ rb_protect(protected_end_stream, handler, &state);
304
505
  done = 1;
305
506
  break;
306
507
  }
307
508
  yaml_event_delete(&event);
509
+ if (state) rb_jump_tag(state);
308
510
  }
309
511
 
310
512
  return self;
311
513
  }
312
514
 
313
- /*
314
- * call-seq:
315
- * parser.external_encoding=(encoding)
316
- *
317
- * Set the encoding for this parser to +encoding+
318
- */
319
- static VALUE set_external_encoding(VALUE self, VALUE encoding)
320
- {
321
- yaml_parser_t * parser;
322
- VALUE exception;
323
-
324
- Data_Get_Struct(self, yaml_parser_t, parser);
325
-
326
- if(parser->encoding) {
327
- exception = rb_const_get_at(mPsych, rb_intern("Exception"));
328
- rb_raise(exception, "don't set the encoding twice!");
329
- }
330
-
331
- yaml_parser_set_encoding(parser, NUM2INT(encoding));
332
-
333
- return encoding;
334
- }
335
-
336
515
  /*
337
516
  * call-seq:
338
517
  * parser.mark # => #<Psych::Parser::Mark>
@@ -376,11 +555,11 @@ void Init_psych_parser()
376
555
  /* UTF-16-BE Encoding with BOM */
377
556
  rb_define_const(cPsychParser, "UTF16BE", INT2NUM(YAML_UTF16BE_ENCODING));
378
557
 
558
+ rb_require("psych/syntax_error");
379
559
  ePsychSyntaxError = rb_define_class_under(mPsych, "SyntaxError", rb_eSyntaxError);
380
560
 
381
- rb_define_method(cPsychParser, "parse", parse, 1);
561
+ rb_define_method(cPsychParser, "parse", parse, -1);
382
562
  rb_define_method(cPsychParser, "mark", mark, 0);
383
- rb_define_method(cPsychParser, "external_encoding=", set_external_encoding, 1);
384
563
 
385
564
  id_read = rb_intern("read");
386
565
  id_path = rb_intern("path");