a77402cb88dcb9497c1e473300cc87ba1150d38b
[blender.git] / source / blender / makesrna / intern / makesrna.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 <float.h>
22 #include <limits.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27
28 #include "MEM_guardedalloc.h"
29
30 #include "BLI_utildefines.h"
31
32 #include "RNA_define.h"
33 #include "RNA_types.h"
34 #include "RNA_enum_types.h"
35
36 #include "rna_internal.h"
37
38 #ifdef _WIN32
39 #  ifndef snprintf
40 #    define snprintf _snprintf
41 #  endif
42 #endif
43
44 #include "CLG_log.h"
45
46 static CLG_LogRef LOG = {"makesrna"};
47
48 /**
49  * Variable to control debug output of makesrna.
50  * debugSRNA:
51  * - 0 = no output, except errors
52  * - 1 = detail actions
53  */
54 static int debugSRNA = 0;
55
56 /* stub for BLI_abort() */
57 #ifndef NDEBUG
58 void BLI_system_backtrace(FILE *fp)
59 {
60   (void)fp;
61 }
62 #endif
63
64 /* Replace if different */
65 #define TMP_EXT ".tmp"
66
67 /* copied from BLI_file_older */
68 #include <sys/stat.h>
69 static int file_older(const char *file1, const char *file2)
70 {
71   struct stat st1, st2;
72   if (debugSRNA > 0) {
73     printf("compare: %s %s\n", file1, file2);
74   }
75
76   if (stat(file1, &st1)) {
77     return 0;
78   }
79   if (stat(file2, &st2)) {
80     return 0;
81   }
82
83   return (st1.st_mtime < st2.st_mtime);
84 }
85 static const char *makesrna_path = NULL;
86
87 /* forward declarations */
88 static void rna_generate_static_parameter_prototypes(FILE *f,
89                                                      StructRNA *srna,
90                                                      FunctionDefRNA *dfunc,
91                                                      const char *name_override,
92                                                      int close_prototype);
93
94 /* helpers */
95 #define WRITE_COMMA \
96   { \
97     if (!first) \
98       fprintf(f, ", "); \
99     first = 0; \
100   } \
101   (void)0
102
103 #define WRITE_PARAM(param) \
104   { \
105     WRITE_COMMA; \
106     fprintf(f, param); \
107   } \
108   (void)0
109
110 static int replace_if_different(const char *tmpfile, const char *dep_files[])
111 {
112   /* return 0;  */ /* use for testing had edited rna */
113
114 #define REN_IF_DIFF \
115   { \
116     FILE *file_test = fopen(orgfile, "rb"); \
117     if (file_test) { \
118       fclose(file_test); \
119       if (fp_org) \
120         fclose(fp_org); \
121       if (fp_new) \
122         fclose(fp_new); \
123       if (remove(orgfile) != 0) { \
124         CLOG_ERROR(&LOG, "remove error (%s): \"%s\"", strerror(errno), orgfile); \
125         return -1; \
126       } \
127     } \
128   } \
129   if (rename(tmpfile, orgfile) != 0) { \
130     CLOG_ERROR(&LOG, "rename error (%s): \"%s\" -> \"%s\"", strerror(errno), tmpfile, orgfile); \
131     return -1; \
132   } \
133   remove(tmpfile); \
134   return 1
135
136   /* end REN_IF_DIFF */
137
138   FILE *fp_new = NULL, *fp_org = NULL;
139   int len_new, len_org;
140   char *arr_new, *arr_org;
141   int cmp;
142
143   char orgfile[4096];
144
145   strcpy(orgfile, tmpfile);
146   orgfile[strlen(orgfile) - strlen(TMP_EXT)] = '\0'; /* strip '.tmp' */
147
148   fp_org = fopen(orgfile, "rb");
149
150   if (fp_org == NULL) {
151     REN_IF_DIFF;
152   }
153
154   /* XXX, trick to work around dependency problem
155    * assumes dep_files is in the same dir as makesrna.c, which is true for now. */
156
157   if (1) {
158     /* first check if makesrna.c is newer then generated files
159      * for development on makesrna.c you may want to disable this */
160     if (file_older(orgfile, __FILE__)) {
161       REN_IF_DIFF;
162     }
163
164     if (file_older(orgfile, makesrna_path)) {
165       REN_IF_DIFF;
166     }
167
168     /* now check if any files we depend on are newer then any generated files */
169     if (dep_files) {
170       int pass;
171       for (pass = 0; dep_files[pass]; pass++) {
172         char from_path[4096] = __FILE__;
173         char *p1, *p2;
174
175         /* dir only */
176         p1 = strrchr(from_path, '/');
177         p2 = strrchr(from_path, '\\');
178         strcpy((p1 > p2 ? p1 : p2) + 1, dep_files[pass]);
179         /* account for build deps, if makesrna.c (this file) is newer */
180         if (file_older(orgfile, from_path)) {
181           REN_IF_DIFF;
182         }
183       }
184     }
185   }
186   /* XXX end dep trick */
187
188   fp_new = fopen(tmpfile, "rb");
189
190   if (fp_new == NULL) {
191     /* shouldn't happen, just to be safe */
192     CLOG_ERROR(&LOG, "open error: \"%s\"", tmpfile);
193     fclose(fp_org);
194     return -1;
195   }
196
197   fseek(fp_new, 0L, SEEK_END);
198   len_new = ftell(fp_new);
199   fseek(fp_new, 0L, SEEK_SET);
200   fseek(fp_org, 0L, SEEK_END);
201   len_org = ftell(fp_org);
202   fseek(fp_org, 0L, SEEK_SET);
203
204   if (len_new != len_org) {
205     fclose(fp_new);
206     fp_new = NULL;
207     fclose(fp_org);
208     fp_org = NULL;
209     REN_IF_DIFF;
210   }
211
212   /* now compare the files... */
213   arr_new = MEM_mallocN(sizeof(char) * len_new, "rna_cmp_file_new");
214   arr_org = MEM_mallocN(sizeof(char) * len_org, "rna_cmp_file_org");
215
216   if (fread(arr_new, sizeof(char), len_new, fp_new) != len_new) {
217     CLOG_ERROR(&LOG, "unable to read file %s for comparison.", tmpfile);
218   }
219   if (fread(arr_org, sizeof(char), len_org, fp_org) != len_org) {
220     CLOG_ERROR(&LOG, "unable to read file %s for comparison.", orgfile);
221   }
222
223   fclose(fp_new);
224   fp_new = NULL;
225   fclose(fp_org);
226   fp_org = NULL;
227
228   cmp = memcmp(arr_new, arr_org, len_new);
229
230   MEM_freeN(arr_new);
231   MEM_freeN(arr_org);
232
233   if (cmp) {
234     REN_IF_DIFF;
235   }
236   else {
237     remove(tmpfile);
238     return 0;
239   }
240
241 #undef REN_IF_DIFF
242 }
243
244 /* Helper to solve keyword problems with C/C++ */
245
246 static const char *rna_safe_id(const char *id)
247 {
248   if (STREQ(id, "default")) {
249     return "default_value";
250   }
251   else if (STREQ(id, "operator")) {
252     return "operator_value";
253   }
254   else if (STREQ(id, "new")) {
255     return "create";
256   }
257   else if (STREQ(id, "co_return")) {
258     /* MSVC2015, C++ uses for coroutines */
259     return "coord_return";
260   }
261
262   return id;
263 }
264
265 /* Sorting */
266
267 static int cmp_struct(const void *a, const void *b)
268 {
269   const StructRNA *structa = *(const StructRNA **)a;
270   const StructRNA *structb = *(const StructRNA **)b;
271
272   return strcmp(structa->identifier, structb->identifier);
273 }
274
275 static int cmp_property(const void *a, const void *b)
276 {
277   const PropertyRNA *propa = *(const PropertyRNA **)a;
278   const PropertyRNA *propb = *(const PropertyRNA **)b;
279
280   if (STREQ(propa->identifier, "rna_type")) {
281     return -1;
282   }
283   else if (STREQ(propb->identifier, "rna_type")) {
284     return 1;
285   }
286
287   if (STREQ(propa->identifier, "name")) {
288     return -1;
289   }
290   else if (STREQ(propb->identifier, "name")) {
291     return 1;
292   }
293
294   return strcmp(propa->name, propb->name);
295 }
296
297 static int cmp_def_struct(const void *a, const void *b)
298 {
299   const StructDefRNA *dsa = *(const StructDefRNA **)a;
300   const StructDefRNA *dsb = *(const StructDefRNA **)b;
301
302   return cmp_struct(&dsa->srna, &dsb->srna);
303 }
304
305 static int cmp_def_property(const void *a, const void *b)
306 {
307   const PropertyDefRNA *dpa = *(const PropertyDefRNA **)a;
308   const PropertyDefRNA *dpb = *(const PropertyDefRNA **)b;
309
310   return cmp_property(&dpa->prop, &dpb->prop);
311 }
312
313 static void rna_sortlist(ListBase *listbase, int (*cmp)(const void *, const void *))
314 {
315   Link *link;
316   void **array;
317   int a, size;
318
319   if (listbase->first == listbase->last) {
320     return;
321   }
322
323   for (size = 0, link = listbase->first; link; link = link->next) {
324     size++;
325   }
326
327   array = MEM_mallocN(sizeof(void *) * size, "rna_sortlist");
328   for (a = 0, link = listbase->first; link; link = link->next, a++) {
329     array[a] = link;
330   }
331
332   qsort(array, size, sizeof(void *), cmp);
333
334   listbase->first = listbase->last = NULL;
335   for (a = 0; a < size; a++) {
336     link = array[a];
337     link->next = link->prev = NULL;
338     rna_addtail(listbase, link);
339   }
340
341   MEM_freeN(array);
342 }
343
344 /* Preprocessing */
345
346 static void rna_print_c_string(FILE *f, const char *str)
347 {
348   static const char *escape[] = {
349       "\''", "\"\"", "\??", "\\\\", "\aa", "\bb", "\ff", "\nn", "\rr", "\tt", "\vv", NULL};
350   int i, j;
351
352   if (!str) {
353     fprintf(f, "NULL");
354     return;
355   }
356
357   fprintf(f, "\"");
358   for (i = 0; str[i]; i++) {
359     for (j = 0; escape[j]; j++) {
360       if (str[i] == escape[j][0]) {
361         break;
362       }
363     }
364
365     if (escape[j]) {
366       fprintf(f, "\\%c", escape[j][1]);
367     }
368     else {
369       fprintf(f, "%c", str[i]);
370     }
371   }
372   fprintf(f, "\"");
373 }
374
375 static void rna_print_data_get(FILE *f, PropertyDefRNA *dp)
376 {
377   if (dp->dnastructfromname && dp->dnastructfromprop) {
378     fprintf(f,
379             "    %s *data = (%s *)(((%s *)ptr->data)->%s);\n",
380             dp->dnastructname,
381             dp->dnastructname,
382             dp->dnastructfromname,
383             dp->dnastructfromprop);
384   }
385   else {
386     fprintf(f, "    %s *data = (%s *)(ptr->data);\n", dp->dnastructname, dp->dnastructname);
387   }
388 }
389
390 static void rna_print_id_get(FILE *f, PropertyDefRNA *UNUSED(dp))
391 {
392   fprintf(f, "    ID *id = ptr->id.data;\n");
393 }
394
395 static void rna_construct_function_name(
396     char *buffer, int size, const char *structname, const char *propname, const char *type)
397 {
398   snprintf(buffer, size, "%s_%s_%s", structname, propname, type);
399 }
400
401 static void rna_construct_wrapper_function_name(
402     char *buffer, int size, const char *structname, const char *propname, const char *type)
403 {
404   if (type == NULL || type[0] == '\0') {
405     snprintf(buffer, size, "%s_%s", structname, propname);
406   }
407   else {
408     snprintf(buffer, size, "%s_%s_%s", structname, propname, type);
409   }
410 }
411
412 static char *rna_alloc_function_name(const char *structname,
413                                      const char *propname,
414                                      const char *type)
415 {
416   AllocDefRNA *alloc;
417   char buffer[2048];
418   char *result;
419
420   rna_construct_function_name(buffer, sizeof(buffer), structname, propname, type);
421   result = MEM_callocN(sizeof(char) * strlen(buffer) + 1, "rna_alloc_function_name");
422   strcpy(result, buffer);
423
424   alloc = MEM_callocN(sizeof(AllocDefRNA), "AllocDefRNA");
425   alloc->mem = result;
426   rna_addtail(&DefRNA.allocs, alloc);
427
428   return result;
429 }
430
431 static StructRNA *rna_find_struct(const char *identifier)
432 {
433   StructDefRNA *ds;
434
435   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
436     if (STREQ(ds->srna->identifier, identifier)) {
437       return ds->srna;
438     }
439   }
440
441   return NULL;
442 }
443
444 static const char *rna_find_type(const char *type)
445 {
446   StructDefRNA *ds;
447
448   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
449     if (ds->dnaname && STREQ(ds->dnaname, type)) {
450       return ds->srna->identifier;
451     }
452   }
453
454   return NULL;
455 }
456
457 static const char *rna_find_dna_type(const char *type)
458 {
459   StructDefRNA *ds;
460
461   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
462     if (STREQ(ds->srna->identifier, type)) {
463       return ds->dnaname;
464     }
465   }
466
467   return NULL;
468 }
469
470 static const char *rna_type_type_name(PropertyRNA *prop)
471 {
472   switch (prop->type) {
473     case PROP_BOOLEAN:
474       return "bool";
475     case PROP_INT:
476     case PROP_ENUM:
477       return "int";
478     case PROP_FLOAT:
479       return "float";
480     case PROP_STRING:
481       if (prop->flag & PROP_THICK_WRAP) {
482         return "char *";
483       }
484       else {
485         return "const char *";
486       }
487     default:
488       return NULL;
489   }
490 }
491
492 static const char *rna_type_type(PropertyRNA *prop)
493 {
494   const char *type;
495
496   type = rna_type_type_name(prop);
497
498   if (type) {
499     return type;
500   }
501
502   return "PointerRNA";
503 }
504
505 static const char *rna_type_struct(PropertyRNA *prop)
506 {
507   const char *type;
508
509   type = rna_type_type_name(prop);
510
511   if (type) {
512     return "";
513   }
514
515   return "struct ";
516 }
517
518 static const char *rna_parameter_type_name(PropertyRNA *parm)
519 {
520   const char *type;
521
522   type = rna_type_type_name(parm);
523
524   if (type) {
525     return type;
526   }
527
528   switch (parm->type) {
529     case PROP_POINTER: {
530       PointerPropertyRNA *pparm = (PointerPropertyRNA *)parm;
531
532       if (parm->flag_parameter & PARM_RNAPTR) {
533         return "PointerRNA";
534       }
535       else {
536         return rna_find_dna_type((const char *)pparm->type);
537       }
538     }
539     case PROP_COLLECTION: {
540       return "CollectionListBase";
541     }
542     default:
543       return "<error, no type specified>";
544   }
545 }
546
547 static int rna_enum_bitmask(PropertyRNA *prop)
548 {
549   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
550   int a, mask = 0;
551
552   if (eprop->item) {
553     for (a = 0; a < eprop->totitem; a++) {
554       if (eprop->item[a].identifier[0]) {
555         mask |= eprop->item[a].value;
556       }
557     }
558   }
559
560   return mask;
561 }
562
563 static int rna_color_quantize(PropertyRNA *prop, PropertyDefRNA *dp)
564 {
565   return ((prop->type == PROP_FLOAT) &&
566           (prop->subtype == PROP_COLOR || prop->subtype == PROP_COLOR_GAMMA) &&
567           (IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0));
568 }
569
570 static const char *rna_function_string(void *func)
571 {
572   return (func) ? (const char *)func : "NULL";
573 }
574
575 static void rna_float_print(FILE *f, float num)
576 {
577   if (num == -FLT_MAX) {
578     fprintf(f, "-FLT_MAX");
579   }
580   else if (num == FLT_MAX) {
581     fprintf(f, "FLT_MAX");
582   }
583   else if ((ABS(num) < INT64_MAX) && ((int64_t)num == num)) {
584     fprintf(f, "%.1ff", num);
585   }
586   else {
587     fprintf(f, "%.10ff", num);
588   }
589 }
590
591 static void rna_int_print(FILE *f, int num)
592 {
593   if (num == INT_MIN) {
594     fprintf(f, "INT_MIN");
595   }
596   else if (num == INT_MAX) {
597     fprintf(f, "INT_MAX");
598   }
599   else {
600     fprintf(f, "%d", num);
601   }
602 }
603
604 static char *rna_def_property_get_func(
605     FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, const char *manualfunc)
606 {
607   char *func;
608
609   if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL) {
610     return NULL;
611   }
612
613   if (!manualfunc) {
614     if (!dp->dnastructname || !dp->dnaname) {
615       CLOG_ERROR(&LOG, "%s.%s has no valid dna info.", srna->identifier, prop->identifier);
616       DefRNA.error = 1;
617       return NULL;
618     }
619
620     /* typecheck,  */
621     if (dp->dnatype && *dp->dnatype) {
622
623       if (prop->type == PROP_FLOAT) {
624         if (IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) {
625           if (prop->subtype !=
626               PROP_COLOR_GAMMA) { /* colors are an exception. these get translated */
627             CLOG_ERROR(&LOG,
628                        "%s.%s is a '%s' but wrapped as type '%s'.",
629                        srna->identifier,
630                        prop->identifier,
631                        dp->dnatype,
632                        RNA_property_typename(prop->type));
633             DefRNA.error = 1;
634             return NULL;
635           }
636         }
637       }
638       else if (prop->type == PROP_INT || prop->type == PROP_BOOLEAN || prop->type == PROP_ENUM) {
639         if (IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
640           CLOG_ERROR(&LOG,
641                      "%s.%s is a '%s' but wrapped as type '%s'.",
642                      srna->identifier,
643                      prop->identifier,
644                      dp->dnatype,
645                      RNA_property_typename(prop->type));
646           DefRNA.error = 1;
647           return NULL;
648         }
649       }
650     }
651   }
652
653   func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get");
654
655   switch (prop->type) {
656     case PROP_STRING: {
657       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
658       fprintf(f, "void %s(PointerRNA *ptr, char *value)\n", func);
659       fprintf(f, "{\n");
660       if (manualfunc) {
661         fprintf(f, "    %s(ptr, value);\n", manualfunc);
662       }
663       else {
664         const PropertySubType subtype = prop->subtype;
665         const char *string_copy_func = (subtype == PROP_FILEPATH || subtype == PROP_DIRPATH ||
666                                         subtype == PROP_FILENAME || subtype == PROP_BYTESTRING) ?
667                                            "BLI_strncpy" :
668                                            "BLI_strncpy_utf8";
669
670         rna_print_data_get(f, dp);
671
672         if (!(prop->flag & PROP_NEVER_NULL)) {
673           fprintf(f, "    if (data->%s == NULL) {\n", dp->dnaname);
674           fprintf(f, "        *value = '\\0';\n");
675           fprintf(f, "        return;\n");
676           fprintf(f, "    }\n");
677         }
678
679         if (sprop->maxlength) {
680           fprintf(f,
681                   "    %s(value, data->%s, %d);\n",
682                   string_copy_func,
683                   dp->dnaname,
684                   sprop->maxlength);
685         }
686         else {
687           fprintf(f,
688                   "    %s(value, data->%s, sizeof(data->%s));\n",
689                   string_copy_func,
690                   dp->dnaname,
691                   dp->dnaname);
692         }
693       }
694       fprintf(f, "}\n\n");
695       break;
696     }
697     case PROP_POINTER: {
698       fprintf(f, "PointerRNA %s(PointerRNA *ptr)\n", func);
699       fprintf(f, "{\n");
700       if (manualfunc) {
701         fprintf(f, "    return %s(ptr);\n", manualfunc);
702       }
703       else {
704         PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
705         rna_print_data_get(f, dp);
706         if (dp->dnapointerlevel == 0) {
707           fprintf(f,
708                   "    return rna_pointer_inherit_refine(ptr, &RNA_%s, &data->%s);\n",
709                   (const char *)pprop->type,
710                   dp->dnaname);
711         }
712         else {
713           fprintf(f,
714                   "    return rna_pointer_inherit_refine(ptr, &RNA_%s, data->%s);\n",
715                   (const char *)pprop->type,
716                   dp->dnaname);
717         }
718       }
719       fprintf(f, "}\n\n");
720       break;
721     }
722     case PROP_COLLECTION: {
723       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
724
725       fprintf(f, "static PointerRNA %s(CollectionPropertyIterator *iter)\n", func);
726       fprintf(f, "{\n");
727       if (manualfunc) {
728         if (STREQ(manualfunc, "rna_iterator_listbase_get") ||
729             STREQ(manualfunc, "rna_iterator_array_get") ||
730             STREQ(manualfunc, "rna_iterator_array_dereference_get")) {
731           fprintf(f,
732                   "    return rna_pointer_inherit_refine(&iter->parent, &RNA_%s, %s(iter));\n",
733                   (cprop->item_type) ? (const char *)cprop->item_type : "UnknownType",
734                   manualfunc);
735         }
736         else {
737           fprintf(f, "    return %s(iter);\n", manualfunc);
738         }
739       }
740       fprintf(f, "}\n\n");
741       break;
742     }
743     default:
744       if (prop->arraydimension) {
745         if (prop->flag & PROP_DYNAMIC) {
746           fprintf(f, "void %s(PointerRNA *ptr, %s values[])\n", func, rna_type_type(prop));
747         }
748         else {
749           fprintf(f,
750                   "void %s(PointerRNA *ptr, %s values[%u])\n",
751                   func,
752                   rna_type_type(prop),
753                   prop->totarraylength);
754         }
755         fprintf(f, "{\n");
756
757         if (manualfunc) {
758           fprintf(f, "    %s(ptr, values);\n", manualfunc);
759         }
760         else {
761           rna_print_data_get(f, dp);
762
763           if (prop->flag & PROP_DYNAMIC) {
764             char *lenfunc = rna_alloc_function_name(
765                 srna->identifier, rna_safe_id(prop->identifier), "get_length");
766             fprintf(f, "    unsigned int arraylen[RNA_MAX_ARRAY_DIMENSION];\n");
767             fprintf(f, "    unsigned int i;\n");
768             fprintf(f, "    unsigned int len = %s(ptr, arraylen);\n\n", lenfunc);
769             fprintf(f, "    for (i = 0; i < len; i++) {\n");
770             MEM_freeN(lenfunc);
771           }
772           else {
773             fprintf(f, "    unsigned int i;\n\n");
774             fprintf(f, "    for (i = 0; i < %u; i++) {\n", prop->totarraylength);
775           }
776
777           if (dp->dnaarraylength == 1) {
778             if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
779               fprintf(f,
780                       "        values[i] = %s((data->%s & (%du << i)) != 0);\n",
781                       (dp->booleannegative) ? "!" : "",
782                       dp->dnaname,
783                       dp->booleanbit);
784             }
785             else {
786               fprintf(f,
787                       "        values[i] = (%s)%s((&data->%s)[i]);\n",
788                       rna_type_type(prop),
789                       (dp->booleannegative) ? "!" : "",
790                       dp->dnaname);
791             }
792           }
793           else {
794             if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
795               fprintf(f,
796                       "        values[i] = %s((data->%s[i] & ",
797                       (dp->booleannegative) ? "!" : "",
798                       dp->dnaname);
799               rna_int_print(f, dp->booleanbit);
800               fprintf(f, ") != 0);\n");
801             }
802             else if (rna_color_quantize(prop, dp)) {
803               fprintf(f,
804                       "        values[i] = (%s)(data->%s[i] * (1.0f / 255.0f));\n",
805                       rna_type_type(prop),
806                       dp->dnaname);
807             }
808             else if (dp->dnatype) {
809               fprintf(f,
810                       "        values[i] = (%s)%s(((%s *)data->%s)[i]);\n",
811                       rna_type_type(prop),
812                       (dp->booleannegative) ? "!" : "",
813                       dp->dnatype,
814                       dp->dnaname);
815             }
816             else {
817               fprintf(f,
818                       "        values[i] = (%s)%s((data->%s)[i]);\n",
819                       rna_type_type(prop),
820                       (dp->booleannegative) ? "!" : "",
821                       dp->dnaname);
822             }
823           }
824           fprintf(f, "    }\n");
825         }
826         fprintf(f, "}\n\n");
827       }
828       else {
829         fprintf(f, "%s %s(PointerRNA *ptr)\n", rna_type_type(prop), func);
830         fprintf(f, "{\n");
831
832         if (manualfunc) {
833           fprintf(f, "    return %s(ptr);\n", manualfunc);
834         }
835         else {
836           rna_print_data_get(f, dp);
837           if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
838             fprintf(
839                 f, "    return %s(((data->%s) & ", (dp->booleannegative) ? "!" : "", dp->dnaname);
840             rna_int_print(f, dp->booleanbit);
841             fprintf(f, ") != 0);\n");
842           }
843           else if (prop->type == PROP_ENUM && dp->enumbitflags) {
844             fprintf(f, "    return ((data->%s) & ", dp->dnaname);
845             rna_int_print(f, rna_enum_bitmask(prop));
846             fprintf(f, ");\n");
847           }
848           else {
849             fprintf(f,
850                     "    return (%s)%s(data->%s);\n",
851                     rna_type_type(prop),
852                     (dp->booleannegative) ? "!" : "",
853                     dp->dnaname);
854           }
855         }
856
857         fprintf(f, "}\n\n");
858       }
859       break;
860   }
861
862   return func;
863 }
864
865 /* defined min/max variables to be used by rna_clamp_value() */
866 static void rna_clamp_value_range(FILE *f, PropertyRNA *prop)
867 {
868   if (prop->type == PROP_FLOAT) {
869     FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
870     if (fprop->range) {
871       fprintf(f,
872               "    float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, "
873               "prop_soft_max;\n");
874       fprintf(f,
875               "    %s(ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max);\n",
876               rna_function_string(fprop->range));
877     }
878   }
879   else if (prop->type == PROP_INT) {
880     IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
881     if (iprop->range) {
882       fprintf(f,
883               "    int prop_clamp_min = INT_MIN, prop_clamp_max = INT_MAX, prop_soft_min, "
884               "prop_soft_max;\n");
885       fprintf(f,
886               "    %s(ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max);\n",
887               rna_function_string(iprop->range));
888     }
889   }
890 }
891
892 #ifdef USE_RNA_RANGE_CHECK
893 static void rna_clamp_value_range_check(FILE *f,
894                                         PropertyRNA *prop,
895                                         const char *dnaname_prefix,
896                                         const char *dnaname)
897 {
898   if (prop->type == PROP_INT) {
899     IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
900     fprintf(f,
901             "    { BLI_STATIC_ASSERT("
902             "(TYPEOF_MAX(%s%s) >= %d) && "
903             "(TYPEOF_MIN(%s%s) <= %d), "
904             "\"invalid limits\"); }\n",
905             dnaname_prefix,
906             dnaname,
907             iprop->hardmax,
908             dnaname_prefix,
909             dnaname,
910             iprop->hardmin);
911   }
912 }
913 #endif /* USE_RNA_RANGE_CHECK */
914
915 static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array)
916 {
917   if (prop->type == PROP_INT) {
918     IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
919
920     if (iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX || iprop->range) {
921       if (array) {
922         fprintf(f, "CLAMPIS(values[i], ");
923       }
924       else {
925         fprintf(f, "CLAMPIS(value, ");
926       }
927       if (iprop->range) {
928         fprintf(f, "prop_clamp_min, prop_clamp_max);");
929       }
930       else {
931         rna_int_print(f, iprop->hardmin);
932         fprintf(f, ", ");
933         rna_int_print(f, iprop->hardmax);
934         fprintf(f, ");\n");
935       }
936       return;
937     }
938   }
939   else if (prop->type == PROP_FLOAT) {
940     FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
941
942     if (fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX || fprop->range) {
943       if (array) {
944         fprintf(f, "CLAMPIS(values[i], ");
945       }
946       else {
947         fprintf(f, "CLAMPIS(value, ");
948       }
949       if (fprop->range) {
950         fprintf(f, "prop_clamp_min, prop_clamp_max);");
951       }
952       else {
953         rna_float_print(f, fprop->hardmin);
954         fprintf(f, ", ");
955         rna_float_print(f, fprop->hardmax);
956         fprintf(f, ");\n");
957       }
958       return;
959     }
960   }
961
962   if (array) {
963     fprintf(f, "values[i];\n");
964   }
965   else {
966     fprintf(f, "value;\n");
967   }
968 }
969
970 static char *rna_def_property_set_func(
971     FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, const char *manualfunc)
972 {
973   char *func;
974
975   if (!(prop->flag & PROP_EDITABLE)) {
976     return NULL;
977   }
978   if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL) {
979     return NULL;
980   }
981
982   if (!manualfunc) {
983     if (!dp->dnastructname || !dp->dnaname) {
984       if (prop->flag & PROP_EDITABLE) {
985         CLOG_ERROR(&LOG, "%s.%s has no valid dna info.", srna->identifier, prop->identifier);
986         DefRNA.error = 1;
987       }
988       return NULL;
989     }
990   }
991
992   func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "set");
993
994   switch (prop->type) {
995     case PROP_STRING: {
996       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
997       fprintf(f, "void %s(PointerRNA *ptr, const char *value)\n", func);
998       fprintf(f, "{\n");
999       if (manualfunc) {
1000         fprintf(f, "    %s(ptr, value);\n", manualfunc);
1001       }
1002       else {
1003         const PropertySubType subtype = prop->subtype;
1004         const char *string_copy_func = (subtype == PROP_FILEPATH || subtype == PROP_DIRPATH ||
1005                                         subtype == PROP_FILENAME || subtype == PROP_BYTESTRING) ?
1006                                            "BLI_strncpy" :
1007                                            "BLI_strncpy_utf8";
1008
1009         rna_print_data_get(f, dp);
1010
1011         if (!(prop->flag & PROP_NEVER_NULL)) {
1012           fprintf(f, "    if (data->%s == NULL) {\n", dp->dnaname);
1013           fprintf(f, "        return;\n");
1014           fprintf(f, "    }\n");
1015         }
1016
1017         if (sprop->maxlength) {
1018           fprintf(f,
1019                   "    %s(data->%s, value, %d);\n",
1020                   string_copy_func,
1021                   dp->dnaname,
1022                   sprop->maxlength);
1023         }
1024         else {
1025           fprintf(f,
1026                   "    %s(data->%s, value, sizeof(data->%s));\n",
1027                   string_copy_func,
1028                   dp->dnaname,
1029                   dp->dnaname);
1030         }
1031       }
1032       fprintf(f, "}\n\n");
1033       break;
1034     }
1035     case PROP_POINTER: {
1036       fprintf(f, "void %s(struct ReportList *reports, PointerRNA *ptr, PointerRNA value)\n", func);
1037       fprintf(f, "{\n");
1038       if (manualfunc) {
1039         fprintf(f, "    %s(reports, ptr, value);\n", manualfunc);
1040       }
1041       else {
1042         rna_print_data_get(f, dp);
1043
1044         if (prop->flag & PROP_ID_SELF_CHECK) {
1045           rna_print_id_get(f, dp);
1046           fprintf(f, "    if (id == value.data) return;\n\n");
1047         }
1048
1049         if (prop->flag & PROP_ID_REFCOUNT) {
1050           fprintf(f, "\n    if (data->%s)\n", dp->dnaname);
1051           fprintf(f, "        id_us_min((ID *)data->%s);\n", dp->dnaname);
1052           fprintf(f, "    if (value.data)\n");
1053           fprintf(f, "        id_us_plus((ID *)value.data);\n\n");
1054         }
1055         else {
1056           PointerPropertyRNA *pprop = (PointerPropertyRNA *)dp->prop;
1057           StructRNA *type = (pprop->type) ? rna_find_struct((const char *)pprop->type) : NULL;
1058           if (type && (type->flag & STRUCT_ID)) {
1059             fprintf(f, "    if (value.data)\n");
1060             fprintf(f, "        id_lib_extern((ID *)value.data);\n\n");
1061           }
1062         }
1063
1064         fprintf(f, "    data->%s = value.data;\n", dp->dnaname);
1065       }
1066       fprintf(f, "}\n\n");
1067       break;
1068     }
1069     default:
1070       if (prop->arraydimension) {
1071         if (prop->flag & PROP_DYNAMIC) {
1072           fprintf(f, "void %s(PointerRNA *ptr, const %s values[])\n", func, rna_type_type(prop));
1073         }
1074         else {
1075           fprintf(f,
1076                   "void %s(PointerRNA *ptr, const %s values[%u])\n",
1077                   func,
1078                   rna_type_type(prop),
1079                   prop->totarraylength);
1080         }
1081         fprintf(f, "{\n");
1082
1083         if (manualfunc) {
1084           fprintf(f, "    %s(ptr, values);\n", manualfunc);
1085         }
1086         else {
1087           rna_print_data_get(f, dp);
1088
1089           if (prop->flag & PROP_DYNAMIC) {
1090             char *lenfunc = rna_alloc_function_name(
1091                 srna->identifier, rna_safe_id(prop->identifier), "set_length");
1092             fprintf(f, "    unsigned int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n");
1093             fprintf(f, "    unsigned int len = %s(ptr, arraylen);\n\n", lenfunc);
1094             rna_clamp_value_range(f, prop);
1095             fprintf(f, "    for (i = 0; i < len; i++) {\n");
1096             MEM_freeN(lenfunc);
1097           }
1098           else {
1099             fprintf(f, "    unsigned int i;\n\n");
1100             rna_clamp_value_range(f, prop);
1101             fprintf(f, "    for (i = 0; i < %u; i++) {\n", prop->totarraylength);
1102           }
1103
1104           if (dp->dnaarraylength == 1) {
1105             if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
1106               fprintf(f,
1107                       "        if (%svalues[i]) data->%s |= (%du << i);\n",
1108                       (dp->booleannegative) ? "!" : "",
1109                       dp->dnaname,
1110                       dp->booleanbit);
1111               fprintf(f, "        else data->%s &= ~(%du << i);\n", dp->dnaname, dp->booleanbit);
1112             }
1113             else {
1114               fprintf(
1115                   f, "        (&data->%s)[i] = %s", dp->dnaname, (dp->booleannegative) ? "!" : "");
1116               rna_clamp_value(f, prop, 1);
1117             }
1118           }
1119           else {
1120             if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
1121               fprintf(f,
1122                       "        if (%svalues[i]) data->%s[i] |= ",
1123                       (dp->booleannegative) ? "!" : "",
1124                       dp->dnaname);
1125               rna_int_print(f, dp->booleanbit);
1126               fprintf(f, ";\n");
1127               fprintf(f, "        else data->%s[i] &= ~", dp->dnaname);
1128               rna_int_print(f, dp->booleanbit);
1129               fprintf(f, ";\n");
1130             }
1131             else if (rna_color_quantize(prop, dp)) {
1132               fprintf(
1133                   f, "        data->%s[i] = unit_float_to_uchar_clamp(values[i]);\n", dp->dnaname);
1134             }
1135             else {
1136               if (dp->dnatype) {
1137                 fprintf(f,
1138                         "        ((%s *)data->%s)[i] = %s",
1139                         dp->dnatype,
1140                         dp->dnaname,
1141                         (dp->booleannegative) ? "!" : "");
1142               }
1143               else {
1144                 fprintf(f,
1145                         "        (data->%s)[i] = %s",
1146                         dp->dnaname,
1147                         (dp->booleannegative) ? "!" : "");
1148               }
1149               rna_clamp_value(f, prop, 1);
1150             }
1151           }
1152           fprintf(f, "    }\n");
1153         }
1154
1155 #ifdef USE_RNA_RANGE_CHECK
1156         if (dp->dnaname && manualfunc == NULL) {
1157           if (dp->dnaarraylength == 1) {
1158             rna_clamp_value_range_check(f, prop, "data->", dp->dnaname);
1159           }
1160           else {
1161             rna_clamp_value_range_check(f, prop, "*data->", dp->dnaname);
1162           }
1163         }
1164 #endif
1165
1166         fprintf(f, "}\n\n");
1167       }
1168       else {
1169         fprintf(f, "void %s(PointerRNA *ptr, %s value)\n", func, rna_type_type(prop));
1170         fprintf(f, "{\n");
1171
1172         if (manualfunc) {
1173           fprintf(f, "    %s(ptr, value);\n", manualfunc);
1174         }
1175         else {
1176           rna_print_data_get(f, dp);
1177           if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
1178             fprintf(
1179                 f, "    if (%svalue) data->%s |= ", (dp->booleannegative) ? "!" : "", dp->dnaname);
1180             rna_int_print(f, dp->booleanbit);
1181             fprintf(f, ";\n");
1182             fprintf(f, "    else data->%s &= ~", dp->dnaname);
1183             rna_int_print(f, dp->booleanbit);
1184             fprintf(f, ";\n");
1185           }
1186           else if (prop->type == PROP_ENUM && dp->enumbitflags) {
1187             fprintf(f, "    data->%s &= ~", dp->dnaname);
1188             rna_int_print(f, rna_enum_bitmask(prop));
1189             fprintf(f, ";\n");
1190             fprintf(f, "    data->%s |= value;\n", dp->dnaname);
1191           }
1192           else {
1193             rna_clamp_value_range(f, prop);
1194             fprintf(f, "    data->%s = %s", dp->dnaname, (dp->booleannegative) ? "!" : "");
1195             rna_clamp_value(f, prop, 0);
1196           }
1197         }
1198
1199 #ifdef USE_RNA_RANGE_CHECK
1200         if (dp->dnaname && manualfunc == NULL) {
1201           rna_clamp_value_range_check(f, prop, "data->", dp->dnaname);
1202         }
1203 #endif
1204
1205         fprintf(f, "}\n\n");
1206       }
1207       break;
1208   }
1209
1210   return func;
1211 }
1212
1213 static char *rna_def_property_length_func(
1214     FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, const char *manualfunc)
1215 {
1216   char *func = NULL;
1217
1218   if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL) {
1219     return NULL;
1220   }
1221
1222   if (prop->type == PROP_STRING) {
1223     if (!manualfunc) {
1224       if (!dp->dnastructname || !dp->dnaname) {
1225         CLOG_ERROR(&LOG, "%s.%s has no valid dna info.", srna->identifier, prop->identifier);
1226         DefRNA.error = 1;
1227         return NULL;
1228       }
1229     }
1230
1231     func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "length");
1232
1233     fprintf(f, "int %s(PointerRNA *ptr)\n", func);
1234     fprintf(f, "{\n");
1235     if (manualfunc) {
1236       fprintf(f, "    return %s(ptr);\n", manualfunc);
1237     }
1238     else {
1239       rna_print_data_get(f, dp);
1240       if (!(prop->flag & PROP_NEVER_NULL)) {
1241         fprintf(f, "    if (data->%s == NULL) return 0;\n", dp->dnaname);
1242       }
1243       fprintf(f, "    return strlen(data->%s);\n", dp->dnaname);
1244     }
1245     fprintf(f, "}\n\n");
1246   }
1247   else if (prop->type == PROP_COLLECTION) {
1248     if (!manualfunc) {
1249       if (prop->type == PROP_COLLECTION &&
1250           (!(dp->dnalengthname || dp->dnalengthfixed) || !dp->dnaname)) {
1251         CLOG_ERROR(&LOG, "%s.%s has no valid dna info.", srna->identifier, prop->identifier);
1252         DefRNA.error = 1;
1253         return NULL;
1254       }
1255     }
1256
1257     func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "length");
1258
1259     fprintf(f, "int %s(PointerRNA *ptr)\n", func);
1260     fprintf(f, "{\n");
1261     if (manualfunc) {
1262       fprintf(f, "    return %s(ptr);\n", manualfunc);
1263     }
1264     else {
1265       if (dp->dnaarraylength <= 1 || dp->dnalengthname) {
1266         rna_print_data_get(f, dp);
1267       }
1268
1269       if (dp->dnaarraylength > 1) {
1270         fprintf(f, "    return ");
1271       }
1272       else {
1273         fprintf(f, "    return (data->%s == NULL) ? 0 : ", dp->dnaname);
1274       }
1275
1276       if (dp->dnalengthname) {
1277         fprintf(f, "data->%s;\n", dp->dnalengthname);
1278       }
1279       else {
1280         fprintf(f, "%d;\n", dp->dnalengthfixed);
1281       }
1282     }
1283     fprintf(f, "}\n\n");
1284   }
1285
1286   return func;
1287 }
1288
1289 static char *rna_def_property_begin_func(
1290     FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, const char *manualfunc)
1291 {
1292   char *func, *getfunc;
1293
1294   if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL) {
1295     return NULL;
1296   }
1297
1298   if (!manualfunc) {
1299     if (!dp->dnastructname || !dp->dnaname) {
1300       CLOG_ERROR(&LOG, "%s.%s has no valid dna info.", srna->identifier, prop->identifier);
1301       DefRNA.error = 1;
1302       return NULL;
1303     }
1304   }
1305
1306   func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "begin");
1307
1308   fprintf(f, "void %s(CollectionPropertyIterator *iter, PointerRNA *ptr)\n", func);
1309   fprintf(f, "{\n");
1310
1311   if (!manualfunc) {
1312     rna_print_data_get(f, dp);
1313   }
1314
1315   fprintf(f, "\n    memset(iter, 0, sizeof(*iter));\n");
1316   fprintf(f, "    iter->parent = *ptr;\n");
1317   fprintf(f, "    iter->prop = (PropertyRNA *)&rna_%s_%s;\n", srna->identifier, prop->identifier);
1318
1319   if (dp->dnalengthname || dp->dnalengthfixed) {
1320     if (manualfunc) {
1321       fprintf(f, "\n    %s(iter, ptr);\n", manualfunc);
1322     }
1323     else {
1324       if (dp->dnalengthname) {
1325         fprintf(f,
1326                 "\n    rna_iterator_array_begin(iter, data->%s, sizeof(data->%s[0]), data->%s, 0, "
1327                 "NULL);\n",
1328                 dp->dnaname,
1329                 dp->dnaname,
1330                 dp->dnalengthname);
1331       }
1332       else {
1333         fprintf(
1334             f,
1335             "\n    rna_iterator_array_begin(iter, data->%s, sizeof(data->%s[0]), %d, 0, NULL);\n",
1336             dp->dnaname,
1337             dp->dnaname,
1338             dp->dnalengthfixed);
1339       }
1340     }
1341   }
1342   else {
1343     if (manualfunc) {
1344       fprintf(f, "\n    %s(iter, ptr);\n", manualfunc);
1345     }
1346     else if (dp->dnapointerlevel == 0) {
1347       fprintf(f, "\n    rna_iterator_listbase_begin(iter, &data->%s, NULL);\n", dp->dnaname);
1348     }
1349     else {
1350       fprintf(f, "\n    rna_iterator_listbase_begin(iter, data->%s, NULL);\n", dp->dnaname);
1351     }
1352   }
1353
1354   getfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get");
1355
1356   fprintf(f, "\n    if (iter->valid)\n");
1357   fprintf(f, "        iter->ptr = %s(iter);\n", getfunc);
1358
1359   fprintf(f, "}\n\n");
1360
1361   return func;
1362 }
1363
1364 static char *rna_def_property_lookup_int_func(FILE *f,
1365                                               StructRNA *srna,
1366                                               PropertyRNA *prop,
1367                                               PropertyDefRNA *dp,
1368                                               const char *manualfunc,
1369                                               const char *nextfunc)
1370 {
1371   /* note on indices, this is for external functions and ignores skipped values.
1372    * so the index can only be checked against the length when there is no 'skip' function. */
1373   char *func;
1374
1375   if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL) {
1376     return NULL;
1377   }
1378
1379   if (!manualfunc) {
1380     if (!dp->dnastructname || !dp->dnaname) {
1381       return NULL;
1382     }
1383
1384     /* only supported in case of standard next functions */
1385     if (STREQ(nextfunc, "rna_iterator_array_next")) {
1386     }
1387     else if (STREQ(nextfunc, "rna_iterator_listbase_next")) {
1388     }
1389     else {
1390       return NULL;
1391     }
1392   }
1393
1394   func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "lookup_int");
1395
1396   fprintf(f, "int %s(PointerRNA *ptr, int index, PointerRNA *r_ptr)\n", func);
1397   fprintf(f, "{\n");
1398
1399   if (manualfunc) {
1400     fprintf(f, "\n    return %s(ptr, index, r_ptr);\n", manualfunc);
1401     fprintf(f, "}\n\n");
1402     return func;
1403   }
1404
1405   fprintf(f, "    int found = 0;\n");
1406   fprintf(f, "    CollectionPropertyIterator iter;\n\n");
1407
1408   fprintf(f, "    %s_%s_begin(&iter, ptr);\n\n", srna->identifier, rna_safe_id(prop->identifier));
1409   fprintf(f, "    if (iter.valid) {\n");
1410
1411   if (STREQ(nextfunc, "rna_iterator_array_next")) {
1412     fprintf(f, "        ArrayIterator *internal = &iter.internal.array;\n");
1413     fprintf(f, "        if (index < 0 || index >= internal->length) {\n");
1414     fprintf(f, "#ifdef __GNUC__\n");
1415     fprintf(f,
1416             "            printf(\"Array iterator out of range: %%s (index %%d)\\n\", __func__, "
1417             "index);\n");
1418     fprintf(f, "#else\n");
1419     fprintf(f, "            printf(\"Array iterator out of range: (index %%d)\\n\", index);\n");
1420     fprintf(f, "#endif\n");
1421     fprintf(f, "        }\n");
1422     fprintf(f, "        else if (internal->skip) {\n");
1423     fprintf(f, "            while (index-- > 0 && iter.valid) {\n");
1424     fprintf(f, "                rna_iterator_array_next(&iter);\n");
1425     fprintf(f, "            }\n");
1426     fprintf(f, "            found = (index == -1 && iter.valid);\n");
1427     fprintf(f, "        }\n");
1428     fprintf(f, "        else {\n");
1429     fprintf(f, "            internal->ptr += internal->itemsize * index;\n");
1430     fprintf(f, "            found = 1;\n");
1431     fprintf(f, "        }\n");
1432   }
1433   else if (STREQ(nextfunc, "rna_iterator_listbase_next")) {
1434     fprintf(f, "        ListBaseIterator *internal = &iter.internal.listbase;\n");
1435     fprintf(f, "        if (internal->skip) {\n");
1436     fprintf(f, "            while (index-- > 0 && iter.valid) {\n");
1437     fprintf(f, "                rna_iterator_listbase_next(&iter);\n");
1438     fprintf(f, "            }\n");
1439     fprintf(f, "            found = (index == -1 && iter.valid);\n");
1440     fprintf(f, "        }\n");
1441     fprintf(f, "        else {\n");
1442     fprintf(f, "            while (index-- > 0 && internal->link)\n");
1443     fprintf(f, "                internal->link = internal->link->next;\n");
1444     fprintf(f, "            found = (index == -1 && internal->link);\n");
1445     fprintf(f, "        }\n");
1446   }
1447
1448   fprintf(f,
1449           "        if (found) *r_ptr = %s_%s_get(&iter);\n",
1450           srna->identifier,
1451           rna_safe_id(prop->identifier));
1452   fprintf(f, "    }\n\n");
1453   fprintf(f, "    %s_%s_end(&iter);\n\n", srna->identifier, rna_safe_id(prop->identifier));
1454
1455   fprintf(f, "    return found;\n");
1456
1457 #if 0
1458   rna_print_data_get(f, dp);
1459   item_type = (cprop->item_type) ? (const char *)cprop->item_type : "UnknownType";
1460
1461   if (dp->dnalengthname || dp->dnalengthfixed) {
1462     if (dp->dnalengthname)
1463       fprintf(f,
1464               "\n    rna_array_lookup_int(ptr, &RNA_%s, data->%s, sizeof(data->%s[0]), data->%s, "
1465               "index);\n",
1466               item_type,
1467               dp->dnaname,
1468               dp->dnaname,
1469               dp->dnalengthname);
1470     else
1471       fprintf(
1472           f,
1473           "\n    rna_array_lookup_int(ptr, &RNA_%s, data->%s, sizeof(data->%s[0]), %d, index);\n",
1474           item_type,
1475           dp->dnaname,
1476           dp->dnaname,
1477           dp->dnalengthfixed);
1478   }
1479   else {
1480     if (dp->dnapointerlevel == 0)
1481       fprintf(f,
1482               "\n    return rna_listbase_lookup_int(ptr, &RNA_%s, &data->%s, index);\n",
1483               item_type,
1484               dp->dnaname);
1485     else
1486       fprintf(f,
1487               "\n    return rna_listbase_lookup_int(ptr, &RNA_%s, data->%s, index);\n",
1488               item_type,
1489               dp->dnaname);
1490   }
1491 #endif
1492
1493   fprintf(f, "}\n\n");
1494
1495   return func;
1496 }
1497
1498 static char *rna_def_property_lookup_string_func(FILE *f,
1499                                                  StructRNA *srna,
1500                                                  PropertyRNA *prop,
1501                                                  PropertyDefRNA *dp,
1502                                                  const char *manualfunc,
1503                                                  const char *item_type)
1504 {
1505   char *func;
1506   StructRNA *item_srna, *item_name_base;
1507   PropertyRNA *item_name_prop;
1508   const int namebuflen = 1024;
1509
1510   if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL) {
1511     return NULL;
1512   }
1513
1514   if (!manualfunc) {
1515     if (!dp->dnastructname || !dp->dnaname) {
1516       return NULL;
1517     }
1518
1519     /* only supported for collection items with name properties */
1520     item_srna = rna_find_struct(item_type);
1521     if (item_srna && item_srna->nameproperty) {
1522       item_name_prop = item_srna->nameproperty;
1523       item_name_base = item_srna;
1524       while (item_name_base->base && item_name_base->base->nameproperty == item_name_prop) {
1525         item_name_base = item_name_base->base;
1526       }
1527     }
1528     else {
1529       return NULL;
1530     }
1531   }
1532
1533   func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "lookup_string");
1534
1535   fprintf(f, "int %s(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)\n", func);
1536   fprintf(f, "{\n");
1537
1538   if (manualfunc) {
1539     fprintf(f, "    return %s(ptr, key, r_ptr);\n", manualfunc);
1540     fprintf(f, "}\n\n");
1541     return func;
1542   }
1543
1544   /* XXX extern declaration could be avoid by including RNA_blender.h, but this has lots of unknown
1545    * DNA types in functions, leading to conflicting function signatures.
1546    */
1547   fprintf(f,
1548           "    extern int %s_%s_length(PointerRNA *);\n",
1549           item_name_base->identifier,
1550           rna_safe_id(item_name_prop->identifier));
1551   fprintf(f,
1552           "    extern void %s_%s_get(PointerRNA *, char *);\n\n",
1553           item_name_base->identifier,
1554           rna_safe_id(item_name_prop->identifier));
1555
1556   fprintf(f, "    bool found = false;\n");
1557   fprintf(f, "    CollectionPropertyIterator iter;\n");
1558   fprintf(f, "    char namebuf[%d];\n", namebuflen);
1559   fprintf(f, "    char *name;\n\n");
1560
1561   fprintf(f, "    %s_%s_begin(&iter, ptr);\n\n", srna->identifier, rna_safe_id(prop->identifier));
1562
1563   fprintf(f, "    while (iter.valid) {\n");
1564   fprintf(f, "        if (iter.ptr.data) {\n");
1565   fprintf(f,
1566           "            int namelen = %s_%s_length(&iter.ptr);\n",
1567           item_name_base->identifier,
1568           rna_safe_id(item_name_prop->identifier));
1569   fprintf(f, "            if (namelen < %d) {\n", namebuflen);
1570   fprintf(f,
1571           "                %s_%s_get(&iter.ptr, namebuf);\n",
1572           item_name_base->identifier,
1573           rna_safe_id(item_name_prop->identifier));
1574   fprintf(f, "                if (strcmp(namebuf, key) == 0) {\n");
1575   fprintf(f, "                    found = true;\n");
1576   fprintf(f, "                    *r_ptr = iter.ptr;\n");
1577   fprintf(f, "                    break;\n");
1578   fprintf(f, "                }\n");
1579   fprintf(f, "            }\n");
1580   fprintf(f, "            else {\n");
1581   fprintf(f, "                name = MEM_mallocN(namelen+1, \"name string\");\n");
1582   fprintf(f,
1583           "                %s_%s_get(&iter.ptr, name);\n",
1584           item_name_base->identifier,
1585           rna_safe_id(item_name_prop->identifier));
1586   fprintf(f, "                if (strcmp(name, key) == 0) {\n");
1587   fprintf(f, "                    MEM_freeN(name);\n\n");
1588   fprintf(f, "                    found = true;\n");
1589   fprintf(f, "                    *r_ptr = iter.ptr;\n");
1590   fprintf(f, "                    break;\n");
1591   fprintf(f, "                }\n");
1592   fprintf(f, "                else {\n");
1593   fprintf(f, "                    MEM_freeN(name);\n");
1594   fprintf(f, "                }\n");
1595   fprintf(f, "            }\n");
1596   fprintf(f, "        }\n");
1597   fprintf(f, "        %s_%s_next(&iter);\n", srna->identifier, rna_safe_id(prop->identifier));
1598   fprintf(f, "    }\n");
1599   fprintf(f, "    %s_%s_end(&iter);\n\n", srna->identifier, rna_safe_id(prop->identifier));
1600
1601   fprintf(f, "    return found;\n");
1602   fprintf(f, "}\n\n");
1603
1604   return func;
1605 }
1606
1607 static char *rna_def_property_next_func(FILE *f,
1608                                         StructRNA *srna,
1609                                         PropertyRNA *prop,
1610                                         PropertyDefRNA *UNUSED(dp),
1611                                         const char *manualfunc)
1612 {
1613   char *func, *getfunc;
1614
1615   if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL) {
1616     return NULL;
1617   }
1618
1619   if (!manualfunc) {
1620     return NULL;
1621   }
1622
1623   func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "next");
1624
1625   fprintf(f, "void %s(CollectionPropertyIterator *iter)\n", func);
1626   fprintf(f, "{\n");
1627   fprintf(f, "    %s(iter);\n", manualfunc);
1628
1629   getfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get");
1630
1631   fprintf(f, "\n    if (iter->valid)\n");
1632   fprintf(f, "        iter->ptr = %s(iter);\n", getfunc);
1633
1634   fprintf(f, "}\n\n");
1635
1636   return func;
1637 }
1638
1639 static char *rna_def_property_end_func(FILE *f,
1640                                        StructRNA *srna,
1641                                        PropertyRNA *prop,
1642                                        PropertyDefRNA *UNUSED(dp),
1643                                        const char *manualfunc)
1644 {
1645   char *func;
1646
1647   if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL) {
1648     return NULL;
1649   }
1650
1651   func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "end");
1652
1653   fprintf(f, "void %s(CollectionPropertyIterator *iter)\n", func);
1654   fprintf(f, "{\n");
1655   if (manualfunc) {
1656     fprintf(f, "    %s(iter);\n", manualfunc);
1657   }
1658   fprintf(f, "}\n\n");
1659
1660   return func;
1661 }
1662
1663 static void rna_set_raw_property(PropertyDefRNA *dp, PropertyRNA *prop)
1664 {
1665   if (dp->dnapointerlevel != 0) {
1666     return;
1667   }
1668   if (!dp->dnatype || !dp->dnaname || !dp->dnastructname) {
1669     return;
1670   }
1671
1672   if (STREQ(dp->dnatype, "char")) {
1673     prop->rawtype = PROP_RAW_CHAR;
1674     prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
1675   }
1676   else if (STREQ(dp->dnatype, "short")) {
1677     prop->rawtype = PROP_RAW_SHORT;
1678     prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
1679   }
1680   else if (STREQ(dp->dnatype, "int")) {
1681     prop->rawtype = PROP_RAW_INT;
1682     prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
1683   }
1684   else if (STREQ(dp->dnatype, "float")) {
1685     prop->rawtype = PROP_RAW_FLOAT;
1686     prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
1687   }
1688   else if (STREQ(dp->dnatype, "double")) {
1689     prop->rawtype = PROP_RAW_DOUBLE;
1690     prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
1691   }
1692 }
1693
1694 static void rna_set_raw_offset(FILE *f, StructRNA *srna, PropertyRNA *prop)
1695 {
1696   PropertyDefRNA *dp = rna_find_struct_property_def(srna, prop);
1697
1698   fprintf(f, "\toffsetof(%s, %s), %d", dp->dnastructname, dp->dnaname, prop->rawtype);
1699 }
1700
1701 static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
1702 {
1703   PropertyRNA *prop;
1704
1705   prop = dp->prop;
1706
1707   switch (prop->type) {
1708     case PROP_BOOLEAN: {
1709       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1710
1711       if (!prop->arraydimension) {
1712         if (!bprop->get && !bprop->set && !dp->booleanbit) {
1713           rna_set_raw_property(dp, prop);
1714         }
1715
1716         bprop->get = (void *)rna_def_property_get_func(
1717             f, srna, prop, dp, (const char *)bprop->get);
1718         bprop->set = (void *)rna_def_property_set_func(
1719             f, srna, prop, dp, (const char *)bprop->set);
1720       }
1721       else {
1722         bprop->getarray = (void *)rna_def_property_get_func(
1723             f, srna, prop, dp, (const char *)bprop->getarray);
1724         bprop->setarray = (void *)rna_def_property_set_func(
1725             f, srna, prop, dp, (const char *)bprop->setarray);
1726       }
1727       break;
1728     }
1729     case PROP_INT: {
1730       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1731
1732       if (!prop->arraydimension) {
1733         if (!iprop->get && !iprop->set) {
1734           rna_set_raw_property(dp, prop);
1735         }
1736
1737         iprop->get = (void *)rna_def_property_get_func(
1738             f, srna, prop, dp, (const char *)iprop->get);
1739         iprop->set = (void *)rna_def_property_set_func(
1740             f, srna, prop, dp, (const char *)iprop->set);
1741       }
1742       else {
1743         if (!iprop->getarray && !iprop->setarray) {
1744           rna_set_raw_property(dp, prop);
1745         }
1746
1747         iprop->getarray = (void *)rna_def_property_get_func(
1748             f, srna, prop, dp, (const char *)iprop->getarray);
1749         iprop->setarray = (void *)rna_def_property_set_func(
1750             f, srna, prop, dp, (const char *)iprop->setarray);
1751       }
1752       break;
1753     }
1754     case PROP_FLOAT: {
1755       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1756
1757       if (!prop->arraydimension) {
1758         if (!fprop->get && !fprop->set) {
1759           rna_set_raw_property(dp, prop);
1760         }
1761
1762         fprop->get = (void *)rna_def_property_get_func(
1763             f, srna, prop, dp, (const char *)fprop->get);
1764         fprop->set = (void *)rna_def_property_set_func(
1765             f, srna, prop, dp, (const char *)fprop->set);
1766       }
1767       else {
1768         if (!fprop->getarray && !fprop->setarray) {
1769           rna_set_raw_property(dp, prop);
1770         }
1771
1772         fprop->getarray = (void *)rna_def_property_get_func(
1773             f, srna, prop, dp, (const char *)fprop->getarray);
1774         fprop->setarray = (void *)rna_def_property_set_func(
1775             f, srna, prop, dp, (const char *)fprop->setarray);
1776       }
1777       break;
1778     }
1779     case PROP_ENUM: {
1780       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
1781
1782       eprop->get = (void *)rna_def_property_get_func(f, srna, prop, dp, (const char *)eprop->get);
1783       eprop->set = (void *)rna_def_property_set_func(f, srna, prop, dp, (const char *)eprop->set);
1784       break;
1785     }
1786     case PROP_STRING: {
1787       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
1788
1789       sprop->get = (void *)rna_def_property_get_func(f, srna, prop, dp, (const char *)sprop->get);
1790       sprop->length = (void *)rna_def_property_length_func(
1791           f, srna, prop, dp, (const char *)sprop->length);
1792       sprop->set = (void *)rna_def_property_set_func(f, srna, prop, dp, (const char *)sprop->set);
1793       break;
1794     }
1795     case PROP_POINTER: {
1796       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1797
1798       pprop->get = (void *)rna_def_property_get_func(f, srna, prop, dp, (const char *)pprop->get);
1799       pprop->set = (void *)rna_def_property_set_func(f, srna, prop, dp, (const char *)pprop->set);
1800       if (!pprop->type) {
1801         CLOG_ERROR(
1802             &LOG, "%s.%s, pointer must have a struct type.", srna->identifier, prop->identifier);
1803         DefRNA.error = 1;
1804       }
1805       break;
1806     }
1807     case PROP_COLLECTION: {
1808       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1809       const char *nextfunc = (const char *)cprop->next;
1810       const char *item_type = (const char *)cprop->item_type;
1811
1812       if (cprop->length) {
1813         /* always generate if we have a manual implementation */
1814         cprop->length = (void *)rna_def_property_length_func(
1815             f, srna, prop, dp, (const char *)cprop->length);
1816       }
1817       else if (dp->dnatype && STREQ(dp->dnatype, "ListBase")) {
1818         /* pass */
1819       }
1820       else if (dp->dnalengthname || dp->dnalengthfixed) {
1821         cprop->length = (void *)rna_def_property_length_func(
1822             f, srna, prop, dp, (const char *)cprop->length);
1823       }
1824
1825       /* test if we can allow raw array access, if it is using our standard
1826        * array get/next function, we can be sure it is an actual array */
1827       if (cprop->next && cprop->get) {
1828         if (STREQ((const char *)cprop->next, "rna_iterator_array_next") &&
1829             STREQ((const char *)cprop->get, "rna_iterator_array_get")) {
1830           prop->flag_internal |= PROP_INTERN_RAW_ARRAY;
1831         }
1832       }
1833
1834       cprop->get = (void *)rna_def_property_get_func(f, srna, prop, dp, (const char *)cprop->get);
1835       cprop->begin = (void *)rna_def_property_begin_func(
1836           f, srna, prop, dp, (const char *)cprop->begin);
1837       cprop->next = (void *)rna_def_property_next_func(
1838           f, srna, prop, dp, (const char *)cprop->next);
1839       cprop->end = (void *)rna_def_property_end_func(f, srna, prop, dp, (const char *)cprop->end);
1840       cprop->lookupint = (void *)rna_def_property_lookup_int_func(
1841           f, srna, prop, dp, (const char *)cprop->lookupint, nextfunc);
1842       cprop->lookupstring = (void *)rna_def_property_lookup_string_func(
1843           f, srna, prop, dp, (const char *)cprop->lookupstring, item_type);
1844
1845       if (!(prop->flag & PROP_IDPROPERTY)) {
1846         if (!cprop->begin) {
1847           CLOG_ERROR(&LOG,
1848                      "%s.%s, collection must have a begin function.",
1849                      srna->identifier,
1850                      prop->identifier);
1851           DefRNA.error = 1;
1852         }
1853         if (!cprop->next) {
1854           CLOG_ERROR(&LOG,
1855                      "%s.%s, collection must have a next function.",
1856                      srna->identifier,
1857                      prop->identifier);
1858           DefRNA.error = 1;
1859         }
1860         if (!cprop->get) {
1861           CLOG_ERROR(&LOG,
1862                      "%s.%s, collection must have a get function.",
1863                      srna->identifier,
1864                      prop->identifier);
1865           DefRNA.error = 1;
1866         }
1867       }
1868       if (!cprop->item_type) {
1869         CLOG_ERROR(&LOG,
1870                    "%s.%s, collection must have a struct type.",
1871                    srna->identifier,
1872                    prop->identifier);
1873         DefRNA.error = 1;
1874       }
1875       break;
1876     }
1877   }
1878 }
1879
1880 static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
1881 {
1882   PropertyRNA *prop;
1883   const char *func;
1884
1885   prop = dp->prop;
1886
1887   if (prop->flag & PROP_IDPROPERTY || prop->flag_internal & PROP_INTERN_BUILTIN) {
1888     return;
1889   }
1890
1891   func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "");
1892
1893   switch (prop->type) {
1894     case PROP_BOOLEAN: {
1895       if (!prop->arraydimension) {
1896         fprintf(f, "bool %sget(PointerRNA *ptr);\n", func);
1897         fprintf(f, "void %sset(PointerRNA *ptr, bool value);\n", func);
1898       }
1899       else if (prop->arraydimension && prop->totarraylength) {
1900         fprintf(f, "void %sget(PointerRNA *ptr, bool values[%u]);\n", func, prop->totarraylength);
1901         fprintf(f,
1902                 "void %sset(PointerRNA *ptr, const bool values[%u]);\n",
1903                 func,
1904                 prop->totarraylength);
1905       }
1906       else {
1907         fprintf(f, "void %sget(PointerRNA *ptr, bool values[]);\n", func);
1908         fprintf(f, "void %sset(PointerRNA *ptr, const bool values[]);\n", func);
1909       }
1910       break;
1911     }
1912     case PROP_INT: {
1913       if (!prop->arraydimension) {
1914         fprintf(f, "int %sget(PointerRNA *ptr);\n", func);
1915         fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func);
1916       }
1917       else if (prop->arraydimension && prop->totarraylength) {
1918         fprintf(f, "void %sget(PointerRNA *ptr, int values[%u]);\n", func, prop->totarraylength);
1919         fprintf(
1920             f, "void %sset(PointerRNA *ptr, const int values[%u]);\n", func, prop->totarraylength);
1921       }
1922       else {
1923         fprintf(f, "void %sget(PointerRNA *ptr, int values[]);\n", func);
1924         fprintf(f, "void %sset(PointerRNA *ptr, const int values[]);\n", func);
1925       }
1926       break;
1927     }
1928     case PROP_FLOAT: {
1929       if (!prop->arraydimension) {
1930         fprintf(f, "float %sget(PointerRNA *ptr);\n", func);
1931         fprintf(f, "void %sset(PointerRNA *ptr, float value);\n", func);
1932       }
1933       else if (prop->arraydimension && prop->totarraylength) {
1934         fprintf(f, "void %sget(PointerRNA *ptr, float values[%u]);\n", func, prop->totarraylength);
1935         fprintf(f,
1936                 "void %sset(PointerRNA *ptr, const float values[%u]);\n",
1937                 func,
1938                 prop->totarraylength);
1939       }
1940       else {
1941         fprintf(f, "void %sget(PointerRNA *ptr, float values[]);\n", func);
1942         fprintf(f, "void %sset(PointerRNA *ptr, const float values[]);", func);
1943       }
1944       break;
1945     }
1946     case PROP_ENUM: {
1947       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
1948       int i;
1949
1950       if (eprop->item && eprop->totitem) {
1951         fprintf(f, "enum {\n");
1952
1953         for (i = 0; i < eprop->totitem; i++) {
1954           if (eprop->item[i].identifier[0]) {
1955             fprintf(f,
1956                     "\t%s_%s_%s = %d,\n",
1957                     srna->identifier,
1958                     prop->identifier,
1959                     eprop->item[i].identifier,
1960                     eprop->item[i].value);
1961           }
1962         }
1963
1964         fprintf(f, "};\n\n");
1965       }
1966
1967       fprintf(f, "int %sget(PointerRNA *ptr);\n", func);
1968       fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func);
1969
1970       break;
1971     }
1972     case PROP_STRING: {
1973       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
1974
1975       if (sprop->maxlength) {
1976         fprintf(
1977             f, "#define %s_%s_MAX %d\n\n", srna->identifier, prop->identifier, sprop->maxlength);
1978       }
1979
1980       fprintf(f, "void %sget(PointerRNA *ptr, char *value);\n", func);
1981       fprintf(f, "int %slength(PointerRNA *ptr);\n", func);
1982       fprintf(f, "void %sset(PointerRNA *ptr, const char *value);\n", func);
1983
1984       break;
1985     }
1986     case PROP_POINTER: {
1987       fprintf(f, "PointerRNA %sget(PointerRNA *ptr);\n", func);
1988       /*fprintf(f, "void %sset(PointerRNA *ptr, PointerRNA value);\n", func); */
1989       break;
1990     }
1991     case PROP_COLLECTION: {
1992       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1993       fprintf(f, "void %sbegin(CollectionPropertyIterator *iter, PointerRNA *ptr);\n", func);
1994       fprintf(f, "void %snext(CollectionPropertyIterator *iter);\n", func);
1995       fprintf(f, "void %send(CollectionPropertyIterator *iter);\n", func);
1996       if (cprop->length) {
1997         fprintf(f, "int %slength(PointerRNA *ptr);\n", func);
1998       }
1999       if (cprop->lookupint) {
2000         fprintf(f, "int %slookup_int(PointerRNA *ptr, int key, PointerRNA *r_ptr);\n", func);
2001       }
2002       if (cprop->lookupstring) {
2003         fprintf(f,
2004                 "int %slookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr);\n",
2005                 func);
2006       }
2007       break;
2008     }
2009   }
2010
2011   if (prop->getlength) {
2012     char funcname[2048];
2013     rna_construct_wrapper_function_name(
2014         funcname, sizeof(funcname), srna->identifier, prop->identifier, "get_length");
2015     fprintf(f, "int %s(PointerRNA *ptr, int *arraylen);\n", funcname);
2016   }
2017
2018   fprintf(f, "\n");
2019 }
2020
2021 static void rna_def_function_funcs_header(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc)
2022 {
2023   FunctionRNA *func = dfunc->func;
2024   char funcname[2048];
2025
2026   rna_construct_wrapper_function_name(
2027       funcname, sizeof(funcname), srna->identifier, func->identifier, "func");
2028   rna_generate_static_parameter_prototypes(f, srna, dfunc, funcname, 1);
2029 }
2030
2031 static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
2032 {
2033   PropertyRNA *prop;
2034
2035   prop = dp->prop;
2036
2037   if (prop->flag & PROP_IDPROPERTY || prop->flag_internal & PROP_INTERN_BUILTIN) {
2038     return;
2039   }
2040
2041   /* disabled for now to avoid msvc compiler error due to large file size */
2042 #if 0
2043   if (prop->name && prop->description && prop->description[0] != '\0')
2044     fprintf(f, "\t/* %s: %s */\n", prop->name, prop->description);
2045   else if (prop->name)
2046     fprintf(f, "\t/* %s */\n", prop->name);
2047   else
2048     fprintf(f, "\t/* */\n");
2049 #endif
2050
2051   switch (prop->type) {
2052     case PROP_BOOLEAN: {
2053       if (!prop->arraydimension) {
2054         fprintf(f, "\tinline bool %s(void);\n", rna_safe_id(prop->identifier));
2055         fprintf(f, "\tinline void %s(bool value);", rna_safe_id(prop->identifier));
2056       }
2057       else if (prop->totarraylength) {
2058         fprintf(f,
2059                 "\tinline Array<bool, %u> %s(void);\n",
2060                 prop->totarraylength,
2061                 rna_safe_id(prop->identifier));
2062         fprintf(f,
2063                 "\tinline void %s(bool values[%u]);",
2064                 rna_safe_id(prop->identifier),
2065                 prop->totarraylength);
2066       }
2067       else if (prop->getlength) {
2068         fprintf(f, "\tinline DynamicArray<bool> %s(void);\n", rna_safe_id(prop->identifier));
2069         fprintf(f, "\tinline void %s(bool values[]);", rna_safe_id(prop->identifier));
2070       }
2071       break;
2072     }
2073     case PROP_INT: {
2074       if (!prop->arraydimension) {
2075         fprintf(f, "\tinline int %s(void);\n", rna_safe_id(prop->identifier));
2076         fprintf(f, "\tinline void %s(int value);", rna_safe_id(prop->identifier));
2077       }
2078       else if (prop->totarraylength) {
2079         fprintf(f,
2080                 "\tinline Array<int, %u> %s(void);\n",
2081                 prop->totarraylength,
2082                 rna_safe_id(prop->identifier));
2083         fprintf(f,
2084                 "\tinline void %s(int values[%u]);",
2085                 rna_safe_id(prop->identifier),
2086                 prop->totarraylength);
2087       }
2088       else if (prop->getlength) {
2089         fprintf(f, "\tinline DynamicArray<int> %s(void);\n", rna_safe_id(prop->identifier));
2090         fprintf(f, "\tinline void %s(int values[]);", rna_safe_id(prop->identifier));
2091       }
2092       break;
2093     }
2094     case PROP_FLOAT: {
2095       if (!prop->arraydimension) {
2096         fprintf(f, "\tinline float %s(void);\n", rna_safe_id(prop->identifier));
2097         fprintf(f, "\tinline void %s(float value);", rna_safe_id(prop->identifier));
2098       }
2099       else if (prop->totarraylength) {
2100         fprintf(f,
2101                 "\tinline Array<float, %u> %s(void);\n",
2102                 prop->totarraylength,
2103                 rna_safe_id(prop->identifier));
2104         fprintf(f,
2105                 "\tinline void %s(float values[%u]);",
2106                 rna_safe_id(prop->identifier),
2107                 prop->totarraylength);
2108       }
2109       else if (prop->getlength) {
2110         fprintf(f, "\tinline DynamicArray<float> %s(void);\n", rna_safe_id(prop->identifier));
2111         fprintf(f, "\tinline void %s(float values[]);", rna_safe_id(prop->identifier));
2112       }
2113       break;
2114     }
2115     case PROP_ENUM: {
2116       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2117       int i;
2118
2119       if (eprop->item) {
2120         fprintf(f, "\tenum %s_enum {\n", rna_safe_id(prop->identifier));
2121
2122         for (i = 0; i < eprop->totitem; i++) {
2123           if (eprop->item[i].identifier[0]) {
2124             fprintf(f,
2125                     "\t\t%s_%s = %d,\n",
2126                     rna_safe_id(prop->identifier),
2127                     eprop->item[i].identifier,
2128                     eprop->item[i].value);
2129           }
2130         }
2131
2132         fprintf(f, "\t};\n");
2133       }
2134
2135       fprintf(f,
2136               "\tinline %s_enum %s(void);\n",
2137               rna_safe_id(prop->identifier),
2138               rna_safe_id(prop->identifier));
2139       fprintf(f,
2140               "\tinline void %s(%s_enum value);",
2141               rna_safe_id(prop->identifier),
2142               rna_safe_id(prop->identifier));
2143       break;
2144     }
2145     case PROP_STRING: {
2146       fprintf(f, "\tinline std::string %s(void);\n", rna_safe_id(prop->identifier));
2147       fprintf(f, "\tinline void %s(const std::string& value);", rna_safe_id(prop->identifier));
2148       break;
2149     }
2150     case PROP_POINTER: {
2151       PointerPropertyRNA *pprop = (PointerPropertyRNA *)dp->prop;
2152
2153       if (pprop->type) {
2154         fprintf(
2155             f, "\tinline %s %s(void);", (const char *)pprop->type, rna_safe_id(prop->identifier));
2156       }
2157       else {
2158         fprintf(f, "\tinline %s %s(void);", "UnknownType", rna_safe_id(prop->identifier));
2159       }
2160       break;
2161     }
2162     case PROP_COLLECTION: {
2163       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)dp->prop;
2164       const char *collection_funcs = "DefaultCollectionFunctions";
2165
2166       if (!(dp->prop->flag & PROP_IDPROPERTY || dp->prop->flag_internal & PROP_INTERN_BUILTIN) &&
2167           cprop->property.srna) {
2168         collection_funcs = (char *)cprop->property.srna;
2169       }
2170
2171       if (cprop->item_type) {
2172         fprintf(f,
2173                 "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)",
2174                 collection_funcs,
2175                 (const char *)cprop->item_type,
2176                 srna->identifier,
2177                 rna_safe_id(prop->identifier),
2178                 (cprop->length ? "true" : "false"),
2179                 (cprop->lookupint ? "true" : "false"),
2180                 (cprop->lookupstring ? "true" : "false"));
2181       }
2182       else {
2183         fprintf(f,
2184                 "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)",
2185                 collection_funcs,
2186                 "UnknownType",
2187                 srna->identifier,
2188                 rna_safe_id(prop->identifier),
2189                 (cprop->length ? "true" : "false"),
2190                 (cprop->lookupint ? "true" : "false"),
2191                 (cprop->lookupstring ? "true" : "false"));
2192       }
2193       break;
2194     }
2195   }
2196
2197   fprintf(f, "\n");
2198 }
2199
2200 static const char *rna_parameter_type_cpp_name(PropertyRNA *prop)
2201 {
2202   if (prop->type == PROP_POINTER) {
2203     /* for cpp api we need to use RNA structures names for pointers */
2204     PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
2205
2206     return (const char *)pprop->type;
2207   }
2208   else {
2209     return rna_parameter_type_name(prop);
2210   }
2211 }
2212
2213 static void rna_def_struct_function_prototype_cpp(FILE *f,
2214                                                   StructRNA *UNUSED(srna),
2215                                                   FunctionDefRNA *dfunc,
2216                                                   const char *namespace,
2217                                                   int close_prototype)
2218 {
2219   PropertyDefRNA *dp;
2220   FunctionRNA *func = dfunc->func;
2221
2222   int first = 1;
2223   const char *retval_type = "void";
2224
2225   if (func->c_ret) {
2226     dp = rna_find_parameter_def(func->c_ret);
2227     retval_type = rna_parameter_type_cpp_name(dp->prop);
2228   }
2229
2230   if (namespace && namespace[0]) {
2231     fprintf(f, "\tinline %s %s::%s(", retval_type, namespace, rna_safe_id(func->identifier));
2232   }
2233   else {
2234     fprintf(f, "\tinline %s %s(", retval_type, rna_safe_id(func->identifier));
2235   }
2236
2237   if (func->flag & FUNC_USE_MAIN)
2238     WRITE_PARAM("void *main");
2239
2240   if (func->flag & FUNC_USE_CONTEXT)
2241     WRITE_PARAM("Context C");
2242
2243   for (dp = dfunc->cont.properties.first; dp; dp = dp->next) {
2244     int type, flag, flag_parameter, pout;
2245     const char *ptrstr;
2246
2247     if (dp->prop == func->c_ret) {
2248       continue;
2249     }
2250
2251     type = dp->prop->type;
2252     flag = dp->prop->flag;
2253     flag_parameter = dp->prop->flag_parameter;
2254     pout = (flag_parameter & PARM_OUTPUT);
2255
2256     if (flag & PROP_DYNAMIC) {
2257       ptrstr = pout ? "**" : "*";
2258     }
2259     else if (type == PROP_POINTER) {
2260       ptrstr = pout ? "*" : "";
2261     }
2262     else if (dp->prop->arraydimension) {
2263       ptrstr = "*";
2264     }
2265     else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) {
2266       ptrstr = "";
2267     }
2268     else {
2269       ptrstr = pout ? "*" : "";
2270     }
2271
2272     WRITE_COMMA;
2273
2274     if (flag & PROP_DYNAMIC) {
2275       fprintf(
2276           f, "int %s%s_len, ", (flag_parameter & PARM_OUTPUT) ? "*" : "", dp->prop->identifier);
2277     }
2278
2279     if (!(flag & PROP_DYNAMIC) && dp->prop->arraydimension) {
2280       fprintf(f,
2281               "%s %s[%u]",
2282               rna_parameter_type_cpp_name(dp->prop),
2283               rna_safe_id(dp->prop->identifier),
2284               dp->prop->totarraylength);
2285     }
2286     else {
2287       fprintf(f,
2288               "%s%s%s%s",
2289               rna_parameter_type_cpp_name(dp->prop),
2290               (dp->prop->type == PROP_POINTER && ptrstr[0] == '\0') ? "& " : " ",
2291               ptrstr,
2292               rna_safe_id(dp->prop->identifier));
2293     }
2294   }
2295
2296   fprintf(f, ")");
2297   if (close_prototype) {
2298     fprintf(f, ";\n");
2299   }
2300 }
2301
2302 static void rna_def_struct_function_header_cpp(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc)
2303 {
2304   if (dfunc->call) {
2305     /* disabled for now to avoid msvc compiler error due to large file size */
2306 #if 0
2307     FunctionRNA *func = dfunc->func;
2308     fprintf(f, "\n\t/* %s */\n", func->description);
2309 #endif
2310
2311     rna_def_struct_function_prototype_cpp(f, srna, dfunc, NULL, 1);
2312   }
2313 }
2314
2315 static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
2316 {
2317   PropertyRNA *prop;
2318
2319   prop = dp->prop;
2320
2321   if (prop->flag & PROP_IDPROPERTY || prop->flag_internal & PROP_INTERN_BUILTIN) {
2322     return;
2323   }
2324
2325   switch (prop->type) {
2326     case PROP_BOOLEAN: {
2327       if (!prop->arraydimension) {
2328         fprintf(f, "\tBOOLEAN_PROPERTY(%s, %s)", srna->identifier, rna_safe_id(prop->identifier));
2329       }
2330       else if (prop->totarraylength) {
2331         fprintf(f,
2332                 "\tBOOLEAN_ARRAY_PROPERTY(%s, %u, %s)",
2333                 srna->identifier,
2334                 prop->totarraylength,
2335                 rna_safe_id(prop->identifier));
2336       }
2337       else if (prop->getlength) {
2338         fprintf(f,
2339                 "\tBOOLEAN_DYNAMIC_ARRAY_PROPERTY(%s, %s)",
2340                 srna->identifier,
2341                 rna_safe_id(prop->identifier));
2342       }
2343       break;
2344     }
2345     case PROP_INT: {
2346       if (!prop->arraydimension) {
2347         fprintf(f, "\tINT_PROPERTY(%s, %s)", srna->identifier, rna_safe_id(prop->identifier));
2348       }
2349       else if (prop->totarraylength) {
2350         fprintf(f,
2351                 "\tINT_ARRAY_PROPERTY(%s, %u, %s)",
2352                 srna->identifier,
2353                 prop->totarraylength,
2354                 rna_safe_id(prop->identifier));
2355       }
2356       else if (prop->getlength) {
2357         fprintf(f,
2358                 "\tINT_DYNAMIC_ARRAY_PROPERTY(%s, %s)",
2359                 srna->identifier,
2360                 rna_safe_id(prop->identifier));
2361       }
2362       break;
2363     }
2364     case PROP_FLOAT: {
2365       if (!prop->arraydimension) {
2366         fprintf(f, "\tFLOAT_PROPERTY(%s, %s)", srna->identifier, rna_safe_id(prop->identifier));
2367       }
2368       else if (prop->totarraylength) {
2369         fprintf(f,
2370                 "\tFLOAT_ARRAY_PROPERTY(%s, %u, %s)",
2371                 srna->identifier,
2372                 prop->totarraylength,
2373                 rna_safe_id(prop->identifier));
2374       }
2375       else if (prop->getlength) {
2376         fprintf(f,
2377                 "\tFLOAT_DYNAMIC_ARRAY_PROPERTY(%s, %s)",
2378                 srna->identifier,
2379                 rna_safe_id(prop->identifier));
2380       }
2381       break;
2382     }
2383     case PROP_ENUM: {
2384       fprintf(f,
2385               "\tENUM_PROPERTY(%s_enum, %s, %s)",
2386               rna_safe_id(prop->identifier),
2387               srna->identifier,
2388               rna_safe_id(prop->identifier));
2389
2390       break;
2391     }
2392     case PROP_STRING: {
2393       fprintf(f, "\tSTRING_PROPERTY(%s, %s)", srna->identifier, rna_safe_id(prop->identifier));
2394       break;
2395     }
2396     case PROP_POINTER: {
2397       PointerPropertyRNA *pprop = (PointerPropertyRNA *)dp->prop;
2398
2399       if (pprop->type) {
2400         fprintf(f,
2401                 "\tPOINTER_PROPERTY(%s, %s, %s)",
2402                 (const char *)pprop->type,
2403                 srna->identifier,
2404                 rna_safe_id(prop->identifier));
2405       }
2406       else {
2407         fprintf(f,
2408                 "\tPOINTER_PROPERTY(%s, %s, %s)",
2409                 "UnknownType",
2410                 srna->identifier,
2411                 rna_safe_id(prop->identifier));
2412       }
2413       break;
2414     }
2415     case PROP_COLLECTION: {
2416 #if 0
2417       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)dp->prop;
2418
2419       if (cprop->type)
2420         fprintf(f,
2421                 "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s)",
2422                 (const char *)cprop->type,
2423                 srna->identifier,
2424                 prop->identifier,
2425                 (cprop->length ? "true" : "false"),
2426                 (cprop->lookupint ? "true" : "false"),
2427                 (cprop->lookupstring ? "true" : "false"));
2428       else
2429         fprintf(f,
2430                 "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s)",
2431                 "UnknownType",
2432                 srna->identifier,
2433                 prop->identifier,
2434                 (cprop->length ? "true" : "false"),
2435                 (cprop->lookupint ? "true" : "false"),
2436                 (cprop->lookupstring ? "true" : "false"));
2437 #endif
2438       break;
2439     }
2440   }
2441
2442   fprintf(f, "\n");
2443 }
2444
2445 static void rna_def_struct_function_call_impl_cpp(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc)
2446 {
2447   PropertyDefRNA *dp;
2448   StructDefRNA *dsrna;
2449   FunctionRNA *func = dfunc->func;
2450   char funcname[2048];
2451
2452   int first = 1;
2453
2454   rna_construct_wrapper_function_name(
2455       funcname, sizeof(funcname), srna->identifier, func->identifier, "func");
2456
2457   fprintf(f, "%s(", funcname);
2458
2459   dsrna = rna_find_struct_def(srna);
2460
2461   if (func->flag & FUNC_USE_SELF_ID)
2462     WRITE_PARAM("(::ID *) ptr.id.data");
2463
2464   if ((func->flag & FUNC_NO_SELF) == 0) {
2465     WRITE_COMMA;
2466     if (dsrna->dnafromprop) {
2467       fprintf(f, "(::%s *) this->ptr.data", dsrna->dnafromname);
2468     }
2469     else if (dsrna->dnaname) {
2470       fprintf(f, "(::%s *) this->ptr.data", dsrna->dnaname);
2471     }
2472     else {
2473       fprintf(f, "(::%s *) this->ptr.data", srna->identifier);
2474     }
2475   }
2476   else if (func->flag & FUNC_USE_SELF_TYPE) {
2477     WRITE_COMMA;
2478     fprintf(f, "this->ptr.type");
2479   }
2480
2481   if (func->flag & FUNC_USE_MAIN)
2482     WRITE_PARAM("(::Main *) main");
2483
2484   if (func->flag & FUNC_USE_CONTEXT)
2485     WRITE_PARAM("(::bContext *) C.ptr.data");
2486
2487   if (func->flag & FUNC_USE_REPORTS)
2488     WRITE_PARAM("NULL");
2489
2490   dp = dfunc->cont.properties.first;
2491   for (; dp; dp = dp->next) {
2492     if (dp->prop == func->c_ret) {
2493       continue;
2494     }
2495
2496     WRITE_COMMA;
2497
2498     if (dp->prop->flag & PROP_DYNAMIC) {
2499       fprintf(f, "%s_len, ", dp->prop->identifier);
2500     }
2501
2502     if (dp->prop->type == PROP_POINTER) {
2503       if ((dp->prop->flag_parameter & PARM_RNAPTR) && !(dp->prop->flag & PROP_THICK_WRAP)) {
2504         fprintf(f,
2505                 "(::%s *) &%s.ptr",
2506                 rna_parameter_type_name(dp->prop),
2507                 rna_safe_id(dp->prop->identifier));
2508       }
2509       else if (dp->prop->flag_parameter & PARM_OUTPUT) {
2510         if (dp->prop->flag_parameter & PARM_RNAPTR) {
2511           fprintf(f, "&%s->ptr", rna_safe_id(dp->prop->identifier));
2512         }
2513         else {
2514           fprintf(f,
2515                   "(::%s **) &%s->ptr.data",
2516                   rna_parameter_type_name(dp->prop),
2517                   rna_safe_id(dp->prop->identifier));
2518         }
2519       }
2520       else {
2521         fprintf(f,
2522                 "(::%s *) %s.ptr.data",
2523                 rna_parameter_type_name(dp->prop),
2524                 rna_safe_id(dp->prop->identifier));
2525       }
2526     }
2527     else {
2528       fprintf(f, "%s", rna_safe_id(dp->prop->identifier));
2529     }
2530   }
2531
2532   fprintf(f, ");\n");
2533 }
2534
2535 static void rna_def_struct_function_impl_cpp(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc)
2536 {
2537   PropertyDefRNA *dp;
2538   PointerPropertyRNA *pprop;
2539
2540   FunctionRNA *func = dfunc->func;
2541
2542   if (!dfunc->call) {
2543     return;
2544   }
2545
2546   rna_def_struct_function_prototype_cpp(f, srna, dfunc, srna->identifier, 0);
2547
2548   fprintf(f, " {\n");
2549
2550   if (func->c_ret) {
2551     dp = rna_find_parameter_def(func->c_ret);
2552
2553     if (dp->prop->type == PROP_POINTER) {
2554       pprop = (PointerPropertyRNA *)dp->prop;
2555
2556       fprintf(f, "\t\tPointerRNA result;\n");
2557
2558       if ((dp->prop->flag_parameter & PARM_RNAPTR) == 0) {
2559         StructRNA *ret_srna = rna_find_struct((const char *)pprop->type);
2560         fprintf(f, "\t\t::%s *retdata = ", rna_parameter_type_name(dp->prop));
2561         rna_def_struct_function_call_impl_cpp(f, srna, dfunc);
2562         if (ret_srna->flag & STRUCT_ID) {
2563           fprintf(f, "\t\tRNA_id_pointer_create((::ID *) retdata, &result);\n");
2564         }
2565         else {
2566           fprintf(f,
2567                   "\t\tRNA_pointer_create((::ID *) ptr.id.data, &RNA_%s, retdata, &result);\n",
2568                   (const char *)pprop->type);
2569         }
2570       }
2571       else {
2572         fprintf(f, "\t\tresult = ");
2573         rna_def_struct_function_call_impl_cpp(f, srna, dfunc);
2574       }
2575
2576       fprintf(f, "\t\treturn %s(result);\n", (const char *)pprop->type);
2577     }
2578     else {
2579       fprintf(f, "\t\treturn ");
2580       rna_def_struct_function_call_impl_cpp(f, srna, dfunc);
2581     }
2582   }
2583   else {
2584     fprintf(f, "\t\t");
2585     rna_def_struct_function_call_impl_cpp(f, srna, dfunc);
2586   }
2587
2588   fprintf(f, "\t}\n\n");
2589 }
2590
2591 static void rna_def_property_wrapper_funcs(FILE *f, StructDefRNA *dsrna, PropertyDefRNA *dp)
2592 {
2593   if (dp->prop->getlength) {
2594     char funcname[2048];
2595     rna_construct_wrapper_function_name(
2596         funcname, sizeof(funcname), dsrna->srna->identifier, dp->prop->identifier, "get_length");
2597     fprintf(f, "int %s(PointerRNA *ptr, int *arraylen)\n", funcname);
2598     fprintf(f, "{\n");
2599     fprintf(f, "\treturn %s(ptr, arraylen);\n", rna_function_string(dp->prop->getlength));
2600     fprintf(f, "}\n\n");
2601   }
2602 }
2603
2604 static void rna_def_function_wrapper_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA *dfunc)
2605 {
2606   StructRNA *srna = dsrna->srna;
2607   FunctionRNA *func = dfunc->func;
2608   PropertyDefRNA *dparm;
2609
2610   int first;
2611   char funcname[2048];
2612
2613   if (!dfunc->call) {
2614     return;
2615   }
2616
2617   rna_construct_wrapper_function_name(
2618       funcname, sizeof(funcname), srna->identifier, func->identifier, "func");
2619
2620   rna_generate_static_parameter_prototypes(f, srna, dfunc, funcname, 0);
2621
2622   fprintf(f, "\n{\n");
2623
2624   if (func->c_ret) {
2625     fprintf(f, "\treturn %s(", dfunc->call);
2626   }
2627   else {
2628     fprintf(f, "\t%s(", dfunc->call);
2629   }
2630
2631   first = 1;
2632
2633   if (func->flag & FUNC_USE_SELF_ID)
2634     WRITE_PARAM("_selfid");
2635
2636   if ((func->flag & FUNC_NO_SELF) == 0) {
2637     WRITE_PARAM("_self");
2638   }
2639   else if (func->flag & FUNC_USE_SELF_TYPE) {
2640     WRITE_PARAM("_type");
2641   }
2642
2643   if (func->flag & FUNC_USE_MAIN)
2644     WRITE_PARAM("bmain");
2645
2646   if (func->flag & FUNC_USE_CONTEXT)
2647     WRITE_PARAM("C");
2648
2649   if (func->flag & FUNC_USE_REPORTS)
2650     WRITE_PARAM("reports");
2651
2652   dparm = dfunc->cont.properties.first;
2653   for (; dparm; dparm = dparm->next) {
2654     if (dparm->prop == func->c_ret) {
2655       continue;
2656     }
2657
2658     WRITE_COMMA;
2659
2660     if (dparm->prop->flag & PROP_DYNAMIC) {
2661       fprintf(f, "%s_len, %s", dparm->prop->identifier, dparm->prop->identifier);
2662     }
2663     else {
2664       fprintf(f, "%s", rna_safe_id(dparm->prop->identifier));
2665     }
2666   }
2667
2668   fprintf(f, ");\n");
2669   fprintf(f, "}\n\n");
2670 }
2671
2672 static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA *dfunc)
2673 {
2674   StructRNA *srna;
2675   FunctionRNA *func;
2676   PropertyDefRNA *dparm;
2677   PropertyType type;
2678   const char *funcname, *valstr;
2679   const char *ptrstr;
2680   const bool has_data = (dfunc->cont.properties.first != NULL);
2681   int flag, flag_parameter, pout, cptr, first;
2682
2683   srna = dsrna->srna;
2684   func = dfunc->func;
2685
2686   if (!dfunc->call) {
2687     return;
2688   }
2689
2690   funcname = rna_alloc_function_name(srna->identifier, func->identifier, "call");
2691
2692   /* function definition */
2693   fprintf(f,
2694           "void %s(bContext *C, ReportList *reports, PointerRNA *_ptr, ParameterList *_parms)",
2695           funcname);
2696   fprintf(f, "\n{\n");
2697
2698   /* variable definitions */
2699
2700   if (func->flag & FUNC_USE_SELF_ID) {
2701     fprintf(f, "\tstruct ID *_selfid;\n");
2702   }
2703
2704   if ((func->flag & FUNC_NO_SELF) == 0) {
2705     if (dsrna->dnafromprop) {
2706       fprintf(f, "\tstruct %s *_self;\n", dsrna->dnafromname);
2707     }
2708     else if (dsrna->dnaname) {
2709       fprintf(f, "\tstruct %s *_self;\n", dsrna->dnaname);
2710     }
2711     else {
2712       fprintf(f, "\tstruct %s *_self;\n", srna->identifier);
2713     }
2714   }
2715   else if (func->flag & FUNC_USE_SELF_TYPE) {
2716     fprintf(f, "\tstruct StructRNA *_type;\n");
2717   }
2718
2719   dparm = dfunc->cont.properties.first;
2720   for (; dparm; dparm = dparm->next) {
2721     type = dparm->prop->type;
2722     flag = dparm->prop->flag;
2723     flag_parameter = dparm->prop->flag_parameter;
2724     pout = (flag_parameter & PARM_OUTPUT);
2725     cptr = ((type == PROP_POINTER) && !(flag_parameter & PARM_RNAPTR));
2726
2727     if (dparm->prop == func->c_ret) {
2728       ptrstr = cptr || dparm->prop->arraydimension ? "*" : "";
2729       /* XXX only arrays and strings are allowed to be dynamic, is this checked anywhere? */
2730     }
2731     else if (cptr || (flag & PROP_DYNAMIC)) {
2732       ptrstr = pout ? "**" : "*";
2733       /* Fixed size arrays and RNA pointers are pre-allocated on the ParameterList stack,
2734        * pass a pointer to it. */
2735     }
2736     else if (type == PROP_POINTER || dparm->prop->arraydimension) {
2737       ptrstr = "*";
2738     }
2739     else if ((type == PROP_POINTER) && (flag_parameter & PARM_RNAPTR) &&
2740              !(flag & PROP_THICK_WRAP)) {
2741       ptrstr = "*";
2742       /* PROP_THICK_WRAP strings are pre-allocated on the ParameterList stack,
2743        * but type name for string props is already (char *), so leave empty */
2744     }
2745     else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) {
2746       ptrstr = "";
2747     }
2748     else {
2749       ptrstr = pout ? "*" : "";
2750     }
2751
2752     /* for dynamic parameters we pass an additional int for the length of the parameter */
2753     if (flag & PROP_DYNAMIC) {
2754       fprintf(f, "\tint %s%s_len;\n", pout ? "*" : "", dparm->prop->identifier);
2755     }
2756
2757     fprintf(f,
2758             "\t%s%s %s%s;\n",
2759             rna_type_struct(dparm->prop),
2760             rna_parameter_type_name(dparm->prop),
2761             ptrstr,
2762             dparm->prop->identifier);
2763   }
2764
2765   if (has_data) {
2766     fprintf(f, "\tchar *_data");
2767     if (func->c_ret) {
2768       fprintf(f, ", *_retdata");
2769     }
2770     fprintf(f, ";\n");
2771     fprintf(f, "\t\n");
2772   }
2773
2774   /* assign self */
2775   if (func->flag & FUNC_USE_SELF_ID) {
2776     fprintf(f, "\t_selfid = (struct ID *)_ptr->id.data;\n");
2777   }
2778
2779   if ((func->flag & FUNC_NO_SELF) == 0) {
2780     if (dsrna->dnafromprop) {
2781       fprintf(f, "\t_self = (struct %s *)_ptr->data;\n", dsrna->dnafromname);
2782     }
2783     else if (dsrna->dnaname) {
2784       fprintf(f, "\t_self = (struct %s *)_ptr->data;\n", dsrna->dnaname);
2785     }
2786     else {
2787       fprintf(f, "\t_self = (struct %s *)_ptr->data;\n", srna->identifier);
2788     }
2789   }
2790   else if (func->flag & FUNC_USE_SELF_TYPE) {
2791     fprintf(f, "\t_type = _ptr->type;\n");
2792   }
2793
2794   if (has_data) {
2795     fprintf(f, "\t_data = (char *)_parms->data;\n");
2796   }
2797
2798   dparm = dfunc->cont.properties.first;
2799   for (; dparm; dparm = dparm->next) {
2800     type = dparm->prop->type;
2801     flag = dparm->prop->flag;
2802     flag_parameter = dparm->prop->flag_parameter;
2803     pout = (flag_parameter & PARM_OUTPUT);
2804     cptr = ((type == PROP_POINTER) && !(flag_parameter & PARM_RNAPTR));
2805
2806     if (dparm->prop == func->c_ret) {
2807       fprintf(f, "\t_retdata = _data;\n");
2808     }
2809     else {
2810       const char *data_str;
2811       if (cptr || (flag & PROP_DYNAMIC)) {
2812         ptrstr = "**";
2813         valstr = "*";
2814       }
2815       else if ((type == PROP_POINTER) && !(flag & PROP_THICK_WRAP)) {
2816         ptrstr = "**";
2817         valstr = "*";
2818       }
2819       else if (type == PROP_POINTER || dparm->prop->arraydimension) {
2820         ptrstr = "*";
2821         valstr = "";
2822       }
2823       else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) {
2824         ptrstr = "";
2825         valstr = "";
2826       }
2827       else {
2828         ptrstr = "*";
2829         valstr = "*";
2830       }
2831
2832       /* This must be kept in sync with RNA_parameter_dynamic_length_get_data and
2833        * RNA_parameter_get, we could just call the function directly, but this is faster. */
2834       if (flag & PROP_DYNAMIC) {
2835         fprintf(f,
2836                 "\t%s_len = %s((ParameterDynAlloc *)_data)->array_tot;\n",
2837                 dparm->prop->identifier,
2838                 pout ? "(int *)&" : "(int)");
2839         data_str = "(&(((ParameterDynAlloc *)_data)->array))";
2840       }
2841       else {
2842         data_str = "_data";
2843       }
2844       fprintf(f, "\t%s = ", dparm->prop->identifier);
2845
2846       if (!pout) {
2847         fprintf(f, "%s", valstr);
2848       }
2849
2850       fprintf(f,
2851               "((%s%s %s)%s);\n",
2852               rna_type_struct(dparm->prop),
2853               rna_parameter_type_name(dparm->prop),
2854               ptrstr,
2855               data_str);
2856     }
2857
2858     if (dparm->next) {
2859       fprintf(f, "\t_data += %d;\n", rna_parameter_size(dparm->prop));
2860     }
2861   }
2862
2863   if (dfunc->call) {
2864     fprintf(f, "\t\n");
2865     fprintf(f, "\t");
2866     if (func->c_ret) {
2867       fprintf(f, "%s = ", func->c_ret->identifier);
2868     }
2869     fprintf(f, "%s(", dfunc->call);
2870
2871     first = 1;
2872
2873     if (func->flag & FUNC_USE_SELF_ID) {
2874       fprintf(f, "_selfid");
2875       first = 0;
2876     }
2877
2878     if ((func->flag & FUNC_NO_SELF) == 0) {
2879       if (!first) {
2880         fprintf(f, ", ");
2881       }
2882       fprintf(f, "_self");
2883       first = 0;
2884     }
2885     else if (func->flag & FUNC_USE_SELF_TYPE) {
2886       if (!first) {
2887         fprintf(f, ", ");
2888       }
2889       fprintf(f, "_type");
2890       first = 0;
2891     }
2892
2893     if (func->flag & FUNC_USE_MAIN) {
2894       if (!first) {
2895         fprintf(f, ", ");
2896       }
2897       first = 0;
2898       fprintf(f, "CTX_data_main(C)"); /* may have direct access later */
2899     }
2900
2901     if (func->flag & FUNC_USE_CONTEXT) {
2902       if (!first) {
2903         fprintf(f, ", ");
2904       }
2905       first = 0;
2906       fprintf(f, "C");
2907     }
2908
2909     if (func->flag & FUNC_USE_REPORTS) {
2910       if (!first) {
2911         fprintf(f, ", ");
2912       }
2913       first = 0;
2914       fprintf(f, "reports");
2915     }
2916
2917     dparm = dfunc->cont.properties.first;
2918     for (; dparm; dparm = dparm->next) {
2919       if (dparm->prop == func->c_ret) {
2920         continue;
2921       }
2922
2923       if (!first) {
2924         fprintf(f, ", ");
2925       }
2926       first = 0;
2927
2928       if (dparm->prop->flag & PROP_DYNAMIC) {
2929         fprintf(f, "%s_len, %s", dparm->prop->identifier, dparm->prop->identifier);
2930       }
2931       else {
2932         fprintf(f, "%s", dparm->prop->identifier);
2933       }
2934     }
2935
2936     fprintf(f, ");\n");
2937
2938     if (func->c_ret) {
2939       dparm = rna_find_parameter_def(func->c_ret);
2940       ptrstr = (((dparm->prop->type == PROP_POINTER) &&
2941                  !(dparm->prop->flag_parameter & PARM_RNAPTR)) ||
2942                 (dparm->prop->arraydimension)) ?
2943                    "*" :
2944                    "";
2945       fprintf(f,
2946               "\t*((%s%s %s*)_retdata) = %s;\n",
2947               rna_type_struct(dparm->prop),
2948               rna_parameter_type_name(dparm->prop),
2949               ptrstr,
2950               func->c_ret->identifier);
2951     }
2952   }
2953
2954   fprintf(f, "}\n\n");
2955
2956   dfunc->gencall = funcname;
2957 }
2958
2959 static void rna_auto_types(void)
2960 {
2961   StructDefRNA *ds;
2962   PropertyDefRNA *dp;
2963
2964   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
2965     /* DNA name for Screen is patched in 2.5, we do the reverse here .. */
2966     if (ds->dnaname) {
2967       if (STREQ(ds->dnaname, "Screen")) {
2968         ds->dnaname = "bScreen";
2969       }
2970       if (STREQ(ds->dnaname, "Group")) {
2971         ds->dnaname = "Collection";
2972       }
2973       if (STREQ(ds->dnaname, "GroupObject")) {
2974         ds->dnaname = "CollectionObject";
2975       }
2976     }
2977
2978     for (dp = ds->cont.properties.first; dp; dp = dp->next) {
2979       if (dp->dnastructname) {
2980         if (STREQ(dp->dnastructname, "Screen")) {
2981           dp->dnastructname = "bScreen";
2982         }
2983         if (STREQ(dp->dnastructname, "Group")) {
2984           dp->dnastructname = "Collection";
2985         }
2986         if (STREQ(dp->dnastructname, "GroupObject")) {
2987           dp->dnastructname = "CollectionObject";
2988         }
2989       }
2990
2991       if (dp->dnatype) {
2992         if (dp->prop->type == PROP_POINTER) {
2993           PointerPropertyRNA *pprop = (PointerPropertyRNA *)dp->prop;
2994           StructRNA *type;
2995
2996           if (!pprop->type && !pprop->get) {
2997             pprop->type = (StructRNA *)rna_find_type(dp->dnatype);
2998           }
2999
3000           if (pprop->type) {
3001             type = rna_find_struct((const char *)pprop->type);
3002             if (type && (type->flag & STRUCT_ID_REFCOUNT)) {
3003               pprop->property.flag |= PROP_ID_REFCOUNT;
3004             }
3005           }
3006         }
3007         else if (dp->prop->type == PROP_COLLECTION) {
3008           CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)dp->prop;
3009
3010           if (!cprop->item_type && !cprop->get && STREQ(dp->dnatype, "ListBase")) {
3011             cprop->item_type = (StructRNA *)rna_find_type(dp->dnatype);
3012           }
3013         }
3014       }
3015     }
3016   }
3017 }
3018
3019 static void rna_sort(BlenderRNA *brna)
3020 {
3021   StructDefRNA *ds;
3022   StructRNA *srna;
3023
3024   rna_sortlist(&brna->structs, cmp_struct);
3025   rna_sortlist(&DefRNA.structs, cmp_def_struct);
3026
3027   for (srna = brna->structs.first; srna; srna = srna->cont.next) {
3028     rna_sortlist(&srna->cont.properties, cmp_property);
3029   }
3030
3031   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
3032     rna_sortlist(&ds->cont.properties, cmp_def_property);
3033   }
3034 }
3035
3036 static const char *rna_property_structname(PropertyType type)
3037 {
3038   switch (type) {
3039     case PROP_BOOLEAN:
3040       return "BoolPropertyRNA";
3041     case PROP_INT:
3042       return "IntPropertyRNA";
3043     case PROP_FLOAT:
3044       return "FloatPropertyRNA";
3045     case PROP_STRING:
3046       return "StringPropertyRNA";
3047     case PROP_ENUM:
3048       return "EnumPropertyRNA";
3049     case PROP_POINTER:
3050       return "PointerPropertyRNA";
3051     case PROP_COLLECTION:
3052       return "CollectionPropertyRNA";
3053     default:
3054       return "UnknownPropertyRNA";
3055   }
3056 }
3057
3058 static const char *rna_property_subtypename(PropertySubType type)
3059 {
3060   switch (type) {
3061     case PROP_NONE:
3062       return "PROP_NONE";
3063     case PROP_FILEPATH:
3064       return "PROP_FILEPATH";
3065     case PROP_FILENAME:
3066       return "PROP_FILENAME";
3067     case PROP_DIRPATH:
3068       return "PROP_DIRPATH";
3069     case PROP_PIXEL:
3070       return "PROP_PIXEL";
3071     case PROP_BYTESTRING:
3072       return "PROP_BYTESTRING";
3073     case PROP_UNSIGNED:
3074       return "PROP_UNSIGNED";
3075     case PROP_PERCENTAGE:
3076       return "PROP_PERCENTAGE";
3077     case PROP_FACTOR:
3078       return "PROP_FACTOR";
3079     case PROP_ANGLE:
3080       return "PROP_ANGLE";
3081     case PROP_TIME:
3082       return "PROP_TIME";
3083     case PROP_DISTANCE:
3084       return "PROP_DISTANCE";
3085     case PROP_DISTANCE_CAMERA:
3086       return "PROP_DISTANCE_CAMERA";
3087     case PROP_COLOR:
3088       return "PROP_COLOR";
3089     case PROP_TRANSLATION:
3090       return "PROP_TRANSLATION";
3091     case PROP_DIRECTION:
3092       return "PROP_DIRECTION";
3093     case PROP_MATRIX:
3094       return "PROP_MATRIX";
3095     case PROP_EULER:
3096       return "PROP_EULER";
3097     case PROP_QUATERNION:
3098       return "PROP_QUATERNION";
3099     case PROP_AXISANGLE:
3100       return "PROP_AXISANGLE";
3101     case PROP_VELOCITY:
3102       return "PROP_VELOCITY";
3103     case PROP_ACCELERATION:
3104       return "PROP_ACCELERATION";
3105     case PROP_XYZ:
3106       return "PROP_XYZ";
3107     case PROP_COLOR_GAMMA:
3108       return "PROP_COLOR_GAMMA";
3109     case PROP_COORDS:
3110       return "PROP_COORDS";
3111     case PROP_LAYER:
3112       return "PROP_LAYER";
3113     case PROP_LAYER_MEMBER:
3114       return "PROP_LAYER_MEMBER";
3115     case PROP_PASSWORD:
3116       return "PROP_PASSWORD";
3117     case PROP_POWER:
3118       return "PROP_POWER";
3119     default: {
3120       /* in case we don't have a type preset that includes the subtype */
3121       if (RNA_SUBTYPE_UNIT(type)) {
3122         return rna_property_subtypename(type & ~RNA_SUBTYPE_UNIT(type));
3123       }
3124       else {
3125         return "PROP_SUBTYPE_UNKNOWN";
3126       }
3127     }
3128   }
3129 }
3130
3131 static const char *rna_property_subtype_unit(PropertySubType type)
3132 {
3133   switch (RNA_SUBTYPE_UNIT(type)) {
3134     case PROP_UNIT_NONE:
3135       return "PROP_UNIT_NONE";
3136     case PROP_UNIT_LENGTH:
3137       return "PROP_UNIT_LENGTH";
3138     case PROP_UNIT_AREA:
3139       return "PROP_UNIT_AREA";
3140     case PROP_UNIT_VOLUME:
3141       return "PROP_UNIT_VOLUME";
3142     case PROP_UNIT_MASS:
3143       return "PROP_UNIT_MASS";
3144     case PROP_UNIT_ROTATION:
3145       return "PROP_UNIT_ROTATION";
3146     case PROP_UNIT_TIME:
3147       return "PROP_UNIT_TIME";
3148     case PROP_UNIT_VELOCITY:
3149       return "PROP_UNIT_VELOCITY";
3150     case PROP_UNIT_ACCELERATION:
3151       return "PROP_UNIT_ACCELERATION";
3152     case PROP_UNIT_CAMERA:
3153       return "PROP_UNIT_CAMERA";
3154     case PROP_UNIT_POWER:
3155       return "PROP_UNIT_POWER";
3156     default:
3157       return "PROP_UNIT_UNKNOWN";
3158   }
3159 }
3160
3161 static void rna_generate_prototypes(BlenderRNA *brna, FILE *f)
3162 {
3163   StructRNA *srna;
3164
3165   for (srna = brna->structs.first; srna; srna = srna->cont.next) {
3166     fprintf(f, "extern StructRNA RNA_%s;\n", srna->identifier);
3167   }
3168   fprintf(f, "\n");
3169 }
3170
3171 static void rna_generate_blender(BlenderRNA *brna, FILE *f)
3172 {
3173   StructRNA *srna;
3174
3175   fprintf(f,
3176           "BlenderRNA BLENDER_RNA = {\n"
3177           "\t.structs = {");
3178   srna = brna->structs.first;
3179   if (srna) {
3180     fprintf(f, "&RNA_%s, ", srna->identifier);
3181   }
3182   else {
3183     fprintf(f, "NULL, ");
3184   }
3185
3186   srna = brna->structs.last;
3187   if (srna) {
3188     fprintf(f, "&RNA_%s},\n", srna->identifier);
3189   }
3190   else {
3191     fprintf(f, "NULL},\n");
3192   }
3193
3194   fprintf(f,
3195           "\t.structs_map = NULL,\n"
3196           "\t.structs_len = 0,\n"
3197           "};\n\n");
3198 }
3199
3200 static void rna_generate_property_prototypes(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE *f)
3201 {
3202   PropertyRNA *prop;
3203   StructRNA *base;
3204
3205   base = srna->base;
3206   while (base) {
3207     fprintf(f, "\n");
3208     for (prop = base->cont.properties.first; prop; prop = prop->next) {
3209       fprintf(f,
3210               "%s%s rna_%s_%s;\n",
3211               "extern ",
3212               rna_property_structname(prop->type),
3213               base->identifier,
3214               prop->identifier);
3215     }
3216     base = base->base;
3217   }
3218
3219   if (srna->cont.properties.first) {
3220     fprintf(f, "\n");
3221   }
3222
3223   for (prop = srna->cont.properties.first; prop; prop = prop->next) {
3224     fprintf(f,
3225             "%s rna_%s_%s;\n",
3226             rna_property_structname(prop->type),
3227             srna->identifier,
3228             prop->identifier);
3229   }
3230   fprintf(f, "\n");
3231 }
3232
3233 static void rna_generate_parameter_prototypes(BlenderRNA *UNUSED(brna),
3234                                               StructRNA *srna,
3235                                               FunctionRNA *func,
3236                                               FILE *f)
3237 {
3238   PropertyRNA *parm;
3239
3240   for (parm = func->cont.properties.first; parm; parm = parm->next) {
3241     fprintf(f,
3242             "%s%s rna_%s_%s_%s;\n",
3243             "extern ",
3244             rna_property_structname(parm->type),
3245             srna->identifier,
3246             func->identifier,
3247             parm->identifier);
3248   }
3249
3250   if (func->cont.properties.first) {
3251     fprintf(f, "\n");
3252   }
3253 }
3254
3255 static void rna_generate_function_prototypes(BlenderRNA *brna, StructRNA *srna, FILE *f)
3256 {
3257   FunctionRNA *func;
3258   StructRNA *base;
3259
3260   base = srna->base;
3261   while (base) {
3262     for (func = base->functions.first; func; func = func->cont.next) {
3263       fprintf(f,
3264               "%s%s rna_%s_%s_func;\n",
3265               "extern ",
3266               "FunctionRNA",
3267               base->identifier,
3268               func->identifier);
3269       rna_generate_parameter_prototypes(brna, base, func, f);
3270     }
3271
3272     if (base->functions.first) {
3273       fprintf(f, "\n");
3274     }
3275
3276     base = base->base;
3277   }
3278
3279   for (func = srna->functions.first; func; func = func->cont.next) {
3280     fprintf(
3281         f, "%s%s rna_%s_%s_func;\n", "extern ", "FunctionRNA", srna->identifier, func->identifier);
3282     rna_generate_parameter_prototypes(brna, srna, func, f);
3283   }
3284
3285   if (srna->functions.first) {
3286     fprintf(f, "\n");
3287   }
3288 }
3289
3290 static void rna_generate_static_parameter_prototypes(FILE *f,
3291                                                      StructRNA *srna,
3292                                                      FunctionDefRNA *dfunc,
3293                                                      const char *name_override,
3294                                                      int close_prototype)
3295 {
3296   FunctionRNA *func;
3297   PropertyDefRNA *dparm;
3298   StructDefRNA *dsrna;
3299   PropertyType type;
3300   int flag, flag_parameter, pout, cptr, first;
3301   const char *ptrstr;
3302
3303   dsrna = rna_find_struct_def(srna);
3304   func = dfunc->func;
3305
3306   /* return type */
3307   for (dparm = dfunc->cont.properties.first; dparm; dparm = dparm->next) {
3308     if (dparm->prop == func->c_ret) {
3309       if (dparm->prop->arraydimension) {
3310         fprintf(f, "XXX no array return types yet"); /* XXX not supported */
3311       }
3312       else if (dparm->prop->type == PROP_POINTER && !(dparm->prop->flag_parameter & PARM_RNAPTR)) {
3313         fprintf(f, "%s%s *", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
3314       }
3315       else {
3316         fprintf(f, "%s%s ", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
3317       }
3318
3319       break;
3320     }
3321   }
3322
3323   /* void if nothing to return */
3324   if (!dparm) {
3325     fprintf(f, "void ");
3326   }
3327
3328   /* function name */
3329   if (name_override == NULL || name_override[0] == '\0') {
3330     fprintf(f, "%s(", dfunc->call);
3331   }
3332   else {
3333     fprintf(f, "%s(", name_override);
3334   }
3335
3336   first = 1;
3337
3338   /* self, context and reports parameters */
3339   if (func->flag & FUNC_USE_SELF_ID) {
3340     fprintf(f, "struct ID *_selfid");
3341     first = 0;
3342   }
3343
3344   if ((func->flag & FUNC_NO_SELF) == 0) {
3345     if (!first) {
3346       fprintf(f, ", ");
3347     }
3348     if (dsrna->dnafromprop) {
3349       fprintf(f, "struct %s *_self", dsrna->dnafromname);
3350     }
3351     else if (dsrna->dnaname) {
3352       fprintf(f, "struct %s *_self", dsrna->dnaname);
3353     }
3354     else {
3355       fprintf(f, "struct %s *_self", srna->identifier);
3356     }
3357     first = 0;
3358   }
3359   else if (func->flag & FUNC_USE_SELF_TYPE) {
3360     if (!first) {
3361       fprintf(f, ", ");
3362     }
3363     fprintf(f, "struct StructRNA *_type");
3364     first = 0;
3365   }
3366
3367   if (func->flag & FUNC_USE_MAIN) {
3368     if (!first) {
3369       fprintf(f, ", ");
3370     }
3371     first = 0;
3372     fprintf(f, "Main *bmain");
3373   }
3374
3375   if (func->flag & FUNC_USE_CONTEXT) {
3376     if (!first) {
3377       fprintf(f, ", ");
3378     }
3379     first = 0;
3380     fprintf(f, "bContext *C");
3381   }
3382
3383   if (func->flag & FUNC_USE_REPORTS) {
3384     if (!first) {
3385       fprintf(f, ", ");
3386     }
3387     first = 0;
3388     fprintf(f, "ReportList *reports");
3389   }
3390
3391   /* defined parameters */
3392   for (dparm = dfunc->cont.properties.first; dparm; dparm = dparm->next) {
3393     type = dparm->prop->type;
3394     flag = dparm->prop->flag;
3395     flag_parameter = dparm->prop->flag_parameter;
3396     pout = (flag_parameter & PARM_OUTPUT);
3397     cptr = ((type == PROP_POINTER) && !(flag_parameter & PARM_RNAPTR));
3398
3399     if (dparm->prop == func->c_ret) {
3400       continue;
3401     }
3402
3403     if (cptr || (flag & PROP_DYNAMIC)) {
3404       ptrstr = pout ? "**" : "*";
3405     }
3406     else if (type == PROP_POINTER || dparm->prop->arraydimension) {
3407       ptrstr = "*";
3408     }
3409     else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) {
3410       ptrstr = "";
3411     }
3412     else {
3413       ptrstr = pout ? "*" : "";
3414     }
3415
3416     if (!first) {
3417       fprintf(f, ", ");
3418     }
3419     first = 0;
3420
3421     if (flag & PROP_DYNAMIC) {
3422       fprintf(f, "int %s%s_len, ", pout ? "*" : "", dparm->prop->identifier);
3423     }
3424
3425     if (!(flag & PROP_DYNAMIC) && dparm->prop->arraydimension) {
3426       fprintf(f,
3427               "%s%s %s[%u]",
3428               rna_type_struct(dparm->prop),
3429               rna_parameter_type_name(dparm->prop),
3430               rna_safe_id(dparm->prop->identifier),
3431               dparm->prop->totarraylength);
3432     }
3433     else {
3434       fprintf(f,
3435               "%s%s %s%s",
3436               rna_type_struct(dparm->prop),
3437               rna_parameter_type_name(dparm->prop),
3438               ptrstr,
3439               rna_safe_id(dparm->prop->identifier));
3440     }
3441   }
3442
3443   /* ensure func(void) if there are no args */
3444   if (first) {
3445     fprintf(f, "void");
3446   }
3447
3448   fprintf(f, ")");
3449
3450   if (close_prototype) {
3451     fprintf(f, ";\n");
3452   }
3453 }
3454
3455 static void rna_generate_static_function_prototypes(BlenderRNA *UNUSED(brna),
3456                                                     StructRNA *srna,
3457                                                     FILE *f)
3458 {
3459   FunctionRNA *func;
3460   FunctionDefRNA *dfunc;
3461   int first = 1;
3462
3463   for (func = srna->functions.first; func; func = func->cont.next) {
3464     dfunc = rna_find_function_def(func);
3465
3466     if (dfunc->call) {
3467       if (first) {
3468         fprintf(f, "/* Repeated prototypes to detect errors */\n\n");
3469         first = 0;
3470       }
3471
3472       rna_generate_static_parameter_prototypes(f, srna, dfunc, NULL, 1);
3473     }
3474   }
3475
3476   fprintf(f, "\n");
3477 }
3478
3479 static void rna_generate_struct_prototypes(FILE *f)
3480 {
3481   StructDefRNA *ds;
3482   PropertyDefRNA *dp;
3483   FunctionDefRNA *dfunc;
3484   const char *structures[2048];
3485   int all_structures = 0;
3486
3487   /* structures definitions */
3488   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
3489     for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) {
3490       if (dfunc->call) {
3491         for (dp = dfunc->cont.properties.first; dp; dp = dp->next) {
3492           if (dp->prop->type == PROP_POINTER) {
3493             int a, found = 0;
3494             const char *struct_name = rna_parameter_type_name(dp->prop);
3495             if (struct_name == NULL) {
3496               printf("No struct found for property '%s'\n", dp->prop->identifier);
3497               exit(1);
3498             }
3499
3500             for (a = 0; a < all_structures; a++) {
3501               if (STREQ(struct_name, structures[a])) {
3502                 found = 1;
3503                 break;
3504               }
3505             }
3506
3507             if (found == 0) {
3508               fprintf(f, "struct %s;\n", struct_name);
3509
3510               if (all_structures >= sizeof(structures) / sizeof(structures[0])) {
3511                 printf("Array size to store all structures names is too small\n");
3512                 exit(1);
3513               }
3514
3515               structures[all_structures++] = struct_name;
3516             }
3517           }
3518         }
3519       }
3520     }
3521   }
3522
3523   fprintf(f, "\n");
3524 }
3525
3526 static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, PropertyRNA *prop)
3527 {
3528   char *strnest = (char *)"", *errnest = (char *)"";
3529   int len, freenest = 0;
3530
3531   if (nest != NULL) {
3532     len = strlen(nest);
3533
3534     strnest = MEM_mallocN(sizeof(char) * (len + 2), "rna_generate_property -> strnest");
3535     errnest = MEM_mallocN(sizeof(char) * (len + 2), "rna_generate_property -> errnest");
3536
3537     strcpy(strnest, "_");
3538     strcat(strnest, nest);
3539     strcpy(errnest, ".");
3540     strcat(errnest, nest);
3541
3542     freenest = 1;
3543   }
3544
3545   switch (prop->type) {
3546     case PROP_ENUM: {
3547       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3548       int i, defaultfound = 0, totflag = 0;
3549
3550       if (eprop->item) {
3551         fprintf(f,
3552                 "static const EnumPropertyItem rna_%s%s_%s_items[%d] = {\n\t",
3553                 srna->identifier,
3554                 strnest,
3555                 prop->identifier,
3556                 eprop->totitem + 1);
3557
3558         for (i = 0; i < eprop->totitem; i++) {
3559           fprintf(f, "{%d, ", eprop->item[i].value);
3560           rna_print_c_string(f, eprop->item[i].identifier);
3561           fprintf(f, ", ");
3562           fprintf(f, "%d, ", eprop->item[i].icon);
3563           rna_print_c_string(f, eprop->item[i].name);
3564           fprintf(f, ", ");
3565           rna_print_c_string(f, eprop->item[i].description);
3566           fprintf(f, "},\n\t");
3567
3568           if (eprop->item[i].identifier[0]) {
3569             if (prop->flag & PROP_ENUM_FLAG) {
3570               totflag |= eprop->item[i].value;
3571             }
3572             else {
3573               if (eprop->defaultvalue == eprop->item[i].value) {
3574                 defaultfound = 1;
3575               }
3576             }
3577           }
3578         }
3579
3580         fprintf(f, "{0, NULL, 0, NULL, NULL}\n};\n\n");
3581
3582         if (prop->flag & PROP_ENUM_FLAG) {
3583           if (eprop->defaultvalue & ~totflag) {
3584             CLOG_ERROR(&LOG,
3585                        "%s%s.%s, enum default includes unused bits (%d).",
3586                        srna->identifier,
3587                        errnest,
3588                        prop->identifier,
3589                        eprop->defaultvalue & ~totflag);
3590             DefRNA.error = 1;
3591           }
3592         }
3593         else {
3594           if (!defaultfound && !(eprop->itemf && eprop->item == DummyRNA_NULL_items)) {
3595             CLOG_ERROR(&LOG,
3596                        "%s%s.%s, enum default is not in items.",
3597                        srna->identifier,