rubysl-syck 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+