|
1 /* |
|
2 * Hedgewars, a free turn based strategy game |
|
3 * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com> |
|
4 * |
|
5 * This program is free software; you can redistribute it and/or |
|
6 * modify it under the terms of the GNU General Public License |
|
7 * as published by the Free Software Foundation; either version 2 |
|
8 * of the License, or (at your option) any later version. |
|
9 * |
|
10 * This program is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 * GNU General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License |
|
16 * along with this program; if not, write to the Free Software |
|
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
18 */ |
|
19 |
|
20 /** |
|
21 * Simple dynamic array manipulation functions. |
|
22 */ |
|
23 |
|
24 #ifndef LIST_H_ |
|
25 #define LIST_H_ |
|
26 |
|
27 #include <stddef.h> |
|
28 #include <string.h> |
|
29 #include <stdlib.h> |
|
30 #include "util.h" |
|
31 #include "logging.h" |
|
32 |
|
33 /** |
|
34 * Generate a static function that inserts a new value into a heap array of the given type, |
|
35 * using realloc and memmove to increase the capacity and shift existing values. |
|
36 * The function takes a pointer to the array variable and a pointer to the size variable |
|
37 * because both can be changed by this operation (realloc / increment). |
|
38 * The function returns 0 on success and leaves the array unchanged on error. |
|
39 */ |
|
40 #define GENERATE_STATIC_LIST_INSERT(fname, type) \ |
|
41 static int fname(type **listptr, int *listSizePtr, type element, int pos) { \ |
|
42 int result = -1; \ |
|
43 if(!log_badargs_if4(listptr==NULL, listSizePtr==NULL, pos < 0, pos > *listSizePtr)) { \ |
|
44 type *newList = flib_realloc(*listptr, ((*listSizePtr)+1)*sizeof(type)); \ |
|
45 if(newList) { \ |
|
46 memmove(newList + (pos+1), newList + pos, ((*listSizePtr)-pos)*sizeof(type)); \ |
|
47 newList[pos] = element; \ |
|
48 (*listSizePtr)++; \ |
|
49 *listptr = newList; \ |
|
50 result = 0; \ |
|
51 } \ |
|
52 } \ |
|
53 return result; \ |
|
54 } |
|
55 |
|
56 /** |
|
57 * Generate a static function that deletes a value from a heap array of the given type, |
|
58 * using realloc and memmove to decrease the capacity and shift existing values. |
|
59 * The function takes a pointer to the array variable and a pointer to the size variable |
|
60 * because both can be changed by this operation (realloc / decrement). |
|
61 * The function returns 0 on success and leaves the array unchanged on error. |
|
62 */ |
|
63 #define GENERATE_STATIC_LIST_DELETE(fname, type) \ |
|
64 static int fname(type **listPtr, int *listSizePtr, int pos) { \ |
|
65 int result = -1; \ |
|
66 if(!log_badargs_if4(listPtr==NULL, listSizePtr==NULL, pos < 0, pos >= *listSizePtr)) { \ |
|
67 memmove((*listPtr) + pos, (*listPtr) + (pos+1), ((*listSizePtr)-(pos+1))*sizeof(type)); \ |
|
68 (*listSizePtr)--; \ |
|
69 \ |
|
70 size_t newCharSize = (*listSizePtr)*sizeof(type); \ |
|
71 type *newList = flib_realloc((*listPtr), newCharSize); \ |
|
72 if(newList || newCharSize==0) { \ |
|
73 (*listPtr) = newList; \ |
|
74 } /* If the realloc fails, just keep using the old buffer...*/ \ |
|
75 result = 0; \ |
|
76 } \ |
|
77 return result; \ |
|
78 } |
|
79 |
|
80 #endif /* LIST_H_ */ |