00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "ruby/ruby.h"
00010 #include "syck.h"
00011
00012
00013
00014
00015 SyckNode *
00016 syck_alloc_node( enum syck_kind_tag type )
00017 {
00018 SyckNode *s;
00019
00020 s = S_ALLOC( SyckNode );
00021 s->kind = type;
00022 s->id = 0;
00023 s->type_id = NULL;
00024 s->anchor = NULL;
00025 s->shortcut = NULL;
00026
00027 return s;
00028 }
00029
00030 void
00031 syck_free_node( SyckNode *n )
00032 {
00033 syck_free_members( n );
00034 if ( n->type_id != NULL )
00035 {
00036 S_FREE( n->type_id );
00037 n->type_id = NULL;
00038 }
00039 if ( n->anchor != NULL )
00040 {
00041 S_FREE( n->anchor );
00042 n->anchor = NULL;
00043 }
00044 S_FREE( n );
00045 }
00046
00047 SyckNode *
00048 syck_alloc_map(void)
00049 {
00050 SyckNode *n;
00051 struct SyckMap *m;
00052
00053 m = S_ALLOC( struct SyckMap );
00054 m->style = map_none;
00055 m->idx = 0;
00056 m->capa = ALLOC_CT;
00057 m->keys = S_ALLOC_N( SYMID, m->capa );
00058 m->values = S_ALLOC_N( SYMID, m->capa );
00059
00060 n = syck_alloc_node( syck_map_kind );
00061 n->data.pairs = m;
00062
00063 return n;
00064 }
00065
00066 SyckNode *
00067 syck_alloc_seq(void)
00068 {
00069 SyckNode *n;
00070 struct SyckSeq *s;
00071
00072 s = S_ALLOC( struct SyckSeq );
00073 s->style = seq_none;
00074 s->idx = 0;
00075 s->capa = ALLOC_CT;
00076 s->items = S_ALLOC_N( SYMID, s->capa );
00077
00078 n = syck_alloc_node( syck_seq_kind );
00079 n->data.list = s;
00080
00081 return n;
00082 }
00083
00084 SyckNode *
00085 syck_alloc_str(void)
00086 {
00087 SyckNode *n;
00088 struct SyckStr *s;
00089
00090 s = S_ALLOC( struct SyckStr );
00091 s->len = 0;
00092 s->ptr = NULL;
00093 s->style = scalar_none;
00094
00095 n = syck_alloc_node( syck_str_kind );
00096 n->data.str = s;
00097
00098 return n;
00099 }
00100
00101 SyckNode *
00102 syck_new_str( const char *str, enum scalar_style style )
00103 {
00104 return syck_new_str2( str, strlen( str ), style );
00105 }
00106
00107 SyckNode *
00108 syck_new_str2( const char *str, long len, enum scalar_style style )
00109 {
00110 SyckNode *n;
00111
00112 n = syck_alloc_str();
00113 n->data.str->ptr = S_ALLOC_N( char, len + 1 );
00114 n->data.str->len = len;
00115 n->data.str->style = style;
00116 memcpy( n->data.str->ptr, str, len );
00117 n->data.str->ptr[len] = '\0';
00118
00119 return n;
00120 }
00121
00122 void
00123 syck_replace_str( SyckNode *n, char *str, enum scalar_style style )
00124 {
00125 syck_replace_str2( n, str, strlen( str ), style );
00126 }
00127
00128 void
00129 syck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style )
00130 {
00131 if ( n->data.str->ptr != NULL )
00132 {
00133 S_FREE( n->data.str->ptr );
00134 n->data.str->ptr = NULL;
00135 n->data.str->len = 0;
00136 }
00137 n->data.str->ptr = S_ALLOC_N( char, len + 1 );
00138 n->data.str->len = len;
00139 n->data.str->style = style;
00140 memcpy( n->data.str->ptr, str, len );
00141 n->data.str->ptr[len] = '\0';
00142 }
00143
00144 void
00145 syck_str_blow_away_commas( SyckNode *n )
00146 {
00147 char *go, *end;
00148
00149 go = n->data.str->ptr;
00150 end = go + n->data.str->len;
00151 while ( *(++go) != '\0' )
00152 {
00153 if ( *go == ',' )
00154 {
00155 n->data.str->len -= 1;
00156 memmove( go, go + 1, end - go );
00157 end -= 1;
00158 }
00159 }
00160 }
00161
00162 char *
00163 syck_str_read( SyckNode *n )
00164 {
00165 ASSERT( n != NULL );
00166 return n->data.str->ptr;
00167 }
00168
00169 SyckNode *
00170 syck_new_map( SYMID key, SYMID value )
00171 {
00172 SyckNode *n;
00173
00174 n = syck_alloc_map();
00175 syck_map_add( n, key, value );
00176
00177 return n;
00178 }
00179
00180 void
00181 syck_map_empty( SyckNode *n )
00182 {
00183 struct SyckMap *m;
00184 ASSERT( n != NULL );
00185 ASSERT( n->data.list != NULL );
00186
00187 S_FREE( n->data.pairs->keys );
00188 S_FREE( n->data.pairs->values );
00189 m = n->data.pairs;
00190 m->idx = 0;
00191 m->capa = ALLOC_CT;
00192 m->keys = S_ALLOC_N( SYMID, m->capa );
00193 m->values = S_ALLOC_N( SYMID, m->capa );
00194 }
00195
00196 void
00197 syck_map_add( SyckNode *map, SYMID key, SYMID value )
00198 {
00199 struct SyckMap *m;
00200 long idx;
00201
00202 ASSERT( map != NULL );
00203 ASSERT( map->data.pairs != NULL );
00204
00205 m = map->data.pairs;
00206 idx = m->idx;
00207 m->idx += 1;
00208 if ( m->idx > m->capa )
00209 {
00210 m->capa += ALLOC_CT;
00211 S_REALLOC_N( m->keys, SYMID, m->capa );
00212 S_REALLOC_N( m->values, SYMID, m->capa );
00213 }
00214 m->keys[idx] = key;
00215 m->values[idx] = value;
00216 }
00217
00218 void
00219 syck_map_update( SyckNode *map1, SyckNode *map2 )
00220 {
00221 struct SyckMap *m1, *m2;
00222 long new_idx, new_capa;
00223 ASSERT( map1 != NULL );
00224 ASSERT( map2 != NULL );
00225
00226 m1 = map1->data.pairs;
00227 m2 = map2->data.pairs;
00228 if ( m2->idx < 1 ) return;
00229
00230 new_idx = m1->idx;
00231 new_idx += m2->idx;
00232 new_capa = m1->capa;
00233 while ( new_idx > new_capa )
00234 {
00235 new_capa += ALLOC_CT;
00236 }
00237 if ( new_capa > m1->capa )
00238 {
00239 m1->capa = new_capa;
00240 S_REALLOC_N( m1->keys, SYMID, m1->capa );
00241 S_REALLOC_N( m1->values, SYMID, m1->capa );
00242 }
00243 for ( new_idx = 0; new_idx < m2->idx; m1->idx++, new_idx++ )
00244 {
00245 m1->keys[m1->idx] = m2->keys[new_idx];
00246 m1->values[m1->idx] = m2->values[new_idx];
00247 }
00248 }
00249
00250 long
00251 syck_map_count( SyckNode *map )
00252 {
00253 ASSERT( map != NULL );
00254 ASSERT( map->data.pairs != NULL );
00255 return map->data.pairs->idx;
00256 }
00257
00258 void
00259 syck_map_assign( SyckNode *map, enum map_part p, long idx, SYMID id )
00260 {
00261 struct SyckMap *m;
00262
00263 ASSERT( map != NULL );
00264 m = map->data.pairs;
00265 ASSERT( m != NULL );
00266 if ( p == map_key )
00267 {
00268 m->keys[idx] = id;
00269 }
00270 else
00271 {
00272 m->values[idx] = id;
00273 }
00274 }
00275
00276 SYMID
00277 syck_map_read( SyckNode *map, enum map_part p, long idx )
00278 {
00279 struct SyckMap *m;
00280
00281 ASSERT( map != NULL );
00282 m = map->data.pairs;
00283 ASSERT( m != NULL );
00284 if ( p == map_key )
00285 {
00286 return m->keys[idx];
00287 }
00288 else
00289 {
00290 return m->values[idx];
00291 }
00292 }
00293
00294 SyckNode *
00295 syck_new_seq( SYMID value )
00296 {
00297 SyckNode *n;
00298
00299 n = syck_alloc_seq();
00300 syck_seq_add( n, value );
00301
00302 return n;
00303 }
00304
00305 void
00306 syck_seq_empty( SyckNode *n )
00307 {
00308 struct SyckSeq *s;
00309 ASSERT( n != NULL );
00310 ASSERT( n->data.list != NULL );
00311
00312 S_FREE( n->data.list->items );
00313 s = n->data.list;
00314 s->idx = 0;
00315 s->capa = ALLOC_CT;
00316 s->items = S_ALLOC_N( SYMID, s->capa );
00317 }
00318
00319 void
00320 syck_seq_add( SyckNode *arr, SYMID value )
00321 {
00322 struct SyckSeq *s;
00323 long idx;
00324
00325 ASSERT( arr != NULL );
00326 ASSERT( arr->data.list != NULL );
00327
00328 s = arr->data.list;
00329 idx = s->idx;
00330 s->idx += 1;
00331 if ( s->idx > s->capa )
00332 {
00333 s->capa += ALLOC_CT;
00334 S_REALLOC_N( s->items, SYMID, s->capa );
00335 }
00336 s->items[idx] = value;
00337 }
00338
00339 long
00340 syck_seq_count( SyckNode *seq )
00341 {
00342 ASSERT( seq != NULL );
00343 ASSERT( seq->data.list != NULL );
00344 return seq->data.list->idx;
00345 }
00346
00347 void
00348 syck_seq_assign( SyckNode *seq, long idx, SYMID id )
00349 {
00350 struct SyckSeq *s;
00351
00352 ASSERT( map != NULL );
00353 s = seq->data.list;
00354 ASSERT( m != NULL );
00355 s->items[idx] = id;
00356 }
00357
00358 SYMID
00359 syck_seq_read( SyckNode *seq, long idx )
00360 {
00361 struct SyckSeq *s;
00362
00363 ASSERT( seq != NULL );
00364 s = seq->data.list;
00365 ASSERT( s != NULL );
00366 return s->items[idx];
00367 }
00368
00369 void
00370 syck_free_members( SyckNode *n )
00371 {
00372 if ( n == NULL ) return;
00373
00374 switch ( n->kind )
00375 {
00376 case syck_str_kind:
00377 if ( n->data.str != NULL )
00378 {
00379 S_FREE( n->data.str->ptr );
00380 n->data.str->ptr = NULL;
00381 n->data.str->len = 0;
00382 S_FREE( n->data.str );
00383 n->data.str = NULL;
00384 }
00385 break;
00386
00387 case syck_seq_kind:
00388 if ( n->data.list != NULL )
00389 {
00390 S_FREE( n->data.list->items );
00391 S_FREE( n->data.list );
00392 n->data.list = NULL;
00393 }
00394 break;
00395
00396 case syck_map_kind:
00397 if ( n->data.pairs != NULL )
00398 {
00399 S_FREE( n->data.pairs->keys );
00400 S_FREE( n->data.pairs->values );
00401 S_FREE( n->data.pairs );
00402 n->data.pairs = NULL;
00403 }
00404 break;
00405 }
00406 }
00407
00408