Imported Upstream version 2.14.2
[platform/upstream/fontconfig.git] / src / fcptrlist.c
1 /*
2  * fontconfig/src/fcptrlist.c
3  *
4  * Copyright © 2000 Keith Packard
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the author(s) not be used in
11  * advertising or publicity pertaining to distribution of the software without
12  * specific, written prior permission.  The authors make no
13  * representations about the suitability of this software for any purpose.  It
14  * is provided "as is" without express or implied warranty.
15  *
16  * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #include "fcint.h"
26
27 typedef struct _FcPtrListEntry {
28     struct _FcPtrListEntry      *next;
29     void                        *data;
30 } FcPtrListEntry;
31 struct _FcPtrList {
32     FcDestroyFunc       destroy_func;
33     FcPtrListEntry      *list;
34 };
35 typedef struct _FcPtrListIterPrivate {
36     const FcPtrList     *list;
37     FcPtrListEntry      *entry;
38     FcPtrListEntry      *prev;
39 } FcPtrListIterPrivate;
40
41 FcPtrList *
42 FcPtrListCreate (FcDestroyFunc func)
43 {
44     FcPtrList *ret = (FcPtrList *) malloc (sizeof (FcPtrList));
45
46     if (ret)
47     {
48         ret->destroy_func = func;
49         ret->list = NULL;
50     }
51
52     return ret;
53 }
54
55 void
56 FcPtrListDestroy (FcPtrList *list)
57 {
58     FcPtrListIter iter;
59
60     if (list)
61     {
62         FcPtrListIterInit (list, &iter);
63         do
64         {
65             if (FcPtrListIterGetValue (list, &iter))
66                 list->destroy_func (FcPtrListIterGetValue (list, &iter));
67             FcPtrListIterRemove (list, &iter);
68         } while (FcPtrListIterIsValid (list, &iter));
69
70         free (list);
71     }
72 }
73
74 void
75 FcPtrListIterInit (const FcPtrList      *list,
76                  FcPtrListIter          *iter)
77 {
78     FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
79
80     priv->list = list;
81     priv->entry = list->list;
82     priv->prev = NULL;
83 }
84
85 void
86 FcPtrListIterInitAtLast (FcPtrList      *list,
87                        FcPtrListIter    *iter)
88 {
89     FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
90     FcPtrListEntry **e, **p;
91
92     e = &list->list;
93     p = e;
94     for (; *e; p = e, e = &(*e)->next);
95
96     priv->list = list;
97     priv->entry = *e;
98     priv->prev = *p;
99 }
100
101 FcBool
102 FcPtrListIterNext (const FcPtrList      *list,
103                  FcPtrListIter          *iter)
104 {
105     FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
106
107     if (list != priv->list)
108         return FcFalse;
109     priv->prev = priv->entry;
110     priv->entry = priv->entry->next;
111
112     return priv->entry != NULL;
113 }
114
115 FcBool
116 FcPtrListIterIsValid (const FcPtrList   *list,
117                     const FcPtrListIter *iter)
118 {
119     FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
120
121     return list == priv->list && priv->entry;
122 }
123
124 void *
125 FcPtrListIterGetValue (const FcPtrList          *list,
126                      const FcPtrListIter        *iter)
127 {
128     FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
129
130     if (list != priv->list ||
131         !priv->entry)
132         return NULL;
133
134     return priv->entry->data;
135 }
136
137 FcBool
138 FcPtrListIterAdd (FcPtrList     *list,
139                 FcPtrListIter   *iter,
140                 void            *data)
141 {
142     FcPtrListEntry *e;
143     FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
144
145     if (list != priv->list)
146         return FcFalse;
147
148     e = (FcPtrListEntry *) malloc (sizeof (FcPtrListEntry));
149     if (!e)
150         return FcFalse;
151     e->data = data;
152
153     if (priv->entry)
154     {
155         e->next = priv->entry->next;
156         priv->entry->next = e;
157     }
158     else
159     {
160         e->next = NULL;
161         if (priv->prev)
162         {
163             priv->prev->next = e;
164             priv->entry = priv->prev;
165         }
166         else
167         {
168             list->list = e;
169             priv->entry = e;
170
171             return FcTrue;
172         }
173     }
174
175     return FcPtrListIterNext (list, iter);
176 }
177
178 FcBool
179 FcPtrListIterRemove (FcPtrList          *list,
180                    FcPtrListIter        *iter)
181 {
182     FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
183     FcPtrListEntry *e;
184
185     if (list != priv->list)
186         return FcFalse;
187     if (!priv->entry)
188         return FcTrue;
189
190     if (list->list == priv->entry)
191         list->list = list->list->next;
192     e = priv->entry;
193     if (priv->prev)
194         priv->prev->next = priv->entry->next;
195     priv->entry = priv->entry->next;
196     free (e);
197
198     return FcTrue;
199 }
200
201 #define __fcplist__
202 #include "fcaliastail.h"
203 #undef __fcplist__