libyang  2.0.7
libyang is YANG data modelling language parser and toolkit written (and providing API) in C.
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 #include "log.h"
22 #include "tree.h"
23 
24 #ifndef LOGMEM
25 #define LOGMEM(CTX)
26 #endif
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
41 void *ly_realloc(void *ptr, size_t size);
42 
63 #define LY_ARRAY_NEW(CTX, ARRAY, EACTION) \
64  { \
65  void *p__; \
66  if (ARRAY) { \
67  ++(*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1)); \
68  p__ = realloc(((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1), \
69  sizeof(LY_ARRAY_COUNT_TYPE) + (*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1) * sizeof *(ARRAY))); \
70  if (!p__) { \
71  --(*((LY_ARRAY_COUNT_TYPE*)(p__) - 1)); \
72  LOGMEM(CTX); \
73  EACTION; \
74  } \
75  } else { \
76  p__ = malloc(sizeof(LY_ARRAY_COUNT_TYPE) + sizeof *(ARRAY)); \
77  if (!p__) { \
78  LOGMEM(CTX); \
79  EACTION; \
80  } \
81  *((LY_ARRAY_COUNT_TYPE*)(p__)) = 1; \
82  } \
83  p__ = (void*)((LY_ARRAY_COUNT_TYPE*)(p__) + 1); \
84  memcpy(&(ARRAY), &p__, sizeof p__); \
85  }
86 
98 #define LY_ARRAY_NEW_RET(CTX, ARRAY, NEW_ITEM, RETVAL) \
99  LY_ARRAY_NEW(CTX, ARRAY, return RETVAL); \
100  (NEW_ITEM) = &(ARRAY)[*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1) - 1]; \
101  memset(NEW_ITEM, 0, sizeof *(NEW_ITEM))
102 
115 #define LY_ARRAY_NEW_GOTO(CTX, ARRAY, NEW_ITEM, RET, GOTO) \
116  LY_ARRAY_NEW(CTX, ARRAY, RET = LY_EMEM; goto GOTO); \
117  (NEW_ITEM) = &(ARRAY)[*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1) - 1]; \
118  memset(NEW_ITEM, 0, sizeof *(NEW_ITEM))
119 
135 #define LY_ARRAY_CREATE(CTX, ARRAY, SIZE, EACTION) \
136  { \
137  void *p__; \
138  if (ARRAY) { \
139  p__ = realloc(((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1), \
140  sizeof(LY_ARRAY_COUNT_TYPE) + ((*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1) + (SIZE)) * sizeof *(ARRAY))); \
141  if (!p__) { \
142  LOGMEM(CTX); \
143  EACTION; \
144  } \
145  } else { \
146  p__ = calloc(1, sizeof(LY_ARRAY_COUNT_TYPE) + (SIZE) * sizeof *(ARRAY)); \
147  if (!p__) { \
148  LOGMEM(CTX); \
149  EACTION; \
150  } \
151  } \
152  p__ = (void*)((LY_ARRAY_COUNT_TYPE*)(p__) + 1); \
153  memcpy(&(ARRAY), &p__, sizeof p__); \
154  if (ARRAY) { \
155  memset(&(ARRAY)[*((LY_ARRAY_COUNT_TYPE*)(p__) - 1)], 0, (SIZE) * sizeof *(ARRAY)); \
156  } \
157  }
158 
172 #define LY_ARRAY_CREATE_RET(CTX, ARRAY, SIZE, RETVAL) \
173  LY_ARRAY_CREATE(CTX, ARRAY, SIZE, return RETVAL)
174 
189 #define LY_ARRAY_CREATE_GOTO(CTX, ARRAY, SIZE, RET, GOTO) \
190  LY_ARRAY_CREATE(CTX, ARRAY, SIZE, RET = LY_EMEM; goto GOTO)
191 
200 #define LY_ARRAY_INCREMENT(ARRAY) \
201  ++(*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1))
202 
211 #define LY_ARRAY_DECREMENT(ARRAY) \
212  --(*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1))
213 
220 #define LY_ARRAY_DECREMENT_FREE(ARRAY) \
221  --(*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1)); \
222  if (!LY_ARRAY_COUNT(ARRAY)) { \
223  LY_ARRAY_FREE(ARRAY); \
224  (ARRAY) = NULL; \
225  }
226 
234 #define LY_ARRAY_FREE(ARRAY) \
235  if (ARRAY){free((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1);}
236 
244 #define LY_LIST_INSERT(LIST, NEW_ITEM, LINKER)\
245  if (!(*LIST)) { \
246  memcpy(LIST, &(NEW_ITEM), sizeof NEW_ITEM); \
247  } else { \
248  size_t offset__ = (void*)&(*LIST)->LINKER - (void*)(*LIST); \
249  void **iter__ = (void **)((size_t)(*LIST) + offset__); \
250  while (*iter__) { \
251  iter__ = (void **)((size_t)(*iter__) + offset__); \
252  } \
253  memcpy(iter__, &(NEW_ITEM), sizeof NEW_ITEM); \
254  }
255 
267 #define LY_LIST_NEW(CTX, LIST, NEW_ITEM, LINKER, EACTION) \
268  { \
269  void *p__ = calloc(1, sizeof *NEW_ITEM); \
270  if (!p__) { \
271  LOGMEM(CTX); \
272  EACTION; \
273  } \
274  memcpy(&(NEW_ITEM), &p__, sizeof p__); \
275  LY_LIST_INSERT(LIST, NEW_ITEM, LINKER); \
276  }
277 
287 #define LY_LIST_NEW_RET(CTX, LIST, NEW_ITEM, LINKER, RETVAL) \
288  LY_LIST_NEW(CTX, LIST, NEW_ITEM, LINKER, return RETVAL)
289 
300 #define LY_LIST_NEW_GOTO(CTX, LIST, NEW_ITEM, LINKER, RET, LABEL) \
301  LY_LIST_NEW(CTX, LIST, NEW_ITEM, LINKER, RET = LY_EMEM; goto LABEL)
302 
305 #ifdef __cplusplus
306 }
307 #endif
308 
309 #endif /* LY_TREE_EDIT_H_ */
Logger manipulation routines and error definitions.
libyang generic macros and functions to work with YANG schema or data trees.
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,...