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 
15 static const lives_struct_def_t *lsd_table[LIVES_N_STRUCTS];
16 boolean tab_inited = FALSE;
17 
18 static void init_lsd_tab(void) {
19  for (int i = 0; i < LIVES_N_STRUCTS; i++) lsd_table[i] = NULL;
20  tab_inited = TRUE;
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 |
35  LIVES_FIELD_FLAG_FREE_ON_DELETE, cdata, &cdata->priv,
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 
111 LIVES_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 
222 char *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
#define LIVES_GLOBAL_INLINE
Definition: main.h:239
lives_struct_def_t
112 bytes
Definition: lsd.h:241
copy_struct
LIVES_GLOBAL_INLINE void * copy_struct(lives_struct_def_t *lsd)
Definition: lsd-tab.c:83
lives_file_dets_t::md5sum
char * md5sum
Definition: machinestate.h:356
LIVES_STRUCT_ID
#define LIVES_STRUCT_ID
Definition: lsd.h:51
lives_free
#define lives_free
Definition: machinestate.h:52
lives_file_dets_t::name
char * name
Definition: machinestate.h:343
lives_clip_data_t::URI
char * URI
the URI of this cdata
Definition: plugins.h:334
lives_clip_data_t::title
char title[1024]
Definition: plugins.h:339
lives_clip_data_t::palettes
int * palettes
number forames from one keyframe to the next, 0 if unknown
Definition: plugins.h:375
lives_file_dets_t::extra_details
char * extra_details
only filled if EXTRA_DETAILS_MD5 is set, otherwis NULL
Definition: machinestate.h:357
lives_file_dets_t
Definition: machinestate.h:338
lives_strcmp
LIVES_GLOBAL_INLINE boolean lives_strcmp(const char *st1, const char *st2)
returns FALSE if strings match
Definition: machinestate.c:1506
LIVES_FIELD_CHARPTR
#define LIVES_FIELD_CHARPTR
Definition: lsd.h:171
struct_from_template
void * struct_from_template(lives_struct_type st_type)
Definition: lsd-tab.c:76
tab_inited
boolean tab_inited
Definition: lsd-tab.c:16
lsd_check_match
uint64_t lsd_check_match(lives_struct_def_t *lsd1, lives_struct_def_t *lsd2)
Definition: lsd-tab.c:174
LIVES_FIELD_FLAG_ZERO_ON_COPY
#define LIVES_FIELD_FLAG_ZERO_ON_COPY
Definition: lsd.h:119
LIVES_N_STRUCTS
@ LIVES_N_STRUCTS
Definition: lsd-tab.h:14
LIVES_STRUCT_CLIP_DATA_T
@ LIVES_STRUCT_CLIP_DATA_T
Definition: lsd-tab.h:12
lives_struct_is_a
LIVES_GLOBAL_INLINE boolean lives_struct_is_a(lives_struct_def_t *lsd, const char *st_type)
Definition: lsd-tab.c:111
lives_special_field_t
Definition: lsd.h:228
lives_clip_data_t::lsd
lives_struct_def_t lsd
Definition: plugins.h:321
TRUE
#define TRUE
Definition: videoplugin.h:59
lives_clip_data_t::priv
void * priv
Definition: plugins.h:332
ref_struct
LIVES_GLOBAL_INLINE void ref_struct(lives_struct_def_t *lsd)
Definition: lsd-tab.c:94
lsd_check_struct
uint64_t lsd_check_struct(lives_struct_def_t *lsd)
Definition: lsd-tab.c:131
weed_plant_to_header
char * weed_plant_to_header(weed_plant_t *plant, const char *tname)
bonus functions
Definition: lsd-tab.c:222
LIVES_FIELD_FLAG_FREE_ON_DELETE
#define LIVES_FIELD_FLAG_FREE_ON_DELETE
< field wiill be freed in lives_struct_delete free(struct->field)
Definition: lsd.h:124
lives_strdup_printf
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
lives_calloc
#define lives_calloc
Definition: machinestate.h:67
get_lsd
const lives_struct_def_t * get_lsd(lives_struct_type st_type)
Definition: lsd-tab.c:23
LIVES_STRUCT_FILE_DETS_T
@ LIVES_STRUCT_FILE_DETS_T
Definition: lsd-tab.h:13
unref_struct
LIVES_GLOBAL_INLINE void unref_struct(lives_struct_def_t *lsd)
Definition: lsd-tab.c:89
lives_clip_data_t
Definition: plugins.h:319
lives_clip_data_t::comment
char comment[1024]
Definition: plugins.h:341
main.h
CREATOR_ID
#define CREATOR_ID
Definition: lsd-tab.c:13
lives_struct_get_creator
LIVES_GLOBAL_INLINE const char * lives_struct_get_creator(lives_struct_def_t *lsd)
Definition: lsd-tab.c:99
lives_structs_equal
LIVES_GLOBAL_INLINE boolean lives_structs_equal(lives_struct_def_t *lsd, lives_struct_def_t *other)
Definition: lsd-tab.c:105
lives_structs_same_type
LIVES_GLOBAL_INLINE boolean lives_structs_same_type(lives_struct_def_t *lsd, lives_struct_def_t *other)
Definition: lsd-tab.c:117
lives_struct_def_t::special_fields
lives_special_field_t ** special_fields
user_data for delete_struct_callback
Definition: lsd.h:263
lives_file_dets_t::lsd
lives_struct_def_t * lsd
Definition: machinestate.h:342
lsd.h
lives_struct_type
lives_struct_type
Definition: lsd-tab.h:11
errprint
#define errprint(...)
Definition: lsd-tab.c:128
lives_clip_data_t::author
char author[1024]
Definition: plugins.h:340
LIVES_FIELD_ARRAY
#define LIVES_FIELD_ARRAY
Definition: lsd.h:174
FALSE
#define FALSE
Definition: videoplugin.h:60
lives_concat
LIVES_GLOBAL_INLINE char * lives_concat(char *st, char *x)
Definition: machinestate.c:1426