LiVES 3.2.0
lsd-tab.c
Go to the documentation of this file.
1// lsd-tab.c
2// LiVES
3// (c) G. Finch 2020 <salsaman+lives@gmail.com>
4// released under the GNU GPL 3 or later
5// see file ../COPYING or www.gnu.org for licensing details
6
7// functions for handling the LiVES Struct Def Table
8
9#include "main.h"
10
11#include "lsd.h"
12
13#define CREATOR_ID "Created in LiVES main"
14
15static const lives_struct_def_t *lsd_table[LIVES_N_STRUCTS];
16boolean tab_inited = FALSE;
17
18static void init_lsd_tab(void) {
19 for (int i = 0; i < LIVES_N_STRUCTS; i++) lsd_table[i] = NULL;
21}
22
24 const lives_struct_def_t *lsd;
25 if (st_type < LIVES_STRUCT_FIRST || st_type >= LIVES_N_STRUCTS) return NULL;
26 if (!tab_inited) init_lsd_tab();
27 else if (lsd_table[st_type]) return lsd_table[st_type];
28 switch (st_type) {
30 lsd = lsd_create("lives_clip_data_t", sizeof(lives_clip_data_t), "sync_hint", 6);
31 if (lsd) {
34 specf[0] = make_special_field(LIVES_FIELD_FLAG_ZERO_ON_COPY |
36 "priv", 0, NULL, NULL, NULL);
37 specf[1] = make_special_field(LIVES_FIELD_CHARPTR, cdata, &cdata->URI,
38 "URI", 0, NULL, NULL, NULL);
39 specf[2] = make_special_field(LIVES_FIELD_FLAG_ZERO_ON_COPY, cdata, &cdata->title,
40 "title", 1024, NULL, NULL, NULL);
41 specf[3] = make_special_field(LIVES_FIELD_FLAG_ZERO_ON_COPY, cdata, &cdata->author,
42 "author", 1024, NULL, NULL, NULL);
43 specf[4] = make_special_field(LIVES_FIELD_FLAG_ZERO_ON_COPY, cdata, &cdata->comment,
44 "comment", 1024, NULL, NULL, NULL);
45 specf[5] = make_special_field(LIVES_FIELD_ARRAY, cdata, &cdata->palettes,
46 "palettes", 4, NULL, NULL, NULL);
47 lives_struct_init(lsd, cdata, &cdata->lsd);
48 lives_free(cdata);
49 }
50 break;
52 lsd = lsd_create("lives_file_dets_t", sizeof(lives_file_dets_t), "widgets", 3);
53 if (lsd) {
56 specf[0] = make_special_field(LIVES_FIELD_CHARPTR, fdets, &fdets->name,
57 "name", 0, NULL, NULL, NULL);
58 specf[1] = make_special_field(LIVES_FIELD_CHARPTR, fdets, &fdets->md5sum,
59 "md5sum", 0, NULL, NULL, NULL);
60 specf[2] = make_special_field(LIVES_FIELD_CHARPTR, fdets, &fdets->extra_details,
61 "extra_details", 0, NULL, NULL, NULL);
62 lives_struct_init_p(lsd, fdets, &fdets->lsd);
63 lives_free(fdets);
64 }
65 break;
66 default:
67 return NULL;
68 }
69 if (lsd) {
70 lives_struct_set_class_data((lives_struct_def_t *)lsd, CREATOR_ID);
71 lsd_table[st_type] = lsd;
72 }
73 return lsd;
74}
75
77 const lives_struct_def_t *lsd = get_lsd(st_type);
78 if (!lsd) return NULL;
79 return lives_struct_create(lsd);
80}
81
82
84 if (lsd) return lives_struct_copy(lsd);
85 return NULL;
86}
87
88
90 if (lsd) lives_struct_unref(lsd);
91}
92
93
95 if (lsd) lives_struct_ref(lsd);
96}
97
98
100 if (lsd) return lives_struct_get_class_data(lsd);
101 return NULL;
102}
103
104
106 if (lsd && other) return (lives_struct_get_uid(lsd) == lives_struct_get_uid(other));
107 return FALSE;
108}
109
110
111LIVES_GLOBAL_INLINE boolean lives_struct_is_a(lives_struct_def_t *lsd, const char *st_type) {
112 if (lsd) return (!lives_strcmp(lives_struct_get_type(lsd), st_type));
113 return FALSE;
114}
115
116
118 lives_struct_def_t *other) {
119 if (lsd && other) return lives_struct_is_a(lsd, lives_struct_get_type(other));
120 return FALSE;
121}
122
123
124#define CHECK_VERBOSE 0
125#if CHECK_VERBOSE
126#define errprint(...) fprintf(stderr, __VA_ARGS__)
127#else
128#define errprint(...)
129#endif
130
132#if CHECK_VERBOSE
133 uint64_t id, eid, uid;
134#endif
135 uint64_t err = 0;
136 if (!lsd) {
137 errprint("lsd_check: lsd1 is NULL\n");
138 err |= (1ul << 0);
139 return err;
140 }
141
142#if CHECK_VERBOSE
143
145 id = lives_struct_get_identifier(lsd);
146
147 if (id != LIVES_STRUCT_ID)
148 errprint("lsd_check: lsd (%p) has non-standard identifier 0X%016lX\n", lsd, id);
149
150 eid = lives_struct_get_end_id(lsd);
151
152 if (eid != (LIVES_STRUCT_ID ^ 0xFFFFFFFFFFFFFFFF))
153 errprint("lsd_check: lsd (%p) has non-standard end_id 0X%016lX\n", lsd, eid);
154
155 if (eid != (id ^ 0xFFFFFFFFFFFFFFFF))
156 errprint("lsd_check: lsd (%p) has non matching identifier / end_id pair\n"
157 "0X%016lX 0X%016lX should be 0X%016lX\n", lsd, id, eid, id ^ 0xFFFFFFFFFFFFFFFF);
158
159 uid = lives_struct_get_uid(lsd);
160 if (!uid)
161 errprint("lsd_check: lsd (%p) has no unique_id\n", lsd);
162
163 else if (uid < (1 << 20))
164 errprint("lsd_check: lsd (%p) has unique_id 0X%016lX\n"
165 "The probability of this is < 1 in 17.5 trillion\n", lsd, uid);
166
167 if (lives_strcmp(lives_struct_get_class_data(lsd), CREATOR_ID))
168 errprint("lsd_check: lsd (%p) has alternate class_data [%s]\n"
169 "Ours is [%s]\n", lsd, (char *)lives_struct_get_class_data(lsd), CREATOR_ID);
170#endif
171 return err;
172}
173
175 size_t sz1, sz2;
176 uint64_t err = 0;
177 if (!lsd1) {
178 errprint("lsd_check: lsd1 is NULL\n");
179 err |= (1ul << 0);
180 }
181 if (!lsd1) {
182 errprint("lsd_check: lsd1 is NULL\n");
183 err |= (1ul << 24);
184 }
185 if (err) return err;
186
187 if (!lives_structs_same_type(lsd1, lsd2)) {
188 errprint("lsd_check: lsd1 type is %s but lsd2 type is %s\n",
189 lives_struct_get_type(lsd1), lives_struct_get_type(lsd2));
190 err |= (1ul << 48);
191 }
192
193 sz1 = lives_struct_get_size(lsd1);
194 sz2 = lives_struct_get_size(lsd2);
195 if (sz1 != sz2) {
196 errprint("lsd_check: lsd1 (%p) size is %lu but lsd2 (%p) size is %lu\n",
197 lsd1, sz1, lsd2, sz2);
198 if (sz1 > sz2) err |= (1ul << 49);
199 else err |= (1ul << 50);
200 }
201 if (lives_strcmp(lives_struct_get_last_field(lsd1), lives_struct_get_last_field(lsd2))) {
202 errprint("lsd_check: lsd1 (%p) last field [%s]\n"
203 "is not the same as lsd2 (%p) last field [%s]\n",
204 lsd1, lives_struct_get_last_field(lsd1),
205 lsd2, lives_struct_get_last_field(lsd2));
206 err |= (1ul << 51);
207 }
208
210
211 errprint("lsd_check: checking lsd1 (%p)\n", lsd1);
212 err |= lsd_check_struct(lsd1);
213 errprint("lsd_check: checking lsd2 (%p)\n", lsd2);
214 err |= (lsd_check_struct(lsd2) << 24);
215
216 return err;
217}
218
219
221
222char *weed_plant_to_header(weed_plant_t *plant, const char *tname) {
223 char **leaves = weed_plant_list_leaves(plant, NULL);
224 char *hdr, *ar = NULL, *line;
225
226 if (tname)
227 hdr = lives_strdup("typedef struct {");
228 else
229 hdr = lives_strdup("struct {");
230
231 for (int i = 0; leaves[i]; i++) {
232 uint32_t st = weed_leaf_seed_type(plant, leaves[i]);
233 weed_size_t ne = weed_leaf_num_elements(plant, leaves[i]);
234 char *tp;
235 switch (st) {
236 case WEED_SEED_INT: tp = "int "; break;
237 case WEED_SEED_BOOLEAN: tp = "boolean "; break;
238 case WEED_SEED_DOUBLE: tp = "double "; break;
239 case WEED_SEED_STRING: tp = "char *"; break;
240 case WEED_SEED_INT64: tp = "int64_t "; break;
241 case WEED_SEED_FUNCPTR: tp = "lives_func_t *"; break;
242 case WEED_SEED_VOIDPTR: tp = "void *"; break;
243 case WEED_SEED_PLANTPTR: tp = "weed_plant_t *"; break;
244 default: tp = "void *"; break;
245 }
246
247 if (ne > 1) ar = lives_strdup_printf("[%d]", ne);
248 line = lives_strdup_printf("\n %s%s%s;", tp, leaves[i], ar ? ar : "");
249 hdr = lives_concat(hdr, line);
250 if (ar) {
251 lives_free(ar);
252 ar = NULL;
253 }
254 lives_free(leaves[i]);
255 }
256 lives_free(leaves);
257
258 if (!tname)
259 line = lives_strdup("\n}");
260 else
261 line = lives_strdup_printf("\n} %s;", tname);
262 lives_concat(hdr, line);
263 return hdr;
264}
265
LIVES_GLOBAL_INLINE boolean lives_struct_is_a(lives_struct_def_t *lsd, const char *st_type)
Definition: lsd-tab.c:111
boolean tab_inited
Definition: lsd-tab.c:16
LIVES_GLOBAL_INLINE void ref_struct(lives_struct_def_t *lsd)
Definition: lsd-tab.c:94
LIVES_GLOBAL_INLINE void unref_struct(lives_struct_def_t *lsd)
Definition: lsd-tab.c:89
LIVES_GLOBAL_INLINE boolean lives_structs_equal(lives_struct_def_t *lsd, lives_struct_def_t *other)
Definition: lsd-tab.c:105
LIVES_GLOBAL_INLINE boolean lives_structs_same_type(lives_struct_def_t *lsd, lives_struct_def_t *other)
Definition: lsd-tab.c:117
#define errprint(...)
Definition: lsd-tab.c:128
#define CREATOR_ID
Definition: lsd-tab.c:13
LIVES_GLOBAL_INLINE void * copy_struct(lives_struct_def_t *lsd)
Definition: lsd-tab.c:83
uint64_t lsd_check_struct(lives_struct_def_t *lsd)
Definition: lsd-tab.c:131
char * weed_plant_to_header(weed_plant_t *plant, const char *tname)
bonus functions
Definition: lsd-tab.c:222
void * struct_from_template(lives_struct_type st_type)
Definition: lsd-tab.c:76
const lives_struct_def_t * get_lsd(lives_struct_type st_type)
Definition: lsd-tab.c:23
uint64_t lsd_check_match(lives_struct_def_t *lsd1, lives_struct_def_t *lsd2)
Definition: lsd-tab.c:174
LIVES_GLOBAL_INLINE const char * lives_struct_get_creator(lives_struct_def_t *lsd)
Definition: lsd-tab.c:99
lives_struct_type
Definition: lsd-tab.h:11
@ LIVES_N_STRUCTS
Definition: lsd-tab.h:14
@ LIVES_STRUCT_FILE_DETS_T
Definition: lsd-tab.h:13
@ LIVES_STRUCT_CLIP_DATA_T
Definition: lsd-tab.h:12
#define LIVES_FIELD_ARRAY
Definition: lsd.h:174
#define LIVES_FIELD_CHARPTR
Definition: lsd.h:171
#define LIVES_STRUCT_ID
Definition: lsd.h:51
#define LIVES_FIELD_FLAG_ZERO_ON_COPY
Definition: lsd.h:119
#define LIVES_FIELD_FLAG_FREE_ON_DELETE
< field wiill be freed in lives_struct_delete free(struct->field)
Definition: lsd.h:124
LIVES_GLOBAL_INLINE boolean lives_strcmp(const char *st1, const char *st2)
returns FALSE if strings match
LIVES_GLOBAL_INLINE char * lives_concat(char *st, char *x)
#define lives_calloc
Definition: machinestate.h:67
#define lives_free
Definition: machinestate.h:52
#define LIVES_GLOBAL_INLINE
Definition: main.h:239
int * palettes
number forames from one keyframe to the next, 0 if unknown
Definition: plugins.h:375
lives_struct_def_t lsd
Definition: plugins.h:321
char * URI
the URI of this cdata
Definition: plugins.h:334
char author[1024]
Definition: plugins.h:340
char comment[1024]
Definition: plugins.h:341
char title[1024]
Definition: plugins.h:339
char * extra_details
only filled if EXTRA_DETAILS_MD5 is set, otherwis NULL
Definition: machinestate.h:357
lives_struct_def_t * lsd
Definition: machinestate.h:342
112 bytes
Definition: lsd.h:241
lives_special_field_t ** special_fields
user_data for delete_struct_callback
Definition: lsd.h:263
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
#define TRUE
Definition: videoplugin.h:59
#define FALSE
Definition: videoplugin.h:60