Generic Trace Generator (GTG)  0.1
GTGList.h
Go to the documentation of this file.
00001 #ifndef GTG_LIST_H
00002 #define GTG_LIST_H
00003 
00004 struct gtg_list {
00005   struct gtg_list *prev;
00006   struct gtg_list *next;
00007 };
00008 
00009 typedef struct gtg_list* gtg_list_t;
00010 
00016 #define GTG_LIST_INIT(ptr)                      \
00017   do {                                          \
00018     (ptr)->prev = (ptr);                        \
00019     (ptr)->next = (ptr);                        \
00020   } while(0)
00021 
00027 #define GTG_LIST(name) \
00028   struct gtg_list name; \
00029   GTG_LIST_INIT(&name)
00030 
00031 
00039 #define gtg_list_entry(ptr, type, member) \
00040   ((type *)((char *)(ptr) - (char *)(&((type *)0)->member)))
00041 
00042 
00043 /*
00044  * Insert a new entry between two known consecutive entries.
00045  *
00046  * This is only for internal list manipulation where we know
00047  * the prev/next entries already!
00048  */
00049 static inline void __gtg_list_add(gtg_list_t lnew,
00050                                   gtg_list_t prev,
00051                                   gtg_list_t next)
00052 {
00053   next->prev = lnew;
00054   lnew->next = next;
00055   lnew->prev = prev;
00056   prev->next = lnew;
00057 }
00058 
00065 static inline void gtg_list_add(gtg_list_t lnew, gtg_list_t head)
00066 {
00067   __gtg_list_add(lnew, head, head->next);
00068 }
00069 
00076 static inline void gtg_list_add_tail(gtg_list_t lnew, gtg_list_t head)
00077 {
00078   __gtg_list_add(lnew, head->prev, head);
00079 }
00080 
00088 static inline void __gtg_list_del(gtg_list_t prev, gtg_list_t next)
00089 {
00090         next->prev = prev;
00091         prev->next = next;
00092 }
00093 
00099 static inline void gtg_list_del(gtg_list_t entry)
00100 {
00101   __gtg_list_del(entry->prev, entry->next);
00102   GTG_LIST_INIT(entry);
00103 }
00104 
00105 
00112 #define gtg_list_for_each(pos, head) \
00113   for (pos = (head)->next; pos != (head); pos = pos->next)
00114 
00121 #define gtg_list_for_each_reverse(pos, head)                    \
00122   for (pos = (head)->prev; pos != (head); pos = pos->prev)
00123 
00131 #define gtg_list_for_each_safe(pos, n, head)                    \
00132   for (pos = (head)->next, n = pos->next; pos != (head);        \
00133        pos = n, n = pos->next)
00134 
00135 
00136 
00144 #define gtg_list_for_each_entry(pos, head, member)                      \
00145   for (pos = gtg_list_entry((head)->next, typeof(*pos), member);        \
00146        &pos->member != (head);                                          \
00147        pos = gtg_list_entry(pos->member.next, typeof(*pos), member))
00148 
00157 #define gtg_list_for_each_entry_safe(pos, n, head, member)              \
00158   for (pos = gtg_list_entry((head)->next, typeof(*pos), member),        \
00159          n = gtg_list_entry(pos->member.next, typeof(*pos), member);    \
00160        &pos->member != (head);                                          \
00161        pos = n, n = gtg_list_entry(n->member.next, typeof(*n), member))
00162 
00163 
00164 static inline int gtg_list_size(gtg_list_t l)
00165 {
00166   int res = 0;
00167   gtg_list_t ptr = NULL;
00168   gtg_list_for_each(ptr, l)
00169     res++;
00170 
00171   return res;
00172 }
00173 
00174 #endif  /* GTG_LIST_H */