/*
 * String List Library
 * Copyright (c) 1990, 1999 Erick Engelke
 */
#include <stdio.h>
#include <string.h>
#include <rtos.h>
#include <strlst.h>

stringlist *strlst_new( void )
{
    stringlist *sl;
    if ( (sl = kcalloc( sizeof( stringlist ), 1 )) != NULL )
        sl->sl_sig = _STRLST_SL_SIG;
    return( sl );
}

/*
 * returns the 1 based index of the new string, or 0 on failure
 */
int strlst_adddata( stringlist *sl, char *s, void *d )
{
    int i;
    stringentry *se, *stemp;

    if ( sl == NULL ) return( 0 );
    if ( sl->sl_sig != _STRLST_SL_SIG ) return( 0 );

    se = kcalloc( sizeof( stringentry ) , 1 );
    if ( se == NULL ) goto fail;
    se->se_sig = _STRLST_SE_SIG;


    /* allocate space, even if orig string is zero length */
    if ( (se->se_string = kstrdup( s )) == NULL ) goto fail;

    se->se_data = d;
    if ( sl->sl_list == NULL ) {
        sl->sl_list = se;
        return( 1 );
    }
    stemp = sl->sl_list;
    i = 1;
    while ( stemp->se_next ) {
        stemp = stemp->se_next;
        i++;
    }
    stemp->se_next = se;
    return( i );

fail:
    if ( se != NULL ) {
        if ( se->se_string != NULL ) kfree ( se->se_string);
        kfree( se );
    }
    return( 0 );
}

int strlst_add( stringlist *sl, char *s )
{
    return( strlst_adddata( sl, s, NULL ));
}

static void free_entry( stringentry *se )
{
    if ( se != NULL ) {
        if ( se->se_sig== _STRLST_SE_SIG ) {
            if ( se->se_string != NULL ) kfree( se->se_string );
            kfree( se );
        }
    }
}

void strlst_del( stringlist *sl, int index )
{
    stringentry *se, *sf;
    int i;

    if ( sl == NULL ) return;
    if ( sl->sl_sig != _STRLST_SL_SIG ) return;

    se = sl->sl_list;
    if ( se == NULL ) return;
    if ( se->se_sig != _STRLST_SE_SIG ) return;

    i = 1;
    if ( index == 1 ) {
        sl->sl_list = se->se_next;
        free_entry( se );
        return;
    }

    while ( se != NULL ) {
        sf = se->se_next;
        if ( i == index - 1 ) {
            if ( sf != NULL ) {
                se->se_next = sf->se_next;
                free_entry( sf );
            } else
                se->se_next = NULL;
            return;
        }
        i++;
        se = sf;
    }
    return;
}

void strlst_freeall( stringlist *sl )
{
    stringentry *se, *sf;

    if ( sl == NULL ) return;
    if ( sl->sl_sig != _STRLST_SL_SIG ) return;
    for ( se = sl->sl_list ; se != NULL ; se = sf ) {
        sf = se->se_next;
        if ( se->se_sig == _STRLST_SE_SIG )
            free_entry( se );
    }
    kfree( sl );
}


char *strlst_getfirst( stringlist *sl, void **dummy, BYTE **data )
{
    stringentry *se;

    if ( sl == NULL ) return( NULL );
    se = sl->sl_list;
    if ( se == NULL ) return( NULL );
    if ( dummy ) *dummy = se->se_next;
    if (data) *data = se->se_data;
    return( se->se_string );
}

char *strlst_getnext( stringlist *sl, void **dummy, BYTE **data )
{
    stringentry *se;

    se = *dummy;
    if (se == NULL ) return( NULL );
    *dummy = se->se_next;
    if (data) *data = se->se_data;
    return( se->se_string );
}
char *strlst_findfirst( stringlist *sl, char *text, void **dummy, BYTE **data )
{
    stringentry *se;

    if ( sl == NULL ) return( NULL );
    se = sl->sl_list;
    while ( se != NULL ) {
        if ( !strcmp( se->se_string, text )) {
            if ( dummy ) *dummy = se->se_next;
            if (data) *data = se->se_data;
            return( se->se_string );
        }
        se = se->se_next;
    }
    return( NULL );
}

