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