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