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.
Files changed (54) hide show
  1. data/.autotest.erb +8 -0
  2. data/.gemtest +0 -0
  3. data/CHANGELOG.rdoc +6 -0
  4. data/Manifest.txt +52 -0
  5. data/README.rdoc +51 -0
  6. data/Rakefile +32 -0
  7. data/ext/syck/bytecode.c +1165 -0
  8. data/ext/syck/emitter.c +1247 -0
  9. data/ext/syck/extconf.h +3 -0
  10. data/ext/syck/extconf.rb +5 -0
  11. data/ext/syck/gram.c +1894 -0
  12. data/ext/syck/gram.h +79 -0
  13. data/ext/syck/handler.c +173 -0
  14. data/ext/syck/implicit.c +2990 -0
  15. data/ext/syck/node.c +407 -0
  16. data/ext/syck/rubyext.c +2328 -0
  17. data/ext/syck/syck.c +524 -0
  18. data/ext/syck/syck.h +453 -0
  19. data/ext/syck/token.c +2724 -0
  20. data/ext/syck/yaml2byte.c +259 -0
  21. data/ext/syck/yamlbyte.h +171 -0
  22. data/lib/syck.bundle +0 -0
  23. data/lib/syck.rb +447 -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/syck.rb +14 -0
  39. data/test/helper.rb +2 -0
  40. data/test/test_array.rb +13 -0
  41. data/test/test_boolean.rb +36 -0
  42. data/test/test_class.rb +11 -0
  43. data/test/test_exception.rb +45 -0
  44. data/test/test_hash.rb +24 -0
  45. data/test/test_null.rb +19 -0
  46. data/test/test_omap.rb +55 -0
  47. data/test/test_set.rb +30 -0
  48. data/test/test_string.rb +44 -0
  49. data/test/test_struct.rb +32 -0
  50. data/test/test_symbol.rb +21 -0
  51. data/test/test_time.rb +23 -0
  52. data/test/test_yaml.rb +1403 -0
  53. data/test/test_yaml_properties.rb +63 -0
  54. metadata +187 -0
@@ -0,0 +1,524 @@
1
+ /*
2
+ * syck.c
3
+ *
4
+ * $Author$
5
+ *
6
+ * Copyright (C) 2003 why the lucky stiff
7
+ */
8
+ #include "ruby/ruby.h"
9
+
10
+ #include <stdio.h>
11
+ #include <string.h>
12
+
13
+ #include "syck.h"
14
+
15
+ void syck_parser_pop_level( SyckParser * );
16
+
17
+ /*
18
+ * Custom assert
19
+ */
20
+ void
21
+ syck_assert( const char *file_name, unsigned line_num, const char *expr )
22
+ {
23
+ fflush( NULL );
24
+ fprintf( stderr, "\nAssertion failed: %s, line %u: %s\n",
25
+ file_name, line_num, expr );
26
+ fflush( stderr );
27
+ abort();
28
+ }
29
+
30
+ /*
31
+ * Allocates and copies a string
32
+ */
33
+ char *
34
+ syck_strndup( const char *buf, long len )
35
+ {
36
+ char *new = S_ALLOC_N( char, len + 1 );
37
+ S_MEMZERO( new, char, len + 1 );
38
+ S_MEMCPY( new, buf, char, len );
39
+ return new;
40
+ }
41
+
42
+ /*
43
+ * Default FILE IO function
44
+ */
45
+ long
46
+ syck_io_file_read( char *buf, SyckIoFile *file, long max_size, long skip )
47
+ {
48
+ long len = 0;
49
+
50
+ ASSERT( file != NULL );
51
+
52
+ max_size -= skip;
53
+ len = fread( buf + skip, sizeof( char ), max_size, file->ptr );
54
+ len += skip;
55
+ buf[len] = '\0';
56
+
57
+ return len;
58
+ }
59
+
60
+ /*
61
+ * Default string IO function
62
+ */
63
+ long
64
+ syck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip )
65
+ {
66
+ char *beg;
67
+ long len = 0;
68
+
69
+ ASSERT( str != NULL );
70
+ beg = str->ptr;
71
+ if ( max_size >= 0 )
72
+ {
73
+ max_size -= skip;
74
+ if ( max_size <= 0 ) max_size = 0;
75
+ else str->ptr += max_size;
76
+
77
+ if ( str->ptr > str->end )
78
+ {
79
+ str->ptr = str->end;
80
+ }
81
+ }
82
+ else
83
+ {
84
+ /* Use exact string length */
85
+ while ( str->ptr < str->end ) {
86
+ if (*(str->ptr++) == '\n') break;
87
+ }
88
+ }
89
+ if ( beg < str->ptr )
90
+ {
91
+ len = ( str->ptr - beg );
92
+ S_MEMCPY( buf + skip, beg, char, len );
93
+ }
94
+ len += skip;
95
+ buf[len] = '\0';
96
+
97
+ return len;
98
+ }
99
+
100
+ void
101
+ syck_parser_reset_levels( SyckParser *p )
102
+ {
103
+ while ( p->lvl_idx > 1 )
104
+ {
105
+ syck_parser_pop_level( p );
106
+ }
107
+
108
+ if ( p->lvl_idx < 1 )
109
+ {
110
+ p->lvl_idx = 1;
111
+ p->levels[0].spaces = -1;
112
+ p->levels[0].ncount = 0;
113
+ p->levels[0].domain = syck_strndup( "", 0 );
114
+ }
115
+ p->levels[0].status = syck_lvl_header;
116
+ }
117
+
118
+ void
119
+ syck_parser_reset_cursor( SyckParser *p )
120
+ {
121
+ if ( p->buffer == NULL )
122
+ {
123
+ p->buffer = S_ALLOC_N( char, p->bufsize );
124
+ S_MEMZERO( p->buffer, char, p->bufsize );
125
+ }
126
+ p->buffer[0] = '\0';
127
+
128
+ p->cursor = NULL;
129
+ p->lineptr = NULL;
130
+ p->linectptr = NULL;
131
+ p->token = NULL;
132
+ p->toktmp = NULL;
133
+ p->marker = NULL;
134
+ p->limit = NULL;
135
+
136
+ p->root = 0;
137
+ p->root_on_error = 0;
138
+ p->linect = 0;
139
+ p->eof = 0;
140
+ p->last_token = 0;
141
+ p->force_token = 0;
142
+ }
143
+
144
+ /*
145
+ * Value to return on a parse error
146
+ */
147
+ void
148
+ syck_parser_set_root_on_error( SyckParser *p, SYMID roer )
149
+ {
150
+ p->root_on_error = roer;
151
+ }
152
+
153
+ /*
154
+ * Allocate the parser
155
+ */
156
+ SyckParser *
157
+ syck_new_parser(void)
158
+ {
159
+ SyckParser *p;
160
+ p = S_ALLOC( SyckParser );
161
+ S_MEMZERO( p, SyckParser, 1 );
162
+ p->lvl_capa = ALLOC_CT;
163
+ p->levels = S_ALLOC_N( SyckLevel, p->lvl_capa );
164
+ p->input_type = syck_yaml_utf8;
165
+ p->io_type = syck_io_str;
166
+ p->io.str = NULL;
167
+ p->syms = NULL;
168
+ p->anchors = NULL;
169
+ p->bad_anchors = NULL;
170
+ p->implicit_typing = 1;
171
+ p->taguri_expansion = 0;
172
+ p->bufsize = SYCK_BUFFERSIZE;
173
+ p->buffer = NULL;
174
+ p->lvl_idx = 0;
175
+ syck_parser_reset_levels( p );
176
+ return p;
177
+ }
178
+
179
+ int
180
+ syck_add_sym( SyckParser *p, void *data )
181
+ {
182
+ SYMID id = 0;
183
+ if ( p->syms == NULL )
184
+ {
185
+ p->syms = st_init_numtable();
186
+ }
187
+ id = p->syms->num_entries + 1;
188
+ st_insert( p->syms, id, (st_data_t)data );
189
+ return (int)id;
190
+ }
191
+
192
+ int
193
+ syck_lookup_sym( SyckParser *p, SYMID id, void **datap )
194
+ {
195
+ st_data_t data;
196
+ int ret;
197
+ if ( p->syms == NULL ) return 0;
198
+ ret = st_lookup( p->syms, id, &data );
199
+ if(ret) *datap = (void *)data;
200
+ return ret;
201
+ }
202
+
203
+ int
204
+ syck_st_free_nodes( char *key, SyckNode *n, char *arg )
205
+ {
206
+ if ( n != (void *)1 ) syck_free_node( n );
207
+ n = NULL;
208
+ return ST_CONTINUE;
209
+ }
210
+
211
+ void
212
+ syck_st_free( SyckParser *p )
213
+ {
214
+ /*
215
+ * Free the anchor tables
216
+ */
217
+ if ( p->anchors != NULL )
218
+ {
219
+ st_foreach( p->anchors, syck_st_free_nodes, 0 );
220
+ st_free_table( p->anchors );
221
+ p->anchors = NULL;
222
+ }
223
+
224
+ if ( p->bad_anchors != NULL )
225
+ {
226
+ st_foreach( p->bad_anchors, syck_st_free_nodes, 0 );
227
+ st_free_table( p->bad_anchors );
228
+ p->bad_anchors = NULL;
229
+ }
230
+ }
231
+
232
+ typedef struct {
233
+ long hash;
234
+ char *buffer;
235
+ long length;
236
+ long remaining;
237
+ int printed;
238
+ } bytestring_t;
239
+
240
+ int
241
+ syck_st_free_syms( void *key, bytestring_t *sav, void *dummy )
242
+ {
243
+ S_FREE(sav->buffer);
244
+ S_FREE(sav);
245
+ return ST_CONTINUE;
246
+ }
247
+
248
+ void
249
+ syck_free_parser( SyckParser *p )
250
+ {
251
+ /*
252
+ * Free the adhoc symbol table
253
+ */
254
+ if ( p->syms != NULL )
255
+ {
256
+ st_foreach( p->syms, syck_st_free_syms, 0 );
257
+ st_free_table( p->syms );
258
+ p->syms = NULL;
259
+ }
260
+
261
+ /*
262
+ * Free tables, levels
263
+ */
264
+ syck_st_free( p );
265
+ syck_parser_reset_levels( p );
266
+ S_FREE( p->levels[0].domain );
267
+ S_FREE( p->levels );
268
+
269
+ if ( p->buffer != NULL )
270
+ {
271
+ S_FREE( p->buffer );
272
+ }
273
+ free_any_io( p );
274
+ S_FREE( p );
275
+ }
276
+
277
+ void
278
+ syck_parser_handler( SyckParser *p, SyckNodeHandler hdlr )
279
+ {
280
+ ASSERT( p != NULL );
281
+ p->handler = hdlr;
282
+ }
283
+
284
+ void
285
+ syck_parser_implicit_typing( SyckParser *p, int flag )
286
+ {
287
+ p->implicit_typing = ( flag == 0 ? 0 : 1 );
288
+ }
289
+
290
+ void
291
+ syck_parser_taguri_expansion( SyckParser *p, int flag )
292
+ {
293
+ p->taguri_expansion = ( flag == 0 ? 0 : 1 );
294
+ }
295
+
296
+ void
297
+ syck_parser_error_handler( SyckParser *p, SyckErrorHandler hdlr )
298
+ {
299
+ ASSERT( p != NULL );
300
+ p->error_handler = hdlr;
301
+ }
302
+
303
+ void
304
+ syck_parser_bad_anchor_handler( SyckParser *p, SyckBadAnchorHandler hdlr )
305
+ {
306
+ ASSERT( p != NULL );
307
+ p->bad_anchor_handler = hdlr;
308
+ }
309
+
310
+ void
311
+ syck_parser_set_input_type( SyckParser *p, enum syck_parser_input input_type )
312
+ {
313
+ ASSERT( p != NULL );
314
+ p->input_type = input_type;
315
+ }
316
+
317
+ void
318
+ syck_parser_file( SyckParser *p, FILE *fp, SyckIoFileRead read )
319
+ {
320
+ ASSERT( p != NULL );
321
+ free_any_io( p );
322
+ syck_parser_reset_cursor( p );
323
+ p->io_type = syck_io_file;
324
+ p->io.file = S_ALLOC( SyckIoFile );
325
+ p->io.file->ptr = fp;
326
+ if ( read != NULL )
327
+ {
328
+ p->io.file->read = read;
329
+ }
330
+ else
331
+ {
332
+ p->io.file->read = syck_io_file_read;
333
+ }
334
+ }
335
+
336
+ void
337
+ syck_parser_str( SyckParser *p, char *ptr, long len, SyckIoStrRead read )
338
+ {
339
+ ASSERT( p != NULL );
340
+ free_any_io( p );
341
+ syck_parser_reset_cursor( p );
342
+ p->io_type = syck_io_str;
343
+ p->io.str = S_ALLOC( SyckIoStr );
344
+ p->io.str->beg = ptr;
345
+ p->io.str->ptr = ptr;
346
+ p->io.str->end = ptr + len;
347
+ if ( read != NULL )
348
+ {
349
+ p->io.str->read = read;
350
+ }
351
+ else
352
+ {
353
+ p->io.str->read = syck_io_str_read;
354
+ }
355
+ }
356
+
357
+ void
358
+ syck_parser_str_auto( SyckParser *p, char *ptr, SyckIoStrRead read )
359
+ {
360
+ syck_parser_str( p, ptr, strlen( ptr ), read );
361
+ }
362
+
363
+ SyckLevel *
364
+ syck_parser_current_level( SyckParser *p )
365
+ {
366
+ return &p->levels[p->lvl_idx-1];
367
+ }
368
+
369
+ void
370
+ syck_parser_pop_level( SyckParser *p )
371
+ {
372
+ ASSERT( p != NULL );
373
+
374
+ /* The root level should never be popped */
375
+ if ( p->lvl_idx <= 1 ) return;
376
+
377
+ p->lvl_idx -= 1;
378
+ free( p->levels[p->lvl_idx].domain );
379
+ }
380
+
381
+ void
382
+ syck_parser_add_level( SyckParser *p, int len, enum syck_level_status status )
383
+ {
384
+ ASSERT( p != NULL );
385
+ if ( p->lvl_idx + 1 > p->lvl_capa )
386
+ {
387
+ p->lvl_capa += ALLOC_CT;
388
+ S_REALLOC_N( p->levels, SyckLevel, p->lvl_capa );
389
+ }
390
+
391
+ ASSERT( len > p->levels[p->lvl_idx-1].spaces );
392
+ p->levels[p->lvl_idx].spaces = len;
393
+ p->levels[p->lvl_idx].ncount = 0;
394
+ p->levels[p->lvl_idx].domain = syck_strndup( p->levels[p->lvl_idx-1].domain, strlen( p->levels[p->lvl_idx-1].domain ) );
395
+ p->levels[p->lvl_idx].status = status;
396
+ p->lvl_idx += 1;
397
+ }
398
+
399
+ void
400
+ free_any_io( SyckParser *p )
401
+ {
402
+ ASSERT( p != NULL );
403
+ switch ( p->io_type )
404
+ {
405
+ case syck_io_str:
406
+ if ( p->io.str != NULL )
407
+ {
408
+ S_FREE( p->io.str );
409
+ p->io.str = NULL;
410
+ }
411
+ break;
412
+
413
+ case syck_io_file:
414
+ if ( p->io.file != NULL )
415
+ {
416
+ S_FREE( p->io.file );
417
+ p->io.file = NULL;
418
+ }
419
+ break;
420
+ }
421
+ }
422
+
423
+ long
424
+ syck_move_tokens( SyckParser *p )
425
+ {
426
+ long count, skip;
427
+ ASSERT( p->buffer != NULL );
428
+
429
+ if ( p->token == NULL )
430
+ return 0;
431
+
432
+ skip = p->limit - p->token;
433
+ if ( ( count = p->token - p->buffer ) )
434
+ {
435
+ if (skip > 0)
436
+ S_MEMMOVE( p->buffer, p->token, char, skip );
437
+ p->token = p->buffer;
438
+ p->marker -= count;
439
+ p->cursor -= count;
440
+ p->toktmp -= count;
441
+ p->limit -= count;
442
+ p->lineptr -= count;
443
+ p->linectptr -= count;
444
+ }
445
+ return skip;
446
+ }
447
+
448
+ void
449
+ syck_check_limit( SyckParser *p, long len )
450
+ {
451
+ if ( p->cursor == NULL )
452
+ {
453
+ p->cursor = p->buffer;
454
+ p->lineptr = p->buffer;
455
+ p->linectptr = p->buffer;
456
+ p->marker = p->buffer;
457
+ }
458
+ p->limit = p->buffer + len;
459
+ }
460
+
461
+ long
462
+ syck_parser_read( SyckParser *p )
463
+ {
464
+ long len = 0;
465
+ long skip = 0;
466
+ ASSERT( p != NULL );
467
+ switch ( p->io_type )
468
+ {
469
+ case syck_io_str:
470
+ skip = syck_move_tokens( p );
471
+ len = (p->io.str->read)( p->buffer, p->io.str, SYCK_BUFFERSIZE - 1, skip );
472
+ break;
473
+
474
+ case syck_io_file:
475
+ skip = syck_move_tokens( p );
476
+ len = (p->io.file->read)( p->buffer, p->io.file, SYCK_BUFFERSIZE - 1, skip );
477
+ break;
478
+ }
479
+ syck_check_limit( p, len );
480
+ return len;
481
+ }
482
+
483
+ long
484
+ syck_parser_readlen( SyckParser *p, long max_size )
485
+ {
486
+ long len = 0;
487
+ long skip = 0;
488
+ ASSERT( p != NULL );
489
+ switch ( p->io_type )
490
+ {
491
+ case syck_io_str:
492
+ skip = syck_move_tokens( p );
493
+ len = (p->io.str->read)( p->buffer, p->io.str, max_size, skip );
494
+ break;
495
+
496
+ case syck_io_file:
497
+ skip = syck_move_tokens( p );
498
+ len = (p->io.file->read)( p->buffer, p->io.file, max_size, skip );
499
+ break;
500
+ }
501
+ syck_check_limit( p, len );
502
+ return len;
503
+ }
504
+
505
+ SYMID
506
+ syck_parse( SyckParser *p )
507
+ {
508
+ ASSERT( p != NULL );
509
+
510
+ syck_st_free( p );
511
+ syck_parser_reset_levels( p );
512
+ syckparse( p );
513
+ return p->root;
514
+ }
515
+
516
+ void
517
+ syck_default_error_handler( SyckParser *p, const char *msg )
518
+ {
519
+ printf( "Error at [Line %d, Col %"PRIdPTRDIFF"]: %s\n",
520
+ p->linect,
521
+ p->cursor - p->lineptr,
522
+ msg );
523
+ }
524
+