syck 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest.erb +8 -0
- data/.gemtest +0 -0
- data/CHANGELOG.rdoc +6 -0
- data/Manifest.txt +52 -0
- data/README.rdoc +51 -0
- data/Rakefile +32 -0
- data/ext/syck/bytecode.c +1165 -0
- data/ext/syck/emitter.c +1247 -0
- data/ext/syck/extconf.h +3 -0
- data/ext/syck/extconf.rb +5 -0
- data/ext/syck/gram.c +1894 -0
- data/ext/syck/gram.h +79 -0
- data/ext/syck/handler.c +173 -0
- data/ext/syck/implicit.c +2990 -0
- data/ext/syck/node.c +407 -0
- data/ext/syck/rubyext.c +2328 -0
- data/ext/syck/syck.c +524 -0
- data/ext/syck/syck.h +453 -0
- data/ext/syck/token.c +2724 -0
- data/ext/syck/yaml2byte.c +259 -0
- data/ext/syck/yamlbyte.h +171 -0
- data/lib/syck.bundle +0 -0
- data/lib/syck.rb +447 -0
- data/lib/syck/baseemitter.rb +242 -0
- data/lib/syck/basenode.rb +222 -0
- data/lib/syck/constants.rb +45 -0
- data/lib/syck/encoding.rb +35 -0
- data/lib/syck/error.rb +34 -0
- data/lib/syck/loader.rb +14 -0
- data/lib/syck/rubytypes.rb +450 -0
- data/lib/syck/stream.rb +41 -0
- data/lib/syck/stringio.rb +85 -0
- data/lib/syck/syck.rb +16 -0
- data/lib/syck/tag.rb +95 -0
- data/lib/syck/types.rb +192 -0
- data/lib/syck/yamlnode.rb +54 -0
- data/lib/syck/ypath.rb +54 -0
- data/lib/yaml/syck.rb +14 -0
- data/test/helper.rb +2 -0
- data/test/test_array.rb +13 -0
- data/test/test_boolean.rb +36 -0
- data/test/test_class.rb +11 -0
- data/test/test_exception.rb +45 -0
- data/test/test_hash.rb +24 -0
- data/test/test_null.rb +19 -0
- data/test/test_omap.rb +55 -0
- data/test/test_set.rb +30 -0
- data/test/test_string.rb +44 -0
- data/test/test_struct.rb +32 -0
- data/test/test_symbol.rb +21 -0
- data/test/test_time.rb +23 -0
- data/test/test_yaml.rb +1403 -0
- data/test/test_yaml_properties.rb +63 -0
- metadata +187 -0
data/ext/syck/node.c
ADDED
@@ -0,0 +1,407 @@
|
|
1
|
+
/*
|
2
|
+
* node.c
|
3
|
+
*
|
4
|
+
* $Author$
|
5
|
+
*
|
6
|
+
* Copyright (C) 2003 why the lucky stiff
|
7
|
+
*/
|
8
|
+
|
9
|
+
#include "ruby/ruby.h"
|
10
|
+
#include "syck.h"
|
11
|
+
|
12
|
+
/*
|
13
|
+
* Node allocation functions
|
14
|
+
*/
|
15
|
+
SyckNode *
|
16
|
+
syck_alloc_node( enum syck_kind_tag type )
|
17
|
+
{
|
18
|
+
SyckNode *s;
|
19
|
+
|
20
|
+
s = S_ALLOC( SyckNode );
|
21
|
+
s->kind = type;
|
22
|
+
s->id = 0;
|
23
|
+
s->type_id = NULL;
|
24
|
+
s->anchor = NULL;
|
25
|
+
s->shortcut = NULL;
|
26
|
+
|
27
|
+
return s;
|
28
|
+
}
|
29
|
+
|
30
|
+
void
|
31
|
+
syck_free_node( SyckNode *n )
|
32
|
+
{
|
33
|
+
syck_free_members( n );
|
34
|
+
if ( n->type_id != NULL )
|
35
|
+
{
|
36
|
+
S_FREE( n->type_id );
|
37
|
+
n->type_id = NULL;
|
38
|
+
}
|
39
|
+
if ( n->anchor != NULL )
|
40
|
+
{
|
41
|
+
S_FREE( n->anchor );
|
42
|
+
n->anchor = NULL;
|
43
|
+
}
|
44
|
+
S_FREE( n );
|
45
|
+
}
|
46
|
+
|
47
|
+
SyckNode *
|
48
|
+
syck_alloc_map(void)
|
49
|
+
{
|
50
|
+
SyckNode *n;
|
51
|
+
struct SyckMap *m;
|
52
|
+
|
53
|
+
m = S_ALLOC( struct SyckMap );
|
54
|
+
m->style = map_none;
|
55
|
+
m->idx = 0;
|
56
|
+
m->capa = ALLOC_CT;
|
57
|
+
m->keys = S_ALLOC_N( SYMID, m->capa );
|
58
|
+
m->values = S_ALLOC_N( SYMID, m->capa );
|
59
|
+
|
60
|
+
n = syck_alloc_node( syck_map_kind );
|
61
|
+
n->data.pairs = m;
|
62
|
+
|
63
|
+
return n;
|
64
|
+
}
|
65
|
+
|
66
|
+
SyckNode *
|
67
|
+
syck_alloc_seq(void)
|
68
|
+
{
|
69
|
+
SyckNode *n;
|
70
|
+
struct SyckSeq *s;
|
71
|
+
|
72
|
+
s = S_ALLOC( struct SyckSeq );
|
73
|
+
s->style = seq_none;
|
74
|
+
s->idx = 0;
|
75
|
+
s->capa = ALLOC_CT;
|
76
|
+
s->items = S_ALLOC_N( SYMID, s->capa );
|
77
|
+
|
78
|
+
n = syck_alloc_node( syck_seq_kind );
|
79
|
+
n->data.list = s;
|
80
|
+
|
81
|
+
return n;
|
82
|
+
}
|
83
|
+
|
84
|
+
SyckNode *
|
85
|
+
syck_alloc_str(void)
|
86
|
+
{
|
87
|
+
SyckNode *n;
|
88
|
+
struct SyckStr *s;
|
89
|
+
|
90
|
+
s = S_ALLOC( struct SyckStr );
|
91
|
+
s->len = 0;
|
92
|
+
s->ptr = NULL;
|
93
|
+
s->style = scalar_none;
|
94
|
+
|
95
|
+
n = syck_alloc_node( syck_str_kind );
|
96
|
+
n->data.str = s;
|
97
|
+
|
98
|
+
return n;
|
99
|
+
}
|
100
|
+
|
101
|
+
SyckNode *
|
102
|
+
syck_new_str( const char *str, enum scalar_style style )
|
103
|
+
{
|
104
|
+
return syck_new_str2( str, strlen( str ), style );
|
105
|
+
}
|
106
|
+
|
107
|
+
SyckNode *
|
108
|
+
syck_new_str2( const char *str, long len, enum scalar_style style )
|
109
|
+
{
|
110
|
+
SyckNode *n;
|
111
|
+
|
112
|
+
n = syck_alloc_str();
|
113
|
+
n->data.str->ptr = S_ALLOC_N( char, len + 1 );
|
114
|
+
n->data.str->len = len;
|
115
|
+
n->data.str->style = style;
|
116
|
+
memcpy( n->data.str->ptr, str, len );
|
117
|
+
n->data.str->ptr[len] = '\0';
|
118
|
+
|
119
|
+
return n;
|
120
|
+
}
|
121
|
+
|
122
|
+
void
|
123
|
+
syck_replace_str( SyckNode *n, char *str, enum scalar_style style )
|
124
|
+
{
|
125
|
+
syck_replace_str2( n, str, strlen( str ), style );
|
126
|
+
}
|
127
|
+
|
128
|
+
void
|
129
|
+
syck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style )
|
130
|
+
{
|
131
|
+
if ( n->data.str->ptr != NULL )
|
132
|
+
{
|
133
|
+
S_FREE( n->data.str->ptr );
|
134
|
+
n->data.str->ptr = NULL;
|
135
|
+
n->data.str->len = 0;
|
136
|
+
}
|
137
|
+
n->data.str->ptr = S_ALLOC_N( char, len + 1 );
|
138
|
+
n->data.str->len = len;
|
139
|
+
n->data.str->style = style;
|
140
|
+
memcpy( n->data.str->ptr, str, len );
|
141
|
+
n->data.str->ptr[len] = '\0';
|
142
|
+
}
|
143
|
+
|
144
|
+
void
|
145
|
+
syck_str_blow_away_commas( SyckNode *n )
|
146
|
+
{
|
147
|
+
char *go, *end;
|
148
|
+
|
149
|
+
go = n->data.str->ptr;
|
150
|
+
end = go + n->data.str->len;
|
151
|
+
while ( *(++go) != '\0' )
|
152
|
+
{
|
153
|
+
if ( *go == ',' )
|
154
|
+
{
|
155
|
+
n->data.str->len -= 1;
|
156
|
+
memmove( go, go + 1, end - go );
|
157
|
+
end -= 1;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
char *
|
163
|
+
syck_str_read( SyckNode *n )
|
164
|
+
{
|
165
|
+
ASSERT( n != NULL );
|
166
|
+
return n->data.str->ptr;
|
167
|
+
}
|
168
|
+
|
169
|
+
SyckNode *
|
170
|
+
syck_new_map( SYMID key, SYMID value )
|
171
|
+
{
|
172
|
+
SyckNode *n;
|
173
|
+
|
174
|
+
n = syck_alloc_map();
|
175
|
+
syck_map_add( n, key, value );
|
176
|
+
|
177
|
+
return n;
|
178
|
+
}
|
179
|
+
|
180
|
+
void
|
181
|
+
syck_map_empty( SyckNode *n )
|
182
|
+
{
|
183
|
+
struct SyckMap *m;
|
184
|
+
ASSERT( n != NULL );
|
185
|
+
ASSERT( n->data.list != NULL );
|
186
|
+
|
187
|
+
S_FREE( n->data.pairs->keys );
|
188
|
+
S_FREE( n->data.pairs->values );
|
189
|
+
m = n->data.pairs;
|
190
|
+
m->idx = 0;
|
191
|
+
m->capa = ALLOC_CT;
|
192
|
+
m->keys = S_ALLOC_N( SYMID, m->capa );
|
193
|
+
m->values = S_ALLOC_N( SYMID, m->capa );
|
194
|
+
}
|
195
|
+
|
196
|
+
void
|
197
|
+
syck_map_add( SyckNode *map, SYMID key, SYMID value )
|
198
|
+
{
|
199
|
+
struct SyckMap *m;
|
200
|
+
long idx;
|
201
|
+
|
202
|
+
ASSERT( map != NULL );
|
203
|
+
ASSERT( map->data.pairs != NULL );
|
204
|
+
|
205
|
+
m = map->data.pairs;
|
206
|
+
idx = m->idx;
|
207
|
+
m->idx += 1;
|
208
|
+
if ( m->idx > m->capa )
|
209
|
+
{
|
210
|
+
m->capa += ALLOC_CT;
|
211
|
+
S_REALLOC_N( m->keys, SYMID, m->capa );
|
212
|
+
S_REALLOC_N( m->values, SYMID, m->capa );
|
213
|
+
}
|
214
|
+
m->keys[idx] = key;
|
215
|
+
m->values[idx] = value;
|
216
|
+
}
|
217
|
+
|
218
|
+
void
|
219
|
+
syck_map_update( SyckNode *map1, SyckNode *map2 )
|
220
|
+
{
|
221
|
+
struct SyckMap *m1, *m2;
|
222
|
+
long new_idx, new_capa;
|
223
|
+
ASSERT( map1 != NULL );
|
224
|
+
ASSERT( map2 != NULL );
|
225
|
+
|
226
|
+
m1 = map1->data.pairs;
|
227
|
+
m2 = map2->data.pairs;
|
228
|
+
if ( m2->idx < 1 ) return;
|
229
|
+
|
230
|
+
new_idx = m1->idx;
|
231
|
+
new_idx += m2->idx;
|
232
|
+
new_capa = m1->capa;
|
233
|
+
while ( new_idx > new_capa )
|
234
|
+
{
|
235
|
+
new_capa += ALLOC_CT;
|
236
|
+
}
|
237
|
+
if ( new_capa > m1->capa )
|
238
|
+
{
|
239
|
+
m1->capa = new_capa;
|
240
|
+
S_REALLOC_N( m1->keys, SYMID, m1->capa );
|
241
|
+
S_REALLOC_N( m1->values, SYMID, m1->capa );
|
242
|
+
}
|
243
|
+
for ( new_idx = 0; new_idx < m2->idx; m1->idx++, new_idx++ )
|
244
|
+
{
|
245
|
+
m1->keys[m1->idx] = m2->keys[new_idx];
|
246
|
+
m1->values[m1->idx] = m2->values[new_idx];
|
247
|
+
}
|
248
|
+
}
|
249
|
+
|
250
|
+
long
|
251
|
+
syck_map_count( SyckNode *map )
|
252
|
+
{
|
253
|
+
ASSERT( map != NULL );
|
254
|
+
ASSERT( map->data.pairs != NULL );
|
255
|
+
return map->data.pairs->idx;
|
256
|
+
}
|
257
|
+
|
258
|
+
void
|
259
|
+
syck_map_assign( SyckNode *map, enum map_part p, long idx, SYMID id )
|
260
|
+
{
|
261
|
+
struct SyckMap *m;
|
262
|
+
|
263
|
+
ASSERT( map != NULL );
|
264
|
+
m = map->data.pairs;
|
265
|
+
ASSERT( m != NULL );
|
266
|
+
if ( p == map_key )
|
267
|
+
{
|
268
|
+
m->keys[idx] = id;
|
269
|
+
}
|
270
|
+
else
|
271
|
+
{
|
272
|
+
m->values[idx] = id;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
|
276
|
+
SYMID
|
277
|
+
syck_map_read( SyckNode *map, enum map_part p, long idx )
|
278
|
+
{
|
279
|
+
struct SyckMap *m;
|
280
|
+
|
281
|
+
ASSERT( map != NULL );
|
282
|
+
m = map->data.pairs;
|
283
|
+
ASSERT( m != NULL );
|
284
|
+
if ( p == map_key )
|
285
|
+
{
|
286
|
+
return m->keys[idx];
|
287
|
+
}
|
288
|
+
else
|
289
|
+
{
|
290
|
+
return m->values[idx];
|
291
|
+
}
|
292
|
+
}
|
293
|
+
|
294
|
+
SyckNode *
|
295
|
+
syck_new_seq( SYMID value )
|
296
|
+
{
|
297
|
+
SyckNode *n;
|
298
|
+
|
299
|
+
n = syck_alloc_seq();
|
300
|
+
syck_seq_add( n, value );
|
301
|
+
|
302
|
+
return n;
|
303
|
+
}
|
304
|
+
|
305
|
+
void
|
306
|
+
syck_seq_empty( SyckNode *n )
|
307
|
+
{
|
308
|
+
struct SyckSeq *s;
|
309
|
+
ASSERT( n != NULL );
|
310
|
+
ASSERT( n->data.list != NULL );
|
311
|
+
|
312
|
+
S_FREE( n->data.list->items );
|
313
|
+
s = n->data.list;
|
314
|
+
s->idx = 0;
|
315
|
+
s->capa = ALLOC_CT;
|
316
|
+
s->items = S_ALLOC_N( SYMID, s->capa );
|
317
|
+
}
|
318
|
+
|
319
|
+
void
|
320
|
+
syck_seq_add( SyckNode *arr, SYMID value )
|
321
|
+
{
|
322
|
+
struct SyckSeq *s;
|
323
|
+
long idx;
|
324
|
+
|
325
|
+
ASSERT( arr != NULL );
|
326
|
+
ASSERT( arr->data.list != NULL );
|
327
|
+
|
328
|
+
s = arr->data.list;
|
329
|
+
idx = s->idx;
|
330
|
+
s->idx += 1;
|
331
|
+
if ( s->idx > s->capa )
|
332
|
+
{
|
333
|
+
s->capa += ALLOC_CT;
|
334
|
+
S_REALLOC_N( s->items, SYMID, s->capa );
|
335
|
+
}
|
336
|
+
s->items[idx] = value;
|
337
|
+
}
|
338
|
+
|
339
|
+
long
|
340
|
+
syck_seq_count( SyckNode *seq )
|
341
|
+
{
|
342
|
+
ASSERT( seq != NULL );
|
343
|
+
ASSERT( seq->data.list != NULL );
|
344
|
+
return seq->data.list->idx;
|
345
|
+
}
|
346
|
+
|
347
|
+
void
|
348
|
+
syck_seq_assign( SyckNode *seq, long idx, SYMID id )
|
349
|
+
{
|
350
|
+
struct SyckSeq *s;
|
351
|
+
|
352
|
+
ASSERT( map != NULL );
|
353
|
+
s = seq->data.list;
|
354
|
+
ASSERT( m != NULL );
|
355
|
+
s->items[idx] = id;
|
356
|
+
}
|
357
|
+
|
358
|
+
SYMID
|
359
|
+
syck_seq_read( SyckNode *seq, long idx )
|
360
|
+
{
|
361
|
+
struct SyckSeq *s;
|
362
|
+
|
363
|
+
ASSERT( seq != NULL );
|
364
|
+
s = seq->data.list;
|
365
|
+
ASSERT( s != NULL );
|
366
|
+
return s->items[idx];
|
367
|
+
}
|
368
|
+
|
369
|
+
void
|
370
|
+
syck_free_members( SyckNode *n )
|
371
|
+
{
|
372
|
+
if ( n == NULL ) return;
|
373
|
+
|
374
|
+
switch ( n->kind )
|
375
|
+
{
|
376
|
+
case syck_str_kind:
|
377
|
+
if ( n->data.str != NULL )
|
378
|
+
{
|
379
|
+
S_FREE( n->data.str->ptr );
|
380
|
+
n->data.str->ptr = NULL;
|
381
|
+
n->data.str->len = 0;
|
382
|
+
S_FREE( n->data.str );
|
383
|
+
n->data.str = NULL;
|
384
|
+
}
|
385
|
+
break;
|
386
|
+
|
387
|
+
case syck_seq_kind:
|
388
|
+
if ( n->data.list != NULL )
|
389
|
+
{
|
390
|
+
S_FREE( n->data.list->items );
|
391
|
+
S_FREE( n->data.list );
|
392
|
+
n->data.list = NULL;
|
393
|
+
}
|
394
|
+
break;
|
395
|
+
|
396
|
+
case syck_map_kind:
|
397
|
+
if ( n->data.pairs != NULL )
|
398
|
+
{
|
399
|
+
S_FREE( n->data.pairs->keys );
|
400
|
+
S_FREE( n->data.pairs->values );
|
401
|
+
S_FREE( n->data.pairs );
|
402
|
+
n->data.pairs = NULL;
|
403
|
+
}
|
404
|
+
break;
|
405
|
+
}
|
406
|
+
}
|
407
|
+
|
data/ext/syck/rubyext.c
ADDED
@@ -0,0 +1,2328 @@
|
|
1
|
+
/* -*- indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* rubyext.c
|
4
|
+
*
|
5
|
+
* $Author$
|
6
|
+
*
|
7
|
+
* Copyright (C) 2003-2005 why the lucky stiff
|
8
|
+
*/
|
9
|
+
|
10
|
+
#include "ruby/ruby.h"
|
11
|
+
#include "ruby/encoding.h"
|
12
|
+
#include "syck.h"
|
13
|
+
#include <sys/types.h>
|
14
|
+
#include <time.h>
|
15
|
+
|
16
|
+
typedef struct RVALUE {
|
17
|
+
union {
|
18
|
+
#if 0
|
19
|
+
struct {
|
20
|
+
unsigned long flags; /* always 0 for freed obj */
|
21
|
+
struct RVALUE *next;
|
22
|
+
} free;
|
23
|
+
#endif
|
24
|
+
struct RBasic basic;
|
25
|
+
struct RObject object;
|
26
|
+
struct RClass klass;
|
27
|
+
/*struct RFloat flonum;*/
|
28
|
+
/*struct RString string;*/
|
29
|
+
struct RArray array;
|
30
|
+
/*struct RRegexp regexp;*/
|
31
|
+
struct RHash hash;
|
32
|
+
/*struct RData data;*/
|
33
|
+
struct RStruct rstruct;
|
34
|
+
/*struct RBignum bignum;*/
|
35
|
+
/*struct RFile file;*/
|
36
|
+
} as;
|
37
|
+
} RVALUE;
|
38
|
+
|
39
|
+
typedef struct {
|
40
|
+
long hash;
|
41
|
+
char *buffer;
|
42
|
+
long length;
|
43
|
+
long remaining;
|
44
|
+
int printed;
|
45
|
+
} bytestring_t;
|
46
|
+
|
47
|
+
#define RUBY_DOMAIN "ruby.yaml.org,2002"
|
48
|
+
|
49
|
+
/*
|
50
|
+
* symbols and constants
|
51
|
+
*/
|
52
|
+
static ID s_new, s_utc, s_at, s_to_f, s_to_i, s_read, s_binmode, s_call, s_cmp, s_transfer, s_update, s_dup, s_haskey, s_match, s_keys, s_unpack, s_tr_bang, s_default_set, s_tag_read_class, s_tag_subclasses, s_resolver, s_push, s_emitter, s_level, s_detect_implicit, s_node_import, s_out, s_input, s_intern, s_transform, s_yaml_new, s_yaml_initialize, s_node_export, s_to_yaml, s_write, s_set_resolver, s_each;
|
53
|
+
static ID s_tags, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, s_style_set, s_value, s_value_set, s_parse;
|
54
|
+
static VALUE sym_model, sym_generic, sym_input, sym_bytecode;
|
55
|
+
static VALUE sym_scalar, sym_seq, sym_map;
|
56
|
+
static VALUE sym_1quote, sym_2quote, sym_fold, sym_literal, sym_plain, sym_inline;
|
57
|
+
static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter, cDateTime;
|
58
|
+
static VALUE oDefaultResolver, oGenericResolver;
|
59
|
+
|
60
|
+
/*
|
61
|
+
* my private collection of numerical oddities.
|
62
|
+
*/
|
63
|
+
static double S_zero(void) { return 0.0; }
|
64
|
+
static double S_one(void) { return 1.0; }
|
65
|
+
static double S_inf(void) { return S_one() / S_zero(); }
|
66
|
+
static double S_nan(void) { return S_zero() / S_zero(); }
|
67
|
+
|
68
|
+
static VALUE syck_node_transform( VALUE );
|
69
|
+
|
70
|
+
/*
|
71
|
+
* handler prototypes
|
72
|
+
*/
|
73
|
+
SYMID rb_syck_load_handler _((SyckParser *, SyckNode *));
|
74
|
+
void rb_syck_err_handler _((SyckParser *, const char *));
|
75
|
+
SyckNode * rb_syck_bad_anchor_handler _((SyckParser *, char *));
|
76
|
+
void rb_syck_output_handler _((SyckEmitter *, char *, long));
|
77
|
+
void rb_syck_emitter_handler _((SyckEmitter *, st_data_t));
|
78
|
+
int syck_parser_assign_io _((SyckParser *, VALUE *));
|
79
|
+
VALUE syck_scalar_alloc _((VALUE class));
|
80
|
+
VALUE syck_seq_alloc _((VALUE class));
|
81
|
+
VALUE syck_map_alloc _((VALUE class));
|
82
|
+
|
83
|
+
struct parser_xtra {
|
84
|
+
VALUE data; /* Borrowed this idea from marshal.c to fix [ruby-core:8067] problem */
|
85
|
+
VALUE proc;
|
86
|
+
VALUE resolver;
|
87
|
+
int taint;
|
88
|
+
};
|
89
|
+
|
90
|
+
struct emitter_xtra {
|
91
|
+
VALUE oid;
|
92
|
+
VALUE data;
|
93
|
+
VALUE port;
|
94
|
+
};
|
95
|
+
|
96
|
+
/*
|
97
|
+
* Convert YAML to bytecode
|
98
|
+
*/
|
99
|
+
VALUE
|
100
|
+
rb_syck_compile(VALUE self, VALUE port)
|
101
|
+
{
|
102
|
+
SYMID oid;
|
103
|
+
int taint;
|
104
|
+
char *ret;
|
105
|
+
VALUE bc;
|
106
|
+
bytestring_t *sav = NULL;
|
107
|
+
void *data = NULL;
|
108
|
+
|
109
|
+
SyckParser *parser = syck_new_parser();
|
110
|
+
taint = syck_parser_assign_io(parser, &port);
|
111
|
+
syck_parser_handler( parser, syck_yaml2byte_handler );
|
112
|
+
syck_parser_error_handler( parser, NULL );
|
113
|
+
syck_parser_implicit_typing( parser, 0 );
|
114
|
+
syck_parser_taguri_expansion( parser, 0 );
|
115
|
+
oid = syck_parse( parser );
|
116
|
+
if (!syck_lookup_sym( parser, oid, &data )) {
|
117
|
+
rb_raise(rb_eSyntaxError, "root node <%p> not found", (void *)oid);
|
118
|
+
}
|
119
|
+
sav = data;
|
120
|
+
|
121
|
+
ret = S_ALLOCA_N( char, strlen( sav->buffer ) + 3 );
|
122
|
+
ret[0] = '\0';
|
123
|
+
strcat( ret, "D\n" );
|
124
|
+
strcat( ret, sav->buffer );
|
125
|
+
|
126
|
+
syck_free_parser( parser );
|
127
|
+
|
128
|
+
bc = rb_str_new2( ret );
|
129
|
+
if ( taint ) OBJ_TAINT( bc );
|
130
|
+
return bc;
|
131
|
+
}
|
132
|
+
|
133
|
+
/*
|
134
|
+
* read from io.
|
135
|
+
*/
|
136
|
+
long
|
137
|
+
rb_syck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip )
|
138
|
+
{
|
139
|
+
long len = 0;
|
140
|
+
|
141
|
+
ASSERT( str != NULL );
|
142
|
+
max_size -= skip;
|
143
|
+
|
144
|
+
if ( max_size <= 0 ) max_size = 0;
|
145
|
+
else
|
146
|
+
{
|
147
|
+
/*
|
148
|
+
* call io#read.
|
149
|
+
*/
|
150
|
+
VALUE src = (VALUE)str->ptr;
|
151
|
+
VALUE n = LONG2NUM(max_size);
|
152
|
+
VALUE str2 = rb_funcall2(src, s_read, 1, &n);
|
153
|
+
if (!NIL_P(str2))
|
154
|
+
{
|
155
|
+
StringValue(str2);
|
156
|
+
len = RSTRING_LEN(str2);
|
157
|
+
memcpy( buf + skip, RSTRING_PTR(str2), len );
|
158
|
+
}
|
159
|
+
}
|
160
|
+
len += skip;
|
161
|
+
buf[len] = '\0';
|
162
|
+
return len;
|
163
|
+
}
|
164
|
+
|
165
|
+
/*
|
166
|
+
* determine: are we reading from a string or io?
|
167
|
+
* (returns tainted? boolean)
|
168
|
+
*/
|
169
|
+
int
|
170
|
+
syck_parser_assign_io(SyckParser *parser, VALUE *pport)
|
171
|
+
{
|
172
|
+
int taint = Qtrue;
|
173
|
+
VALUE tmp, port = *pport;
|
174
|
+
if (!NIL_P(tmp = rb_check_string_type(port))) {
|
175
|
+
taint = OBJ_TAINTED(port); /* original taintedness */
|
176
|
+
port = tmp;
|
177
|
+
syck_parser_str( parser, RSTRING_PTR(port), RSTRING_LEN(port), NULL );
|
178
|
+
}
|
179
|
+
else if (rb_respond_to(port, s_read)) {
|
180
|
+
if (rb_respond_to(port, s_binmode)) {
|
181
|
+
rb_funcall2(port, s_binmode, 0, 0);
|
182
|
+
}
|
183
|
+
syck_parser_str( parser, (char *)port, 0, rb_syck_io_str_read );
|
184
|
+
}
|
185
|
+
else {
|
186
|
+
rb_raise(rb_eTypeError, "instance of IO needed");
|
187
|
+
}
|
188
|
+
*pport = port;
|
189
|
+
return taint;
|
190
|
+
}
|
191
|
+
|
192
|
+
/*
|
193
|
+
* Get value in hash by key, forcing an empty hash if nil.
|
194
|
+
*/
|
195
|
+
VALUE
|
196
|
+
syck_get_hash_aref(VALUE hsh, VALUE key)
|
197
|
+
{
|
198
|
+
VALUE val = rb_hash_aref( hsh, key );
|
199
|
+
if ( NIL_P( val ) )
|
200
|
+
{
|
201
|
+
val = rb_hash_new();
|
202
|
+
rb_hash_aset(hsh, key, val);
|
203
|
+
}
|
204
|
+
return val;
|
205
|
+
}
|
206
|
+
|
207
|
+
/*
|
208
|
+
* creating timestamps
|
209
|
+
*/
|
210
|
+
struct mktime_arg {
|
211
|
+
const char *str;
|
212
|
+
long len;
|
213
|
+
};
|
214
|
+
|
215
|
+
VALUE
|
216
|
+
mktime_do(VALUE varg)
|
217
|
+
{
|
218
|
+
struct mktime_arg *arg = (struct mktime_arg *)varg;
|
219
|
+
VALUE time;
|
220
|
+
const char *str = arg->str;
|
221
|
+
long len = arg->len;
|
222
|
+
const char *ptr = str;
|
223
|
+
VALUE year = INT2FIX(0);
|
224
|
+
VALUE mon = INT2FIX(0);
|
225
|
+
VALUE day = INT2FIX(0);
|
226
|
+
VALUE hour = INT2FIX(0);
|
227
|
+
VALUE min = INT2FIX(0);
|
228
|
+
VALUE sec = INT2FIX(0);
|
229
|
+
long usec;
|
230
|
+
|
231
|
+
/* Year*/
|
232
|
+
if ( ptr[0] != '\0' && len > 0 ) {
|
233
|
+
year = INT2FIX(strtol(ptr, NULL, 10));
|
234
|
+
}
|
235
|
+
|
236
|
+
/* Month*/
|
237
|
+
ptr += 4;
|
238
|
+
if ( ptr[0] != '\0' && len > ptr - str ) {
|
239
|
+
while ( !ISDIGIT( *ptr ) ) ptr++;
|
240
|
+
mon = INT2FIX(strtol(ptr, NULL, 10));
|
241
|
+
}
|
242
|
+
|
243
|
+
/* Day*/
|
244
|
+
ptr += 2;
|
245
|
+
if ( ptr[0] != '\0' && len > ptr - str ) {
|
246
|
+
while ( !ISDIGIT( *ptr ) ) ptr++;
|
247
|
+
day = INT2FIX(strtol(ptr, NULL, 10));
|
248
|
+
}
|
249
|
+
|
250
|
+
/* Hour*/
|
251
|
+
ptr += 2;
|
252
|
+
if ( ptr[0] != '\0' && len > ptr - str ) {
|
253
|
+
while ( !ISDIGIT( *ptr ) ) ptr++;
|
254
|
+
hour = INT2FIX(strtol(ptr, NULL, 10));
|
255
|
+
}
|
256
|
+
|
257
|
+
/* Minute */
|
258
|
+
ptr += 2;
|
259
|
+
if ( ptr[0] != '\0' && len > ptr - str ) {
|
260
|
+
while ( !ISDIGIT( *ptr ) ) ptr++;
|
261
|
+
min = INT2FIX(strtol(ptr, NULL, 10));
|
262
|
+
}
|
263
|
+
|
264
|
+
/* Second */
|
265
|
+
ptr += 2;
|
266
|
+
if ( ptr[0] != '\0' && len > ptr - str ) {
|
267
|
+
while ( !ISDIGIT( *ptr ) ) ptr++;
|
268
|
+
sec = INT2FIX(strtol(ptr, NULL, 10));
|
269
|
+
}
|
270
|
+
|
271
|
+
/* Millisecond */
|
272
|
+
ptr += 2;
|
273
|
+
if ( len > ptr - str && *ptr == '.' )
|
274
|
+
{
|
275
|
+
char padded[] = "000000";
|
276
|
+
const int padding = (int)(sizeof(padded) - 1);
|
277
|
+
const char *end = ptr + 1;
|
278
|
+
const char *begin = end;
|
279
|
+
ptrdiff_t length;
|
280
|
+
while ( ISDIGIT( *end ) ) end++;
|
281
|
+
if ((length = (end - begin)) > padding) length = padding;
|
282
|
+
MEMCPY(padded, begin, char, length);
|
283
|
+
usec = strtol(padded, NULL, 10);
|
284
|
+
}
|
285
|
+
else
|
286
|
+
{
|
287
|
+
usec = 0;
|
288
|
+
}
|
289
|
+
|
290
|
+
/* Time Zone*/
|
291
|
+
while ( len > ptr - str && *ptr != 'Z' && *ptr != '+' && *ptr != '-' && *ptr != '\0' ) ptr++;
|
292
|
+
if ( len > ptr - str && ( *ptr == '-' || *ptr == '+' ) )
|
293
|
+
{
|
294
|
+
time_t tz_offset = strtol(ptr, NULL, 10) * 3600;
|
295
|
+
VALUE tmp;
|
296
|
+
|
297
|
+
while ( *ptr != ':' && *ptr != '\0' ) ptr++;
|
298
|
+
if ( *ptr == ':' )
|
299
|
+
{
|
300
|
+
ptr += 1;
|
301
|
+
if ( tz_offset < 0 )
|
302
|
+
{
|
303
|
+
tz_offset -= strtol(ptr, NULL, 10) * 60;
|
304
|
+
}
|
305
|
+
else
|
306
|
+
{
|
307
|
+
tz_offset += strtol(ptr, NULL, 10) * 60;
|
308
|
+
}
|
309
|
+
}
|
310
|
+
|
311
|
+
/* Make TZ time*/
|
312
|
+
time = rb_funcall(rb_cTime, s_utc, 6, year, mon, day, hour, min, sec);
|
313
|
+
tmp = rb_funcall(time, s_to_i, 0);
|
314
|
+
tmp = rb_funcall(tmp, '-', 1, LONG2FIX(tz_offset));
|
315
|
+
return rb_funcall(rb_cTime, s_at, 2, tmp, LONG2NUM(usec));
|
316
|
+
}
|
317
|
+
else
|
318
|
+
{
|
319
|
+
/* Make UTC time*/
|
320
|
+
return rb_funcall(rb_cTime, s_utc, 7, year, mon, day, hour, min, sec, LONG2NUM(usec));
|
321
|
+
}
|
322
|
+
}
|
323
|
+
|
324
|
+
VALUE
|
325
|
+
mktime_r(VALUE varg)
|
326
|
+
{
|
327
|
+
struct mktime_arg *arg = (struct mktime_arg *)varg;
|
328
|
+
|
329
|
+
if (!cDateTime) {
|
330
|
+
/*
|
331
|
+
* Load Date module
|
332
|
+
*/
|
333
|
+
rb_require("date");
|
334
|
+
cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
|
335
|
+
}
|
336
|
+
return rb_funcall(cDateTime, s_parse, 1, rb_str_new(arg->str, arg->len));
|
337
|
+
}
|
338
|
+
|
339
|
+
VALUE
|
340
|
+
rb_syck_mktime(const char *str, long len)
|
341
|
+
{
|
342
|
+
struct mktime_arg a;
|
343
|
+
|
344
|
+
a.str = str;
|
345
|
+
a.len = len;
|
346
|
+
return rb_rescue2(mktime_do, (VALUE)&a, mktime_r, (VALUE)&a, rb_eArgError, NULL);
|
347
|
+
}
|
348
|
+
|
349
|
+
/*
|
350
|
+
* handles merging of an array of hashes
|
351
|
+
* (see http://www.yaml.org/type/merge/)
|
352
|
+
*/
|
353
|
+
VALUE
|
354
|
+
syck_merge_i(VALUE entry, VALUE hsh )
|
355
|
+
{
|
356
|
+
VALUE tmp;
|
357
|
+
if ( !NIL_P(tmp = rb_check_convert_type(entry, T_HASH, "Hash", "to_hash")) )
|
358
|
+
{
|
359
|
+
entry = tmp;
|
360
|
+
rb_funcall( hsh, s_update, 1, entry );
|
361
|
+
}
|
362
|
+
return Qnil;
|
363
|
+
}
|
364
|
+
|
365
|
+
/*
|
366
|
+
* default handler for ruby.yaml.org types
|
367
|
+
*/
|
368
|
+
int
|
369
|
+
yaml_org_handler( SyckNode *n, VALUE *ref )
|
370
|
+
{
|
371
|
+
char *type_id = n->type_id;
|
372
|
+
int transferred = 0;
|
373
|
+
long i = 0;
|
374
|
+
VALUE obj = Qnil;
|
375
|
+
|
376
|
+
if ( type_id != NULL && strncmp( type_id, "tag:yaml.org,2002:", 18 ) == 0 )
|
377
|
+
{
|
378
|
+
type_id += 18;
|
379
|
+
}
|
380
|
+
|
381
|
+
switch (n->kind)
|
382
|
+
{
|
383
|
+
case syck_str_kind:
|
384
|
+
transferred = 1;
|
385
|
+
if ( type_id == NULL )
|
386
|
+
{
|
387
|
+
obj = rb_str_new( n->data.str->ptr, n->data.str->len );
|
388
|
+
}
|
389
|
+
else if ( strcmp( type_id, "null" ) == 0 )
|
390
|
+
{
|
391
|
+
obj = Qnil;
|
392
|
+
}
|
393
|
+
else if ( strcmp( type_id, "binary" ) == 0 )
|
394
|
+
{
|
395
|
+
VALUE arr;
|
396
|
+
obj = rb_str_new( n->data.str->ptr, n->data.str->len );
|
397
|
+
rb_funcall( obj, s_tr_bang, 2, rb_str_new2( "\n\t " ), rb_str_new2( "" ) );
|
398
|
+
arr = rb_funcall( obj, s_unpack, 1, rb_str_new2( "m" ) );
|
399
|
+
obj = rb_ary_shift( arr );
|
400
|
+
}
|
401
|
+
else if ( strcmp( type_id, "bool#yes" ) == 0 )
|
402
|
+
{
|
403
|
+
obj = Qtrue;
|
404
|
+
}
|
405
|
+
else if ( strcmp( type_id, "bool#no" ) == 0 )
|
406
|
+
{
|
407
|
+
obj = Qfalse;
|
408
|
+
}
|
409
|
+
else if ( strcmp( type_id, "int#hex" ) == 0 )
|
410
|
+
{
|
411
|
+
syck_str_blow_away_commas( n );
|
412
|
+
obj = rb_cstr2inum( n->data.str->ptr, 16 );
|
413
|
+
}
|
414
|
+
else if ( strcmp( type_id, "int#oct" ) == 0 )
|
415
|
+
{
|
416
|
+
syck_str_blow_away_commas( n );
|
417
|
+
obj = rb_cstr2inum( n->data.str->ptr, 8 );
|
418
|
+
}
|
419
|
+
else if ( strcmp( type_id, "int#base60" ) == 0 )
|
420
|
+
{
|
421
|
+
char *ptr, *end;
|
422
|
+
long sixty = 1;
|
423
|
+
long total = 0;
|
424
|
+
syck_str_blow_away_commas( n );
|
425
|
+
ptr = n->data.str->ptr;
|
426
|
+
end = n->data.str->ptr + n->data.str->len;
|
427
|
+
while ( end > ptr )
|
428
|
+
{
|
429
|
+
long bnum = 0;
|
430
|
+
char *colon = end - 1;
|
431
|
+
while ( colon >= ptr && *colon != ':' )
|
432
|
+
{
|
433
|
+
colon--;
|
434
|
+
}
|
435
|
+
if ( colon >= ptr && *colon == ':' ) *colon = '\0';
|
436
|
+
|
437
|
+
bnum = strtol( colon + 1, NULL, 10 );
|
438
|
+
total += bnum * sixty;
|
439
|
+
sixty *= 60;
|
440
|
+
end = colon;
|
441
|
+
}
|
442
|
+
obj = INT2FIX(total);
|
443
|
+
}
|
444
|
+
else if ( strncmp( type_id, "int", 3 ) == 0 )
|
445
|
+
{
|
446
|
+
syck_str_blow_away_commas( n );
|
447
|
+
obj = rb_cstr2inum( n->data.str->ptr, 10 );
|
448
|
+
}
|
449
|
+
else if ( strcmp( type_id, "float#base60" ) == 0 )
|
450
|
+
{
|
451
|
+
char *ptr, *end;
|
452
|
+
long sixty = 1;
|
453
|
+
double total = 0.0;
|
454
|
+
syck_str_blow_away_commas( n );
|
455
|
+
ptr = n->data.str->ptr;
|
456
|
+
end = n->data.str->ptr + n->data.str->len;
|
457
|
+
while ( end > ptr )
|
458
|
+
{
|
459
|
+
double bnum = 0;
|
460
|
+
char *colon = end - 1;
|
461
|
+
while ( colon >= ptr && *colon != ':' )
|
462
|
+
{
|
463
|
+
colon--;
|
464
|
+
}
|
465
|
+
if ( colon >= ptr && *colon == ':' ) *colon = '\0';
|
466
|
+
|
467
|
+
bnum = strtod( colon + 1, NULL );
|
468
|
+
total += bnum * sixty;
|
469
|
+
sixty *= 60;
|
470
|
+
end = colon;
|
471
|
+
}
|
472
|
+
obj = rb_float_new( total );
|
473
|
+
}
|
474
|
+
else if ( strcmp( type_id, "float#nan" ) == 0 )
|
475
|
+
{
|
476
|
+
obj = rb_float_new( S_nan() );
|
477
|
+
}
|
478
|
+
else if ( strcmp( type_id, "float#inf" ) == 0 )
|
479
|
+
{
|
480
|
+
obj = rb_float_new( S_inf() );
|
481
|
+
}
|
482
|
+
else if ( strcmp( type_id, "float#neginf" ) == 0 )
|
483
|
+
{
|
484
|
+
obj = rb_float_new( -S_inf() );
|
485
|
+
}
|
486
|
+
else if ( strncmp( type_id, "float", 5 ) == 0 )
|
487
|
+
{
|
488
|
+
double f;
|
489
|
+
syck_str_blow_away_commas( n );
|
490
|
+
f = strtod( n->data.str->ptr, NULL );
|
491
|
+
obj = rb_float_new( f );
|
492
|
+
}
|
493
|
+
else if ( strcmp( type_id, "timestamp#iso8601" ) == 0 )
|
494
|
+
{
|
495
|
+
obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );
|
496
|
+
}
|
497
|
+
else if ( strcmp( type_id, "timestamp#spaced" ) == 0 )
|
498
|
+
{
|
499
|
+
obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );
|
500
|
+
}
|
501
|
+
else if ( strcmp( type_id, "timestamp#ymd" ) == 0 )
|
502
|
+
{
|
503
|
+
char *ptr = n->data.str->ptr;
|
504
|
+
VALUE year, mon, day;
|
505
|
+
|
506
|
+
/* Year*/
|
507
|
+
ptr[4] = '\0';
|
508
|
+
year = INT2FIX(strtol(ptr, NULL, 10));
|
509
|
+
|
510
|
+
/* Month*/
|
511
|
+
ptr += 4;
|
512
|
+
while ( !ISDIGIT( *ptr ) ) ptr++;
|
513
|
+
mon = INT2FIX(strtol(ptr, NULL, 10));
|
514
|
+
|
515
|
+
/* Day*/
|
516
|
+
ptr += 2;
|
517
|
+
while ( !ISDIGIT( *ptr ) ) ptr++;
|
518
|
+
day = INT2FIX(strtol(ptr, NULL, 10));
|
519
|
+
|
520
|
+
if ( !cDate ) {
|
521
|
+
/*
|
522
|
+
* Load Date module
|
523
|
+
*/
|
524
|
+
rb_require( "date" );
|
525
|
+
cDate = rb_const_get( rb_cObject, rb_intern("Date") );
|
526
|
+
}
|
527
|
+
|
528
|
+
obj = rb_funcall( cDate, s_new, 3, year, mon, day );
|
529
|
+
}
|
530
|
+
else if ( strncmp( type_id, "timestamp", 9 ) == 0 )
|
531
|
+
{
|
532
|
+
obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );
|
533
|
+
}
|
534
|
+
else if ( strncmp( type_id, "merge", 5 ) == 0 )
|
535
|
+
{
|
536
|
+
obj = rb_funcall( cMergeKey, s_new, 0 );
|
537
|
+
}
|
538
|
+
else if ( strncmp( type_id, "default", 7 ) == 0 )
|
539
|
+
{
|
540
|
+
obj = rb_funcall( cDefaultKey, s_new, 0 );
|
541
|
+
}
|
542
|
+
else if ( n->data.str->style == scalar_plain &&
|
543
|
+
n->data.str->len > 1 &&
|
544
|
+
strncmp( n->data.str->ptr, ":", 1 ) == 0 )
|
545
|
+
{
|
546
|
+
obj = rb_funcall( oDefaultResolver, s_transfer, 2,
|
547
|
+
rb_str_new2( "tag:ruby.yaml.org,2002:sym" ),
|
548
|
+
rb_str_new( n->data.str->ptr + 1, n->data.str->len - 1 ) );
|
549
|
+
}
|
550
|
+
else if ( strcmp( type_id, "str" ) == 0 )
|
551
|
+
{
|
552
|
+
obj = rb_str_new( n->data.str->ptr, n->data.str->len );
|
553
|
+
rb_enc_associate(obj, rb_utf8_encoding());
|
554
|
+
}
|
555
|
+
else
|
556
|
+
{
|
557
|
+
transferred = 0;
|
558
|
+
obj = rb_str_new( n->data.str->ptr, n->data.str->len );
|
559
|
+
}
|
560
|
+
break;
|
561
|
+
|
562
|
+
case syck_seq_kind:
|
563
|
+
if ( type_id == NULL || strcmp( type_id, "seq" ) == 0 )
|
564
|
+
{
|
565
|
+
transferred = 1;
|
566
|
+
}
|
567
|
+
obj = rb_ary_new2( n->data.list->idx );
|
568
|
+
for ( i = 0; i < n->data.list->idx; i++ )
|
569
|
+
{
|
570
|
+
rb_ary_store( obj, i, syck_seq_read( n, i ) );
|
571
|
+
}
|
572
|
+
break;
|
573
|
+
|
574
|
+
case syck_map_kind:
|
575
|
+
if ( type_id == NULL || strcmp( type_id, "map" ) == 0 )
|
576
|
+
{
|
577
|
+
transferred = 1;
|
578
|
+
}
|
579
|
+
obj = rb_hash_new();
|
580
|
+
for ( i = 0; i < n->data.pairs->idx; i++ )
|
581
|
+
{
|
582
|
+
VALUE k = syck_map_read( n, map_key, i );
|
583
|
+
VALUE v = syck_map_read( n, map_value, i );
|
584
|
+
int skip_aset = 0;
|
585
|
+
|
586
|
+
/*
|
587
|
+
* Handle merge keys
|
588
|
+
*/
|
589
|
+
if ( rb_obj_is_kind_of( k, cMergeKey ) )
|
590
|
+
{
|
591
|
+
VALUE tmp;
|
592
|
+
if ( !NIL_P(tmp = rb_check_convert_type(v, T_HASH, "Hash", "to_hash")) )
|
593
|
+
{
|
594
|
+
VALUE dup = rb_funcall( tmp, s_dup, 0 );
|
595
|
+
rb_funcall( dup, s_update, 1, obj );
|
596
|
+
obj = dup;
|
597
|
+
skip_aset = 1;
|
598
|
+
}
|
599
|
+
else if ( !NIL_P(tmp = rb_check_array_type(v)) )
|
600
|
+
{
|
601
|
+
VALUE end = rb_ary_pop( tmp );
|
602
|
+
VALUE tmph = rb_check_convert_type(end, T_HASH, "Hash", "to_hash");
|
603
|
+
if ( !NIL_P(tmph) )
|
604
|
+
{
|
605
|
+
VALUE dup = rb_funcall( tmph, s_dup, 0 );
|
606
|
+
tmp = rb_ary_reverse( tmp );
|
607
|
+
rb_ary_push( tmp, obj );
|
608
|
+
rb_block_call( tmp, s_each, 0, 0, syck_merge_i, dup );
|
609
|
+
obj = dup;
|
610
|
+
skip_aset = 1;
|
611
|
+
}
|
612
|
+
}
|
613
|
+
}
|
614
|
+
else if ( rb_obj_is_kind_of( k, cDefaultKey ) )
|
615
|
+
{
|
616
|
+
rb_funcall( obj, s_default_set, 1, v );
|
617
|
+
skip_aset = 1;
|
618
|
+
}
|
619
|
+
|
620
|
+
if ( ! skip_aset )
|
621
|
+
{
|
622
|
+
rb_hash_aset( obj, k, v );
|
623
|
+
}
|
624
|
+
}
|
625
|
+
break;
|
626
|
+
}
|
627
|
+
|
628
|
+
*ref = obj;
|
629
|
+
return transferred;
|
630
|
+
}
|
631
|
+
|
632
|
+
static void syck_node_mark( SyckNode *n );
|
633
|
+
|
634
|
+
/*
|
635
|
+
* {native mode} node handler
|
636
|
+
* - Converts data into native Ruby types
|
637
|
+
*/
|
638
|
+
SYMID
|
639
|
+
rb_syck_load_handler(SyckParser *p, SyckNode *n)
|
640
|
+
{
|
641
|
+
VALUE obj = Qnil;
|
642
|
+
struct parser_xtra *bonus = (struct parser_xtra *)p->bonus;
|
643
|
+
VALUE resolver = bonus->resolver;
|
644
|
+
if ( NIL_P( resolver ) )
|
645
|
+
{
|
646
|
+
resolver = oDefaultResolver;
|
647
|
+
}
|
648
|
+
|
649
|
+
/*
|
650
|
+
* Create node,
|
651
|
+
*/
|
652
|
+
obj = rb_funcall( resolver, s_node_import, 1, Data_Wrap_Struct( cNode, NULL, NULL, n ) );
|
653
|
+
|
654
|
+
/*
|
655
|
+
* ID already set, let's alter the symbol table to accept the new object
|
656
|
+
*/
|
657
|
+
if (n->id > 0 && !NIL_P(obj))
|
658
|
+
{
|
659
|
+
MEMCPY((void *)n->id, (void *)obj, RVALUE, 1);
|
660
|
+
MEMZERO((void *)obj, RVALUE, 1);
|
661
|
+
obj = n->id;
|
662
|
+
}
|
663
|
+
|
664
|
+
if ( bonus->taint) OBJ_TAINT( obj );
|
665
|
+
if ( bonus->proc != 0 ) rb_funcall(bonus->proc, s_call, 1, obj);
|
666
|
+
|
667
|
+
rb_hash_aset(bonus->data, INT2FIX(RHASH_SIZE(bonus->data)), obj);
|
668
|
+
return obj;
|
669
|
+
}
|
670
|
+
|
671
|
+
/*
|
672
|
+
* friendly errors.
|
673
|
+
*/
|
674
|
+
void
|
675
|
+
rb_syck_err_handler(SyckParser *p, const char *msg)
|
676
|
+
{
|
677
|
+
char *endl = p->cursor;
|
678
|
+
|
679
|
+
while ( *endl != '\0' && *endl != '\n' )
|
680
|
+
endl++;
|
681
|
+
|
682
|
+
endl[0] = '\0';
|
683
|
+
rb_raise(rb_eArgError, "%s on line %d, col %"PRIdPTRDIFF": `%s'",
|
684
|
+
msg,
|
685
|
+
p->linect,
|
686
|
+
p->cursor - p->lineptr,
|
687
|
+
p->lineptr);
|
688
|
+
}
|
689
|
+
|
690
|
+
/*
|
691
|
+
* provide bad anchor object to the parser.
|
692
|
+
*/
|
693
|
+
SyckNode *
|
694
|
+
rb_syck_bad_anchor_handler(SyckParser *p, char *a)
|
695
|
+
{
|
696
|
+
VALUE anchor_name = rb_str_new2( a );
|
697
|
+
SyckNode *badanc = syck_new_map( rb_str_new2( "name" ), anchor_name );
|
698
|
+
badanc->type_id = syck_strndup( "tag:ruby.yaml.org,2002:object:YAML::Syck::BadAlias", 53 );
|
699
|
+
return badanc;
|
700
|
+
}
|
701
|
+
|
702
|
+
/*
|
703
|
+
* data loaded based on the model requested.
|
704
|
+
*/
|
705
|
+
void
|
706
|
+
syck_set_model(VALUE p, VALUE input, VALUE model)
|
707
|
+
{
|
708
|
+
SyckParser *parser;
|
709
|
+
Data_Get_Struct(p, SyckParser, parser);
|
710
|
+
syck_parser_handler( parser, rb_syck_load_handler );
|
711
|
+
/* WARN: gonna be obsoleted soon!! */
|
712
|
+
if ( model == sym_generic )
|
713
|
+
{
|
714
|
+
rb_funcall( p, s_set_resolver, 1, oGenericResolver );
|
715
|
+
}
|
716
|
+
syck_parser_implicit_typing( parser, 1 );
|
717
|
+
syck_parser_taguri_expansion( parser, 1 );
|
718
|
+
|
719
|
+
if ( NIL_P( input ) )
|
720
|
+
{
|
721
|
+
input = rb_ivar_get( p, s_input );
|
722
|
+
}
|
723
|
+
if ( input == sym_bytecode )
|
724
|
+
{
|
725
|
+
syck_parser_set_input_type( parser, syck_bytecode_utf8 );
|
726
|
+
}
|
727
|
+
else
|
728
|
+
{
|
729
|
+
syck_parser_set_input_type( parser, syck_yaml_utf8 );
|
730
|
+
}
|
731
|
+
syck_parser_error_handler( parser, rb_syck_err_handler );
|
732
|
+
syck_parser_bad_anchor_handler( parser, rb_syck_bad_anchor_handler );
|
733
|
+
}
|
734
|
+
|
735
|
+
static int
|
736
|
+
syck_st_mark_nodes( char *key, SyckNode *n, char *arg )
|
737
|
+
{
|
738
|
+
if ( n != (void *)1 ) syck_node_mark( n );
|
739
|
+
return ST_CONTINUE;
|
740
|
+
}
|
741
|
+
|
742
|
+
/*
|
743
|
+
* mark parser nodes
|
744
|
+
*/
|
745
|
+
static void
|
746
|
+
syck_mark_parser(SyckParser *parser)
|
747
|
+
{
|
748
|
+
struct parser_xtra *bonus = (struct parser_xtra *)parser->bonus;
|
749
|
+
rb_gc_mark_maybe(parser->root);
|
750
|
+
rb_gc_mark_maybe(parser->root_on_error);
|
751
|
+
rb_gc_mark( bonus->data );
|
752
|
+
rb_gc_mark( bonus->proc );
|
753
|
+
rb_gc_mark( bonus->resolver );
|
754
|
+
|
755
|
+
if ( parser->anchors != NULL )
|
756
|
+
{
|
757
|
+
st_foreach( parser->anchors, syck_st_mark_nodes, 0 );
|
758
|
+
}
|
759
|
+
if ( parser->bad_anchors != NULL )
|
760
|
+
{
|
761
|
+
st_foreach( parser->bad_anchors, syck_st_mark_nodes, 0 );
|
762
|
+
}
|
763
|
+
}
|
764
|
+
|
765
|
+
/*
|
766
|
+
* Free the parser and any bonus attachment.
|
767
|
+
*/
|
768
|
+
void
|
769
|
+
rb_syck_free_parser(SyckParser *p)
|
770
|
+
{
|
771
|
+
S_FREE( p->bonus );
|
772
|
+
syck_free_parser(p);
|
773
|
+
}
|
774
|
+
|
775
|
+
/*
|
776
|
+
* YAML::Syck::Parser.allocate
|
777
|
+
*/
|
778
|
+
VALUE syck_parser_s_alloc _((VALUE));
|
779
|
+
VALUE
|
780
|
+
syck_parser_s_alloc(VALUE class)
|
781
|
+
{
|
782
|
+
VALUE pobj;
|
783
|
+
SyckParser *parser = syck_new_parser();
|
784
|
+
|
785
|
+
parser->bonus = S_ALLOC( struct parser_xtra );
|
786
|
+
S_MEMZERO( parser->bonus, struct parser_xtra, 1 );
|
787
|
+
|
788
|
+
pobj = Data_Wrap_Struct( class, syck_mark_parser, rb_syck_free_parser, parser );
|
789
|
+
|
790
|
+
syck_parser_set_root_on_error( parser, Qnil );
|
791
|
+
|
792
|
+
return pobj;
|
793
|
+
}
|
794
|
+
|
795
|
+
/*
|
796
|
+
* YAML::Syck::Parser.initialize( resolver, options )
|
797
|
+
*/
|
798
|
+
static VALUE
|
799
|
+
syck_parser_initialize(int argc, VALUE *argv, VALUE self)
|
800
|
+
{
|
801
|
+
VALUE options;
|
802
|
+
if (rb_scan_args(argc, argv, "01", &options) == 0)
|
803
|
+
{
|
804
|
+
options = rb_hash_new();
|
805
|
+
}
|
806
|
+
else
|
807
|
+
{
|
808
|
+
Check_Type(options, T_HASH);
|
809
|
+
}
|
810
|
+
rb_ivar_set(self, s_options, options);
|
811
|
+
rb_ivar_set(self, s_input, Qnil);
|
812
|
+
return self;
|
813
|
+
}
|
814
|
+
|
815
|
+
/*
|
816
|
+
* YAML::Syck::Parser.bufsize = Integer
|
817
|
+
*/
|
818
|
+
static VALUE
|
819
|
+
syck_parser_bufsize_set(VALUE self, VALUE size)
|
820
|
+
{
|
821
|
+
SyckParser *parser;
|
822
|
+
|
823
|
+
if ( rb_respond_to( size, s_to_i ) ) {
|
824
|
+
int n = NUM2INT(rb_funcall(size, s_to_i, 0));
|
825
|
+
Data_Get_Struct(self, SyckParser, parser);
|
826
|
+
parser->bufsize = n;
|
827
|
+
}
|
828
|
+
return self;
|
829
|
+
}
|
830
|
+
|
831
|
+
/*
|
832
|
+
* YAML::Syck::Parser.bufsize => Integer
|
833
|
+
*/
|
834
|
+
static VALUE
|
835
|
+
syck_parser_bufsize_get(VALUE self)
|
836
|
+
{
|
837
|
+
SyckParser *parser;
|
838
|
+
|
839
|
+
Data_Get_Struct(self, SyckParser, parser);
|
840
|
+
return INT2FIX( parser->bufsize );
|
841
|
+
}
|
842
|
+
|
843
|
+
/*
|
844
|
+
* YAML::Syck::Parser.load( IO or String )
|
845
|
+
*/
|
846
|
+
VALUE
|
847
|
+
syck_parser_load(int argc, VALUE *argv, VALUE self)
|
848
|
+
{
|
849
|
+
VALUE port, proc, model, input;
|
850
|
+
SyckParser *parser;
|
851
|
+
struct parser_xtra *bonus;
|
852
|
+
|
853
|
+
rb_scan_args(argc, argv, "11", &port, &proc);
|
854
|
+
|
855
|
+
input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input );
|
856
|
+
model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model );
|
857
|
+
Data_Get_Struct(self, SyckParser, parser);
|
858
|
+
syck_set_model( self, input, model );
|
859
|
+
|
860
|
+
bonus = (struct parser_xtra *)parser->bonus;
|
861
|
+
bonus->taint = syck_parser_assign_io(parser, &port);
|
862
|
+
bonus->data = rb_hash_new();
|
863
|
+
bonus->resolver = rb_attr_get( self, s_resolver );
|
864
|
+
if ( NIL_P( proc ) ) bonus->proc = 0;
|
865
|
+
else bonus->proc = proc;
|
866
|
+
|
867
|
+
return syck_parse( parser );
|
868
|
+
}
|
869
|
+
|
870
|
+
/*
|
871
|
+
* YAML::Syck::Parser.load_documents( IO or String ) { |doc| }
|
872
|
+
*/
|
873
|
+
VALUE
|
874
|
+
syck_parser_load_documents(int argc, VALUE *argv, VALUE self)
|
875
|
+
{
|
876
|
+
VALUE port, proc, v, input, model;
|
877
|
+
SyckParser *parser;
|
878
|
+
struct parser_xtra *bonus;
|
879
|
+
|
880
|
+
rb_scan_args(argc, argv, "1&", &port, &proc);
|
881
|
+
|
882
|
+
input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input );
|
883
|
+
model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model );
|
884
|
+
Data_Get_Struct(self, SyckParser, parser);
|
885
|
+
syck_set_model( self, input, model );
|
886
|
+
|
887
|
+
bonus = (struct parser_xtra *)parser->bonus;
|
888
|
+
bonus->taint = syck_parser_assign_io(parser, &port);
|
889
|
+
bonus->resolver = rb_attr_get( self, s_resolver );
|
890
|
+
bonus->proc = 0;
|
891
|
+
|
892
|
+
while ( 1 )
|
893
|
+
{
|
894
|
+
/* Reset hash for tracking nodes */
|
895
|
+
bonus->data = rb_hash_new();
|
896
|
+
|
897
|
+
/* Parse a document */
|
898
|
+
v = syck_parse( parser );
|
899
|
+
if ( parser->eof == 1 )
|
900
|
+
{
|
901
|
+
break;
|
902
|
+
}
|
903
|
+
|
904
|
+
/* Pass document to block */
|
905
|
+
rb_funcall( proc, s_call, 1, v );
|
906
|
+
}
|
907
|
+
|
908
|
+
return Qnil;
|
909
|
+
}
|
910
|
+
|
911
|
+
/*
|
912
|
+
* YAML::Syck::Parser#set_resolver
|
913
|
+
*/
|
914
|
+
VALUE
|
915
|
+
syck_parser_set_resolver(VALUE self, VALUE resolver)
|
916
|
+
{
|
917
|
+
rb_ivar_set( self, s_resolver, resolver );
|
918
|
+
return self;
|
919
|
+
}
|
920
|
+
|
921
|
+
/*
|
922
|
+
* YAML::Syck::Resolver.initialize
|
923
|
+
*/
|
924
|
+
static VALUE
|
925
|
+
syck_resolver_initialize(VALUE self)
|
926
|
+
{
|
927
|
+
rb_ivar_set(self, s_tags, rb_hash_new());
|
928
|
+
return self;
|
929
|
+
}
|
930
|
+
|
931
|
+
/*
|
932
|
+
* YAML::Syck::Resolver#add_type
|
933
|
+
*/
|
934
|
+
VALUE
|
935
|
+
syck_resolver_add_type(VALUE self, VALUE taguri, VALUE cls)
|
936
|
+
{
|
937
|
+
VALUE tags = rb_attr_get(self, s_tags);
|
938
|
+
rb_hash_aset( tags, taguri, cls );
|
939
|
+
return Qnil;
|
940
|
+
}
|
941
|
+
|
942
|
+
/*
|
943
|
+
* YAML::Syck::Resolver#use_types_at
|
944
|
+
*/
|
945
|
+
VALUE
|
946
|
+
syck_resolver_use_types_at(VALUE self, VALUE hsh)
|
947
|
+
{
|
948
|
+
rb_ivar_set( self, s_tags, hsh );
|
949
|
+
return Qnil;
|
950
|
+
}
|
951
|
+
|
952
|
+
/*
|
953
|
+
* YAML::Syck::Resolver#detect_implicit
|
954
|
+
*/
|
955
|
+
VALUE
|
956
|
+
syck_resolver_detect_implicit(VALUE self, VALUE val)
|
957
|
+
{
|
958
|
+
return rb_str_new2( "" );
|
959
|
+
}
|
960
|
+
|
961
|
+
/*
|
962
|
+
* YAML::Syck::Resolver#node_import
|
963
|
+
*/
|
964
|
+
VALUE
|
965
|
+
syck_resolver_node_import(VALUE self, VALUE node)
|
966
|
+
{
|
967
|
+
SyckNode *n;
|
968
|
+
VALUE obj = Qnil;
|
969
|
+
int i = 0;
|
970
|
+
Data_Get_Struct(node, SyckNode, n);
|
971
|
+
|
972
|
+
switch (n->kind)
|
973
|
+
{
|
974
|
+
case syck_str_kind:
|
975
|
+
obj = rb_str_new( n->data.str->ptr, n->data.str->len );
|
976
|
+
break;
|
977
|
+
|
978
|
+
case syck_seq_kind:
|
979
|
+
obj = rb_ary_new2( n->data.list->idx );
|
980
|
+
for ( i = 0; i < n->data.list->idx; i++ )
|
981
|
+
{
|
982
|
+
rb_ary_store( obj, i, syck_seq_read( n, i ) );
|
983
|
+
}
|
984
|
+
break;
|
985
|
+
|
986
|
+
case syck_map_kind:
|
987
|
+
obj = rb_hash_new();
|
988
|
+
for ( i = 0; i < n->data.pairs->idx; i++ )
|
989
|
+
{
|
990
|
+
VALUE k = syck_map_read( n, map_key, i );
|
991
|
+
VALUE v = syck_map_read( n, map_value, i );
|
992
|
+
int skip_aset = 0;
|
993
|
+
|
994
|
+
/*
|
995
|
+
* Handle merge keys
|
996
|
+
*/
|
997
|
+
if ( rb_obj_is_kind_of( k, cMergeKey ) )
|
998
|
+
{
|
999
|
+
if ( rb_obj_is_kind_of( v, rb_cHash ) )
|
1000
|
+
{
|
1001
|
+
VALUE dup = rb_funcall( v, s_dup, 0 );
|
1002
|
+
rb_funcall( dup, s_update, 1, obj );
|
1003
|
+
obj = dup;
|
1004
|
+
skip_aset = 1;
|
1005
|
+
}
|
1006
|
+
else if ( rb_obj_is_kind_of( v, rb_cArray ) )
|
1007
|
+
{
|
1008
|
+
VALUE end = rb_ary_pop( v );
|
1009
|
+
if ( rb_obj_is_kind_of( end, rb_cHash ) )
|
1010
|
+
{
|
1011
|
+
VALUE dup = rb_funcall( end, s_dup, 0 );
|
1012
|
+
v = rb_ary_reverse( v );
|
1013
|
+
rb_ary_push( v, obj );
|
1014
|
+
rb_block_call( v, s_each, 0, 0, syck_merge_i, dup );
|
1015
|
+
obj = dup;
|
1016
|
+
skip_aset = 1;
|
1017
|
+
}
|
1018
|
+
}
|
1019
|
+
}
|
1020
|
+
else if ( rb_obj_is_kind_of( k, cDefaultKey ) )
|
1021
|
+
{
|
1022
|
+
rb_funcall( obj, s_default_set, 1, v );
|
1023
|
+
skip_aset = 1;
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
if ( ! skip_aset )
|
1027
|
+
{
|
1028
|
+
rb_hash_aset( obj, k, v );
|
1029
|
+
}
|
1030
|
+
}
|
1031
|
+
break;
|
1032
|
+
}
|
1033
|
+
|
1034
|
+
if ( n->type_id != NULL )
|
1035
|
+
{
|
1036
|
+
obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj );
|
1037
|
+
}
|
1038
|
+
return obj;
|
1039
|
+
}
|
1040
|
+
|
1041
|
+
/*
|
1042
|
+
* Set instance variables
|
1043
|
+
*/
|
1044
|
+
VALUE
|
1045
|
+
syck_set_ivars(VALUE vars, VALUE obj)
|
1046
|
+
{
|
1047
|
+
VALUE ivname = rb_ary_entry( vars, 0 );
|
1048
|
+
char *ivn;
|
1049
|
+
StringValue( ivname );
|
1050
|
+
ivn = S_ALLOCA_N( char, RSTRING_LEN(ivname) + 2 );
|
1051
|
+
ivn[0] = '@';
|
1052
|
+
ivn[1] = '\0';
|
1053
|
+
strncat( ivn, RSTRING_PTR(ivname), RSTRING_LEN(ivname) );
|
1054
|
+
rb_iv_set( obj, ivn, rb_ary_entry( vars, 1 ) );
|
1055
|
+
return Qnil;
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
/*
|
1059
|
+
* YAML::Syck::Resolver#const_find
|
1060
|
+
*/
|
1061
|
+
VALUE
|
1062
|
+
syck_const_find(VALUE const_name)
|
1063
|
+
{
|
1064
|
+
VALUE tclass = rb_cObject;
|
1065
|
+
VALUE tparts = rb_str_split( const_name, "::" );
|
1066
|
+
int i = 0;
|
1067
|
+
for ( i = 0; i < RARRAY_LEN(tparts); i++ ) {
|
1068
|
+
VALUE tpart = rb_to_id( rb_ary_entry( tparts, i ) );
|
1069
|
+
if ( !rb_const_defined( tclass, tpart ) ) return Qnil;
|
1070
|
+
tclass = rb_const_get( tclass, tpart );
|
1071
|
+
}
|
1072
|
+
return tclass;
|
1073
|
+
}
|
1074
|
+
|
1075
|
+
/*
|
1076
|
+
* YAML::Syck::Resolver#transfer
|
1077
|
+
*/
|
1078
|
+
VALUE
|
1079
|
+
syck_resolver_transfer(VALUE self, VALUE type, VALUE val)
|
1080
|
+
{
|
1081
|
+
if (NIL_P(type) || RSTRING_LEN(StringValue(type)) == 0)
|
1082
|
+
{
|
1083
|
+
type = rb_funcall( self, s_detect_implicit, 1, val );
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
if ( ! (NIL_P(type) || RSTRING_LEN(StringValue(type)) == 0) )
|
1087
|
+
{
|
1088
|
+
VALUE str_xprivate = rb_str_new2( "x-private" );
|
1089
|
+
VALUE colon = rb_str_new2( ":" );
|
1090
|
+
VALUE tags = rb_attr_get(self, s_tags);
|
1091
|
+
VALUE target_class = rb_hash_aref( tags, type );
|
1092
|
+
VALUE subclass = target_class;
|
1093
|
+
VALUE obj = Qnil;
|
1094
|
+
|
1095
|
+
/*
|
1096
|
+
* Should no tag match exactly, check for subclass format
|
1097
|
+
*/
|
1098
|
+
if ( NIL_P( target_class ) )
|
1099
|
+
{
|
1100
|
+
VALUE subclass_parts = rb_ary_new();
|
1101
|
+
VALUE parts = rb_str_split( type, ":" );
|
1102
|
+
|
1103
|
+
while ( RARRAY_LEN(parts) > 1 )
|
1104
|
+
{
|
1105
|
+
VALUE partial;
|
1106
|
+
rb_ary_unshift( subclass_parts, rb_ary_pop( parts ) );
|
1107
|
+
partial = rb_ary_join( parts, colon );
|
1108
|
+
target_class = rb_hash_aref( tags, partial );
|
1109
|
+
if ( NIL_P( target_class ) )
|
1110
|
+
{
|
1111
|
+
rb_str_append( partial, colon );
|
1112
|
+
target_class = rb_hash_aref( tags, partial );
|
1113
|
+
}
|
1114
|
+
|
1115
|
+
/*
|
1116
|
+
* Possible subclass found, see if it supports subclassing
|
1117
|
+
*/
|
1118
|
+
if ( ! NIL_P( target_class ) )
|
1119
|
+
{
|
1120
|
+
subclass = target_class;
|
1121
|
+
if ( RARRAY_LEN(subclass_parts) > 0 && rb_respond_to( target_class, s_tag_subclasses ) &&
|
1122
|
+
RTEST( rb_funcall( target_class, s_tag_subclasses, 0 ) ) )
|
1123
|
+
{
|
1124
|
+
VALUE subclass_v;
|
1125
|
+
subclass = rb_ary_join( subclass_parts, colon );
|
1126
|
+
subclass = rb_funcall( target_class, s_tag_read_class, 1, subclass );
|
1127
|
+
subclass_v = syck_const_find( subclass );
|
1128
|
+
|
1129
|
+
if ( subclass_v != Qnil )
|
1130
|
+
{
|
1131
|
+
subclass = subclass_v;
|
1132
|
+
}
|
1133
|
+
else if ( rb_cObject == target_class && subclass_v == Qnil )
|
1134
|
+
{
|
1135
|
+
target_class = cYObject;
|
1136
|
+
type = subclass;
|
1137
|
+
subclass = cYObject;
|
1138
|
+
}
|
1139
|
+
else /* workaround for SEGV. real fix please */
|
1140
|
+
{
|
1141
|
+
rb_raise( rb_eTypeError, "invalid subclass" );
|
1142
|
+
}
|
1143
|
+
}
|
1144
|
+
break;
|
1145
|
+
}
|
1146
|
+
}
|
1147
|
+
}
|
1148
|
+
|
1149
|
+
/* rb_raise(rb_eTypeError, "invalid typing scheme: %s given",
|
1150
|
+
* scheme);
|
1151
|
+
*/
|
1152
|
+
|
1153
|
+
if ( rb_respond_to( target_class, s_call ) )
|
1154
|
+
{
|
1155
|
+
obj = rb_funcall( target_class, s_call, 2, type, val );
|
1156
|
+
}
|
1157
|
+
else
|
1158
|
+
{
|
1159
|
+
if ( rb_respond_to( target_class, s_yaml_new ) )
|
1160
|
+
{
|
1161
|
+
obj = rb_funcall( target_class, s_yaml_new, 3, subclass, type, val );
|
1162
|
+
}
|
1163
|
+
else if ( !NIL_P( target_class ) )
|
1164
|
+
{
|
1165
|
+
if ( subclass == rb_cBignum )
|
1166
|
+
{
|
1167
|
+
obj = rb_str2inum( val, 10 ); /* for yaml dumped by 1.8.3 [ruby-core:6159] */
|
1168
|
+
}
|
1169
|
+
else
|
1170
|
+
{
|
1171
|
+
obj = rb_obj_alloc( subclass );
|
1172
|
+
}
|
1173
|
+
|
1174
|
+
if ( rb_respond_to( obj, s_yaml_initialize ) )
|
1175
|
+
{
|
1176
|
+
rb_funcall( obj, s_yaml_initialize, 2, type, val );
|
1177
|
+
}
|
1178
|
+
else if ( !NIL_P( obj ) && rb_obj_is_instance_of( val, rb_cHash ) )
|
1179
|
+
{
|
1180
|
+
rb_block_call( val, s_each, 0, 0, syck_set_ivars, obj );
|
1181
|
+
}
|
1182
|
+
}
|
1183
|
+
else
|
1184
|
+
{
|
1185
|
+
VALUE parts = rb_str_split( type, ":" );
|
1186
|
+
VALUE scheme = rb_ary_shift( parts );
|
1187
|
+
if ( rb_str_cmp( scheme, str_xprivate ) == 0 )
|
1188
|
+
{
|
1189
|
+
VALUE name = rb_ary_join( parts, colon );
|
1190
|
+
obj = rb_funcall( cPrivateType, s_new, 2, name, val );
|
1191
|
+
}
|
1192
|
+
else
|
1193
|
+
{
|
1194
|
+
VALUE domain = rb_ary_shift( parts );
|
1195
|
+
VALUE name = rb_ary_join( parts, colon );
|
1196
|
+
obj = rb_funcall( cDomainType, s_new, 3, domain, name, val );
|
1197
|
+
}
|
1198
|
+
}
|
1199
|
+
}
|
1200
|
+
val = obj;
|
1201
|
+
}
|
1202
|
+
|
1203
|
+
return val;
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
/*
|
1207
|
+
* YAML::Syck::Resolver#tagurize
|
1208
|
+
*/
|
1209
|
+
VALUE
|
1210
|
+
syck_resolver_tagurize(VALUE self, VALUE val)
|
1211
|
+
{
|
1212
|
+
VALUE tmp = rb_check_string_type(val);
|
1213
|
+
|
1214
|
+
if ( !NIL_P(tmp) )
|
1215
|
+
{
|
1216
|
+
char *taguri = syck_type_id_to_uri( RSTRING_PTR(tmp) );
|
1217
|
+
val = rb_str_new2( taguri );
|
1218
|
+
S_FREE( taguri );
|
1219
|
+
}
|
1220
|
+
|
1221
|
+
return val;
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
/*
|
1225
|
+
* YAML::Syck::DefaultResolver#detect_implicit
|
1226
|
+
*/
|
1227
|
+
VALUE
|
1228
|
+
syck_defaultresolver_detect_implicit(VALUE self, VALUE val)
|
1229
|
+
{
|
1230
|
+
const char *type_id;
|
1231
|
+
VALUE tmp = rb_check_string_type(val);
|
1232
|
+
|
1233
|
+
if ( !NIL_P(tmp) )
|
1234
|
+
{
|
1235
|
+
val = tmp;
|
1236
|
+
type_id = syck_match_implicit( RSTRING_PTR(val), RSTRING_LEN(val) );
|
1237
|
+
return rb_str_new2( type_id );
|
1238
|
+
}
|
1239
|
+
|
1240
|
+
return rb_str_new2( "" );
|
1241
|
+
}
|
1242
|
+
|
1243
|
+
/*
|
1244
|
+
* YAML::Syck::DefaultResolver#node_import
|
1245
|
+
*/
|
1246
|
+
VALUE
|
1247
|
+
syck_defaultresolver_node_import(VALUE self, VALUE node)
|
1248
|
+
{
|
1249
|
+
SyckNode *n;
|
1250
|
+
VALUE obj;
|
1251
|
+
Data_Get_Struct( node, SyckNode, n );
|
1252
|
+
if ( !yaml_org_handler( n, &obj ) )
|
1253
|
+
{
|
1254
|
+
obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj );
|
1255
|
+
}
|
1256
|
+
return obj;
|
1257
|
+
}
|
1258
|
+
|
1259
|
+
/*
|
1260
|
+
* YAML::Syck::GenericResolver#node_import
|
1261
|
+
*/
|
1262
|
+
VALUE
|
1263
|
+
syck_genericresolver_node_import(VALUE self, VALUE node)
|
1264
|
+
{
|
1265
|
+
SyckNode *n;
|
1266
|
+
int i = 0;
|
1267
|
+
VALUE t = Qnil, obj = Qnil, v = Qnil, style = Qnil;
|
1268
|
+
Data_Get_Struct(node, SyckNode, n);
|
1269
|
+
|
1270
|
+
if ( n->type_id != NULL )
|
1271
|
+
{
|
1272
|
+
t = rb_str_new2(n->type_id);
|
1273
|
+
}
|
1274
|
+
|
1275
|
+
switch (n->kind)
|
1276
|
+
{
|
1277
|
+
case syck_str_kind:
|
1278
|
+
{
|
1279
|
+
v = rb_str_new( n->data.str->ptr, n->data.str->len );
|
1280
|
+
rb_enc_associate(v, rb_utf8_encoding());
|
1281
|
+
if ( n->data.str->style == scalar_1quote )
|
1282
|
+
{
|
1283
|
+
style = sym_1quote;
|
1284
|
+
}
|
1285
|
+
else if ( n->data.str->style == scalar_2quote )
|
1286
|
+
{
|
1287
|
+
style = sym_2quote;
|
1288
|
+
}
|
1289
|
+
else if ( n->data.str->style == scalar_fold )
|
1290
|
+
{
|
1291
|
+
style = sym_fold;
|
1292
|
+
}
|
1293
|
+
else if ( n->data.str->style == scalar_literal )
|
1294
|
+
{
|
1295
|
+
style = sym_literal;
|
1296
|
+
}
|
1297
|
+
else if ( n->data.str->style == scalar_plain )
|
1298
|
+
{
|
1299
|
+
style = sym_plain;
|
1300
|
+
}
|
1301
|
+
obj = rb_funcall( cScalar, s_new, 3, t, v, style );
|
1302
|
+
}
|
1303
|
+
break;
|
1304
|
+
|
1305
|
+
case syck_seq_kind:
|
1306
|
+
v = rb_ary_new2( syck_seq_count( n ) );
|
1307
|
+
for ( i = 0; i < syck_seq_count( n ); i++ )
|
1308
|
+
{
|
1309
|
+
rb_ary_store( v, i, syck_seq_read( n, i ) );
|
1310
|
+
}
|
1311
|
+
if ( n->data.list->style == seq_inline )
|
1312
|
+
{
|
1313
|
+
style = sym_inline;
|
1314
|
+
}
|
1315
|
+
obj = rb_funcall( cSeq, s_new, 3, t, v, style );
|
1316
|
+
rb_iv_set(obj, "@kind", sym_seq);
|
1317
|
+
break;
|
1318
|
+
|
1319
|
+
case syck_map_kind:
|
1320
|
+
v = rb_hash_new();
|
1321
|
+
for ( i = 0; i < syck_map_count( n ); i++ )
|
1322
|
+
{
|
1323
|
+
rb_hash_aset( v, syck_map_read( n, map_key, i ), syck_map_read( n, map_value, i ) );
|
1324
|
+
}
|
1325
|
+
if ( n->data.pairs->style == map_inline )
|
1326
|
+
{
|
1327
|
+
style = sym_inline;
|
1328
|
+
}
|
1329
|
+
obj = rb_funcall( cMap, s_new, 3, t, v, style );
|
1330
|
+
rb_iv_set(obj, "@kind", sym_map);
|
1331
|
+
break;
|
1332
|
+
}
|
1333
|
+
|
1334
|
+
return obj;
|
1335
|
+
}
|
1336
|
+
|
1337
|
+
/*
|
1338
|
+
* YAML::Syck::BadAlias.initialize
|
1339
|
+
*/
|
1340
|
+
VALUE
|
1341
|
+
syck_badalias_initialize(VALUE self, VALUE val)
|
1342
|
+
{
|
1343
|
+
rb_iv_set( self, "@name", val );
|
1344
|
+
return self;
|
1345
|
+
}
|
1346
|
+
|
1347
|
+
/*
|
1348
|
+
* YAML::Syck::BadAlias.<=>
|
1349
|
+
*/
|
1350
|
+
VALUE
|
1351
|
+
syck_badalias_cmp(VALUE alias1, VALUE alias2)
|
1352
|
+
{
|
1353
|
+
VALUE str1 = rb_ivar_get( alias1, s_name );
|
1354
|
+
VALUE str2 = rb_ivar_get( alias2, s_name );
|
1355
|
+
VALUE val = rb_funcall( str1, s_cmp, 1, str2 );
|
1356
|
+
return val;
|
1357
|
+
}
|
1358
|
+
|
1359
|
+
/*
|
1360
|
+
* YAML::DomainType.initialize
|
1361
|
+
*/
|
1362
|
+
VALUE
|
1363
|
+
syck_domaintype_initialize(VALUE self, VALUE domain, VALUE type_id, VALUE val)
|
1364
|
+
{
|
1365
|
+
rb_iv_set( self, "@domain", domain );
|
1366
|
+
rb_iv_set( self, "@type_id", type_id );
|
1367
|
+
rb_iv_set( self, "@value", val );
|
1368
|
+
return self;
|
1369
|
+
}
|
1370
|
+
|
1371
|
+
/*
|
1372
|
+
* YAML::Object.initialize
|
1373
|
+
*/
|
1374
|
+
VALUE
|
1375
|
+
syck_yobject_initialize(VALUE self, VALUE klass, VALUE ivars)
|
1376
|
+
{
|
1377
|
+
rb_iv_set( self, "@class", klass );
|
1378
|
+
rb_iv_set( self, "@ivars", ivars );
|
1379
|
+
return self;
|
1380
|
+
}
|
1381
|
+
|
1382
|
+
/*
|
1383
|
+
* YAML::PrivateType.initialize
|
1384
|
+
*/
|
1385
|
+
VALUE
|
1386
|
+
syck_privatetype_initialize(VALUE self, VALUE type_id, VALUE val)
|
1387
|
+
{
|
1388
|
+
rb_iv_set( self, "@type_id", type_id );
|
1389
|
+
rb_iv_set( self, "@value", val );
|
1390
|
+
return self;
|
1391
|
+
}
|
1392
|
+
|
1393
|
+
/*
|
1394
|
+
* Mark node contents.
|
1395
|
+
*/
|
1396
|
+
static void
|
1397
|
+
syck_node_mark(SyckNode *n)
|
1398
|
+
{
|
1399
|
+
int i;
|
1400
|
+
rb_gc_mark_maybe( n->id );
|
1401
|
+
switch ( n->kind )
|
1402
|
+
{
|
1403
|
+
case syck_seq_kind:
|
1404
|
+
for ( i = 0; i < n->data.list->idx; i++ )
|
1405
|
+
{
|
1406
|
+
rb_gc_mark( syck_seq_read( n, i ) );
|
1407
|
+
}
|
1408
|
+
break;
|
1409
|
+
|
1410
|
+
case syck_map_kind:
|
1411
|
+
for ( i = 0; i < n->data.pairs->idx; i++ )
|
1412
|
+
{
|
1413
|
+
rb_gc_mark( syck_map_read( n, map_key, i ) );
|
1414
|
+
rb_gc_mark( syck_map_read( n, map_value, i ) );
|
1415
|
+
}
|
1416
|
+
break;
|
1417
|
+
|
1418
|
+
case syck_str_kind:
|
1419
|
+
default:
|
1420
|
+
/* nothing */
|
1421
|
+
break;
|
1422
|
+
}
|
1423
|
+
#if 0 /* maybe needed */
|
1424
|
+
if ( n->shortcut ) syck_node_mark( n->shortcut ); /* caution: maybe cyclic */
|
1425
|
+
#endif
|
1426
|
+
}
|
1427
|
+
|
1428
|
+
/*
|
1429
|
+
* YAML::Syck::Scalar.allocate
|
1430
|
+
*/
|
1431
|
+
VALUE
|
1432
|
+
syck_scalar_alloc(VALUE class)
|
1433
|
+
{
|
1434
|
+
SyckNode *node = syck_alloc_str();
|
1435
|
+
VALUE obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node );
|
1436
|
+
node->id = obj;
|
1437
|
+
return obj;
|
1438
|
+
}
|
1439
|
+
|
1440
|
+
/*
|
1441
|
+
* YAML::Syck::Scalar.initialize
|
1442
|
+
*/
|
1443
|
+
VALUE
|
1444
|
+
syck_scalar_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style)
|
1445
|
+
{
|
1446
|
+
rb_iv_set( self, "@kind", sym_scalar );
|
1447
|
+
rb_funcall( self, s_type_id_set, 1, type_id );
|
1448
|
+
rb_funcall( self, s_value_set, 1, val );
|
1449
|
+
rb_funcall( self, s_style_set, 1, style );
|
1450
|
+
return self;
|
1451
|
+
}
|
1452
|
+
|
1453
|
+
/*
|
1454
|
+
* YAML::Syck::Scalar.style=
|
1455
|
+
*/
|
1456
|
+
VALUE
|
1457
|
+
syck_scalar_style_set(VALUE self, VALUE style)
|
1458
|
+
{
|
1459
|
+
SyckNode *node;
|
1460
|
+
Data_Get_Struct( self, SyckNode, node );
|
1461
|
+
|
1462
|
+
if ( NIL_P( style ) )
|
1463
|
+
{
|
1464
|
+
node->data.str->style = scalar_none;
|
1465
|
+
}
|
1466
|
+
else if ( style == sym_1quote )
|
1467
|
+
{
|
1468
|
+
node->data.str->style = scalar_1quote;
|
1469
|
+
}
|
1470
|
+
else if ( style == sym_2quote )
|
1471
|
+
{
|
1472
|
+
node->data.str->style = scalar_2quote;
|
1473
|
+
}
|
1474
|
+
else if ( style == sym_fold )
|
1475
|
+
{
|
1476
|
+
node->data.str->style = scalar_fold;
|
1477
|
+
}
|
1478
|
+
else if ( style == sym_literal )
|
1479
|
+
{
|
1480
|
+
node->data.str->style = scalar_literal;
|
1481
|
+
}
|
1482
|
+
else if ( style == sym_plain )
|
1483
|
+
{
|
1484
|
+
node->data.str->style = scalar_plain;
|
1485
|
+
}
|
1486
|
+
|
1487
|
+
rb_iv_set( self, "@style", style );
|
1488
|
+
return self;
|
1489
|
+
}
|
1490
|
+
|
1491
|
+
/*
|
1492
|
+
* YAML::Syck::Scalar.value=
|
1493
|
+
*/
|
1494
|
+
VALUE
|
1495
|
+
syck_scalar_value_set(VALUE self, VALUE val)
|
1496
|
+
{
|
1497
|
+
SyckNode *node;
|
1498
|
+
Data_Get_Struct( self, SyckNode, node );
|
1499
|
+
|
1500
|
+
StringValue( val );
|
1501
|
+
node->data.str->ptr = syck_strndup( RSTRING_PTR(val), RSTRING_LEN(val) );
|
1502
|
+
node->data.str->len = RSTRING_LEN(val);
|
1503
|
+
node->data.str->style = scalar_none;
|
1504
|
+
|
1505
|
+
rb_iv_set( self, "@value", val );
|
1506
|
+
return val;
|
1507
|
+
}
|
1508
|
+
|
1509
|
+
/*
|
1510
|
+
* YAML::Syck::Seq.allocate
|
1511
|
+
*/
|
1512
|
+
VALUE
|
1513
|
+
syck_seq_alloc(VALUE class)
|
1514
|
+
{
|
1515
|
+
SyckNode *node;
|
1516
|
+
VALUE obj;
|
1517
|
+
node = syck_alloc_seq();
|
1518
|
+
obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node );
|
1519
|
+
node->id = obj;
|
1520
|
+
return obj;
|
1521
|
+
}
|
1522
|
+
|
1523
|
+
/*
|
1524
|
+
* YAML::Syck::Seq.initialize
|
1525
|
+
*/
|
1526
|
+
VALUE
|
1527
|
+
syck_seq_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style)
|
1528
|
+
{
|
1529
|
+
SyckNode *node;
|
1530
|
+
Data_Get_Struct( self, SyckNode, node );
|
1531
|
+
|
1532
|
+
rb_iv_set( self, "@kind", sym_seq );
|
1533
|
+
rb_funcall( self, s_type_id_set, 1, type_id );
|
1534
|
+
rb_funcall( self, s_value_set, 1, val );
|
1535
|
+
rb_funcall( self, s_style_set, 1, style );
|
1536
|
+
return self;
|
1537
|
+
}
|
1538
|
+
|
1539
|
+
/*
|
1540
|
+
* YAML::Syck::Seq.value=
|
1541
|
+
*/
|
1542
|
+
VALUE
|
1543
|
+
syck_seq_value_set(VALUE self, VALUE val)
|
1544
|
+
{
|
1545
|
+
SyckNode *node;
|
1546
|
+
Data_Get_Struct( self, SyckNode, node );
|
1547
|
+
|
1548
|
+
val = rb_check_array_type( val );
|
1549
|
+
if ( !NIL_P( val ) ) {
|
1550
|
+
int i;
|
1551
|
+
syck_seq_empty( node );
|
1552
|
+
for ( i = 0; i < RARRAY_LEN( val ); i++ )
|
1553
|
+
{
|
1554
|
+
syck_seq_add( node, rb_ary_entry(val, i) );
|
1555
|
+
}
|
1556
|
+
}
|
1557
|
+
|
1558
|
+
rb_iv_set( self, "@value", val );
|
1559
|
+
return val;
|
1560
|
+
}
|
1561
|
+
|
1562
|
+
/*
|
1563
|
+
* YAML::Syck::Seq.add
|
1564
|
+
*/
|
1565
|
+
VALUE
|
1566
|
+
syck_seq_add_m(VALUE self, VALUE val)
|
1567
|
+
{
|
1568
|
+
SyckNode *node;
|
1569
|
+
VALUE emitter = rb_ivar_get( self, s_emitter );
|
1570
|
+
Data_Get_Struct( self, SyckNode, node );
|
1571
|
+
|
1572
|
+
if ( rb_respond_to( emitter, s_node_export ) ) {
|
1573
|
+
val = rb_funcall( emitter, s_node_export, 1, val );
|
1574
|
+
}
|
1575
|
+
syck_seq_add( node, val );
|
1576
|
+
rb_ary_push( rb_ivar_get( self, s_value ), val );
|
1577
|
+
|
1578
|
+
return self;
|
1579
|
+
}
|
1580
|
+
|
1581
|
+
/*
|
1582
|
+
* YAML::Syck::Seq.style=
|
1583
|
+
*/
|
1584
|
+
VALUE
|
1585
|
+
syck_seq_style_set(VALUE self, VALUE style)
|
1586
|
+
{
|
1587
|
+
SyckNode *node;
|
1588
|
+
Data_Get_Struct( self, SyckNode, node );
|
1589
|
+
|
1590
|
+
if ( style == sym_inline )
|
1591
|
+
{
|
1592
|
+
node->data.list->style = seq_inline;
|
1593
|
+
}
|
1594
|
+
else
|
1595
|
+
{
|
1596
|
+
node->data.list->style = seq_none;
|
1597
|
+
}
|
1598
|
+
|
1599
|
+
rb_iv_set( self, "@style", style );
|
1600
|
+
return self;
|
1601
|
+
}
|
1602
|
+
|
1603
|
+
/*
|
1604
|
+
* YAML::Syck::Map.allocate
|
1605
|
+
*/
|
1606
|
+
VALUE
|
1607
|
+
syck_map_alloc(VALUE class)
|
1608
|
+
{
|
1609
|
+
SyckNode *node;
|
1610
|
+
VALUE obj;
|
1611
|
+
node = syck_alloc_map();
|
1612
|
+
obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node );
|
1613
|
+
node->id = obj;
|
1614
|
+
return obj;
|
1615
|
+
}
|
1616
|
+
|
1617
|
+
/*
|
1618
|
+
* YAML::Syck::Map.initialize
|
1619
|
+
*/
|
1620
|
+
VALUE
|
1621
|
+
syck_map_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style)
|
1622
|
+
{
|
1623
|
+
SyckNode *node;
|
1624
|
+
Data_Get_Struct( self, SyckNode, node );
|
1625
|
+
|
1626
|
+
if ( !NIL_P( val ) )
|
1627
|
+
{
|
1628
|
+
VALUE hsh = rb_check_convert_type(val, T_HASH, "Hash", "to_hash");
|
1629
|
+
VALUE keys;
|
1630
|
+
int i;
|
1631
|
+
if ( NIL_P(hsh) )
|
1632
|
+
{
|
1633
|
+
rb_raise( rb_eTypeError, "wrong argument type" );
|
1634
|
+
}
|
1635
|
+
|
1636
|
+
keys = rb_funcall( hsh, s_keys, 0 );
|
1637
|
+
for ( i = 0; i < RARRAY_LEN(keys); i++ )
|
1638
|
+
{
|
1639
|
+
VALUE key = rb_ary_entry(keys, i);
|
1640
|
+
syck_map_add( node, key, rb_hash_aref(hsh, key) );
|
1641
|
+
}
|
1642
|
+
}
|
1643
|
+
|
1644
|
+
rb_iv_set( self, "@kind", sym_seq );
|
1645
|
+
rb_funcall( self, s_type_id_set, 1, type_id );
|
1646
|
+
rb_funcall( self, s_value_set, 1, val );
|
1647
|
+
rb_funcall( self, s_style_set, 1, style );
|
1648
|
+
return self;
|
1649
|
+
}
|
1650
|
+
|
1651
|
+
/*
|
1652
|
+
* YAML::Syck::Map.value=
|
1653
|
+
*/
|
1654
|
+
VALUE
|
1655
|
+
syck_map_value_set(VALUE self, VALUE val)
|
1656
|
+
{
|
1657
|
+
SyckNode *node;
|
1658
|
+
Data_Get_Struct( self, SyckNode, node );
|
1659
|
+
|
1660
|
+
if ( !NIL_P( val ) )
|
1661
|
+
{
|
1662
|
+
VALUE hsh = rb_check_convert_type(val, T_HASH, "Hash", "to_hash");
|
1663
|
+
VALUE keys;
|
1664
|
+
int i;
|
1665
|
+
if ( NIL_P(hsh) )
|
1666
|
+
{
|
1667
|
+
rb_raise( rb_eTypeError, "wrong argument type" );
|
1668
|
+
}
|
1669
|
+
|
1670
|
+
syck_map_empty( node );
|
1671
|
+
keys = rb_funcall( hsh, s_keys, 0 );
|
1672
|
+
for ( i = 0; i < RARRAY_LEN(keys); i++ )
|
1673
|
+
{
|
1674
|
+
VALUE key = rb_ary_entry(keys, i);
|
1675
|
+
syck_map_add( node, key, rb_hash_aref(hsh, key) );
|
1676
|
+
}
|
1677
|
+
}
|
1678
|
+
|
1679
|
+
rb_iv_set( self, "@value", val );
|
1680
|
+
return val;
|
1681
|
+
}
|
1682
|
+
|
1683
|
+
/*
|
1684
|
+
* YAML::Syck::Map.add
|
1685
|
+
*/
|
1686
|
+
VALUE
|
1687
|
+
syck_map_add_m(VALUE self, VALUE key, VALUE val)
|
1688
|
+
{
|
1689
|
+
SyckNode *node;
|
1690
|
+
VALUE emitter = rb_ivar_get( self, s_emitter );
|
1691
|
+
Data_Get_Struct( self, SyckNode, node );
|
1692
|
+
|
1693
|
+
if ( rb_respond_to( emitter, s_node_export ) ) {
|
1694
|
+
key = rb_funcall( emitter, s_node_export, 1, key );
|
1695
|
+
val = rb_funcall( emitter, s_node_export, 1, val );
|
1696
|
+
}
|
1697
|
+
syck_map_add( node, key, val );
|
1698
|
+
rb_hash_aset( rb_ivar_get( self, s_value ), key, val );
|
1699
|
+
|
1700
|
+
return self;
|
1701
|
+
}
|
1702
|
+
|
1703
|
+
/*
|
1704
|
+
* YAML::Syck::Map.style=
|
1705
|
+
*/
|
1706
|
+
VALUE
|
1707
|
+
syck_map_style_set(VALUE self, VALUE style)
|
1708
|
+
{
|
1709
|
+
SyckNode *node;
|
1710
|
+
Data_Get_Struct( self, SyckNode, node );
|
1711
|
+
|
1712
|
+
if ( style == sym_inline )
|
1713
|
+
{
|
1714
|
+
node->data.pairs->style = map_inline;
|
1715
|
+
}
|
1716
|
+
else
|
1717
|
+
{
|
1718
|
+
node->data.pairs->style = map_none;
|
1719
|
+
}
|
1720
|
+
|
1721
|
+
rb_iv_set( self, "@style", style );
|
1722
|
+
return self;
|
1723
|
+
}
|
1724
|
+
|
1725
|
+
#if 0
|
1726
|
+
/*
|
1727
|
+
* Cloning method for all node types
|
1728
|
+
*/
|
1729
|
+
VALUE
|
1730
|
+
syck_node_init_copy(VALUE copy, VALUE orig)
|
1731
|
+
{
|
1732
|
+
SyckNode *copy_n;
|
1733
|
+
SyckNode *orig_n;
|
1734
|
+
|
1735
|
+
if ( copy == orig )
|
1736
|
+
return copy;
|
1737
|
+
|
1738
|
+
if ( TYPE( orig ) != T_DATA )
|
1739
|
+
{
|
1740
|
+
rb_raise( rb_eTypeError, "wrong argument type" );
|
1741
|
+
}
|
1742
|
+
|
1743
|
+
Data_Get_Struct( orig, SyckNode, orig_n );
|
1744
|
+
Data_Get_Struct( copy, SyckNode, copy_n );
|
1745
|
+
MEMCPY( copy_n, orig_n, SyckNode, 1 );
|
1746
|
+
return copy;
|
1747
|
+
}
|
1748
|
+
#endif
|
1749
|
+
|
1750
|
+
/*
|
1751
|
+
* YAML::Syck::Node#type_id=
|
1752
|
+
*/
|
1753
|
+
VALUE
|
1754
|
+
syck_node_type_id_set(VALUE self, VALUE type_id)
|
1755
|
+
{
|
1756
|
+
SyckNode *node;
|
1757
|
+
Data_Get_Struct( self, SyckNode, node );
|
1758
|
+
|
1759
|
+
S_FREE( node->type_id );
|
1760
|
+
|
1761
|
+
if ( !NIL_P( type_id ) ) {
|
1762
|
+
StringValue( type_id );
|
1763
|
+
node->type_id = syck_strndup( RSTRING_PTR(type_id), RSTRING_LEN(type_id) );
|
1764
|
+
}
|
1765
|
+
|
1766
|
+
rb_iv_set( self, "@type_id", type_id );
|
1767
|
+
return type_id;
|
1768
|
+
}
|
1769
|
+
|
1770
|
+
/*
|
1771
|
+
* YAML::Syck::Node.transform
|
1772
|
+
*/
|
1773
|
+
VALUE
|
1774
|
+
syck_node_transform(VALUE self)
|
1775
|
+
{
|
1776
|
+
VALUE t;
|
1777
|
+
SyckNode *n = NULL;
|
1778
|
+
SyckNode *orig_n;
|
1779
|
+
Data_Get_Struct(self, SyckNode, orig_n);
|
1780
|
+
t = Data_Wrap_Struct( cNode, syck_node_mark, syck_free_node, 0 );
|
1781
|
+
|
1782
|
+
switch (orig_n->kind)
|
1783
|
+
{
|
1784
|
+
case syck_map_kind:
|
1785
|
+
{
|
1786
|
+
int i;
|
1787
|
+
DATA_PTR(t) = n = syck_alloc_map();
|
1788
|
+
for ( i = 0; i < orig_n->data.pairs->idx; i++ )
|
1789
|
+
{
|
1790
|
+
syck_map_add( n, rb_funcall( syck_map_read( orig_n, map_key, i ), s_transform, 0 ),
|
1791
|
+
rb_funcall( syck_map_read( orig_n, map_value, i ), s_transform, 0 ) );
|
1792
|
+
}
|
1793
|
+
}
|
1794
|
+
break;
|
1795
|
+
|
1796
|
+
case syck_seq_kind:
|
1797
|
+
{
|
1798
|
+
int i;
|
1799
|
+
DATA_PTR(t) = n = syck_alloc_seq();
|
1800
|
+
for ( i = 0; i < orig_n->data.list->idx; i++ )
|
1801
|
+
{
|
1802
|
+
syck_seq_add( n, rb_funcall( syck_seq_read( orig_n, i ), s_transform, 0 ) );
|
1803
|
+
}
|
1804
|
+
}
|
1805
|
+
break;
|
1806
|
+
|
1807
|
+
case syck_str_kind:
|
1808
|
+
DATA_PTR(t) = n = syck_new_str2( orig_n->data.str->ptr, orig_n->data.str->len, orig_n->data.str->style );
|
1809
|
+
break;
|
1810
|
+
}
|
1811
|
+
|
1812
|
+
if ( orig_n->type_id != NULL )
|
1813
|
+
{
|
1814
|
+
n->type_id = syck_strndup( orig_n->type_id, strlen( orig_n->type_id ) );
|
1815
|
+
}
|
1816
|
+
if ( orig_n->anchor != NULL )
|
1817
|
+
{
|
1818
|
+
n->anchor = syck_strndup( orig_n->anchor, strlen( orig_n->anchor ) );
|
1819
|
+
}
|
1820
|
+
n->id = t;
|
1821
|
+
return rb_funcall( oDefaultResolver, s_node_import, 1, t );
|
1822
|
+
}
|
1823
|
+
|
1824
|
+
/*
|
1825
|
+
* Emitter callback: assembles YAML document events from
|
1826
|
+
* Ruby symbols. This is a brilliant way to do it.
|
1827
|
+
* No one could possibly object.
|
1828
|
+
*/
|
1829
|
+
void
|
1830
|
+
rb_syck_emitter_handler(SyckEmitter *e, st_data_t data)
|
1831
|
+
{
|
1832
|
+
SyckNode *n;
|
1833
|
+
Data_Get_Struct((VALUE)data, SyckNode, n);
|
1834
|
+
|
1835
|
+
switch (n->kind)
|
1836
|
+
{
|
1837
|
+
case syck_map_kind:
|
1838
|
+
{
|
1839
|
+
int i;
|
1840
|
+
syck_emit_map( e, n->type_id, n->data.pairs->style );
|
1841
|
+
for ( i = 0; i < n->data.pairs->idx; i++ )
|
1842
|
+
{
|
1843
|
+
syck_emit_item( e, syck_map_read( n, map_key, i ) );
|
1844
|
+
syck_emit_item( e, syck_map_read( n, map_value, i ) );
|
1845
|
+
}
|
1846
|
+
syck_emit_end( e );
|
1847
|
+
}
|
1848
|
+
break;
|
1849
|
+
|
1850
|
+
case syck_seq_kind:
|
1851
|
+
{
|
1852
|
+
int i;
|
1853
|
+
syck_emit_seq( e, n->type_id, n->data.list->style );
|
1854
|
+
for ( i = 0; i < n->data.list->idx; i++ )
|
1855
|
+
{
|
1856
|
+
syck_emit_item( e, syck_seq_read( n, i ) );
|
1857
|
+
}
|
1858
|
+
syck_emit_end( e );
|
1859
|
+
}
|
1860
|
+
break;
|
1861
|
+
|
1862
|
+
case syck_str_kind:
|
1863
|
+
{
|
1864
|
+
syck_emit_scalar( e, n->type_id, n->data.str->style, 0, 0, 0, n->data.str->ptr, n->data.str->len );
|
1865
|
+
}
|
1866
|
+
break;
|
1867
|
+
}
|
1868
|
+
}
|
1869
|
+
|
1870
|
+
/*
|
1871
|
+
* Handle output from the emitter
|
1872
|
+
*/
|
1873
|
+
void
|
1874
|
+
rb_syck_output_handler(SyckEmitter * emitter, char *str, long len)
|
1875
|
+
{
|
1876
|
+
struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus;
|
1877
|
+
VALUE dest = bonus->port;
|
1878
|
+
if (TYPE(dest) == T_STRING) {
|
1879
|
+
rb_str_cat( dest, str, len );
|
1880
|
+
} else {
|
1881
|
+
rb_io_write( dest, rb_str_new( str, len ) );
|
1882
|
+
}
|
1883
|
+
}
|
1884
|
+
|
1885
|
+
/*
|
1886
|
+
* Helper function for marking nodes in the anchor
|
1887
|
+
* symbol table.
|
1888
|
+
*/
|
1889
|
+
void
|
1890
|
+
syck_out_mark(VALUE emitter, VALUE node)
|
1891
|
+
{
|
1892
|
+
SyckEmitter *emitterPtr;
|
1893
|
+
struct emitter_xtra *bonus;
|
1894
|
+
Data_Get_Struct(emitter, SyckEmitter, emitterPtr);
|
1895
|
+
bonus = (struct emitter_xtra *)emitterPtr->bonus;
|
1896
|
+
rb_ivar_set( node, s_emitter, emitter );
|
1897
|
+
/* syck_emitter_mark_node( emitterPtr, (st_data_t)node ); */
|
1898
|
+
if ( !NIL_P( bonus->oid ) ) {
|
1899
|
+
rb_hash_aset( bonus->data, bonus->oid, node );
|
1900
|
+
}
|
1901
|
+
}
|
1902
|
+
|
1903
|
+
/*
|
1904
|
+
* Mark emitter values.
|
1905
|
+
*/
|
1906
|
+
static void
|
1907
|
+
syck_mark_emitter(SyckEmitter *emitter)
|
1908
|
+
{
|
1909
|
+
struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus;
|
1910
|
+
rb_gc_mark( bonus->oid );
|
1911
|
+
rb_gc_mark( bonus->data );
|
1912
|
+
rb_gc_mark( bonus->port );
|
1913
|
+
}
|
1914
|
+
|
1915
|
+
/*
|
1916
|
+
* Free the emitter and any bonus attachment.
|
1917
|
+
*/
|
1918
|
+
void
|
1919
|
+
rb_syck_free_emitter(SyckEmitter *e)
|
1920
|
+
{
|
1921
|
+
S_FREE( e->bonus );
|
1922
|
+
syck_free_emitter(e);
|
1923
|
+
}
|
1924
|
+
|
1925
|
+
/*
|
1926
|
+
* YAML::Syck::Emitter.allocate
|
1927
|
+
*/
|
1928
|
+
VALUE syck_emitter_s_alloc _((VALUE));
|
1929
|
+
VALUE
|
1930
|
+
syck_emitter_s_alloc(VALUE class)
|
1931
|
+
{
|
1932
|
+
VALUE pobj;
|
1933
|
+
SyckEmitter *emitter = syck_new_emitter();
|
1934
|
+
|
1935
|
+
emitter->bonus = S_ALLOC( struct emitter_xtra );
|
1936
|
+
S_MEMZERO( emitter->bonus, struct emitter_xtra, 1 );
|
1937
|
+
|
1938
|
+
pobj = Data_Wrap_Struct( class, syck_mark_emitter, rb_syck_free_emitter, emitter );
|
1939
|
+
syck_emitter_handler( emitter, rb_syck_emitter_handler );
|
1940
|
+
syck_output_handler( emitter, rb_syck_output_handler );
|
1941
|
+
|
1942
|
+
rb_ivar_set( pobj, s_out, rb_funcall( cOut, s_new, 1, pobj ) );
|
1943
|
+
return pobj;
|
1944
|
+
}
|
1945
|
+
|
1946
|
+
static VALUE
|
1947
|
+
id_hash_new(void)
|
1948
|
+
{
|
1949
|
+
VALUE hash;
|
1950
|
+
hash = rb_hash_new();
|
1951
|
+
rb_funcall(hash, rb_intern("compare_by_identity"), 0);
|
1952
|
+
return hash;
|
1953
|
+
}
|
1954
|
+
|
1955
|
+
/*
|
1956
|
+
* YAML::Syck::Emitter.reset( options )
|
1957
|
+
*/
|
1958
|
+
VALUE
|
1959
|
+
syck_emitter_reset(int argc, VALUE *argv, VALUE self)
|
1960
|
+
{
|
1961
|
+
VALUE options, tmp;
|
1962
|
+
SyckEmitter *emitter;
|
1963
|
+
struct emitter_xtra *bonus;
|
1964
|
+
|
1965
|
+
Data_Get_Struct(self, SyckEmitter, emitter);
|
1966
|
+
bonus = (struct emitter_xtra *)emitter->bonus;
|
1967
|
+
|
1968
|
+
bonus->oid = Qnil;
|
1969
|
+
bonus->port = rb_str_new2( "" );
|
1970
|
+
bonus->data = id_hash_new();
|
1971
|
+
|
1972
|
+
if (rb_scan_args(argc, argv, "01", &options) == 0)
|
1973
|
+
{
|
1974
|
+
options = rb_hash_new();
|
1975
|
+
rb_ivar_set(self, s_options, options);
|
1976
|
+
}
|
1977
|
+
else if ( !NIL_P(tmp = rb_check_string_type(options)) )
|
1978
|
+
{
|
1979
|
+
bonus->port = tmp;
|
1980
|
+
}
|
1981
|
+
else if ( rb_respond_to( options, s_write ) )
|
1982
|
+
{
|
1983
|
+
bonus->port = options;
|
1984
|
+
}
|
1985
|
+
else
|
1986
|
+
{
|
1987
|
+
Check_Type(options, T_HASH);
|
1988
|
+
rb_ivar_set(self, s_options, options);
|
1989
|
+
}
|
1990
|
+
|
1991
|
+
emitter->headless = 0;
|
1992
|
+
rb_ivar_set(self, s_level, INT2FIX(0));
|
1993
|
+
rb_ivar_set(self, s_resolver, Qnil);
|
1994
|
+
return self;
|
1995
|
+
}
|
1996
|
+
|
1997
|
+
/*
|
1998
|
+
* YAML::Syck::Emitter.emit( object_id ) { |out| ... }
|
1999
|
+
*/
|
2000
|
+
VALUE
|
2001
|
+
syck_emitter_emit(int argc, VALUE *argv, VALUE self)
|
2002
|
+
{
|
2003
|
+
VALUE oid, proc;
|
2004
|
+
SyckEmitter *emitter;
|
2005
|
+
struct emitter_xtra *bonus;
|
2006
|
+
SYMID symple;
|
2007
|
+
int level = FIX2INT(rb_ivar_get(self, s_level)) + 1;
|
2008
|
+
rb_ivar_set(self, s_level, INT2FIX(level));
|
2009
|
+
|
2010
|
+
rb_scan_args(argc, argv, "1&", &oid, &proc);
|
2011
|
+
Data_Get_Struct(self, SyckEmitter, emitter);
|
2012
|
+
bonus = (struct emitter_xtra *)emitter->bonus;
|
2013
|
+
|
2014
|
+
/* Calculate anchors, normalize nodes, build a simpler symbol table */
|
2015
|
+
bonus->oid = oid;
|
2016
|
+
if ( !NIL_P( oid ) && RTEST( rb_funcall( bonus->data, s_haskey, 1, oid ) ) ) {
|
2017
|
+
symple = rb_hash_aref( bonus->data, oid );
|
2018
|
+
} else {
|
2019
|
+
symple = rb_funcall( proc, s_call, 1, rb_ivar_get( self, s_out ) );
|
2020
|
+
}
|
2021
|
+
syck_emitter_mark_node( emitter, (st_data_t)symple );
|
2022
|
+
|
2023
|
+
/* Second pass, build emitted string */
|
2024
|
+
level -= 1;
|
2025
|
+
rb_ivar_set(self, s_level, INT2FIX(level));
|
2026
|
+
if ( level == 0 )
|
2027
|
+
{
|
2028
|
+
syck_emit(emitter, (st_data_t)symple);
|
2029
|
+
syck_emitter_flush(emitter, 0);
|
2030
|
+
|
2031
|
+
return bonus->port;
|
2032
|
+
}
|
2033
|
+
|
2034
|
+
return symple;
|
2035
|
+
}
|
2036
|
+
|
2037
|
+
/*
|
2038
|
+
* YAML::Syck::Emitter#node_export
|
2039
|
+
*/
|
2040
|
+
VALUE
|
2041
|
+
syck_emitter_node_export(VALUE self, VALUE node)
|
2042
|
+
{
|
2043
|
+
return rb_funcall( node, s_to_yaml, 1, self );
|
2044
|
+
}
|
2045
|
+
|
2046
|
+
/*
|
2047
|
+
* YAML::Syck::Emitter#set_resolver
|
2048
|
+
*/
|
2049
|
+
VALUE
|
2050
|
+
syck_emitter_set_resolver(VALUE self, VALUE resolver)
|
2051
|
+
{
|
2052
|
+
rb_ivar_set( self, s_resolver, resolver );
|
2053
|
+
return self;
|
2054
|
+
}
|
2055
|
+
|
2056
|
+
/*
|
2057
|
+
* YAML::Syck::Out::initialize
|
2058
|
+
*/
|
2059
|
+
VALUE
|
2060
|
+
syck_out_initialize(VALUE self, VALUE emitter)
|
2061
|
+
{
|
2062
|
+
rb_ivar_set( self, s_emitter, emitter );
|
2063
|
+
return self;
|
2064
|
+
}
|
2065
|
+
|
2066
|
+
/*
|
2067
|
+
* YAML::Syck::Out::map
|
2068
|
+
*/
|
2069
|
+
VALUE
|
2070
|
+
syck_out_map(int argc, VALUE *argv, VALUE self)
|
2071
|
+
{
|
2072
|
+
VALUE type_id, style, map;
|
2073
|
+
if (rb_scan_args(argc, argv, "11", &type_id, &style) == 1) {
|
2074
|
+
style = Qnil;
|
2075
|
+
}
|
2076
|
+
map = rb_funcall( cMap, s_new, 3, type_id, rb_hash_new(), style );
|
2077
|
+
syck_out_mark( rb_ivar_get( self, s_emitter ), map );
|
2078
|
+
rb_yield( map );
|
2079
|
+
return map;
|
2080
|
+
}
|
2081
|
+
|
2082
|
+
/*
|
2083
|
+
* YAML::Syck::Out::seq
|
2084
|
+
*/
|
2085
|
+
VALUE
|
2086
|
+
syck_out_seq(int argc, VALUE *argv, VALUE self)
|
2087
|
+
{
|
2088
|
+
VALUE type_id, style, seq;
|
2089
|
+
if (rb_scan_args(argc, argv, "11", &type_id, &style) == 1) {
|
2090
|
+
style = Qnil;
|
2091
|
+
}
|
2092
|
+
seq = rb_funcall( cSeq, s_new, 3, type_id, rb_ary_new(), style );
|
2093
|
+
syck_out_mark( rb_ivar_get( self, s_emitter ), seq );
|
2094
|
+
rb_yield( seq );
|
2095
|
+
return seq;
|
2096
|
+
}
|
2097
|
+
|
2098
|
+
/*
|
2099
|
+
* YAML::Syck::Out::scalar
|
2100
|
+
syck_out_scalar( self, type_id, str, style )
|
2101
|
+
VALUE self, type_id, str, style;
|
2102
|
+
*/
|
2103
|
+
VALUE
|
2104
|
+
syck_out_scalar(int argc, VALUE *argv, VALUE self)
|
2105
|
+
{
|
2106
|
+
VALUE type_id, str, style, scalar;
|
2107
|
+
rb_scan_args(argc, argv, "21", &type_id, &str, &style);
|
2108
|
+
scalar = rb_funcall( cScalar, s_new, 3, type_id, str, style );
|
2109
|
+
syck_out_mark( rb_ivar_get( self, s_emitter ), scalar );
|
2110
|
+
return scalar;
|
2111
|
+
}
|
2112
|
+
|
2113
|
+
/*
|
2114
|
+
* Initialize Syck extension
|
2115
|
+
*/
|
2116
|
+
void
|
2117
|
+
Init_syck()
|
2118
|
+
{
|
2119
|
+
VALUE rb_syck = rb_define_module_under( rb_cObject, "Syck" );
|
2120
|
+
rb_define_module_function( rb_syck, "compile", rb_syck_compile, 1 );
|
2121
|
+
|
2122
|
+
/*
|
2123
|
+
* Global symbols
|
2124
|
+
*/
|
2125
|
+
s_new = rb_intern("new");
|
2126
|
+
s_utc = rb_intern("utc");
|
2127
|
+
s_at = rb_intern("at");
|
2128
|
+
s_to_f = rb_intern("to_f");
|
2129
|
+
s_to_i = rb_intern("to_i");
|
2130
|
+
s_read = rb_intern("read");
|
2131
|
+
s_binmode = rb_intern("binmode");
|
2132
|
+
s_transfer = rb_intern("transfer");
|
2133
|
+
s_call = rb_intern("call");
|
2134
|
+
s_cmp = rb_intern("<=>");
|
2135
|
+
s_intern = rb_intern("intern");
|
2136
|
+
s_update = rb_intern("update");
|
2137
|
+
s_detect_implicit = rb_intern("detect_implicit");
|
2138
|
+
s_dup = rb_intern("dup");
|
2139
|
+
s_default_set = rb_intern("default=");
|
2140
|
+
s_match = rb_intern("match");
|
2141
|
+
s_push = rb_intern("push");
|
2142
|
+
s_haskey = rb_intern("has_key?");
|
2143
|
+
s_keys = rb_intern("keys");
|
2144
|
+
s_node_import = rb_intern("node_import");
|
2145
|
+
s_tr_bang = rb_intern("tr!");
|
2146
|
+
s_unpack = rb_intern("unpack");
|
2147
|
+
s_write = rb_intern("write");
|
2148
|
+
s_tag_read_class = rb_intern( "yaml_tag_read_class" );
|
2149
|
+
s_tag_subclasses = rb_intern( "yaml_tag_subclasses?" );
|
2150
|
+
s_emitter = rb_intern( "emitter" );
|
2151
|
+
s_set_resolver = rb_intern( "set_resolver" );
|
2152
|
+
s_node_export = rb_intern( "node_export" );
|
2153
|
+
s_to_yaml = rb_intern( "to_yaml" );
|
2154
|
+
s_transform = rb_intern( "transform" );
|
2155
|
+
s_yaml_new = rb_intern("yaml_new");
|
2156
|
+
s_yaml_initialize = rb_intern("yaml_initialize");
|
2157
|
+
s_each = rb_intern("each");
|
2158
|
+
s_parse = rb_intern("parse");
|
2159
|
+
|
2160
|
+
s_tags = rb_intern("@tags");
|
2161
|
+
s_name = rb_intern("@name");
|
2162
|
+
s_options = rb_intern("@options");
|
2163
|
+
s_kind = rb_intern("@kind");
|
2164
|
+
s_type_id = rb_intern("@type_id");
|
2165
|
+
s_type_id_set = rb_intern("type_id=");
|
2166
|
+
s_resolver = rb_intern("@resolver");
|
2167
|
+
s_level = rb_intern( "@level" );
|
2168
|
+
s_style = rb_intern("@style");
|
2169
|
+
s_style_set = rb_intern("style=");
|
2170
|
+
s_value = rb_intern("@value");
|
2171
|
+
s_value_set = rb_intern("value=");
|
2172
|
+
s_out = rb_intern("@out");
|
2173
|
+
s_input = rb_intern("@input");
|
2174
|
+
|
2175
|
+
sym_model = ID2SYM(rb_intern("Model"));
|
2176
|
+
sym_generic = ID2SYM(rb_intern("Generic"));
|
2177
|
+
sym_bytecode = ID2SYM(rb_intern("bytecode"));
|
2178
|
+
sym_map = ID2SYM(rb_intern("map"));
|
2179
|
+
sym_scalar = ID2SYM(rb_intern("scalar"));
|
2180
|
+
sym_seq = ID2SYM(rb_intern("seq"));
|
2181
|
+
sym_1quote = ID2SYM(rb_intern("quote1"));
|
2182
|
+
sym_2quote = ID2SYM(rb_intern("quote2"));
|
2183
|
+
sym_fold = ID2SYM(rb_intern("fold"));
|
2184
|
+
sym_literal = ID2SYM(rb_intern("literal"));
|
2185
|
+
sym_plain = ID2SYM(rb_intern("plain"));
|
2186
|
+
sym_inline = ID2SYM(rb_intern("inline"));
|
2187
|
+
|
2188
|
+
/*
|
2189
|
+
* Define YAML::Syck::Resolver class
|
2190
|
+
*/
|
2191
|
+
cResolver = rb_define_class_under( rb_syck, "Resolver", rb_cObject );
|
2192
|
+
rb_define_attr( cResolver, "tags", 1, 1 );
|
2193
|
+
rb_define_method( cResolver, "initialize", syck_resolver_initialize, 0 );
|
2194
|
+
rb_define_method( cResolver, "add_type", syck_resolver_add_type, 2 );
|
2195
|
+
rb_define_method( cResolver, "use_types_at", syck_resolver_use_types_at, 1 );
|
2196
|
+
rb_define_method( cResolver, "detect_implicit", syck_resolver_detect_implicit, 1 );
|
2197
|
+
rb_define_method( cResolver, "transfer", syck_resolver_transfer, 2 );
|
2198
|
+
rb_define_method( cResolver, "node_import", syck_resolver_node_import, 1 );
|
2199
|
+
rb_define_method( cResolver, "tagurize", syck_resolver_tagurize, 1 );
|
2200
|
+
|
2201
|
+
rb_global_variable( &oDefaultResolver );
|
2202
|
+
oDefaultResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 );
|
2203
|
+
rb_define_singleton_method( oDefaultResolver, "node_import", syck_defaultresolver_node_import, 1 );
|
2204
|
+
rb_define_singleton_method( oDefaultResolver, "detect_implicit", syck_defaultresolver_detect_implicit, 1 );
|
2205
|
+
rb_define_const( rb_syck, "DefaultResolver", oDefaultResolver );
|
2206
|
+
rb_global_variable( &oGenericResolver );
|
2207
|
+
oGenericResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 );
|
2208
|
+
rb_define_singleton_method( oGenericResolver, "node_import", syck_genericresolver_node_import, 1 );
|
2209
|
+
rb_define_const( rb_syck, "GenericResolver", oGenericResolver );
|
2210
|
+
|
2211
|
+
/*
|
2212
|
+
* Define YAML::Syck::Parser class
|
2213
|
+
*/
|
2214
|
+
cParser = rb_define_class_under( rb_syck, "Parser", rb_cObject );
|
2215
|
+
rb_define_attr( cParser, "options", 1, 1 );
|
2216
|
+
rb_define_attr( cParser, "resolver", 1, 1 );
|
2217
|
+
rb_define_attr( cParser, "input", 1, 1 );
|
2218
|
+
rb_define_alloc_func( cParser, syck_parser_s_alloc );
|
2219
|
+
rb_define_method(cParser, "initialize", syck_parser_initialize, -1 );
|
2220
|
+
rb_define_method(cParser, "bufsize=", syck_parser_bufsize_set, 1 );
|
2221
|
+
rb_define_method(cParser, "bufsize", syck_parser_bufsize_get, 0 );
|
2222
|
+
rb_define_method(cParser, "load", syck_parser_load, -1);
|
2223
|
+
rb_define_method(cParser, "load_documents", syck_parser_load_documents, -1);
|
2224
|
+
rb_define_method(cParser, "set_resolver", syck_parser_set_resolver, 1);
|
2225
|
+
|
2226
|
+
/*
|
2227
|
+
* Define YAML::Syck::Node class
|
2228
|
+
*/
|
2229
|
+
cNode = rb_define_class_under( rb_syck, "Node", rb_cObject );
|
2230
|
+
rb_undef( cNode, rb_intern("initialize_copy") );
|
2231
|
+
rb_define_attr( cNode, "emitter", 1, 1 );
|
2232
|
+
rb_define_attr( cNode, "resolver", 1, 1 );
|
2233
|
+
rb_define_attr( cNode, "kind", 1, 0 );
|
2234
|
+
rb_define_attr( cNode, "type_id", 1, 0 );
|
2235
|
+
rb_define_attr( cNode, "value", 1, 0 );
|
2236
|
+
rb_define_method( cNode, "type_id=", syck_node_type_id_set, 1 );
|
2237
|
+
rb_define_method( cNode, "transform", syck_node_transform, 0);
|
2238
|
+
|
2239
|
+
/*
|
2240
|
+
* Define YAML::Syck::Scalar, YAML::Syck::Seq, YAML::Syck::Map --
|
2241
|
+
* all are the publicly usable variants of YAML::Syck::Node
|
2242
|
+
*/
|
2243
|
+
cScalar = rb_define_class_under( rb_syck, "Scalar", cNode );
|
2244
|
+
rb_define_alloc_func( cScalar, syck_scalar_alloc );
|
2245
|
+
rb_define_method( cScalar, "initialize", syck_scalar_initialize, 3 );
|
2246
|
+
rb_define_method( cScalar, "value=", syck_scalar_value_set, 1 );
|
2247
|
+
rb_define_method( cScalar, "style=", syck_scalar_style_set, 1 );
|
2248
|
+
cSeq = rb_define_class_under( rb_syck, "Seq", cNode );
|
2249
|
+
rb_define_alloc_func( cSeq, syck_seq_alloc );
|
2250
|
+
rb_define_method( cSeq, "initialize", syck_seq_initialize, 3 );
|
2251
|
+
rb_define_method( cSeq, "value=", syck_seq_value_set, 1 );
|
2252
|
+
rb_define_method( cSeq, "add", syck_seq_add_m, 1 );
|
2253
|
+
rb_define_method( cSeq, "style=", syck_seq_style_set, 1 );
|
2254
|
+
cMap = rb_define_class_under( rb_syck, "Map", cNode );
|
2255
|
+
rb_define_alloc_func( cMap, syck_map_alloc );
|
2256
|
+
rb_define_method( cMap, "initialize", syck_map_initialize, 3 );
|
2257
|
+
rb_define_method( cMap, "value=", syck_map_value_set, 1 );
|
2258
|
+
rb_define_method( cMap, "add", syck_map_add_m, 2 );
|
2259
|
+
rb_define_method( cMap, "style=", syck_map_style_set, 1 );
|
2260
|
+
|
2261
|
+
/*
|
2262
|
+
* Define YAML::PrivateType class
|
2263
|
+
*/
|
2264
|
+
cPrivateType = rb_define_class_under( rb_syck, "PrivateType", rb_cObject );
|
2265
|
+
rb_define_attr( cPrivateType, "type_id", 1, 1 );
|
2266
|
+
rb_define_attr( cPrivateType, "value", 1, 1 );
|
2267
|
+
rb_define_method( cPrivateType, "initialize", syck_privatetype_initialize, 2);
|
2268
|
+
|
2269
|
+
/*
|
2270
|
+
* Define YAML::DomainType class
|
2271
|
+
*/
|
2272
|
+
cDomainType = rb_define_class_under( rb_syck, "DomainType", rb_cObject );
|
2273
|
+
rb_define_attr( cDomainType, "domain", 1, 1 );
|
2274
|
+
rb_define_attr( cDomainType, "type_id", 1, 1 );
|
2275
|
+
rb_define_attr( cDomainType, "value", 1, 1 );
|
2276
|
+
rb_define_method( cDomainType, "initialize", syck_domaintype_initialize, 3);
|
2277
|
+
|
2278
|
+
/*
|
2279
|
+
* Define YAML::Object class
|
2280
|
+
*/
|
2281
|
+
cYObject = rb_define_class_under( rb_syck, "Object", rb_cObject );
|
2282
|
+
rb_define_attr( cYObject, "class", 1, 1 );
|
2283
|
+
rb_define_attr( cYObject, "ivars", 1, 1 );
|
2284
|
+
rb_define_method( cYObject, "initialize", syck_yobject_initialize, 2);
|
2285
|
+
rb_define_method( cYObject, "yaml_initialize", syck_yobject_initialize, 2);
|
2286
|
+
|
2287
|
+
/*
|
2288
|
+
* Define YAML::Syck::BadAlias class
|
2289
|
+
*/
|
2290
|
+
cBadAlias = rb_define_class_under( rb_syck, "BadAlias", rb_cObject );
|
2291
|
+
rb_define_attr( cBadAlias, "name", 1, 1 );
|
2292
|
+
rb_define_method( cBadAlias, "initialize", syck_badalias_initialize, 1);
|
2293
|
+
rb_define_method( cBadAlias, "<=>", syck_badalias_cmp, 1);
|
2294
|
+
rb_include_module( cBadAlias, rb_const_get( rb_cObject, rb_intern("Comparable") ) );
|
2295
|
+
|
2296
|
+
/*
|
2297
|
+
* Define YAML::Syck::MergeKey class
|
2298
|
+
*/
|
2299
|
+
cMergeKey = rb_define_class_under( rb_syck, "MergeKey", rb_cObject );
|
2300
|
+
|
2301
|
+
/*
|
2302
|
+
* Define YAML::Syck::DefaultKey class
|
2303
|
+
*/
|
2304
|
+
cDefaultKey = rb_define_class_under( rb_syck, "DefaultKey", rb_cObject );
|
2305
|
+
|
2306
|
+
/*
|
2307
|
+
* Define YAML::Syck::Out classes
|
2308
|
+
*/
|
2309
|
+
cOut = rb_define_class_under( rb_syck, "Out", rb_cObject );
|
2310
|
+
rb_define_attr( cOut, "emitter", 1, 1 );
|
2311
|
+
rb_define_method( cOut, "initialize", syck_out_initialize, 1 );
|
2312
|
+
rb_define_method( cOut, "map", syck_out_map, -1 );
|
2313
|
+
rb_define_method( cOut, "seq", syck_out_seq, -1 );
|
2314
|
+
rb_define_method( cOut, "scalar", syck_out_scalar, -1 );
|
2315
|
+
|
2316
|
+
/*
|
2317
|
+
* Define YAML::Syck::Emitter class
|
2318
|
+
*/
|
2319
|
+
cEmitter = rb_define_class_under( rb_syck, "Emitter", rb_cObject );
|
2320
|
+
rb_define_attr( cEmitter, "level", 1, 1 );
|
2321
|
+
rb_define_alloc_func( cEmitter, syck_emitter_s_alloc );
|
2322
|
+
rb_define_method( cEmitter, "initialize", syck_emitter_reset, -1 );
|
2323
|
+
rb_define_method( cEmitter, "reset", syck_emitter_reset, -1 );
|
2324
|
+
rb_define_method( cEmitter, "emit", syck_emitter_emit, -1 );
|
2325
|
+
rb_define_method( cEmitter, "set_resolver", syck_emitter_set_resolver, 1);
|
2326
|
+
rb_define_method( cEmitter, "node_export", syck_emitter_node_export, 1);
|
2327
|
+
}
|
2328
|
+
|