1 /* 2 Based on gslist.c from glib-1.2.9 (LGPL). 3 4 Adaption to JACK, Copyright (C) 2002 Kai Vehmanen. 5 - replaced use of gtypes with normal ANSI C types 6 - glib's memory allocation routines replaced with 7 malloc/free calls 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU Lesser General Public License as published by 11 the Free Software Foundation; either version 2.1 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU Lesser General Public License for more details. 18 19 You should have received a copy of the GNU Lesser General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 23 */ 24 25 module jack.c.jslist; 26 public import jack.c.systemdeps; 27 import core.stdc.stdlib; 28 29 extern(C) 30 { 31 32 alias JCompareFunc = int function(void* a, void* b); 33 struct JSList 34 { 35 void *data; 36 JSList *next; 37 }; 38 39 // pragma(inline, true) 40 static 41 JSList* 42 jack_slist_alloc () 43 { 44 JSList *new_list; 45 46 new_list = cast(JSList*)malloc(JSList.sizeof); 47 if (new_list) { 48 new_list.data = null; 49 new_list.next = null; 50 } 51 52 return new_list; 53 } 54 55 // pragma(inline, true) 56 static 57 JSList* 58 jack_slist_prepend (JSList* list, void* data) 59 { 60 JSList *new_list; 61 62 new_list = cast(JSList*)malloc(JSList.sizeof); 63 if (new_list) { 64 new_list.data = data; 65 new_list.next = list; 66 } 67 68 return new_list; 69 } 70 71 // pragma(inline, true) 72 static 73 JSList* 74 jack_slist_next (JSList *slist) 75 { 76 return slist ? slist.next : null; 77 } 78 79 // pragma(inline, true) 80 static 81 JSList* 82 jack_slist_last (JSList *list) 83 { 84 if (list) { 85 while (list.next) 86 list = list.next; 87 } 88 89 return list; 90 } 91 92 // pragma(inline, true) 93 static 94 JSList* 95 jack_slist_remove_link (JSList *list, 96 JSList *link) 97 { 98 JSList *tmp; 99 JSList *prev; 100 101 prev = null; 102 tmp = list; 103 104 while (tmp) { 105 if (tmp == link) { 106 if (prev) 107 prev.next = tmp.next; 108 if (list == tmp) 109 list = list.next; 110 111 tmp.next = null; 112 break; 113 } 114 115 prev = tmp; 116 tmp = tmp.next; 117 } 118 119 return list; 120 } 121 122 // pragma(inline, true) 123 static 124 void 125 jack_slist_free (JSList *list) 126 { 127 while (list) { 128 JSList *next = list.next; 129 free(list); 130 list = next; 131 } 132 } 133 134 // pragma(inline, true) 135 static 136 void 137 jack_slist_free_1 (JSList *list) 138 { 139 if (list) { 140 free(list); 141 } 142 } 143 144 // pragma(inline, true) 145 static 146 JSList* 147 jack_slist_remove (JSList *list, 148 void *data) 149 { 150 JSList *tmp; 151 JSList *prev; 152 153 prev = null; 154 tmp = list; 155 156 while (tmp) { 157 if (tmp.data == data) { 158 if (prev) 159 prev.next = tmp.next; 160 if (list == tmp) 161 list = list.next; 162 163 tmp.next = null; 164 jack_slist_free (tmp); 165 166 break; 167 } 168 169 prev = tmp; 170 tmp = tmp.next; 171 } 172 173 return list; 174 } 175 176 // pragma(inline, true) 177 static 178 uint 179 jack_slist_length (JSList *list) 180 { 181 uint length; 182 183 length = 0; 184 while (list) { 185 length++; 186 list = list.next; 187 } 188 189 return length; 190 } 191 192 // pragma(inline, true) 193 static 194 JSList* 195 jack_slist_find (JSList *list, 196 void *data) 197 { 198 while (list) { 199 if (list.data == data) 200 break; 201 list = list.next; 202 } 203 204 return list; 205 } 206 207 // pragma(inline, true) 208 static 209 JSList* 210 jack_slist_copy (JSList *list) 211 { 212 JSList *new_list = null; 213 214 if (list) { 215 JSList *last; 216 217 new_list = jack_slist_alloc (); 218 new_list.data = list.data; 219 last = new_list; 220 list = list.next; 221 while (list) { 222 last.next = jack_slist_alloc (); 223 last = last.next; 224 last.data = list.data; 225 list = list.next; 226 } 227 } 228 229 return new_list; 230 } 231 232 // pragma(inline, true) 233 static 234 JSList* 235 jack_slist_append (JSList *list, 236 void *data) 237 { 238 JSList *new_list; 239 JSList *last; 240 241 new_list = jack_slist_alloc (); 242 new_list.data = data; 243 244 if (list) { 245 last = jack_slist_last (list); 246 last.next = new_list; 247 248 return list; 249 } else 250 return new_list; 251 } 252 253 // pragma(inline, true) 254 static 255 JSList* 256 jack_slist_sort_merge (JSList *l1, 257 JSList *l2, 258 JCompareFunc compare_func) 259 { 260 JSList list; 261 JSList *l; 262 263 l = &list; 264 265 while (l1 && l2) { 266 if (compare_func(l1.data, l2.data) < 0) { 267 l = l.next = l1; 268 l1 = l1.next; 269 } else { 270 l = l.next = l2; 271 l2 = l2.next; 272 } 273 } 274 l.next = l1 ? l1 : l2; 275 276 return list.next; 277 } 278 279 // pragma(inline, true) 280 static 281 JSList* 282 jack_slist_sort (JSList *list, 283 JCompareFunc compare_func) 284 { 285 JSList *l1; 286 JSList *l2; 287 288 if (!list) 289 return null; 290 if (!list.next) 291 return list; 292 293 l1 = list; 294 l2 = list.next; 295 296 while ((l2 = l2.next) != null) { 297 if ((l2 = l2.next) == null) 298 break; 299 l1 = l1.next; 300 } 301 l2 = l1.next; 302 l1.next = null; 303 304 return jack_slist_sort_merge (jack_slist_sort (list, compare_func), 305 jack_slist_sort (l2, compare_func), 306 compare_func); 307 } 308 309 }