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 27typedef struct _FcPtrListEntry { 28 struct _FcPtrListEntry *next; 29 void *data; 30} FcPtrListEntry; 31struct _FcPtrList { 32 FcDestroyFunc destroy_func; 33 FcPtrListEntry *list; 34}; 35typedef struct _FcPtrListIterPrivate { 36 const FcPtrList *list; 37 FcPtrListEntry *entry; 38 FcPtrListEntry *prev; 39} FcPtrListIterPrivate; 40 41FcPtrList * 42FcPtrListCreate (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 55void 56FcPtrListDestroy (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 74void 75FcPtrListIterInit (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 85void 86FcPtrListIterInitAtLast (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 101FcBool 102FcPtrListIterNext (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 115FcBool 116FcPtrListIterIsValid (const FcPtrList *list, 117 const FcPtrListIter *iter) 118{ 119 FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter; 120 121 return list == priv->list && priv->entry; 122} 123 124void * 125FcPtrListIterGetValue (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 137FcBool 138FcPtrListIterAdd (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 178FcBool 179FcPtrListIterRemove (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__ 204