• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _SHELL_LIST_H
33 #define _SHELL_LIST_H
34 
35 #include "sherr.h"
36 #include "stdint.h"
37 
38 #ifdef __cplusplus
39 #if __cplusplus
40 extern "C" {
41 #endif /* __cplusplus */
42 #endif /* __cplusplus */
43 
44 typedef size_t bool;
45 
46 /**
47  * @ingroup shell_list
48  * Structure of a node in a doubly linked list.
49  */
50 typedef struct SH_List {
51     struct SH_List *pstPrev; /**< Current node's pointer to the previous node */
52     struct SH_List *pstNext; /**< Current node's pointer to the next node */
53 } SH_List;
54 
55 /**
56  * @ingroup shell_list
57  *
58  * @par Description:
59  * This API is used to initialize a doubly linked list.
60  * @attention
61  * <ul>
62  * <li>The parameter passed in should be ensured to be a legal pointer.</li>
63  * </ul>
64  *
65  * @param list    [IN] Node in a doubly linked list.
66  *
67  * @retval None.
68  * @par Dependency:
69  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
70  * @see
71  */
SH_ListInit(SH_List * list)72 static inline void SH_ListInit(SH_List *list)
73 {
74     list->pstNext = list;
75     list->pstPrev = list;
76 }
77 
78 /**
79  * @ingroup shell_list
80  * @brief Point to the next node pointed to by the current node.
81  *
82  * @par Description:
83  * <ul>
84  * <li>This API is used to point to the next node pointed to by the current node.</li>
85  * </ul>
86  * @attention
87  * <ul>
88  * <li>None.</li>
89  * </ul>
90  *
91  * @param object  [IN] Node in the doubly linked list.
92  *
93  * @retval None.
94  * @par Dependency:
95  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
96  * @see
97  */
98 #define SH_LIST_FIRST(object) ((object)->pstNext)
99 
100 /**
101  * @ingroup shell_list
102  * @brief Point to the previous node pointed to by the current node.
103  *
104  * @par Description:
105  * <ul>
106  * <li>This API is used to point to the previous node pointed to by the current node.</li>
107  * </ul>
108  * @attention
109  * <ul>
110  * <li>None.</li>
111  * </ul>
112  *
113  * @param object  [IN] Node in the doubly linked list.
114  *
115  * @retval None.
116  * @par Dependency:
117  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
118  * @see
119  */
120 #define SH_LIST_LAST(object) ((object)->pstPrev)
121 
122 /**
123  * @ingroup shell_list
124  * @brief Insert a new node to a doubly linked list.
125  *
126  * @par Description:
127  * This API is used to insert a new node to a doubly linked list.
128  * @attention
129  * <ul>
130  * <li>The parameters passed in should be ensured to be legal pointers.</li>
131  * </ul>
132  *
133  * @param list    [IN] Doubly linked list where the new node is inserted.
134  * @param node    [IN] New node to be inserted.
135  *
136  * @retval None
137  * @par Dependency:
138  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
139  * @see SH_ListDelete
140  */
SH_ListAdd(SH_List * list,SH_List * node)141 static inline void SH_ListAdd(SH_List *list, SH_List *node)
142 {
143     node->pstNext = list->pstNext;
144     node->pstPrev = list;
145     list->pstNext->pstPrev = node;
146     list->pstNext = node;
147 }
148 
149 /**
150  * @ingroup shell_list
151  * @brief Insert a node to the tail of a doubly linked list.
152  *
153  * @par Description:
154  * This API is used to insert a new node to the tail of a doubly linked list.
155  * @attention
156  * <ul>
157  * <li>The parameters passed in should be ensured to be legal pointers.</li>
158  * </ul>
159  *
160  * @param list     [IN] Doubly linked list where the new node is inserted.
161  * @param node     [IN] New node to be inserted.
162  *
163  * @retval None.
164  * @par Dependency:
165  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
166  * @see SH_ListAdd | SH_ListHeadInsert
167  */
SH_ListTailInsert(SH_List * list,SH_List * node)168 static inline void SH_ListTailInsert(SH_List *list, SH_List *node)
169 {
170     if ((list == NULL) || (node == NULL)) {
171         return;
172     }
173 
174     SH_ListAdd(list->pstPrev, node);
175 }
176 
177 /**
178  * @ingroup shell_list
179  * @brief Insert a node to the head of a doubly linked list.
180  *
181  * @par Description:
182  * This API is used to insert a new node to the head of a doubly linked list.
183  * @attention
184  * <ul>
185  * <li>The parameters passed in should be ensured to be legal pointers.</li>
186  * </ul>
187  *
188  * @param list     [IN] Doubly linked list where the new node is inserted.
189  * @param node     [IN] New node to be inserted.
190  *
191  * @retval None.
192  * @par Dependency:
193  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
194  * @see SH_ListAdd | SH_ListTailInsert
195  */
SH_ListHeadInsert(SH_List * list,SH_List * node)196 static inline void SH_ListHeadInsert(SH_List *list, SH_List *node)
197 {
198     if ((list == NULL) || (node == NULL)) {
199         return;
200     }
201 
202     SH_ListAdd(list, node);
203 }
204 
205 /**
206  * @ingroup shell_list
207  *
208  * @par Description:
209  * <ul>
210  * <li>This API is used to delete a specified node from a doubly linked list.</li>
211  * </ul>
212  * @attention
213  * <ul>
214  * <li>The parameter passed in should be ensured to be a legal pointer.</li>
215  * </ul>
216  *
217  * @param node    [IN] Node to be deleted.
218  *
219  * @retval None.
220  * @par Dependency:
221  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
222  * @see SH_ListAdd
223  */
SH_ListDelete(SH_List * node)224 static inline void SH_ListDelete(SH_List *node)
225 {
226     node->pstNext->pstPrev = node->pstPrev;
227     node->pstPrev->pstNext = node->pstNext;
228     node->pstNext = NULL;
229     node->pstPrev = NULL;
230 }
231 
232 /**
233  * @ingroup shell_list
234  * @brief Identify whether a specified doubly linked list is empty.
235  *
236  * @par Description:
237  * <ul>
238  * <li>This API is used to return whether a doubly linked list is empty.</li>
239  * </ul>
240  * @attention
241  * <ul>
242  * <li>The parameter passed in should be ensured to be a legal pointer.</li>
243  * </ul>
244  *
245  * @param list  [IN] Doubly linked list.
246  *
247  * @retval TRUE The doubly linked list is empty.
248  * @retval FALSE The doubly linked list is not empty.
249  * @par Dependency:
250  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
251  * @see
252  */
SH_ListEmpty(SH_List * list)253 static inline bool SH_ListEmpty(SH_List *list)
254 {
255     if (list == NULL) {
256         return FALSE;
257     }
258 
259     return (bool)(list->pstNext == list);
260 }
261 
262 /**
263  * @ingroup shell_list
264  * @brief Insert a new list to a doubly linked list.
265  *
266  * @par Description:
267  * This API is used to insert a new list to a doubly linked list.
268  * @attention
269  * <ul>
270  * <li>The parameters passed in should be ensured to be legal pointers.</li>
271  * </ul>
272  *
273  * @param oldList    [IN] Doubly linked list where the new list is inserted.
274  * @param newList    [IN] New list to be inserted.
275  *
276  * @retval None
277  * @par Dependency:
278  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
279  * @see SH_ListDelete
280  */
SH_ListAddList(SH_List * oldList,SH_List * newList)281 static inline void SH_ListAddList(SH_List *oldList, SH_List *newList)
282 {
283     SH_List *oldListHead = oldList->pstNext;
284     SH_List *oldListTail = oldList;
285     SH_List *newListHead = newList;
286     SH_List *newListTail = newList->pstPrev;
287 
288     oldListTail->pstNext = newListHead;
289     newListHead->pstPrev = oldListTail;
290     oldListHead->pstPrev = newListTail;
291     newListTail->pstNext = oldListHead;
292 }
293 
294 /**
295  * @ingroup shell_list
296  * @brief Insert a doubly list to the tail of a doubly linked list.
297  *
298  * @par Description:
299  * This API is used to insert a new doubly list to the tail of a doubly linked list.
300  * @attention
301  * <ul>
302  * <li>The parameters passed in should be ensured to be legal pointers.</li>
303  * </ul>
304  *
305  * @param oldList     [IN] Doubly linked list where the new list is inserted.
306  * @param newList     [IN] New list to be inserted.
307  *
308  * @retval None.
309  * @par Dependency:
310  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
311  * @see SH_ListAddList | SH_ListHeadInsertList
312  */
SH_ListTailInsertList(SH_List * oldList,SH_List * newList)313 static inline void SH_ListTailInsertList(SH_List *oldList, SH_List *newList)
314 {
315     SH_ListAddList(oldList->pstPrev, newList);
316 }
317 
318 /**
319  * @ingroup shell_list
320  * @brief Insert a doubly list to the head of a doubly linked list.
321  *
322  * @par Description:
323  * This API is used to insert a new doubly list to the head of a doubly linked list.
324  * @attention
325  * <ul>
326  * <li>The parameters passed in should be ensured to be legal pointers.</li>
327  * </ul>
328  *
329  * @param oldList     [IN] Doubly linked list where the new list is inserted.
330  * @param newList     [IN] New list to be inserted.
331  *
332  * @retval None.
333  * @par Dependency:
334  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
335  * @see SH_ListAddList | SH_ListTailInsertList
336  */
SH_ListHeadInsertList(SH_List * oldList,SH_List * newList)337 static inline void SH_ListHeadInsertList(SH_List *oldList, SH_List *newList)
338 {
339     SH_ListAddList(oldList, newList);
340 }
341 
342 /**
343  * @ingroup shell_list
344  * @brief Obtain the offset of a field to a structure address.
345  *
346  * @par  Description:
347  * This API is used to obtain the offset of a field to a structure address.
348  * @attention
349  * <ul>
350  * <li>None.</li>
351  * </ul>
352  *
353  * @param type    [IN] Structure name.
354  * @param member  [IN] Name of the member of which the offset is to be measured.
355  *
356  * @retval Offset of the field to the structure address.
357  * @par Dependency:
358  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
359  * @see
360  */
361 #define LOS_OFF_SET_OF(type, member) ((uintptr_t)&((type *)0)->member)
362 
363 /**
364  * @ingroup shell_list
365  * @brief Obtain the pointer to a structure that contains a doubly linked list.
366  *
367  * @par Description:
368  * This API is used to obtain the pointer to a structure that contains a doubly linked list.
369  * <ul>
370  * <li>None.</li>
371  * </ul>
372  * @attention
373  * <ul>
374  * <li>None.</li>
375  * </ul>
376  *
377  * @param item    [IN] Current node's pointer to the next node.
378  * @param type    [IN] Structure name.
379  * @param member  [IN] Member name of the doubly linked list in the structure.
380  *
381  * @retval Pointer to the structure that contains the doubly linked list.
382  * @par Dependency:
383  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
384  * @see
385  */
386 #define SH_LIST_ENTRY(item, type, member) \
387     ((type *)(void *)((char *)(item) - LOS_OFF_SET_OF(type, member)))
388 
389 /**
390  * @ingroup shell_list
391  * @brief Iterate over a doubly linked list of given type.
392  *
393  * @par Description:
394  * This API is used to iterate over a doubly linked list of given type.
395  * @attention
396  * <ul>
397  * <li>None.</li>
398  * </ul>
399  *
400  * @param item           [IN] Pointer to the structure that contains the doubly linked list that is to be traversed.
401  * @param list           [IN] Pointer to the doubly linked list to be traversed.
402  * @param type           [IN] Structure name.
403  * @param member         [IN] Member name of the doubly linked list in the structure.
404  *
405  * @retval None.
406  * @par Dependency:
407  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
408  * @see
409  */
410 #define SH_LIST_FOR_EACH_ENTRY(item, list, type, member)             \
411     for (item = SH_LIST_ENTRY((list)->pstNext, type, member);        \
412          &(item)->member != (list);                                      \
413          item = SH_LIST_ENTRY((item)->member.pstNext, type, member))
414 
415 /**
416  * @ingroup shell_list
417  * @brief iterate over a doubly linked list safe against removal of list entry.
418  *
419  * @par Description:
420  * This API is used to iterate over a doubly linked list safe against removal of list entry.
421  * @attention
422  * <ul>
423  * <li>None.</li>
424  * </ul>
425  *
426  * @param item           [IN] Pointer to the structure that contains the doubly linked list that is to be traversed.
427  * @param next           [IN] Save the next node.
428  * @param list           [IN] Pointer to the doubly linked list to be traversed.
429  * @param type           [IN] Structure name.
430  * @param member         [IN] Member name of the doubly linked list in the structure.
431  *
432  * @retval None.
433  * @par Dependency:
434  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
435  * @see
436  */
437 #define SH_LIST_FOR_EACH_ENTRY_SAFE(item, next, list, type, member)               \
438     for (item = SH_LIST_ENTRY((list)->pstNext, type, member),                     \
439          next = SH_LIST_ENTRY((item)->member.pstNext, type, member);              \
440          &(item)->member != (list);                                                   \
441          item = next, next = SH_LIST_ENTRY((item)->member.pstNext, type, member))
442 
443 /**
444  * @ingroup shell_list
445  * @brief Delete initialize a doubly linked list.
446  *
447  * @par Description:
448  * This API is used to delete initialize a doubly linked list.
449  * @attention
450  * <ul>
451  * <li>The parameter passed in should be ensured to be s legal pointer.</li>
452  * </ul>
453  *
454  * @param list    [IN] Doubly linked list.
455  *
456  * @retval None.
457  * @par Dependency:
458  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
459  * @see
460  */
SH_ListDelInit(SH_List * list)461 static inline void SH_ListDelInit(SH_List *list)
462 {
463     list->pstNext->pstPrev = list->pstPrev;
464     list->pstPrev->pstNext = list->pstNext;
465     SH_ListInit(list);
466 }
467 
468 /**
469  * @ingroup shell_list
470  * @brief iterate over a doubly linked list.
471  *
472  * @par Description:
473  * This API is used to iterate over a doubly linked list.
474  * @attention
475  * <ul>
476  * <li>None.</li>
477  * </ul>
478  *
479  * @param item           [IN] Pointer to the structure that contains the doubly linked list that is to be traversed.
480  * @param list           [IN] Pointer to the doubly linked list to be traversed.
481  *
482  * @retval None.
483  * @par Dependency:
484  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
485  * @see
486  */
487 #define SH_LIST_FOR_EACH(item, list) \
488     for (item = (list)->pstNext;         \
489          (item) != (list);               \
490          item = (item)->pstNext)
491 
492 /**
493  * @ingroup shell_list
494  * @brief Iterate over a doubly linked list safe against removal of list entry.
495  *
496  * @par Description:
497  * This API is used to iterate over a doubly linked list safe against removal of list entry.
498  * @attention
499  * <ul>
500  * <li>None.</li>
501  * </ul>
502  *
503  * @param item           [IN] Pointer to the structure that contains the doubly linked list that is to be traversed.
504  * @param next           [IN] Save the next node.
505  * @param list           [IN] Pointer to the doubly linked list to be traversed.
506  *
507  * @retval None.
508  * @par Dependency:
509  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
510  * @see
511  */
512 #define SH_LIST_FOR_EACH_SAFE(item, next, list)      \
513     for (item = (list)->pstNext, next = (item)->pstNext; \
514          (item) != (list);                               \
515          item = next, next = (item)->pstNext)
516 
517 /**
518  * @ingroup shell_list
519  * @brief Initialize a double linked list.
520  *
521  * @par Description:
522  * This API is used to initialize a double linked list.
523  * @attention
524  * <ul>
525  * <li>None.</li>
526  * </ul>
527  *
528  * @param list           [IN] Pointer to the doubly linked list to be traversed.
529  *
530  * @retval None.
531  * @par Dependency:
532  * <ul><li>shell_list.h: the header file that contains the API declaration.</li></ul>
533  * @see
534  */
535 #define SH_LIST_HEAD(list) SH_List list = { &(list), &(list) }
536 
537 #define SH_ListPeekHeadType(list, type, element) do {            \
538     type *__t;                                                  \
539     if ((list)->pstNext == list) {                              \
540         __t = NULL;                                             \
541     } else {                                                    \
542         __t = SH_LIST_ENTRY((list)->pstNext, type, element);    \
543     }                                                           \
544     __t;                                                        \
545 } while (0)
546 
547 #define SH_ListRemoveHeadType(list, type, element) do {          \
548     type *__t;                                                  \
549     if ((list)->pstNext == list) {                              \
550         __t = NULL;                                             \
551     } else {                                                    \
552         __t = SH_LIST_ENTRY((list)->pstNext, type, element);    \
553         SH_ListDelete((list)->pstNext);                        \
554     }                                                           \
555     __t;                                                        \
556 } while (0)
557 
558 #define SH_ListNextType(list, item, type, element) do {          \
559     type *__t;                                                  \
560     if ((item)->pstNext == list) {                              \
561         __t = NULL;                                             \
562     } else {                                                    \
563         __t = SH_LIST_ENTRY((item)->pstNext, type, element);    \
564     }                                                           \
565     __t;                                                        \
566 } while (0)
567 
568 #ifdef __cplusplus
569 #if __cplusplus
570 }
571 #endif /* __cplusplus */
572 #endif /* __cplusplus */
573 
574 #endif /* _SHELL_LIST_H */
575