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