rubysl-syck 1.0.1

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