merge the formfield patch from ooo-build
[ooovba.git] / vcl / source / fontsubset / list.c
blob63c40f624135b9729e2622f3bd2412a955a6b07d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 /*[]---------------------------------------------------[]*/
29 /*| |*/
30 /*| list.c - bidirectional list class |*/
31 /*| |*/
32 /*| |*/
33 /*| Author: Alexander Gelfenbain |*/
34 /*[]---------------------------------------------------[]*/
36 #include <stdlib.h>
38 #if OSL_DEBUG_LEVEL == 0
39 # ifndef NDEBUG
40 # define NDEBUG
41 # endif
42 #endif
44 #include <assert.h>
46 #ifdef MALLOC_TRACE
47 #include <stdio.h>
48 #include </usr/local/include/malloc.h>
49 #endif
50 /* #define TEST */
51 #include "list.h"
53 /*- private data types */
54 typedef struct _lnode {
55 struct _lnode *next;
56 struct _lnode *prev;
58 void *value;
60 } lnode;
62 struct _list {
63 lnode *head, *tail, *cptr;
64 size_t aCount;
65 list_destructor eDtor;
68 /*- private methods */
70 static lnode *newNode(void *el)
72 lnode *ptr = malloc(sizeof(lnode));
73 assert(ptr != 0);
75 ptr->value = el;
77 return ptr;
80 static lnode *appendPrim(list this, void *el)
82 lnode *ptr = newNode(el);
83 lnode **flink, *blink;
85 if (this->tail != 0) {
86 flink = &(this->tail->next);
87 blink = this->tail;
88 } else {
89 flink = &this->head;
90 blink = 0;
91 this->cptr = ptr; /*- list was empty - set current to this element */
94 *flink = ptr;
95 this->tail = ptr;
97 ptr->prev = blink;
98 ptr->next = 0;
100 this->aCount++;
101 return ptr;
103 #ifdef TEST
104 static lnode *prependPrim(list this, void *el)
106 lnode *ptr = newNode(el);
107 lnode *flink, **blink;
109 if (this->head != 0) {
110 blink = &(this->head->prev);
111 flink = this->head;
112 } else {
113 blink = &this->tail;
114 flink = 0;
115 this->cptr = ptr; /*- list was empty - set current to this element */
118 *blink = ptr;
119 this->head = ptr;
121 ptr->next = flink;
122 ptr->prev = 0;
124 this->aCount++;
125 return ptr;
127 #endif
129 /*- public methods */
130 list listNewEmpty(void) /*- default ctor */
132 list this = malloc(sizeof(struct _list));
133 assert(this != 0);
135 this->aCount = 0;
136 this->eDtor = 0;
137 this->head = this->tail = this->cptr = 0;
139 return this;
142 #ifdef TEST
143 list listNewCopy(list l) /*- copy ctor */
145 lnode *ptr, *c;
146 list this;
147 assert(l != 0);
149 this = malloc(sizeof(struct _list));
150 assert(this != 0);
152 ptr = l->head;
154 this->aCount = 0;
155 this->eDtor = 0;
156 this->head = this->tail = this->cptr = 0;
158 while (ptr) {
159 c = appendPrim(this, ptr->value);
160 if (ptr == l->cptr) this->cptr = c;
161 ptr = ptr->next;
164 return this;
166 #endif
168 void listDispose(list this) /*- dtor */
170 assert(this != 0);
171 listClear(this);
172 free(this);
175 void listSetElementDtor(list this, list_destructor f)
177 assert(this != 0);
178 this->eDtor = f;
181 /* calling this function on an empty list is a run-time error */
182 void *listCurrent(list this)
184 assert(this != 0);
185 assert(this->cptr != 0);
186 return this->cptr->value;
189 int listCount(list this)
191 assert(this != 0);
192 return this->aCount;
195 int listIsEmpty(list this)
197 assert(this != 0);
198 return this->aCount == 0;
202 #ifdef TEST
203 int listAtFirst(list this)
205 assert(this != 0);
206 return this->cptr == this->head;
209 int listAtLast(list this)
211 assert(this != 0);
212 return this->cptr == this->tail;
215 int listPosition(list this)
217 int res = 0;
218 lnode *ptr;
219 assert(this != 0);
221 ptr = this->head;
223 while (ptr != this->cptr) {
224 ptr = ptr->next;
225 res++;
228 return res;
230 #endif
231 int listFind(list this, void *el)
233 lnode *ptr;
234 assert(this != 0);
236 ptr = this->head;
238 while (ptr) {
239 if (ptr->value == el) {
240 this->cptr = ptr;
241 return 1;
243 ptr = ptr->next;
246 return 0;
249 int listNext(list this)
251 return listSkipForward(this, 1);
254 int listSkipForward(list this, int n)
256 int m = 0;
257 assert(this != 0);
259 if (this->cptr == 0) return 0;
261 while (n != 0) {
262 if (this->cptr->next == 0) break;
263 this->cptr = this->cptr->next;
264 n--;
265 m++;
267 return m;
270 int listToFirst(list this)
272 assert(this != 0);
274 if (this->cptr != this->head) {
275 this->cptr = this->head;
276 return 1;
278 return 0;
281 int listToLast(list this)
283 assert(this != 0);
285 if (this->cptr != this->tail) {
286 this->cptr = this->tail;
287 return 1;
289 return 0;
292 int listPositionAt(list this, int n) /*- returns the actual position number */
294 int m = 0;
295 assert(this != 0);
297 this->cptr = this->head;
298 while (n != 0) {
299 if (this->cptr->next == 0) break;
300 this->cptr = this->cptr->next;
301 n--;
302 m++;
304 return m;
307 list listAppend(list this, void *el)
309 assert(this != 0);
311 appendPrim(this, el);
312 return this;
314 #ifdef TEST
315 list listPrepend(list this, void *el)
317 assert(this != 0);
319 prependPrim(this, el);
320 return this;
323 list listInsertAfter(list this, void *el)
325 lnode *ptr;
326 assert(this != 0);
328 if (this->cptr == 0) return listAppend(this, el);
330 ptr = newNode(el);
332 ptr->prev = this->cptr;
333 ptr->next = this->cptr->next;
334 this->cptr->next = ptr;
336 if (ptr->next != 0) {
337 ptr->next->prev = ptr;
338 } else {
339 this->tail = ptr;
341 this->aCount++;
342 return this;
345 list listInsertBefore(list this, void *el)
347 lnode *ptr;
348 assert(this != 0);
350 if (this->cptr == 0) return listAppend(this, el);
352 ptr = newNode(el);
354 ptr->prev = this->cptr->prev;
355 ptr->next = this->cptr;
356 this->cptr->prev = ptr;
358 if (ptr->prev != 0) {
359 ptr->prev->next = ptr;
360 } else {
361 this->head = ptr;
363 this->aCount++;
364 return this;
366 #endif
367 list listRemove(list this)
369 lnode *ptr = 0;
370 if (this->cptr == 0) return this;
372 if (this->cptr->next != 0) {
373 ptr = this->cptr->next;
374 this->cptr->next->prev = this->cptr->prev;
375 } else {
376 this->tail = this->cptr->prev;
379 if (this->cptr->prev != 0) {
380 if (ptr == 0) ptr = this->cptr->prev;
381 this->cptr->prev->next = this->cptr->next;
382 } else {
383 this->head = this->cptr->next;
386 if (this->eDtor) this->eDtor(this->cptr->value); /* call the dtor callback */
388 free(this->cptr);
389 this->aCount--;
390 this->cptr = ptr;
391 return this;
394 list listClear(list this)
396 lnode *node = this->head, *ptr;
398 while (node) {
399 ptr = node->next;
400 if (this->eDtor) this->eDtor(node->value); /* call the dtor callback */
401 free(node);
402 this->aCount--;
403 node = ptr;
406 this->head = this->tail = this->cptr = 0;
407 assert(this->aCount == 0);
408 return this;
411 #ifdef TEST
413 void listForAll(list this, void (*f)(void *))
415 lnode *ptr = this->head;
416 while (ptr) {
417 f(ptr->value);
418 ptr = ptr->next;
423 #include <stdio.h>
425 void printlist(list l)
427 int saved;
428 assert(l != 0);
429 saved = listPosition(l);
431 printf("[ ");
433 if (!listIsEmpty(l)) {
434 listToFirst(l);
435 do {
436 printf("%d ", (int) listCurrent(l));
437 } while (listNext(l));
440 printf("]\n");
442 listPositionAt(l, saved);
445 void printstringlist(list l)
447 int saved;
448 assert(l != 0);
449 saved = listPosition(l);
451 printf("[ ");
453 if (!listIsEmpty(l)) {
454 listToFirst(l);
455 do {
456 printf("'%s' ", (char *) listCurrent(l));
457 } while (listNext(l));
460 printf("]\n");
462 listPositionAt(l, saved);
465 void printstat(list l)
467 printf("count: %d, position: %d, isEmpty: %d, atFirst: %d, atLast: %d.\n",
468 listCount(l), listPosition(l), listIsEmpty(l), listAtFirst(l), listAtLast(l));
471 void allfunc(void *e)
473 printf("%d ", e);
476 void edtor(void *ptr)
478 printf("element dtor: 0x%08x\n", ptr);
479 free(ptr);
482 int main()
484 list l1, l2;
485 char *ptr;
486 int i;
488 #ifdef MALLOC_TRACE
489 mal_leaktrace(1);
490 mal_debug(2);
491 #endif
493 l1 = listNewEmpty();
494 printstat(l1);
496 listAppend(l1, 1);
497 printstat(l1);
499 listAppend(l1, 2);
500 printstat(l1);
502 listAppend(l1, 3);
503 printstat(l1);
505 printlist(l1);
507 listToFirst(l1);
508 listInsertBefore(l1, -5);
509 printlist(l1);
511 l2 = listNewCopy(l1);
512 printlist(l2);
514 listForAll(l2, allfunc);
515 printf("\n");
517 listClear(l1);
518 listSetElementDtor(l1, edtor);
520 for(i=0; i<10; i++) {
521 ptr = malloc(20);
522 snprintf(ptr, 20, "element # %d", i);
523 listAppend(l1, ptr);
526 printstringlist(l1);
529 listDispose(l1);
530 listDispose(l2);
532 #ifdef MALLOC_TRACE
533 mal_dumpleaktrace(stdout);
534 #endif
537 return 0;
539 #endif