Institut de Robòtica i Informàtica Industrial
KRD Group

The CuikSuite Project

list.c

Go to the documentation of this file.
00001 #include "list.h"
00002 
00003 #include "error.h"
00004 #include "defines.h"
00005 
00006 #include <stdlib.h>
00007 #include <string.h>
00008 
00026 void PrivDelEle(Tbuf *node,Tlist *list);
00027 
00028 
00040 void PrivAddElement(void *Info,Tbuf *pos,boolean in_front,Tlist *list);
00041 
00042 
00043 /*Delete the element pointed by node from the list 'list'*/
00044 void PrivDelEle(Tbuf *node, /*pointer to the element to be removed from the list*/
00045                 Tlist *list /*list*/
00046                 )
00047 {
00048   if (node->previous!=(Tbuf *)NULL)
00049     node->previous->next=node->next;
00050 
00051   if (node->next!=(Tbuf *)NULL)
00052    node->next->previous=node->previous;
00053       
00054   if (node==list->first)
00055     list->first=node->next;
00056   if (node==list->last)
00057     list->last=node->previous;
00058         
00059   list->num_ele--;
00060 
00061   free(node->data);
00062   free(node);
00063 }
00064 
00065 /*
00066  * Adds a new element (pointed by Info) in the position of the list pointed by pos.
00067  * If in_front is TRUE then the new element is inserted in front of that pointed by
00068  * pos and if not behind.
00069  * If the list is empty, the parameter pos is not used.
00070  */
00071 void PrivAddElement(void *Info,       /*pointer to the data to de added to the list*/
00072                     Tbuf *pos,        /*pointer to the position of the list where the new data is added*/
00073                     boolean in_front, /*TRUE if info is added in front of the node*/
00074                     Tlist *list       /*list to be extended*/
00075                     )
00076 {
00077   Tbuf *node;
00078 
00079   NEW(node,1,Tbuf);
00080 
00081   NEW(node->data,list->ele_size,char);
00082   
00083   memcpy(node->data,Info,list->ele_size);
00084 
00085   if (list->num_ele==0) /*pos must be NULL*/
00086     {
00087       node->previous=NULL;
00088       node->next=NULL;
00089 
00090       list->first=node;
00091       list->last=node;
00092     }
00093   else
00094     {
00095       if (in_front)
00096         {
00097           node->next=pos;
00098           node->previous=pos->previous;
00099 
00100           if (node->previous!=NULL)
00101             node->previous->next=node;
00102           pos->previous=node;
00103         }
00104       else
00105         {
00106           node->next=pos->next;
00107           node->previous=pos;
00108 
00109           if (node->next!=NULL)
00110             node->next->previous=node;
00111           pos->next=node;
00112         }
00113       
00114       if ((list->first==pos)&&(in_front))
00115         list->first=node;
00116       
00117       if ((list->last==pos)&&(!in_front))
00118         list->last=node;
00119     }
00120 
00121   list->num_ele++;
00122 }
00123 
00124 /**************************************************************************
00125  **************************************************************************/
00126 
00127 /*PUBLIC FUNCTIONS*/
00128 
00129 /*
00130  * Init a list with elements of size ele_size.
00131  * This size can be obtained usint sizeof(type)
00132  * where type is the type of elements to be stored
00133  * in the list.
00134  */
00135 void InitList(unsigned int ele_size, /*size of the elements of the list*/
00136               Tlist *list            /*list to be initialized*/
00137               )
00138 {
00139 
00140   list->num_ele=0;
00141   list->ele_size=ele_size;
00142   list->first=(Tbuf *)NULL;
00143   list->last=(Tbuf *)NULL;
00144 }
00145 
00146 /*
00147  * Deletes a list. 
00148  * No operation is done on each list element.
00149  * The user is in charge of deleting each element of the list using
00150  * the apropritate delete function (iterating on the list, getting and
00151  * deleting each element and the removing it from the list)
00152  */
00153 void DeleteList(Tlist *list /*list to be deleted*/
00154                 )
00155 {  
00156   DeleteAllItems(list); 
00157 }
00158 
00159 /*
00160  * Deletes all the items of a list list. 
00161  */
00162 void DeleteAllItems(Tlist *list /*list to be deleted*/
00163                 )
00164 {
00165   Tbuf *e,*next;
00166 
00167   e=list->first;
00168   while(e!=NULL)
00169     {
00170       next=e->next;
00171       PrivDelEle(e,list);
00172       e=next;
00173     }
00174 }
00175 
00176 
00177 /*
00178  * Returns the number of elements of the list
00179  */
00180 unsigned int ListSize(Tlist *list)
00181 {
00182   return(list->num_ele);
00183 }
00184 
00185 /*
00186  * Returns true if the list is empty
00187 */
00188 boolean ListEmpty(Tlist *list)
00189 {
00190   return(list->num_ele==0);
00191 }
00192 
00193 /*
00194  * Adds a new element at the head of the list
00195  */
00196 void AddFirstElement(void *Info, /*pointer to the data to de added to the list*/
00197                      Tlist *list /*list to be extended*/
00198                      )
00199 {
00200   PrivAddElement(Info,list->first,TRUE,list);
00201 }
00202 
00203 /*
00204  * Adds a new element at the end of the list
00205  */
00206 void AddLastElement(void *Info,
00207                     Tlist *list)
00208 {
00209   PrivAddElement(Info,list->last,FALSE,list);
00210 }
00211 
00212 void ExtractFirst(void *Info,Tlist *list)
00213 {
00214   if (list->first!=NULL)
00215     {
00216       Tbuf *e;
00217 
00218       memcpy(Info,list->first->data,list->ele_size);
00219 
00220       e=list->first->next;
00221       PrivDelEle(list->first,list);
00222       list->first=e;
00223     }
00224   else
00225     Error("Empty list");
00226 }
00227 
00228 void ExtractLast(void *Info,Tlist *list)
00229 {
00230   if (list->last!=NULL)
00231     {
00232       Tbuf *e;
00233 
00234       memcpy(Info,list->last->data,list->ele_size);
00235 
00236       e=list->last->next;
00237       PrivDelEle(list->last,list);
00238       list->last=e;
00239     }
00240   else
00241     Error("Empty list");
00242 }
00243 
00244 boolean HasElement(void *Info,boolean (* cmp)(void *,void*),Tlist *list)
00245 {
00246   Tbuf *current;
00247   boolean found;
00248 
00249   current=list->first;
00250 
00251   found=FALSE;
00252   while((!found)&&(current!=NULL))
00253     {
00254       found=cmp(Info,current->data);
00255       if (!found)
00256         current=current->next;
00257     }
00258   return(found);
00259 }
00260 
00261 void PrintList(Tlist *l)
00262 {
00263   Tbuf *current;
00264   printf("L:[");
00265   
00266   current=l->first;
00267 
00268   while(current!=NULL)
00269     {
00270       printf("%p (%p)  ",current,current->data);
00271       current=current->next;
00272     }
00273 
00274   printf(" ]\n");
00275 }
00276 
00277 /**************************************************************************/
00278 
00279 /*Iterators functions*/
00280 
00281 /*
00282  * Starts a new itarator for a given list
00283  */
00284 void InitIterator(Titerator *i,Tlist *list)
00285 {
00286   i->current=NULL;
00287   i->list=list;  
00288 }
00289 
00290 void CopyIterator(Titerator *dst,Titerator *src)
00291 {
00292   dst->current=src->current;
00293   dst->list=src->list;
00294 }
00295 
00296 /*
00297  * Returns a pointer to the data stored at the position of the list pointed by 'i->current'
00298  */
00299 void *GetCurrent(Titerator *i)
00300 {
00301   return(i->current->data);
00302 }
00303 
00304 /*
00305  * Makes a copy of the element pointed by the iterator
00306  * and deletes the element from the list
00307  */
00308 void ExtractCurrent(void *Info,Titerator *i)
00309 {
00310   if (i->current!=NULL)
00311     {
00312       Tbuf *e;
00313 
00314       memcpy(Info,i->current->data,i->list->ele_size);
00315 
00316       e=i->current->next;
00317       PrivDelEle(i->current,i->list);
00318       i->current=e;
00319     }
00320 }
00321 
00322 /*
00323  * Adds a new item in front of the element pointed by i->current
00324  */
00325 void AddInFrontOfCurrent(void *Info,Titerator *i)
00326 {
00327   PrivAddElement(Info,i->current,TRUE,i->list);
00328 }
00329 
00330 /*
00331  * Adds a new item behind the element pointed by i->current
00332  */
00333 void AddBehindCurrent(void *Info,Titerator *i)
00334 {
00335   PrivAddElement(Info,i->current,FALSE,i->list);
00336 }
00337 
00338 /*
00339  * Removes the element pointed by i->current from the list
00340  */
00341 void DeleteCurrent(Titerator *i)
00342 {
00343   if (i->current!=NULL)
00344     {
00345       Tbuf *e;
00346 
00347       e=i->current->next;
00348       PrivDelEle(i->current,i->list);
00349       i->current=e;
00350     }
00351 }
00352 
00353 /*
00354  * Moves the iterator to the behning of the list
00355  */
00356 void First(Titerator *i)
00357 {
00358   i->current=i->list->first;
00359 }
00360 
00361 /*
00362  * Moves the iterator to the end of the list
00363  */
00364 void Last(Titerator *i)
00365 {
00366   i->current=i->list->last;
00367 }
00368 
00369 /*
00370  * Moves the iterator forward on the list
00371  * Returns FALSE if the movement can not be performed
00372  */
00373 boolean Advance(Titerator *i)
00374 {
00375   boolean b;
00376 
00377   if (i->current!=NULL)
00378     {
00379       i->current=i->current->next;
00380       if (i->current!=NULL)
00381         b=TRUE;
00382       else
00383         b=FALSE;
00384     }
00385   else
00386     b=FALSE;
00387 
00388   return(b);
00389 }
00390 
00391 /*
00392  * Moves the iterator backwards on the list
00393  * Returns FALSE if the movement can not be performed
00394  */
00395 boolean Bacward(Titerator *i)
00396 {
00397   boolean b;
00398 
00399   if (i->current!=NULL)
00400     {
00401       i->current=i->current->previous;
00402       if (i->current!=NULL)
00403         b=TRUE;
00404       else
00405         b=FALSE;
00406     }
00407   else
00408     b=FALSE;
00409 
00410   return(b);
00411 }
00412 
00413 /*
00414  * Moves the iterator to the position 'n' of the list
00415  * Returns FALSE if the movement can not be performed
00416  */
00417 boolean MoveTo(unsigned int n,Titerator *i)
00418 {
00419   unsigned int j;
00420   boolean b;
00421 
00422   if (n>=i->list->num_ele)
00423     {
00424       i->current=NULL;
00425       b=FALSE;
00426     }
00427   else
00428     {
00429       i->current=i->list->first;
00430       j=0;
00431       while(j<n)
00432         {
00433           i->current=i->current->next;
00434           j++;
00435         }
00436       b=TRUE;
00437     }
00438 
00439   return(b);
00440 }
00441 
00442 /*
00443  * Returns TRUE if the iterator points to a non valid element
00444  */
00445 boolean EndOfList(Titerator *i)
00446 {
00447   return(i->current==NULL);
00448 }