mGNCS API Reference  v1.5.0
A new control set and a new framework for MiniGUI apps
mdblist.h
Go to the documentation of this file.
1 //
3 // IMPORTANT NOTICE
4 //
5 // The following open source license statement does not apply to any
6 // entity in the Exception List published by FMSoft.
7 //
8 // For more information, please visit:
9 //
10 // https://www.fmsoft.cn/exception-list
11 //
13 
54 #ifndef _NCS_DBLIST_H
55 #define _NCS_DBLIST_H
56 
57 #ifdef __cplusplus
58 extern "C" {
59 #endif
60 
71 struct list_head {
72  struct list_head *next, *prev;
73 };
74 
79 typedef struct list_head list_t;
80 
81 #define LIST_HEAD_INIT(name) { &(name), &(name) }
82 
83 /* define and init a list head */
84 #define LIST_HEAD(name) \
85  struct list_head name = LIST_HEAD_INIT(name)
86 
87 /* init a list head */
88 #define INIT_LIST_HEAD(ptr) do { \
89  (ptr)->next = (ptr); (ptr)->prev = (ptr); \
90 } while (0)
91 
92 /*
93  * \fn void __list_add(struct list_head * _new, \
94  struct list_head * prev, \
95  struct list_head * next)
96  * \brief Insert a _new entry between two known consecutive entries.
97  *
98  * This is only for internal list manipulation where we know
99  * the prev/next entries already!
100  */
101 static inline void __list_add(struct list_head * _new,
102  struct list_head * prev,
103  struct list_head * next)
104 {
105  next->prev = _new;
106  _new->next = next;
107  _new->prev = prev;
108  prev->next = _new;
109 }
110 
121 static inline void list_add(struct list_head *_new, struct list_head *head)
122 {
123  __list_add(_new, head, head->next);
124 }
125 
136 static inline void list_add_tail(struct list_head *_new, struct list_head *head)
137 {
138  __list_add(_new, head->prev, head);
139 }
140 
141 /*
142  * \fn void __list_del(struct list_head * prev, \
143  struct list_head * next)
144  * \brief Delete a list entry by making the prev/next entries
145  * point to each other.
146  *
147  * This is only for internal list manipulation where we know
148  * the prev/next entries already!
149  */
150 static inline void __list_del(struct list_head * prev,
151  struct list_head * next)
152 {
153  next->prev = prev;
154  prev->next = next;
155 }
156 
162 static inline void list_del(struct list_head *entry)
163 {
164  __list_del(entry->prev, entry->next);
165 }
166 
173 static inline void list_del_init(struct list_head *entry)
174 {
175  __list_del(entry->prev, entry->next);
176  INIT_LIST_HEAD(entry);
177 }
178 
185 static inline int list_empty(struct list_head *head)
186 {
187  return head->next == head;
188 }
189 
198 #define list_entry(ptr, type, member) \
199  ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
200 
207 #define list_for_each(pos, head) \
208  for (pos = (head)->next; pos != (head); pos = pos->next)
209 
217 #define list_for_each_safe(pos, n, head) \
218  for (pos = (head)->next, n = pos->next; pos != (head); \
219  pos = n, n = pos->next)
220 
228 #define list_for_each_ex(pos, head, begin) \
229  for (pos = (begin)->next; pos != (head); pos = (pos)->next)
230 
240 #define list_for_index(pos, i, head, index) \
241  for (pos = (head)->next, i=0; (pos != (head) && i < index); pos = pos->next,i++)
242 
243 
244 static inline int list_add_by_index(struct list_head *_new, struct list_head *head, int index)
245 {
246  list_t *pos = head;
247  int i = -1;
248 
249  if (index >= 0) {
250  for (pos = (head)->next, i=0; (pos != (head) && i < index); pos = pos->next,i++);
251  }
252  list_add_tail (_new, pos);
253  return i;
254 }
255 
256 
257 /* added for normal list operations */
258 #define GETBY_EX(func, head, entrytype, member, datatype, ret, equal_cond) \
259  void* func (datatype data) \
260  { \
261  list_t *me; \
262  entrytype *pdata; \
263  int i = 0; \
264  \
265  list_for_each(me, head) { \
266  pdata = list_entry(me, entrytype, member); \
267  if (equal_cond) \
268  return ret; \
269  } \
270  return NULL; \
271  }
272 
273 #define GET_LIST_BY_DATA(func, head, entrytype, member, datamember, datatype) \
274  GETBY_EX(func, head, entrytype, member, datatype, me, (pdata->datamember == data))
275 
276 #define GET_ENTRY_BY_DATA(func, head, entrytype, member, datamember, datatype) \
277  GETBY_EX(func, head, entrytype, member, datatype, pdata, (pdata->datamember == data))
278 
279 /* for string */
280 #define GET_LIST_BY_STRING(func, head, entrytype, member, datamember, datatype) \
281  GETBY_EX(func, head, entrytype, member, datatype, me, (strcmp(pdata->datamember,data)==0))
282 
283 #define GET_ENTRY_BY_STRING(func, head, entrytype, member, datamember, datatype) \
284  GETBY_EX(func, head, entrytype, member, datatype, pdata, (strcmp(pdata->datamember,data)==0))
285 
286 /* for index */
287 #define GET_ENTRY_BY_INDEX(func, entrytype, member) \
288  static inline entrytype* func (list_t *head, int index) \
289  { \
290  list_t *me; \
291  int i = 0; \
292  \
293  list_for_each(me, head) { \
294  if (i++ == index) \
295  return list_entry(me, entrytype, member); \
296  } \
297  return NULL; \
298  }
299 
300 #define GET_ENTRY_INDEX(func, entrytype, member) \
301  static inline int func (list_t *head, entrytype* entry) \
302  { \
303  list_t *me; \
304  int i = 0; \
305  \
306  list_for_each(me, head) { \
307  if (entry == list_entry(me, entrytype, member)) \
308  return i; \
309  i++; \
310  } \
311  return -1; \
312  }
313 
314 #ifdef __cplusplus
315 }
316 #endif
317 
318 #endif /* _NCS_DBLIST_H */
list_add
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:121
list_empty
static int list_empty(struct list_head *head)
Tests whether a list is empty.
Definition: mdblist.h:185
list_del_init
static void list_del_init(struct list_head *entry)
Deletes entry from list and reinitialize it.
Definition: mdblist.h:173
list_head
The structure of double linked list.
Definition: mdblist.h:71
list_del
static void list_del(struct list_head *entry)
Deletes entry from list. Note: list_empty on entry does not return true after this,...
Definition: mdblist.h:162
list_add_tail
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:136