Blender  V3.3
dna_utils.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2018 Blender Foundation. */
3 
10 #include <string.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "BLI_assert.h"
15 #include "BLI_ghash.h"
16 #include "BLI_sys_types.h"
17 #include "BLI_utildefines.h"
18 
19 #include "BLI_memarena.h"
20 
21 #include "dna_utils.h"
22 
23 /* -------------------------------------------------------------------- */
27 int DNA_elem_array_size(const char *str)
28 {
29  int result = 1;
30  int current = 0;
31  while (true) {
32  char c = *str++;
33  switch (c) {
34  case '\0':
35  return result;
36  case '[':
37  current = 0;
38  break;
39  case ']':
40  result *= current;
41  break;
42  case '0':
43  case '1':
44  case '2':
45  case '3':
46  case '4':
47  case '5':
48  case '6':
49  case '7':
50  case '8':
51  case '9':
52  current = current * 10 + (c - '0');
53  break;
54  default:
55  break;
56  }
57  }
58 }
59 
62 /* -------------------------------------------------------------------- */
66 static bool is_identifier(const char c)
67 {
68  return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') ||
69  (c == '_'));
70 }
71 
72 uint DNA_elem_id_offset_start(const char *elem_full)
73 {
74  uint elem_full_offset = 0;
75  while (!is_identifier(elem_full[elem_full_offset])) {
76  elem_full_offset++;
77  }
78  return elem_full_offset;
79 }
80 
81 uint DNA_elem_id_offset_end(const char *elem_full)
82 {
83  uint elem_full_offset = 0;
84  while (is_identifier(elem_full[elem_full_offset])) {
85  elem_full_offset++;
86  }
87  return elem_full_offset;
88 }
89 
90 uint DNA_elem_id_strip_copy(char *elem_dst, const char *elem_src)
91 {
92  const uint elem_src_offset = DNA_elem_id_offset_start(elem_src);
93  const char *elem_src_trim = elem_src + elem_src_offset;
94  const uint elem_src_trim_len = DNA_elem_id_offset_end(elem_src_trim);
95  memcpy(elem_dst, elem_src_trim, elem_src_trim_len);
96  elem_dst[elem_src_trim_len] = '\0';
97  return elem_src_trim_len;
98 }
99 
101 {
103  const char *elem_trim = elem + elem_offset;
104  const uint elem_trim_len = DNA_elem_id_offset_end(elem_trim);
105  memmove(elem, elem_trim, elem_trim_len);
106  elem[elem_trim_len] = '\0';
107  return elem_trim_len;
108 }
109 
110 bool DNA_elem_id_match(const char *elem_search,
111  const int elem_search_len,
112  const char *elem_full,
113  uint *r_elem_full_offset)
114 {
115  BLI_assert(strlen(elem_search) == elem_search_len);
116  const uint elem_full_offset = DNA_elem_id_offset_start(elem_full);
117  const char *elem_full_trim = elem_full + elem_full_offset;
118  if (strncmp(elem_search, elem_full_trim, elem_search_len) == 0) {
119  const char c = elem_full_trim[elem_search_len];
120  if (c == '\0' || !is_identifier(c)) {
121  *r_elem_full_offset = elem_full_offset;
122  return true;
123  }
124  }
125  return false;
126 }
127 
129  const char *elem_src,
130  const int elem_src_len,
131  const char *elem_dst,
132  const int elem_dst_len,
133  const char *elem_src_full,
134  const int elem_src_full_len,
135  const uint elem_src_full_offset_len)
136 {
137  BLI_assert(strlen(elem_src) == elem_src_len);
138  BLI_assert(strlen(elem_dst) == elem_dst_len);
139  BLI_assert(strlen(elem_src_full) == elem_src_full_len);
140  BLI_assert(DNA_elem_id_offset_start(elem_src_full) == elem_src_full_offset_len);
141  UNUSED_VARS_NDEBUG(elem_src);
142 
143  const int elem_final_len = (elem_src_full_len - elem_src_len) + elem_dst_len;
144  char *elem_dst_full = BLI_memarena_alloc(mem_arena, elem_final_len + 1);
145  uint i = 0;
146  if (elem_src_full_offset_len != 0) {
147  memcpy(elem_dst_full, elem_src_full, elem_src_full_offset_len);
148  i = elem_src_full_offset_len;
149  }
150  memcpy(&elem_dst_full[i], elem_dst, elem_dst_len + 1);
151  i += elem_dst_len;
152  uint elem_src_full_offset_end = elem_src_full_offset_len + elem_src_len;
153  if (elem_src_full[elem_src_full_offset_end] != '\0') {
154  const int elem_full_tail_len = (elem_src_full_len - elem_src_full_offset_end);
155  memcpy(&elem_dst_full[i], &elem_src_full[elem_src_full_offset_end], elem_full_tail_len + 1);
156  i += elem_full_tail_len;
157  }
158  BLI_assert((strlen(elem_dst_full) == elem_final_len) && (i == elem_final_len));
159  return elem_dst_full;
160 }
161 
164 /* -------------------------------------------------------------------- */
168 static uint strhash_pair_p(const void *ptr)
169 {
170  const char *const *pair = ptr;
171  return (BLI_ghashutil_strhash_p(pair[0]) ^ BLI_ghashutil_strhash_p(pair[1]));
172 }
173 
174 static bool strhash_pair_cmp(const void *a, const void *b)
175 {
176  const char *const *pair_a = a;
177  const char *const *pair_b = b;
178  return (STREQ(pair_a[0], pair_b[0]) && STREQ(pair_a[1], pair_b[1])) ? false : true;
179 }
180 
181 void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_struct_map, GHash **r_elem_map)
182 {
183  GHash *struct_map_local = NULL;
184  if (r_struct_map) {
185  const char *data[][2] = {
186 #define DNA_STRUCT_RENAME(old, new) {#old, #new},
187 #define DNA_STRUCT_RENAME_ELEM(struct_name, old, new)
188 #include "dna_rename_defs.h"
189 #undef DNA_STRUCT_RENAME
190 #undef DNA_STRUCT_RENAME_ELEM
191  };
192 
193  int elem_key, elem_val;
194  if (version_dir == DNA_RENAME_ALIAS_FROM_STATIC) {
195  elem_key = 0;
196  elem_val = 1;
197  }
198  else {
199  elem_key = 1;
200  elem_val = 0;
201  }
202  GHash *struct_map = BLI_ghash_str_new_ex(__func__, ARRAY_SIZE(data));
203  for (int i = 0; i < ARRAY_SIZE(data); i++) {
204  BLI_ghash_insert(struct_map, (void *)data[i][elem_key], (void *)data[i][elem_val]);
205  }
206 
207  if (version_dir == DNA_RENAME_STATIC_FROM_ALIAS) {
208  const char *renames[][2] = {
209  {"uint8_t", "uchar"},
210  {"int16_t", "short"},
211  {"uint16_t", "ushort"},
212  {"int32_t", "int"},
213  {"uint32_t", "int"},
214  };
215  for (int i = 0; i < ARRAY_SIZE(renames); i++) {
216  BLI_ghash_insert(struct_map, (void *)renames[i][0], (void *)renames[i][1]);
217  }
218  }
219 
220  *r_struct_map = struct_map;
221 
222  /* We know the direction of this, for local use. */
223  struct_map_local = BLI_ghash_str_new_ex(__func__, ARRAY_SIZE(data));
224  for (int i = 0; i < ARRAY_SIZE(data); i++) {
225  BLI_ghash_insert(struct_map_local, (void *)data[i][1], (void *)data[i][0]);
226  }
227  }
228 
229  if (r_elem_map != NULL) {
230  const char *data[][3] = {
231 #define DNA_STRUCT_RENAME(old, new)
232 #define DNA_STRUCT_RENAME_ELEM(struct_name, old, new) {#struct_name, #old, #new},
233 #include "dna_rename_defs.h"
234 #undef DNA_STRUCT_RENAME
235 #undef DNA_STRUCT_RENAME_ELEM
236  };
237 
238  int elem_key, elem_val;
239  if (version_dir == DNA_RENAME_ALIAS_FROM_STATIC) {
240  elem_key = 1;
241  elem_val = 2;
242  }
243  else {
244  elem_key = 2;
245  elem_val = 1;
246  }
247  GHash *elem_map = BLI_ghash_new_ex(
249  for (int i = 0; i < ARRAY_SIZE(data); i++) {
250  const char **str_pair = MEM_mallocN(sizeof(char *) * 2, __func__);
251  str_pair[0] = BLI_ghash_lookup_default(struct_map_local, data[i][0], (void *)data[i][0]);
252  str_pair[1] = data[i][elem_key];
253  BLI_ghash_insert(elem_map, (void *)str_pair, (void *)data[i][elem_val]);
254  }
255  *r_elem_map = elem_map;
256  }
257 
258  if (struct_map_local) {
259  BLI_ghash_free(struct_map_local, NULL, NULL);
260  }
261 }
262 
263 #undef DNA_MAKESDNA
264 
267 /* -------------------------------------------------------------------- */
272 {
273  /* Only keep this for compatibility: *NEVER ADD NEW STRINGS HERE*.
274  *
275  * The renaming here isn't complete, references to the old struct names
276  * are still included in DNA, now fixing these struct names properly
277  * breaks forward compatibility. Leave these as-is, but don't add to them!
278  * See D4342#98780. */
279 
280  /* 'bScreen' replaces the old IrisGL 'Screen' struct */
281  if (STREQ("bScreen", name)) {
282  return "Screen";
283  }
284  /* Groups renamed to collections in 2.8 */
285  if (STREQ("Collection", name)) {
286  return "Group";
287  }
288  if (STREQ("CollectionObject", name)) {
289  return "GroupObject";
290  }
291  return name;
292 }
293 
295 {
296  /* 'bScreen' replaces the old IrisGL 'Screen' struct */
297  if (STREQ("Screen", name)) {
298  return "bScreen";
299  }
300  /* Groups renamed to collections in 2.8 */
301  if (STREQ("Group", name)) {
302  return "Collection";
303  }
304  if (STREQ("GroupObject", name)) {
305  return "CollectionObject";
306  }
307  return name;
308 }
309 
312 /* -------------------------------------------------------------------- */
316 void _DNA_internal_memcpy(void *dst, const void *src, size_t size);
317 void _DNA_internal_memcpy(void *dst, const void *src, const size_t size)
318 {
319  memcpy(dst, src, size);
320 }
321 
322 void _DNA_internal_memzero(void *dst, size_t size);
323 void _DNA_internal_memzero(void *dst, const size_t size)
324 {
325  memset(dst, 0, size);
326 }
327 
#define BLI_assert(a)
Definition: BLI_assert.h:46
GHash * BLI_ghash_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
unsigned int BLI_ghashutil_strhash_p(const void *ptr)
void * BLI_ghash_lookup_default(const GHash *gh, const void *key, void *val_default) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:741
GHash * BLI_ghash_new_ex(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:681
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
Definition: BLI_memarena.c:116
unsigned int uint
Definition: BLI_sys_types.h:67
#define ARRAY_SIZE(arr)
#define UNUSED_VARS_NDEBUG(...)
#define STREQ(a, b)
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SyclQueue void void * src
static int elem_offset(const SDNA *sdna, const char *type, const char *name, const SDNA_Struct *old)
Definition: dna_genfile.c:954
static bool strhash_pair_cmp(const void *a, const void *b)
Definition: dna_utils.c:174
void _DNA_internal_memzero(void *dst, size_t size)
Definition: dna_utils.c:323
uint DNA_elem_id_strip(char *elem)
Definition: dna_utils.c:100
const char * DNA_struct_rename_legacy_hack_static_from_alias(const char *name)
Definition: dna_utils.c:271
char * DNA_elem_id_rename(struct MemArena *mem_arena, const char *elem_src, const int elem_src_len, const char *elem_dst, const int elem_dst_len, const char *elem_src_full, const int elem_src_full_len, const uint elem_src_full_offset_len)
Definition: dna_utils.c:128
void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_struct_map, GHash **r_elem_map)
Definition: dna_utils.c:181
uint DNA_elem_id_offset_start(const char *elem_full)
Definition: dna_utils.c:72
void _DNA_internal_memcpy(void *dst, const void *src, size_t size)
Definition: dna_utils.c:317
uint DNA_elem_id_offset_end(const char *elem_full)
Definition: dna_utils.c:81
bool DNA_elem_id_match(const char *elem_search, const int elem_search_len, const char *elem_full, uint *r_elem_full_offset)
Definition: dna_utils.c:110
const char * DNA_struct_rename_legacy_hack_alias_from_static(const char *name)
Definition: dna_utils.c:294
uint DNA_elem_id_strip_copy(char *elem_dst, const char *elem_src)
Definition: dna_utils.c:90
int DNA_elem_array_size(const char *str)
Definition: dna_utils.c:27
static bool is_identifier(const char c)
Definition: dna_utils.c:66
static uint strhash_pair_p(const void *ptr)
Definition: dna_utils.c:168
eDNA_RenameDir
Definition: dna_utils.h:52
@ DNA_RENAME_ALIAS_FROM_STATIC
Definition: dna_utils.h:54
@ DNA_RENAME_STATIC_FROM_ALIAS
Definition: dna_utils.h:53
#define str(s)
static MemArena * mem_arena
Definition: makesdna.c:58
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
PointerRNA * ptr
Definition: wm_files.c:3480