mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27437 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			407 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			407 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * node.c
 | 
						|
 *
 | 
						|
 * $Author$
 | 
						|
 *
 | 
						|
 * Copyright (C) 2003 why the lucky stiff
 | 
						|
 */
 | 
						|
 | 
						|
#include "ruby/ruby.h"
 | 
						|
#include "syck.h"
 | 
						|
 | 
						|
/*
 | 
						|
 * Node allocation functions
 | 
						|
 */
 | 
						|
SyckNode *
 | 
						|
syck_alloc_node( enum syck_kind_tag type )
 | 
						|
{
 | 
						|
    SyckNode *s;
 | 
						|
 | 
						|
    s = S_ALLOC( SyckNode );
 | 
						|
    s->kind = type;
 | 
						|
    s->id = 0;
 | 
						|
    s->type_id = NULL;
 | 
						|
    s->anchor = NULL;
 | 
						|
    s->shortcut = NULL;
 | 
						|
 | 
						|
    return s;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_free_node( SyckNode *n )
 | 
						|
{
 | 
						|
    syck_free_members( n );
 | 
						|
    if ( n->type_id != NULL )
 | 
						|
    {
 | 
						|
        S_FREE( n->type_id );
 | 
						|
        n->type_id = NULL;
 | 
						|
    }
 | 
						|
    if ( n->anchor != NULL )
 | 
						|
    {
 | 
						|
        S_FREE( n->anchor );
 | 
						|
        n->anchor = NULL;
 | 
						|
    }
 | 
						|
    S_FREE( n );
 | 
						|
}
 | 
						|
 | 
						|
SyckNode *
 | 
						|
syck_alloc_map(void)
 | 
						|
{
 | 
						|
    SyckNode *n;
 | 
						|
    struct SyckMap *m;
 | 
						|
 | 
						|
    m = S_ALLOC( struct SyckMap );
 | 
						|
    m->style = map_none;
 | 
						|
    m->idx = 0;
 | 
						|
    m->capa = ALLOC_CT;
 | 
						|
    m->keys = S_ALLOC_N( SYMID, m->capa );
 | 
						|
    m->values = S_ALLOC_N( SYMID, m->capa );
 | 
						|
 | 
						|
    n = syck_alloc_node( syck_map_kind );
 | 
						|
    n->data.pairs = m;
 | 
						|
 | 
						|
    return n;
 | 
						|
}
 | 
						|
 | 
						|
SyckNode *
 | 
						|
syck_alloc_seq(void)
 | 
						|
{
 | 
						|
    SyckNode *n;
 | 
						|
    struct SyckSeq *s;
 | 
						|
 | 
						|
    s = S_ALLOC( struct SyckSeq );
 | 
						|
    s->style = seq_none;
 | 
						|
    s->idx = 0;
 | 
						|
    s->capa = ALLOC_CT;
 | 
						|
    s->items = S_ALLOC_N( SYMID, s->capa );
 | 
						|
 | 
						|
    n = syck_alloc_node( syck_seq_kind );
 | 
						|
    n->data.list = s;
 | 
						|
 | 
						|
    return n;
 | 
						|
}
 | 
						|
 | 
						|
SyckNode *
 | 
						|
syck_alloc_str(void)
 | 
						|
{
 | 
						|
    SyckNode *n;
 | 
						|
    struct SyckStr *s;
 | 
						|
 | 
						|
    s = S_ALLOC( struct SyckStr );
 | 
						|
    s->len = 0;
 | 
						|
    s->ptr = NULL;
 | 
						|
    s->style = scalar_none;
 | 
						|
 | 
						|
    n = syck_alloc_node( syck_str_kind );
 | 
						|
    n->data.str = s;
 | 
						|
 | 
						|
    return n;
 | 
						|
}
 | 
						|
 | 
						|
SyckNode *
 | 
						|
syck_new_str( const char *str, enum scalar_style style )
 | 
						|
{
 | 
						|
    return syck_new_str2( str, strlen( str ), style );
 | 
						|
}
 | 
						|
 | 
						|
SyckNode *
 | 
						|
syck_new_str2( const char *str, long len, enum scalar_style style )
 | 
						|
{
 | 
						|
    SyckNode *n;
 | 
						|
 | 
						|
    n = syck_alloc_str();
 | 
						|
    n->data.str->ptr = S_ALLOC_N( char, len + 1 );
 | 
						|
    n->data.str->len = len;
 | 
						|
    n->data.str->style = style;
 | 
						|
    memcpy( n->data.str->ptr, str, len );
 | 
						|
    n->data.str->ptr[len] = '\0';
 | 
						|
 | 
						|
    return n;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_replace_str( SyckNode *n, char *str, enum scalar_style style )
 | 
						|
{
 | 
						|
    syck_replace_str2( n, str, strlen( str ), style );
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style )
 | 
						|
{
 | 
						|
    if ( n->data.str->ptr != NULL )
 | 
						|
    {
 | 
						|
        S_FREE( n->data.str->ptr );
 | 
						|
        n->data.str->ptr = NULL;
 | 
						|
        n->data.str->len = 0;
 | 
						|
    }
 | 
						|
    n->data.str->ptr = S_ALLOC_N( char, len + 1 );
 | 
						|
    n->data.str->len = len;
 | 
						|
    n->data.str->style = style;
 | 
						|
    memcpy( n->data.str->ptr, str, len );
 | 
						|
    n->data.str->ptr[len] = '\0';
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_str_blow_away_commas( SyckNode *n )
 | 
						|
{
 | 
						|
    char *go, *end;
 | 
						|
 | 
						|
    go = n->data.str->ptr;
 | 
						|
    end = go + n->data.str->len;
 | 
						|
    while ( *(++go) != '\0' )
 | 
						|
    {
 | 
						|
        if ( *go == ',' )
 | 
						|
        {
 | 
						|
            n->data.str->len -= 1;
 | 
						|
            memmove( go, go + 1, end - go );
 | 
						|
            end -= 1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
syck_str_read( SyckNode *n )
 | 
						|
{
 | 
						|
    ASSERT( n != NULL );
 | 
						|
    return n->data.str->ptr;
 | 
						|
}
 | 
						|
 | 
						|
SyckNode *
 | 
						|
syck_new_map( SYMID key, SYMID value )
 | 
						|
{
 | 
						|
    SyckNode *n;
 | 
						|
 | 
						|
    n = syck_alloc_map();
 | 
						|
    syck_map_add( n, key, value );
 | 
						|
 | 
						|
    return n;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_map_empty( SyckNode *n )
 | 
						|
{
 | 
						|
    struct SyckMap *m;
 | 
						|
    ASSERT( n != NULL );
 | 
						|
    ASSERT( n->data.list != NULL );
 | 
						|
 | 
						|
    S_FREE( n->data.pairs->keys );
 | 
						|
    S_FREE( n->data.pairs->values );
 | 
						|
    m = n->data.pairs;
 | 
						|
    m->idx = 0;
 | 
						|
    m->capa = ALLOC_CT;
 | 
						|
    m->keys = S_ALLOC_N( SYMID, m->capa );
 | 
						|
    m->values = S_ALLOC_N( SYMID, m->capa );
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_map_add( SyckNode *map, SYMID key, SYMID value )
 | 
						|
{
 | 
						|
    struct SyckMap *m;
 | 
						|
    long idx;
 | 
						|
 | 
						|
    ASSERT( map != NULL );
 | 
						|
    ASSERT( map->data.pairs != NULL );
 | 
						|
 | 
						|
    m = map->data.pairs;
 | 
						|
    idx = m->idx;
 | 
						|
    m->idx += 1;
 | 
						|
    if ( m->idx > m->capa )
 | 
						|
    {
 | 
						|
        m->capa += ALLOC_CT;
 | 
						|
        S_REALLOC_N( m->keys, SYMID, m->capa );
 | 
						|
        S_REALLOC_N( m->values, SYMID, m->capa );
 | 
						|
    }
 | 
						|
    m->keys[idx] = key;
 | 
						|
    m->values[idx] = value;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_map_update( SyckNode *map1, SyckNode *map2 )
 | 
						|
{
 | 
						|
    struct SyckMap *m1, *m2;
 | 
						|
    long new_idx, new_capa;
 | 
						|
    ASSERT( map1 != NULL );
 | 
						|
    ASSERT( map2 != NULL );
 | 
						|
 | 
						|
    m1 = map1->data.pairs;
 | 
						|
    m2 = map2->data.pairs;
 | 
						|
    if ( m2->idx < 1 ) return;
 | 
						|
 | 
						|
    new_idx = m1->idx;
 | 
						|
    new_idx += m2->idx;
 | 
						|
    new_capa = m1->capa;
 | 
						|
    while ( new_idx > new_capa )
 | 
						|
    {
 | 
						|
        new_capa += ALLOC_CT;
 | 
						|
    }
 | 
						|
    if ( new_capa > m1->capa )
 | 
						|
    {
 | 
						|
        m1->capa = new_capa;
 | 
						|
        S_REALLOC_N( m1->keys, SYMID, m1->capa );
 | 
						|
        S_REALLOC_N( m1->values, SYMID, m1->capa );
 | 
						|
    }
 | 
						|
    for ( new_idx = 0; new_idx < m2->idx; m1->idx++, new_idx++ )
 | 
						|
    {
 | 
						|
        m1->keys[m1->idx] = m2->keys[new_idx];
 | 
						|
        m1->values[m1->idx] = m2->values[new_idx];
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
long
 | 
						|
syck_map_count( SyckNode *map )
 | 
						|
{
 | 
						|
    ASSERT( map != NULL );
 | 
						|
    ASSERT( map->data.pairs != NULL );
 | 
						|
    return map->data.pairs->idx;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_map_assign( SyckNode *map, enum map_part p, long idx, SYMID id )
 | 
						|
{
 | 
						|
    struct SyckMap *m;
 | 
						|
 | 
						|
    ASSERT( map != NULL );
 | 
						|
    m = map->data.pairs;
 | 
						|
    ASSERT( m != NULL );
 | 
						|
    if ( p == map_key )
 | 
						|
    {
 | 
						|
        m->keys[idx] = id;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        m->values[idx] = id;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
SYMID
 | 
						|
syck_map_read( SyckNode *map, enum map_part p, long idx )
 | 
						|
{
 | 
						|
    struct SyckMap *m;
 | 
						|
 | 
						|
    ASSERT( map != NULL );
 | 
						|
    m = map->data.pairs;
 | 
						|
    ASSERT( m != NULL );
 | 
						|
    if ( p == map_key )
 | 
						|
    {
 | 
						|
        return m->keys[idx];
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        return m->values[idx];
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
SyckNode *
 | 
						|
syck_new_seq( SYMID value )
 | 
						|
{
 | 
						|
    SyckNode *n;
 | 
						|
 | 
						|
    n = syck_alloc_seq();
 | 
						|
    syck_seq_add( n, value );
 | 
						|
 | 
						|
    return n;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_seq_empty( SyckNode *n )
 | 
						|
{
 | 
						|
    struct SyckSeq *s;
 | 
						|
    ASSERT( n != NULL );
 | 
						|
    ASSERT( n->data.list != NULL );
 | 
						|
 | 
						|
    S_FREE( n->data.list->items );
 | 
						|
    s = n->data.list;
 | 
						|
    s->idx = 0;
 | 
						|
    s->capa = ALLOC_CT;
 | 
						|
    s->items = S_ALLOC_N( SYMID, s->capa );
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_seq_add( SyckNode *arr, SYMID value )
 | 
						|
{
 | 
						|
    struct SyckSeq *s;
 | 
						|
    long idx;
 | 
						|
 | 
						|
    ASSERT( arr != NULL );
 | 
						|
    ASSERT( arr->data.list != NULL );
 | 
						|
 | 
						|
    s = arr->data.list;
 | 
						|
    idx = s->idx;
 | 
						|
    s->idx += 1;
 | 
						|
    if ( s->idx > s->capa )
 | 
						|
    {
 | 
						|
        s->capa += ALLOC_CT;
 | 
						|
        S_REALLOC_N( s->items, SYMID, s->capa );
 | 
						|
    }
 | 
						|
    s->items[idx] = value;
 | 
						|
}
 | 
						|
 | 
						|
long
 | 
						|
syck_seq_count( SyckNode *seq )
 | 
						|
{
 | 
						|
    ASSERT( seq != NULL );
 | 
						|
    ASSERT( seq->data.list != NULL );
 | 
						|
    return seq->data.list->idx;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_seq_assign( SyckNode *seq, long idx, SYMID id )
 | 
						|
{
 | 
						|
    struct SyckSeq *s;
 | 
						|
 | 
						|
    ASSERT( map != NULL );
 | 
						|
    s = seq->data.list;
 | 
						|
    ASSERT( m != NULL );
 | 
						|
    s->items[idx] = id;
 | 
						|
}
 | 
						|
 | 
						|
SYMID
 | 
						|
syck_seq_read( SyckNode *seq, long idx )
 | 
						|
{
 | 
						|
    struct SyckSeq *s;
 | 
						|
 | 
						|
    ASSERT( seq != NULL );
 | 
						|
    s = seq->data.list;
 | 
						|
    ASSERT( s != NULL );
 | 
						|
    return s->items[idx];
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
syck_free_members( SyckNode *n )
 | 
						|
{
 | 
						|
    if ( n == NULL ) return;
 | 
						|
 | 
						|
    switch ( n->kind  )
 | 
						|
    {
 | 
						|
        case syck_str_kind:
 | 
						|
            if ( n->data.str != NULL )
 | 
						|
            {
 | 
						|
                S_FREE( n->data.str->ptr );
 | 
						|
                n->data.str->ptr = NULL;
 | 
						|
                n->data.str->len = 0;
 | 
						|
                S_FREE( n->data.str );
 | 
						|
                n->data.str = NULL;
 | 
						|
            }
 | 
						|
        break;
 | 
						|
 | 
						|
        case syck_seq_kind:
 | 
						|
            if ( n->data.list != NULL )
 | 
						|
            {
 | 
						|
                S_FREE( n->data.list->items );
 | 
						|
                S_FREE( n->data.list );
 | 
						|
                n->data.list = NULL;
 | 
						|
            }
 | 
						|
        break;
 | 
						|
 | 
						|
        case syck_map_kind:
 | 
						|
            if ( n->data.pairs != NULL )
 | 
						|
            {
 | 
						|
                S_FREE( n->data.pairs->keys );
 | 
						|
                S_FREE( n->data.pairs->values );
 | 
						|
                S_FREE( n->data.pairs );
 | 
						|
                n->data.pairs = NULL;
 | 
						|
            }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 |