list.h

Go to the documentation of this file.
00001 /* TinyaML
00002  * Copyright (C) 2007 Damien Leroux
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017  */
00018 
00019 #ifndef _BML_LIST_H_
00020 #define _BML_LIST_H_
00021 
00022 #include "vm_assert.h"
00023 
00034 typedef struct _slist_node_t* slist_node_t;
00035 typedef struct _slist_t* slist_t;
00036 
00037 struct _slist_node_t {
00038         slist_node_t next;
00039         word_t value;
00040 };
00041 
00042 struct _slist_t {
00043         slist_node_t head;
00044         slist_node_t tail;
00045 };
00046 
00048 #define _snode_local_new(_n) slist_node_t _n = malloc(sizeof(struct _slist_node_t))
00049 
00050 #define snode_del free
00051 
00057 typedef struct _dlist_node_t* dlist_node_t;
00058 typedef struct _dlist_t* dlist_t;
00059 
00060 struct _dlist_node_t {
00061         dlist_node_t prev;
00062         dlist_node_t next;
00063         word_t value;
00064 };
00065 
00066 struct _dlist_t {
00067         dlist_node_t head;
00068         dlist_node_t tail;
00069 };
00070 
00072 #define _dnode_local_new(_n) dlist_node_t _n = malloc(sizeof(struct _dlist_node_t))
00073 
00074 #define dnode_del free
00075 
00080 /*
00081  * Adding values
00082  */
00083 
00088 #define dlist_insert_head_node(_l,_n)   do {\
00089                 _n->next=(_l)->head;\
00090                 _n->prev=NULL;\
00091                 if((_l)->tail==NULL) {\
00092                         (_l)->tail=_n;\
00093                 } else {\
00094                         (_l)->head->prev=_n;\
00095                 }\
00096                 (_l)->head=_n;\
00097         } while(0)
00098 
00099 #define dlist_insert_head(_l,_v)        do {\
00100                 _dnode_local_new(n);\
00101                 n->value=(word_t)(_v);\
00102                 dlist_insert_head_node(_l,n);\
00103         } while(0)
00104 
00105 #define dlist_insert_tail_node(_l,_n)   do {\
00106                 (_n)->next=NULL;\
00107                 (_n)->prev=(_l)->tail;\
00108                 if((_l)->head==NULL) {\
00109                         (_l)->head=(_n);\
00110                 } else {\
00111                         (_l)->tail->next=(_n);\
00112                 }\
00113                 (_l)->tail=(_n);\
00114         } while(0)
00115 
00116 #define dlist_insert_tail(_l,_v)        do {\
00117                 _dnode_local_new(n);\
00118                 n->value=(word_t)(_v);\
00119                 dlist_insert_tail_node(_l,n);\
00120         } while(0)
00121 
00122 #define dlist_remove_head(_l)   do {\
00123                 dlist_node_t n=(_l)->head;\
00124                 if((_l)->tail==(_l)->head) {\
00125                         (_l)->head=NULL;\
00126                         (_l)->tail=NULL;\
00127                 } else {\
00128                         (_l)->head = n->next;\
00129                         (_l)->head->prev = NULL;\
00130                 }\
00131                 snode_del(n);\
00132         } while(0)
00133 
00134 #define dlist_remove_head_no_free(_l)   do {\
00135                 dlist_node_t n=(_l)->head;\
00136                 if((_l)->tail==(_l)->head) {\
00137                         (_l)->head=NULL;\
00138                         (_l)->tail=NULL;\
00139                 } else {\
00140                         (_l)->head = n->next;\
00141                         (_l)->head->prev = NULL;\
00142                 }\
00143         } while(0)
00144 
00145 #define dlist_remove_tail(_l)   do {\
00146                 dlist_node_t n=(_l)->tail;\
00147                 if((_l)->tail==(_l)->head) {\
00148                         (_l)->head=NULL;\
00149                         (_l)->tail=NULL;\
00150                 } else {\
00151                         (_l)->tail = n->prev;\
00152                         (_l)->tail->next = NULL;\
00153                 }\
00154                 dnode_del(n);\
00155         } while(0)
00156 
00157 #define dlist_remove_tail_no_free(_l)   do {\
00158                 dlist_node_t n=(_l)->tail;\
00159                 if((_l)->tail==(_l)->head) {\
00160                         (_l)->head=NULL;\
00161                         (_l)->tail=NULL;\
00162                 } else {\
00163                         (_l)->tail = n->prev;\
00164                         (_l)->tail->next = NULL;\
00165                 }\
00166         } while(0)
00167 
00168 #define dlist_remove(_l,_n)     do {\
00169                 if((_n)==(_l)->head) {\
00170                         dlist_remove_head(_l);\
00171                 } else if((_n)==(_l)->tail) {\
00172                         dlist_remove_tail(_l);\
00173                 } else {\
00174                         (_n)->next->prev=(_n)->prev;\
00175                         (_n)->prev->next=(_n)->next;\
00176                         dnode_del(_n);\
00177                 }\
00178         } while(0)
00179 
00180 #define dlist_remove_no_free(_l,_n)     do {\
00181                 if((_n)==(_l)->head) {\
00182                         dlist_remove_head_no_free(_l);\
00183                 } else if((_n)==(_l)->tail) {\
00184                         dlist_remove_tail_no_free(_l);\
00185                 } else {\
00186                         (_n)->next->prev=(_n)->prev;\
00187                         (_n)->prev->next=(_n)->next;\
00188                 }\
00189         } while(0)
00190 
00196 #define slist_insert_head(_l,_v)        do {\
00197                 _snode_local_new(n);\
00198                 n->value=(word_t)(_v);\
00199                 n->next=(_l)->head;\
00200                 if((_l)->tail==NULL) {\
00201                         (_l)->tail=n;\
00202                 }\
00203                 (_l)->head=n;\
00204         } while(0)
00205 
00206 #define slist_insert_tail(_l,_v)        do {\
00207                 _snode_local_new(n);\
00208                 n->value=(word_t)(_v);\
00209                 n->next=NULL;\
00210                 if((_l)->tail!=NULL) {\
00211                         (_l)->tail->next=n;\
00212                 } else {\
00213                         (_l)->head=n;\
00214                 }\
00215                 (_l)->tail=n;\
00216         } while(0)
00217 
00218 #define slist_remove_head(_l)   do {\
00219                 slist_node_t n=(_l)->head;\
00220                 (_l)->head = (_l)->head->next;\
00221                 snode_del(n);\
00222         } while(0)
00223 
00225 /*
00226  * Iterating over a list
00227  */
00228 
00229 #define list_head(_l) ((_l)->head)
00230 #define list_tail(_l) ((_l)->tail)
00231 
00232 #define node_next(_n) ((_n)->next)
00233 /* No need to check type here.
00234  * The compiler will whine explicitly if prev isn't defined. */
00235 #define node_prev(_n) ((_n)->prev)
00236 
00237 /*
00238  * Accessing a node's value
00239  */
00240 
00241 #define node_value(_t,_n) ((_t)((_n)->value))
00242 
00243 /*
00244  * Verifying conditions
00245  */
00246 
00247 #define list_is_empty(_l)       ((_l)->head==NULL)
00248 #define list_not_empty(_l)      ((_l)->head!=NULL)
00249 #define node_has_next(_n)       ((_n)->next!=NULL)
00250 #define node_has_prev(_n)       ((_n)->prev!=NULL)
00251 
00252 
00253 /*
00254  * Typical algorithms
00255  */
00256 
00260 #define slist_forward(_l,_t,_f) do {\
00261                 slist_node_t n=list_head(_l);\
00262                 while(n!=NULL) {\
00263                         _f(node_value(_t,n));\
00264                         n=n->next;\
00265                 }\
00266         } while(0)
00267 
00268 #define slist_flush(_l) do {\
00269                 slist_node_t q,n=list_head(_l);\
00270                 while(n!=NULL) {\
00271                         q=n->next;\
00272                         free(n);\
00273                         n=q;\
00274                 }\
00275         } while(0)
00276 /*
00277  * Creating and destroying Lists
00278  */
00279 
00280 inline void slist_init(slist_t);
00281 slist_t slist_new();
00282 void slist_del(slist_t);
00289 #define dlist_forward(_l,_t,_f) do {\
00290                 dlist_node_t n=list_head(_l);\
00291                 while(n!=NULL) {\
00292                         _f(node_value(_t,n));\
00293                         n=n->next;\
00294                 }\
00295         } while(0)
00296 
00297 #define dlist_reverse(_l,_t,_f) do {\
00298                 dlist_node_t n=list_tail(_l);\
00299                 while(n!=NULL) {\
00300                         _f(node_value(_t,n));\
00301                         n=n->prev;\
00302                 }\
00303         } while(0)
00304 
00305 #define slist_insert_sorted(_l,_n,_cmp) do {\
00306                 slist_node_t r=(_l)->head;\
00307                 if(r==NULL) {\
00308                         dlist_insert_head(_l,_n);\
00309                 } else if(_cmp((_l)->tail,_n)<=0) {\
00310                         dlist_insert_tail(_l,_n);\
00311                 } else {\
00312                         while(_cmp(_n,r)<0) {\
00313                                 r=r->next;\
00314                         }\
00315                         (_n)->next=r->next;\
00316                         if(r->next==NULL) {\
00317                                 (_l)->tail=(_n);\
00318                         }\
00319                         r->next=(_n);\
00320                 }\
00321         } while(0)
00322 
00323 #define dlist_flush(_l) do {\
00324                 dlist_node_t q,n=list_head(_l);\
00325                 while(n!=NULL) {\
00326                         q=n->next;\
00327                         free(n);\
00328                         n=q;\
00329                 }\
00330         } while(0)
00331 
00332 #define debug(_n) vm_printf("[%p]<- %p -> [%p]\n",(_n)->sched_data.prev,(_n),(_n)->sched_data.next)
00333 #define dlist_insert_sorted(_l,_n,_cmp) do {\
00334                 dlist_node_t r=(_l)->head;\
00335                 if(r==NULL||_cmp(_n,r)<=0) {\
00336                         dlist_insert_head_node(_l,(_n));\
00337                 } else if(_cmp((_l)->tail,(_n))<=0) {\
00338                         dlist_insert_tail_node(_l,(_n));\
00339                 } else {\
00340                         while(r&&_cmp((_n),r)<0) {\
00341                                 r=r->next;\
00342                         }\
00343                         if(!r) {\
00344                                 vm_printf("PROUUUUUUUT\n");\
00345                                 dlist_forward(_l,thread_t,debug);\
00346                         }\
00347                         (_n)->next=r->next;\
00348                         (_n)->prev=r;\
00349                         if(r->next==NULL) {\
00350                                 (_l)->tail=(_n);\
00351                         } else {\
00352                                 r->next->prev=(_n);\
00353                         }\
00354                         r->next=(_n);\
00355                 }\
00356         } while(0)
00357 
00358 /*
00359  * Creating and destroying Lists
00360  */
00361 
00362 inline void dlist_init(dlist_t); 
00363 dlist_t dlist_new();
00364 void dlist_del(dlist_t);
00365 
00370 
00371 #endif
00372 

Generated on Wed Feb 6 14:46:04 2008 for TinyaML by  doxygen 1.5.3