* io.c (rb_open_file): encoding in mode string was ignored if perm is
[ruby-svn.git] / ext / syck / node.c
blob890eba9d5884632f7287de04d20c3be64096e2dd
1 /*
2 * node.c
4 * $Author$
6 * Copyright (C) 2003 why the lucky stiff
7 */
9 #include "ruby/ruby.h"
10 #include "syck.h"
13 * Node allocation functions
15 SyckNode *
16 syck_alloc_node( enum syck_kind_tag type )
18 SyckNode *s;
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;
27 return s;
30 void
31 syck_free_node( SyckNode *n )
33 syck_free_members( n );
34 if ( n->type_id != NULL )
36 S_FREE( n->type_id );
37 n->type_id = NULL;
39 if ( n->anchor != NULL )
41 S_FREE( n->anchor );
42 n->anchor = NULL;
44 S_FREE( n );
47 SyckNode *
48 syck_alloc_map(void)
50 SyckNode *n;
51 struct SyckMap *m;
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 );
60 n = syck_alloc_node( syck_map_kind );
61 n->data.pairs = m;
63 return n;
66 SyckNode *
67 syck_alloc_seq(void)
69 SyckNode *n;
70 struct SyckSeq *s;
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 );
78 n = syck_alloc_node( syck_seq_kind );
79 n->data.list = s;
81 return n;
84 SyckNode *
85 syck_alloc_str(void)
87 SyckNode *n;
88 struct SyckStr *s;
90 s = S_ALLOC( struct SyckStr );
91 s->len = 0;
92 s->ptr = NULL;
93 s->style = scalar_none;
95 n = syck_alloc_node( syck_str_kind );
96 n->data.str = s;
98 return n;
101 SyckNode *
102 syck_new_str( const char *str, enum scalar_style style )
104 return syck_new_str2( str, strlen( str ), style );
107 SyckNode *
108 syck_new_str2( const char *str, long len, enum scalar_style style )
110 SyckNode *n;
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';
119 return n;
122 void
123 syck_replace_str( SyckNode *n, char *str, enum scalar_style style )
125 syck_replace_str2( n, str, strlen( str ), style );
128 void
129 syck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style )
131 if ( n->data.str != NULL )
133 S_FREE( n->data.str->ptr );
134 n->data.str->ptr = NULL;
135 n->data.str->len = 0;
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';
144 void
145 syck_str_blow_away_commas( SyckNode *n )
147 char *go, *end;
149 go = n->data.str->ptr;
150 end = go + n->data.str->len;
151 while ( *(++go) != '\0' )
153 if ( *go == ',' )
155 n->data.str->len -= 1;
156 memmove( go, go + 1, end - go );
157 end -= 1;
162 char *
163 syck_str_read( SyckNode *n )
165 ASSERT( n != NULL );
166 return n->data.str->ptr;
169 SyckNode *
170 syck_new_map( SYMID key, SYMID value )
172 SyckNode *n;
174 n = syck_alloc_map();
175 syck_map_add( n, key, value );
177 return n;
180 void
181 syck_map_empty( SyckNode *n )
183 struct SyckMap *m;
184 ASSERT( n != NULL );
185 ASSERT( n->data.list != NULL );
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 );
196 void
197 syck_map_add( SyckNode *map, SYMID key, SYMID value )
199 struct SyckMap *m;
200 long idx;
202 ASSERT( map != NULL );
203 ASSERT( map->data.pairs != NULL );
205 m = map->data.pairs;
206 idx = m->idx;
207 m->idx += 1;
208 if ( m->idx > m->capa )
210 m->capa += ALLOC_CT;
211 S_REALLOC_N( m->keys, SYMID, m->capa );
212 S_REALLOC_N( m->values, SYMID, m->capa );
214 m->keys[idx] = key;
215 m->values[idx] = value;
218 void
219 syck_map_update( SyckNode *map1, SyckNode *map2 )
221 struct SyckMap *m1, *m2;
222 long new_idx, new_capa;
223 ASSERT( map1 != NULL );
224 ASSERT( map2 != NULL );
226 m1 = map1->data.pairs;
227 m2 = map2->data.pairs;
228 if ( m2->idx < 1 ) return;
230 new_idx = m1->idx;
231 new_idx += m2->idx;
232 new_capa = m1->capa;
233 while ( new_idx > new_capa )
235 new_capa += ALLOC_CT;
237 if ( new_capa > m1->capa )
239 m1->capa = new_capa;
240 S_REALLOC_N( m1->keys, SYMID, m1->capa );
241 S_REALLOC_N( m1->values, SYMID, m1->capa );
243 for ( new_idx = 0; new_idx < m2->idx; m1->idx++, new_idx++ )
245 m1->keys[m1->idx] = m2->keys[new_idx];
246 m1->values[m1->idx] = m2->values[new_idx];
250 long
251 syck_map_count( SyckNode *map )
253 ASSERT( map != NULL );
254 ASSERT( map->data.pairs != NULL );
255 return map->data.pairs->idx;
258 void
259 syck_map_assign( SyckNode *map, enum map_part p, long idx, SYMID id )
261 struct SyckMap *m;
263 ASSERT( map != NULL );
264 m = map->data.pairs;
265 ASSERT( m != NULL );
266 if ( p == map_key )
268 m->keys[idx] = id;
270 else
272 m->values[idx] = id;
276 SYMID
277 syck_map_read( SyckNode *map, enum map_part p, long idx )
279 struct SyckMap *m;
281 ASSERT( map != NULL );
282 m = map->data.pairs;
283 ASSERT( m != NULL );
284 if ( p == map_key )
286 return m->keys[idx];
288 else
290 return m->values[idx];
294 SyckNode *
295 syck_new_seq( SYMID value )
297 SyckNode *n;
299 n = syck_alloc_seq();
300 syck_seq_add( n, value );
302 return n;
305 void
306 syck_seq_empty( SyckNode *n )
308 struct SyckSeq *s;
309 ASSERT( n != NULL );
310 ASSERT( n->data.list != NULL );
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 );
319 void
320 syck_seq_add( SyckNode *arr, SYMID value )
322 struct SyckSeq *s;
323 long idx;
325 ASSERT( arr != NULL );
326 ASSERT( arr->data.list != NULL );
328 s = arr->data.list;
329 idx = s->idx;
330 s->idx += 1;
331 if ( s->idx > s->capa )
333 s->capa += ALLOC_CT;
334 S_REALLOC_N( s->items, SYMID, s->capa );
336 s->items[idx] = value;
339 long
340 syck_seq_count( SyckNode *seq )
342 ASSERT( seq != NULL );
343 ASSERT( seq->data.list != NULL );
344 return seq->data.list->idx;
347 void
348 syck_seq_assign( SyckNode *seq, long idx, SYMID id )
350 struct SyckSeq *s;
352 ASSERT( map != NULL );
353 s = seq->data.list;
354 ASSERT( m != NULL );
355 s->items[idx] = id;
358 SYMID
359 syck_seq_read( SyckNode *seq, long idx )
361 struct SyckSeq *s;
363 ASSERT( seq != NULL );
364 s = seq->data.list;
365 ASSERT( s != NULL );
366 return s->items[idx];
369 void
370 syck_free_members( SyckNode *n )
372 if ( n == NULL ) return;
374 switch ( n->kind )
376 case syck_str_kind:
377 if ( n->data.str != NULL )
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;
385 break;
387 case syck_seq_kind:
388 if ( n->data.list != NULL )
390 S_FREE( n->data.list->items );
391 S_FREE( n->data.list );
392 n->data.list = NULL;
394 break;
396 case syck_map_kind:
397 if ( n->data.pairs != NULL )
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;
404 break;