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