diff options
-rw-r--r-- | src/include/gnunet_common.h | 50 | ||||
-rw-r--r-- | src/util/test_common_allocation.c | 26 |
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 | ||
29 | static int | 29 | static int |
30 | check () | 30 | check (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 | ||
137 | static int | ||
138 | check2 (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 | |||
137 | int | 159 | int |
138 | main (int argc, char *argv[]) | 160 | main (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", |