rubysl-yaml 2.0.0 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,524 @@
1
+ /*
2
+ * syck.c
3
+ *
4
+ * $Author: naruse $
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 %d]: %s\n",
520
+ p->linect,
521
+ (int)(p->cursor - p->lineptr),
522
+ msg );
523
+ }
524
+