mGNCS API Reference  v1.2.0
A new control set and a new framework for MiniGUI apps
mdblist.h
Go to the documentation of this file.
1 
42 #ifndef _NCS_DBLIST_H
43 #define _NCS_DBLIST_H
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 
59 struct list_head {
60  struct list_head *next, *prev;
61 };
62 
67 typedef struct list_head list_t;
68 
69 #define LIST_HEAD_INIT(name) { &(name), &(name) }
70 
71 /* define and init a list head */
72 #define LIST_HEAD(name) \
73  struct list_head name = LIST_HEAD_INIT(name)
74 
75 /* init a list head */
76 #define INIT_LIST_HEAD(ptr) do { \
77  (ptr)->next = (ptr); (ptr)->prev = (ptr); \
78 } while (0)
79 
80 /*
81  * \fn void __list_add(struct list_head * _new, \
82  struct list_head * prev, \
83  struct list_head * next)
84  * \brief Insert a _new entry between two known consecutive entries.
85  *
86  * This is only for internal list manipulation where we know
87  * the prev/next entries already!
88  */
89 static inline void __list_add(struct list_head * _new,
90  struct list_head * prev,
91  struct list_head * next)
92 {
93  next->prev = _new;
94  _new->next = next;
95  _new->prev = prev;
96  prev->next = _new;
97 }
98 
109 static inline void list_add(struct list_head *_new, struct list_head *head)
110 {
111  __list_add(_new, head, head->next);
112 }
113 
124 static inline void list_add_tail(struct list_head *_new, struct list_head *head)
125 {
126  __list_add(_new, head->prev, head);
127 }
128 
129 /*
130  * \fn void __list_del(struct list_head * prev, \
131  struct list_head * next)
132  * \brief Delete a list entry by making the prev/next entries
133  * point to each other.
134  *
135  * This is only for internal list manipulation where we know
136  * the prev/next entries already!
137  */
138 static inline void __list_del(struct list_head * prev,
139  struct list_head * next)
140 {
141  next->prev = prev;
142  prev->next = next;
143 }
144 
150 static inline void list_del(struct list_head *entry)
151 {
152  __list_del(entry->prev, entry->next);
153 }
154 
161 static inline void list_del_init(struct list_head *entry)
162 {
163  __list_del(entry->prev, entry->next);
164  INIT_LIST_HEAD(entry);
165 }
166 
173 static inline int list_empty(struct list_head *head)
174 {
175  return head->next == head;
176 }
177 
186 #define list_entry(ptr, type, member) \
187  ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
188 
195 #define list_for_each(pos, head) \
196  for (pos = (head)->next; pos != (head); pos = pos->next)
197 
205 #define list_for_each_safe(pos, n, head) \
206  for (pos = (head)->next, n = pos->next; pos != (head); \
207  pos = n, n = pos->next)
208 
216 #define list_for_each_ex(pos, head, begin) \
217  for (pos = (begin)->next; pos != (head); pos = (pos)->next)
218 
228 #define list_for_index(pos, i, head, index) \
229  for (pos = (head)->next, i=0; (pos != (head) && i < index); pos = pos->next,i++)
230 
231 
232 static inline int list_add_by_index(struct list_head *_new, struct list_head *head, int index)
233 {
234  list_t *pos = head;
235  int i = -1;
236 
237  if (index >= 0) {
238  for (pos = (head)->next, i=0; (pos != (head) && i < index); pos = pos->next,i++);
239  }
240  list_add_tail (_new, pos);
241  return i;
242 }
243 
244 
245 /* added for normal list operations */
246 #define GETBY_EX(func, head, entrytype, member, datatype, ret, equal_cond) \
247  void* func (datatype data) \
248  { \
249  list_t *me; \
250  entrytype *pdata; \
251  int i = 0; \
252  \
253  list_for_each(me, head) { \
254  pdata = list_entry(me, entrytype, member); \
255  if (equal_cond) \
256  return ret; \
257  } \
258  return NULL; \
259  }
260 
261 #define GET_LIST_BY_DATA(func, head, entrytype, member, datamember, datatype) \
262  GETBY_EX(func, head, entrytype, member, datatype, me, (pdata->datamember == data))
263 
264 #define GET_ENTRY_BY_DATA(func, head, entrytype, member, datamember, datatype) \
265  GETBY_EX(func, head, entrytype, member, datatype, pdata, (pdata->datamember == data))
266 
267 /* for string */
268 #define GET_LIST_BY_STRING(func, head, entrytype, member, datamember, datatype) \
269  GETBY_EX(func, head, entrytype, member, datatype, me, (strcmp(pdata->datamember,data)==0))
270 
271 #define GET_ENTRY_BY_STRING(func, head, entrytype, member, datamember, datatype) \
272  GETBY_EX(func, head, entrytype, member, datatype, pdata, (strcmp(pdata->datamember,data)==0))
273 
274 /* for index */
275 #define GET_ENTRY_BY_INDEX(func, entrytype, member) \
276  static inline entrytype* func (list_t *head, int index) \
277  { \
278  list_t *me; \
279  int i = 0; \
280  \
281  list_for_each(me, head) { \
282  if (i++ == index) \
283  return list_entry(me, entrytype, member); \
284  } \
285  return NULL; \
286  }
287 
288 #define GET_ENTRY_INDEX(func, entrytype, member) \
289  static inline int func (list_t *head, entrytype* entry) \
290  { \
291  list_t *me; \
292  int i = 0; \
293  \
294  list_for_each(me, head) { \
295  if (entry == list_entry(me, entrytype, member)) \
296  return i; \
297  i++; \
298  } \
299  return -1; \
300  }
301 
302 #ifdef __cplusplus
303 }
304 #endif
305 
306 #endif /* _NCS_DBLIST_H */
static int list_empty(struct list_head *head)
Tests whether a list is empty.
Definition: mdblist.h:173
static void list_add_tail(struct list_head *_new, struct list_head *head)
Add a _new entry, insert a _new entry before the specified head. This is useful for implementing queu...
Definition: mdblist.h:124
static void list_add(struct list_head *_new, struct list_head *head)
Add a _new entry, insert a _new entry after the specified head. This is good for implementing stacks...
Definition: mdblist.h:109
The structure of double linked list.
Definition: mdblist.h:59
static void list_del_init(struct list_head *entry)
Deletes entry from list and reinitialize it.
Definition: mdblist.h:161
static void list_del(struct list_head *entry)
Deletes entry from list. Note: list_empty on entry does not return true after this, the entry is in an undefined state.
Definition: mdblist.h:150