libyang  3.1.0
libyang is YANG data modelling language parser and toolkit written (and providing API) in C.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tree_edit.h
Go to the documentation of this file.
1 
16 #ifndef LY_TREE_EDIT_H_
17 #define LY_TREE_EDIT_H_
18 
19 #include <stdlib.h>
20 
21 #ifndef LOGMEM
22 #define LOGMEM(CTX)
23 #endif
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
38 void *ly_realloc(void *ptr, size_t size);
39 
60 #define LY_ARRAY_NEW(CTX, ARRAY, EACTION) \
61  { \
62  char *p__; \
63  if (ARRAY) { \
64  ++(*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1)); \
65  p__ = (char *)realloc(((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1), \
66  sizeof(LY_ARRAY_COUNT_TYPE) + (*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1) * sizeof *(ARRAY))); \
67  if (!p__) { \
68  --(*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1)); \
69  LOGMEM(CTX); \
70  EACTION; \
71  } \
72  } else { \
73  p__ = (char *)malloc(sizeof(LY_ARRAY_COUNT_TYPE) + sizeof *(ARRAY)); \
74  if (!p__) { \
75  LOGMEM(CTX); \
76  EACTION; \
77  } \
78  *((LY_ARRAY_COUNT_TYPE*)(p__)) = 1; \
79  } \
80  p__ = (char *)((LY_ARRAY_COUNT_TYPE*)(p__) + 1); \
81  memcpy(&(ARRAY), &p__, sizeof p__); \
82  }
83 
95 #define LY_ARRAY_NEW_RET(CTX, ARRAY, NEW_ITEM, RETVAL) \
96  LY_ARRAY_NEW(CTX, ARRAY, return RETVAL); \
97  (NEW_ITEM) = &(ARRAY)[*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1) - 1]; \
98  memset(NEW_ITEM, 0, sizeof *(NEW_ITEM))
99 
112 #define LY_ARRAY_NEW_GOTO(CTX, ARRAY, NEW_ITEM, RET, GOTO) \
113  LY_ARRAY_NEW(CTX, ARRAY, RET = LY_EMEM; goto GOTO); \
114  (NEW_ITEM) = &(ARRAY)[*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1) - 1]; \
115  memset(NEW_ITEM, 0, sizeof *(NEW_ITEM))
116 
132 #define LY_ARRAY_CREATE(CTX, ARRAY, SIZE, EACTION) \
133  { \
134  char *p__; \
135  if (ARRAY) { \
136  p__ = (char *)realloc(((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1), \
137  sizeof(LY_ARRAY_COUNT_TYPE) + ((*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1) + (SIZE)) * sizeof *(ARRAY))); \
138  if (!p__) { \
139  LOGMEM(CTX); \
140  EACTION; \
141  } \
142  } else { \
143  p__ = (char *)calloc(1, sizeof(LY_ARRAY_COUNT_TYPE) + (SIZE) * sizeof *(ARRAY)); \
144  if (!p__) { \
145  LOGMEM(CTX); \
146  EACTION; \
147  } \
148  } \
149  p__ = (char *)((LY_ARRAY_COUNT_TYPE*)(p__) + 1); \
150  memcpy(&(ARRAY), &p__, sizeof p__); \
151  if (ARRAY) { \
152  memset(&(ARRAY)[*((LY_ARRAY_COUNT_TYPE*)(p__) - 1)], 0, (SIZE) * sizeof *(ARRAY)); \
153  } \
154  }
155 
169 #define LY_ARRAY_CREATE_RET(CTX, ARRAY, SIZE, RETVAL) \
170  LY_ARRAY_CREATE(CTX, ARRAY, SIZE, return RETVAL)
171 
186 #define LY_ARRAY_CREATE_GOTO(CTX, ARRAY, SIZE, RET, GOTO) \
187  LY_ARRAY_CREATE(CTX, ARRAY, SIZE, RET = LY_EMEM; goto GOTO)
188 
197 #define LY_ARRAY_INCREMENT(ARRAY) \
198  ++(*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1))
199 
208 #define LY_ARRAY_DECREMENT(ARRAY) \
209  --(*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1))
210 
217 #define LY_ARRAY_DECREMENT_FREE(ARRAY) \
218  --(*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1)); \
219  if (!LY_ARRAY_COUNT(ARRAY)) { \
220  LY_ARRAY_FREE(ARRAY); \
221  (ARRAY) = NULL; \
222  }
223 
231 #define LY_ARRAY_FREE(ARRAY) \
232  if (ARRAY){free((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1);}
233 
240 #define LY_ARRAY_REMOVE_VALUE(ARRAY, VALUE) \
241  { \
242  LY_ARRAY_COUNT_TYPE index__; \
243  LY_ARRAY_FOR(ARRAY, index__) { \
244  if ((ARRAY)[index__] == VALUE) { \
245  if (index__ != LY_ARRAY_COUNT(ARRAY) - 1) { \
246  memmove(&((ARRAY)[index__]), &((ARRAY)[LY_ARRAY_COUNT(ARRAY) - 1]), sizeof *(ARRAY)); \
247  } \
248  LY_ARRAY_DECREMENT(ARRAY); \
249  break; \
250  } \
251  } \
252  }
253 
261 #define LY_LIST_INSERT(LIST, NEW_ITEM, LINKER)\
262  if (!(*LIST)) { \
263  memcpy(LIST, &(NEW_ITEM), sizeof NEW_ITEM); \
264  } else { \
265  size_t offset__ = (char *)&(*LIST)->LINKER - (char *)(*LIST); \
266  char **iter__ = (char **)((size_t)(*LIST) + offset__); \
267  while (*iter__) { \
268  iter__ = (char **)((size_t)(*iter__) + offset__); \
269  } \
270  memcpy(iter__, &(NEW_ITEM), sizeof NEW_ITEM); \
271  }
272 
284 #define LY_LIST_NEW(CTX, LIST, NEW_ITEM, LINKER, EACTION) \
285  { \
286  char *p__ = (char *)calloc(1, sizeof *NEW_ITEM); \
287  if (!p__) { \
288  LOGMEM(CTX); \
289  EACTION; \
290  } \
291  memcpy(&(NEW_ITEM), &p__, sizeof p__); \
292  LY_LIST_INSERT(LIST, NEW_ITEM, LINKER); \
293  }
294 
304 #define LY_LIST_NEW_RET(CTX, LIST, NEW_ITEM, LINKER, RETVAL) \
305  LY_LIST_NEW(CTX, LIST, NEW_ITEM, LINKER, return RETVAL)
306 
317 #define LY_LIST_NEW_GOTO(CTX, LIST, NEW_ITEM, LINKER, RET, LABEL) \
318  LY_LIST_NEW(CTX, LIST, NEW_ITEM, LINKER, RET = LY_EMEM; goto LABEL)
319 
322 #ifdef __cplusplus
323 }
324 #endif
325 
326 #endif /* LY_TREE_EDIT_H_ */
void * ly_realloc(void *ptr, size_t size)
Wrapper for realloc() call. The only difference is that if it fails to allocate the requested memory...