Logo Search packages:      
Sourcecode: rapple version File versions  Download package

list.c

Go to the documentation of this file.
/*
   Name: $RCSfile: list.c,v $
   Author: Alan Moran
   $Date: 2005/08/07 19:52:55 $
   $Revision: 1.11 $
   $Id: list.c,v 1.11 2005/08/07 19:52:55 nloyola Exp $

   Legal Notice:

   This program is free software; you can redistribute it and/or
   modify it under the terms of the license contained in the
   COPYING file that comes with this distribution.

 */

/**
   @file

   @brief Implementation to support linked lists.

   The list module is a simple linked list implementation.  This low level
   module is employed by other modules with a need to record lists of items
   (e.g., typically parsers etc.)

*/

#include "globals.h"

/**
   Initializes a linked list.
*/
00032 void rpl_list_init (rpl_list * list_p)
{
    assert(list_p != NULL);
    list_p->first = list_p->last = NULL;
    list_p->count = 0;
}


/**
   Inserts the new node at the head of the list.

   @param list_p Points to the list.
   @param node_p Points to the new node.
   @param data_ptr Points to the struct being added.

   @return Returns pointer to the new head of the list.
 */
00049 rpl_list_node * rpl_list_prepend(rpl_list *      list_p,
                                 rpl_list_node * node_p,
                                 void *          data_ptr)
{
    assert(list_p != NULL);
    assert(node_p != NULL);
    assert(data_ptr != NULL);

    node_p->data_ptr = data_ptr;
    node_p->prev = NULL;
    if (list_p->count == 0)
    {
        list_p->last = node_p;
    }
    else
    {
        node_p->next = list_p->first;
        list_p->first->prev = node_p;
    }
    list_p->first = node_p;
    list_p->count++;
    return list_p->first;
}

/**
   Inserts the new node at the end of the list.

   @param list_p Points to the list.
   @param node_p Points to the new node.
   @param data_ptr Points to the struct being added.

   @return Returns pointer to the new tail of the list.
 */
00082 rpl_list_node * rpl_list_append(rpl_list *      list_p,
                                rpl_list_node * node_p,
                                void *          data_ptr)
{
    assert(list_p != NULL);
    assert(node_p != NULL);
    assert(data_ptr != NULL);

    node_p->data_ptr = data_ptr;
    node_p->next = NULL;
    if (list_p->count == 0)
    {
        list_p->first = node_p;
    }
    else
    {
        node_p->prev = list_p->last;
        list_p->last->next = node_p;
    }
    list_p->last = node_p;
    list_p->count++;
    return list_p->last;
}

/**
   Inserts a new node into before or after a selected node in a list.
*/
00109 void rpl_list_insert (rpl_list *          list_p,
                      rpl_list_node *     node_p,
                      RPL_LIST_INSERT_POS position,
                      rpl_list_node *     new_node_p,
                      void *              data_ptr)
{
    assert(list_p != NULL);
    assert(node_p != NULL);
    assert(new_node_p != NULL);
    assert(data_ptr != NULL);

    list_p->count++;
    new_node_p->data_ptr = data_ptr;

    switch (position)
    {
        case RPL_LIST_INSERT_BEFORE:
            /* Fix up the newNode prev and next ptrs */
            new_node_p->prev = node_p->prev;
            new_node_p->next = node_p;

            /*Ensure that node pointing to node_p now points to the new_node_p */
            if (node_p->prev != NULL)
            {
                node_p->prev->next = new_node_p;
            }

            /* check if being inserted at head of list */
            if (list_p->first == node_p)
            {
                list_p->first = new_node_p;
            }

            /* Ensure that the node_p prev pointer points to new node */
            node_p->prev = new_node_p;
            break;

        case RPL_LIST_INSERT_AFTER:
            /* Fix up newNode prev and next */
            new_node_p->prev = node_p;
            new_node_p->next = node_p->next;

            if (node_p->next != NULL)
            {
                node_p->next->prev = new_node_p;
            }

            /* check if being inserted at the tail of the list */
            if ( list_p->last == node_p )
            {
                list_p->last = new_node_p;
            }

            /* Ensure that the node_p next pointer points to new node */
            node_p->next = new_node_p;
            break;

        default:
            /* invalid position parameter */
            assert (0);
    }
}

/**
   Returns the data pointer to the first item in the list.
*/
00175 void * rpl_list_first (rpl_list * list_p)
{
    assert(list_p != NULL);
    if (list_p->first == NULL) return NULL;
    return list_p->first->data_ptr;
}

/**
   Returns the data pointer to the last item in the list.
*/
00185 void * rpl_list_last (rpl_list * list_p)
{
    assert(list_p != NULL);
    if (list_p->last == NULL) return NULL;
    return list_p->last->data_ptr;
}

/**
   Returns the next item in the list that contains node_p.
*/
00195 void * rpl_list_next (rpl_list_node * node_p)
{
    assert(node_p != NULL);
    if (node_p->next == NULL) return NULL;
    return node_p->next->data_ptr;
}

/**
   Returns the previous item in the list that contains node_p.
*/
00205 void * rpl_list_prev (rpl_list_node * node_p)
{
    assert(node_p != NULL);
    if (node_p->prev == NULL) return NULL;
    return node_p->prev->data_ptr;
}

/**
   Returns the number of nodes in the list.

   @param list_p Points to the list.

   @return the number of nodes in list.
 */
00219 unsigned rpl_list_count(rpl_list * list_p)
{
    assert(list_p != NULL);
    return list_p->count;
}

/**
   Removes a node from the list.

   @note This function does not deallocate memory. It is left up to the caller.

   @param list_p Points to the list.
   @param node_p Points to the new node.
 */
00233 void rpl_list_remove(rpl_list * list_p, rpl_list_node * node_p)
{
    assert(list_p != NULL);
    assert(node_p != NULL);

    if (node_p->prev != NULL)
    {
        node_p->prev->next = node_p->next;
    }
    else
    {
        list_p->first = node_p->next;
    }

    if (node_p->next != NULL)
    {
        node_p->next->prev = node_p->prev;
    }
    else
    {
        list_p->last = node_p->prev;
    }

    list_p->count--;
}



Generated by  Doxygen 1.6.0   Back to index