list.h

Go to the documentation of this file.
00001 
00006 #ifndef __LIST
00007 #define __LIST
00008 
00021 
00022 #define ALLOCATE(type)  ( (type *) malloc(sizeof(type)) )
00023 
00025 #define DEF_ALLOC(type, name)   \
00026         type *name;     \
00027         ( name = (type *) malloc(sizeof(type)) );
00028 
00029 
00052 #define LIST_DATA(type)         struct { struct type *next,*previous; }
00053 
00054 // Macros de uso interno
00055 #define LIST_NEXT(list,node)            ((node->list).next)
00056 #define LIST_PREVIOUS(list,node)        ((node->list).previous)
00057 
00058 #define HEADER_NEXT(header)             ((header).next)
00059 #define HEADER_PREVIOUS(header)         ((header).previous)
00060 
00061 
00067 #define LIST_NEW(type)          \
00068         struct {                                \
00069                 type *next;                     \
00070                 type *previous;         \
00071         }
00072 
00073 #define LIST_INITIALIZER        {NULL,NULL}
00074 
00075 #define LIST_INIT(header)                       \
00076         HEADER_NEXT(header)=NULL;               \
00077         HEADER_PREVIOUS(header)=NULL;
00078 
00079 
00083 #define LIST_FIRST(header)              \
00084         HEADER_NEXT(header)
00085 
00088 #define LIST_TAIL(header)               \
00089         HEADER_PREVIOUS(header)
00090 
00091 
00092 
00097 #define LIST_EMPTY(header)              \
00098         ((HEADER_NEXT(header) && HEADER_PREVIOUS(header)) ? 0 : 1)
00099 
00100 
00108 #define LIST_ADD(header,list,node)                                                      \
00109         LIST_NEXT(list,node)=HEADER_NEXT(header);                                       \
00110         if ( HEADER_NEXT(header) != NULL)                                               \
00111                 LIST_PREVIOUS( list, LIST_NEXT(list,node) )= node;              \
00112         else                                                                    \
00113                 HEADER_PREVIOUS(header)=node;                                   \
00114         LIST_PREVIOUS(list,node)=NULL;                                          \
00115         HEADER_NEXT(header)=node;
00116 
00117 
00118 
00124 #define LIST_ADD_TAIL(header,list,node)                         \
00125         if ( HEADER_PREVIOUS(header) != NULL )                  \
00126                 LIST_NEXT( list, HEADER_PREVIOUS(header) ) = node;      \
00127         else                                                    \
00128                 HEADER_NEXT(header) = node;                     \
00129         LIST_NEXT(list,node) = NULL;                                    \
00130         LIST_PREVIOUS(list,node) = HEADER_PREVIOUS(header);             \
00131         HEADER_PREVIOUS(header) = node;
00132 
00133 
00138 #define LIST_DEL(header,list,node)                                              \
00139         if ( LIST_PREVIOUS(list,node) != NULL )                                 \
00140                 LIST_NEXT( list, LIST_PREVIOUS(list,node) ) = LIST_NEXT(list,node);     \
00141         else                                                            \
00142                 HEADER_NEXT(header) = LIST_NEXT(list,node);                     \
00143         if ( LIST_NEXT(list,node) != NULL )                                     \
00144                 LIST_PREVIOUS( list, LIST_NEXT(list,node) ) = LIST_PREVIOUS(list,node); \
00145         else                                                            \
00146                 HEADER_PREVIOUS(header) = LIST_PREVIOUS(list,node);
00147         
00148 
00159 #define LIST_FOREACH(var,header,list)                                                   \
00160         for(var=HEADER_NEXT(header); var!=NULL; var=LIST_NEXT(list,var))
00161 
00162 
00163 
00164 /* \brief Simil LIST_FOREACH, pero se pueden remover los nodos que se recorren
00165  * su utilizacion es un poco compleja (deben agregarse dos líneas de código para su correcto uso)
00166  *
00167  *   _LIST_FOREACH(child, actual->childs, brothers) {
00168  *      aux = LIST_NEXT(brothers, child);                                                       // Agregado 1
00169  *      if (child->estado == TASK_ZOMBIE)
00170  *              pid = sys_waitpid(child->pid,&value,WNOHANG);
00171  *      child = aux;                                                                                            // Agregado 2
00172  *       }
00173  * \todo Implementarlo más limpiamente
00174  */
00175 #define _LIST_FOREACH(var,header,list)                                                  \
00176         for(var=HEADER_NEXT(header); var!=NULL; )
00177 
00178 /* \brief Permite insertar un nodo antes de otro nodo determinado
00179  * es importante que nodebefore sea un nodo válido, esto implica que
00180  * no se permite que nodebefore sea NULL por ejemplo.
00181  */
00182 #define LIST_INSERT_BEFORE(header,list,nodebefore,node)                         \
00183         LIST_PREVIOUS(list,node)=LIST_PREVIOUS(list,nodebefore);                \
00184         LIST_NEXT(list,node)=nodebefore;                                                                                                                \
00185         if ( HEADER_NEXT(header)==nodebefore )                                                                                  \
00186                 HEADER_NEXT(header)=node;                                                                                                                                       \
00187         else                                                                                                                                                                                                                            \
00188                 LIST_NEXT(list,LIST_PREVIOUS(list,nodebefore))=node;                    \
00189         LIST_PREVIOUS(list,nodebefore)=node;
00190 
00191         
00192 
00193 
00202 #define LIST_FOREACH_REVERSE(var,header,list)                                           \
00203         for(var=HEADER_PREVIOUS(header); var!=NULL; var=LIST_PREVIOUS(list,var))
00204 
00205 
00206 /* Permite buscar un nodo de la lista por un valor de
00207  * un atributo particular.
00208  * Recibe como argumentos la lista, la variable donde
00209  * devuelve un puntero al nodo encontrado o NULL en caso
00210  * de busqueda sin resultados, el siguiente argumento es
00211  * el nombre de la variable a buscar (definida en la 
00212  * estructura y por ultimo el valor buscado.
00213  * ej:
00214  *              task_struct_t *nodobuscado;
00215  *              LIST_FIND(runqueue,nodobuscado,priority,3)
00216  */
00217 #define LIST_FIND(header,list,var,name,value)                                                   \
00218         for(var=HEADER_NEXT(header); var!=NULL && var->name!=value; var=LIST_NEXT(list,var))
00219 
00220 
00227 #define LIST_ATTACH(dest, src, type)                                    \
00228 {       type *aux;                                                                                      \
00229         _LIST_FOREACH(ptr, src) {                       \
00230                 aux = LIST_NEXT(src,ptr);                                                       \
00231                 LIST_ADD_TAIL(dest,dest, ptr);  \
00232                 ptr = aux;                                                                              \
00233         }                                                                                                       \
00234 }
00235 
00239 #define LIST_CLEAN(header)                                                                      \
00240         LIST_INIT(header);
00241 
00242 #define LIST_REPLACE(list, original, replace)                                           \
00243         LIST_NEXT(list, replace) = LIST_NEXT(list, original);                   \
00244         LIST_PREVIOUS(list, replace) = LIST_PREVIOUS(list, original);   \
00245         if (LIST_NEXT(list, replace))                                                                   \
00246                 LIST_PREVIOUS(list,LIST_NEXT(list, replace)) = replace;         \
00247         if (LIST_PREVIOUS(list, replace))                                                               \
00248                 LIST_NEXT(list,LIST_PREVIOUS(list, replace)) = replace;
00249 
00250 #endif

Generated on Sun May 30 18:38:35 2004 for Routix OS by doxygen 1.3.6