km-psych 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/README.rdoc +129 -0
  2. data/ext/psych/emitter.c +488 -0
  3. data/ext/psych/emitter.h +8 -0
  4. data/ext/psych/extconf.rb +22 -0
  5. data/ext/psych/parser.c +349 -0
  6. data/ext/psych/parser.h +6 -0
  7. data/ext/psych/psych.c +34 -0
  8. data/ext/psych/psych.h +20 -0
  9. data/ext/psych/to_ruby.c +41 -0
  10. data/ext/psych/to_ruby.h +8 -0
  11. data/ext/psych/yaml_tree.c +24 -0
  12. data/ext/psych/yaml_tree.h +8 -0
  13. data/lib/km-psych.rb +244 -0
  14. data/lib/psych/coder.rb +86 -0
  15. data/lib/psych/core_ext.rb +38 -0
  16. data/lib/psych/deprecated.rb +82 -0
  17. data/lib/psych/handler.rb +221 -0
  18. data/lib/psych/json.rb +6 -0
  19. data/lib/psych/json/stream.rb +32 -0
  20. data/lib/psych/json/tree_builder.rb +32 -0
  21. data/lib/psych/nodes.rb +77 -0
  22. data/lib/psych/nodes/alias.rb +18 -0
  23. data/lib/psych/nodes/document.rb +60 -0
  24. data/lib/psych/nodes/mapping.rb +56 -0
  25. data/lib/psych/nodes/node.rb +42 -0
  26. data/lib/psych/nodes/scalar.rb +67 -0
  27. data/lib/psych/nodes/sequence.rb +81 -0
  28. data/lib/psych/nodes/stream.rb +37 -0
  29. data/lib/psych/omap.rb +4 -0
  30. data/lib/psych/parser.rb +44 -0
  31. data/lib/psych/scalar_scanner.rb +105 -0
  32. data/lib/psych/set.rb +4 -0
  33. data/lib/psych/stream.rb +53 -0
  34. data/lib/psych/tree_builder.rb +94 -0
  35. data/lib/psych/visitors.rb +5 -0
  36. data/lib/psych/visitors/emitter.rb +41 -0
  37. data/lib/psych/visitors/json_tree.rb +14 -0
  38. data/lib/psych/visitors/to_ruby.rb +263 -0
  39. data/lib/psych/visitors/visitor.rb +27 -0
  40. data/lib/psych/visitors/yaml_tree.rb +342 -0
  41. data/test/psych/helper.rb +63 -0
  42. data/test/psych/json/test_stream.rb +75 -0
  43. data/test/psych/test_alias_and_anchor.rb +26 -0
  44. data/test/psych/test_array.rb +19 -0
  45. data/test/psych/test_boolean.rb +36 -0
  46. data/test/psych/test_class.rb +17 -0
  47. data/test/psych/test_coder.rb +169 -0
  48. data/test/psych/test_date_time.rb +17 -0
  49. data/test/psych/test_deprecated.rb +210 -0
  50. data/test/psych/test_document.rb +46 -0
  51. data/test/psych/test_emitter.rb +88 -0
  52. data/test/psych/test_encoding.rb +179 -0
  53. data/test/psych/test_engine_manager.rb +57 -0
  54. data/test/psych/test_exception.rb +39 -0
  55. data/test/psych/test_hash.rb +30 -0
  56. data/test/psych/test_json_tree.rb +43 -0
  57. data/test/psych/test_null.rb +19 -0
  58. data/test/psych/test_object.rb +27 -0
  59. data/test/psych/test_omap.rb +68 -0
  60. data/test/psych/test_parser.rb +216 -0
  61. data/test/psych/test_psych.rb +133 -0
  62. data/test/psych/test_scalar.rb +11 -0
  63. data/test/psych/test_scalar_scanner.rb +70 -0
  64. data/test/psych/test_serialize_subclasses.rb +38 -0
  65. data/test/psych/test_set.rb +49 -0
  66. data/test/psych/test_stream.rb +49 -0
  67. data/test/psych/test_string.rb +49 -0
  68. data/test/psych/test_struct.rb +51 -0
  69. data/test/psych/test_symbol.rb +17 -0
  70. data/test/psych/test_to_yaml_properties.rb +63 -0
  71. data/test/psych/test_tree_builder.rb +79 -0
  72. data/test/psych/test_yaml.rb +1251 -0
  73. data/test/psych/visitors/test_emitter.rb +124 -0
  74. data/test/psych/visitors/test_to_ruby.rb +325 -0
  75. data/test/psych/visitors/test_yaml_tree.rb +149 -0
  76. metadata +187 -0
@@ -0,0 +1,8 @@
1
+ #ifndef PSYCH_EMITTER_H
2
+ #define PSYCH_EMITTER_H
3
+
4
+ #include <psych.h>
5
+
6
+ void Init_psych_emitter();
7
+
8
+ #endif
@@ -0,0 +1,22 @@
1
+ require 'mkmf'
2
+
3
+ # :stopdoc:
4
+
5
+ RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
6
+
7
+ INCLUDEDIR = Config::CONFIG['includedir']
8
+ LIBDIR = Config::CONFIG['libdir']
9
+ LIB_DIRS = ['/opt/local/lib', '/usr/local/lib', LIBDIR, '/usr/lib']
10
+ libyaml = dir_config 'libyaml', '/opt/local/include', '/opt/local/lib'
11
+
12
+ def asplode missing
13
+ abort "#{missing} is missing. Try 'port install libyaml +universal' " +
14
+ "or 'yum install libyaml-devel'"
15
+ end
16
+
17
+ asplode('yaml.h') unless find_header 'yaml.h'
18
+ asplode('libyaml') unless find_library 'yaml', 'yaml_get_version'
19
+
20
+ create_makefile 'psych/psych'
21
+
22
+ # :startdoc:
@@ -0,0 +1,349 @@
1
+ #include <psych.h>
2
+
3
+ VALUE cPsychParser;
4
+ VALUE ePsychSyntaxError;
5
+
6
+ static ID id_read;
7
+ static ID id_empty;
8
+ static ID id_start_stream;
9
+ static ID id_end_stream;
10
+ static ID id_start_document;
11
+ static ID id_end_document;
12
+ static ID id_alias;
13
+ static ID id_scalar;
14
+ static ID id_start_sequence;
15
+ static ID id_end_sequence;
16
+ static ID id_start_mapping;
17
+ static ID id_end_mapping;
18
+
19
+ #define PSYCH_TRANSCODE(_str, _yaml_enc, _internal_enc) \
20
+ do { \
21
+ rb_enc_associate_index(_str, _yaml_enc); \
22
+ if(_internal_enc) \
23
+ _str = rb_str_export_to_enc(_str, _internal_enc); \
24
+ } while (0)
25
+
26
+ static int io_reader(void * data, unsigned char *buf, size_t size, size_t *read)
27
+ {
28
+ VALUE io = (VALUE)data;
29
+ VALUE string = rb_funcall(io, id_read, 1, INT2NUM(size));
30
+
31
+ *read = 0;
32
+
33
+ if(! NIL_P(string)) {
34
+ void * str = (void *)StringValuePtr(string);
35
+ *read = (size_t)RSTRING_LEN(string);
36
+ memcpy(buf, str, *read);
37
+ }
38
+
39
+ return 1;
40
+ }
41
+
42
+ static void dealloc(void * ptr)
43
+ {
44
+ yaml_parser_t * parser;
45
+
46
+ parser = (yaml_parser_t *)ptr;
47
+ yaml_parser_delete(parser);
48
+ xfree(parser);
49
+ }
50
+
51
+ static VALUE allocate(VALUE klass)
52
+ {
53
+ yaml_parser_t * parser;
54
+
55
+ parser = xmalloc(sizeof(yaml_parser_t));
56
+ yaml_parser_initialize(parser);
57
+
58
+ return Data_Wrap_Struct(klass, 0, dealloc, parser);
59
+ }
60
+
61
+ /*
62
+ * call-seq:
63
+ * parser.parse(yaml)
64
+ *
65
+ * Parse the YAML document contained in +yaml+. Events will be called on
66
+ * the handler set on the parser instance.
67
+ *
68
+ * See Psych::Parser and Psych::Parser#handler
69
+ */
70
+ static VALUE parse(VALUE self, VALUE yaml)
71
+ {
72
+ yaml_parser_t * parser;
73
+ yaml_event_t event;
74
+ int done = 0;
75
+ #ifdef HAVE_RUBY_ENCODING_H
76
+ int encoding = rb_utf8_encindex();
77
+ rb_encoding * internal_enc = rb_default_internal_encoding();
78
+ #endif
79
+ VALUE handler = rb_iv_get(self, "@handler");
80
+
81
+ Data_Get_Struct(self, yaml_parser_t, parser);
82
+
83
+ if(rb_respond_to(yaml, id_read)) {
84
+ yaml_parser_set_input(parser, io_reader, (void *)yaml);
85
+ } else {
86
+ StringValue(yaml);
87
+ yaml_parser_set_input_string(
88
+ parser,
89
+ (const unsigned char *)RSTRING_PTR(yaml),
90
+ (size_t)RSTRING_LEN(yaml)
91
+ );
92
+ }
93
+
94
+ while(!done) {
95
+ if(!yaml_parser_parse(parser, &event)) {
96
+ size_t line = parser->mark.line;
97
+ size_t column = parser->mark.column;
98
+
99
+ rb_raise(ePsychSyntaxError, "couldn't parse YAML at line %d column %d",
100
+ (int)line, (int)column);
101
+ }
102
+
103
+ switch(event.type) {
104
+ case YAML_STREAM_START_EVENT:
105
+
106
+ rb_funcall(handler, id_start_stream, 1,
107
+ INT2NUM((long)event.data.stream_start.encoding)
108
+ );
109
+ break;
110
+ case YAML_DOCUMENT_START_EVENT:
111
+ {
112
+ /* Get a list of tag directives (if any) */
113
+ VALUE tag_directives = rb_ary_new();
114
+ /* Grab the document version */
115
+ VALUE version = event.data.document_start.version_directive ?
116
+ rb_ary_new3(
117
+ (long)2,
118
+ INT2NUM((long)event.data.document_start.version_directive->major),
119
+ INT2NUM((long)event.data.document_start.version_directive->minor)
120
+ ) : rb_ary_new();
121
+
122
+ if(event.data.document_start.tag_directives.start) {
123
+ yaml_tag_directive_t *start =
124
+ event.data.document_start.tag_directives.start;
125
+ yaml_tag_directive_t *end =
126
+ event.data.document_start.tag_directives.end;
127
+ for(; start != end; start++) {
128
+ VALUE handle = Qnil;
129
+ VALUE prefix = Qnil;
130
+ if(start->handle) {
131
+ handle = rb_str_new2((const char *)start->handle);
132
+ #ifdef HAVE_RUBY_ENCODING_H
133
+ PSYCH_TRANSCODE(handle, encoding, internal_enc);
134
+ #endif
135
+ }
136
+
137
+ if(start->prefix) {
138
+ prefix = rb_str_new2((const char *)start->prefix);
139
+ #ifdef HAVE_RUBY_ENCODING_H
140
+ PSYCH_TRANSCODE(prefix, encoding, internal_enc);
141
+ #endif
142
+ }
143
+
144
+ rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix));
145
+ }
146
+ }
147
+ rb_funcall(handler, id_start_document, 3,
148
+ version, tag_directives,
149
+ event.data.document_start.implicit == 1 ? Qtrue : Qfalse
150
+ );
151
+ }
152
+ break;
153
+ case YAML_DOCUMENT_END_EVENT:
154
+ rb_funcall(handler, id_end_document, 1,
155
+ event.data.document_end.implicit == 1 ? Qtrue : Qfalse
156
+ );
157
+ break;
158
+ case YAML_ALIAS_EVENT:
159
+ {
160
+ VALUE alias = Qnil;
161
+ if(event.data.alias.anchor) {
162
+ alias = rb_str_new2((const char *)event.data.alias.anchor);
163
+ #ifdef HAVE_RUBY_ENCODING_H
164
+ PSYCH_TRANSCODE(alias, encoding, internal_enc);
165
+ #endif
166
+ }
167
+
168
+ rb_funcall(handler, id_alias, 1, alias);
169
+ }
170
+ break;
171
+ case YAML_SCALAR_EVENT:
172
+ {
173
+ VALUE anchor = Qnil;
174
+ VALUE tag = Qnil;
175
+ VALUE plain_implicit, quoted_implicit, style;
176
+ VALUE val = rb_str_new(
177
+ (const char *)event.data.scalar.value,
178
+ (long)event.data.scalar.length
179
+ );
180
+
181
+ #ifdef HAVE_RUBY_ENCODING_H
182
+ PSYCH_TRANSCODE(val, encoding, internal_enc);
183
+ #endif
184
+
185
+ if(event.data.scalar.anchor) {
186
+ anchor = rb_str_new2((const char *)event.data.scalar.anchor);
187
+ #ifdef HAVE_RUBY_ENCODING_H
188
+ PSYCH_TRANSCODE(anchor, encoding, internal_enc);
189
+ #endif
190
+ }
191
+
192
+ if(event.data.scalar.tag) {
193
+ tag = rb_str_new2((const char *)event.data.scalar.tag);
194
+ #ifdef HAVE_RUBY_ENCODING_H
195
+ PSYCH_TRANSCODE(tag, encoding, internal_enc);
196
+ #endif
197
+ }
198
+
199
+ plain_implicit =
200
+ event.data.scalar.plain_implicit == 0 ? Qfalse : Qtrue;
201
+
202
+ quoted_implicit =
203
+ event.data.scalar.quoted_implicit == 0 ? Qfalse : Qtrue;
204
+
205
+ style = INT2NUM((long)event.data.scalar.style);
206
+
207
+ rb_funcall(handler, id_scalar, 6,
208
+ val, anchor, tag, plain_implicit, quoted_implicit, style);
209
+ }
210
+ break;
211
+ case YAML_SEQUENCE_START_EVENT:
212
+ {
213
+ VALUE anchor = Qnil;
214
+ VALUE tag = Qnil;
215
+ VALUE implicit, style;
216
+ if(event.data.sequence_start.anchor) {
217
+ anchor = rb_str_new2((const char *)event.data.sequence_start.anchor);
218
+ #ifdef HAVE_RUBY_ENCODING_H
219
+ PSYCH_TRANSCODE(anchor, encoding, internal_enc);
220
+ #endif
221
+ }
222
+
223
+ tag = Qnil;
224
+ if(event.data.sequence_start.tag) {
225
+ tag = rb_str_new2((const char *)event.data.sequence_start.tag);
226
+ #ifdef HAVE_RUBY_ENCODING_H
227
+ PSYCH_TRANSCODE(tag, encoding, internal_enc);
228
+ #endif
229
+ }
230
+
231
+ implicit =
232
+ event.data.sequence_start.implicit == 0 ? Qfalse : Qtrue;
233
+
234
+ style = INT2NUM((long)event.data.sequence_start.style);
235
+
236
+ rb_funcall(handler, id_start_sequence, 4,
237
+ anchor, tag, implicit, style);
238
+ }
239
+ break;
240
+ case YAML_SEQUENCE_END_EVENT:
241
+ rb_funcall(handler, id_end_sequence, 0);
242
+ break;
243
+ case YAML_MAPPING_START_EVENT:
244
+ {
245
+ VALUE anchor = Qnil;
246
+ VALUE tag = Qnil;
247
+ VALUE implicit, style;
248
+ if(event.data.mapping_start.anchor) {
249
+ anchor = rb_str_new2((const char *)event.data.mapping_start.anchor);
250
+ #ifdef HAVE_RUBY_ENCODING_H
251
+ PSYCH_TRANSCODE(anchor, encoding, internal_enc);
252
+ #endif
253
+ }
254
+
255
+ if(event.data.mapping_start.tag) {
256
+ tag = rb_str_new2((const char *)event.data.mapping_start.tag);
257
+ #ifdef HAVE_RUBY_ENCODING_H
258
+ PSYCH_TRANSCODE(tag, encoding, internal_enc);
259
+ #endif
260
+ }
261
+
262
+ implicit =
263
+ event.data.mapping_start.implicit == 0 ? Qfalse : Qtrue;
264
+
265
+ style = INT2NUM((long)event.data.mapping_start.style);
266
+
267
+ rb_funcall(handler, id_start_mapping, 4,
268
+ anchor, tag, implicit, style);
269
+ }
270
+ break;
271
+ case YAML_MAPPING_END_EVENT:
272
+ rb_funcall(handler, id_end_mapping, 0);
273
+ break;
274
+ case YAML_NO_EVENT:
275
+ rb_funcall(handler, id_empty, 0);
276
+ break;
277
+ case YAML_STREAM_END_EVENT:
278
+ rb_funcall(handler, id_end_stream, 0);
279
+ done = 1;
280
+ break;
281
+ }
282
+ }
283
+
284
+ return self;
285
+ }
286
+
287
+ /*
288
+ * call-seq:
289
+ * parser.external_encoding=(encoding)
290
+ *
291
+ * Set the encoding for this parser to +encoding+
292
+ */
293
+ static VALUE set_external_encoding(VALUE self, VALUE encoding)
294
+ {
295
+ yaml_parser_t * parser;
296
+ VALUE exception;
297
+
298
+ Data_Get_Struct(self, yaml_parser_t, parser);
299
+
300
+ if(parser->encoding) {
301
+ exception = rb_const_get_at(mPsych, rb_intern("Exception"));
302
+ rb_raise(exception, "don't set the encoding twice!");
303
+ }
304
+
305
+ yaml_parser_set_encoding(parser, NUM2INT(encoding));
306
+
307
+ return encoding;
308
+ }
309
+
310
+ void Init_psych_parser()
311
+ {
312
+ #if 0
313
+ mPsych = rb_define_module("Psych");
314
+ #endif
315
+
316
+ cPsychParser = rb_define_class_under(mPsych, "Parser", rb_cObject);
317
+ rb_define_alloc_func(cPsychParser, allocate);
318
+
319
+ /* Any encoding: Let the parser choose the encoding */
320
+ rb_define_const(cPsychParser, "ANY", INT2NUM(YAML_ANY_ENCODING));
321
+
322
+ /* UTF-8 Encoding */
323
+ rb_define_const(cPsychParser, "UTF8", INT2NUM(YAML_UTF8_ENCODING));
324
+
325
+ /* UTF-16-LE Encoding with BOM */
326
+ rb_define_const(cPsychParser, "UTF16LE", INT2NUM(YAML_UTF16LE_ENCODING));
327
+
328
+ /* UTF-16-BE Encoding with BOM */
329
+ rb_define_const(cPsychParser, "UTF16BE", INT2NUM(YAML_UTF16BE_ENCODING));
330
+
331
+ ePsychSyntaxError = rb_define_class_under(mPsych, "SyntaxError", rb_eSyntaxError);
332
+
333
+ rb_define_method(cPsychParser, "parse", parse, 1);
334
+ rb_define_method(cPsychParser, "external_encoding=", set_external_encoding, 1);
335
+
336
+ id_read = rb_intern("read");
337
+ id_empty = rb_intern("empty");
338
+ id_start_stream = rb_intern("start_stream");
339
+ id_end_stream = rb_intern("end_stream");
340
+ id_start_document = rb_intern("start_document");
341
+ id_end_document = rb_intern("end_document");
342
+ id_alias = rb_intern("alias");
343
+ id_scalar = rb_intern("scalar");
344
+ id_start_sequence = rb_intern("start_sequence");
345
+ id_end_sequence = rb_intern("end_sequence");
346
+ id_start_mapping = rb_intern("start_mapping");
347
+ id_end_mapping = rb_intern("end_mapping");
348
+ }
349
+ /* vim: set noet sws=4 sw=4: */
@@ -0,0 +1,6 @@
1
+ #ifndef PSYCH_PARSER_H
2
+ #define PSYCH_PARSER_H
3
+
4
+ void Init_psych_parser();
5
+
6
+ #endif
@@ -0,0 +1,34 @@
1
+ #include <psych.h>
2
+
3
+ /* call-seq: Psych.libyaml_version
4
+ *
5
+ * Returns the version of libyaml being used
6
+ */
7
+ static VALUE libyaml_version(VALUE module)
8
+ {
9
+ int major, minor, patch;
10
+ VALUE list[3];
11
+
12
+ yaml_get_version(&major, &minor, &patch);
13
+
14
+ list[0] = INT2NUM((long)major);
15
+ list[1] = INT2NUM((long)minor);
16
+ list[2] = INT2NUM((long)patch);
17
+
18
+ return rb_ary_new4((long)3, list);
19
+ }
20
+
21
+ VALUE mPsych;
22
+
23
+ void Init_psych()
24
+ {
25
+ mPsych = rb_define_module("Psych");
26
+
27
+ rb_define_singleton_method(mPsych, "libyaml_version", libyaml_version, 0);
28
+
29
+ Init_psych_parser();
30
+ Init_psych_emitter();
31
+ Init_psych_to_ruby();
32
+ Init_psych_yaml_tree();
33
+ }
34
+ /* vim: set noet sws=4 sw=4: */
@@ -0,0 +1,20 @@
1
+ #ifndef PSYCH_H
2
+ #define PSYCH_H
3
+
4
+ #include <ruby.h>
5
+
6
+ #ifdef HAVE_RUBY_ENCODING_H
7
+ #include <ruby/encoding.h>
8
+ #endif
9
+
10
+ #include <yaml.h>
11
+
12
+ #include <parser.h>
13
+ #include <emitter.h>
14
+ #include <to_ruby.h>
15
+ #include <yaml_tree.h>
16
+
17
+ extern VALUE mPsych;
18
+
19
+
20
+ #endif
@@ -0,0 +1,41 @@
1
+ #include <psych.h>
2
+
3
+ VALUE cPsychVisitorsToRuby;
4
+
5
+ /* call-seq: vis.build_exception(klass, message)
6
+ *
7
+ * Create an exception with class +klass+ and +message+
8
+ */
9
+ static VALUE build_exception(VALUE self, VALUE klass, VALUE mesg)
10
+ {
11
+ VALUE e = rb_obj_alloc(klass);
12
+
13
+ rb_iv_set(e, "mesg", mesg);
14
+
15
+ return e;
16
+ }
17
+
18
+ /* call-seq: vis.path2class(path)
19
+ *
20
+ * Convert +path+ string to a class
21
+ */
22
+ static VALUE path2class(VALUE self, VALUE path)
23
+ {
24
+ #ifdef HAVE_RUBY_ENCODING_H
25
+ return rb_path_to_class(path);
26
+ #else
27
+ return rb_path2class(StringValuePtr(path));
28
+ #endif
29
+ }
30
+
31
+ void Init_psych_to_ruby(void)
32
+ {
33
+ VALUE psych = rb_define_module("Psych");
34
+ VALUE visitors = rb_define_module_under(psych, "Visitors");
35
+ VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject);
36
+ cPsychVisitorsToRuby = rb_define_class_under(visitors, "ToRuby", visitor);
37
+
38
+ rb_define_private_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2);
39
+ rb_define_private_method(cPsychVisitorsToRuby, "path2class", path2class, 1);
40
+ }
41
+ /* vim: set noet sws=4 sw=4: */