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