Cleanup: Blendkernel, Clang-Tidy else-after-return fixes (incomplete)
[blender.git] / source / blender / makesrna / intern / rna_define.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup RNA
19  */
20
21 #include <ctype.h>
22 #include <float.h>
23 #include <limits.h>
24 #include <stddef.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "BLI_utildefines.h"
30 #include "MEM_guardedalloc.h"
31
32 #include "DNA_defaults.h"
33 #include "DNA_genfile.h"
34 #include "DNA_sdna_types.h"
35
36 #include "BLI_ghash.h"
37 #include "BLI_listbase.h"
38
39 #include "BLT_translation.h"
40
41 #include "UI_interface.h" /* For things like UI_PRECISION_FLOAT_MAX... */
42
43 #include "RNA_define.h"
44
45 #include "rna_internal.h"
46
47 #include "CLG_log.h"
48
49 static CLG_LogRef LOG = {"rna.define"};
50
51 #ifdef DEBUG
52 #  define ASSERT_SOFT_HARD_LIMITS \
53     if (softmin < hardmin || softmax > hardmax) { \
54       CLOG_ERROR(&LOG, "error with soft/hard limits: %s.%s", CONTAINER_RNA_ID(cont), identifier); \
55       BLI_assert(!"invalid soft/hard limits"); \
56     } \
57     (void)0
58 #else
59 #  define ASSERT_SOFT_HARD_LIMITS (void)0
60 #endif
61
62 /* Global used during defining */
63
64 BlenderDefRNA DefRNA = {
65     .sdna = NULL,
66     .structs = {NULL, NULL},
67     .allocs = {NULL, NULL},
68     .laststruct = NULL,
69     .error = 0,
70     .silent = false,
71     .preprocess = false,
72     .verify = true,
73     .animate = true,
74     .make_overridable = false,
75 };
76
77 #ifndef RNA_RUNTIME
78 static struct {
79   GHash *struct_map_static_from_alias;
80 } g_version_data;
81 #endif
82
83 #ifndef RNA_RUNTIME
84 /**
85  * When set, report details about which defaults are used.
86  * Noisy but handy when investigating default extraction.
87  */
88 static bool debugSRNA_defaults = false;
89
90 static void print_defult_info(const PropertyDefRNA *dp)
91 {
92   fprintf(stderr,
93           "dna_type=%s, dna_offset=%d, dna_struct=%s, dna_name=%s, id=%s\n",
94           dp->dnatype,
95           dp->dnaoffset,
96           dp->dnastructname,
97           dp->dnaname,
98           dp->prop->identifier);
99 }
100 #endif /* RNA_RUNTIME */
101
102 /* Duplicated code since we can't link in blenkernel or blenlib */
103
104 /* pedantic check for final '.', note '...' are allowed though. */
105 #ifndef NDEBUG
106 #  define DESCR_CHECK(description, id1, id2) \
107     if (description && (description)[0]) { \
108       int i = strlen(description); \
109       if (i > 3 && (description)[i - 1] == '.' && (description)[i - 3] != '.') { \
110         CLOG_WARN(&LOG, \
111                   "'%s' description from '%s' '%s' ends with a '.' !", \
112                   description, \
113                   id1 ? id1 : "", \
114                   id2 ? id2 : ""); \
115       } \
116     } \
117     (void)0
118
119 #else
120 #  define DESCR_CHECK(description, id1, id2)
121 #endif
122
123 void rna_addtail(ListBase *listbase, void *vlink)
124 {
125   Link *link = vlink;
126
127   link->next = NULL;
128   link->prev = listbase->last;
129
130   if (listbase->last) {
131     ((Link *)listbase->last)->next = link;
132   }
133   if (listbase->first == NULL) {
134     listbase->first = link;
135   }
136   listbase->last = link;
137 }
138
139 static void rna_remlink(ListBase *listbase, void *vlink)
140 {
141   Link *link = vlink;
142
143   if (link->next) {
144     link->next->prev = link->prev;
145   }
146   if (link->prev) {
147     link->prev->next = link->next;
148   }
149
150   if (listbase->last == link) {
151     listbase->last = link->prev;
152   }
153   if (listbase->first == link) {
154     listbase->first = link->next;
155   }
156 }
157
158 PropertyDefRNA *rna_findlink(ListBase *listbase, const char *identifier)
159 {
160   Link *link;
161
162   for (link = listbase->first; link; link = link->next) {
163     PropertyRNA *prop = ((PropertyDefRNA *)link)->prop;
164     if (prop && (STREQ(prop->identifier, identifier))) {
165       return (PropertyDefRNA *)link;
166     }
167   }
168
169   return NULL;
170 }
171
172 void rna_freelinkN(ListBase *listbase, void *vlink)
173 {
174   rna_remlink(listbase, vlink);
175   MEM_freeN(vlink);
176 }
177
178 void rna_freelistN(ListBase *listbase)
179 {
180   Link *link, *next;
181
182   for (link = listbase->first; link; link = next) {
183     next = link->next;
184     MEM_freeN(link);
185   }
186
187   listbase->first = listbase->last = NULL;
188 }
189
190 static void rna_brna_structs_add(BlenderRNA *brna, StructRNA *srna)
191 {
192   rna_addtail(&brna->structs, srna);
193   brna->structs_len += 1;
194
195   /* This exception is only needed for pre-processing.
196    * otherwise we don't allow empty names. */
197   if ((srna->flag & STRUCT_PUBLIC_NAMESPACE) && (srna->identifier[0] != '\0')) {
198     BLI_ghash_insert(brna->structs_map, (void *)srna->identifier, srna);
199   }
200 }
201
202 #ifdef RNA_RUNTIME
203 static void rna_brna_structs_remove_and_free(BlenderRNA *brna, StructRNA *srna)
204 {
205   if ((srna->flag & STRUCT_PUBLIC_NAMESPACE) && brna->structs_map) {
206     if (srna->identifier[0] != '\0') {
207       BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL);
208     }
209   }
210
211   RNA_def_struct_free_pointers(NULL, srna);
212
213   if (srna->flag & STRUCT_RUNTIME) {
214     rna_freelinkN(&brna->structs, srna);
215   }
216   brna->structs_len -= 1;
217 }
218 #endif
219
220 static int DNA_struct_find_nr_wrapper(const struct SDNA *sdna, const char *struct_name)
221 {
222   struct_name = DNA_struct_rename_legacy_hack_static_from_alias(struct_name);
223 #ifdef RNA_RUNTIME
224   /* We may support this at some point but for now we don't. */
225   BLI_assert(0);
226 #else
227   struct_name = BLI_ghash_lookup_default(
228       g_version_data.struct_map_static_from_alias, struct_name, (void *)struct_name);
229 #endif
230   return DNA_struct_find_nr(sdna, struct_name);
231 }
232
233 StructDefRNA *rna_find_struct_def(StructRNA *srna)
234 {
235   StructDefRNA *dsrna;
236
237   if (!DefRNA.preprocess) {
238     /* we should never get here */
239     CLOG_ERROR(&LOG, "only at preprocess time.");
240     return NULL;
241   }
242
243   dsrna = DefRNA.structs.last;
244   for (; dsrna; dsrna = dsrna->cont.prev) {
245     if (dsrna->srna == srna) {
246       return dsrna;
247     }
248   }
249
250   return NULL;
251 }
252
253 PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop)
254 {
255   StructDefRNA *dsrna;
256   PropertyDefRNA *dprop;
257
258   if (!DefRNA.preprocess) {
259     /* we should never get here */
260     CLOG_ERROR(&LOG, "only at preprocess time.");
261     return NULL;
262   }
263
264   dsrna = rna_find_struct_def(srna);
265   dprop = dsrna->cont.properties.last;
266   for (; dprop; dprop = dprop->prev) {
267     if (dprop->prop == prop) {
268       return dprop;
269     }
270   }
271
272   dsrna = DefRNA.structs.last;
273   for (; dsrna; dsrna = dsrna->cont.prev) {
274     dprop = dsrna->cont.properties.last;
275     for (; dprop; dprop = dprop->prev) {
276       if (dprop->prop == prop) {
277         return dprop;
278       }
279     }
280   }
281
282   return NULL;
283 }
284
285 #if 0
286 static PropertyDefRNA *rna_find_property_def(PropertyRNA *prop)
287 {
288   PropertyDefRNA *dprop;
289
290   if (!DefRNA.preprocess) {
291     /* we should never get here */
292     CLOG_ERROR(&LOG, "only at preprocess time.");
293     return NULL;
294   }
295
296   dprop = rna_find_struct_property_def(DefRNA.laststruct, prop);
297   if (dprop) {
298     return dprop;
299   }
300
301   dprop = rna_find_parameter_def(prop);
302   if (dprop) {
303     return dprop;
304   }
305
306   return NULL;
307 }
308 #endif
309
310 FunctionDefRNA *rna_find_function_def(FunctionRNA *func)
311 {
312   StructDefRNA *dsrna;
313   FunctionDefRNA *dfunc;
314
315   if (!DefRNA.preprocess) {
316     /* we should never get here */
317     CLOG_ERROR(&LOG, "only at preprocess time.");
318     return NULL;
319   }
320
321   dsrna = rna_find_struct_def(DefRNA.laststruct);
322   dfunc = dsrna->functions.last;
323   for (; dfunc; dfunc = dfunc->cont.prev) {
324     if (dfunc->func == func) {
325       return dfunc;
326     }
327   }
328
329   dsrna = DefRNA.structs.last;
330   for (; dsrna; dsrna = dsrna->cont.prev) {
331     dfunc = dsrna->functions.last;
332     for (; dfunc; dfunc = dfunc->cont.prev) {
333       if (dfunc->func == func) {
334         return dfunc;
335       }
336     }
337   }
338
339   return NULL;
340 }
341
342 PropertyDefRNA *rna_find_parameter_def(PropertyRNA *parm)
343 {
344   StructDefRNA *dsrna;
345   FunctionDefRNA *dfunc;
346   PropertyDefRNA *dparm;
347
348   if (!DefRNA.preprocess) {
349     /* we should never get here */
350     CLOG_ERROR(&LOG, "only at preprocess time.");
351     return NULL;
352   }
353
354   dsrna = rna_find_struct_def(DefRNA.laststruct);
355   dfunc = dsrna->functions.last;
356   for (; dfunc; dfunc = dfunc->cont.prev) {
357     dparm = dfunc->cont.properties.last;
358     for (; dparm; dparm = dparm->prev) {
359       if (dparm->prop == parm) {
360         return dparm;
361       }
362     }
363   }
364
365   dsrna = DefRNA.structs.last;
366   for (; dsrna; dsrna = dsrna->cont.prev) {
367     dfunc = dsrna->functions.last;
368     for (; dfunc; dfunc = dfunc->cont.prev) {
369       dparm = dfunc->cont.properties.last;
370       for (; dparm; dparm = dparm->prev) {
371         if (dparm->prop == parm) {
372           return dparm;
373         }
374       }
375     }
376   }
377
378   return NULL;
379 }
380
381 static ContainerDefRNA *rna_find_container_def(ContainerRNA *cont)
382 {
383   StructDefRNA *ds;
384   FunctionDefRNA *dfunc;
385
386   if (!DefRNA.preprocess) {
387     /* we should never get here */
388     CLOG_ERROR(&LOG, "only at preprocess time.");
389     return NULL;
390   }
391
392   ds = rna_find_struct_def((StructRNA *)cont);
393   if (ds) {
394     return &ds->cont;
395   }
396
397   dfunc = rna_find_function_def((FunctionRNA *)cont);
398   if (dfunc) {
399     return &dfunc->cont;
400   }
401
402   return NULL;
403 }
404
405 /* DNA utility function for looking up members */
406
407 typedef struct DNAStructMember {
408   const char *type;
409   const char *name;
410   int arraylength;
411   int pointerlevel;
412   int offset;
413   int size;
414 } DNAStructMember;
415
416 static int rna_member_cmp(const char *name, const char *oname)
417 {
418   int a = 0;
419
420   /* compare without pointer or array part */
421   while (name[0] == '*') {
422     name++;
423   }
424   while (oname[0] == '*') {
425     oname++;
426   }
427
428   while (1) {
429     if (name[a] == '[' && oname[a] == 0) {
430       return 1;
431     }
432     if (name[a] == '[' && oname[a] == '[') {
433       return 1;
434     }
435     if (name[a] == 0) {
436       break;
437     }
438     if (name[a] != oname[a]) {
439       return 0;
440     }
441     a++;
442   }
443   if (name[a] == 0 && oname[a] == '.') {
444     return 2;
445   }
446   if (name[a] == 0 && oname[a] == '-' && oname[a + 1] == '>') {
447     return 3;
448   }
449
450   return (name[a] == oname[a]);
451 }
452
453 static int rna_find_sdna_member(SDNA *sdna,
454                                 const char *structname,
455                                 const char *membername,
456                                 DNAStructMember *smember,
457                                 int *offset)
458 {
459   const char *dnaname;
460   const short *sp;
461   int a, b, structnr, totmember, cmp;
462
463   if (!DefRNA.preprocess) {
464     CLOG_ERROR(&LOG, "only during preprocessing.");
465     return 0;
466   }
467   structnr = DNA_struct_find_nr_wrapper(sdna, structname);
468
469   smember->offset = -1;
470   if (structnr == -1) {
471     if (offset) {
472       *offset = -1;
473     }
474     return 0;
475   }
476
477   sp = sdna->structs[structnr];
478   totmember = sp[1];
479   sp += 2;
480
481   for (a = 0; a < totmember; a++, sp += 2) {
482     const int size = DNA_elem_size_nr(sdna, sp[0], sp[1]);
483     dnaname = sdna->alias.names[sp[1]];
484     cmp = rna_member_cmp(dnaname, membername);
485
486     if (cmp == 1) {
487       smember->type = sdna->alias.types[sp[0]];
488       smember->name = dnaname;
489       smember->offset = *offset;
490       smember->size = size;
491
492       if (strstr(membername, "[")) {
493         smember->arraylength = 0;
494       }
495       else {
496         smember->arraylength = DNA_elem_array_size(smember->name);
497       }
498
499       smember->pointerlevel = 0;
500       for (b = 0; dnaname[b] == '*'; b++) {
501         smember->pointerlevel++;
502       }
503
504       return 1;
505     }
506     else if (cmp == 2) {
507       smember->type = "";
508       smember->name = dnaname;
509       smember->offset = *offset;
510       smember->size = size;
511       smember->pointerlevel = 0;
512       smember->arraylength = 0;
513
514       membername = strstr(membername, ".") + strlen(".");
515       rna_find_sdna_member(sdna, sdna->alias.types[sp[0]], membername, smember, offset);
516
517       return 1;
518     }
519     else if (cmp == 3) {
520       smember->type = "";
521       smember->name = dnaname;
522       smember->offset = *offset;
523       smember->size = size;
524       smember->pointerlevel = 0;
525       smember->arraylength = 0;
526
527       if (offset) {
528         *offset = -1;
529       }
530       membername = strstr(membername, "->") + strlen("->");
531       rna_find_sdna_member(sdna, sdna->alias.types[sp[0]], membername, smember, offset);
532
533       return 1;
534     }
535
536     if (offset && *offset != -1) {
537       *offset += size;
538     }
539   }
540
541   return 0;
542 }
543
544 static int rna_validate_identifier(const char *identifier, char *error, bool property)
545 {
546   int a = 0;
547
548   /** List is from:
549    * \code{.py}
550    * ", ".join([
551    *     '"%s"' % kw for kw in __import__("keyword").kwlist
552    *     if kw not in {"False", "None", "True"}
553    * ])
554    * \endcode
555    */
556   static const char *kwlist[] = {
557       /* "False", "None", "True", */
558       "and",    "as",   "assert", "async",  "await",    "break", "class", "continue", "def",
559       "del",    "elif", "else",   "except", "finally",  "for",   "from",  "global",   "if",
560       "import", "in",   "is",     "lambda", "nonlocal", "not",   "or",    "pass",     "raise",
561       "return", "try",  "while",  "with",   "yield",    NULL,
562   };
563
564   if (!isalpha(identifier[0])) {
565     strcpy(error, "first character failed isalpha() check");
566     return 0;
567   }
568
569   for (a = 0; identifier[a]; a++) {
570     if (DefRNA.preprocess && property) {
571       if (isalpha(identifier[a]) && isupper(identifier[a])) {
572         strcpy(error, "property names must contain lower case characters only");
573         return 0;
574       }
575     }
576
577     if (identifier[a] == '_') {
578       continue;
579     }
580
581     if (identifier[a] == ' ') {
582       strcpy(error, "spaces are not okay in identifier names");
583       return 0;
584     }
585
586     if (isalnum(identifier[a]) == 0) {
587       strcpy(error, "one of the characters failed an isalnum() check and is not an underscore");
588       return 0;
589     }
590   }
591
592   for (a = 0; kwlist[a]; a++) {
593     if (STREQ(identifier, kwlist[a])) {
594       strcpy(error, "this keyword is reserved by python");
595       return 0;
596     }
597   }
598
599   if (property) {
600     static const char *kwlist_prop[] = {
601         /* not keywords but reserved all the same because py uses */
602         "keys",
603         "values",
604         "items",
605         "get",
606         NULL,
607     };
608
609     for (a = 0; kwlist_prop[a]; a++) {
610       if (STREQ(identifier, kwlist_prop[a])) {
611         strcpy(error, "this keyword is reserved by python");
612         return 0;
613       }
614     }
615   }
616
617   return 1;
618 }
619
620 void RNA_identifier_sanitize(char *identifier, int property)
621 {
622   int a = 0;
623
624   /*  list from http://docs.python.org/py3k/reference/lexical_analysis.html#keywords */
625   static const char *kwlist[] = {
626       /* "False", "None", "True", */
627       "and",    "as",     "assert", "break",   "class",    "continue", "def",    "del",
628       "elif",   "else",   "except", "finally", "for",      "from",     "global", "if",
629       "import", "in",     "is",     "lambda",  "nonlocal", "not",      "or",     "pass",
630       "raise",  "return", "try",    "while",   "with",     "yield",    NULL,
631   };
632
633   if (!isalpha(identifier[0])) {
634     /* first character failed isalpha() check */
635     identifier[0] = '_';
636   }
637
638   for (a = 0; identifier[a]; a++) {
639     if (DefRNA.preprocess && property) {
640       if (isalpha(identifier[a]) && isupper(identifier[a])) {
641         /* property names must contain lower case characters only */
642         identifier[a] = tolower(identifier[a]);
643       }
644     }
645
646     if (identifier[a] == '_') {
647       continue;
648     }
649
650     if (identifier[a] == ' ') {
651       /* spaces are not okay in identifier names */
652       identifier[a] = '_';
653     }
654
655     if (isalnum(identifier[a]) == 0) {
656       /* one of the characters failed an isalnum() check and is not an underscore */
657       identifier[a] = '_';
658     }
659   }
660
661   for (a = 0; kwlist[a]; a++) {
662     if (STREQ(identifier, kwlist[a])) {
663       /* this keyword is reserved by python.
664        * just replace the last character by '_' to keep it readable.
665        */
666       identifier[strlen(identifier) - 1] = '_';
667       break;
668     }
669   }
670
671   if (property) {
672     static const char *kwlist_prop[] = {
673         /* not keywords but reserved all the same because py uses */
674         "keys",
675         "values",
676         "items",
677         "get",
678         NULL,
679     };
680
681     for (a = 0; kwlist_prop[a]; a++) {
682       if (STREQ(identifier, kwlist_prop[a])) {
683         /* this keyword is reserved by python.
684          * just replace the last character by '_' to keep it readable.
685          */
686         identifier[strlen(identifier) - 1] = '_';
687         break;
688       }
689     }
690   }
691 }
692
693 /* Blender Data Definition */
694
695 BlenderRNA *RNA_create(void)
696 {
697   BlenderRNA *brna;
698
699   brna = MEM_callocN(sizeof(BlenderRNA), "BlenderRNA");
700   const char *error_message = NULL;
701
702   BLI_listbase_clear(&DefRNA.structs);
703   brna->structs_map = BLI_ghash_str_new_ex(__func__, 2048);
704
705   DefRNA.error = false;
706   DefRNA.preprocess = true;
707
708   DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, &error_message);
709   if (DefRNA.sdna == NULL) {
710     CLOG_ERROR(&LOG, "Failed to decode SDNA: %s.", error_message);
711     DefRNA.error = true;
712   }
713
714   /* We need both alias and static (on-disk) DNA names. */
715   DNA_sdna_alias_data_ensure(DefRNA.sdna);
716
717 #ifndef RNA_RUNTIME
718   DNA_alias_maps(DNA_RENAME_STATIC_FROM_ALIAS, &g_version_data.struct_map_static_from_alias, NULL);
719 #endif
720
721   return brna;
722 }
723
724 void RNA_define_free(BlenderRNA *UNUSED(brna))
725 {
726   StructDefRNA *ds;
727   FunctionDefRNA *dfunc;
728   AllocDefRNA *alloc;
729
730   for (alloc = DefRNA.allocs.first; alloc; alloc = alloc->next) {
731     MEM_freeN(alloc->mem);
732   }
733   rna_freelistN(&DefRNA.allocs);
734
735   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
736     for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) {
737       rna_freelistN(&dfunc->cont.properties);
738     }
739
740     rna_freelistN(&ds->cont.properties);
741     rna_freelistN(&ds->functions);
742   }
743
744   rna_freelistN(&DefRNA.structs);
745
746   if (DefRNA.sdna) {
747     DNA_sdna_free(DefRNA.sdna);
748     DefRNA.sdna = NULL;
749   }
750
751   DefRNA.error = false;
752 }
753
754 void RNA_define_verify_sdna(bool verify)
755 {
756   DefRNA.verify = verify;
757 }
758
759 /**
760  * Properties defined when this is enabled are lib-overridable by default (except for Pointer
761  * ones).
762  */
763 void RNA_define_lib_overridable(const bool make_overridable)
764 {
765   DefRNA.make_overridable = make_overridable;
766 }
767
768 #ifndef RNA_RUNTIME
769 void RNA_define_animate_sdna(bool animate)
770 {
771   DefRNA.animate = animate;
772 }
773 #endif
774
775 #ifndef RNA_RUNTIME
776 void RNA_define_fallback_property_update(int noteflag, const char *updatefunc)
777 {
778   DefRNA.fallback.property_update.noteflag = noteflag;
779   DefRNA.fallback.property_update.updatefunc = updatefunc;
780 }
781 #endif
782
783 void RNA_struct_free_extension(StructRNA *srna, ExtensionRNA *rna_ext)
784 {
785 #ifdef RNA_RUNTIME
786   rna_ext->free(rna_ext->data);            /* decref's the PyObject that the srna owns */
787   RNA_struct_blender_type_set(srna, NULL); /* this gets accessed again - XXX fixme */
788
789   /* NULL the srna's value so RNA_struct_free wont complain of a leak */
790   RNA_struct_py_type_set(srna, NULL);
791
792 #else
793   (void)srna;
794   (void)rna_ext;
795 #endif
796 }
797
798 void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
799 {
800 #ifdef RNA_RUNTIME
801   FunctionRNA *func, *nextfunc;
802   PropertyRNA *prop, *nextprop;
803   PropertyRNA *parm, *nextparm;
804
805 #  if 0
806   if (srna->flag & STRUCT_RUNTIME) {
807     if (RNA_struct_py_type_get(srna)) {
808       fprintf(stderr, "%s '%s' freed while holding a python reference.", srna->identifier);
809     }
810   }
811 #  endif
812
813   for (prop = srna->cont.properties.first; prop; prop = nextprop) {
814     nextprop = prop->next;
815
816     RNA_def_property_free_pointers(prop);
817
818     if (prop->flag_internal & PROP_INTERN_RUNTIME) {
819       rna_freelinkN(&srna->cont.properties, prop);
820     }
821   }
822
823   for (func = srna->functions.first; func; func = nextfunc) {
824     nextfunc = func->cont.next;
825
826     for (parm = func->cont.properties.first; parm; parm = nextparm) {
827       nextparm = parm->next;
828
829       RNA_def_property_free_pointers(parm);
830
831       if (parm->flag_internal & PROP_INTERN_RUNTIME) {
832         rna_freelinkN(&func->cont.properties, parm);
833       }
834     }
835
836     RNA_def_func_free_pointers(func);
837
838     if (func->flag & FUNC_RUNTIME) {
839       rna_freelinkN(&srna->functions, func);
840     }
841   }
842
843   rna_brna_structs_remove_and_free(brna, srna);
844 #else
845   UNUSED_VARS(brna, srna);
846 #endif
847 }
848
849 void RNA_free(BlenderRNA *brna)
850 {
851   StructRNA *srna, *nextsrna;
852   FunctionRNA *func;
853
854   BLI_ghash_free(brna->structs_map, NULL, NULL);
855   brna->structs_map = NULL;
856
857   if (DefRNA.preprocess) {
858     RNA_define_free(brna);
859
860     for (srna = brna->structs.first; srna; srna = srna->cont.next) {
861       for (func = srna->functions.first; func; func = func->cont.next) {
862         rna_freelistN(&func->cont.properties);
863       }
864
865       rna_freelistN(&srna->cont.properties);
866       rna_freelistN(&srna->functions);
867     }
868
869     rna_freelistN(&brna->structs);
870
871     MEM_freeN(brna);
872   }
873   else {
874     for (srna = brna->structs.first; srna; srna = nextsrna) {
875       nextsrna = srna->cont.next;
876       RNA_struct_free(brna, srna);
877     }
878   }
879
880 #ifndef RNA_RUNTIME
881   BLI_ghash_free(g_version_data.struct_map_static_from_alias, NULL, NULL);
882   g_version_data.struct_map_static_from_alias = NULL;
883 #endif
884 }
885
886 static size_t rna_property_type_sizeof(PropertyType type)
887 {
888   switch (type) {
889     case PROP_BOOLEAN:
890       return sizeof(BoolPropertyRNA);
891     case PROP_INT:
892       return sizeof(IntPropertyRNA);
893     case PROP_FLOAT:
894       return sizeof(FloatPropertyRNA);
895     case PROP_STRING:
896       return sizeof(StringPropertyRNA);
897     case PROP_ENUM:
898       return sizeof(EnumPropertyRNA);
899     case PROP_POINTER:
900       return sizeof(PointerPropertyRNA);
901     case PROP_COLLECTION:
902       return sizeof(CollectionPropertyRNA);
903     default:
904       return 0;
905   }
906 }
907
908 static StructDefRNA *rna_find_def_struct(StructRNA *srna)
909 {
910   StructDefRNA *ds;
911
912   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
913     if (ds->srna == srna) {
914       return ds;
915     }
916   }
917
918   return NULL;
919 }
920
921 /* Struct Definition */
922 StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
923 {
924   StructRNA *srna;
925   StructDefRNA *ds = NULL, *dsfrom = NULL;
926   PropertyRNA *prop;
927
928   if (DefRNA.preprocess) {
929     char error[512];
930
931     if (rna_validate_identifier(identifier, error, false) == 0) {
932       CLOG_ERROR(&LOG, "struct identifier \"%s\" error - %s", identifier, error);
933       DefRNA.error = true;
934     }
935   }
936
937   srna = MEM_callocN(sizeof(StructRNA), "StructRNA");
938   DefRNA.laststruct = srna;
939
940   if (srnafrom) {
941     /* copy from struct to derive stuff, a bit clumsy since we can't
942      * use MEM_dupallocN, data structs may not be alloced but builtin */
943     memcpy(srna, srnafrom, sizeof(StructRNA));
944     srna->cont.prophash = NULL;
945     BLI_listbase_clear(&srna->cont.properties);
946     BLI_listbase_clear(&srna->functions);
947     srna->py_type = NULL;
948
949     srna->base = srnafrom;
950
951     if (DefRNA.preprocess) {
952       dsfrom = rna_find_def_struct(srnafrom);
953     }
954     else {
955       if (srnafrom->flag & STRUCT_PUBLIC_NAMESPACE_INHERIT) {
956         srna->flag |= STRUCT_PUBLIC_NAMESPACE | STRUCT_PUBLIC_NAMESPACE_INHERIT;
957       }
958       else {
959         srna->flag &= ~(STRUCT_PUBLIC_NAMESPACE | STRUCT_PUBLIC_NAMESPACE_INHERIT);
960       }
961     }
962   }
963
964   srna->identifier = identifier;
965   srna->name = identifier; /* may be overwritten later RNA_def_struct_ui_text */
966   srna->description = "";
967   /* may be overwritten later RNA_def_struct_translation_context */
968   srna->translation_context = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
969   if (!srnafrom) {
970     srna->icon = ICON_DOT;
971     srna->flag |= STRUCT_UNDO;
972   }
973
974   if (DefRNA.preprocess) {
975     srna->flag |= STRUCT_PUBLIC_NAMESPACE;
976   }
977
978   rna_brna_structs_add(brna, srna);
979
980   if (DefRNA.preprocess) {
981     ds = MEM_callocN(sizeof(StructDefRNA), "StructDefRNA");
982     ds->srna = srna;
983     rna_addtail(&DefRNA.structs, ds);
984
985     if (dsfrom) {
986       ds->dnafromname = dsfrom->dnaname;
987     }
988   }
989
990   /* in preprocess, try to find sdna */
991   if (DefRNA.preprocess) {
992     RNA_def_struct_sdna(srna, srna->identifier);
993   }
994   else {
995     srna->flag |= STRUCT_RUNTIME;
996   }
997
998   if (srnafrom) {
999     srna->nameproperty = srnafrom->nameproperty;
1000     srna->iteratorproperty = srnafrom->iteratorproperty;
1001   }
1002   else {
1003     /* define some builtin properties */
1004     prop = RNA_def_property(&srna->cont, "rna_properties", PROP_COLLECTION, PROP_NONE);
1005     prop->flag_internal |= PROP_INTERN_BUILTIN;
1006     RNA_def_property_ui_text(prop, "Properties", "RNA property collection");
1007
1008     if (DefRNA.preprocess) {
1009       RNA_def_property_struct_type(prop, "Property");
1010       RNA_def_property_collection_funcs(prop,
1011                                         "rna_builtin_properties_begin",
1012                                         "rna_builtin_properties_next",
1013                                         "rna_iterator_listbase_end",
1014                                         "rna_builtin_properties_get",
1015                                         NULL,
1016                                         NULL,
1017                                         "rna_builtin_properties_lookup_string",
1018                                         NULL);
1019     }
1020     else {
1021 #ifdef RNA_RUNTIME
1022       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1023       cprop->begin = rna_builtin_properties_begin;
1024       cprop->next = rna_builtin_properties_next;
1025       cprop->get = rna_builtin_properties_get;
1026       cprop->item_type = &RNA_Property;
1027 #endif
1028     }
1029
1030     prop = RNA_def_property(&srna->cont, "rna_type", PROP_POINTER, PROP_NONE);
1031     RNA_def_property_flag(prop, PROP_HIDDEN);
1032     RNA_def_property_ui_text(prop, "RNA", "RNA type definition");
1033
1034     if (DefRNA.preprocess) {
1035       RNA_def_property_struct_type(prop, "Struct");
1036       RNA_def_property_pointer_funcs(prop, "rna_builtin_type_get", NULL, NULL, NULL);
1037     }
1038     else {
1039 #ifdef RNA_RUNTIME
1040       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1041       pprop->get = rna_builtin_type_get;
1042       pprop->type = &RNA_Struct;
1043 #endif
1044     }
1045   }
1046
1047   return srna;
1048 }
1049
1050 StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
1051 {
1052   StructRNA *srnafrom = NULL;
1053
1054   /* only use RNA_def_struct() while pre-processing, otherwise use RNA_def_struct_ptr() */
1055   BLI_assert(DefRNA.preprocess);
1056
1057   if (from) {
1058     /* find struct to derive from */
1059     /* Inline RNA_struct_find(...) because it wont link from here. */
1060     srnafrom = BLI_ghash_lookup(brna->structs_map, from);
1061     if (!srnafrom) {
1062       CLOG_ERROR(&LOG, "struct %s not found to define %s.", from, identifier);
1063       DefRNA.error = true;
1064     }
1065   }
1066
1067   return RNA_def_struct_ptr(brna, identifier, srnafrom);
1068 }
1069
1070 void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
1071 {
1072   StructDefRNA *ds;
1073
1074   if (!DefRNA.preprocess) {
1075     CLOG_ERROR(&LOG, "only during preprocessing.");
1076     return;
1077   }
1078
1079   ds = rna_find_def_struct(srna);
1080
1081   /* There are far too many structs which initialize without valid DNA struct names,
1082    * this can't be checked without adding an option to disable
1083    * (tested this and it means changes all over - Campbell) */
1084 #if 0
1085   if (DNA_struct_find_nr_wrapper(DefRNA.sdna, structname) == -1) {
1086     if (!DefRNA.silent) {
1087       CLOG_ERROR(&LOG, "%s not found.", structname);
1088       DefRNA.error = true;
1089     }
1090     return;
1091   }
1092 #endif
1093
1094   ds->dnaname = structname;
1095 }
1096
1097 void RNA_def_struct_sdna_from(StructRNA *srna, const char *structname, const char *propname)
1098 {
1099   StructDefRNA *ds;
1100
1101   if (!DefRNA.preprocess) {
1102     CLOG_ERROR(&LOG, "only during preprocessing.");
1103     return;
1104   }
1105
1106   ds = rna_find_def_struct(srna);
1107
1108   if (!ds->dnaname) {
1109     CLOG_ERROR(&LOG, "%s base struct must know DNA already.", structname);
1110     return;
1111   }
1112
1113   if (DNA_struct_find_nr_wrapper(DefRNA.sdna, structname) == -1) {
1114     if (!DefRNA.silent) {
1115       CLOG_ERROR(&LOG, "%s not found.", structname);
1116       DefRNA.error = true;
1117     }
1118     return;
1119   }
1120
1121   ds->dnafromprop = propname;
1122   ds->dnaname = structname;
1123 }
1124
1125 void RNA_def_struct_name_property(struct StructRNA *srna, struct PropertyRNA *prop)
1126 {
1127   if (prop->type != PROP_STRING) {
1128     CLOG_ERROR(&LOG, "\"%s.%s\", must be a string property.", srna->identifier, prop->identifier);
1129     DefRNA.error = true;
1130   }
1131   else {
1132     srna->nameproperty = prop;
1133   }
1134 }
1135
1136 void RNA_def_struct_nested(BlenderRNA *brna, StructRNA *srna, const char *structname)
1137 {
1138   StructRNA *srnafrom;
1139
1140   /* find struct to derive from */
1141   srnafrom = BLI_ghash_lookup(brna->structs_map, structname);
1142   if (!srnafrom) {
1143     CLOG_ERROR(&LOG, "struct %s not found for %s.", structname, srna->identifier);
1144     DefRNA.error = true;
1145   }
1146
1147   srna->nested = srnafrom;
1148 }
1149
1150 void RNA_def_struct_flag(StructRNA *srna, int flag)
1151 {
1152   srna->flag |= flag;
1153 }
1154
1155 void RNA_def_struct_clear_flag(StructRNA *srna, int flag)
1156 {
1157   srna->flag &= ~flag;
1158 }
1159
1160 void RNA_def_struct_property_tags(StructRNA *srna, const EnumPropertyItem *prop_tag_defines)
1161 {
1162   srna->prop_tag_defines = prop_tag_defines;
1163 }
1164
1165 void RNA_def_struct_refine_func(StructRNA *srna, const char *refine)
1166 {
1167   if (!DefRNA.preprocess) {
1168     CLOG_ERROR(&LOG, "only during preprocessing.");
1169     return;
1170   }
1171
1172   if (refine) {
1173     srna->refine = (StructRefineFunc)refine;
1174   }
1175 }
1176
1177 void RNA_def_struct_idprops_func(StructRNA *srna, const char *idproperties)
1178 {
1179   if (!DefRNA.preprocess) {
1180     CLOG_ERROR(&LOG, "only during preprocessing.");
1181     return;
1182   }
1183
1184   if (idproperties) {
1185     srna->idproperties = (IDPropertiesFunc)idproperties;
1186   }
1187 }
1188
1189 void RNA_def_struct_register_funcs(StructRNA *srna,
1190                                    const char *reg,
1191                                    const char *unreg,
1192                                    const char *instance)
1193 {
1194   if (!DefRNA.preprocess) {
1195     CLOG_ERROR(&LOG, "only during preprocessing.");
1196     return;
1197   }
1198
1199   if (reg) {
1200     srna->reg = (StructRegisterFunc)reg;
1201   }
1202   if (unreg) {
1203     srna->unreg = (StructUnregisterFunc)unreg;
1204   }
1205   if (instance) {
1206     srna->instance = (StructInstanceFunc)instance;
1207   }
1208 }
1209
1210 void RNA_def_struct_path_func(StructRNA *srna, const char *path)
1211 {
1212   if (!DefRNA.preprocess) {
1213     CLOG_ERROR(&LOG, "only during preprocessing.");
1214     return;
1215   }
1216
1217   if (path) {
1218     srna->path = (StructPathFunc)path;
1219   }
1220 }
1221
1222 void RNA_def_struct_identifier(BlenderRNA *brna, StructRNA *srna, const char *identifier)
1223 {
1224   if (DefRNA.preprocess) {
1225     CLOG_ERROR(&LOG, "only at runtime.");
1226     return;
1227   }
1228
1229   /* Operator registration may set twice, see: operator_properties_init */
1230   if (srna->flag & STRUCT_PUBLIC_NAMESPACE) {
1231     if (identifier != srna->identifier) {
1232       if (srna->identifier[0] != '\0') {
1233         BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL);
1234       }
1235       if (identifier[0] != '\0') {
1236         BLI_ghash_insert(brna->structs_map, (void *)identifier, srna);
1237       }
1238     }
1239   }
1240
1241   srna->identifier = identifier;
1242 }
1243
1244 /**
1245  * Only used in one case when we name the struct for the purpose of useful error messages.
1246  */
1247 void RNA_def_struct_identifier_no_struct_map(StructRNA *srna, const char *identifier)
1248 {
1249   if (DefRNA.preprocess) {
1250     CLOG_ERROR(&LOG, "only at runtime.");
1251     return;
1252   }
1253
1254   srna->identifier = identifier;
1255 }
1256
1257 void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
1258 {
1259   DESCR_CHECK(description, srna->identifier, NULL);
1260
1261   srna->name = name;
1262   srna->description = description;
1263 }
1264
1265 void RNA_def_struct_ui_icon(StructRNA *srna, int icon)
1266 {
1267   srna->icon = icon;
1268 }
1269
1270 void RNA_def_struct_translation_context(StructRNA *srna, const char *context)
1271 {
1272   srna->translation_context = context ? context : BLT_I18NCONTEXT_DEFAULT_BPYRNA;
1273 }
1274
1275 /* Property Definition */
1276
1277 PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_,
1278                               const char *identifier,
1279                               int type,
1280                               int subtype)
1281 {
1282   /*StructRNA *srna = DefRNA.laststruct;*/ /* invalid for python defined props */
1283   ContainerRNA *cont = cont_;
1284   ContainerDefRNA *dcont;
1285   PropertyDefRNA *dprop = NULL;
1286   PropertyRNA *prop;
1287
1288   if (DefRNA.preprocess) {
1289     char error[512];
1290
1291     if (rna_validate_identifier(identifier, error, true) == 0) {
1292       CLOG_ERROR(
1293           &LOG, "property identifier \"%s.%s\" - %s", CONTAINER_RNA_ID(cont), identifier, error);
1294       DefRNA.error = true;
1295     }
1296
1297     dcont = rna_find_container_def(cont);
1298
1299     /* XXX - toto, detect supertype collisions */
1300     if (rna_findlink(&dcont->properties, identifier)) {
1301       CLOG_ERROR(&LOG, "duplicate identifier \"%s.%s\"", CONTAINER_RNA_ID(cont), identifier);
1302       DefRNA.error = true;
1303     }
1304
1305     dprop = MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
1306     rna_addtail(&dcont->properties, dprop);
1307   }
1308   else {
1309 #ifdef DEBUG
1310     char error[512];
1311     if (rna_validate_identifier(identifier, error, true) == 0) {
1312       CLOG_ERROR(&LOG,
1313                  "runtime property identifier \"%s.%s\" - %s",
1314                  CONTAINER_RNA_ID(cont),
1315                  identifier,
1316                  error);
1317       DefRNA.error = true;
1318     }
1319 #endif
1320   }
1321
1322   prop = MEM_callocN(rna_property_type_sizeof(type), "PropertyRNA");
1323
1324   switch (type) {
1325     case PROP_BOOLEAN:
1326       if (DefRNA.preprocess) {
1327         if ((subtype & ~PROP_LAYER_MEMBER) != PROP_NONE) {
1328           CLOG_ERROR(&LOG,
1329                      "subtype does not apply to 'PROP_BOOLEAN' \"%s.%s\"",
1330                      CONTAINER_RNA_ID(cont),
1331                      identifier);
1332           DefRNA.error = true;
1333         }
1334       }
1335       break;
1336     case PROP_INT: {
1337       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1338
1339 #ifndef RNA_RUNTIME
1340       if (subtype == PROP_DISTANCE) {
1341         CLOG_ERROR(&LOG,
1342                    "subtype does not apply to 'PROP_INT' \"%s.%s\"",
1343                    CONTAINER_RNA_ID(cont),
1344                    identifier);
1345         DefRNA.error = true;
1346       }
1347 #endif
1348
1349       iprop->hardmin = (subtype == PROP_UNSIGNED) ? 0 : INT_MIN;
1350       iprop->hardmax = INT_MAX;
1351
1352       iprop->softmin = (subtype == PROP_UNSIGNED) ? 0 : -10000; /* rather arbitrary .. */
1353       iprop->softmax = 10000;
1354       iprop->step = 1;
1355       break;
1356     }
1357     case PROP_FLOAT: {
1358       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1359
1360       fprop->hardmin = (subtype == PROP_UNSIGNED) ? 0.0f : -FLT_MAX;
1361       fprop->hardmax = FLT_MAX;
1362
1363       if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
1364         fprop->softmin = fprop->hardmin = 0.0f;
1365         fprop->softmax = 1.0f;
1366       }
1367       else if (subtype == PROP_FACTOR) {
1368         fprop->softmin = fprop->hardmin = 0.0f;
1369         fprop->softmax = fprop->hardmax = 1.0f;
1370       }
1371       else {
1372         fprop->softmin = (subtype == PROP_UNSIGNED) ? 0.0f : -10000.0f; /* rather arbitrary .. */
1373         fprop->softmax = 10000.0f;
1374       }
1375       fprop->step = 10;
1376       fprop->precision = 3;
1377       break;
1378     }
1379     case PROP_STRING: {
1380       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
1381       /* By default don't allow NULL string args, callers may clear. */
1382       RNA_def_property_flag(prop, PROP_NEVER_NULL);
1383       sprop->defaultvalue = "";
1384       break;
1385     }
1386     case PROP_POINTER:
1387       prop->flag |= PROP_THICK_WRAP; /* needed for default behavior when PARM_RNAPTR is set */
1388       break;
1389     case PROP_ENUM:
1390     case PROP_COLLECTION:
1391       break;
1392     default:
1393       CLOG_ERROR(&LOG, "\"%s.%s\", invalid property type.", CONTAINER_RNA_ID(cont), identifier);
1394       DefRNA.error = true;
1395       return NULL;
1396   }
1397
1398   if (DefRNA.preprocess) {
1399     dprop->cont = cont;
1400     dprop->prop = prop;
1401   }
1402
1403   prop->magic = RNA_MAGIC;
1404   prop->identifier = identifier;
1405   prop->type = type;
1406   prop->subtype = subtype;
1407   prop->name = identifier;
1408   prop->description = "";
1409   prop->translation_context = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
1410   /* a priori not raw editable */
1411   prop->rawtype = -1;
1412
1413   if (type != PROP_COLLECTION && type != PROP_POINTER) {
1414     prop->flag = PROP_EDITABLE;
1415
1416     if (type != PROP_STRING) {
1417 #ifdef RNA_RUNTIME
1418       prop->flag |= PROP_ANIMATABLE;
1419 #else
1420       if (DefRNA.animate) {
1421         prop->flag |= PROP_ANIMATABLE;
1422       }
1423 #endif
1424     }
1425   }
1426
1427 #ifndef RNA_RUNTIME
1428   if (DefRNA.make_overridable) {
1429     prop->flag_override |= PROPOVERRIDE_OVERRIDABLE_LIBRARY;
1430   }
1431 #endif
1432
1433   if (type == PROP_STRING) {
1434     /* used so generated 'get/length/set' functions skip a NULL check
1435      * in some cases we want it */
1436     RNA_def_property_flag(prop, PROP_NEVER_NULL);
1437   }
1438
1439   if (DefRNA.preprocess) {
1440     switch (type) {
1441       case PROP_BOOLEAN:
1442         DefRNA.silent = true;
1443         RNA_def_property_boolean_sdna(prop, NULL, identifier, 0);
1444         DefRNA.silent = false;
1445         break;
1446       case PROP_INT: {
1447         DefRNA.silent = true;
1448         RNA_def_property_int_sdna(prop, NULL, identifier);
1449         DefRNA.silent = false;
1450         break;
1451       }
1452       case PROP_FLOAT: {
1453         DefRNA.silent = true;
1454         RNA_def_property_float_sdna(prop, NULL, identifier);
1455         DefRNA.silent = false;
1456         break;
1457       }
1458       case PROP_STRING: {
1459         DefRNA.silent = true;
1460         RNA_def_property_string_sdna(prop, NULL, identifier);
1461         DefRNA.silent = false;
1462         break;
1463       }
1464       case PROP_ENUM:
1465         DefRNA.silent = true;
1466         RNA_def_property_enum_sdna(prop, NULL, identifier);
1467         DefRNA.silent = false;
1468         break;
1469       case PROP_POINTER:
1470         DefRNA.silent = true;
1471         RNA_def_property_pointer_sdna(prop, NULL, identifier);
1472         DefRNA.silent = false;
1473         break;
1474       case PROP_COLLECTION:
1475         DefRNA.silent = true;
1476         RNA_def_property_collection_sdna(prop, NULL, identifier, NULL);
1477         DefRNA.silent = false;
1478         break;
1479     }
1480   }
1481   else {
1482     prop->flag |= PROP_IDPROPERTY;
1483     prop->flag_internal |= PROP_INTERN_RUNTIME;
1484 #ifdef RNA_RUNTIME
1485     if (cont->prophash) {
1486       BLI_ghash_insert(cont->prophash, (void *)prop->identifier, prop);
1487     }
1488 #endif
1489   }
1490
1491   /* Override handling. */
1492   if (DefRNA.preprocess) {
1493     prop->override_diff = (RNAPropOverrideDiff) "rna_property_override_diff_default";
1494     prop->override_store = (RNAPropOverrideStore) "rna_property_override_store_default";
1495     prop->override_apply = (RNAPropOverrideApply) "rna_property_override_apply_default";
1496   }
1497   /* TODO: do we want that for runtime-defined stuff too? I’d say no, but... maybe yes :/ */
1498
1499 #ifndef RNA_RUNTIME
1500   /* Both are typically cleared. */
1501   RNA_def_property_update(
1502       prop, DefRNA.fallback.property_update.noteflag, DefRNA.fallback.property_update.updatefunc);
1503 #endif
1504
1505   rna_addtail(&cont->properties, prop);
1506
1507   return prop;
1508 }
1509
1510 void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
1511 {
1512   prop->flag |= flag;
1513 }
1514
1515 void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
1516 {
1517   prop->flag &= ~flag;
1518   if (flag & PROP_PTR_NO_OWNERSHIP) {
1519     prop->flag_internal |= PROP_INTERN_PTR_OWNERSHIP_FORCED;
1520   }
1521 }
1522
1523 void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
1524 {
1525   prop->flag_override |= flag;
1526 }
1527
1528 void RNA_def_property_override_clear_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
1529 {
1530   prop->flag_override &= ~flag;
1531 }
1532
1533 /**
1534  * Add the property-tags passed as \a tags to \a prop (if valid).
1535  *
1536  * \note Multiple tags can be set by passing them within \a tags (using bitflags).
1537  * \note Doesn't do any type-checking with the tags defined in the parent StructRNA
1538  *       of \a prop. This should be done before (e.g. see #WM_operatortype_prop_tag).
1539  */
1540 void RNA_def_property_tags(PropertyRNA *prop, int tags)
1541 {
1542   prop->tags |= tags;
1543 }
1544
1545 void RNA_def_parameter_flags(PropertyRNA *prop,
1546                              PropertyFlag flag_property,
1547                              ParameterFlag flag_parameter)
1548 {
1549   prop->flag |= flag_property;
1550   prop->flag_parameter |= flag_parameter;
1551 }
1552
1553 void RNA_def_parameter_clear_flags(PropertyRNA *prop,
1554                                    PropertyFlag flag_property,
1555                                    ParameterFlag flag_parameter)
1556 {
1557   prop->flag &= ~flag_property;
1558   prop->flag_parameter &= ~flag_parameter;
1559 }
1560
1561 void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
1562 {
1563   prop->subtype = subtype;
1564 }
1565
1566 void RNA_def_property_array(PropertyRNA *prop, int length)
1567 {
1568   StructRNA *srna = DefRNA.laststruct;
1569
1570   if (length < 0) {
1571     CLOG_ERROR(&LOG,
1572                "\"%s.%s\", array length must be zero of greater.",
1573                srna->identifier,
1574                prop->identifier);
1575     DefRNA.error = true;
1576     return;
1577   }
1578
1579   if (length > RNA_MAX_ARRAY_LENGTH) {
1580     CLOG_ERROR(&LOG,
1581                "\"%s.%s\", array length must be smaller than %d.",
1582                srna->identifier,
1583                prop->identifier,
1584                RNA_MAX_ARRAY_LENGTH);
1585     DefRNA.error = true;
1586     return;
1587   }
1588
1589   if (prop->arraydimension > 1) {
1590     CLOG_ERROR(&LOG,
1591                "\"%s.%s\", array dimensions has been set to %u but would be overwritten as 1.",
1592                srna->identifier,
1593                prop->identifier,
1594                prop->arraydimension);
1595     DefRNA.error = true;
1596     return;
1597   }
1598
1599   switch (prop->type) {
1600     case PROP_BOOLEAN:
1601     case PROP_INT:
1602     case PROP_FLOAT:
1603       prop->arraylength[0] = length;
1604       prop->totarraylength = length;
1605       prop->arraydimension = 1;
1606       break;
1607     default:
1608       CLOG_ERROR(&LOG,
1609                  "\"%s.%s\", only boolean/int/float can be array.",
1610                  srna->identifier,
1611                  prop->identifier);
1612       DefRNA.error = true;
1613       break;
1614   }
1615 }
1616
1617 /* common args for defaults. */
1618 const float rna_default_quaternion[4] = {1, 0, 0, 0};
1619 const float rna_default_axis_angle[4] = {0, 0, 1, 0};
1620 const float rna_default_scale_3d[3] = {1, 1, 1};
1621
1622 /* common args for length */
1623 const int rna_matrix_dimsize_3x3[] = {3, 3};
1624 const int rna_matrix_dimsize_4x4[] = {4, 4};
1625 const int rna_matrix_dimsize_4x2[] = {4, 2};
1626
1627 void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
1628 {
1629   StructRNA *srna = DefRNA.laststruct;
1630   int i;
1631
1632   if (dimension < 1 || dimension > RNA_MAX_ARRAY_DIMENSION) {
1633     CLOG_ERROR(&LOG,
1634                "\"%s.%s\", array dimension must be between 1 and %d.",
1635                srna->identifier,
1636                prop->identifier,
1637                RNA_MAX_ARRAY_DIMENSION);
1638     DefRNA.error = true;
1639     return;
1640   }
1641
1642   switch (prop->type) {
1643     case PROP_BOOLEAN:
1644     case PROP_INT:
1645     case PROP_FLOAT:
1646       break;
1647     default:
1648       CLOG_ERROR(&LOG,
1649                  "\"%s.%s\", only boolean/int/float can be array.",
1650                  srna->identifier,
1651                  prop->identifier);
1652       DefRNA.error = true;
1653       break;
1654   }
1655
1656   prop->arraydimension = dimension;
1657   prop->totarraylength = 0;
1658
1659   if (length) {
1660     memcpy(prop->arraylength, length, sizeof(int) * dimension);
1661
1662     prop->totarraylength = length[0];
1663     for (i = 1; i < dimension; i++) {
1664       prop->totarraylength *= length[i];
1665     }
1666   }
1667   else {
1668     memset(prop->arraylength, 0, sizeof(prop->arraylength));
1669   }
1670
1671   /* TODO make sure arraylength values are sane  */
1672 }
1673
1674 void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
1675 {
1676   DESCR_CHECK(description, prop->identifier, NULL);
1677
1678   prop->name = name;
1679   prop->description = description;
1680 }
1681
1682 void RNA_def_property_ui_icon(PropertyRNA *prop, int icon, int consecutive)
1683 {
1684   prop->icon = icon;
1685   if (consecutive != 0) {
1686     prop->flag |= PROP_ICONS_CONSECUTIVE;
1687   }
1688   if (consecutive < 0) {
1689     prop->flag |= PROP_ICONS_REVERSE;
1690   }
1691 }
1692
1693 /**
1694  * The values hare are a little confusing:
1695  *
1696  * \param step: Used as the value to increase/decrease when clicking on number buttons,
1697  * as well as scaling mouse input for click-dragging number buttons.
1698  * For floats this is (step * UI_PRECISION_FLOAT_SCALE), why? - nobody knows.
1699  * For ints, whole values are used.
1700  *
1701  * \param precision: The number of zeros to show
1702  * (as a whole number - common range is 1 - 6), see UI_PRECISION_FLOAT_MAX
1703  */
1704 void RNA_def_property_ui_range(
1705     PropertyRNA *prop, double min, double max, double step, int precision)
1706 {
1707   StructRNA *srna = DefRNA.laststruct;
1708
1709 #ifndef NDEBUG
1710   if (min > max) {
1711     CLOG_ERROR(&LOG, "\"%s.%s\", min > max.", srna->identifier, prop->identifier);
1712     DefRNA.error = true;
1713   }
1714
1715   if (step < 0 || step > 100) {
1716     CLOG_ERROR(&LOG, "\"%s.%s\", step outside range.", srna->identifier, prop->identifier);
1717     DefRNA.error = true;
1718   }
1719
1720   if (step == 0) {
1721     CLOG_ERROR(&LOG, "\"%s.%s\", step is zero.", srna->identifier, prop->identifier);
1722     DefRNA.error = true;
1723   }
1724
1725   if (precision < -1 || precision > UI_PRECISION_FLOAT_MAX) {
1726     CLOG_ERROR(&LOG, "\"%s.%s\", precision outside range.", srna->identifier, prop->identifier);
1727     DefRNA.error = true;
1728   }
1729 #endif
1730
1731   switch (prop->type) {
1732     case PROP_INT: {
1733       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1734       iprop->softmin = (int)min;
1735       iprop->softmax = (int)max;
1736       iprop->step = (int)step;
1737       break;
1738     }
1739     case PROP_FLOAT: {
1740       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1741       fprop->softmin = (float)min;
1742       fprop->softmax = (float)max;
1743       fprop->step = (float)step;
1744       fprop->precision = (int)precision;
1745       break;
1746     }
1747     default:
1748       CLOG_ERROR(
1749           &LOG, "\"%s.%s\", invalid type for ui range.", srna->identifier, prop->identifier);
1750       DefRNA.error = true;
1751       break;
1752   }
1753 }
1754
1755 void RNA_def_property_range(PropertyRNA *prop, double min, double max)
1756 {
1757   StructRNA *srna = DefRNA.laststruct;
1758
1759 #ifdef DEBUG
1760   if (min > max) {
1761     CLOG_ERROR(&LOG, "\"%s.%s\", min > max.", srna->identifier, prop->identifier);
1762     DefRNA.error = true;
1763   }
1764 #endif
1765
1766   switch (prop->type) {
1767     case PROP_INT: {
1768       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1769       iprop->hardmin = (int)min;
1770       iprop->hardmax = (int)max;
1771       iprop->softmin = MAX2((int)min, iprop->hardmin);
1772       iprop->softmax = MIN2((int)max, iprop->hardmax);
1773       break;
1774     }
1775     case PROP_FLOAT: {
1776       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1777       fprop->hardmin = (float)min;
1778       fprop->hardmax = (float)max;
1779       fprop->softmin = MAX2((float)min, fprop->hardmin);
1780       fprop->softmax = MIN2((float)max, fprop->hardmax);
1781       break;
1782     }
1783     default:
1784       CLOG_ERROR(&LOG, "\"%s.%s\", invalid type for range.", srna->identifier, prop->identifier);
1785       DefRNA.error = true;
1786       break;
1787   }
1788 }
1789
1790 void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
1791 {
1792   StructRNA *srna = DefRNA.laststruct;
1793
1794   if (!DefRNA.preprocess) {
1795     fprintf(stderr, "\"%s.%s\": only during preprocessing.", srna->identifier, prop->identifier);
1796     return;
1797   }
1798
1799   switch (prop->type) {
1800     case PROP_POINTER: {
1801       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1802       pprop->type = (StructRNA *)type;
1803       break;
1804     }
1805     case PROP_COLLECTION: {
1806       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1807       cprop->item_type = (StructRNA *)type;
1808       break;
1809     }
1810     default:
1811       CLOG_ERROR(
1812           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1813       DefRNA.error = true;
1814       break;
1815   }
1816 }
1817
1818 void RNA_def_property_struct_runtime(PropertyRNA *prop, StructRNA *type)
1819 {
1820   StructRNA *srna = DefRNA.laststruct;
1821
1822   if (DefRNA.preprocess) {
1823     CLOG_ERROR(&LOG, "only at runtime.");
1824     return;
1825   }
1826
1827   switch (prop->type) {
1828     case PROP_POINTER: {
1829       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1830       pprop->type = type;
1831
1832       if (type && (type->flag & STRUCT_ID_REFCOUNT)) {
1833         prop->flag |= PROP_ID_REFCOUNT;
1834       }
1835
1836       break;
1837     }
1838     case PROP_COLLECTION: {
1839       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1840       cprop->item_type = type;
1841       break;
1842     }
1843     default:
1844       CLOG_ERROR(
1845           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1846       DefRNA.error = true;
1847       break;
1848   }
1849 }
1850
1851 void RNA_def_property_enum_native_type(PropertyRNA *prop, const char *native_enum_type)
1852 {
1853   StructRNA *srna = DefRNA.laststruct;
1854   switch (prop->type) {
1855     case PROP_ENUM: {
1856       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
1857       eprop->native_enum_type = native_enum_type;
1858       break;
1859     }
1860     default:
1861       CLOG_ERROR(
1862           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1863       DefRNA.error = true;
1864       break;
1865   }
1866 }
1867
1868 void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
1869 {
1870   StructRNA *srna = DefRNA.laststruct;
1871   int i, defaultfound = 0;
1872
1873   switch (prop->type) {
1874     case PROP_ENUM: {
1875       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
1876       eprop->item = (EnumPropertyItem *)item;
1877       eprop->totitem = 0;
1878       for (i = 0; item[i].identifier; i++) {
1879         eprop->totitem++;
1880
1881         if (item[i].identifier[0]) {
1882           /* Don't allow spaces in internal enum items (it's fine for Python ones). */
1883           if (DefRNA.preprocess && strstr(item[i].identifier, " ")) {
1884             CLOG_ERROR(&LOG,
1885                        "\"%s.%s\", enum identifiers must not contain spaces.",
1886                        srna->identifier,
1887                        prop->identifier);
1888             DefRNA.error = true;
1889             break;
1890           }
1891           else if (item[i].value == eprop->defaultvalue) {
1892             defaultfound = 1;
1893           }
1894         }
1895       }
1896
1897       if (!defaultfound) {
1898         for (i = 0; item[i].identifier; i++) {
1899           if (item[i].identifier[0]) {
1900             eprop->defaultvalue = item[i].value;
1901             break;
1902           }
1903         }
1904       }
1905
1906       break;
1907     }
1908     default:
1909       CLOG_ERROR(
1910           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1911       DefRNA.error = true;
1912       break;
1913   }
1914 }
1915
1916 void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
1917 {
1918   StructRNA *srna = DefRNA.laststruct;
1919
1920   switch (prop->type) {
1921     case PROP_STRING: {
1922       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
1923       sprop->maxlength = maxlength;
1924       break;
1925     }
1926     default:
1927       CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
1928       DefRNA.error = true;
1929       break;
1930   }
1931 }
1932
1933 void RNA_def_property_boolean_default(PropertyRNA *prop, bool value)
1934 {
1935   StructRNA *srna = DefRNA.laststruct;
1936
1937   switch (prop->type) {
1938     case PROP_BOOLEAN: {
1939       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1940       BLI_assert(ELEM(value, false, true));
1941 #ifndef RNA_RUNTIME
1942       /* Default may be set from items. */
1943       if (bprop->defaultvalue) {
1944         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
1945       }
1946 #endif
1947       bprop->defaultvalue = value;
1948       break;
1949     }
1950     default:
1951       CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
1952       DefRNA.error = true;
1953       break;
1954   }
1955 }
1956
1957 void RNA_def_property_boolean_array_default(PropertyRNA *prop, const bool *array)
1958 {
1959   StructRNA *srna = DefRNA.laststruct;
1960
1961   switch (prop->type) {
1962     case PROP_BOOLEAN: {
1963       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1964       bprop->defaultarray = array;
1965       break;
1966     }
1967     default:
1968       CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
1969       DefRNA.error = true;
1970       break;
1971   }
1972 }
1973
1974 void RNA_def_property_int_default(PropertyRNA *prop, int value)
1975 {
1976   StructRNA *srna = DefRNA.laststruct;
1977
1978   switch (prop->type) {
1979     case PROP_INT: {
1980       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1981 #ifndef RNA_RUNTIME
1982       if (iprop->defaultvalue != 0) {
1983         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
1984       }
1985 #endif
1986       iprop->defaultvalue = value;
1987       break;
1988     }
1989     default:
1990       CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
1991       DefRNA.error = true;
1992       break;
1993   }
1994 }
1995
1996 void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
1997 {
1998   StructRNA *srna = DefRNA.laststruct;
1999
2000   switch (prop->type) {
2001     case PROP_INT: {
2002       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2003 #ifndef RNA_RUNTIME
2004       if (iprop->defaultarray != NULL) {
2005         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
2006       }
2007 #endif
2008       iprop->defaultarray = array;
2009       break;
2010     }
2011     default:
2012       CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
2013       DefRNA.error = true;
2014       break;
2015   }
2016 }
2017
2018 void RNA_def_property_float_default(PropertyRNA *prop, float value)
2019 {
2020   StructRNA *srna = DefRNA.laststruct;
2021
2022   switch (prop->type) {
2023     case PROP_FLOAT: {
2024       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2025 #ifndef RNA_RUNTIME
2026       if (fprop->defaultvalue != 0) {
2027         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
2028       }
2029 #endif
2030       fprop->defaultvalue = value;
2031       break;
2032     }
2033     default:
2034       CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
2035       DefRNA.error = true;
2036       break;
2037   }
2038 }
2039 /* array must remain valid after this function finishes */
2040 void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
2041 {
2042   StructRNA *srna = DefRNA.laststruct;
2043
2044   switch (prop->type) {
2045     case PROP_FLOAT: {
2046       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2047 #ifndef RNA_RUNTIME
2048       if (fprop->defaultarray != NULL) {
2049         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
2050       }
2051 #endif
2052       fprop->defaultarray = array; /* WARNING, this array must not come from the stack and lost */
2053       break;
2054     }
2055     default:
2056       CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
2057       DefRNA.error = true;
2058       break;
2059   }
2060 }
2061
2062 void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
2063 {
2064   StructRNA *srna = DefRNA.laststruct;
2065
2066   switch (prop->type) {
2067     case PROP_STRING: {
2068       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2069
2070       if (value == NULL) {
2071         CLOG_ERROR(&LOG,
2072                    "\"%s.%s\", NULL string passed (dont call in this case).",
2073                    srna->identifier,
2074                    prop->identifier);
2075         DefRNA.error = true;
2076         break;
2077       }
2078
2079       if (!value[0]) {
2080         CLOG_ERROR(&LOG,
2081                    "\"%s.%s\", empty string passed (dont call in this case).",
2082                    srna->identifier,
2083                    prop->identifier);
2084         DefRNA.error = true;
2085         // BLI_assert(0);
2086         break;
2087       }
2088 #ifndef RNA_RUNTIME
2089       if (sprop->defaultvalue != NULL && sprop->defaultvalue[0]) {
2090         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
2091       }
2092 #endif
2093       sprop->defaultvalue = value;
2094       break;
2095     }
2096     default:
2097       CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
2098       DefRNA.error = true;
2099       break;
2100   }
2101 }
2102
2103 void RNA_def_property_enum_default(PropertyRNA *prop, int value)
2104 {
2105   StructRNA *srna = DefRNA.laststruct;
2106   int i, defaultfound = 0;
2107
2108   switch (prop->type) {
2109     case PROP_ENUM: {
2110       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2111       eprop->defaultvalue = value;
2112
2113       if (prop->flag & PROP_ENUM_FLAG) {
2114         /* check all bits are accounted for */
2115         int totflag = 0;
2116         for (i = 0; i < eprop->totitem; i++) {
2117           if (eprop->item[i].identifier[0]) {
2118             totflag |= eprop->item[i].value;
2119           }
2120         }
2121
2122         if (eprop->defaultvalue & ~totflag) {
2123           CLOG_ERROR(&LOG,
2124                      "\"%s.%s\", default includes unused bits (%d).",
2125                      srna->identifier,
2126                      prop->identifier,
2127                      eprop->defaultvalue & ~totflag);
2128           DefRNA.error = true;
2129         }
2130       }
2131       else {
2132         for (i = 0; i < eprop->totitem; i++) {
2133           if (eprop->item[i].identifier[0] && eprop->item[i].value == eprop->defaultvalue) {
2134             defaultfound = 1;
2135           }
2136         }
2137
2138         if (!defaultfound && eprop->totitem) {
2139           if (value == 0) {
2140             eprop->defaultvalue = eprop->item[0].value;
2141           }
2142           else {
2143             CLOG_ERROR(
2144                 &LOG, "\"%s.%s\", default is not in items.", srna->identifier, prop->identifier);
2145             DefRNA.error = true;
2146           }
2147         }
2148       }
2149
2150       break;
2151     }
2152     default:
2153       CLOG_ERROR(&LOG, "\"%s.%s\", type is not enum.", srna->identifier, prop->identifier);
2154       DefRNA.error = true;
2155       break;
2156   }
2157 }
2158
2159 /* SDNA */
2160
2161 static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop,
2162                                              const char *structname,
2163                                              const char *propname)
2164 {
2165   DNAStructMember smember;
2166   StructDefRNA *ds;
2167   PropertyDefRNA *dp;
2168
2169   dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
2170   if (dp == NULL) {
2171     return NULL;
2172   }
2173
2174   ds = rna_find_struct_def((StructRNA *)dp->cont);
2175
2176   if (!structname) {
2177     structname = ds->dnaname;
2178   }
2179   if (!propname) {
2180     propname = prop->identifier;
2181   }
2182
2183   int dnaoffset = 0;
2184   if (!rna_find_sdna_member(DefRNA.sdna, structname, propname, &smember, &dnaoffset)) {
2185     if (DefRNA.silent) {
2186       return NULL;
2187     }
2188     else if (!DefRNA.verify) {
2189       /* some basic values to survive even with sdna info */
2190       dp->dnastructname = structname;
2191       dp->dnaname = propname;
2192       if (prop->type == PROP_BOOLEAN) {
2193         dp->dnaarraylength = 1;
2194       }
2195       if (prop->type == PROP_POINTER) {
2196         dp->dnapointerlevel = 1;
2197       }
2198       dp->dnaoffset = smember.offset;
2199       return dp;
2200     }
2201     else {
2202       CLOG_ERROR(&LOG,
2203                  "\"%s.%s\" (identifier \"%s\") not found. Struct must be in DNA.",
2204                  structname,
2205                  propname,
2206                  prop->identifier);
2207       DefRNA.error = true;
2208       return NULL;
2209     }
2210   }
2211
2212   if (smember.arraylength > 1) {
2213     prop->arraylength[0] = smember.arraylength;
2214     prop->totarraylength = smember.arraylength;
2215     prop->arraydimension = 1;
2216   }
2217   else {
2218     prop->arraydimension = 0;
2219     prop->totarraylength = 0;
2220   }
2221
2222   dp->dnastructname = structname;
2223   dp->dnastructfromname = ds->dnafromname;
2224   dp->dnastructfromprop = ds->dnafromprop;
2225   dp->dnaname = propname;
2226   dp->dnatype = smember.type;
2227   dp->dnaarraylength = smember.arraylength;
2228   dp->dnapointerlevel = smember.pointerlevel;
2229   dp->dnaoffset = smember.offset;
2230   dp->dnasize = smember.size;
2231
2232   return dp;
2233 }
2234
2235 void RNA_def_property_boolean_sdna(PropertyRNA *prop,
2236                                    const char *structname,
2237                                    const char *propname,
2238                                    int64_t bit)
2239 {
2240   PropertyDefRNA *dp;
2241   BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2242   StructRNA *srna = DefRNA.laststruct;
2243
2244   if (!DefRNA.preprocess) {
2245     CLOG_ERROR(&LOG, "only during preprocessing.");
2246     return;
2247   }
2248
2249   if (prop->type != PROP_BOOLEAN) {
2250     CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
2251     DefRNA.error = true;
2252     return;
2253   }
2254
2255   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2256
2257     if (!DefRNA.silent) {
2258       /* error check to ensure floats are not wrapped as ints/bools */
2259       if (dp->dnatype && *dp->dnatype && IS_DNATYPE_BOOLEAN_COMPAT(dp->dnatype) == 0) {
2260         CLOG_ERROR(&LOG,
2261                    "%s.%s is a '%s' but wrapped as type '%s'.",
2262                    srna->identifier,
2263                    prop->identifier,
2264                    dp->dnatype,
2265                    RNA_property_typename(prop->type));
2266         DefRNA.error = true;
2267         return;
2268       }
2269     }
2270
2271     dp->booleanbit = bit;
2272
2273 #ifndef RNA_RUNTIME
2274     /* Set the default if possible. */
2275     if (dp->dnaoffset != -1) {
2276       int SDNAnr = DNA_struct_find_nr_wrapper(DefRNA.sdna, dp->dnastructname);
2277       if (SDNAnr != -1) {
2278         const void *default_data = DNA_default_table[SDNAnr];
2279         if (default_data) {
2280           default_data = POINTER_OFFSET(default_data, dp->dnaoffset);
2281           bool has_default = true;
2282           if (prop->totarraylength > 0) {
2283             has_default = false;
2284             if (debugSRNA_defaults) {
2285               fprintf(stderr, "%s default: unsupported boolean array default\n", __func__);
2286             }
2287           }
2288           else {
2289             if (STREQ(dp->dnatype, "char")) {
2290               bprop->defaultvalue = *(const char *)default_data & bit;
2291             }
2292             else if (STREQ(dp->dnatype, "short")) {
2293               bprop->defaultvalue = *(const short *)default_data & bit;
2294             }
2295             else if (STREQ(dp->dnatype, "int")) {
2296               bprop->defaultvalue = *(const int *)default_data & bit;
2297             }
2298             else {
2299               has_default = false;
2300               if (debugSRNA_defaults) {
2301                 fprintf(
2302                     stderr, "%s default: unsupported boolean type (%s)\n", __func__, dp->dnatype);
2303               }
2304             }
2305
2306             if (has_default) {
2307               if (dp->booleannegative) {
2308                 bprop->defaultvalue = !bprop->defaultvalue;
2309               }
2310
2311               if (debugSRNA_defaults) {
2312                 fprintf(stderr, "value=%d, ", bprop->defaultvalue);
2313                 print_defult_info(dp);
2314               }
2315             }
2316           }
2317         }
2318       }
2319     }
2320 #else
2321     UNUSED_VARS(bprop);
2322 #endif
2323   }
2324 }
2325
2326 void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop,
2327                                             const char *structname,
2328                                             const char *propname,
2329                                             int64_t booleanbit)
2330 {
2331   PropertyDefRNA *dp;
2332
2333   RNA_def_property_boolean_sdna(prop, structname, propname, booleanbit);
2334
2335   dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
2336
2337   if (dp) {
2338     dp->booleannegative = true;
2339   }
2340 }
2341
2342 void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2343 {
2344   PropertyDefRNA *dp;
2345   IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2346   StructRNA *srna = DefRNA.laststruct;
2347
2348   if (!DefRNA.preprocess) {
2349     CLOG_ERROR(&LOG, "only during preprocessing.");
2350     return;
2351   }
2352
2353   if (prop->type != PROP_INT) {
2354     CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
2355     DefRNA.error = true;
2356     return;
2357   }
2358
2359   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2360
2361     /* error check to ensure floats are not wrapped as ints/bools */
2362     if (!DefRNA.silent) {
2363       if (dp->dnatype && *dp->dnatype && IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
2364         CLOG_ERROR(&LOG,
2365                    "%s.%s is a '%s' but wrapped as type '%s'.",
2366                    srna->identifier,
2367                    prop->identifier,
2368                    dp->dnatype,
2369                    RNA_property_typename(prop->type));
2370         DefRNA.error = true;
2371         return;
2372       }
2373     }
2374
2375     /* SDNA doesn't pass us unsigned unfortunately .. */
2376     if (dp->dnatype && STREQ(dp->dnatype, "char")) {
2377       iprop->hardmin = iprop->softmin = CHAR_MIN;
2378       iprop->hardmax = iprop->softmax = CHAR_MAX;
2379     }
2380     else if (dp->dnatype && STREQ(dp->dnatype, "short")) {
2381       iprop->hardmin = iprop->softmin = SHRT_MIN;
2382       iprop->hardmax = iprop->softmax = SHRT_MAX;
2383     }
2384     else if (dp->dnatype && STREQ(dp->dnatype, "int")) {
2385       iprop->hardmin = INT_MIN;
2386       iprop->hardmax = INT_MAX;
2387
2388       iprop->softmin = -10000; /* rather arbitrary .. */
2389       iprop->softmax = 10000;
2390     }
2391
2392     if (prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE ||
2393         prop->subtype == PROP_FACTOR) {
2394       iprop->hardmin = iprop->softmin = 0;
2395     }
2396
2397 #ifndef RNA_RUNTIME
2398     /* Set the default if possible. */
2399     if (dp->dnaoffset != -1) {
2400       int SDNAnr = DNA_struct_find_nr_wrapper(DefRNA.sdna, dp->dnastructname);
2401       if (SDNAnr != -1) {
2402         const void *default_data = DNA_default_table[SDNAnr];
2403         if (default_data) {
2404           default_data = POINTER_OFFSET(default_data, dp->dnaoffset);
2405           /* NOTE: Currently doesn't store sign, assume chars are unsigned because
2406            * we build with this enabled, otherwise check 'PROP_UNSIGNED'. */
2407           bool has_default = true;
2408           if (prop->totarraylength > 0) {
2409             const void *default_data_end = POINTER_OFFSET(default_data, dp->dnasize);
2410             const int size_final = sizeof(int) * prop->totarraylength;
2411             if (STREQ(dp->dnatype, "char")) {
2412               int *defaultarray = rna_calloc(size_final);
2413               for (int i = 0; i < prop->totarraylength && default_data < default_data_end; i++) {
2414                 defaultarray[i] = *(const char *)default_data;
2415                 default_data = POINTER_OFFSET(default_data, sizeof(char));
2416               }
2417               iprop->defaultarray = defaultarray;
2418             }
2419             else if (STREQ(dp->dnatype, "short")) {
2420
2421               int *defaultarray = rna_calloc(size_final);
2422               for (int i = 0; i < prop->totarraylength && default_data < default_data_end; i++) {
2423                 defaultarray[i] = (prop->subtype != PROP_UNSIGNED) ? *(const short *)default_data :
2424                                                                      *(const ushort *)default_data;
2425                 default_data = POINTER_OFFSET(default_data, sizeof(short));
2426               }
2427               iprop->defaultarray = defaultarray;
2428             }
2429             else if (STREQ(dp->dnatype, "int")) {
2430               int *defaultarray = rna_calloc(size_final);
2431               memcpy(defaultarray, default_data, MIN2(size_final, dp->dnasize));
2432               iprop->defaultarray = defaultarray;
2433             }
2434             else {
2435               has_default = false;
2436               if (debugSRNA_defaults) {
2437                 fprintf(stderr,
2438                         "%s default: unsupported int array type (%s)\n",
2439                         __func__,
2440                         dp->dnatype);
2441               }
2442             }
2443
2444             if (has_default) {
2445               if (debugSRNA_defaults) {
2446                 fprintf(stderr, "value=(");
2447                 for (int i = 0; i < prop->totarraylength; i++) {
2448                   fprintf(stderr, "%d, ", iprop->defaultarray[i]);
2449                 }
2450                 fprintf(stderr, "), ");
2451                 print_defult_info(dp);
2452               }
2453             }
2454           }
2455           else {
2456             if (STREQ(dp->dnatype, "char")) {
2457               iprop->defaultvalue = *(const char *)default_data;
2458             }
2459             else if (STREQ(dp->dnatype, "short")) {
2460               iprop->defaultvalue = (prop->subtype != PROP_UNSIGNED) ?
2461                                         *(const short *)default_data :
2462                                         *(const ushort *)default_data;
2463             }
2464             else if (STREQ(dp->dnatype, "int")) {
2465               iprop->defaultvalue = (prop->subtype != PROP_UNSIGNED) ? *(const int *)default_data :
2466                                                                        *(const uint *)default_data;
2467             }
2468             else {
2469               has_default = false;
2470               if (debugSRNA_defaults) {
2471                 fprintf(stderr, "%s default: unsupported int type (%s)\n", __func__, dp->dnatype);
2472               }
2473             }
2474
2475             if (has_default) {
2476               if (debugSRNA_defaults) {
2477                 fprintf(stderr, "value=%d, ", iprop->defaultvalue);
2478                 print_defult_info(dp);
2479               }
2480             }
2481           }
2482         }
2483       }
2484     }
2485 #endif
2486   }
2487 }
2488
2489 void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2490 {
2491   PropertyDefRNA *dp;
2492   FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2493   StructRNA *srna = DefRNA.laststruct;
2494
2495   if (!DefRNA.preprocess) {
2496     CLOG_ERROR(&LOG, "only during preprocessing.");
2497     return;
2498   }
2499
2500   if (prop->type != PROP_FLOAT) {
2501     CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
2502     DefRNA.error = true;
2503     return;
2504   }
2505
2506   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2507     /* silent is for internal use */
2508     if (!DefRNA.silent) {
2509       if (dp->dnatype && *dp->dnatype && IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) {
2510         /* Colors are an exception. these get translated. */
2511         if (prop->subtype != PROP_COLOR_GAMMA) {
2512           CLOG_ERROR(&LOG,
2513                      "%s.%s is a '%s' but wrapped as type '%s'.",
2514                      srna->identifier,
2515                      prop->identifier,
2516                      dp->dnatype,
2517                      RNA_property_typename(prop->type));
2518           DefRNA.error = true;
2519           return;
2520         }
2521       }
2522     }
2523
2524     if (dp->dnatype && STREQ(dp->dnatype, "char")) {
2525       fprop->hardmin = fprop->softmin = 0.0f;
2526       fprop->hardmax = fprop->softmax = 1.0f;
2527     }
2528
2529 #ifndef RNA_RUNTIME
2530     /* Set the default if possible. */
2531     if (dp->dnaoffset != -1) {
2532       int SDNAnr = DNA_struct_find_nr_wrapper(DefRNA.sdna, dp->dnastructname);
2533       if (SDNAnr != -1) {
2534         const void *default_data = DNA_default_table[SDNAnr];
2535         if (default_data) {
2536           default_data = POINTER_OFFSET(default_data, dp->dnaoffset);
2537           bool has_default = true;
2538           if (prop->totarraylength > 0) {
2539             if (STREQ(dp->dnatype, "float")) {
2540               const int size_final = sizeof(float) * prop->totarraylength;
2541               float *defaultarray = rna_calloc(size_final);
2542               memcpy(defaultarray, default_data, MIN2(size_final, dp->dnasize));
2543               fprop->defaultarray = defaultarray;
2544             }
2545             else {
2546               has_default = false;
2547               if (debugSRNA_defaults) {
2548                 fprintf(stderr,
2549                         "%s default: unsupported float array type (%s)\n",
2550                         __func__,
2551                         dp->dnatype);
2552               }
2553             }
2554
2555             if (has_default) {
2556               if (debugSRNA_defaults) {
2557                 fprintf(stderr, "value=(");
2558                 for (int i = 0; i < prop->totarraylength; i++) {
2559                   fprintf(stderr, "%g, ", fprop->defaultarray[i]);
2560                 }
2561                 fprintf(stderr, "), ");
2562                 print_defult_info(dp);
2563               }
2564             }
2565           }
2566           else {
2567             if (STREQ(dp->dnatype, "float")) {
2568               fprop->defaultvalue = *(const float *)default_data;
2569             }
2570             else if (STREQ(dp->dnatype, "char")) {
2571               fprop->defaultvalue = (float)*(const char *)default_data * (1.0f / 255.0f);
2572             }
2573             else {
2574               has_default = false;
2575               if (debugSRNA_defaults) {
2576                 fprintf(
2577                     stderr, "%s default: unsupported float type (%s)\n", __func__, dp->dnatype);
2578               }
2579             }
2580
2581             if (has_default) {
2582               if (debugSRNA_defaults) {
2583                 fprintf(stderr, "value=%g, ", fprop->defaultvalue);
2584                 print_defult_info(dp);
2585               }
2586             }
2587           }
2588         }
2589       }
2590     }
2591 #endif
2592   }
2593
2594   rna_def_property_sdna(prop, structname, propname);
2595 }
2596
2597 void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2598 {
2599   PropertyDefRNA *dp;
2600   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2601   StructRNA *srna = DefRNA.laststruct;
2602
2603   if (!DefRNA.preprocess) {
2604     CLOG_ERROR(&LOG, "only during preprocessing.");
2605     return;
2606   }
2607
2608   if (prop->type != PROP_ENUM) {
2609     CLOG_ERROR(&LOG, "\"%s.%s\", type is not enum.", srna->identifier, prop->identifier);
2610     DefRNA.error = true;
2611     return;
2612   }
2613
2614   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2615     if (prop->arraydimension) {
2616       prop->arraydimension = 0;
2617       prop->totarraylength = 0;
2618
2619       if (!DefRNA.silent) {
2620         CLOG_ERROR(&LOG, "\"%s.%s\", array not supported for enum type.", structname, propname);
2621         DefRNA.error = true;
2622       }
2623     }
2624
2625 #ifndef RNA_RUNTIME
2626     /* Set the default if possible. */
2627     if (dp->dnaoffset != -1) {
2628       int SDNAnr = DNA_struct_find_nr_wrapper(DefRNA.sdna, dp->dnastructname);
2629       if (SDNAnr != -1) {
2630         const void *default_data = DNA_default_table[SDNAnr];
2631         if (default_data) {
2632           default_data = POINTER_OFFSET(default_data, dp->dnaoffset);
2633           bool has_default = true;
2634           if (STREQ(dp->dnatype, "char")) {
2635             eprop->defaultvalue = *(const char *)default_data;
2636           }
2637           else if (STREQ(dp->dnatype, "short")) {
2638             eprop->defaultvalue = *(const short *)default_data;
2639           }
2640           else if (STREQ(dp->dnatype, "int")) {
2641             eprop->defaultvalue = *(const int *)default_data;
2642           }
2643           else {
2644             has_default = false;
2645             if (debugSRNA_defaults) {
2646               fprintf(stderr, "%s default: unsupported enum type (%s)\n", __func__, dp->dnatype);
2647             }
2648           }
2649
2650           if (has_default) {
2651             if (debugSRNA_defaults) {
2652               fprintf(stderr, "value=%d, ", eprop->defaultvalue);
2653               print_defult_info(dp);
2654             }
2655           }
2656         }
2657       }
2658     }
2659 #else
2660     UNUSED_VARS(eprop);
2661 #endif
2662   }
2663 }
2664
2665 void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop,
2666                                         const char *structname,
2667                                         const char *propname)
2668 {
2669   PropertyDefRNA *dp;
2670
2671   RNA_def_property_enum_sdna(prop, structname, propname);
2672
2673   dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
2674
2675   if (dp) {
2676     dp->enumbitflags = 1;
2677
2678 #ifndef RNA_RUNTIME
2679     int defaultvalue_mask = 0;
2680     EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2681     for (int i = 0; i < eprop->totitem; i++) {
2682       if (eprop->item[i].identifier[0]) {
2683         defaultvalue_mask |= eprop->defaultvalue & eprop->item[i].value;
2684       }
2685     }
2686     eprop->defaultvalue = defaultvalue_mask;
2687 #endif
2688   }
2689 }
2690
2691 void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2692 {
2693   PropertyDefRNA *dp;
2694   StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2695   StructRNA *srna = DefRNA.laststruct;
2696
2697   if (!DefRNA.preprocess) {
2698     CLOG_ERROR(&LOG, "only during preprocessing.");
2699     return;
2700   }
2701
2702   if (prop->type != PROP_STRING) {
2703     CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
2704     DefRNA.error = true;
2705     return;
2706   }
2707
2708   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2709     if (prop->arraydimension) {
2710       sprop->maxlength = prop->totarraylength;
2711       prop->arraydimension = 0;
2712       prop->totarraylength = 0;
2713     }
2714
2715 #ifndef RNA_RUNTIME
2716     /* Set the default if possible. */
2717     if ((dp->dnaoffset != -1) && (dp->dnapointerlevel != 0)) {
2718       int SDNAnr = DNA_struct_find_nr_wrapper(DefRNA.sdna, dp->dnastructname);
2719       if (SDNAnr != -1) {
2720         const void *default_data = DNA_default_table[SDNAnr];
2721         if (default_data) {
2722           default_data = POINTER_OFFSET(default_data, dp->dnaoffset);
2723           sprop->defaultvalue = default_data;
2724
2725           if (debugSRNA_defaults) {
2726             fprintf(stderr, "value=\"%s\", ", sprop->defaultvalue);
2727             print_defult_info(dp);
2728           }
2729         }
2730       }
2731     }
2732 #endif
2733   }
2734 }
2735
2736 void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2737 {
2738   /* PropertyDefRNA *dp; */
2739   StructRNA *srna = DefRNA.laststruct;
2740
2741   if (!DefRNA.preprocess) {
2742     CLOG_ERROR(&LOG, "only during preprocessing.");
2743     return;
2744   }
2745
2746   if (prop->type != PROP_POINTER) {
2747     CLOG_ERROR(&LOG, "\"%s.%s\", type is not pointer.", srna->identifier, prop->identifier);
2748     DefRNA.error = true;
2749     return;
2750   }
2751
2752   if ((/* dp= */ rna_def_property_sdna(prop, structname, propname))) {
2753     if (prop->arraydimension) {
2754       prop->arraydimension = 0;
2755       prop->totarraylength = 0;
2756
2757       if (!DefRNA.silent) {
2758         CLOG_ERROR(&LOG, "\"%s.%s\", array not supported for pointer type.", structname, propname);
2759         DefRNA.error = true;
2760       }
2761     }
2762   }
2763 }
2764
2765 void RNA_def_property_collection_sdna(PropertyRNA *prop,
2766                                       const char *structname,
2767                                       const char *propname,
2768                                       const char *lengthpropname)
2769 {
2770   PropertyDefRNA *dp;
2771   CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
2772   StructRNA *srna = DefRNA.laststruct;
2773
2774   if (!DefRNA.preprocess) {
2775     CLOG_ERROR(&LOG, "only during preprocessing.");
2776     return;
2777   }
2778
2779   if (prop->type != PROP_COLLECTION) {
2780     CLOG_ERROR(&LOG, "\"%s.%s\", type is not collection.", srna->identifier, prop->identifier);
2781     DefRNA.error = true;
2782     return;
2783   }
2784
2785   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2786     if (prop->arraydimension && !lengthpropname) {
2787       prop->arraydimension = 0;
2788       prop->totarraylength = 0;
2789
2790       if (!DefRNA.silent) {
2791         CLOG_ERROR(&LOG, "\"%s.%s\", array of collections not supported.", structname, propname);
2792         DefRNA.error = true;
2793       }
2794     }
2795
2796     if (dp->dnatype && STREQ(dp->dnatype, "ListBase")) {
2797       cprop->next = (PropCollectionNextFunc) "rna_iterator_listbase_next";
2798       cprop->get = (PropCollectionGetFunc) "rna_iterator_listbase_get";
2799       cprop->end = (PropCollectionEndFunc) "rna_iterator_listbase_end";
2800     }
2801   }
2802
2803   if (dp && lengthpropname) {
2804     DNAStructMember smember;
2805     StructDefRNA *ds = rna_find_struct_def((StructRNA *)dp->cont);
2806
2807     if (!structname) {
2808       structname = ds->dnaname;
2809     }
2810
2811     int dnaoffset = 0;
2812     if (lengthpropname[0] == 0 ||
2813         rna_find_sdna_member(DefRNA.sdna, structname, lengthpropname, &smember, &dnaoffset)) {
2814       if (lengthpropname[0] == 0) {
2815         dp->dnalengthfixed = prop->totarraylength;
2816         prop->arraydimension = 0;
2817         prop->totarraylength = 0;
2818       }
2819       else {
2820         dp->dnalengthstructname = structname;
2821         dp->dnalengthname = lengthpropname;
2822         prop->totarraylength = 0;
2823       }
2824
2825       cprop->next = (PropCollectionNextFunc) "rna_iterator_array_next";
2826       cprop->end = (PropCollectionEndFunc) "rna_iterator_array_end";
2827
2828       if (dp->dnapointerlevel >= 2) {
2829         cprop->get = (PropCollectionGetFunc) "rna_iterator_array_dereference_get";
2830       }
2831       else {
2832         cprop->get = (PropCollectionGetFunc) "rna_iterator_array_get";
2833       }
2834     }
2835     else {
2836       if (!DefRNA.silent) {
2837         CLOG_ERROR(&LOG, "\"%s.%s\" not found.", structname, lengthpropname);
2838         DefRNA.error = true;
2839       }
2840     }
2841   }
2842 }
2843
2844 void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
2845 {
2846   prop->translation_context = context ? context : BLT_I18NCONTEXT_DEFAULT_BPYRNA;
2847 }
2848
2849 /* Functions */
2850
2851 void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable)
2852 {
2853   if (!DefRNA.preprocess) {
2854     CLOG_ERROR(&LOG, "only during preprocessing.");
2855     return;
2856   }
2857
2858   if (editable) {
2859     prop->editable = (EditableFunc)editable;
2860   }
2861 }
2862
2863 void RNA_def_property_editable_array_func(PropertyRNA *prop, const char *editable)
2864 {
2865   if (!DefRNA.preprocess) {
2866     CLOG_ERROR(&LOG, "only during preprocessing.");
2867     return;
2868   }
2869
2870   if (editable) {
2871     prop->itemeditable = (ItemEditableFunc)editable;
2872   }
2873 }
2874
2875 /**
2876  * Set custom callbacks for override operations handling.
2877  *
2878  * \note \a diff callback will also be used by RNA comparison/equality functions.
2879  */
2880 void RNA_def_property_override_funcs(PropertyRNA *prop,
2881                                      const char *diff,
2882                                      const char *store,
2883                                      const char *apply)
2884 {
2885   if (!DefRNA.preprocess) {
2886     CLOG_ERROR(&LOG, "only during preprocessing.");
2887     return;
2888   }
2889
2890   if (diff) {
2891     prop->override_diff = (RNAPropOverrideDiff)diff;
2892   }
2893   if (store) {
2894     prop->override_store = (RNAPropOverrideStore)store;
2895   }
2896   if (apply) {
2897     prop->override_apply = (RNAPropOverrideApply)apply;
2898   }
2899 }
2900
2901 void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
2902 {
2903   if (!DefRNA.preprocess) {
2904     CLOG_ERROR(&LOG, "only during preprocessing.");
2905     return;
2906   }
2907
2908   prop->noteflag = noteflag;
2909   prop->update = (UpdateFunc)func;
2910 }
2911
2912 void RNA_def_property_update_runtime(PropertyRNA *prop, const void *func)
2913 {
2914   prop->update = (void *)func;
2915 }
2916
2917 void RNA_def_property_poll_runtime(PropertyRNA *prop, const void *func)
2918 {
2919   if (prop->type == PROP_POINTER) {
2920     ((PointerPropertyRNA *)prop)->poll = (void *)func;
2921   }
2922   else {
2923     CLOG_ERROR(&LOG, "%s is not a Pointer Property.", prop->identifier);
2924   }
2925 }
2926
2927 void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength)
2928 {
2929   if (!DefRNA.preprocess) {
2930     CLOG_ERROR(&LOG, "only during preprocessing.");
2931     return;
2932   }
2933
2934   if (!(prop->flag & PROP_DYNAMIC)) {
2935     CLOG_ERROR(&LOG, "property is a not dynamic array.");
2936     DefRNA.error = true;
2937     return;
2938   }
2939
2940   if (getlength) {
2941     prop->getlength = (PropArrayLengthGetFunc)getlength;
2942   }
2943 }
2944
2945 void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
2946 {
2947   StructRNA *srna = DefRNA.laststruct;
2948
2949   if (!DefRNA.preprocess) {
2950     CLOG_ERROR(&LOG, "only during preprocessing.");
2951     return;
2952   }
2953
2954   switch (prop->type) {
2955     case PROP_BOOLEAN: {
2956       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2957
2958       if (prop->arraydimension) {
2959         if (get) {
2960           bprop->getarray = (PropBooleanArrayGetFunc)get;
2961         }
2962         if (set) {
2963           bprop->setarray = (PropBooleanArraySetFunc)set;
2964         }
2965       }
2966       else {
2967         if (get) {
2968           bprop->get = (PropBooleanGetFunc)get;
2969         }
2970         if (set) {
2971           bprop->set = (PropBooleanSetFunc)set;
2972         }
2973       }
2974       break;
2975     }
2976     default:
2977       CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
2978       DefRNA.error = true;
2979       break;
2980   }
2981 }
2982
2983 void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop,
2984                                             BooleanPropertyGetFunc getfunc,
2985                                             BooleanPropertySetFunc setfunc)
2986 {
2987   BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2988
2989   if (getfunc) {
2990     bprop->get_ex = getfunc;
2991   }
2992   if (setfunc) {
2993     bprop->set_ex = setfunc;
2994   }
2995
2996   if (getfunc || setfunc) {
2997     /* don't save in id properties */
2998     prop->flag &= ~PROP_IDPROPERTY;
2999
3000     if (!setfunc) {
3001       prop->flag &= ~PROP_EDITABLE;
3002     }
3003   }
3004 }
3005
3006 void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop,
3007                                                   BooleanArrayPropertyGetFunc getfunc,
3008                                                   BooleanArrayPropertySetFunc setfunc)
3009 {
3010   BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
3011
3012   if (getfunc) {
3013     bprop->getarray_ex = getfunc;
3014   }
3015   if (setfunc) {
3016     bprop->setarray_ex = setfunc;
3017   }
3018
3019   if (getfunc || setfunc) {
3020     /* don't save in id properties */
3021     prop->flag &= ~PROP_IDPROPERTY;
3022
3023     if (!setfunc) {
3024       prop->flag &= ~PROP_EDITABLE;
3025     }
3026   }
3027 }
3028
3029 void RNA_def_property_int_funcs(PropertyRNA *prop,
3030                                 const char *get,
3031                                 const char *set,
3032                                 const char *range)
3033 {
3034   StructRNA *srna = DefRNA.laststruct;
3035
3036   if (!DefRNA.preprocess) {
3037     CLOG_ERROR(&LOG, "only during preprocessing.");
3038     return;
3039   }
3040
3041   switch (prop->type) {
3042     case PROP_INT: {
3043       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
3044
3045       if (prop->arraydimension) {
3046         if (get) {
3047           iprop->getarray = (PropIntArrayGetFunc)get;
3048         }
3049         if (set) {
3050           iprop->setarray = (PropIntArraySetFunc)set;
3051         }
3052       }
3053       else {
3054         if (get) {
3055           iprop->get = (PropIntGetFunc)get;
3056         }
3057         if (set) {
3058           iprop->set = (PropIntSetFunc)set;
3059         }
3060       }
3061       if (range) {
3062         iprop->range = (PropIntRangeFunc)range;
3063       }
3064       break;
3065     }
3066     default:
3067       CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
3068       DefRNA.error = true;
3069       break;
3070   }
3071 }
3072
3073 void RNA_def_property_int_funcs_runtime(PropertyRNA *prop,
3074                                         IntPropertyGetFunc getfunc,
3075                                         IntPropertySetFunc setfunc,
3076                                         IntPropertyRangeFunc rangefunc)
3077 {
3078   IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
3079
3080   if (getfunc) {
3081     iprop->get_ex = getfunc;
3082   }
3083   if (setfunc) {
3084     iprop->set_ex = setfunc;
3085   }
3086   if (rangefunc) {
3087     iprop->range_ex = rangefunc;
3088   }
3089
3090   if (getfunc || setfunc) {
3091     /* don't save in id properties */
3092     prop->flag &= ~PROP_IDPROPERTY;
3093
3094     if (!setfunc) {
3095       prop->flag &= ~PROP_EDITABLE;
3096     }
3097   }
3098 }
3099
3100 void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop,
3101                                               IntArrayPropertyGetFunc getfunc,
3102                                               IntArrayPropertySetFunc setfunc,
3103                                               IntPropertyRangeFunc rangefunc)
3104 {
3105   IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
3106
3107   if (getfunc) {
3108     iprop->getarray_ex = getfunc;
3109   }
3110   if (setfunc) {
3111     iprop->setarray_ex = setfunc;
3112   }
3113   if (rangefunc) {
3114     iprop->range_ex = rangefunc;
3115   }
3116
3117   if (getfunc || setfunc) {
3118     /* don't save in id properties */
3119     prop->flag &= ~PROP_IDPROPERTY;
3120
3121     if (!setfunc) {
3122       prop->flag &= ~PROP_EDITABLE;
3123     }
3124   }
3125 }
3126
3127 void RNA_def_property_float_funcs(PropertyRNA *prop,
3128                                   const char *get,
3129                                   const char *set,
3130                                   const char *range)
3131 {
3132   StructRNA *srna = DefRNA.laststruct;
3133
3134   if (!DefRNA.preprocess) {
3135     CLOG_ERROR(&LOG, "only during preprocessing.");
3136     return;
3137   }
3138
3139   switch (prop->type) {
3140     case PROP_FLOAT: {
3141       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3142
3143       if (prop->arraydimension) {
3144         if (get) {
3145           fprop->getarray = (PropFloatArrayGetFunc)get;
3146         }
3147         if (set) {
3148           fprop->setarray = (PropFloatArraySetFunc)set;
3149         }
3150       }
3151       else {
3152         if (get) {
3153           fprop->get = (PropFloatGetFunc)get;
3154         }
3155         if (set) {
3156           fprop->set = (PropFloatSetFunc)set;
3157         }
3158       }
3159       if (range) {
3160         fprop->range = (PropFloatRangeFunc)range;
3161       }
3162       break;
3163     }
3164     default:
3165       CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
3166       DefRNA.error = true;
3167       break;
3168   }
3169 }
3170
3171 void RNA_def_property_float_funcs_runtime(PropertyRNA *prop,
3172                                           FloatPropertyGetFunc getfunc,
3173                                           FloatPropertySetFunc setfunc,
3174                                           FloatPropertyRangeFunc rangefunc)
3175 {
3176   FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3177
3178   if (getfunc) {
3179     fprop->get_ex = getfunc;
3180   }
3181   if (setfunc) {
3182     fprop->set_ex = setfunc;
3183   }
3184   if (rangefunc) {
3185     fprop->range_ex = rangefunc;
3186   }
3187
3188   if (getfunc || setfunc) {
3189     /* don't save in id properties */
3190     prop->flag &= ~PROP_IDPROPERTY;
3191
3192     if (!setfunc) {
3193       prop->flag &= ~PROP_EDITABLE;
3194     }
3195   }
3196 }
3197
3198 void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop,
3199                                                 FloatArrayPropertyGetFunc getfunc,
3200                                                 FloatArrayPropertySetFunc setfunc,
3201                                                 FloatPropertyRangeFunc rangefunc)
3202 {
3203   FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3204
3205   if (getfunc) {
3206     fprop->getarray_ex = getfunc;
3207   }
3208   if (setfunc) {
3209     fprop->setarray_ex = setfunc;
3210   }
3211   if (rangefunc) {
3212     fprop->range_ex = rangefunc;
3213   }
3214
3215   if (getfunc || setfunc) {
3216     /* don't save in id properties */
3217     prop->flag &= ~PROP_IDPROPERTY;
3218
3219     if (!setfunc) {
3220       prop->flag &= ~PROP_EDITABLE;
3221     }
3222   }
3223 }
3224
3225 void RNA_def_property_enum_funcs(PropertyRNA *prop,
3226                                  const char *get,
3227                                  const char *set,
3228                                  const char *item)
3229 {
3230   StructRNA *srna = DefRNA.laststruct;
3231
3232   if (!DefRNA.preprocess) {
3233     CLOG_ERROR(&LOG, "only during preprocessing.");
3234     return;
3235   }
3236
3237   switch (prop->type) {
3238     case PROP_ENUM: {
3239       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3240
3241       if (get) {
3242         eprop->get = (PropEnumGetFunc)get;
3243       }
3244       if (set) {
3245         eprop->set = (PropEnumSetFunc)set;
3246       }
3247       if (item) {
3248         eprop->itemf = (PropEnumItemFunc)item;
3249       }
3250       break;
3251     }
3252     default:
3253       CLOG_ERROR(&LOG, "\"%s.%s\", type is not enum.", srna->identifier, prop->identifier);
3254       DefRNA.error = true;
3255       break;
3256   }
3257 }
3258
3259 void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop,
3260                                          EnumPropertyGetFunc getfunc,
3261                                          EnumPropertySetFunc setfunc,
3262                                          EnumPropertyItemFunc itemfunc)
3263 {
3264   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3265
3266   if (getfunc) {
3267     eprop->get_ex = getfunc;
3268   }
3269   if (setfunc) {
3270     eprop->set_ex = setfunc;
3271   }
3272   if (itemfunc) {
3273     eprop->itemf = itemfunc;
3274   }
3275
3276   if (getfunc || setfunc) {
3277     /* don't save in id properties */
3278     prop->flag &= ~PROP_IDPROPERTY;
3279
3280     if (!setfunc) {
3281       prop->flag &= ~PROP_EDITABLE;
3282     }
3283   }
3284 }
3285
3286 void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data)
3287 {
3288   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3289   eprop->py_data = py_data;
3290 }
3291
3292 void RNA_def_property_string_funcs(PropertyRNA *prop,
3293                                    const char *get,
3294                                    const char *length,
3295                                    const char *set)
3296 {
3297   StructRNA *srna = DefRNA.laststruct;
3298
3299   if (!DefRNA.preprocess) {
3300     CLOG_ERROR(&LOG, "only during preprocessing.");
3301     return;
3302   }
3303
3304   switch (prop->type) {
3305     case PROP_STRING: {
3306       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3307
3308       if (get) {
3309         sprop->get = (PropStringGetFunc)get;
3310       }
3311       if (length) {
3312         sprop->length = (PropStringLengthFunc)length;
3313       }
3314       if (set) {
3315         sprop->set = (PropStringSetFunc)set;
3316       }
3317       break;
3318     }
3319     default:
3320       CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
3321       DefRNA.error = true;
3322       break;
3323   }
3324 }
3325
3326 void RNA_def_property_string_funcs_runtime(PropertyRNA *prop,
3327                                            StringPropertyGetFunc getfunc,
3328                                            StringPropertyLengthFunc lengthfunc,
3329                                            StringPropertySetFunc setfunc)
3330 {
3331   StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3332
3333   if (getfunc) {
3334     sprop->get_ex = getfunc;
3335   }
3336   if (lengthfunc) {
3337     sprop->length_ex = lengthfunc;
3338   }
3339   if (setfunc) {
3340     sprop->set_ex = setfunc;
3341   }
3342
3343   if (getfunc || setfunc) {
3344     /* don't save in id properties */
3345     prop->flag &= ~PROP_IDPROPERTY;
3346
3347     if (!setfunc) {
3348       prop->flag &= ~PROP_EDITABLE;
3349     }
3350   }
3351 }
3352
3353 void RNA_def_property_pointer_funcs(
3354     PropertyRNA *prop, const char *get, const char *set, const char *typef, const char *poll)
3355 {
3356   StructRNA *srna = DefRNA.laststruct;
3357
3358   if (!DefRNA.preprocess) {
3359     CLOG_ERROR(&LOG, "only during preprocessing.");
3360     return;
3361   }
3362
3363   switch (prop->type) {
3364     case PROP_POINTER: {
3365       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
3366
3367       if (get) {
3368         pprop->get = (PropPointerGetFunc)get;
3369       }
3370       if (set) {
3371         pprop->set = (PropPointerSetFunc)set;
3372       }
3373       if (typef) {
3374         pprop->typef = (PropPointerTypeFunc)typef;
3375       }
3376       if (poll) {
3377         pprop->poll = (PropPointerPollFunc)poll;
3378       }
3379       break;
3380     }
3381     default:
3382       CLOG_ERROR(&LOG, "\"%s.%s\", type is not pointer.", srna->identifier, prop->identifier);
3383       DefRNA.error = true;
3384       break;
3385   }
3386 }
3387
3388 void RNA_def_property_collection_funcs(PropertyRNA *prop,
3389                                        const char *begin,
3390                                        const char *next,
3391                                        const char *end,
3392                                        const char *get,
3393                                        const char *length,
3394                                        const char *lookupint,
3395                                        const char *lookupstring,
3396                                        const char *assignint)
3397 {
3398   StructRNA *srna = DefRNA.laststruct;
3399
3400   if (!DefRNA.preprocess) {
3401     CLOG_ERROR(&LOG, "only during preprocessing.");
3402     return;
3403   }
3404
3405   switch (prop->type) {
3406     case PROP_COLLECTION: {
3407       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
3408
3409       if (begin) {
3410         cprop->begin = (PropCollectionBeginFunc)begin;
3411       }
3412       if (next) {
3413         cprop->next = (PropCollectionNextFunc)next;
3414       }
3415       if (end) {
3416         cprop->end = (PropCollectionEndFunc)end;
3417       }
3418       if (get) {
3419         cprop->get = (PropCollectionGetFunc)get;
3420       }
3421       if (length) {
3422         cprop->length = (PropCollectionLengthFunc)length;
3423       }
3424       if (lookupint) {
3425         cprop->lookupint = (PropCollectionLookupIntFunc)lookupint;
3426       }
3427       if (lookupstring) {
3428         cprop->lookupstring = (PropCollectionLookupStringFunc)lookupstring;
3429       }
3430       if (assignint) {
3431         cprop->assignint = (PropCollectionAssignIntFunc)assignint;
3432       }
3433       break;
3434     }
3435     default:
3436       CLOG_ERROR(&LOG, "\"%s.%s\", type is not collection.", srna->identifier, prop->identifier);
3437       DefRNA.error = true;
3438       break;
3439   }
3440 }
3441
3442 void RNA_def_property_srna(PropertyRNA *prop, const char *type)
3443 {
3444   prop->srna = (StructRNA *)type;
3445 }
3446
3447 void RNA_def_py_data(PropertyRNA *prop, void *py_data)
3448 {
3449   prop->py_data = py_data;
3450 }
3451
3452 /* Compact definitions */
3453
3454 PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont_,
3455                              const char *identifier,
3456                              bool default_value,
3457                              const char *ui_name,
3458                              const char *ui_description)
3459 {
3460   ContainerRNA *cont = cont_;
3461   PropertyRNA *prop;
3462
3463   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
3464   RNA_def_property_boolean_default(prop, default_value);
3465   RNA_def_property_ui_text(prop, ui_name, ui_description);
3466
3467   return prop;
3468 }
3469
3470 PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont_,
3471                                    const char *identifier,
3472                                    int len,
3473                                    bool *default_value,
3474                                    const char *ui_name,
3475                                    const char *ui_description)
3476 {
3477   ContainerRNA *cont = cont_;
3478   PropertyRNA *prop;
3479
3480   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
3481   if (len != 0) {
3482     RNA_def_property_array(prop, len);
3483   }
3484   if (default_value) {
3485     RNA_def_property_boolean_array_default(prop, default_value);
3486   }
3487   RNA_def_property_ui_text(prop, ui_name, ui_description);
3488
3489   return prop;
3490 }
3491
3492 PropertyRNA *RNA_def_boolean_layer(StructOrFunctionRNA *cont_,
3493                                    const char *identifier,
3494                                    int len,
3495                                    bool *default_value,
3496                                    const char *ui_name,
3497                                    const char *ui_description)
3498 {
3499   ContainerRNA *cont = cont_;
3500   PropertyRNA *prop;
3501
3502   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER);
3503   if (len != 0) {
3504     RNA_def_property_array(prop, len);
3505   }
3506   if (default_value) {
3507     RNA_def_property_boolean_array_default(prop, default_value);
3508   }
3509   RNA_def_property_ui_text(prop, ui_name, ui_description);
3510
3511   return prop;
3512 }
3513
3514 PropertyRNA *RNA_def_boolean_layer_member(StructOrFunctionRNA *cont_,
3515                                           const char *identifier,
3516                                           int len,
3517                                           bool *default_value,
3518                                           const char *ui_name,
3519                                           const char *ui_description)
3520 {
3521   ContainerRNA *cont = cont_;
3522   PropertyRNA *prop;
3523
3524   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER_MEMBER);
3525   if (len != 0) {
3526     RNA_def_property_array(prop, len);
3527   }
3528   if (default_value) {
3529     RNA_def_property_boolean_array_default(prop, default_value);
3530   }
3531   RNA_def_property_ui_text(prop, ui_name, ui_description);
3532
3533   return prop;
3534 }
3535
3536 PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_,
3537                                     const char *identifier,
3538                                     int len,
3539                                     bool *default_value,
3540                                     const char *ui_name,
3541                                     const char *ui_description)
3542 {
3543   ContainerRNA *cont = cont_;
3544   PropertyRNA *prop;
3545
3546   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_XYZ); /* XXX */
3547   if (len != 0) {
3548     RNA_def_property_array(prop, len);
3549   }
3550   if (default_value) {
3551     RNA_def_property_boolean_array_default(prop, default_value);
3552   }
3553   RNA_def_property_ui_text(prop, ui_name, ui_description);
3554
3555   return prop;
3556 }
3557
3558 PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_,
3559                          const char *identifier,
3560                          int default_value,
3561                          int hardmin,
3562                          int hardmax,
3563                          const char *ui_name,
3564                          const char *ui_description,
3565                          int softmin,
3566                          int softmax)
3567 {
3568   ContainerRNA *cont = cont_;
3569   PropertyRNA *prop;
3570
3571   ASSERT_SOFT_HARD_LIMITS;
3572
3573   prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
3574   RNA_def_property_int_default(prop, default_value);
3575   if (hardmin != hardmax) {
3576     RNA_def_property_range(prop, hardmin, hardmax);
3577   }
3578   RNA_def_property_ui_text(prop, ui_name, ui_description);
3579   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3580
3581   return prop;
3582 }
3583
3584 PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_,
3585                                 const char *identifier,
3586                                 int len,
3587                                 const int *default_value,
3588                                 int hardmin,
3589                                 int hardmax,
3590                                 const char *ui_name,
3591                                 const char *ui_description,
3592                                 int softmin,
3593                                 int softmax)
3594 {
3595   ContainerRNA *cont = cont_;
3596   PropertyRNA *prop;
3597
3598   ASSERT_SOFT_HARD_LIMITS;
3599
3600   prop = RNA_def_property(cont, identifier, PROP_INT, PROP_XYZ); /* XXX */
3601   if (len != 0) {
3602     RNA_def_property_array(prop, len);
3603   }
3604   if (default_value) {
3605     RNA_def_property_int_array_default(prop, default_value);
3606   }
3607   if (hardmin != hardmax) {
3608     RNA_def_property_range(prop, hardmin, hardmax);
3609   }
3610   RNA_def_property_ui_text(prop, ui_name, ui_description);
3611   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3612
3613   return prop;
3614 }
3615
3616 PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_,
3617                                const char *identifier,
3618                                int len,
3619                                const int *default_value,
3620                                int hardmin,
3621                                int hardmax,
3622                                const char *ui_name,
3623                                const char *ui_description,
3624                                int softmin,
3625                                int softmax)
3626 {
3627   ContainerRNA *cont = cont_;
3628   PropertyRNA *prop;
3629
3630   ASSERT_SOFT_HARD_LIMITS;
3631
3632   prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
3633   if (len != 0) {
3634     RNA_def_property_array(prop, len);
3635   }
3636   if (default_value) {
3637     RNA_def_property_int_array_default(prop, default_value);
3638   }
3639   if (hardmin != hardmax) {
3640     RNA_def_property_range(prop, hardmin, hardmax);
3641   }
3642   RNA_def_property_ui_text(prop, ui_name, ui_description);
3643   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3644
3645   return prop;
3646 }
3647
3648 PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont_,
3649                             const char *identifier,
3650                             const char *default_value,
3651                             int maxlen,
3652                             const char *ui_name,
3653                             const char *ui_description)
3654 {
3655   ContainerRNA *cont = cont_;
3656   PropertyRNA *prop;
3657
3658   BLI_assert(default_value == NULL || default_value[0]);
3659
3660   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_NONE);
3661   if (maxlen != 0) {
3662     RNA_def_property_string_maxlength(prop, maxlen);
3663   }
3664   if (default_value) {
3665     RNA_def_property_string_default(prop, default_value);
3666   }
3667   RNA_def_property_ui_text(prop, ui_name, ui_description);
3668
3669   return prop;
3670 }
3671
3672 PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont_,
3673                                       const char *identifier,
3674                                       const char *default_value,
3675                                       int maxlen,
3676                                       const char *ui_name,
3677                                       const char *ui_description)
3678 {
3679   ContainerRNA *cont = cont_;
3680   PropertyRNA *prop;
3681
3682   BLI_assert(default_value == NULL || default_value[0]);
3683
3684   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_FILEPATH);
3685   if (maxlen != 0) {
3686     RNA_def_property_string_maxlength(prop, maxlen);
3687   }
3688   if (default_value) {
3689     RNA_def_property_string_default(prop, default_value);
3690   }
3691   RNA_def_property_ui_text(prop, ui_name, ui_description);
3692
3693   return prop;
3694 }
3695
3696 PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_,
3697                                      const char *identifier,
3698                                      const char *default_value,
3699                                      int maxlen,
3700                                      const char *ui_name,
3701                                      const char *ui_description)
3702 {
3703   ContainerRNA *cont = cont_;
3704   PropertyRNA *prop;
3705
3706   BLI_assert(default_value == NULL || default_value[0]);
3707
3708   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_DIRPATH);
3709   if (maxlen != 0) {
3710     RNA_def_property_string_maxlength(prop, maxlen);
3711   }
3712   if (default_value) {
3713     RNA_def_property_string_default(prop, default_value);
3714   }
3715   RNA_def_property_ui_text(prop, ui_name, ui_description);
3716
3717   return prop;
3718 }
3719
3720 PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont_,
3721                                       const char *identifier,
3722                                       const char *default_value,
3723                                       int maxlen,
3724                                       const char *ui_name,
3725                                       const char *ui_description)
3726 {
3727   ContainerRNA *cont = cont_;
3728   PropertyRNA *prop;
3729
3730   BLI_assert(default_value == NULL || default_value[0]);
3731
3732   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_FILENAME);
3733   if (maxlen != 0) {
3734     RNA_def_property_string_maxlength(prop, maxlen);
3735   }
3736   if (default_value) {
3737     RNA_def_property_string_default(prop, default_value);
3738   }
3739   RNA_def_property_ui_text(prop, ui_name, ui_description);
3740
3741   return prop;
3742 }
3743
3744 PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_,
3745                           const char *identifier,
3746                           const EnumPropertyItem *items,
3747                           int default_value,
3748                           const char *ui_name,
3749                           const char *ui_description)
3750 {
3751   ContainerRNA *cont = cont_;
3752   PropertyRNA *prop;
3753
3754   if (items == NULL) {
3755     CLOG_ERROR(&LOG, "items not allowed to be NULL.");
3756     return NULL;
3757   }
3758
3759   prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
3760   RNA_def_property_enum_items(prop, items);
3761   RNA_def_property_enum_default(prop, default_value);
3762   RNA_def_property_ui_text(prop, ui_name, ui_description);
3763
3764   return prop;
3765 }
3766
3767 /* same as above but sets 'PROP_ENUM_FLAG' before setting the default value */
3768 PropertyRNA *RNA_def_enum_flag(StructOrFunctionRNA *cont_,
3769                                const char *identifier,
3770                                const EnumPropertyItem *items,
3771                                int default_value,
3772                                const char *ui_name,
3773                                const char *ui_description)
3774 {
3775   ContainerRNA *cont = cont_;
3776   PropertyRNA *prop;
3777
3778   if (items == NULL) {
3779     CLOG_ERROR(&LOG, "items not allowed to be NULL.");
3780     return NULL;
3781   }
3782
3783   prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
3784   RNA_def_property_flag(prop, PROP_ENUM_FLAG); /* important to run before default set */
3785   RNA_def_property_enum_items(prop, items);
3786   RNA_def_property_enum_default(prop, default_value);
3787   RNA_def_property_ui_text(prop, ui_name, ui_description);
3788
3789   return prop;
3790 }
3791
3792 void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
3793 {
3794   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3795   eprop->itemf = itemfunc;
3796 }
3797
3798 PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_,
3799                            const char *identifier,
3800                            float default_value,
3801                            float hardmin,
3802                            float hardmax,
3803                            const char *ui_name,
3804                            const char *ui_description,
3805                            float softmin,
3806                            float softmax)
3807 {
3808   ContainerRNA *cont = cont_;
3809   PropertyRNA *prop;
3810
3811   ASSERT_SOFT_HARD_LIMITS;
3812
3813   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
3814   RNA_def_property_float_default(prop, default_value);
3815   if (hardmin != hardmax) {
3816     RNA_def_property_range(prop, hardmin, hardmax);
3817   }
3818   RNA_def_property_ui_text(prop, ui_name, ui_description);
3819   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3820
3821   return prop;
3822 }
3823
3824 PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_,
3825                                   const char *identifier,
3826                                   int len,
3827                                   const float *default_value,
3828                                   float hardmin,
3829                                   float hardmax,
3830                                   const char *ui_name,
3831                                   const char *ui_description,
3832                                   float softmin,
3833                                   float softmax)
3834 {
3835   ContainerRNA *cont = cont_;
3836   PropertyRNA *prop;
3837
3838   ASSERT_SOFT_HARD_LIMITS;
3839
3840   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_XYZ);
3841   if (len != 0) {
3842     RNA_def_property_array(prop, len);
3843   }
3844   if (default_value) {
3845     RNA_def_property_float_array_default(prop, default_value);
3846   }
3847   if (hardmin != hardmax) {
3848     RNA_def_property_range(prop, hardmin, hardmax);
3849   }
3850   RNA_def_property_ui_text(prop, ui_name, ui_description);
3851   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3852
3853   return prop;
3854 }
3855
3856 PropertyRNA *RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_,
3857                                       const char *identifier,
3858                                       int len,
3859                                       const float *default_value,
3860                                       float hardmin,
3861                                       float hardmax,
3862                                       const char *ui_name,
3863                                       const char *ui_description,
3864                                       float softmin,
3865                                       float softmax)
3866 {
3867   PropertyRNA *prop;
3868
3869   prop = RNA_def_float_vector(cont_,
3870                               identifier,
3871                               len,
3872                               default_value,
3873                               hardmin,
3874                               hardmax,
3875                               ui_name,
3876                               ui_description,
3877                               softmin,
3878                               softmax);
3879   prop->subtype = PROP_XYZ_LENGTH;
3880
3881   return prop;
3882 }
3883
3884 PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_,
3885                                  const char *identifier,
3886                                  int len,
3887                                  const float *default_value,
3888                                  float hardmin,
3889                                  float hardmax,
3890                                  const char *ui_name,
3891                                  const char *ui_description,
3892                                  float softmin,
3893                                  float softmax)
3894 {
3895   ContainerRNA *cont = cont_;
3896   PropertyRNA *prop;
3897
3898   ASSERT_SOFT_HARD_LIMITS;
3899
3900   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR);
3901   if (len != 0) {
3902     RNA_def_property_array(prop, len);
3903   }
3904   if (default_value) {
3905     RNA_def_property_float_array_default(prop, default_value);
3906   }
3907   if (hardmin != hardmax) {
3908     RNA_def_property_range(prop, hardmin, hardmax);
3909   }
3910   RNA_def_property_ui_text(prop, ui_name, ui_description);
3911   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3912
3913   return prop;
3914 }
3915
3916 PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_,
3917                                   const char *identifier,
3918                                   int rows,
3919                                   int columns,
3920                                   const float *default_value,
3921                                   float hardmin,
3922                                   float hardmax,
3923                                   const char *ui_name,
3924                                   const char *ui_description,
3925                                   float softmin,
3926                                   float softmax)
3927 {
3928   ContainerRNA *cont = cont_;
3929   PropertyRNA *prop;
3930   const int length[2] = {rows, columns};
3931
3932   ASSERT_SOFT_HARD_LIMITS;
3933
3934   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX);
3935   RNA_def_property_multi_array(prop, 2, length);
3936   if (default_value) {
3937     RNA_def_property_float_array_default(prop, default_value);
3938   }
3939   if (hardmin != hardmax) {
3940     RNA_def_property_range(prop, hardmin, hardmax);
3941   }
3942   RNA_def_property_ui_text(prop, ui_name, ui_description);
3943   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3944
3945   return prop;
3946 }
3947
3948 PropertyRNA *RNA_def_float_translation(StructOrFunctionRNA *cont_,
3949                                        const char *identifier,
3950                                        int len,
3951                                        const float *default_value,
3952                                        float hardmin,
3953                                        float hardmax,
3954                                        const char *ui_name,
3955                                        const char *ui_description,
3956                                        float softmin,
3957                                        float softmax)
3958 {
3959   PropertyRNA *prop;
3960
3961   prop = RNA_def_float_vector(cont_,
3962                               identifier,
3963                               len,
3964                               default_value,
3965                               hardmin,
3966                               hardmax,
3967                               ui_name,
3968                               ui_description,
3969                               softmin,
3970                               softmax);
3971   prop->subtype = PROP_TRANSLATION;
3972
3973   RNA_def_property_ui_range(prop, softmin, softmax, 1, RNA_TRANSLATION_PREC_DEFAULT);
3974
3975   return prop;
3976 }
3977
3978 PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont_,
3979                                     const char *identifier,
3980                                     int len,
3981                                     const float *default_value,
3982                                     float hardmin,
3983                                     float hardmax,
3984                                     const char *ui_name,
3985                                     const char *ui_description,
3986                                     float softmin,
3987                                     float softmax)
3988 {
3989   ContainerRNA *cont = cont_;
3990   PropertyRNA *prop;
3991
3992   ASSERT_SOFT_HARD_LIMITS;
3993
3994   prop = RNA_def_property(cont, identifier, PROP_FLOAT, (len >= 3) ? PROP_EULER : PROP_ANGLE);
3995   if (len != 0) {
3996     RNA_def_property_array(prop, len);
3997     if (default_value) {
3998       RNA_def_property_float_array_default(prop, default_value);
3999     }
4000   }
4001   else {
4002     /* RNA_def_property_float_default must be called outside */
4003     BLI_assert(default_value == NULL);
4004   }
4005   if (hardmin != hardmax) {
4006     RNA_def_property_range(prop, hardmin, hardmax);
4007   }
4008   RNA_def_property_ui_text(prop, ui_name, ui_description);
4009   RNA_def_property_ui_range(prop, softmin, softmax, 10, 3);
4010
4011   return prop;
4012 }
4013
4014 PropertyRNA *RNA_def_float_distance(StructOrFunctionRNA *cont_,
4015                                     const char *identifier,
4016                                     float default_value,
4017                                     float hardmin,
4018                                     float hardmax,
4019                                     const char *ui_name,
4020                                     const char *ui_description,
4021                                     float softmin,
4022                                     float softmax)
4023 {
4024   PropertyRNA *prop = RNA_def_float(cont_,
4025                                     identifier,
4026                                     default_value,
4027                                     hardmin,
4028                                     hardmax,
4029                                     ui_name,
4030                                     ui_description,
4031                                     softmin,
4032                                     softmax);
4033   RNA_def_property_subtype(prop, PROP_DISTANCE);
4034
4035   return prop;
4036 }
4037
4038 PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_,
4039                                  const char *identifier,
4040                                  int len,
4041                                  const float *default_value,
4042                                  float hardmin,
4043                                  float hardmax,
4044                                  const char *ui_name,
4045                                  const char *ui_description,
4046                                  float softmin,
4047                                  float softmax)
4048 {
4049   ContainerRNA *cont = cont_;
4050   PropertyRNA *prop;
4051
4052   ASSERT_SOFT_HARD_LIMITS;
4053
4054   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
4055   if (len != 0) {
4056     RNA_def_property_array(prop, len);
4057   }
4058   if (default_value) {
4059     RNA_def_property_float_array_default(prop, default_value);
4060   }
4061   if (hardmin != hardmax) {
4062     RNA_def_property_range(prop, hardmin, hardmax);
4063   }
4064   RNA_def_property_ui_text(prop, ui_name, ui_description);
4065   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
4066
4067   return prop;
4068 }
4069
4070 PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_,
4071                                       const char *identifier,
4072                                       float default_value,
4073                                       float hardmin,
4074                                       float hardmax,
4075                                       const char *ui_name,
4076                                       const char *ui_description,
4077                                       float softmin,
4078                                       float softmax)
4079 {
4080   ContainerRNA *cont = cont_;
4081   PropertyRNA *prop;
4082
4083   ASSERT_SOFT_HARD_LIMITS;
4084
4085   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE);
4086   RNA_def_property_float_default(prop, default_value);
4087   if (hardmin != hardmax) {
4088     RNA_def_property_range(prop, hardmin, hardmax);
4089   }
4090   RNA_def_property_ui_text(prop, ui_name, ui_description);
4091   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
4092
4093   return prop;
4094 }
4095
4096 PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_,
4097                                   const char *identifier,
4098                                   float default_value,
4099                                   float hardmin,
4100                                   float hardmax,
4101                                   const char *ui_name,
4102                                   const char *ui_description,
4103                                   float softmin,
4104                                   float softmax)
4105 {
4106   ContainerRNA *cont = cont_;
4107   PropertyRNA *prop;
4108
4109   ASSERT_SOFT_HARD_LIMITS;
4110
4111   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR);
4112   RNA_def_property_float_default(prop, default_value);
4113   if (hardmin != hardmax) {
4114     RNA_def_property_range(prop, hardmin, hardmax);
4115   }
4116   RNA_def_property_ui_text(prop, ui_name, ui_description);
4117   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
4118
4119   return prop;
4120 }
4121
4122 PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont_,
4123                              const char *identifier,
4124                              const char *type,
4125                              const char *ui_name,
4126                              const char *ui_description)
4127 {
4128   ContainerRNA *cont = cont_;
4129   PropertyRNA *prop;
4130
4131   prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
4132   RNA_def_property_struct_type(prop, type);
4133   RNA_def_property_ui_text(prop, ui_name, ui_description);
4134
4135   return prop;
4136 }
4137
4138 PropertyRNA *RNA_def_pointer_runtime(StructOrFunctionRNA *cont_,
4139                                      const char *identifier,
4140                                      StructRNA *type,
4141                                      const char *ui_name,
4142                                      const char *ui_description)
4143 {
4144   ContainerRNA *cont = cont_;
4145   PropertyRNA *prop;
4146
4147   prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
4148   RNA_def_property_struct_runtime(prop, type);
4149   if ((type->flag & STRUCT_ID) != 0) {
4150     prop->flag |= PROP_EDITABLE;
4151   }
4152   RNA_def_property_ui_text(prop, ui_name, ui_description);
4153
4154   return prop;
4155 }
4156
4157 PropertyRNA *RNA_def_collection(StructOrFunctionRNA *cont_,
4158                                 const char *identifier,
4159                                 const char *type,
4160                                 const char *ui_name,
4161                                 const char *ui_description)
4162 {
4163   ContainerRNA *cont = cont_;
4164   PropertyRNA *prop;
4165
4166   prop = RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
4167   RNA_def_property_struct_type(prop, type);
4168   RNA_def_property_ui_text(prop, ui_name, ui_description);
4169
4170   return prop;
4171 }