xref: /Universal-ctags/main/numarray.c (revision 4a710c0604fbbe64391d3402768a8c237a1838b4)
14ecf7bb9SMasatake YAMATO /*
24ecf7bb9SMasatake YAMATO *   Copyright (c) 1999-2002, Darren Hiebert
34ecf7bb9SMasatake YAMATO *
44ecf7bb9SMasatake YAMATO *   This source code is released for free distribution under the terms of the
54ecf7bb9SMasatake YAMATO *   GNU General Public License version 2 or (at your option) any later version.
64ecf7bb9SMasatake YAMATO *
74ecf7bb9SMasatake YAMATO *   This module contains functions managing resizable pointer arrays.
84ecf7bb9SMasatake YAMATO */
94ecf7bb9SMasatake YAMATO 
104ecf7bb9SMasatake YAMATO /*
114ecf7bb9SMasatake YAMATO *   INCLUDE FILES
124ecf7bb9SMasatake YAMATO */
134ecf7bb9SMasatake YAMATO #include "general.h"  /* must always come first */
144ecf7bb9SMasatake YAMATO 
154ecf7bb9SMasatake YAMATO #include "debug.h"
164ecf7bb9SMasatake YAMATO #include "numarray.h"
1714781660SMasatake YAMATO #include "routines.h"
184ecf7bb9SMasatake YAMATO 
1921ba4f38SMasatake YAMATO #include <stdlib.h>
2021ba4f38SMasatake YAMATO #include <string.h>
214ecf7bb9SMasatake YAMATO 
224ecf7bb9SMasatake YAMATO #define impNumArray(prefix,Prefix,type)									\
234ecf7bb9SMasatake YAMATO 																		\
244ecf7bb9SMasatake YAMATO 	struct s##Prefix##Array {											\
254ecf7bb9SMasatake YAMATO 		unsigned int max;												\
264ecf7bb9SMasatake YAMATO 		unsigned int count;												\
274ecf7bb9SMasatake YAMATO 		type *array;													\
284ecf7bb9SMasatake YAMATO 	};																	\
294ecf7bb9SMasatake YAMATO 																		\
304ecf7bb9SMasatake YAMATO 	extern prefix##Array *prefix##ArrayNew (void)						\
314ecf7bb9SMasatake YAMATO 	{																	\
324ecf7bb9SMasatake YAMATO 		prefix##Array* const result = xMalloc (1, prefix##Array);		\
334ecf7bb9SMasatake YAMATO 		result->max = 8;												\
344ecf7bb9SMasatake YAMATO 		result->count = 0;												\
354ecf7bb9SMasatake YAMATO 		result->array = xMalloc (result->max, type);					\
364ecf7bb9SMasatake YAMATO 		return result;													\
374ecf7bb9SMasatake YAMATO 	}																	\
384ecf7bb9SMasatake YAMATO 																		\
39b47ea137SMasatake YAMATO 	extern unsigned int prefix##ArrayAdd (prefix##Array *const current, type num) \
404ecf7bb9SMasatake YAMATO 	{																	\
414ecf7bb9SMasatake YAMATO 		Assert (current != NULL);										\
424ecf7bb9SMasatake YAMATO 		if (current->count == current->max)								\
434ecf7bb9SMasatake YAMATO 		{																\
444ecf7bb9SMasatake YAMATO 			current->max *= 2;											\
454ecf7bb9SMasatake YAMATO 			current->array = xRealloc (current->array, current->max, type);	\
464ecf7bb9SMasatake YAMATO 		}																\
47b47ea137SMasatake YAMATO 		current->array [current->count] = num;							\
48b47ea137SMasatake YAMATO 		return current->count++;										\
494ecf7bb9SMasatake YAMATO 	}																	\
504ecf7bb9SMasatake YAMATO 																		\
514ecf7bb9SMasatake YAMATO 	extern void prefix##ArrayRemoveLast (prefix##Array *const current)	\
524ecf7bb9SMasatake YAMATO 	{																	\
534ecf7bb9SMasatake YAMATO 		Assert (current != NULL);										\
544ecf7bb9SMasatake YAMATO 		Assert (current->count > 0);									\
554ecf7bb9SMasatake YAMATO 		--current->count;												\
564ecf7bb9SMasatake YAMATO 	}																	\
574ecf7bb9SMasatake YAMATO 																		\
584ecf7bb9SMasatake YAMATO 	extern void prefix##ArrayCombine (prefix##Array *const current, prefix##Array *const from) \
594ecf7bb9SMasatake YAMATO 	{																	\
604ecf7bb9SMasatake YAMATO 		unsigned int i;													\
614ecf7bb9SMasatake YAMATO 		Assert (current != NULL);										\
624ecf7bb9SMasatake YAMATO 		Assert (from != NULL);											\
634ecf7bb9SMasatake YAMATO 		for (i = 0  ;  i < from->count  ;  ++i)							\
644ecf7bb9SMasatake YAMATO 			prefix##ArrayAdd (current, from->array [i]);				\
654ecf7bb9SMasatake YAMATO 		from->count = 0;												\
664ecf7bb9SMasatake YAMATO 		prefix##ArrayDelete (from);										\
674ecf7bb9SMasatake YAMATO 	}																	\
684ecf7bb9SMasatake YAMATO 																		\
694ecf7bb9SMasatake YAMATO 	extern unsigned int prefix##ArrayCount (const prefix##Array *const current)	\
704ecf7bb9SMasatake YAMATO 	{																	\
714ecf7bb9SMasatake YAMATO 		Assert (current != NULL);										\
724ecf7bb9SMasatake YAMATO 		return current->count;											\
734ecf7bb9SMasatake YAMATO 	}																	\
744ecf7bb9SMasatake YAMATO 																		\
75090f0bb7SMasatake YAMATO 	extern bool prefix##ArrayIsEmpty (const prefix##Array *const current)	\
76090f0bb7SMasatake YAMATO 	{																	\
77090f0bb7SMasatake YAMATO 		return (prefix##ArrayCount(current) == 0);						\
78090f0bb7SMasatake YAMATO 	}																	\
79090f0bb7SMasatake YAMATO 																		\
804ecf7bb9SMasatake YAMATO 	extern type prefix##ArrayItem (const prefix##Array *const current, const unsigned int indx)	\
814ecf7bb9SMasatake YAMATO 	{																	\
824ecf7bb9SMasatake YAMATO 		Assert (current != NULL);										\
834ecf7bb9SMasatake YAMATO 		return current->array [indx];									\
844ecf7bb9SMasatake YAMATO 	}																	\
854ecf7bb9SMasatake YAMATO 																		\
864ecf7bb9SMasatake YAMATO 	extern type prefix##ArrayLast (const prefix##Array *const current)	\
874ecf7bb9SMasatake YAMATO 	{																	\
884ecf7bb9SMasatake YAMATO 		Assert (current != NULL);										\
894ecf7bb9SMasatake YAMATO 		Assert (current->count > 0);									\
904ecf7bb9SMasatake YAMATO 		return current->array [current->count - 1];						\
914ecf7bb9SMasatake YAMATO 	}																	\
924ecf7bb9SMasatake YAMATO 																		\
934ecf7bb9SMasatake YAMATO 	extern void prefix##ArrayClear (prefix##Array *const current)		\
944ecf7bb9SMasatake YAMATO 	{																	\
954ecf7bb9SMasatake YAMATO 		Assert (current != NULL);										\
964ecf7bb9SMasatake YAMATO 		current->count = 0;												\
974ecf7bb9SMasatake YAMATO 	}																	\
984ecf7bb9SMasatake YAMATO 																		\
994ecf7bb9SMasatake YAMATO 	extern void prefix##ArrayDelete (prefix##Array *const current)		\
1004ecf7bb9SMasatake YAMATO 	{																	\
1014ecf7bb9SMasatake YAMATO 		if (current != NULL)											\
1024ecf7bb9SMasatake YAMATO 		{																\
1034ecf7bb9SMasatake YAMATO 			prefix##ArrayClear (current);								\
1044ecf7bb9SMasatake YAMATO 			eFree (current->array);										\
1054ecf7bb9SMasatake YAMATO 			eFree (current);											\
1064ecf7bb9SMasatake YAMATO 		}																\
1074ecf7bb9SMasatake YAMATO 	}																	\
1084ecf7bb9SMasatake YAMATO 																		\
1094ecf7bb9SMasatake YAMATO 	extern bool prefix##ArrayHasTest (const prefix##Array *const current, \
1104ecf7bb9SMasatake YAMATO 									  bool (*test)(const type num, void *userData),	\
1114ecf7bb9SMasatake YAMATO 									  void *userData)					\
1124ecf7bb9SMasatake YAMATO 	{																	\
1134ecf7bb9SMasatake YAMATO 		bool result = false;											\
1144ecf7bb9SMasatake YAMATO 		unsigned int i;													\
1154ecf7bb9SMasatake YAMATO 		Assert (current != NULL);										\
1164ecf7bb9SMasatake YAMATO 		for (i = 0  ;  ! result  &&  i < current->count  ;  ++i)		\
1174ecf7bb9SMasatake YAMATO 			result = (*test)(current->array [i], userData);				\
1184ecf7bb9SMasatake YAMATO 		return result;													\
1194ecf7bb9SMasatake YAMATO 	}																	\
1204ecf7bb9SMasatake YAMATO 																		\
1214ecf7bb9SMasatake YAMATO 	static bool prefix##Eq (const type num, void *userData)				\
1224ecf7bb9SMasatake YAMATO 	{																	\
1234ecf7bb9SMasatake YAMATO 		type *num0 = userData;											\
1244ecf7bb9SMasatake YAMATO 		return (num == *num0);											\
1254ecf7bb9SMasatake YAMATO 	}																	\
1264ecf7bb9SMasatake YAMATO 																		\
1274ecf7bb9SMasatake YAMATO 	extern bool prefix##ArrayHas (const prefix##Array *const current, type num)	\
1284ecf7bb9SMasatake YAMATO 	{																	\
1294ecf7bb9SMasatake YAMATO 		return prefix##ArrayHasTest (current, prefix##Eq, &num);		\
1304ecf7bb9SMasatake YAMATO 	}																	\
1314ecf7bb9SMasatake YAMATO 																		\
1324ecf7bb9SMasatake YAMATO 	extern void prefix##ArrayReverse (const prefix##Array *const current) \
1334ecf7bb9SMasatake YAMATO 	{																	\
1344ecf7bb9SMasatake YAMATO 		unsigned int i, j;												\
1354ecf7bb9SMasatake YAMATO 		type tmp;														\
1364ecf7bb9SMasatake YAMATO 																		\
1374ecf7bb9SMasatake YAMATO 		Assert (current != NULL);										\
1384ecf7bb9SMasatake YAMATO 		for (i = 0, j = current->count - 1 ; i <  (current->count / 2); ++i, --j) \
1394ecf7bb9SMasatake YAMATO 		{																\
1404ecf7bb9SMasatake YAMATO 			tmp = current->array[i];									\
1414ecf7bb9SMasatake YAMATO 			current->array[i] = current->array[j];						\
1424ecf7bb9SMasatake YAMATO 			current->array[j] = tmp;									\
1434ecf7bb9SMasatake YAMATO 		}																\
1444ecf7bb9SMasatake YAMATO 	}																	\
1454ecf7bb9SMasatake YAMATO 																		\
1464ecf7bb9SMasatake YAMATO 	extern void prefix##ArrayDeleteItem (prefix##Array* const current, unsigned int indx) \
1474ecf7bb9SMasatake YAMATO 	{																	\
1484ecf7bb9SMasatake YAMATO 		memmove (current->array + indx, current->array + indx + 1,		\
149*4a710c06SHideki IWAMOTO 				 (current->count - indx - 1) * sizeof (*current->array)); \
1504ecf7bb9SMasatake YAMATO 		--current->count;												\
1514ecf7bb9SMasatake YAMATO 	}																	\
1524ecf7bb9SMasatake YAMATO 	static int prefix##GreaterThan(const void *a, const void *b)		\
1534ecf7bb9SMasatake YAMATO     {																	\
1544ecf7bb9SMasatake YAMATO 		type an = *(type *)a;											\
1554ecf7bb9SMasatake YAMATO 		type bn = *(type *)b;											\
1564ecf7bb9SMasatake YAMATO 		if (an > bn)													\
1574ecf7bb9SMasatake YAMATO 			return 1;													\
1584ecf7bb9SMasatake YAMATO 		else if (an == bn)												\
1594ecf7bb9SMasatake YAMATO 			return 0;													\
1604ecf7bb9SMasatake YAMATO 		else															\
1614ecf7bb9SMasatake YAMATO 			return -1;													\
1624ecf7bb9SMasatake YAMATO 	}																	\
1634ecf7bb9SMasatake YAMATO 	static int prefix##LessThan(const void *a, const void *b)			\
1644ecf7bb9SMasatake YAMATO 	{																	\
1654ecf7bb9SMasatake YAMATO 		return prefix##GreaterThan (b, a);								\
1664ecf7bb9SMasatake YAMATO 	}																	\
1674ecf7bb9SMasatake YAMATO 	extern void prefix##ArraySort (prefix##Array *const current, bool descendingOrder) \
1684ecf7bb9SMasatake YAMATO 	{																	\
1694ecf7bb9SMasatake YAMATO 		if (descendingOrder)											\
1704ecf7bb9SMasatake YAMATO 			qsort (current->array, current->count, sizeof (type), prefix##GreaterThan); \
1714ecf7bb9SMasatake YAMATO 		else															\
1724ecf7bb9SMasatake YAMATO 			qsort (current->array, current->count, sizeof (type), prefix##LessThan); \
1734ecf7bb9SMasatake YAMATO 	}
1744ecf7bb9SMasatake YAMATO 
1754ecf7bb9SMasatake YAMATO /* We expect the linker we use is enough clever to delete dead code. */
176e4f99c14SColomban Wendling impNumArray(char, Char, char)
177e4f99c14SColomban Wendling impNumArray(uchar, Uchar, unsigned char)
178e4f99c14SColomban Wendling impNumArray(int, Int, int)
179e4f99c14SColomban Wendling impNumArray(uint, Uint, unsigned int)
180e4f99c14SColomban Wendling impNumArray(long, Long, long)
181e4f99c14SColomban Wendling impNumArray(ulong, Ulong, unsigned long)
182