1/* 2 * node.c 3 * 4 * $Author: why $ 5 * $Date: 2005-09-17 02:59:53 +0800 (六, 17 9 2005) $ 6 * 7 * Copyright (C) 2003 why the lucky stiff 8 */ 9 10#include "syck.h" 11 12/* 13 * Node allocation functions 14 */ 15SyckNode * 16syck_alloc_node( enum syck_kind_tag type ) 17{ 18 SyckNode *s; 19 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; 26 27 return s; 28} 29 30void 31syck_free_node( SyckNode *n ) 32{ 33 syck_free_members( n ); 34 if ( n->type_id != NULL ) 35 { 36 S_FREE( n->type_id ); 37 n->type_id = NULL; 38 } 39 if ( n->anchor != NULL ) 40 { 41 S_FREE( n->anchor ); 42 n->anchor = NULL; 43 } 44 S_FREE( n ); 45} 46 47SyckNode * 48syck_alloc_map() 49{ 50 SyckNode *n; 51 struct SyckMap *m; 52 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 ); 59 60 n = syck_alloc_node( syck_map_kind ); 61 n->data.pairs = m; 62 63 return n; 64} 65 66SyckNode * 67syck_alloc_seq() 68{ 69 SyckNode *n; 70 struct SyckSeq *s; 71 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 ); 77 78 n = syck_alloc_node( syck_seq_kind ); 79 n->data.list = s; 80 81 return n; 82} 83 84SyckNode * 85syck_alloc_str() 86{ 87 SyckNode *n; 88 struct SyckStr *s; 89 90 s = S_ALLOC( struct SyckStr ); 91 s->len = 0; 92 s->ptr = NULL; 93 s->style = scalar_none; 94 95 n = syck_alloc_node( syck_str_kind ); 96 n->data.str = s; 97 98 return n; 99} 100 101SyckNode * 102syck_new_str( const char *str, enum scalar_style style ) 103{ 104 return syck_new_str2( str, strlen( str ), style ); 105} 106 107SyckNode * 108syck_new_str2( const char *str, long len, enum scalar_style style ) 109{ 110 SyckNode *n; 111 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'; 118 119 return n; 120} 121 122void 123syck_replace_str( SyckNode *n, char *str, enum scalar_style style ) 124{ 125 syck_replace_str2( n, str, strlen( str ), style ); 126} 127 128void 129syck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style ) 130{ 131 if ( n->data.str != NULL ) 132 { 133 S_FREE( n->data.str->ptr ); 134 n->data.str->ptr = NULL; 135 n->data.str->len = 0; 136 } 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'; 142} 143 144void 145syck_str_blow_away_commas( SyckNode *n ) 146{ 147 char *go, *end; 148 149 go = n->data.str->ptr; 150 end = go + n->data.str->len; 151 while ( *(++go) != '\0' ) 152 { 153 if ( *go == ',' ) 154 { 155 n->data.str->len -= 1; 156 memmove( go, go + 1, end - go ); 157 end -= 1; 158 } 159 } 160} 161 162char * 163syck_str_read( SyckNode *n ) 164{ 165 ASSERT( n != NULL ); 166 return n->data.str->ptr; 167} 168 169SyckNode * 170syck_new_map( SYMID key, SYMID value ) 171{ 172 SyckNode *n; 173 174 n = syck_alloc_map(); 175 syck_map_add( n, key, value ); 176 177 return n; 178} 179 180void 181syck_map_empty( SyckNode *n ) 182{ 183 struct SyckMap *m; 184 ASSERT( n != NULL ); 185 ASSERT( n->data.list != NULL ); 186 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 ); 194} 195 196void 197syck_map_add( SyckNode *map, SYMID key, SYMID value ) 198{ 199 struct SyckMap *m; 200 long idx; 201 202 ASSERT( map != NULL ); 203 ASSERT( map->data.pairs != NULL ); 204 205 m = map->data.pairs; 206 idx = m->idx; 207 m->idx += 1; 208 if ( m->idx > m->capa ) 209 { 210 m->capa += ALLOC_CT; 211 S_REALLOC_N( m->keys, SYMID, m->capa ); 212 S_REALLOC_N( m->values, SYMID, m->capa ); 213 } 214 m->keys[idx] = key; 215 m->values[idx] = value; 216} 217 218void 219syck_map_update( SyckNode *map1, SyckNode *map2 ) 220{ 221 struct SyckMap *m1, *m2; 222 long new_idx, new_capa; 223 ASSERT( map1 != NULL ); 224 ASSERT( map2 != NULL ); 225 226 m1 = map1->data.pairs; 227 m2 = map2->data.pairs; 228 if ( m2->idx < 1 ) return; 229 230 new_idx = m1->idx; 231 new_idx += m2->idx; 232 new_capa = m1->capa; 233 while ( new_idx > new_capa ) 234 { 235 new_capa += ALLOC_CT; 236 } 237 if ( new_capa > m1->capa ) 238 { 239 m1->capa = new_capa; 240 S_REALLOC_N( m1->keys, SYMID, m1->capa ); 241 S_REALLOC_N( m1->values, SYMID, m1->capa ); 242 } 243 for ( new_idx = 0; new_idx < m2->idx; m1->idx++, new_idx++ ) 244 { 245 m1->keys[m1->idx] = m2->keys[new_idx]; 246 m1->values[m1->idx] = m2->values[new_idx]; 247 } 248} 249 250long 251syck_map_count( SyckNode *map ) 252{ 253 ASSERT( map != NULL ); 254 ASSERT( map->data.pairs != NULL ); 255 return map->data.pairs->idx; 256} 257 258void 259syck_map_assign( SyckNode *map, enum map_part p, long idx, SYMID id ) 260{ 261 struct SyckMap *m; 262 263 ASSERT( map != NULL ); 264 m = map->data.pairs; 265 ASSERT( m != NULL ); 266 if ( p == map_key ) 267 { 268 m->keys[idx] = id; 269 } 270 else 271 { 272 m->values[idx] = id; 273 } 274} 275 276SYMID 277syck_map_read( SyckNode *map, enum map_part p, long idx ) 278{ 279 struct SyckMap *m; 280 281 ASSERT( map != NULL ); 282 m = map->data.pairs; 283 ASSERT( m != NULL ); 284 if ( p == map_key ) 285 { 286 return m->keys[idx]; 287 } 288 else 289 { 290 return m->values[idx]; 291 } 292} 293 294SyckNode * 295syck_new_seq( SYMID value ) 296{ 297 SyckNode *n; 298 299 n = syck_alloc_seq(); 300 syck_seq_add( n, value ); 301 302 return n; 303} 304 305void 306syck_seq_empty( SyckNode *n ) 307{ 308 struct SyckSeq *s; 309 ASSERT( n != NULL ); 310 ASSERT( n->data.list != NULL ); 311 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 ); 317} 318 319void 320syck_seq_add( SyckNode *arr, SYMID value ) 321{ 322 struct SyckSeq *s; 323 long idx; 324 325 ASSERT( arr != NULL ); 326 ASSERT( arr->data.list != NULL ); 327 328 s = arr->data.list; 329 idx = s->idx; 330 s->idx += 1; 331 if ( s->idx > s->capa ) 332 { 333 s->capa += ALLOC_CT; 334 S_REALLOC_N( s->items, SYMID, s->capa ); 335 } 336 s->items[idx] = value; 337} 338 339long 340syck_seq_count( SyckNode *seq ) 341{ 342 ASSERT( seq != NULL ); 343 ASSERT( seq->data.list != NULL ); 344 return seq->data.list->idx; 345} 346 347void 348syck_seq_assign( SyckNode *seq, long idx, SYMID id ) 349{ 350 struct SyckSeq *s; 351 352 ASSERT( map != NULL ); 353 s = seq->data.list; 354 ASSERT( m != NULL ); 355 s->items[idx] = id; 356} 357 358SYMID 359syck_seq_read( SyckNode *seq, long idx ) 360{ 361 struct SyckSeq *s; 362 363 ASSERT( seq != NULL ); 364 s = seq->data.list; 365 ASSERT( s != NULL ); 366 return s->items[idx]; 367} 368 369void 370syck_free_members( SyckNode *n ) 371{ 372 if ( n == NULL ) return; 373 374 switch ( n->kind ) 375 { 376 case syck_str_kind: 377 if ( n->data.str != NULL ) 378 { 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; 384 } 385 break; 386 387 case syck_seq_kind: 388 if ( n->data.list != NULL ) 389 { 390 S_FREE( n->data.list->items ); 391 S_FREE( n->data.list ); 392 n->data.list = NULL; 393 } 394 break; 395 396 case syck_map_kind: 397 if ( n->data.pairs != NULL ) 398 { 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; 403 } 404 break; 405 } 406} 407 408