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