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