xref: /openbsd-src/usr.bin/make/garray.h (revision 85e3ecf017a4bed648f62d06d079d98c632ca25d)
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