1 #ifndef GARRAY_H 2 #define GARRAY_H 3 4 /* $OpenPackages$ */ 5 /* $OpenBSD: garray.h,v 1.4 2007/12/01 15:14:34 espie Exp $ */ 6 /* Growable array implementation */ 7 8 /* 9 * Copyright (c) 2001 Marc Espie. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD 24 * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 struct growableArray { 34 GNode **a; /* Only used for gnodes right now */ 35 unsigned int size; /* Total max size */ 36 unsigned int n; /* Current number of members */ 37 }; 38 39 #define AppendList2Array(l1, l2) \ 40 do { \ 41 LstNode ln; \ 42 for (ln = Lst_First((l1)); ln != NULL; ln = Lst_Adv(ln))\ 43 Array_AtEnd((l2), Lst_Datum(ln)); \ 44 } while (0) 45 46 #ifdef STATS_GROW 47 #define MAY_INCREASE_STATS STAT_GROWARRAY++ 48 #else 49 #define MAY_INCREASE_STATS 50 #endif 51 52 #define Array_AtEnd(l, gn) \ 53 do { \ 54 if ((l)->n >= (l)->size) { \ 55 (l)->size *= 2; \ 56 (l)->a = erealloc((l)->a, \ 57 sizeof(struct GNode *) * (l)->size);\ 58 MAY_INCREASE_STATS; \ 59 } \ 60 (l)->a[(l)->n++] = (gn); \ 61 } while (0) 62 63 #define Array_Push(l, gn) Array_AtEnd(l, gn) 64 65 #define Array_Pop(l) \ 66 ((l)->n > 0 ? (l)->a[--(l)->n] : NULL) 67 68 #define Array_PushNew(l, gn) \ 69 do { \ 70 unsigned int i; \ 71 for (i = 0; i < (l)->n; i++) \ 72 if ((l)->a[i] == (gn)) \ 73 break; \ 74 if (i == (l)->n) \ 75 Array_Push(l, gn); \ 76 } while (0) 77 78 #define Array_Find(l, func, v) \ 79 do { \ 80 unsigned int i; \ 81 for (i = 0; i < (l)->n; i++) \ 82 if ((func)((l)->a[i], (v)) == 0)\ 83 break; \ 84 } while (0) 85 86 #define Array_FindP(l, func, v) \ 87 do { \ 88 unsigned int i; \ 89 for (i = 0; i < (l)->n; i++) \ 90 if ((func)(&((l)->a[i]), (v)) == 0) \ 91 break; \ 92 } while (0) 93 94 #define Array_ForEach(l, func, v) \ 95 do { \ 96 unsigned int i; \ 97 for (i = 0; i < (l)->n; i++) \ 98 (func)((l)->a[i], (v)); \ 99 } while (0) 100 101 #define Array_Every(l, func) \ 102 do { \ 103 unsigned int i; \ 104 for (i = 0; i < (l)->n; i++) \ 105 (func)((l)->a[i]); \ 106 } while (0) 107 108 #define Array_Init(l, sz) \ 109 do { \ 110 (l)->size = (sz); \ 111 (l)->n = 0; \ 112 (l)->a = emalloc(sizeof(GNode *) * (l)->size); \ 113 } while (0) 114 115 #define Array_Reset(l) \ 116 do { \ 117 (l)->n = 0; \ 118 } while (0) 119 120 #define Array_IsEmpty(l) ((l)->n == 0) 121 122 #endif 123