concordia-publishing-house-syck 1.0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.rdoc +6 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +25 -0
  5. data/Manifest.txt +52 -0
  6. data/README.rdoc +51 -0
  7. data/Rakefile +32 -0
  8. data/ext/syck/bytecode.c +1165 -0
  9. data/ext/syck/emitter.c +1247 -0
  10. data/ext/syck/extconf.h +3 -0
  11. data/ext/syck/extconf.rb +5 -0
  12. data/ext/syck/gram.c +1894 -0
  13. data/ext/syck/gram.h +79 -0
  14. data/ext/syck/handler.c +173 -0
  15. data/ext/syck/implicit.c +2990 -0
  16. data/ext/syck/node.c +407 -0
  17. data/ext/syck/rubyext.c +2328 -0
  18. data/ext/syck/syck.c +524 -0
  19. data/ext/syck/syck.h +453 -0
  20. data/ext/syck/token.c +2724 -0
  21. data/ext/syck/yaml2byte.c +259 -0
  22. data/ext/syck/yamlbyte.h +171 -0
  23. data/lib/syck.rb +448 -0
  24. data/lib/syck/baseemitter.rb +242 -0
  25. data/lib/syck/basenode.rb +222 -0
  26. data/lib/syck/constants.rb +45 -0
  27. data/lib/syck/encoding.rb +35 -0
  28. data/lib/syck/error.rb +34 -0
  29. data/lib/syck/loader.rb +14 -0
  30. data/lib/syck/rubytypes.rb +450 -0
  31. data/lib/syck/stream.rb +41 -0
  32. data/lib/syck/stringio.rb +85 -0
  33. data/lib/syck/syck.rb +16 -0
  34. data/lib/syck/tag.rb +95 -0
  35. data/lib/syck/types.rb +192 -0
  36. data/lib/syck/yamlnode.rb +54 -0
  37. data/lib/syck/ypath.rb +54 -0
  38. data/lib/yaml/engine_manager.rb +71 -0
  39. data/lib/yaml/syck.rb +14 -0
  40. data/test/helper.rb +2 -0
  41. data/test/test_array.rb +13 -0
  42. data/test/test_boolean.rb +36 -0
  43. data/test/test_class.rb +11 -0
  44. data/test/test_exception.rb +45 -0
  45. data/test/test_hash.rb +24 -0
  46. data/test/test_null.rb +19 -0
  47. data/test/test_omap.rb +55 -0
  48. data/test/test_set.rb +30 -0
  49. data/test/test_string.rb +44 -0
  50. data/test/test_struct.rb +32 -0
  51. data/test/test_symbol.rb +21 -0
  52. data/test/test_time.rb +23 -0
  53. data/test/test_yaml.rb +1403 -0
  54. data/test/test_yaml_properties.rb +63 -0
  55. metadata +163 -0
@@ -0,0 +1,259 @@
1
+ /*
2
+ * yaml2byte.c
3
+ *
4
+ * $Author$
5
+ *
6
+ * Copyright (C) 2003 why the lucky stiff, clark evans
7
+ *
8
+ * WARNING WARNING WARNING --- THIS IS *NOT JUST* PLAYING
9
+ * ANYMORE! -- WHY HAS EMBRACED THIS AS THE REAL THING!
10
+ */
11
+ #include "ruby/ruby.h"
12
+ #include <syck.h>
13
+ #include <assert.h>
14
+ #define YAMLBYTE_UTF8
15
+ #include "yamlbyte.h"
16
+
17
+ #include <stdio.h>
18
+ #define TRACE0(a) \
19
+ do { printf(a); printf("\n"); fflush(stdout); } while(0)
20
+ #define TRACE1(a,b) \
21
+ do { printf(a,b); printf("\n"); fflush(stdout); } while(0)
22
+ #define TRACE2(a,b,c) \
23
+ do { printf(a,b,c); printf("\n"); fflush(stdout); } while(0)
24
+ #define TRACE3(a,b,c,d) \
25
+ do { printf(a,b,c,d); printf("\n"); fflush(stdout); } while(0)
26
+
27
+ /* Reinvent the wheel... */
28
+ #define CHUNKSIZE 64
29
+ #define HASH ((long)0xCAFECAFE)
30
+ typedef struct {
31
+ long hash;
32
+ char *buffer;
33
+ long length;
34
+ long remaining;
35
+ int printed;
36
+ } bytestring_t;
37
+ bytestring_t *bytestring_alloc(void) {
38
+ bytestring_t *ret;
39
+ /*TRACE0("bytestring_alloc()");*/
40
+ ret = S_ALLOC(bytestring_t);
41
+ ret->hash = HASH;
42
+ ret->length = CHUNKSIZE;
43
+ ret->remaining = ret->length;
44
+ ret->buffer = S_ALLOC_N(char, ret->length + 1 );
45
+ ret->buffer[0] = 0;
46
+ ret->printed = 0;
47
+ return ret;
48
+ }
49
+ void bytestring_append(bytestring_t *str, char code,
50
+ char *start, char *finish)
51
+ {
52
+ long grow;
53
+ long length = 2; /* CODE + LF */
54
+ char *curr;
55
+ assert(str && HASH == str->hash);
56
+ /*TRACE0("bytestring_append()");*/
57
+ if(start) {
58
+ if(!finish)
59
+ finish = start + strlen(start);
60
+ length += (finish-start);
61
+ }
62
+ if(length > str->remaining) {
63
+ grow = (length - str->remaining) + CHUNKSIZE;
64
+ str->remaining += grow;
65
+ str->length += grow;
66
+ S_REALLOC_N( str->buffer, char, str->length + 1 );
67
+ assert(str->buffer);
68
+ }
69
+ curr = str->buffer + (str->length - str->remaining);
70
+ *curr = code;
71
+ curr += 1;
72
+ if(start)
73
+ while(start < finish)
74
+ *curr ++ = *start ++;
75
+ *curr = '\n';
76
+ curr += 1;
77
+ *curr = 0;
78
+ str->remaining = str->remaining - length;
79
+ assert( (str->buffer + str->length) - str->remaining );
80
+ }
81
+ void bytestring_extend(bytestring_t *str, bytestring_t *ext)
82
+ {
83
+ char *from;
84
+ char *curr;
85
+ char *stop;
86
+ long grow;
87
+ long length;
88
+ assert(str && HASH == str->hash);
89
+ assert(ext && HASH == ext->hash);
90
+ if(ext->printed) {
91
+ assert(ext->buffer[0] ==YAMLBYTE_ANCHOR);
92
+ curr = ext->buffer;
93
+ while( '\n' != *curr)
94
+ curr++;
95
+ bytestring_append(str, YAMLBYTE_ALIAS, ext->buffer + 1, curr);
96
+ } else {
97
+ ext->printed = 1;
98
+ length = (ext->length - ext->remaining);
99
+ if(length > str->remaining) {
100
+ grow = (length - str->remaining) + CHUNKSIZE;
101
+ str->remaining += grow;
102
+ str->length += grow;
103
+ S_REALLOC_N( str->buffer, char, str->length + 1 );
104
+ }
105
+ curr = str->buffer + (str->length - str->remaining);
106
+ from = ext->buffer;
107
+ stop = ext->buffer + length;
108
+ while( from < stop )
109
+ *curr ++ = *from ++;
110
+ *curr = 0;
111
+ str->remaining = str->remaining - length;
112
+ assert( (str->buffer + str->length) - str->remaining );
113
+ }
114
+ }
115
+
116
+ /* convert SyckNode into yamlbyte_buffer_t objects */
117
+ SYMID
118
+ syck_yaml2byte_handler(p, n)
119
+ SyckParser *p;
120
+ SyckNode *n;
121
+ {
122
+ SYMID oid;
123
+ long i;
124
+ char ch;
125
+ char nextcode;
126
+ char *start;
127
+ char *current;
128
+ char *finish;
129
+ bytestring_t *val = NULL;
130
+ bytestring_t *sav = NULL;
131
+ void *data;
132
+ /*TRACE0("syck_yaml2byte_handler()");*/
133
+ val = bytestring_alloc();
134
+ if(n->anchor) bytestring_append(val,YAMLBYTE_ANCHOR, n->anchor, NULL);
135
+ if ( n->type_id )
136
+ {
137
+ if ( p->taguri_expansion )
138
+ {
139
+ bytestring_append(val,YAMLBYTE_TRANSFER, n->type_id, NULL);
140
+ }
141
+ else
142
+ {
143
+ char *type_tag = S_ALLOC_N( char, strlen( n->type_id ) + 1 );
144
+ type_tag[0] = '\0';
145
+ strcat( type_tag, "!" );
146
+ strcat( type_tag, n->type_id );
147
+ bytestring_append( val, YAMLBYTE_TRANSFER, type_tag, NULL);
148
+ S_FREE(type_tag);
149
+ }
150
+ }
151
+ switch (n->kind)
152
+ {
153
+ case syck_str_kind:
154
+ nextcode = YAMLBYTE_SCALAR;
155
+ start = n->data.str->ptr;
156
+ finish = start + n->data.str->len - 1;
157
+ current = start;
158
+ /*TRACE2("SCALAR: %s %d", start, n->data.str->len); */
159
+ while(1) {
160
+ ch = *current;
161
+ if('\n' == ch || 0 == ch || current > finish) {
162
+ if(current >= start) {
163
+ bytestring_append(val, nextcode, start, current);
164
+ nextcode = YAMLBYTE_CONTINUE;
165
+ }
166
+ start = current + 1;
167
+ if(current > finish)
168
+ {
169
+ break;
170
+ }
171
+ else if('\n' == ch )
172
+ {
173
+ bytestring_append(val,YAMLBYTE_NEWLINE,NULL,NULL);
174
+ }
175
+ else if(0 == ch)
176
+ {
177
+ bytestring_append(val,YAMLBYTE_NULLCHAR,NULL,NULL);
178
+ }
179
+ else
180
+ {
181
+ assert("oops");
182
+ }
183
+ }
184
+ current += 1;
185
+ }
186
+ break;
187
+ case syck_seq_kind:
188
+ bytestring_append(val,YAMLBYTE_SEQUENCE,NULL,NULL);
189
+ for ( i = 0; i < n->data.list->idx; i++ )
190
+ {
191
+ oid = syck_seq_read( n, i );
192
+ if (syck_lookup_sym( p, oid, &data )) sav = data;
193
+ bytestring_extend(val, sav);
194
+ }
195
+ bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL);
196
+ break;
197
+ case syck_map_kind:
198
+ bytestring_append(val,YAMLBYTE_MAPPING,NULL,NULL);
199
+ for ( i = 0; i < n->data.pairs->idx; i++ )
200
+ {
201
+ oid = syck_map_read( n, map_key, i );
202
+ if (syck_lookup_sym( p, oid, &data )) sav = data;
203
+ bytestring_extend(val, sav);
204
+ oid = syck_map_read( n, map_value, i );
205
+ if (syck_lookup_sym( p, oid, &data )) sav = data;
206
+ bytestring_extend(val, sav);
207
+ }
208
+ bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL);
209
+ break;
210
+ }
211
+ oid = syck_add_sym( p, (char *) val );
212
+ /*TRACE1("Saving: %s", val->buffer );*/
213
+ return oid;
214
+ }
215
+
216
+ char *
217
+ syck_yaml2byte(char *yamlstr)
218
+ {
219
+ SYMID oid;
220
+ char *ret;
221
+ bytestring_t *sav;
222
+ void *data;
223
+
224
+ SyckParser *parser = syck_new_parser();
225
+ syck_parser_str_auto( parser, yamlstr, NULL );
226
+ syck_parser_handler( parser, syck_yaml2byte_handler );
227
+ syck_parser_error_handler( parser, NULL );
228
+ syck_parser_implicit_typing( parser, 1 );
229
+ syck_parser_taguri_expansion( parser, 1 );
230
+ oid = syck_parse( parser );
231
+
232
+ if ( syck_lookup_sym( parser, oid, &data ) ) {
233
+ sav = data;
234
+ ret = S_ALLOC_N( char, strlen( sav->buffer ) + 3 );
235
+ ret[0] = '\0';
236
+ strcat( ret, "D\n" );
237
+ strcat( ret, sav->buffer );
238
+ }
239
+ else
240
+ {
241
+ ret = NULL;
242
+ }
243
+
244
+ syck_free_parser( parser );
245
+ return ret;
246
+ }
247
+
248
+ #ifdef TEST_YBEXT
249
+ #include <stdio.h>
250
+ int main() {
251
+ char *yaml = "test: 1\nand: \"with new\\nline\\n\"\nalso: &3 three\nmore: *3";
252
+ printf("--- # YAML \n");
253
+ printf(yaml);
254
+ printf("\n...\n");
255
+ printf(syck_yaml2byte(yaml));
256
+ return 0;
257
+ }
258
+ #endif
259
+
@@ -0,0 +1,171 @@
1
+ /* yamlbyte.h
2
+ *
3
+ * The YAML bytecode "C" interface header file. See the YAML bytecode
4
+ * reference for bytecode sequence rules and for the meaning of each
5
+ * bytecode.
6
+ */
7
+
8
+ #ifndef YAMLBYTE_H
9
+ #define YAMLBYTE_H
10
+ #include <stddef.h>
11
+
12
+ /* define what a character is */
13
+ typedef unsigned char yamlbyte_utf8_t;
14
+ typedef unsigned short yamlbyte_utf16_t;
15
+ #ifdef YAMLBYTE_UTF8
16
+ #ifdef YAMLBYTE_UTF16
17
+ #error Must only define YAMLBYTE_UTF8 or YAMLBYTE_UTF16
18
+ #endif
19
+ typedef yamlbyte_utf8_t yamlbyte_char_t;
20
+ #else
21
+ #ifdef YAMLBYTE_UTF16
22
+ typedef yamlbyte_utf16_t yamlbyte_char_t;
23
+ #else
24
+ #error Must define YAMLBYTE_UTF8 or YAMLBYTE_UTF16
25
+ #endif
26
+ #endif
27
+
28
+ /* specify list of bytecodes */
29
+ #define YAMLBYTE_FINISH ((yamlbyte_char_t) 0)
30
+ #define YAMLBYTE_DOCUMENT ((yamlbyte_char_t)'D')
31
+ #define YAMLBYTE_DIRECTIVE ((yamlbyte_char_t)'V')
32
+ #define YAMLBYTE_PAUSE ((yamlbyte_char_t)'P')
33
+ #define YAMLBYTE_MAPPING ((yamlbyte_char_t)'M')
34
+ #define YAMLBYTE_SEQUENCE ((yamlbyte_char_t)'Q')
35
+ #define YAMLBYTE_END_BRANCH ((yamlbyte_char_t)'E')
36
+ #define YAMLBYTE_SCALAR ((yamlbyte_char_t)'S')
37
+ #define YAMLBYTE_CONTINUE ((yamlbyte_char_t)'C')
38
+ #define YAMLBYTE_NEWLINE ((yamlbyte_char_t)'N')
39
+ #define YAMLBYTE_NULLCHAR ((yamlbyte_char_t)'Z')
40
+ #define YAMLBYTE_ANCHOR ((yamlbyte_char_t)'A')
41
+ #define YAMLBYTE_ALIAS ((yamlbyte_char_t)'R')
42
+ #define YAMLBYTE_TRANSFER ((yamlbyte_char_t)'T')
43
+ /* formatting bytecodes */
44
+ #define YAMLBYTE_COMMENT ((yamlbyte_char_t)'c')
45
+ #define YAMLBYTE_INDENT ((yamlbyte_char_t)'i')
46
+ #define YAMLBYTE_STYLE ((yamlbyte_char_t)'s')
47
+ /* other bytecodes */
48
+ #define YAMLBYTE_LINE_NUMBER ((yamlbyte_char_t)'#')
49
+ #define YAMLBYTE_WHOLE_SCALAR ((yamlbyte_char_t)'<')
50
+ #define YAMLBYTE_NOTICE ((yamlbyte_char_t)'!')
51
+ #define YAMLBYTE_SPAN ((yamlbyte_char_t)')')
52
+ #define YAMLBYTE_ALLOC ((yamlbyte_char_t)'@')
53
+
54
+ /* second level style bytecodes, ie "s>" */
55
+ #define YAMLBYTE_FLOW ((yamlbyte_char_t)'>')
56
+ #define YAMLBYTE_LITERAL ((yamlbyte_char_t)'|')
57
+ #define YAMLBYTE_BLOCK ((yamlbyte_char_t)'b')
58
+ #define YAMLBYTE_PLAIN ((yamlbyte_char_t)'p')
59
+ #define YAMLBYTE_INLINE_MAPPING ((yamlbyte_char_t)'{')
60
+ #define YAMLBYTE_INLINE_SEQUENCE ((yamlbyte_char_t)'[')
61
+ #define YAMLBYTE_SINGLE_QUOTED ((yamlbyte_char_t)39)
62
+ #define YAMLBYTE_DOUBLE_QUOTED ((yamlbyte_char_t)'"')
63
+
64
+ /*
65
+ * The "C" API has two variants, one based on instructions,
66
+ * with events delivered via pointers; and the other one
67
+ * is character based where one or more instructions are
68
+ * serialized into a buffer.
69
+ *
70
+ * Note: In the instruction based API, WHOLE_SCALAR does
71
+ * not have the '<here' marshalling stuff.
72
+ */
73
+
74
+ typedef void * yamlbyte_consumer_t;
75
+ typedef void * yamlbyte_producer_t;
76
+
77
+ /* push and pull APIs need a way to communicate results */
78
+ typedef enum {
79
+ YAMLBYTE_OK = 0, /* proceed */
80
+ YAMLBYTE_E_MEMORY = 'M', /* could not allocate memory */
81
+ YAMLBYTE_E_READ = 'R', /* input stream read error */
82
+ YAMLBYTE_E_WRITE = 'W', /* output stream write error */
83
+ YAMLBYTE_E_OTHER = '?', /* some other error condition */
84
+ YAMLBYTE_E_PARSE = 'P', /* parse error, check bytecodes */
85
+ YAMLBYTE_MAX
86
+ } yamlbyte_result_t;
87
+
88
+ typedef const yamlbyte_char_t *yamlbyte_buff_t;
89
+
90
+ /*
91
+ * The "Instruction" API
92
+ */
93
+
94
+ typedef struct yaml_instruction {
95
+ yamlbyte_char_t bytecode;
96
+ yamlbyte_buff_t start;
97
+ yamlbyte_buff_t finish; /* open range, *finish is _not_ part */
98
+ } *yamlbyte_inst_t;
99
+
100
+ /* producer pushes the instruction with one bytecode event to the
101
+ * consumer; if the consumer's result is not YAMLBYTE_OK, then
102
+ * the producer should stop */
103
+ typedef
104
+ yamlbyte_result_t
105
+ (*yamlbyte_push_t)(
106
+ yamlbyte_consumer_t self,
107
+ yamlbyte_inst_t inst
108
+ );
109
+
110
+ /* consumer pulls a bytecode instruction from the producer; in this
111
+ * case the instruction (and is buffer) are owned by the producer and
112
+ * will remain valid till the pull function is called once again;
113
+ * if the instruction is NULL, then there are no more results; and
114
+ * it is important to call the pull function till it returns NULL so
115
+ * that the producer can clean up its memory allocations */
116
+ typedef
117
+ yamlbyte_result_t
118
+ (*yamlbyte_pull_t)(
119
+ yamlbyte_producer_t self,
120
+ yamlbyte_inst_t *inst /* to be filled in by the producer */
121
+ );
122
+
123
+ /*
124
+ * Buffer based API
125
+ */
126
+
127
+ /* producer pushes a null terminated buffer filled with one or more
128
+ * bytecode events to the consumer; if the consumer's result is not
129
+ * YAMLBYTE_OK, then the producer should stop */
130
+ typedef
131
+ yamlbyte_result_t
132
+ (*yamlbyte_pushbuff_t)(
133
+ yamlbyte_consumer_t self,
134
+ yamlbyte_buff_t buff
135
+ );
136
+
137
+ /* consumer pulls bytecode events from the producer; in this case
138
+ * the buffer is owned by the producer, and will remain valid till
139
+ * the pull function is called once again; if the buffer pointer
140
+ * is set to NULL, then there are no more results; it is important
141
+ * to call the pull function till it returns NULL so that the
142
+ * producer can clean up its memory allocations */
143
+ typedef
144
+ yamlbyte_result_t
145
+ (*yamlbyte_pullbuff_t)(
146
+ yamlbyte_producer_t self,
147
+ yamlbyte_buff_t *buff /* to be filled in by the producer */
148
+ );
149
+
150
+ /* convert a pull interface to a push interface; the reverse process
151
+ * requires threads and thus is language dependent */
152
+ #define YAMLBYTE_PULL2PUSH(pull,producer,push,consumer,result) \
153
+ do { \
154
+ yamlbyte_pullbuff_t _pull = (pull); \
155
+ yamlbyte_pushbuff_t _push = (push); \
156
+ yamlbyte_result_t _result = YAMLBYTE_OK; \
157
+ yamlbyte_producer_t _producer = (producer); \
158
+ yamlbyte_consumer_t _consumer = (consumer); \
159
+ while(1) { \
160
+ yamlbyte_buff_t buff = NULL; \
161
+ _result = _pull(_producer,&buff); \
162
+ if(YAMLBYTE_OK != result || NULL == buff) \
163
+ break; \
164
+ _result = _push(_consumer,buff); \
165
+ if(YAMLBYTE_OK != result) \
166
+ break; \
167
+ } \
168
+ (result) = _result; \
169
+ } while(0)
170
+
171
+ #endif
@@ -0,0 +1,448 @@
1
+ # -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
2
+ # $Id$
3
+ #
4
+ # = yaml.rb: top-level module with methods for loading and parsing YAML documents
5
+ #
6
+ # Author:: why the lucky stiff
7
+ #
8
+
9
+ require 'yaml/syck'
10
+ require File.expand_path('../yaml/engine_manager', __FILE__)
11
+
12
+ # == YAML
13
+ #
14
+ # YAML(tm) (rhymes with 'camel') is a
15
+ # straightforward machine parsable data serialization format designed for
16
+ # human readability and interaction with scripting languages such as Perl
17
+ # and Python. YAML is optimized for data serialization, formatted
18
+ # dumping, configuration files, log files, Internet messaging and
19
+ # filtering. This specification describes the YAML information model and
20
+ # serialization format. Together with the Unicode standard for characters, it
21
+ # provides all the information necessary to understand YAML Version 1.0
22
+ # and construct computer programs to process it.
23
+ #
24
+ # See http://yaml.org/ for more information. For a quick tutorial, please
25
+ # visit YAML In Five Minutes (http://yaml.kwiki.org/?YamlInFiveMinutes).
26
+ #
27
+ # == About This Library
28
+ #
29
+ # The YAML 1.0 specification outlines four stages of YAML loading and dumping.
30
+ # This library honors all four of those stages, although data is really only
31
+ # available to you in three stages.
32
+ #
33
+ # The four stages are: native, representation, serialization, and presentation.
34
+ #
35
+ # The native stage refers to data which has been loaded completely into Ruby's
36
+ # own types. (See +YAML::load+.)
37
+ #
38
+ # The representation stage means data which has been composed into
39
+ # +YAML::BaseNode+ objects. In this stage, the document is available as a
40
+ # tree of node objects. You can perform YPath queries and transformations
41
+ # at this level. (See +YAML::parse+.)
42
+ #
43
+ # The serialization stage happens inside the parser. The YAML parser used in
44
+ # Ruby is called Syck. Serialized nodes are available in the extension as
45
+ # SyckNode structs.
46
+ #
47
+ # The presentation stage is the YAML document itself. This is accessible
48
+ # to you as a string. (See +YAML::dump+.)
49
+ #
50
+ # For more information about the various information models, see Chapter
51
+ # 3 of the YAML 1.0 Specification (http://yaml.org/spec/#id2491269).
52
+ #
53
+ # The YAML module provides quick access to the most common loading (YAML::load)
54
+ # and dumping (YAML::dump) tasks. This module also provides an API for registering
55
+ # global types (YAML::add_domain_type).
56
+ #
57
+ # == Example
58
+ #
59
+ # A simple round-trip (load and dump) of an object.
60
+ #
61
+ # require "yaml"
62
+ #
63
+ # test_obj = ["dogs", "cats", "badgers"]
64
+ #
65
+ # yaml_obj = YAML::dump( test_obj )
66
+ # # -> ---
67
+ # - dogs
68
+ # - cats
69
+ # - badgers
70
+ # ruby_obj = YAML::load( yaml_obj )
71
+ # # => ["dogs", "cats", "badgers"]
72
+ # ruby_obj == test_obj
73
+ # # => true
74
+ #
75
+ # To register your custom types with the global resolver, use +add_domain_type+.
76
+ #
77
+ # YAML::add_domain_type( "your-site.com,2004", "widget" ) do |type, val|
78
+ # Widget.new( val )
79
+ # end
80
+ #
81
+ module Syck
82
+
83
+ DefaultResolver.use_types_at( @@tagged_classes )
84
+
85
+ # Returns a new default parser
86
+ def self.parser; Parser.new.set_resolver( self.resolver ); end
87
+
88
+ # Returns a new generic parser
89
+ def self.generic_parser
90
+ warn "#{caller[0]}: YAML.generic_parser is deprecated, switch to psych" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
91
+ Parser.new.set_resolver( GenericResolver )
92
+ end
93
+
94
+ # Returns the default resolver
95
+ def self.resolver
96
+ warn "#{caller[0]}: YAML.resolver is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
97
+ DefaultResolver
98
+ end
99
+
100
+ # Returns a new default emitter
101
+ def self.emitter
102
+ warn "#{caller[0]}: YAML.emitter is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
103
+ Emitter.new.set_resolver( self.resolver )
104
+ end
105
+
106
+ #
107
+ # Converts _obj_ to YAML and writes the YAML result to _io_.
108
+ #
109
+ # File.open( 'animals.yaml', 'w' ) do |out|
110
+ # YAML.dump( ['badger', 'elephant', 'tiger'], out )
111
+ # end
112
+ #
113
+ # If no _io_ is provided, a string containing the dumped YAML
114
+ # is returned.
115
+ #
116
+ # YAML.dump( :locked )
117
+ # #=> "--- :locked"
118
+ #
119
+ def self.dump( obj, io = nil )
120
+ obj.to_yaml( io || io2 = StringIO.new )
121
+ io || ( io2.rewind; io2.read )
122
+ end
123
+
124
+ #
125
+ # Load a document from the current _io_ stream.
126
+ #
127
+ # File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }
128
+ # #=> ['badger', 'elephant', 'tiger']
129
+ #
130
+ # Can also load from a string.
131
+ #
132
+ # YAML.load( "--- :locked" )
133
+ # #=> :locked
134
+ #
135
+ def self.load( io )
136
+ parser.load( io )
137
+ end
138
+
139
+ #
140
+ # Load a document from the file located at _filepath_.
141
+ #
142
+ # YAML.load_file( 'animals.yaml' )
143
+ # #=> ['badger', 'elephant', 'tiger']
144
+ #
145
+ def self.load_file( filepath )
146
+ File.open( filepath ) do |f|
147
+ load( f )
148
+ end
149
+ end
150
+
151
+ #
152
+ # Parse the first document from the current _io_ stream
153
+ #
154
+ # File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }
155
+ # #=> #<YAML::Syck::Node:0x82ccce0
156
+ # @kind=:seq,
157
+ # @value=
158
+ # [#<YAML::Syck::Node:0x82ccd94
159
+ # @kind=:scalar,
160
+ # @type_id="str",
161
+ # @value="badger">,
162
+ # #<YAML::Syck::Node:0x82ccd58
163
+ # @kind=:scalar,
164
+ # @type_id="str",
165
+ # @value="elephant">,
166
+ # #<YAML::Syck::Node:0x82ccd1c
167
+ # @kind=:scalar,
168
+ # @type_id="str",
169
+ # @value="tiger">]>
170
+ #
171
+ # Can also load from a string.
172
+ #
173
+ # YAML.parse( "--- :locked" )
174
+ # #=> #<YAML::Syck::Node:0x82edddc
175
+ # @type_id="tag:ruby.yaml.org,2002:sym",
176
+ # @value=":locked", @kind=:scalar>
177
+ #
178
+ def self.parse( io )
179
+ generic_parser.load( io )
180
+ end
181
+
182
+ #
183
+ # Parse a document from the file located at _filepath_.
184
+ #
185
+ # YAML.parse_file( 'animals.yaml' )
186
+ # #=> #<YAML::Syck::Node:0x82ccce0
187
+ # @kind=:seq,
188
+ # @value=
189
+ # [#<YAML::Syck::Node:0x82ccd94
190
+ # @kind=:scalar,
191
+ # @type_id="str",
192
+ # @value="badger">,
193
+ # #<YAML::Syck::Node:0x82ccd58
194
+ # @kind=:scalar,
195
+ # @type_id="str",
196
+ # @value="elephant">,
197
+ # #<YAML::Syck::Node:0x82ccd1c
198
+ # @kind=:scalar,
199
+ # @type_id="str",
200
+ # @value="tiger">]>
201
+ #
202
+ def self.parse_file( filepath )
203
+ File.open( filepath ) do |f|
204
+ parse( f )
205
+ end
206
+ end
207
+
208
+ #
209
+ # Calls _block_ with each consecutive document in the YAML
210
+ # stream contained in _io_.
211
+ #
212
+ # File.open( 'many-docs.yaml' ) do |yf|
213
+ # YAML.each_document( yf ) do |ydoc|
214
+ # ## ydoc contains the single object
215
+ # ## from the YAML document
216
+ # end
217
+ # end
218
+ #
219
+ def self.each_document( io, &block )
220
+ warn "#{caller[0]}: YAML.each_document is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
221
+ parser.load_documents( io, &block )
222
+ end
223
+
224
+ #
225
+ # Calls _block_ with each consecutive document in the YAML
226
+ # stream contained in _io_.
227
+ #
228
+ # File.open( 'many-docs.yaml' ) do |yf|
229
+ # YAML.load_documents( yf ) do |ydoc|
230
+ # ## ydoc contains the single object
231
+ # ## from the YAML document
232
+ # end
233
+ # end
234
+ #
235
+ def self.load_documents( io, &doc_proc )
236
+ parser.load_documents( io, &doc_proc )
237
+ end
238
+
239
+ #
240
+ # Calls _block_ with a tree of +YAML::BaseNodes+, one tree for
241
+ # each consecutive document in the YAML stream contained in _io_.
242
+ #
243
+ # File.open( 'many-docs.yaml' ) do |yf|
244
+ # YAML.each_node( yf ) do |ydoc|
245
+ # ## ydoc contains a tree of nodes
246
+ # ## from the YAML document
247
+ # end
248
+ # end
249
+ #
250
+ def self.each_node( io, &doc_proc )
251
+ warn "#{caller[0]}: YAML.each_node is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
252
+ generic_parser.load_documents( io, &doc_proc )
253
+ end
254
+
255
+ #
256
+ # Calls _block_ with a tree of +YAML::BaseNodes+, one tree for
257
+ # each consecutive document in the YAML stream contained in _io_.
258
+ #
259
+ # File.open( 'many-docs.yaml' ) do |yf|
260
+ # YAML.parse_documents( yf ) do |ydoc|
261
+ # ## ydoc contains a tree of nodes
262
+ # ## from the YAML document
263
+ # end
264
+ # end
265
+ #
266
+ def self.parse_documents( io, &doc_proc )
267
+ warn "#{caller[0]}: YAML.parse_documents is deprecated, use load_stream" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
268
+ self.each_node( io, &doc_proc )
269
+ end
270
+
271
+ #
272
+ # Loads all documents from the current _io_ stream,
273
+ # returning a +YAML::Stream+ object containing all
274
+ # loaded documents.
275
+ #
276
+ def self.load_stream( io )
277
+ d = nil
278
+ parser.load_documents( io ) do |doc|
279
+ d = Stream.new if not d
280
+ d.add( doc )
281
+ end
282
+ return d
283
+ end
284
+
285
+ #
286
+ # Returns a YAML stream containing each of the items in +objs+,
287
+ # each having their own document.
288
+ #
289
+ # YAML.dump_stream( 0, [], {} )
290
+ # #=> --- 0
291
+ # --- []
292
+ # --- {}
293
+ #
294
+ def self.dump_stream( *objs )
295
+ d = Stream.new
296
+ objs.each do |doc|
297
+ d.add( doc )
298
+ end
299
+ d.emit
300
+ end
301
+
302
+ #
303
+ # Add a global handler for a YAML domain type.
304
+ #
305
+ def self.add_domain_type( domain, type_tag, &transfer_proc )
306
+ resolver.add_type( "tag:#{ domain }:#{ type_tag }", transfer_proc )
307
+ end
308
+
309
+ #
310
+ # Add a transfer method for a builtin type
311
+ #
312
+ def self.add_builtin_type( type_tag, &transfer_proc )
313
+ resolver.add_type( "tag:yaml.org,2002:#{ type_tag }", transfer_proc )
314
+ end
315
+
316
+ #
317
+ # Add a transfer method for a builtin type
318
+ #
319
+ def self.add_ruby_type( type_tag, &transfer_proc )
320
+ warn "#{caller[0]}: YAML.add_ruby_type is deprecated, use add_domain_type" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
321
+ resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc )
322
+ end
323
+
324
+ #
325
+ # Add a private document type
326
+ #
327
+ def self.add_private_type( type_re, &transfer_proc )
328
+ warn "#{caller[0]}: YAML.add_private_type is deprecated, use add_domain_type" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
329
+ resolver.add_type( "x-private:" + type_re, transfer_proc )
330
+ end
331
+
332
+ #
333
+ # Detect typing of a string
334
+ #
335
+ def self.detect_implicit( val )
336
+ warn "#{caller[0]}: YAML.detect_implicit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
337
+ resolver.detect_implicit( val )
338
+ end
339
+
340
+ #
341
+ # Convert a type_id to a taguri
342
+ #
343
+ def self.tagurize( val )
344
+ warn "#{caller[0]}: YAML.tagurize is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
345
+ resolver.tagurize( val )
346
+ end
347
+
348
+ #
349
+ # Apply a transfer method to a Ruby object
350
+ #
351
+ def self.transfer( type_id, obj )
352
+ warn "#{caller[0]}: YAML.transfer is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
353
+ resolver.transfer( tagurize( type_id ), obj )
354
+ end
355
+
356
+ #
357
+ # Apply any implicit a node may qualify for
358
+ #
359
+ def self.try_implicit( obj )
360
+ warn "#{caller[0]}: YAML.try_implicit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
361
+ transfer( detect_implicit( obj ), obj )
362
+ end
363
+
364
+ #
365
+ # Method to extract colon-seperated type and class, returning
366
+ # the type and the constant of the class
367
+ #
368
+ def self.read_type_class( type, obj_class )
369
+ warn "#{caller[0]}: YAML.read_type_class is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
370
+ type, tclass = type.split( ':', 4 ).last(2)
371
+ tclass.split( "::" ).each { |c| obj_class = obj_class.const_get( c ) } if tclass
372
+ return [ type, obj_class ]
373
+ end
374
+
375
+ #
376
+ # Allocate blank object
377
+ #
378
+ def self.object_maker( obj_class, val )
379
+ warn "#{caller[0]}: YAML.object_maker is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
380
+ if Hash === val
381
+ o = obj_class.allocate
382
+ val.each_pair { |k,v|
383
+ o.instance_variable_set("@#{k}", v)
384
+ }
385
+ o
386
+ else
387
+ raise Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect
388
+ end
389
+ end
390
+
391
+ #
392
+ # Allocate an Emitter if needed
393
+ #
394
+ def self.quick_emit( oid, opts = {}, &e )
395
+ warn "#{caller[0]}: YAML.quick_emit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
396
+ out =
397
+ if opts.is_a? Emitter
398
+ opts
399
+ else
400
+ emitter.reset( opts )
401
+ end
402
+ out.emit( oid, &e )
403
+ end
404
+
405
+ end
406
+
407
+ module Kernel
408
+ #
409
+ # ryan:: You know how Kernel.p is a really convenient way to dump ruby
410
+ # structures? The only downside is that it's not as legible as
411
+ # YAML.
412
+ #
413
+ # _why:: (listening)
414
+ #
415
+ # ryan:: I know you don't want to urinate all over your users' namespaces.
416
+ # But, on the other hand, convenience of dumping for debugging is,
417
+ # IMO, a big YAML use case.
418
+ #
419
+ # _why:: Go nuts! Have a pony parade!
420
+ #
421
+ # ryan:: Either way, I certainly will have a pony parade.
422
+ #
423
+
424
+ # Prints any supplied _objects_ out in YAML. Intended as
425
+ # a variation on +Kernel::p+.
426
+ #
427
+ # S = Struct.new(:name, :state)
428
+ # s = S['dave', 'TX']
429
+ # y s
430
+ #
431
+ # _produces:_
432
+ #
433
+ # --- !ruby/struct:S
434
+ # name: dave
435
+ # state: TX
436
+ #
437
+ def y( object, *objects )
438
+ objects.unshift object
439
+ puts( if objects.length == 1
440
+ Syck.dump( *objects )
441
+ else
442
+ Syck.dump_stream( *objects )
443
+ end )
444
+ end
445
+ private :y
446
+ end
447
+
448
+