Imported Upstream version 1.5.0
[platform/upstream/augeas.git] / src / list.h
1 /*
2  * list.h: Simple generic list manipulation
3  *
4  * Copyright (C) 2007-2015 David Lutterkort
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19  *
20  * Author: David Lutterkort <dlutter@redhat.com>
21  */
22
23 #ifndef LIST_H_
24 #define LIST_H_
25
26 #define list_append(head, tail)                                         \
27     do {                                                                \
28         if ((head) == NULL) {                                           \
29             head = tail;                                                \
30             break;                                                      \
31         }                                                               \
32         typeof(head) _p;                                                \
33         for (_p = (head); _p->next != NULL; _p = _p->next);             \
34         _p->next = (tail);                                              \
35     } while (0)
36
37 #define list_for_each(iter, list)                                       \
38     for (typeof(list) (iter) = list; (iter) != NULL; (iter) = (iter)->next)
39
40 #define list_remove(elt, list)                                          \
41     do {                                                                \
42         typeof(elt) _e = (elt);                                         \
43         if (_e == (list)) {                                             \
44             (list) = _e->next;                                          \
45         } else {                                                        \
46             typeof(_e) _p;                                              \
47             for (_p = (list); _p != NULL && _p->next != _e; _p = _p->next); \
48             if (_p != NULL)                                             \
49                 _p->next = _e->next;                                    \
50         }                                                               \
51         _e->next = NULL;                                                \
52     } while(0)
53
54 /* Insert NEW in list LIST before element AC. NEW->next must be null,
55    and ELT must really be on LIST, otherwise chaos will ensue
56 */
57 #define list_insert_before(new, elt, list)                              \
58     do {                                                                \
59         if ((list) == NULL) {                                           \
60             (list) = (new);                                             \
61         } else if ((elt) == (list)) {                                   \
62             (new)->next = (elt);                                        \
63             (list) = (new);                                             \
64         } else {                                                        \
65             typeof(elt) _p;                                             \
66             for (_p = (list); _p != NULL && _p->next != (elt); _p = _p->next); \
67             if (_p != NULL) {                                           \
68                 (new)->next = (elt);                                    \
69                 _p->next = (new);                                       \
70             }                                                           \
71         }                                                               \
72     } while(0)
73
74 #endif
75
76 #define list_free(list)                                                 \
77     while ((list) != NULL) {                                            \
78         typeof(list) _p = list;                                         \
79         (list) = (list)->next;                                          \
80         free((void *) _p);                                              \
81     }
82
83 #define list_length(len, list)                                          \
84     do {                                                                \
85         typeof(list) _p;                                                \
86         for (len=0, _p = (list); _p != NULL; len += 1, _p = _p->next);  \
87     } while(0)
88
89 /* Make ELT the new head of LIST and set LIST to it */
90 #define list_cons(list, elt)                                            \
91     do {                                                                \
92         typeof(elt) _e = (elt);                                         \
93         _e->next = (list);                                              \
94         (list) = _e;                                                    \
95     } while(0)
96
97 #define list_reverse(list)                                              \
98     do {                                                                \
99         typeof(list) _head = (list);                                    \
100         typeof(list) _prev = NULL;                                      \
101         while (_head != NULL) {                                         \
102             typeof(list) _next = _head->next;                           \
103             _head->next = _prev;                                        \
104             _prev = _head;                                              \
105             _head = _next;                                              \
106         }                                                               \
107         (list) = _prev;                                                 \
108     } while (0)
109
110 /* Append ELT to the end of LIST. TAIL must be NULL or a pointer to
111    the last element of LIST. ELT may also be a list
112 */
113 #define list_tail_cons(list, tail, elt)                                 \
114     do {                                                                \
115         /* Append ELT at the end of LIST */                             \
116         if ((list) == NULL) {                                           \
117             (list) = (elt);                                             \
118         } else {                                                        \
119             if ((tail) == NULL)                                         \
120                 for ((tail) = (list); (tail)->next != NULL;             \
121                      (tail) = (tail)->next);                            \
122             (tail)->next = (elt);                                       \
123         }                                                               \
124         /* Make sure TAIL is the last element on the combined LIST */   \
125         (tail) = (elt);                                                 \
126         if ((tail) != NULL)                                             \
127             while ((tail)->next != NULL)                                \
128                 (tail) = (tail)->next;                                  \
129     } while(0)
130
131 /*
132  * Local variables:
133  *  indent-tabs-mode: nil
134  *  c-indent-level: 4
135  *  c-basic-offset: 4
136  *  tab-width: 4
137  * End:
138  */