aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_common.h50
-rw-r--r--src/util/test_common_allocation.c26
2 files changed, 67 insertions, 9 deletions
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index fcc510ec9..033a68894 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -1392,22 +1392,58 @@ GNUNET_is_zero_ (const void *a,
1392 1392
1393/** 1393/**
1394 * @ingroup memory 1394 * @ingroup memory
1395 * Append an element to a list (growing the list by one). 1395 * Append an element to an array (growing the array by one).
1396 * 1396 *
1397 * @param arr base-pointer of the vector, may be NULL if size is 0; 1397 * @param arr base-pointer of the vector, may be NULL if @a len is 0;
1398 * will be updated to reflect the new address. The TYPE of 1398 * will be updated to reflect the new address. The TYPE of
1399 * arr is important since size is the number of elements and 1399 * arr is important since size is the number of elements and
1400 * not the size in bytes 1400 * not the size in bytes
1401 * @param size the number of elements in the existing vector (number 1401 * @param len the number of elements in the existing vector (number
1402 * of elements to copy over), will be updated with the new 1402 * of elements to copy over), will be updated with the new
1403 * array size 1403 * array length
1404 * @param element the element that will be appended to the array 1404 * @param element the element that will be appended to the array
1405 */ 1405 */
1406#define GNUNET_array_append(arr, size, element) \ 1406#define GNUNET_array_append(arr, len, element) \
1407 do \
1408 { \
1409 GNUNET_assert ((len) + 1 > (len)); \
1410 GNUNET_array_grow (arr, len, len + 1); \
1411 (arr) [len - 1] = element; \
1412 } while (0)
1413
1414
1415/**
1416 * @ingroup memory
1417 * Append @a arr2 to @a arr1 (growing @a arr1
1418 * as needed). The @a arr2 array is left unchanged. Naturally
1419 * this function performs a shallow copy. Both arrays must have
1420 * the same type for their elements.
1421 *
1422 * @param arr1 base-pointer of the vector, may be NULL if @a len is 0;
1423 * will be updated to reflect the new address. The TYPE of
1424 * arr is important since size is the number of elements and
1425 * not the size in bytes
1426 * @param len1 the number of elements in the existing vector (number
1427 * of elements to copy over), will be updated with the new
1428 * array size
1429 * @param arr2 base-pointer a second array to concatenate, may be NULL if @a len2 is 0;
1430 * will be updated to reflect the new address. The TYPE of
1431 * arr is important since size is the number of elements and
1432 * not the size in bytes
1433 * @param len the number of elements in the existing vector (number
1434 * of elements to copy over), will be updated with the new
1435 * array size
1436
1437 */
1438#define GNUNET_array_concatenate(arr1, len1, arr2, len2) \
1407 do \ 1439 do \
1408 { \ 1440 { \
1409 GNUNET_array_grow (arr, size, size + 1); \ 1441 const typeof (*arr2) * _a1 = (arr1); \
1410 (arr) [size - 1] = element; \ 1442 const typeof (*arr1) * _a2 = (arr2); \
1443 GNUNET_assert ((len1) + (len2) >= (len1)); \
1444 GNUNET_assert (SIZE_MAX / sizeof (*_a1) >= ((len1) + (len2))); \
1445 GNUNET_array_grow (arr1, len1, (len1) + (len2)); \
1446 memcpy (&(arr1) [(len1) - (len2)], _a2, (len2) * sizeof (*arr1)); \
1411 } while (0) 1447 } while (0)
1412 1448
1413/** 1449/**
diff --git a/src/util/test_common_allocation.c b/src/util/test_common_allocation.c
index e2fc29e82..a24af7124 100644
--- a/src/util/test_common_allocation.c
+++ b/src/util/test_common_allocation.c
@@ -27,7 +27,7 @@
27 27
28 28
29static int 29static int
30check () 30check (void)
31{ 31{
32#define MAX_TESTVAL 1024 32#define MAX_TESTVAL 1024
33 char *ptrs[MAX_TESTVAL]; 33 char *ptrs[MAX_TESTVAL];
@@ -134,6 +134,28 @@ check ()
134} 134}
135 135
136 136
137static int
138check2 (void)
139{
140 char *a1 = NULL;
141 unsigned int a1_len = 0;
142 const char *a2 = "test";
143
144 GNUNET_array_append (a1,
145 a1_len,
146 'x');
147 GNUNET_array_concatenate (a1,
148 a1_len,
149 a2,
150 4);
151 GNUNET_assert (0 == strncmp ("xtest",
152 a1,
153 5));
154 GNUNET_assert (5 == a1_len);
155 return 0;
156}
157
158
137int 159int
138main (int argc, char *argv[]) 160main (int argc, char *argv[])
139{ 161{
@@ -142,7 +164,7 @@ main (int argc, char *argv[])
142 GNUNET_log_setup ("test-common-allocation", 164 GNUNET_log_setup ("test-common-allocation",
143 "WARNING", 165 "WARNING",
144 NULL); 166 NULL);
145 ret = check (); 167 ret = check () | check2 ();
146 if (ret != 0) 168 if (ret != 0)
147 fprintf (stderr, 169 fprintf (stderr,
148 "ERROR %d.\n", 170 "ERROR %d.\n",