
/******************************************************************************
**
**  Copyright (C) 2001  - the shmoo group -
**
**  This program is free software; you can redistribute it and/or
**  modify it, however, you cannot sell it.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
**  You should have received a copy of the license attached to the
**  use of this software.  If not, visit www.shmoo.com/osiris for
**  details.
**
******************************************************************************/

/******************************************************************************
**
**    The Shmoo Group (TSG)
**
**    File:      string_list.c
**    Author:    Brian Wotring
**
**    Date:      June 22, 2001.
**    Project:   osiris
**
******************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>

#include "utilities.h"
#include "string_list.h"
#include "strcasestr.h"

/******************************************************************************
**
**    Function: string_list_new
**
**    Purpose:  create a new string list, default size.
**
******************************************************************************/

string_list * string_list_new()
{
    string_list *list = (string_list *)osi_malloc( sizeof( string_list ) );

    list->list     = (char **)osi_malloc( sizeof(char *) * INITIAL_LIST_SIZE );
    list->max_size = INITIAL_LIST_SIZE;
    list->size     = 0;

    return list;
}

/******************************************************************************
**
**    Function: string_list_destroy
**
**    Purpose:  free every string item in the list, free list itself.
**
******************************************************************************/

void string_list_destroy( string_list *list )
{
    unsigned int index;

    if( list == NULL )
    {
        return;
    }

    for( index = 0; index < list->size; index++ )
    {
        osi_free( (list->list)[index] );
    }

    osi_free( list->list );
    osi_free( list );
}


/******************************************************************************
**
**    Function: string_list_add_item
**
**    Purpose:  add another string item to the end of the
**              end of the list. if the list is full, double it.
**
******************************************************************************/

int string_list_add_item( string_list *list, const char *item )
{
    char *new_item = NULL;

    if( list == NULL )
    {
        return 0;
    }

    /* if item was given, create space and copy into entry. */

    if( item != NULL )
    {
        int length = strlen( item );

        new_item  = (char *)osi_malloc( length + 1 );
        osi_strlcpy( new_item, item, ( length + 1 ) );
	    new_item[length] = '\0';
    }

    list->list[list->size] = new_item;
    list->size++;

    if( list->size == list->max_size )
    {
        string_list_double_size( list );
    }

    return 1;
}

osi_bool string_list_remove_index( string_list *list, int index )
{
    int cursor;

    if( list == NULL )
    {
        return FALSE;
    }

    if( ( index < 0 ) || ( index >= (int)list->size ) )
    {
        return FALSE;
    }

    /* first, we clobber the data in the index we don't need. */

    osi_free( list->list[index] );

    /* now, we move everything after that index back one. */

    for( cursor = index; cursor < (int)list->size; cursor++ )
    {
        list->list[cursor] = list->list[cursor+1];
    } 

    /* now decrement the size by one. */

    list->size -= 1;
    return TRUE;
}


/******************************************************************************
**
**    Function: string_list_contains_item
**
**    Purpose:  check to see if an item already exists in the list.
**
******************************************************************************/

osi_bool string_list_contains_item( string_list *list, const char *item,
                                    osi_bool case_sensitive )
{
    unsigned int index;

    if( list == NULL || item == NULL )
    {
        return FALSE;
    }

    for( index = 0; index < list->size; index++ )
    {
        if( case_sensitive )
        {
            if( strcmp( (list->list)[index], item ) == 0 )
            {
                return TRUE;
            }
        }

        else
        {
            char *found = strcasestr( (list->list)[index], item );

            if( ( found > 0 ) && ( strlen( found ) == strlen( item ) ) )
            {
                return TRUE;
            }
        }
    }

    return FALSE;
}

/******************************************************************************
**
**    Function: string_list_double_size
**
**    Purpose:  create new list twice the size, move data into it.
**
******************************************************************************/

void string_list_double_size( string_list *list )
{
    unsigned int index;
    char **new_list;

    if( list == NULL )
    {
        return;
    }

    list->max_size = ( list->max_size * 2 );
    new_list = (char **)osi_malloc( sizeof(char *) * list->max_size );

    /* copy over the new data. */

    for( index = 0; index < list->size; index++ )
    {
        new_list[index] = list->list[index];
    }

    /* free the old list's entry list. */

    osi_free( list->list );
    list->list = new_list;
}

/******************************************************************************
**
**    Function: string_list_dump
**
**    Purpose:  for debugging, print contents of entire list to stdout.
**
******************************************************************************/

void string_list_dump( string_list *list )
{
    unsigned int index;

    fprintf( stderr, "--- list dump ---\n\n" );

    if( list != NULL )
    {
        for( index = 0; index < list->size; index++ )
        {
            fprintf( stderr, "%s\n", list->list[index] );
        }
    }
}
