Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Examples  

list.c

Go to the documentation of this file.
00001 /*! \file list.c
00002     This code implements linked lists.
00003  */
00004 
00005 
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include "list.h"
00009 
00010 /*! \brief Initialize the linked list. This function should be called first.
00011     \param liste Pointer to a linked list structure (that will be initialized).
00012     \param detruire Pointer to a function that will be called to free the memory used to store one link of the list. Please note that:
00013            <UL>
00014               <li>This function depends on the type of data stored into the linked list.
00015               <li><i>detruire</i> could be a NULL pointer (if user's data are not dtnamically allocated).
00016            </UL>
00017     \param corresp Pointer to a function that will be called to compare to elements. Please note that this function depends on the type
00018                    of data stored into the linked list. The function must returns 1 if the elements' datas are identical; 0 otherwise.
00019  */
00020 
00021 void list_init(List *liste, void (*detruire)(void *donnee), int (*corresp)(const void *val1, const void *val2))
00022 {
00023   liste->taille   = 0;
00024   liste->detruire = detruire;
00025   liste->corresp  = corresp;
00026   liste->tete     = NULL;
00027   liste->queue    = NULL;
00028 
00029   return;
00030 }
00031 
00032 /*! \example test_list.c
00033     This file shows how to use the function list_init().
00034  */
00035 
00036 /*! \brief Destroy the linked list. This function free all allocated memory used by the list.
00037     \param liste Pointer to a linked list structure (that you need to destroy).
00038  */
00039 
00040 void list_destroy(List *liste)
00041 {
00042   void  *donnee;
00043 
00044   while (list_size(liste) > 0)
00045   {
00046     if ((list_rem_next(liste, NULL, (void **)&donnee) == 0) && (liste->detruire !=  NULL))
00047     { liste->detruire(donnee); }
00048   }
00049 
00050   memset(liste, 0, sizeof(List));
00051 
00052   return;
00053 }
00054 
00055 /*! \example test_list.c
00056     This file shows how to use the function list_destroy().
00057  */
00058 
00059 /*! \brief Insert a new element into the linked list.
00060     \param liste Pointer to a linked list structure.
00061     \param element Pointer to an (existing) element of the linked list. The new element will be inserted <B>AFTER</B> the element pointed
00062                    by <i>element</i>.
00063     \param donnee Pointer to the data to insert. Please note that the data is <B>NOT</B> copied into the linked list.
00064     \return Upon successful completion the function return the value 0. Otherwise the function returns -1.
00065     \warning The inserted data is <B>NOT</B> copied into the linked list! Therefore you should not free it unless you know exactly what you
00066              are doing.
00067  */
00068 
00069 int list_ins_next(List *liste, ListElmt *element, const void *donnee)
00070 {
00071   ListElmt *nouv_element;
00072 
00073   /* --------------------------------------------------- */
00074   /* Allocate memory for the new element                 */
00075   /* --------------------------------------------------- */
00076 
00077   if ((nouv_element = (ListElmt *)malloc(sizeof(ListElmt))) == NULL) { return -1; }
00078 
00079   /* --------------------------------------------------- */
00080   /* Set new element's data                              */
00081   /* --------------------------------------------------- */
00082 
00083   nouv_element->donnee = (void *)donnee;
00084 
00085   if (element == NULL)
00086   {
00087     /* ------------------------------------------------- */
00088     /* Insert to the beginning of the list               */
00089     /*   - in this case there is no previous element.    */
00090     /*   - the new element becomes the head of the list  */
00091     /* ------------------------------------------------- */
00092 
00093      if (list_size(liste) == 0) { liste->queue = nouv_element; }
00094 
00095      nouv_element->suivant   = liste->tete;
00096 
00097      #ifdef DOUBLE_LINK
00098        nouv_element->precedent = NULL;
00099      #endif
00100 
00101      liste->tete = nouv_element;
00102   }
00103   else
00104   {
00105     /* ------------------------------------------------- */
00106     /* Somewhere into the list, but not the beginning    */
00107     /* ------------------------------------------------- */
00108 
00109      if (element->suivant == NULL) { liste->queue = nouv_element; }
00110 
00111      nouv_element->suivant = element->suivant;
00112 
00113      #ifdef DOUBLE_LINK
00114        nouv_element->precedent = element;
00115      #endif
00116 
00117      element->suivant = nouv_element;
00118   }
00119 
00120   /* --------------------------------------------------- */
00121   /* increment the number of elements of the list        */
00122   /* --------------------------------------------------- */
00123 
00124   liste->taille++;
00125 
00126   return 0;
00127 }
00128 
00129 /*! \example test_list.c
00130     This file shows how to use the function list_ins_next().
00131  */
00132 
00133 
00134 /*! \brief Remove an element from the linked list.
00135     \param liste Pointer to a linked list structure.
00136     \param element Pointer to an (existing) element of the linked list. The element to delete is the element <B>AFTER</B> the element
00137                    pointed by <i>element</i>. If you want to remove the first element of the list, then you must specify NULL as second
00138                    argument for the function list_rem_next().
00139     \param donnee Pointer that vill point to the data stored by the removed element.
00140     \return Upon successful completion the function return the value 0. Otherwise the function returns -1.
00141     \warning This function does <B>NOT</B> free the element's data (it only frees the element's structure). Therefore you should use
00142              <i>donnee</i> to free the element's data yourself.
00143  */
00144 
00145 int list_rem_next(List *liste, ListElmt *element, void **donnee)
00146 {
00147   ListElmt  *ancien_element;
00148 
00149   /* --------------------------------------------------- */
00150   /* Make sure that the list is not empty                */
00151   /* --------------------------------------------------- */
00152 
00153   if (list_size(liste) == 0) { return -1; }
00154 
00155   /* --------------------------------------------------- */
00156   /* Removing the element                                */
00157   /* --------------------------------------------------- */
00158 
00159   if (element == NULL)
00160   {
00161     /* ------------------------------------------------- */
00162     /* Removing at the beginning of the list             */
00163     /*   - The second element becomes the first (which   */
00164     /*     has no previous element now).                 */
00165     /* ------------------------------------------------- */
00166 
00167     *donnee = liste->tete->donnee;
00168     ancien_element = liste->tete;
00169     liste->tete = liste->tete->suivant;
00170 
00171     if (list_size(liste) == 1) { liste->queue = NULL; }
00172 
00173     #ifdef DOUBLE_LINK
00174       else { liste->tete->precedent = NULL; }
00175     #endif
00176   }
00177   else
00178   {
00179     /* ------------------------------------------------- */
00180     /* Somewhere into the list, but not the beginning    */
00181     /* (And not at the end of the list of course).       */
00182     /* ------------------------------------------------- */
00183 
00184     if (element->suivant == NULL) { return -1; }
00185 
00186     *donnee = element->suivant->donnee;
00187     ancien_element = element->suivant;
00188     element->suivant = element->suivant->suivant;
00189 
00190     if (element->suivant == NULL) { liste->queue = element; }
00191 
00192     #ifdef DOUBLE_LINK
00193       else { element->suivant->precedent = element; }
00194     #endif
00195   }
00196 
00197   /* --------------------------------------------------- */
00198   /* Free the allocated memory (for the element)         */
00199   /* --------------------------------------------------- */
00200 
00201   free(ancien_element);
00202 
00203   /* --------------------------------------------------- */
00204   /* Decrement the number of element of the list         */
00205   /* --------------------------------------------------- */
00206 
00207   liste->taille--;
00208 
00209   return 0;
00210 }
00211 
00212 /*! \example test_list.c
00213     This file shows how to use the function list_rem_next().
00214  */
00215 
00216 
00217 /*! \brief Search an element into the linked list.
00218     \param liste Pointer to the linked list structure.
00219     \param from Pointer to the linked list's element where the search begins. If 'point' in NULL, then the search begins at the beginning
00220                 of the linked list.
00221     \param data Pointer to a data a user defined structure that contains the data to search for.
00222     \param prec Pointer to a pointer that will receive the address of the element before the found element.
00223     \return <UL>
00224               <li>If the function finds an element that matches <i>data</i>, then it returns a pointer to this element. In this case,
00225                   <i>prec</i> points to the previous element (unless the found element was the first element in the linked list ... in this
00226                   the value of <i>prec</i> is NULL).
00227               <li>If there is no element that matches <i>data</i>, then the function returns NULL.
00228             </UL>
00229  */
00230 
00231 ListElmt* list_find (List *liste, ListElmt *from, void* data, ListElmt **prec)
00232 {
00233   *prec = NULL; 
00234 
00235   /* --------------------------------------------------- */
00236   /* If 'from' is NULL pointer, then start the search    */
00237   /* from the beginning of the linked list.              */
00238   /* --------------------------------------------------- */
00239 
00240   if (from == NULL) { from = list_head(liste); }
00241 
00242   /* --------------------------------------------------- */
00243   /* Compare each element with 'data'                    */
00244   /* --------------------------------------------------- */
00245 
00246   while (from != NULL)
00247   {
00248     if (liste->corresp(data, list_data(from))) { return from; }
00249     *prec = from;
00250     from = list_next(from);
00251   }
00252 
00253   return NULL;
00254 }
00255 
00256 /*! \example test_list.c
00257     This file shows how to use the function list_find().
00258  */
00259 
00260 

Generated on Thu Apr 3 16:23:43 2003 for Common_C_libraries by doxygen1.3-rc1