1 /* WEED is free software; you can redistribute it and/or
2    modify it under the terms of the GNU Lesser General Public
3    License as published by the Free Software Foundation; either
4    version 3 of the License, or (at your option) any later version.
5 
6    Weed is distributed in the hope that it will be useful,
7    but WITHOUT ANY WARRANTY; without even the implied warranty of
8    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9    Lesser General Public License for more details.
10 
11    You should have received a copy of the GNU Lesser General Public
12    License along with this source code; if not, write to the Free Software
13    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
14 
15    Weed is developed by:
16    Gabriel "Salsaman" Finch - http://lives-video.com
17 
18    partly based on LiViDO, which is developed by:
19    Niels Elburg - http://veejay.sf.net
20    Denis "Jaromil" Rojo - http://freej.dyne.org
21    Tom Schouten - http://zwizwa.fartit.com
22    Andraz Tori - http://cvs.cinelerra.org
23 
24    reviewed with suggestions and contributions from:
25    Silvano "Kysucix" Galliani - http://freej.dyne.org
26    Kentaro Fukuchi - http://megaui.net/fukuchi
27    Jun Iio - http://www.malib.net
28    Carlo Prelz - http://www2.fluido.as:8080/
29 */
30 
31 /* (C) G. Finch, 2005 - 2020 */
32 
33 #ifndef __WEED_UTILS_H__
34 #define __WEED_UTILS_H__
35 
36 #ifdef __cplusplus
37 extern "C"
38 {
39 #endif /* __cplusplus */
40 
41 #ifndef NEED_LOCAL_WEED
42 #include <weed/weed.h>
43 #else
44 #include "weed.h"
45 #endif
46 
47 /* some nice macros, e.g
48   double x = WEED_LEAF_GET(myplant, "mykey", double);
49 */
50 #define WEED_LEAF_GET(plant, key, type) weed_get_##type##_value(plant, key, NULL)
51 #define WEED_LEAF_GET_ARRAY_COUNTED(plant, key, type, counter) weed_get_##type##_array_counted(plant, key, &count)
52 #define WEED_LEAF_SET(plant, key, type, value) weed_set_##type##_value(plant, key, value)
53 #define WEED_LEAF_SET_ARRAY(plant, key, type, nvals, array) weed_set_##type##_array(plant, key, nvals, array)
54 
55 #if defined(__WEED_HOST__) || defined(__LIBWEED__)
56 typedef int (*weed_memcmp_f)(const void *, const void *, size_t);
57 
58 void weed_utils_set_custom_memfuncs(weed_malloc_f malloc_func, weed_calloc_f calloc_func, weed_memcpy_f memcpy_func,
59                                     weed_memcmp_f memcmp_func, weed_free_f free_func);
60 
61 /* check if leaf exists and has a value, returns WEED_TRUE or WEED_FALSE */
62 int weed_plant_has_leaf(weed_plant_t *, const char *key);
63 
64 /* check if leaf exists; may have a seed_type but no value set */
65 int weed_leaf_exists(weed_plant_t *, const char *key);
66 
67 weed_error_t weed_set_int_value(weed_plant_t *, const char *key, int32_t);
68 weed_error_t weed_set_double_value(weed_plant_t *, const char *key, double);
69 weed_error_t weed_set_boolean_value(weed_plant_t *, const char *key, int32_t);
70 weed_error_t weed_set_int64_value(weed_plant_t *, const char *key, int64_t);
71 weed_error_t weed_set_string_value(weed_plant_t *, const char *key, const char *);
72 weed_error_t weed_set_funcptr_value(weed_plant_t *, const char *key, void *);
73 weed_error_t weed_set_voidptr_value(weed_plant_t *, const char *key, void *);
74 weed_error_t weed_set_plantptr_value(weed_plant_t *, const char *key, weed_plant_t *);
75 weed_error_t weed_set_custom_value(weed_plant_t *, const char *key, uint32_t seed_type, void *);
76 
77 int32_t weed_get_int_value(weed_plant_t *, const char *key, weed_error_t *);
78 double weed_get_double_value(weed_plant_t *, const char *key, weed_error_t *);
79 int32_t weed_get_boolean_value(weed_plant_t *, const char *key, weed_error_t *);
80 int64_t weed_get_int64_value(weed_plant_t *, const char *key, weed_error_t *);
81 char *weed_get_string_value(weed_plant_t *, const char *key, weed_error_t *);
82 weed_funcptr_t weed_get_funcptr_value(weed_plant_t *, const char *key, weed_error_t *);
83 void *weed_get_voidptr_value(weed_plant_t *, const char *key, weed_error_t *);
84 weed_plant_t *weed_get_plantptr_value(weed_plant_t *, const char *key, weed_error_t *);
85 void *weed_get_custom_value(weed_plant_t *, const char *key, uint32_t seed_type, weed_error_t *);
86 
87 weed_error_t weed_set_int_array(weed_plant_t *, const char *key, weed_size_t num_elems, int32_t *);
88 weed_error_t weed_set_double_array(weed_plant_t *, const char *key, weed_size_t num_elems, double *);
89 weed_error_t weed_set_boolean_array(weed_plant_t *, const char *key, weed_size_t num_elems, int32_t *);
90 weed_error_t weed_set_int64_array(weed_plant_t *, const char *key, weed_size_t num_elems, int64_t *);
91 weed_error_t weed_set_string_array(weed_plant_t *, const char *key, weed_size_t num_elems, char **);
92 weed_error_t weed_set_funcptr_array(weed_plant_t *, const char *key, weed_size_t num_elems, weed_funcptr_t *);
93 weed_error_t weed_set_voidptr_array(weed_plant_t *, const char *key, weed_size_t num_elems, void **);
94 weed_error_t weed_set_plantptr_array(weed_plant_t *, const char *key, weed_size_t num_elems, weed_plant_t **);
95 weed_error_t weed_set_custom_array(weed_plant_t *, const char *key, uint32_t seed_type, weed_size_t num_elems, void **);
96 
97 int32_t *weed_get_int_array(weed_plant_t *, const char *key, weed_error_t *);
98 double *weed_get_double_array(weed_plant_t *, const char *key, weed_error_t *);
99 int32_t *weed_get_boolean_array(weed_plant_t *, const char *key, weed_error_t *);
100 int64_t *weed_get_int64_array(weed_plant_t *, const char *key, weed_error_t *);
101 char **weed_get_string_array(weed_plant_t *, const char *key, weed_error_t *);
102 weed_funcptr_t *weed_get_funcptr_array(weed_plant_t *, const char *key, weed_error_t *);
103 void **weed_get_voidptr_array(weed_plant_t *, const char *key, weed_error_t *);
104 weed_plant_t **weed_get_plantptr_array(weed_plant_t *, const char *key, weed_error_t *);
105 void **weed_get_custom_array(weed_plant_t *, const char *key, uint32_t seed_type, weed_error_t *);
106 
107 int32_t *weed_get_int_array_counted(weed_plant_t *, const char *key, int *count);
108 double *weed_get_double_array_counted(weed_plant_t *, const char *key, int *count);
109 int32_t *weed_get_boolean_array_counted(weed_plant_t *, const char *key, int *count);
110 int64_t *weed_get_int64_array_counted(weed_plant_t *, const char *key, int *count);
111 char **weed_get_string_array_counted(weed_plant_t *, const char *key, int *count);
112 weed_funcptr_t *weed_get_funcptr_array_counted(weed_plant_t *, const char *key, int *count);
113 weed_voidptr_t *weed_get_voidptr_array_counted(weed_plant_t *, const char *key, int *count);
114 weed_plant_t **weed_get_plantptr_array_counted(weed_plant_t *, const char *key, int *count);
115 weed_voidptr_t *weed_get_custom_array_counted(weed_plant_t *, const char *key, uint32_t seed_type, int *count);
116 
117 /* make a copy dest leaf from src leaf. Pointers are copied by reference only, but strings are allocated */
118 weed_error_t weed_leaf_copy(weed_plant_t *dest, const char *keyt, weed_plant_t *src, const char *keyf);
119 
120 /* copy only the nth element; if either leaf has n or fewer elements then WEED_ERROR_NOSUCH_ELEMENT is returned */
121 weed_error_t weed_leaf_copy_nth(weed_plant_t *dst, const char *keyt, weed_plant_t *src, const char *keyf, int n);
122 
123 /* convenience functions for the more common case where both keys match */
124 weed_error_t weed_leaf_dup(weed_plant_t *dst, weed_plant_t *src, const char *key);
125 weed_error_t weed_leaf_dup_nth(weed_plant_t *dst, weed_plant_t *src, const char *key, int n);
126 
127 /* copy all leaves in src to dst using weed_leaf_copy */
128 weed_plant_t *weed_plant_copy(weed_plant_t *src);
129 
130 /* returns WEED_TRUE if nth elements of 2 leaves are identical (both exist, both seed_types equal, both values equal)
131      if elem < 0, then all elements must match */
132 int weed_leaf_elements_equate(weed_plant_t *p0, const char *k0, weed_plant_t *p1, const char *k1, int elem);
133 
134 /* returns the value of the "type" leaf; returns WEED_PLANT_UNKNOWN if plant is NULL */
135 int32_t weed_get_plant_type(weed_plant_t *);
136 
137 /* returns WEED_TRUE if higher and lower versions are compatible, WEED_FALSE if not */
138 int check_weed_abi_compat(int32_t higher, int32_t lower);
139 
140 /* returns WEED_TRUE if higher and lower versions are compatible, WEED_FALSE if not */
141 int check_filter_api_compat(int32_t higher, int32_t lower);
142 
143 #ifdef __WEED_EFFECTS_H__
144 /* plugin only function; host should pass a pointer to this to the plugin as the sole parameter when calling  weed_setup()
145   in the plugin */
146 weed_plant_t *weed_bootstrap(weed_default_getter_f *, int32_t plugin_weed_min_api_version, int32_t plugin_weed_max_api_version,
147                              int32_t plugin_filter_min_api_version, int32_t plugin_filter_max_api_version);
148 #endif
149 
150 /* typedef for host callback from weed_bootstrap; host MUST return a host_info, either the original one or a new one */
151 typedef weed_plant_t *(*weed_host_info_callback_f)(weed_plant_t *host_info, void *user_data);
152 
153 /* set a host callback function to be called from within weed_bootstrap() */
154 void weed_set_host_info_callback(weed_host_info_callback_f, void *user_data);
155 #endif
156 
157 #ifdef __WEED_PLUGIN__
158 
159 #ifndef FN_TYPE
160 #define FN_TYPE static inline
161 #endif
162 
163 /* functions need to be defined here for the plugin, else it will use the host versions, breaking function overloading */
164 #ifdef __weed_get_value__
165 #undef __weed_get_value__
166 #endif
167 #ifdef __weed_check_leaf__
168 #undef __weed_check_leaf__
169 #endif
170 
171 #define __weed_get_value__(plant, key, value) weed_leaf_get(plant, key, 0, value)
172 #define __weed_check_leaf__(plant, key) __weed_get_value__(plant, key, NULL)
173 
174 /* check for existence of a leaf; leaf must must have a value and not just a seed_type, returns WEED_TRUE or WEED_FALSE */
weed_plant_has_leaf(weed_plant_t * plant,const char * key)175 FN_TYPE int weed_plant_has_leaf(weed_plant_t *plant, const char *key) {
176   return __weed_check_leaf__(plant, key) == WEED_SUCCESS ? WEED_TRUE : WEED_FALSE;}
177 
178 #define _WEED_SET_(stype) return weed_leaf_set(plant, key, WEED_SEED_##stype, 1, (weed_voidptr_t)&value);
179 
180   /*							--- SINGLE VALUE SETTERS ---						*/
weed_set_int_value(weed_plant_t * plant,const char * key,int32_t value)181 FN_TYPE weed_error_t weed_set_int_value(weed_plant_t *plant, const char *key, int32_t value) {_WEED_SET_(INT)}
weed_set_double_value(weed_plant_t * plant,const char * key,double value)182 FN_TYPE weed_error_t weed_set_double_value(weed_plant_t *plant, const char *key, double value) {_WEED_SET_(DOUBLE)}
weed_set_boolean_value(weed_plant_t * plant,const char * key,int32_t value)183 FN_TYPE weed_error_t weed_set_boolean_value(weed_plant_t *plant, const char *key, int32_t value) {_WEED_SET_(BOOLEAN)}
weed_set_int64_value(weed_plant_t * plant,const char * key,int64_t value)184 FN_TYPE weed_error_t weed_set_int64_value(weed_plant_t *plant, const char *key, int64_t value) {_WEED_SET_(INT64)}
weed_set_string_value(weed_plant_t * plant,const char * key,const char * value)185 FN_TYPE weed_error_t weed_set_string_value(weed_plant_t *plant, const char *key, const char *value) {_WEED_SET_(STRING)}
weed_set_funcptr_value(weed_plant_t * plant,const char * key,weed_funcptr_t value)186 FN_TYPE weed_error_t weed_set_funcptr_value(weed_plant_t *plant, const char *key, weed_funcptr_t value) {_WEED_SET_(FUNCPTR)}
weed_set_voidptr_value(weed_plant_t * plant,const char * key,weed_voidptr_t value)187 FN_TYPE weed_error_t weed_set_voidptr_value(weed_plant_t *plant, const char *key, weed_voidptr_t value) {_WEED_SET_(VOIDPTR)}
weed_set_plantptr_value(weed_plant_t * plant,const char * key,weed_plant_t * value)188 FN_TYPE weed_error_t weed_set_plantptr_value(weed_plant_t *plant, const char *key, weed_plant_t *value) {_WEED_SET_(PLANTPTR)}
189 
190 #undef _WEED_SET_
__weed_leaf_check__(weed_plant_t * plant,const char * key,uint32_t seed_type)191 FN_TYPE weed_error_t __weed_leaf_check__(weed_plant_t *plant, const char *key, uint32_t seed_type) {
192   weed_error_t err = __weed_check_leaf__(plant, key);
193   return err != WEED_SUCCESS ? err
194     : weed_leaf_seed_type(plant, key) != seed_type ? WEED_ERROR_WRONG_SEED_TYPE : WEED_SUCCESS;}
195 
__weed_value_get__(weed_plant_t * plant,const char * key,uint32_t seed_type,weed_voidptr_t retval,weed_error_t * error)196 FN_TYPE weed_voidptr_t __weed_value_get__(weed_plant_t *plant, const char *key, uint32_t seed_type,
197     weed_voidptr_t retval, weed_error_t *error) {
198   weed_error_t err, *perr = (error ? error : &err);
199   if ((*perr = __weed_leaf_check__(plant, key, seed_type)) == WEED_SUCCESS) *perr = __weed_get_value__(plant, key, retval);
200   return retval;}
201 
202 #define _WEED_GET_(ctype, stype) ctype retval; \
203   return *((ctype *)(__weed_value_get__(plant, key, WEED_SEED_##stype, (weed_voidptr_t)&retval, error)));
204 
205   /*							--- SINGLE VALUE GETTERS ---						*/
weed_get_int_value(weed_plant_t * plant,const char * key,weed_error_t * error)206 FN_TYPE int32_t weed_get_int_value(weed_plant_t *plant, const char *key, weed_error_t *error) {_WEED_GET_(int32_t, INT)}
weed_get_double_value(weed_plant_t * plant,const char * key,weed_error_t * error)207 FN_TYPE double weed_get_double_value(weed_plant_t *plant, const char *key, weed_error_t *error) {_WEED_GET_(double, DOUBLE)}
weed_get_boolean_value(weed_plant_t * plant,const char * key,weed_error_t * error)208 FN_TYPE int32_t weed_get_boolean_value(weed_plant_t *plant, const char *key, weed_error_t *error) {_WEED_GET_(int32_t, BOOLEAN)}
weed_get_int64_value(weed_plant_t * plant,const char * key,weed_error_t * error)209 FN_TYPE int64_t weed_get_int64_value(weed_plant_t *plant, const char *key, weed_error_t *error) {_WEED_GET_(int64_t, INT64)}
210 
weed_get_string_value(weed_plant_t * plant,const char * key,weed_error_t * error)211   FN_TYPE char *weed_get_string_value(weed_plant_t *plant, const char *key, weed_error_t *error) {
212   char *retval = NULL; weed_error_t err, *perr = (error ? error : &err);
213   if ((*perr =  __weed_leaf_check__(plant, key, WEED_SEED_STRING)) == WEED_SUCCESS) {
214     if (!(retval = (char *)weed_malloc(weed_leaf_element_size(plant, key, 0) + 1))) *perr = WEED_ERROR_MEMORY_ALLOCATION;
215     else {
216       retval = *((char **)(__weed_value_get__(plant, key, WEED_SEED_STRING, &retval, perr)));
217       if (*perr != WEED_SUCCESS) {if (retval) weed_free(retval); retval = NULL;}
218       }} return retval;}
219 
weed_get_voidptr_value(weed_plant_t * plant,const char * key,weed_error_t * error)220 FN_TYPE weed_voidptr_t weed_get_voidptr_value(weed_plant_t *plant, const char *key, weed_error_t *error) {
221   _WEED_GET_(weed_voidptr_t, VOIDPTR)}
222 
weed_get_funcptr_value(weed_plant_t * plant,const char * key,weed_error_t * error)223 FN_TYPE weed_funcptr_t weed_get_funcptr_value(weed_plant_t *plant, const char *key, weed_error_t *error) {
224   _WEED_GET_(weed_funcptr_t, FUNCPTR)}
225 
weed_get_plantptr_value(weed_plant_t * plant,const char * key,weed_error_t * error)226 FN_TYPE weed_plant_t *weed_get_plantptr_value(weed_plant_t *plant, const char *key, weed_error_t *error) {
227   _WEED_GET_(weed_plantptr_t, PLANTPTR)}
228 
229 #undef _WEED_GET_
__weed_get_values__(weed_plant_t * plant,const char * key,size_t dsize,char ** retval,int * nvals)230 FN_TYPE weed_error_t __weed_get_values__(weed_plant_t *plant, const char *key, size_t dsize, char **retval,
231     int *nvals) {
232   weed_size_t num_elems = weed_leaf_num_elements(plant, key);
233   if (nvals) *nvals = 0;
234   if (!(*retval = (char *)weed_calloc(num_elems, dsize))) return WEED_ERROR_MEMORY_ALLOCATION;
235   for (int i = 0; (weed_size_t)i < num_elems; i++) {
236     weed_error_t err;
237     if ((err = weed_leaf_get(plant, key, i, (weed_voidptr_t) & (*retval)[i * dsize])) != WEED_SUCCESS) {
238       weed_free(*retval); *retval = NULL;
239       return err;
240     }}
241   if (nvals) *nvals = (int)num_elems;
242   return WEED_SUCCESS;}
243 
__weed_get_arrayx__(weed_plant_t * plant,const char * key,uint32_t seed_type,weed_size_t typelen,weed_error_t * error,int * nvals)244 FN_TYPE weed_voidptr_t __weed_get_arrayx__(weed_plant_t *plant, const char *key, uint32_t seed_type, weed_size_t typelen,
245 					   weed_error_t *error, int *nvals) {
246   weed_error_t err, *perr = (error ? error : &err); char *retvals = NULL;
247   if ((*perr = __weed_leaf_check__(plant, key, seed_type)) != WEED_SUCCESS) return NULL;
248   *perr = __weed_get_values__(plant, key, typelen, (char **)&retvals, nvals); return retvals;}
249 
250 #define _ARRAY_COUNT_(ctype, stype) \
251   return (ctype *)(__weed_get_arrayx__(plant, key, WEED_SEED_##stype, sizeof(ctype), NULL, count));
252 #define _ARRAY_NORM_(ctype, stype) \
253   return (ctype *)(__weed_get_arrayx__(plant, key, WEED_SEED_##stype, sizeof(ctype), error, NULL));
254 
255 /*							--- ARRAY GETTERS ---						*/
weed_get_int_array_counted(weed_plant_t * plant,const char * key,int * count)256 FN_TYPE int32_t *weed_get_int_array_counted(weed_plant_t *plant, const char *key, int *count){_ARRAY_COUNT_(int32_t, INT)}
weed_get_int_array(weed_plant_t * plant,const char * key,weed_error_t * error)257 FN_TYPE int32_t *weed_get_int_array(weed_plant_t *plant, const char *key, weed_error_t *error){_ARRAY_NORM_(int32_t, INT)}
weed_get_double_array_counted(weed_plant_t * plant,const char * key,int * count)258 FN_TYPE double *weed_get_double_array_counted(weed_plant_t *plant, const char *key, int *count){_ARRAY_COUNT_(double, DOUBLE)}
weed_get_double_array(weed_plant_t * plant,const char * key,weed_error_t * error)259 FN_TYPE double *weed_get_double_array(weed_plant_t *plant, const char *key, weed_error_t *error){_ARRAY_NORM_(double, DOUBLE)}
weed_get_boolean_array_counted(weed_plant_t * plant,const char * key,int * count)260 FN_TYPE int32_t *weed_get_boolean_array_counted(weed_plant_t *plant, const char *key, int *count){
261   _ARRAY_COUNT_(int32_t, BOOLEAN)}
weed_get_boolean_array(weed_plant_t * plant,const char * key,weed_error_t * error)262 FN_TYPE int32_t *weed_get_boolean_array(weed_plant_t *plant, const char *key, weed_error_t *error){
263   _ARRAY_NORM_(int32_t, BOOLEAN)}
weed_get_int64_array_counted(weed_plant_t * plant,const char * key,int * count)264 FN_TYPE int64_t *weed_get_int64_array_counted(weed_plant_t *plant, const char *key, int *count) {_ARRAY_COUNT_(int64_t, INT64)}
weed_get_int64_array(weed_plant_t * plant,const char * key,weed_error_t * error)265 FN_TYPE int64_t *weed_get_int64_array(weed_plant_t *plant, const char *key, weed_error_t *error) {_ARRAY_NORM_(int64_t, INT64)}
266 
__weed_get_string_array__(weed_plant_t * plant,const char * key,weed_error_t * error,int * count)267 FN_TYPE char **__weed_get_string_array__(weed_plant_t *plant, const char *key, weed_error_t *error, int *count) {
268   weed_size_t num_elems; char **retvals = NULL; weed_error_t err, *perr = (error ? error : &err); uint32_t i;
269   if (count) *count = 0;
270   if ((*perr = __weed_leaf_check__(plant, key, WEED_SEED_STRING)) != WEED_SUCCESS
271       || !(num_elems = weed_leaf_num_elements(plant, key))) return NULL;
272   if (!(retvals = (char **)weed_calloc(num_elems, sizeof(char *)))) *perr = WEED_ERROR_MEMORY_ALLOCATION;
273   else {
274     for (i = 0; i < num_elems; i++) {
275       if (!(retvals[i] = (char *)weed_malloc(weed_leaf_element_size(plant, key, i)) + 1)) {
276         *perr = WEED_ERROR_MEMORY_ALLOCATION;
277         goto __cleanup;
278       }
279       if ((*perr = weed_leaf_get(plant, key, i, &retvals[i])) != WEED_SUCCESS) goto __cleanup;
280     }
281     if (count) *count = num_elems;
282   }
283   return retvals;
284 
285 __cleanup:
286   while (i > 0) {weed_free(retvals[--i]);} weed_free(retvals); return NULL;
287 }
288 
weed_get_string_array_counted(weed_plant_t * plant,const char * key,int * count)289 FN_TYPE char **weed_get_string_array_counted(weed_plant_t *plant, const char *key, int *count) {
290   return __weed_get_string_array__(plant, key, NULL, count);}
weed_get_string_array(weed_plant_t * plant,const char * key,weed_error_t * error)291 FN_TYPE char **weed_get_string_array(weed_plant_t *plant, const char *key, weed_error_t *error) {
292   return __weed_get_string_array__(plant, key, error, NULL);}
293 
weed_get_funcptr_array_counted(weed_plant_t * plant,const char * key,int * count)294 FN_TYPE weed_funcptr_t *weed_get_funcptr_array_counted(weed_plant_t *plant, const char *key, int *count) {
295   _ARRAY_COUNT_(weed_funcptr_t, FUNCPTR)}
weed_get_funcptr_array(weed_plant_t * plant,const char * key,weed_error_t * error)296 FN_TYPE weed_funcptr_t *weed_get_funcptr_array(weed_plant_t *plant, const char *key, weed_error_t *error) {
297   _ARRAY_NORM_(weed_funcptr_t, FUNCPTR)}
298 
weed_get_voidptr_array_counted(weed_plant_t * plant,const char * key,int * count)299 FN_TYPE weed_voidptr_t *weed_get_voidptr_array_counted(weed_plant_t *plant, const char *key, int *count) {
300   _ARRAY_COUNT_(weed_voidptr_t, VOIDPTR)}
weed_get_voidptr_array(weed_plant_t * plant,const char * key,weed_error_t * error)301 FN_TYPE weed_voidptr_t *weed_get_voidptr_array(weed_plant_t *plant, const char *key, weed_error_t *error) {
302   _ARRAY_NORM_(weed_voidptr_t, VOIDPTR)}
303 
weed_get_plantptr_array_counted(weed_plant_t * plant,const char * key,int * count)304 FN_TYPE weed_plant_t **weed_get_plantptr_array_counted(weed_plant_t *plant, const char *key, int *count) {
305   _ARRAY_COUNT_(weed_plantptr_t, PLANTPTR)}
weed_get_plantptr_array(weed_plant_t * plant,const char * key,weed_error_t * error)306 FN_TYPE weed_plant_t **weed_get_plantptr_array(weed_plant_t *plant, const char *key, weed_error_t *error) {
307   _ARRAY_NORM_(weed_plantptr_t, PLANTPTR)}
308 
309 #undef _ARRAY_COUNT_
310 #undef _ARRAY_NORM_
311 #define _SET_ARRAY_(stype)  return weed_leaf_set(plant, key, WEED_SEED_##stype, num_elems, (weed_voidptr_t)values);
312 
313  /*							--- ARRAY SETTERS ---						*/
weed_set_int_array(weed_plant_t * plant,const char * key,weed_size_t num_elems,int32_t * values)314 FN_TYPE weed_error_t weed_set_int_array(weed_plant_t *plant, const char *key, weed_size_t num_elems, int32_t *values) {
315   _SET_ARRAY_(INT)}
316 
weed_set_double_array(weed_plant_t * plant,const char * key,weed_size_t num_elems,double * values)317 FN_TYPE weed_error_t weed_set_double_array(weed_plant_t *plant, const char *key, weed_size_t num_elems, double *values) {
318   _SET_ARRAY_(DOUBLE)}
319 
weed_set_boolean_array(weed_plant_t * plant,const char * key,weed_size_t num_elems,int32_t * values)320 FN_TYPE weed_error_t weed_set_boolean_array(weed_plant_t *plant, const char *key, weed_size_t num_elems, int32_t *values) {
321   _SET_ARRAY_(BOOLEAN)}
322 
weed_set_int64_array(weed_plant_t * plant,const char * key,weed_size_t num_elems,int64_t * values)323 FN_TYPE weed_error_t weed_set_int64_array(weed_plant_t *plant, const char *key, weed_size_t num_elems, int64_t *values) {
324   _SET_ARRAY_(INT64)}
325 
weed_set_string_array(weed_plant_t * plant,const char * key,weed_size_t num_elems,char ** values)326 FN_TYPE weed_error_t weed_set_string_array(weed_plant_t *plant, const char *key, weed_size_t num_elems, char **values) {
327   _SET_ARRAY_(STRING)}
328 
weed_set_funcptr_array(weed_plant_t * plant,const char * key,weed_size_t num_elems,weed_funcptr_t * values)329 FN_TYPE weed_error_t weed_set_funcptr_array(weed_plant_t *plant, const char *key, weed_size_t num_elems, weed_funcptr_t *values) {
330   _SET_ARRAY_(FUNCPTR)}
331 
weed_set_voidptr_array(weed_plant_t * plant,const char * key,weed_size_t num_elems,weed_voidptr_t * values)332 FN_TYPE weed_error_t weed_set_voidptr_array(weed_plant_t *plant, const char *key, weed_size_t num_elems, weed_voidptr_t *values) {
333   _SET_ARRAY_(VOIDPTR)}
334 
weed_set_plantptr_array(weed_plant_t * plant,const char * key,weed_size_t num_elems,weed_plant_t ** values)335 FN_TYPE weed_error_t weed_set_plantptr_array(weed_plant_t *plant, const char *key, weed_size_t num_elems, weed_plant_t **values) {
336   _SET_ARRAY_(PLANTPTR)}
337 #undef _SET_ARRAY_
338 
339 #undef __weed_get_value__
340 #undef __weed_check_leaf__
341 #endif
342 
343 #define WEED_LEAF_MIN_WEED_API_VERSION   "min_weed_api_version"
344 #define WEED_LEAF_MAX_WEED_API_VERSION   "max_weed_api_version"
345 #define WEED_LEAF_MIN_WEED_ABI_VERSION WEED_LEAF_MIN_WEED_API_VERSION
346 #define WEED_LEAF_MAX_WEED_ABI_VERSION WEED_LEAF_MAX_WEED_API_VERSION
347 #define WEED_LEAF_MIN_FILTER_API_VERSION "min_weed_filter_version"
348 #define WEED_LEAF_MAX_FILTER_API_VERSION "max_weed_filter_version"
349 
350 #ifdef __cplusplus
351 }
352 #endif /* __cplusplus */
353 
354 #endif // #ifndef __WEED_UTILS_H__
355