18fe18cbdSespie #ifndef GARRAY_H 28fe18cbdSespie #define GARRAY_H 38fe18cbdSespie 4*85e3ecf0Sespie /* $OpenBSD: garray.h,v 1.10 2019/12/22 16:53:40 espie Exp $ */ 58fe18cbdSespie /* Growable array implementation */ 68fe18cbdSespie 78fe18cbdSespie /* 88fe18cbdSespie * Copyright (c) 2001 Marc Espie. 98fe18cbdSespie * 108fe18cbdSespie * Redistribution and use in source and binary forms, with or without 118fe18cbdSespie * modification, are permitted provided that the following conditions 128fe18cbdSespie * are met: 138fe18cbdSespie * 1. Redistributions of source code must retain the above copyright 148fe18cbdSespie * notice, this list of conditions and the following disclaimer. 158fe18cbdSespie * 2. Redistributions in binary form must reproduce the above copyright 168fe18cbdSespie * notice, this list of conditions and the following disclaimer in the 178fe18cbdSespie * documentation and/or other materials provided with the distribution. 188fe18cbdSespie * 198fe18cbdSespie * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS 208fe18cbdSespie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 218fe18cbdSespie * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 228fe18cbdSespie * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD 238fe18cbdSespie * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 248fe18cbdSespie * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 258fe18cbdSespie * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 268fe18cbdSespie * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 278fe18cbdSespie * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 288fe18cbdSespie * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 298fe18cbdSespie * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 308fe18cbdSespie */ 318fe18cbdSespie 328fe18cbdSespie struct growableArray { 338fe18cbdSespie GNode **a; /* Only used for gnodes right now */ 348fe18cbdSespie unsigned int size; /* Total max size */ 358fe18cbdSespie unsigned int n; /* Current number of members */ 368fe18cbdSespie }; 378fe18cbdSespie 388fe18cbdSespie #define AppendList2Array(l1, l2) \ 398fe18cbdSespie do { \ 408fe18cbdSespie LstNode ln; \ 418fe18cbdSespie for (ln = Lst_First((l1)); ln != NULL; ln = Lst_Adv(ln))\ 428fe18cbdSespie Array_AtEnd((l2), Lst_Datum(ln)); \ 438fe18cbdSespie } while (0) 448fe18cbdSespie 458fe18cbdSespie #ifdef STATS_GROW 468fe18cbdSespie #define MAY_INCREASE_STATS STAT_GROWARRAY++ 478fe18cbdSespie #else 488fe18cbdSespie #define MAY_INCREASE_STATS 498fe18cbdSespie #endif 508fe18cbdSespie 518fe18cbdSespie #define Array_AtEnd(l, gn) \ 528fe18cbdSespie do { \ 538fe18cbdSespie if ((l)->n >= (l)->size) { \ 548fe18cbdSespie (l)->size *= 2; \ 55e2ff9f51Sespie (l)->a = ereallocarray((l)->a, \ 5675d77f2cSespie (l)->size, sizeof(struct GNode *)); \ 578fe18cbdSespie MAY_INCREASE_STATS; \ 588fe18cbdSespie } \ 598fe18cbdSespie (l)->a[(l)->n++] = (gn); \ 608fe18cbdSespie } while (0) 618fe18cbdSespie 622fdf4822Sespie #define Array_Push(l, gn) Array_AtEnd(l, gn) 632fdf4822Sespie 642fdf4822Sespie #define Array_Pop(l) \ 652fdf4822Sespie ((l)->n > 0 ? (l)->a[--(l)->n] : NULL) 662fdf4822Sespie 672fdf4822Sespie #define Array_PushNew(l, gn) \ 682fdf4822Sespie do { \ 692fdf4822Sespie unsigned int i; \ 702fdf4822Sespie for (i = 0; i < (l)->n; i++) \ 712fdf4822Sespie if ((l)->a[i] == (gn)) \ 722fdf4822Sespie break; \ 732fdf4822Sespie if (i == (l)->n) \ 742fdf4822Sespie Array_Push(l, gn); \ 752fdf4822Sespie } while (0) 762fdf4822Sespie 778fe18cbdSespie #define Array_Find(l, func, v) \ 788fe18cbdSespie do { \ 798fe18cbdSespie unsigned int i; \ 808fe18cbdSespie for (i = 0; i < (l)->n; i++) \ 818fe18cbdSespie if ((func)((l)->a[i], (v)) == 0)\ 828fe18cbdSespie break; \ 838fe18cbdSespie } while (0) 848fe18cbdSespie 85981d9684Sespie #define Array_FindP(l, func, v) \ 86981d9684Sespie do { \ 87981d9684Sespie unsigned int i; \ 88981d9684Sespie for (i = 0; i < (l)->n; i++) \ 89981d9684Sespie if ((func)(&((l)->a[i]), (v)) == 0) \ 90981d9684Sespie break; \ 91981d9684Sespie } while (0) 92981d9684Sespie 938fe18cbdSespie #define Array_ForEach(l, func, v) \ 948fe18cbdSespie do { \ 958fe18cbdSespie unsigned int i; \ 968fe18cbdSespie for (i = 0; i < (l)->n; i++) \ 978fe18cbdSespie (func)((l)->a[i], (v)); \ 988fe18cbdSespie } while (0) 998fe18cbdSespie 1008fe18cbdSespie #define Array_Every(l, func) \ 1018fe18cbdSespie do { \ 1028fe18cbdSespie unsigned int i; \ 1038fe18cbdSespie for (i = 0; i < (l)->n; i++) \ 1048fe18cbdSespie (func)((l)->a[i]); \ 1058fe18cbdSespie } while (0) 1068fe18cbdSespie 1078fe18cbdSespie #define Array_Init(l, sz) \ 1088fe18cbdSespie do { \ 1098fe18cbdSespie (l)->size = (sz); \ 1108fe18cbdSespie (l)->n = 0; \ 11177c73da2Sespie (l)->a = ereallocarray(NULL, (l)->size, sizeof(GNode *)); \ 1128fe18cbdSespie } while (0) 1138fe18cbdSespie 1148fe18cbdSespie #define Array_Reset(l) \ 1158fe18cbdSespie do { \ 1168fe18cbdSespie (l)->n = 0; \ 1178fe18cbdSespie } while (0) 1188fe18cbdSespie 1198fe18cbdSespie #define Array_IsEmpty(l) ((l)->n == 0) 1208fe18cbdSespie 1218fe18cbdSespie #endif 122