RNA:
[blender.git] / source / blender / makesrna / intern / makesrna.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Contributor(s): Blender Foundation (2008).
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include <float.h>
26 #include <limits.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include "MEM_guardedalloc.h"
32
33 #include "RNA_access.h"
34 #include "RNA_define.h"
35 #include "RNA_types.h"
36
37 #include "rna_internal.h"
38
39 #define RNA_VERSION_DATE "$Id$"
40
41 #ifdef _WIN32
42 #ifndef snprintf
43 #define snprintf _snprintf
44 #endif
45 #endif
46
47 /* Sorting */
48
49 static int cmp_struct(const void *a, const void *b)
50 {
51         const StructRNA *structa= *(const StructRNA**)a;
52         const StructRNA *structb= *(const StructRNA**)b;
53
54         return strcmp(structa->identifier, structb->identifier);
55 }
56
57 static int cmp_property(const void *a, const void *b)
58 {
59         const PropertyRNA *propa= *(const PropertyRNA**)a;
60         const PropertyRNA *propb= *(const PropertyRNA**)b;
61
62         if(strcmp(propa->identifier, "rna_type") == 0) return -1;
63         else if(strcmp(propb->identifier, "rna_type") == 0) return 1;
64
65         if(strcmp(propa->identifier, "name") == 0) return -1;
66         else if(strcmp(propb->identifier, "name") == 0) return 1;
67
68         return strcmp(propa->name, propb->name);
69 }
70
71 static int cmp_def_struct(const void *a, const void *b)
72 {
73         const StructDefRNA *dsa= *(const StructDefRNA**)a;
74         const StructDefRNA *dsb= *(const StructDefRNA**)b;
75
76         return cmp_struct(&dsa->srna, &dsb->srna);
77 }
78
79 static int cmp_def_property(const void *a, const void *b)
80 {
81         const PropertyDefRNA *dpa= *(const PropertyDefRNA**)a;
82         const PropertyDefRNA *dpb= *(const PropertyDefRNA**)b;
83
84         return cmp_property(&dpa->prop, &dpb->prop);
85 }
86
87 static void rna_sortlist(ListBase *listbase, int(*cmp)(const void*, const void*))
88 {
89         Link *link;
90         void **array;
91         int a, size;
92         
93         if(listbase->first == listbase->last)
94                 return;
95
96         for(size=0, link=listbase->first; link; link=link->next)
97                 size++;
98
99         array= MEM_mallocN(sizeof(void*)*size, "rna_sortlist");
100         for(a=0, link=listbase->first; link; link=link->next, a++)
101                 array[a]= link;
102
103         qsort(array, size, sizeof(void*), cmp);
104
105         listbase->first= listbase->last= NULL;
106         for(a=0; a<size; a++) {
107                 link= array[a];
108                 link->next= link->prev= NULL;
109                 rna_addtail(listbase, link);
110         }
111
112         MEM_freeN(array);
113 }
114
115 /* Preprocessing */
116
117 static void rna_print_c_string(FILE *f, const char *str)
118 {
119         static char *escape[] = {"\''", "\"\"", "\??", "\\\\","\aa", "\bb", "\ff", "\nn", "\rr", "\tt", "\vv", NULL};
120         int i, j;
121
122         fprintf(f, "\"");
123         for(i=0; str[i]; i++) {
124                 for(j=0; escape[j]; j++)
125                         if(str[i] == escape[j][0])
126                                 break;
127
128                 if(escape[j]) fprintf(f, "\\%c", escape[j][1]);
129                 else fprintf(f, "%c", str[i]);
130         }
131         fprintf(f, "\"");
132 }
133
134 static void rna_print_data_get(FILE *f, PropertyDefRNA *dp)
135 {
136         if(dp->dnastructfromname && dp->dnastructfromprop)
137                 fprintf(f, "    %s *data= (%s*)(((%s*)ptr->data)->%s);\n", dp->dnastructname, dp->dnastructname, dp->dnastructfromname, dp->dnastructfromprop);
138         else
139                 fprintf(f, "    %s *data= (%s*)(ptr->data);\n", dp->dnastructname, dp->dnastructname);
140 }
141
142 static char *rna_alloc_function_name(const char *structname, const char *propname, const char *type)
143 {
144         AllocDefRNA *alloc;
145         char buffer[2048];
146         char *result;
147
148         snprintf(buffer, sizeof(buffer), "%s_%s_%s", structname, propname, type);
149         result= MEM_callocN(sizeof(char)*strlen(buffer)+1, "rna_alloc_function_name");
150         strcpy(result, buffer);
151
152         alloc= MEM_callocN(sizeof(AllocDefRNA), "AllocDefRNA");
153         alloc->mem= result;
154         rna_addtail(&DefRNA.allocs, alloc);
155
156         return result;
157 }
158
159 static const char *rna_type_type(PropertyRNA *prop)
160 {
161         switch(prop->type) {
162                 case PROP_BOOLEAN:
163                 case PROP_INT:
164                 case PROP_ENUM:
165                         return "int";
166                 case PROP_FLOAT:
167                         return "float";
168                 case PROP_STRING:
169                         return "char*";
170                 default:
171                         return "PointerRNA";
172         }
173 }
174
175 static int rna_enum_bitmask(PropertyRNA *prop)
176 {
177         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
178         int a, mask= 0;
179
180         for(a=0; a<eprop->totitem; a++)
181                 mask |= eprop->item[a].value;
182         
183         return mask;
184 }
185
186 static int rna_color_quantize(PropertyRNA *prop, PropertyDefRNA *dp)
187 {
188         if(prop->type == PROP_FLOAT && prop->subtype == PROP_COLOR)
189                 if(strcmp(dp->dnatype, "float") != 0 && strcmp(dp->dnatype, "double") != 0)
190                         return 1;
191         
192         return 0;
193 }
194
195 static const char *rna_function_string(void *func)
196 {
197         return (func)? (const char*)func: "NULL";
198 }
199
200 static void rna_float_print(FILE *f, float num)
201 {
202         if(num == -FLT_MAX) fprintf(f, "-FLT_MAX");
203         else if(num == FLT_MAX) fprintf(f, "FLT_MAX");
204         else if((int)num == num) fprintf(f, "%.1ff", num);
205         else fprintf(f, "%.10ff", num);
206 }
207
208 static void rna_int_print(FILE *f, int num)
209 {
210         if(num == INT_MIN) fprintf(f, "INT_MIN");
211         else if(num == INT_MAX) fprintf(f, "INT_MAX");
212         else fprintf(f, "%d", num);
213 }
214
215 static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, const char *manualfunc)
216 {
217         char *func;
218         int i;
219
220         if(prop->flag & PROP_IDPROPERTY)
221                 return NULL;
222         
223         if(!manualfunc) {
224                 if(!dp->dnastructname || !dp->dnaname) {
225                         fprintf(stderr, "rna_def_property_get_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
226                         DefRNA.error= 1;
227                         return NULL;
228                 }
229
230                 if(prop->type == PROP_STRING && ((StringPropertyRNA*)prop)->maxlength == 0) {
231                         fprintf(stderr, "rna_def_property_get_func: string %s.%s has max length 0.\n", srna->identifier, prop->identifier);
232                         DefRNA.error= 1;
233                         return NULL;
234                 }
235         }
236
237         func= rna_alloc_function_name(srna->identifier, prop->identifier, "get");
238
239         switch(prop->type) {
240                 case PROP_STRING: {
241                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
242                         fprintf(f, "void %s(PointerRNA *ptr, char *value)\n", func);
243                         fprintf(f, "{\n");
244                         if(manualfunc) {
245                                 fprintf(f, "    %s(ptr, value);\n", manualfunc);
246                         }
247                         else {
248                                 rna_print_data_get(f, dp);
249                                 fprintf(f, "    BLI_strncpy(value, data->%s, %d);\n", dp->dnaname, sprop->maxlength);
250                         }
251                         fprintf(f, "}\n\n");
252                         break;
253                 }
254                 case PROP_POINTER: {
255                         fprintf(f, "PointerRNA %s(PointerRNA *ptr)\n", func);
256                         fprintf(f, "{\n");
257                         if(manualfunc) {
258                                 fprintf(f, "    return %s(ptr);\n", manualfunc);
259                         }
260                         else {
261                                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
262                                 rna_print_data_get(f, dp);
263                                 if(dp->dnapointerlevel == 0)
264                                         fprintf(f, "    return rna_pointer_inherit_refine(ptr, &RNA_%s, &data->%s);\n", (char*)pprop->type, dp->dnaname);
265                                 else
266                                         fprintf(f, "    return rna_pointer_inherit_refine(ptr, &RNA_%s, data->%s);\n", (char*)pprop->type, dp->dnaname);
267                         }
268                         fprintf(f, "}\n\n");
269                         break;
270                 }
271                 case PROP_COLLECTION: {
272                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
273
274                         fprintf(f, "static PointerRNA %s(CollectionPropertyIterator *iter)\n", func);
275                         fprintf(f, "{\n");
276                         if(manualfunc) {
277                                 if(strcmp(manualfunc, "rna_iterator_listbase_get") == 0 ||
278                                    strcmp(manualfunc, "rna_iterator_array_get") == 0 ||
279                                    strcmp(manualfunc, "rna_iterator_array_dereference_get") == 0)
280                                         fprintf(f, "    return rna_pointer_inherit_refine(&iter->parent, &RNA_%s, %s(iter));\n", (cprop->type)? (char*)cprop->type: "UnknownType", manualfunc);
281                                 else
282                                         fprintf(f, "    return %s(iter);\n", manualfunc);
283                         }
284                         fprintf(f, "}\n\n");
285                         break;
286                 }
287                 default:
288                         if(prop->arraylength) {
289                                 fprintf(f, "void %s(PointerRNA *ptr, %s values[%d])\n", func, rna_type_type(prop), prop->arraylength);
290                                 fprintf(f, "{\n");
291
292                                 if(manualfunc) {
293                                         fprintf(f, "    %s(ptr, values);\n", manualfunc);
294                                 }
295                                 else {
296                                         rna_print_data_get(f, dp);
297
298                                         for(i=0; i<prop->arraylength; i++) {
299                                                 if(dp->dnaarraylength == 1) {
300                                                         if(prop->type == PROP_BOOLEAN && dp->booleanbit)
301                                                                 fprintf(f, "    values[%d]= (%s(data->%s & (%d<<%d)) != 0);\n", i, (dp->booleannegative)? "!": "", dp->dnaname, dp->booleanbit, i);
302                                                         else
303                                                                 fprintf(f, "    values[%d]= (%s)%s((&data->%s)[%d]);\n", i, rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnaname, i);
304                                                 }
305                                                 else {
306                                                         if(prop->type == PROP_BOOLEAN && dp->booleanbit) {
307                                                                 fprintf(f, "    values[%d]= (%s(data->%s[%d] & ", i, (dp->booleannegative)? "!": "", dp->dnaname, i);
308                                                                 rna_int_print(f, dp->booleanbit);
309                                                                 fprintf(f, ") != 0);\n");
310                                                         }
311                                                         else if(rna_color_quantize(prop, dp))
312                                                                 fprintf(f, "    values[%d]= (%s)(data->%s[%d]*(1.0f/255.0f));\n", i, rna_type_type(prop), dp->dnaname, i);
313                                                         else
314                                                                 fprintf(f, "    values[%d]= (%s)%s(data->%s[%d]);\n", i, rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnaname, i);
315                                                 }
316                                         }
317                                 }
318                                 fprintf(f, "}\n\n");
319                         }
320                         else {
321                                 fprintf(f, "%s %s(PointerRNA *ptr)\n", rna_type_type(prop), func);
322                                 fprintf(f, "{\n");
323
324                                 if(manualfunc) {
325                                         fprintf(f, "    return %s(ptr);\n", manualfunc);
326                                 }
327                                 else {
328                                         rna_print_data_get(f, dp);
329                                         if(prop->type == PROP_BOOLEAN && dp->booleanbit) {
330                                                 fprintf(f, "    return (%s((data->%s) & ", (dp->booleannegative)? "!": "", dp->dnaname);
331                                                 rna_int_print(f, dp->booleanbit);
332                                                 fprintf(f, ") != 0);\n");
333                                         }
334                                         else if(prop->type == PROP_ENUM && dp->enumbitflags) {
335                                                 fprintf(f, "    return ((data->%s) & ", dp->dnaname);
336                                                 rna_int_print(f, rna_enum_bitmask(prop));
337                                                 fprintf(f, ");\n");
338                                         }
339                                         else
340                                                 fprintf(f, "    return (%s)%s(data->%s);\n", rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnaname);
341                                 }
342
343                                 fprintf(f, "}\n\n");
344                         }
345                         break;
346         }
347
348         return func;
349 }
350
351 static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array, int i)
352 {
353         if(prop->type == PROP_INT) {
354                 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
355
356                 if(iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX) {
357                         if(array) fprintf(f, "CLAMPIS(values[%d], ", i);
358                         else fprintf(f, "CLAMPIS(value, ");
359                         rna_int_print(f, iprop->hardmin); fprintf(f, ", ");
360                         rna_int_print(f, iprop->hardmax); fprintf(f, ");\n");
361                         return;
362                 }
363         }
364         else if(prop->type == PROP_FLOAT) {
365                 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
366
367                 if(fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX) {
368                         if(array) fprintf(f, "CLAMPIS(values[%d], ", i);
369                         else fprintf(f, "CLAMPIS(value, ");
370                         rna_float_print(f, fprop->hardmin); fprintf(f, ", ");
371                         rna_float_print(f, fprop->hardmax); fprintf(f, ");\n");
372                         return;
373                 }
374         }
375
376         if(array)
377                 fprintf(f, "values[%d];\n", i);
378         else
379                 fprintf(f, "value;\n");
380 }
381
382 static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc)
383 {
384         char *func;
385         int i;
386
387         if(!(prop->flag & PROP_EDITABLE))
388                 return NULL;
389         if(prop->flag & PROP_IDPROPERTY)
390                 return NULL;
391
392         if(!manualfunc) {
393                 if(!dp->dnastructname || !dp->dnaname) {
394                         if(prop->flag & PROP_EDITABLE) {
395                                 fprintf(stderr, "rna_def_property_set_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
396                                 DefRNA.error= 1;
397                         }
398                         return NULL;
399                 }
400         }
401
402         func= rna_alloc_function_name(srna->identifier, prop->identifier, "set");
403
404         switch(prop->type) {
405                 case PROP_STRING: {
406                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
407                         fprintf(f, "void %s(PointerRNA *ptr, const char *value)\n", func);
408                         fprintf(f, "{\n");
409                         if(manualfunc) {
410                                 fprintf(f, "    %s(ptr, value);\n", manualfunc);
411                         }
412                         else {
413                                 rna_print_data_get(f, dp);
414                                 fprintf(f, "    BLI_strncpy(data->%s, value, %d);\n", dp->dnaname, sprop->maxlength);
415                         }
416                         fprintf(f, "}\n\n");
417                         break;
418                 }
419                 case PROP_POINTER: {
420                         fprintf(f, "void %s(PointerRNA *ptr, PointerRNA value)\n", func);
421                         fprintf(f, "{\n");
422                         if(manualfunc) {
423                                 fprintf(f, "    %s(ptr, value);\n", manualfunc);
424                         }
425                         else {
426                                 rna_print_data_get(f, dp);
427                                 fprintf(f, "    data->%s= value.data;\n", dp->dnaname);
428                         }
429                         fprintf(f, "}\n\n");
430                         break;
431                 }
432                 default:
433                         if(prop->arraylength) {
434                                 fprintf(f, "void %s(PointerRNA *ptr, const %s values[%d])\n", func, rna_type_type(prop), prop->arraylength);
435                                 fprintf(f, "{\n");
436
437                                 if(manualfunc) {
438                                         fprintf(f, "    %s(ptr, values);\n", manualfunc);
439                                 }
440                                 else {
441                                         rna_print_data_get(f, dp);
442
443                                         for(i=0; i<prop->arraylength; i++) {
444                                                 if(dp->dnaarraylength == 1) {
445                                                         if(prop->type == PROP_BOOLEAN && dp->booleanbit) {
446                                                                 fprintf(f, "    if(%svalues[%d]) data->%s |= (%d<<%d);\n", (dp->booleannegative)? "!": "", i, dp->dnaname, dp->booleanbit, i);
447                                                                 fprintf(f, "    else data->%s &= ~(%d<<%d);\n", dp->dnaname, dp->booleanbit, i);
448                                                         }
449                                                         else {
450                                                                 fprintf(f, "    (&data->%s)[%d]= %s", dp->dnaname, i, (dp->booleannegative)? "!": "");
451                                                                 rna_clamp_value(f, prop, 1, i);
452                                                         }
453                                                 }
454                                                 else {
455                                                         if(prop->type == PROP_BOOLEAN && dp->booleanbit) {
456                                                                 fprintf(f, "    if(%svalues[%d]) data->%s[%d] |= ", (dp->booleannegative)? "!": "", i, dp->dnaname, i);
457                                                                 rna_int_print(f, dp->booleanbit);
458                                                                 fprintf(f, ";\n");
459                                                                 fprintf(f, "    else data->%s[%d] &= ~", dp->dnaname, i);
460                                                                 rna_int_print(f, dp->booleanbit);
461                                                                 fprintf(f, ";\n");
462                                                         }
463                                                         else if(rna_color_quantize(prop, dp)) {
464                                                                 fprintf(f, "    data->%s[%d]= FTOCHAR(values[%d]);\n", dp->dnaname, i, i);
465                                                         }
466                                                         else {
467                                                                 fprintf(f, "    data->%s[%d]= %s", dp->dnaname, i, (dp->booleannegative)? "!": "");
468                                                                 rna_clamp_value(f, prop, 1, i);
469                                                         }
470                                                 }
471                                         }
472                                 }
473                                 fprintf(f, "}\n\n");
474                         }
475                         else {
476                                 fprintf(f, "void %s(PointerRNA *ptr, %s value)\n", func, rna_type_type(prop));
477                                 fprintf(f, "{\n");
478
479                                 if(manualfunc) {
480                                         fprintf(f, "    %s(ptr, value);\n", manualfunc);
481                                 }
482                                 else {
483                                         rna_print_data_get(f, dp);
484                                         if(prop->type == PROP_BOOLEAN && dp->booleanbit) {
485                                                 fprintf(f, "    if(%svalue) data->%s |= ", (dp->booleannegative)? "!": "", dp->dnaname);
486                                                 rna_int_print(f, dp->booleanbit);
487                                                 fprintf(f, ";\n");
488                                                 fprintf(f, "    else data->%s &= ~", dp->dnaname);
489                                                 rna_int_print(f, dp->booleanbit);
490                                                 fprintf(f, ";\n");
491                                         }
492                                         else if(prop->type == PROP_ENUM && dp->enumbitflags) {
493                                                 fprintf(f, "    data->%s &= ~", dp->dnaname);
494                                                 rna_int_print(f, rna_enum_bitmask(prop));
495                                                 fprintf(f, ";\n");
496                                                 fprintf(f, "    data->%s |= value;\n", dp->dnaname);
497                                         }
498                                         else {
499                                                 fprintf(f, "    data->%s= %s", dp->dnaname, (dp->booleannegative)? "!": "");
500                                                 rna_clamp_value(f, prop, 0, 0);
501                                         }
502                                 }
503                                 fprintf(f, "}\n\n");
504                         }
505                         break;
506         }
507
508         return func;
509 }
510
511 static char *rna_def_property_length_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc)
512 {
513         char *func= NULL;
514
515         if(prop->flag & PROP_IDPROPERTY)
516                 return NULL;
517
518         if(prop->type == PROP_STRING) {
519                 if(!manualfunc) {
520                         if(!dp->dnastructname || !dp->dnaname) {
521                                 fprintf(stderr, "rna_def_property_length_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
522                                 DefRNA.error= 1;
523                                 return NULL;
524                         }
525                 }
526
527                 func= rna_alloc_function_name(srna->identifier, prop->identifier, "length");
528
529                 fprintf(f, "int %s(PointerRNA *ptr)\n", func);
530                 fprintf(f, "{\n");
531                 if(manualfunc) {
532                         fprintf(f, "    return %s(ptr);\n", manualfunc);
533                 }
534                 else {
535                         rna_print_data_get(f, dp);
536                         fprintf(f, "    return strlen(data->%s);\n", dp->dnaname);
537                 }
538                 fprintf(f, "}\n\n");
539         }
540         else if(prop->type == PROP_COLLECTION) {
541                 if(!manualfunc) {
542                         if(prop->type == PROP_COLLECTION && (!(dp->dnalengthname || dp->dnalengthfixed)|| !dp->dnaname)) {
543                                 fprintf(stderr, "rna_def_property_length_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
544                                 DefRNA.error= 1;
545                                 return NULL;
546                         }
547                 }
548
549                 func= rna_alloc_function_name(srna->identifier, prop->identifier, "length");
550
551                 fprintf(f, "int %s(PointerRNA *ptr)\n", func);
552                 fprintf(f, "{\n");
553                 if(manualfunc) {
554                         fprintf(f, "    return %s(ptr);\n", manualfunc);
555                 }
556                 else {
557                         rna_print_data_get(f, dp);
558                         if(dp->dnalengthname)
559                                 fprintf(f, "    return (data->%s == NULL)? 0: data->%s;\n", dp->dnaname, dp->dnalengthname);
560                         else
561                                 fprintf(f, "    return (data->%s == NULL)? 0: %d;\n", dp->dnaname, dp->dnalengthfixed);
562                 }
563                 fprintf(f, "}\n\n");
564         }
565
566         return func;
567 }
568
569 static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc)
570 {
571         char *func, *getfunc;
572
573         if(prop->flag & PROP_IDPROPERTY)
574                 return NULL;
575
576         if(!manualfunc) {
577                 if(!dp->dnastructname || !dp->dnaname) {
578                         fprintf(stderr, "rna_def_property_begin_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
579                         DefRNA.error= 1;
580                         return NULL;
581                 }
582         }
583
584         func= rna_alloc_function_name(srna->identifier, prop->identifier, "begin");
585
586         fprintf(f, "void %s(CollectionPropertyIterator *iter, PointerRNA *ptr)\n", func);
587         fprintf(f, "{\n");
588
589         if(!manualfunc)
590                 rna_print_data_get(f, dp);
591
592         fprintf(f, "\n  memset(iter, 0, sizeof(*iter));\n");
593         fprintf(f, "    iter->parent= *ptr;\n");
594         fprintf(f, "    iter->prop= (PropertyRNA*)&rna_%s_%s;\n", srna->identifier, prop->identifier);
595
596         if(dp->dnalengthname || dp->dnalengthfixed) {
597                 if(manualfunc) {
598                         fprintf(f, "\n  %s(iter, ptr);\n", manualfunc);
599                 }
600                 else {
601                         if(dp->dnalengthname)
602                                 fprintf(f, "\n  rna_iterator_array_begin(iter, data->%s, sizeof(data->%s[0]), data->%s, NULL);\n", dp->dnaname, dp->dnaname, dp->dnalengthname);
603                         else
604                                 fprintf(f, "\n  rna_iterator_array_begin(iter, data->%s, sizeof(data->%s[0]), %d, NULL);\n", dp->dnaname, dp->dnaname, dp->dnalengthfixed);
605                 }
606         }
607         else {
608                 if(manualfunc)
609                         fprintf(f, "\n  %s(iter, ptr);\n", manualfunc);
610                 else
611                         fprintf(f, "\n  rna_iterator_listbase_begin(iter, &data->%s, NULL);\n", dp->dnaname);
612         }
613
614         getfunc= rna_alloc_function_name(srna->identifier, prop->identifier, "get");
615
616         fprintf(f, "\n  if(iter->valid)\n");
617         fprintf(f, "            iter->ptr= %s(iter);\n", getfunc);
618
619         fprintf(f, "}\n\n");
620
621
622         return func;
623 }
624
625 static char *rna_def_property_next_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc)
626 {
627         char *func, *getfunc;
628
629         if(prop->flag & PROP_IDPROPERTY)
630                 return NULL;
631
632         if(!manualfunc)
633                 return NULL;
634
635         func= rna_alloc_function_name(srna->identifier, prop->identifier, "next");
636
637         fprintf(f, "void %s(CollectionPropertyIterator *iter)\n", func);
638         fprintf(f, "{\n");
639         fprintf(f, "    %s(iter);\n", manualfunc);
640
641         getfunc= rna_alloc_function_name(srna->identifier, prop->identifier, "get");
642
643         fprintf(f, "\n  if(iter->valid)\n");
644         fprintf(f, "            iter->ptr= %s(iter);\n", getfunc);
645
646         fprintf(f, "}\n\n");
647
648         return func;
649 }
650
651 static char *rna_def_property_end_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc)
652 {
653         char *func;
654
655         if(prop->flag & PROP_IDPROPERTY)
656                 return NULL;
657
658         func= rna_alloc_function_name(srna->identifier, prop->identifier, "end");
659
660         fprintf(f, "void %s(CollectionPropertyIterator *iter)\n", func);
661         fprintf(f, "{\n");
662         if(manualfunc)
663                 fprintf(f, "    %s(iter);\n", manualfunc);
664         fprintf(f, "}\n\n");
665
666         return func;
667 }
668
669 static void rna_def_property_funcs(FILE *f, PropertyDefRNA *dp)
670 {
671         PropertyRNA *prop;
672         StructRNA *srna;
673
674         srna= dp->srna;
675         prop= dp->prop;
676
677         switch(prop->type) {
678                 case PROP_BOOLEAN: {
679                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
680
681                         if(!prop->arraylength) {
682                                 bprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)bprop->get);
683                                 bprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)bprop->set);
684                         }
685                         else {
686                                 bprop->getarray= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)bprop->getarray);
687                                 bprop->setarray= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)bprop->setarray);
688                         }
689                         break;
690                 }
691                 case PROP_INT: {
692                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
693
694                         if(!prop->arraylength) {
695                                 iprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)iprop->get);
696                                 iprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)iprop->set);
697                         }
698                         else {
699                                 iprop->getarray= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)iprop->getarray);
700                                 iprop->setarray= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)iprop->setarray);
701                         }
702                         break;
703                 }
704                 case PROP_FLOAT: {
705                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
706
707                         if(!prop->arraylength) {
708                                 fprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)fprop->get);
709                                 fprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)fprop->set);
710                         }
711                         else {
712                                 fprop->getarray= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)fprop->getarray);
713                                 fprop->setarray= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)fprop->setarray);
714                         }
715                         break;
716                 }
717                 case PROP_ENUM: {
718                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
719
720                         eprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)eprop->get);
721                         eprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)eprop->set);
722                         break;
723                 }
724                 case PROP_STRING: {
725                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
726
727                         sprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)sprop->get);
728                         sprop->length= (void*)rna_def_property_length_func(f, srna, prop, dp, (char*)sprop->length);
729                         sprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)sprop->set);
730                         break;
731                 }
732                 case PROP_POINTER: {
733                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
734
735                         pprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)pprop->get);
736                         pprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)pprop->set);
737                         if(!pprop->type) {
738                                 fprintf(stderr, "rna_def_property_funcs: %s.%s, pointer must have a struct type.\n", srna->identifier, prop->identifier);
739                                 DefRNA.error= 1;
740                         }
741                         break;
742                 }
743                 case PROP_COLLECTION: {
744                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
745
746                         if(dp->dnatype && strcmp(dp->dnatype, "ListBase")==0);
747                         else if(dp->dnalengthname || dp->dnalengthfixed)
748                                 cprop->length= (void*)rna_def_property_length_func(f, srna, prop, dp, (char*)cprop->length);
749
750                         cprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)cprop->get);
751                         cprop->begin= (void*)rna_def_property_begin_func(f, srna, prop, dp, (char*)cprop->begin);
752                         cprop->next= (void*)rna_def_property_next_func(f, srna, prop, dp, (char*)cprop->next);
753                         cprop->end= (void*)rna_def_property_end_func(f, srna, prop, dp, (char*)cprop->end);
754
755                         if(!(prop->flag & PROP_IDPROPERTY)) {
756                                 if(!cprop->begin) {
757                                         fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a begin function.\n", srna->identifier, prop->identifier);
758                                         DefRNA.error= 1;
759                                 }
760                                 if(!cprop->next) {
761                                         fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a next function.\n", srna->identifier, prop->identifier);
762                                         DefRNA.error= 1;
763                                 }
764                                 if(!cprop->get) {
765                                         fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a get function.\n", srna->identifier, prop->identifier);
766                                         DefRNA.error= 1;
767                                 }
768                         }
769                         if(!cprop->type) {
770                                 fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a struct type.\n", srna->identifier, prop->identifier);
771                                 DefRNA.error= 1;
772                         }
773                         break;
774                 }
775         }
776 }
777
778 static void rna_def_property_funcs_header(FILE *f, PropertyDefRNA *dp)
779 {
780         PropertyRNA *prop;
781         StructRNA *srna;
782         char *func;
783
784         srna= dp->srna;
785         prop= dp->prop;
786
787         if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN))
788                 return;
789
790         func= rna_alloc_function_name(srna->identifier, prop->identifier, "");
791
792         switch(prop->type) {
793                 case PROP_BOOLEAN:
794                 case PROP_INT: {
795                         if(!prop->arraylength) {
796                                 fprintf(f, "int %sget(PointerRNA *ptr);\n", func);
797                                 //fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func);
798                         }
799                         else {
800                                 fprintf(f, "void %sget(PointerRNA *ptr, int values[%d]);\n", func, prop->arraylength);
801                                 //fprintf(f, "void %sset(PointerRNA *ptr, const int values[%d]);\n", func, prop->arraylength);
802                         }
803                         break;
804                 }
805                 case PROP_FLOAT: {
806                         if(!prop->arraylength) {
807                                 fprintf(f, "float %sget(PointerRNA *ptr);\n", func);
808                                 //fprintf(f, "void %sset(PointerRNA *ptr, float value);\n", func);
809                         }
810                         else {
811                                 fprintf(f, "void %sget(PointerRNA *ptr, float values[%d]);\n", func, prop->arraylength);
812                                 //fprintf(f, "void %sset(PointerRNA *ptr, const float values[%d]);\n", func, prop->arraylength);
813                         }
814                         break;
815                 }
816                 case PROP_ENUM: {
817                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
818                         int i;
819
820                         if(eprop->item) {
821                                 fprintf(f, "enum {\n");
822
823                                 for(i=0; i<eprop->totitem; i++)
824                                         fprintf(f, "\t%s_%s_%s = %d,\n", srna->identifier, prop->identifier, eprop->item[i].identifier, eprop->item[i].value);
825
826                                 fprintf(f, "};\n\n");
827                         }
828
829                         fprintf(f, "int %sget(PointerRNA *ptr);\n", func);
830                         //fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func);
831
832                         break;
833                 }
834                 case PROP_STRING: {
835                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
836
837                         if(sprop->maxlength) {
838                                 fprintf(f, "#define %s_%s_MAX %d\n\n", srna->identifier, prop->identifier, sprop->maxlength);
839                         }
840                         
841                         fprintf(f, "void %sget(PointerRNA *ptr, char *value);\n", func);
842                         fprintf(f, "int %slength(PointerRNA *ptr);\n", func);
843                         //fprintf(f, "void %sset(PointerRNA *ptr, const char *value);\n", func);
844
845                         break;
846                 }
847                 case PROP_POINTER: {
848                         fprintf(f, "PointerRNA %sget(PointerRNA *ptr);\n", func);
849                         //fprintf(f, "void %sset(PointerRNA *ptr, PointerRNA value);\n", func);
850                         break;
851                 }
852                 case PROP_COLLECTION: {
853                         fprintf(f, "void %sbegin(CollectionPropertyIterator *iter, PointerRNA *ptr);\n", func);
854                         fprintf(f, "void %snext(CollectionPropertyIterator *iter);\n", func);
855                         fprintf(f, "void %send(CollectionPropertyIterator *iter);\n", func);
856                         //fprintf(f, "int %slength(PointerRNA *ptr);\n", func);
857                         //fprintf(f, "void %slookup_int(PointerRNA *ptr, int key, StructRNA **type);\n", func);
858                         //fprintf(f, "void %slookup_string(PointerRNA *ptr, const char *key, StructRNA **type);\n", func);
859                         break;
860                 }
861         }
862
863         fprintf(f, "\n");
864 }
865
866 static void rna_def_property_funcs_header_cpp(FILE *f, PropertyDefRNA *dp)
867 {
868         PropertyRNA *prop;
869         StructRNA *srna;
870
871         srna= dp->srna;
872         prop= dp->prop;
873
874         if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN))
875                 return;
876         
877         if(prop->name && prop->description && strcmp(prop->description, "") != 0)
878                 fprintf(f, "\t/* %s: %s */\n", prop->name, prop->description);
879         else if(prop->name)
880                 fprintf(f, "\t/* %s */\n", prop->name);
881         else
882                 fprintf(f, "\t/* */\n");
883
884         switch(prop->type) {
885                 case PROP_BOOLEAN: {
886                         if(!prop->arraylength)
887                                 fprintf(f, "\tbool %s(void);", prop->identifier);
888                         else
889                                 fprintf(f, "\tArray<int, %d> %s(void);", prop->arraylength, prop->identifier);
890                         break;
891                 }
892                 case PROP_INT: {
893                         if(!prop->arraylength)
894                                 fprintf(f, "\tint %s(void);", prop->identifier);
895                         else
896                                 fprintf(f, "\tArray<int, %d> %s(void);", prop->arraylength, prop->identifier);
897                         break;
898                 }
899                 case PROP_FLOAT: {
900                         if(!prop->arraylength)
901                                 fprintf(f, "\tfloat %s(void);", prop->identifier);
902                         else
903                                 fprintf(f, "\tArray<float, %d> %s(void);", prop->arraylength, prop->identifier);
904                         break;
905                 }
906                 case PROP_ENUM: {
907                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
908                         int i;
909
910                         if(eprop->item) {
911                                 fprintf(f, "\tenum %s_enum {\n", prop->identifier);
912
913                                 for(i=0; i<eprop->totitem; i++)
914                                         fprintf(f, "\t\t%s_%s = %d,\n", prop->identifier, eprop->item[i].identifier, eprop->item[i].value);
915
916                                 fprintf(f, "\t};\n");
917                         }
918
919                         fprintf(f, "\t%s_enum %s(void);", prop->identifier, prop->identifier);
920                         break;
921                 }
922                 case PROP_STRING: {
923                         fprintf(f, "\tstd::string %s(void);", prop->identifier);
924                         break;
925                 }
926                 case PROP_POINTER: {
927                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)dp->prop;
928
929                         if(pprop->type)
930                                 fprintf(f, "\t%s %s(void);", (char*)pprop->type, prop->identifier);
931                         else
932                                 fprintf(f, "\t%s %s(void);", "UnknownType", prop->identifier);
933                         break;
934                 }
935                 case PROP_COLLECTION: {
936                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)dp->prop;
937
938                         if(cprop->type)
939                                 fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", (char*)cprop->type, srna->identifier, prop->identifier);
940                         else
941                                 fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, prop->identifier);
942                         break;
943                 }
944         }
945
946         fprintf(f, "\n");
947 }
948
949 static void rna_def_property_funcs_impl_cpp(FILE *f, PropertyDefRNA *dp)
950 {
951         PropertyRNA *prop;
952         StructRNA *srna;
953
954         srna= dp->srna;
955         prop= dp->prop;
956
957         if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN))
958                 return;
959
960         switch(prop->type) {
961                 case PROP_BOOLEAN: {
962                         if(!prop->arraylength)
963                                 fprintf(f, "\tBOOLEAN_PROPERTY(%s, %s)", srna->identifier, prop->identifier);
964                         else
965                                 fprintf(f, "\tBOOLEAN_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->arraylength, prop->identifier);
966                         break;
967                 }
968                 case PROP_INT: {
969                         if(!prop->arraylength)
970                                 fprintf(f, "\tINT_PROPERTY(%s, %s)", srna->identifier, prop->identifier);
971                         else
972                                 fprintf(f, "\tINT_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->arraylength, prop->identifier);
973                         break;
974                 }
975                 case PROP_FLOAT: {
976                         if(!prop->arraylength)
977                                 fprintf(f, "\tFLOAT_PROPERTY(%s, %s)", srna->identifier, prop->identifier);
978                         else
979                                 fprintf(f, "\tFLOAT_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->arraylength, prop->identifier);
980                         break;
981                 }
982                 case PROP_ENUM: {
983                         fprintf(f, "\tENUM_PROPERTY(%s_enum, %s, %s)", prop->identifier, srna->identifier, prop->identifier);
984
985                         break;
986                 }
987                 case PROP_STRING: {
988                         fprintf(f, "\tSTRING_PROPERTY(%s, %s)", srna->identifier, prop->identifier);
989                         break;
990                 }
991                 case PROP_POINTER: {
992                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)dp->prop;
993
994                         if(pprop->type)
995                                 fprintf(f, "\tPOINTER_PROPERTY(%s, %s, %s)", (char*)pprop->type, srna->identifier, prop->identifier);
996                         else
997                                 fprintf(f, "\tPOINTER_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, prop->identifier);
998                         break;
999                 }
1000                 case PROP_COLLECTION: {
1001                         /*CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)dp->prop;
1002
1003                         if(cprop->type)
1004                                 fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", (char*)cprop->type, srna->identifier, prop->identifier);
1005                         else
1006                                 fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, prop->identifier);*/
1007                         break;
1008                 }
1009         }
1010
1011         fprintf(f, "\n");
1012 }
1013
1014 static const char *rna_find_type(const char *type)
1015 {
1016         StructDefRNA *ds;
1017
1018         for(ds=DefRNA.structs.first; ds; ds=ds->next)
1019                 if(ds->dnaname && strcmp(ds->dnaname, type)==0)
1020                         return ds->srna->identifier;
1021         
1022         return NULL;
1023 }
1024
1025 static void rna_auto_types()
1026 {
1027         StructDefRNA *ds;
1028         PropertyDefRNA *dp;
1029
1030         for(ds=DefRNA.structs.first; ds; ds=ds->next) {
1031                 /* DNA name for Screen is patched in 2.5, we do the reverse here .. */
1032                 if(ds->dnaname && strcmp(ds->dnaname, "Screen") == 0)
1033                         ds->dnaname= "bScreen";
1034
1035                 for(dp=ds->properties.first; dp; dp=dp->next) {
1036                         if(dp->dnastructname && strcmp(dp->dnastructname, "Screen") == 0)
1037                                 dp->dnastructname= "bScreen";
1038
1039                         if(dp->dnatype) {
1040                                 if(dp->prop->type == PROP_POINTER) {
1041                                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)dp->prop;
1042
1043                                         if(!pprop->type && !pprop->get)
1044                                                 pprop->type= (StructRNA*)rna_find_type(dp->dnatype);
1045                                 }
1046                                 else if(dp->prop->type== PROP_COLLECTION) {
1047                                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)dp->prop;
1048
1049                                         if(!cprop->type && !cprop->get && strcmp(dp->dnatype, "ListBase")==0)
1050                                                 cprop->type= (StructRNA*)rna_find_type(dp->dnatype);
1051                                 }
1052                         }
1053                 }
1054         }
1055 }
1056
1057 static void rna_sort(BlenderRNA *brna)
1058 {
1059         StructDefRNA *ds;
1060         StructRNA *srna;
1061
1062         rna_sortlist(&brna->structs, cmp_struct);
1063         rna_sortlist(&DefRNA.structs, cmp_def_struct);
1064
1065         for(srna=brna->structs.first; srna; srna=srna->next)
1066                 rna_sortlist(&srna->properties, cmp_property);
1067
1068         for(ds=DefRNA.structs.first; ds; ds=ds->next)
1069                 rna_sortlist(&ds->properties, cmp_def_property);
1070 }
1071
1072 static const char *rna_property_structname(PropertyType type)
1073 {
1074         switch(type) {
1075                 case PROP_BOOLEAN: return "BooleanPropertyRNA";
1076                 case PROP_INT: return "IntPropertyRNA";
1077                 case PROP_FLOAT: return "FloatPropertyRNA";
1078                 case PROP_STRING: return "StringPropertyRNA";
1079                 case PROP_ENUM: return "EnumPropertyRNA";
1080                 case PROP_POINTER: return "PointerPropertyRNA";
1081                 case PROP_COLLECTION: return "CollectionPropertyRNA";
1082                 default: return "UnknownPropertyRNA";
1083         }
1084 }
1085
1086 static const char *rna_property_typename(PropertyType type)
1087 {
1088         switch(type) {
1089                 case PROP_BOOLEAN: return "PROP_BOOLEAN";
1090                 case PROP_INT: return "PROP_INT";
1091                 case PROP_FLOAT: return "PROP_FLOAT";
1092                 case PROP_STRING: return "PROP_STRING";
1093                 case PROP_ENUM: return "PROP_ENUM";
1094                 case PROP_POINTER: return "PROP_POINTER";
1095                 case PROP_COLLECTION: return "PROP_COLLECTION";
1096                 default: return "PROP_UNKNOWN";
1097         }
1098 }
1099
1100 static const char *rna_property_subtypename(PropertyType type)
1101 {
1102         switch(type) {
1103                 case PROP_NONE: return "PROP_NONE";
1104                 case PROP_UNSIGNED: return "PROP_UNSIGNED";
1105                 case PROP_FILEPATH: return "PROP_FILEPATH";
1106                 case PROP_DIRPATH: return "PROP_DIRPATH";
1107                 case PROP_COLOR: return "PROP_COLOR";
1108                 case PROP_VECTOR: return "PROP_VECTOR";
1109                 case PROP_MATRIX: return "PROP_MATRIX";
1110                 case PROP_ROTATION: return "PROP_ROTATION";
1111                 case PROP_NEVER_NULL: return "PROP_NEVER_NULL";
1112                 case PROP_PERCENTAGE: return "PROP_PERCENTAGE";
1113                 default: return "PROP_UNKNOWN";
1114         }
1115 }
1116
1117 static void rna_generate_prototypes(BlenderRNA *brna, FILE *f)
1118 {
1119         StructRNA *srna;
1120
1121         for(srna=brna->structs.first; srna; srna=srna->next)
1122                 fprintf(f, "extern StructRNA RNA_%s;\n", srna->identifier);
1123         fprintf(f, "\n");
1124 }
1125
1126 static void rna_generate_blender(BlenderRNA *brna, FILE *f)
1127 {
1128         StructRNA *srna;
1129
1130         fprintf(f, "BlenderRNA BLENDER_RNA = {");
1131
1132         srna= brna->structs.first;
1133         if(srna) fprintf(f, "{&RNA_%s, ", srna->identifier);
1134         else fprintf(f, "{NULL, ");
1135
1136         srna= brna->structs.last;
1137         if(srna) fprintf(f, "&RNA_%s}", srna->identifier);
1138         else fprintf(f, "NULL}");
1139
1140         fprintf(f, "};\n\n");
1141 }
1142
1143 static void rna_generate_property_prototypes(BlenderRNA *brna, StructRNA *srna, FILE *f)
1144 {
1145         PropertyRNA *prop;
1146         StructRNA *base;
1147
1148         base= srna->base;
1149         while (base) {
1150                 fprintf(f, "\n");
1151                 for(prop=base->properties.first; prop; prop=prop->next)
1152                         fprintf(f, "%s%s rna_%s_%s;\n", "extern ", rna_property_structname(prop->type), base->identifier, prop->identifier);
1153                 base= base->base;
1154         }
1155
1156         if(srna->properties.first)
1157                 fprintf(f, "\n");
1158
1159         for(prop=srna->properties.first; prop; prop=prop->next)
1160                 fprintf(f, "%s%s rna_%s_%s;\n", (prop->flag & PROP_EXPORT)? "": "", rna_property_structname(prop->type), srna->identifier, prop->identifier);
1161         fprintf(f, "\n");
1162 }
1163
1164 static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
1165 {
1166         PropertyRNA *prop;
1167         StructRNA *base;
1168
1169         fprintf(f, "/* %s */\n", srna->name);
1170
1171         for(prop=srna->properties.first; prop; prop=prop->next) {
1172                 switch(prop->type) {
1173                         case PROP_ENUM: {
1174                                 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1175                                 int i, defaultfound= 0;
1176
1177                                 if(eprop->item) {
1178                                         fprintf(f, "static EnumPropertyItem rna_%s_%s_items[%d] = {", srna->identifier, prop->identifier, eprop->totitem);
1179
1180                                         for(i=0; i<eprop->totitem; i++) {
1181                                                 fprintf(f, "{%d, ", eprop->item[i].value);
1182                                                 rna_print_c_string(f, eprop->item[i].identifier); fprintf(f, ", ");
1183                                                 rna_print_c_string(f, eprop->item[i].name); fprintf(f, ", ");
1184                                                 rna_print_c_string(f, eprop->item[i].description); fprintf(f, "}");
1185                                                 if(i != eprop->totitem-1)
1186                                                         fprintf(f, ", ");
1187
1188                                                 if(eprop->defaultvalue == eprop->item[i].value)
1189                                                         defaultfound= 1;
1190                                         }
1191
1192                                         fprintf(f, "};\n\n");
1193
1194                                         if(!defaultfound) {
1195                                                 fprintf(stderr, "rna_generate_structs: %s.%s, enum default is not in items.\n", srna->identifier, prop->identifier);
1196                                                 DefRNA.error= 1;
1197                                         }
1198                                 }
1199                                 else {
1200                                         fprintf(stderr, "rna_generate_structs: %s.%s, enum must have items defined.\n", srna->identifier, prop->identifier);
1201                                         DefRNA.error= 1;
1202                                 }
1203                                 break;
1204                         }
1205                         case PROP_BOOLEAN: {
1206                                 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1207                                 unsigned int i;
1208
1209                                 if(prop->arraylength) {
1210                                         fprintf(f, "static int rna_%s_%s_default[%d] = {", srna->identifier, prop->identifier, prop->arraylength);
1211
1212                                         for(i=0; i<prop->arraylength; i++) {
1213                                                 if(bprop->defaultarray)
1214                                                         fprintf(f, "%d", bprop->defaultarray[i]);
1215                                                 else
1216                                                         fprintf(f, "%d", bprop->defaultvalue);
1217                                                 if(i != prop->arraylength-1)
1218                                                         fprintf(f, ", ");
1219                                         }
1220
1221                                         fprintf(f, "};\n\n");
1222                                 }
1223                                 break;
1224                         }
1225                         case PROP_INT: {
1226                                 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1227                                 unsigned int i;
1228
1229                                 if(prop->arraylength) {
1230                                         fprintf(f, "static int rna_%s_%s_default[%d] = {", srna->identifier, prop->identifier, prop->arraylength);
1231
1232                                         for(i=0; i<prop->arraylength; i++) {
1233                                                 if(iprop->defaultarray)
1234                                                         fprintf(f, "%d", iprop->defaultarray[i]);
1235                                                 else
1236                                                         fprintf(f, "%d", iprop->defaultvalue);
1237                                                 if(i != prop->arraylength-1)
1238                                                         fprintf(f, ", ");
1239                                         }
1240
1241                                         fprintf(f, "};\n\n");
1242                                 }
1243                                 break;
1244                         }
1245                         case PROP_FLOAT: {
1246                                 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1247                                 unsigned int i;
1248
1249                                 if(prop->arraylength) {
1250                                         fprintf(f, "static float rna_%s_%s_default[%d] = {", srna->identifier, prop->identifier, prop->arraylength);
1251
1252                                         for(i=0; i<prop->arraylength; i++) {
1253                                                 if(fprop->defaultarray)
1254                                                         rna_float_print(f, fprop->defaultarray[i]);
1255                                                 else
1256                                                         rna_float_print(f, fprop->defaultvalue);
1257                                                 if(i != prop->arraylength-1)
1258                                                         fprintf(f, ", ");
1259                                         }
1260
1261                                         fprintf(f, "};\n\n");
1262                                 }
1263                                 break;
1264                         }
1265                         default:
1266                                 break;
1267                 }
1268
1269                 fprintf(f, "%s%s rna_%s_%s = {\n", (prop->flag & PROP_EXPORT)? "": "", rna_property_structname(prop->type), srna->identifier, prop->identifier);
1270
1271                 if(prop->next) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->next->identifier);
1272                 else fprintf(f, "\t{NULL, ");
1273                 if(prop->prev) fprintf(f, "(PropertyRNA*)&rna_%s_%s,\n", srna->identifier, prop->prev->identifier);
1274                 else fprintf(f, "NULL,\n");
1275                 fprintf(f, "\t%d, ", prop->magic);
1276                 rna_print_c_string(f, prop->identifier);
1277                 fprintf(f, ", %d, ", prop->flag);
1278                 rna_print_c_string(f, prop->name); fprintf(f, ",\n\t");
1279                 rna_print_c_string(f, prop->description); fprintf(f, ",\n");
1280                 fprintf(f, "\t%s, %s, %d,\n", rna_property_typename(prop->type), rna_property_subtypename(prop->subtype), prop->arraylength);
1281                 fprintf(f, "\t%s, %d, %s},\n", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable));
1282
1283                 switch(prop->type) {
1284                         case PROP_BOOLEAN: {
1285                                 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1286                                 fprintf(f, "\t%s, %s, %s, %s, %d, ", rna_function_string(bprop->get), rna_function_string(bprop->set), rna_function_string(bprop->getarray), rna_function_string(bprop->setarray), bprop->defaultvalue);
1287                                 if(prop->arraylength) fprintf(f, "rna_%s_%s_default\n", srna->identifier, prop->identifier);
1288                                 else fprintf(f, "NULL\n");
1289                                 break;
1290                         }
1291                         case PROP_INT: {
1292                                 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1293                                 fprintf(f, "\t%s, %s, %s, %s, %s,\n\t", rna_function_string(iprop->get), rna_function_string(iprop->set), rna_function_string(iprop->getarray), rna_function_string(iprop->setarray), rna_function_string(iprop->range));
1294                                 rna_int_print(f, iprop->softmin); fprintf(f, ", ");
1295                                 rna_int_print(f, iprop->softmax); fprintf(f, ", ");
1296                                 rna_int_print(f, iprop->hardmin); fprintf(f, ", ");
1297                                 rna_int_print(f, iprop->hardmax); fprintf(f, ", ");
1298                                 rna_int_print(f, iprop->step); fprintf(f, ", ");
1299                                 rna_int_print(f, iprop->defaultvalue); fprintf(f, ", ");
1300                                 if(prop->arraylength) fprintf(f, "rna_%s_%s_default\n", srna->identifier, prop->identifier);
1301                                 else fprintf(f, "NULL\n");
1302                                 break;
1303                         }
1304                         case PROP_FLOAT: {
1305                                 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1306                                 fprintf(f, "\t%s, %s, %s, %s, %s, ", rna_function_string(fprop->get), rna_function_string(fprop->set), rna_function_string(fprop->getarray), rna_function_string(fprop->setarray), rna_function_string(fprop->range));
1307                                 rna_float_print(f, fprop->softmin); fprintf(f, ", ");
1308                                 rna_float_print(f, fprop->softmax); fprintf(f, ", ");
1309                                 rna_float_print(f, fprop->hardmin); fprintf(f, ", ");
1310                                 rna_float_print(f, fprop->hardmax); fprintf(f, ", ");
1311                                 rna_float_print(f, fprop->step); fprintf(f, ", ");
1312                                 rna_int_print(f, (int)fprop->precision); fprintf(f, ", ");
1313                                 rna_float_print(f, fprop->defaultvalue); fprintf(f, ", ");
1314                                 if(prop->arraylength) fprintf(f, "rna_%s_%s_default\n", srna->identifier, prop->identifier);
1315                                 else fprintf(f, "NULL\n");
1316                                 break;
1317                         }
1318                         case PROP_STRING: {
1319                                 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1320                                 fprintf(f, "\t%s, %s, %s, %d, ", rna_function_string(sprop->get), rna_function_string(sprop->length), rna_function_string(sprop->set), sprop->maxlength);
1321                                 rna_print_c_string(f, sprop->defaultvalue); fprintf(f, "\n");
1322                                 break;
1323                         }
1324                         case PROP_ENUM: {
1325                                 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1326                                 fprintf(f, "\t%s, %s, rna_%s_%s_items, %d, %d\n", rna_function_string(eprop->get), rna_function_string(eprop->set), srna->identifier, prop->identifier, eprop->totitem, eprop->defaultvalue);
1327                                 break;
1328                         }
1329                         case PROP_POINTER: {
1330                                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1331                                 fprintf(f, "\t%s, %s, ", rna_function_string(pprop->get), rna_function_string(pprop->set));
1332                                 if(pprop->type) fprintf(f, "&RNA_%s\n", (char*)pprop->type);
1333                                 else fprintf(f, "NULL\n");
1334                                 break;
1335                         }
1336                         case PROP_COLLECTION: {
1337                                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1338                                 fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, ", rna_function_string(cprop->begin), rna_function_string(cprop->next), rna_function_string(cprop->end), rna_function_string(cprop->get), rna_function_string(cprop->length), rna_function_string(cprop->lookupint), rna_function_string(cprop->lookupstring));
1339                                 if(cprop->type) fprintf(f, "&RNA_%s\n", (char*)cprop->type);
1340                                 else fprintf(f, "NULL\n");
1341                                 break;
1342                         }
1343                 }
1344
1345                 fprintf(f, "};\n\n");
1346         }
1347
1348         fprintf(f, "StructRNA RNA_%s = {\n", srna->identifier);
1349
1350         if(srna->next) fprintf(f, "\t&RNA_%s, ", srna->next->identifier);
1351         else fprintf(f, "\tNULL, ");
1352         if(srna->prev) fprintf(f, "&RNA_%s,\n", srna->prev->identifier);
1353         else fprintf(f, "NULL,\n");
1354         
1355         fprintf(f, "\tNULL,\n"); /* PyType - Cant initialize here */
1356         
1357         fprintf(f, "\t");
1358         rna_print_c_string(f, srna->identifier);
1359         fprintf(f, ", %d, ", srna->flag);
1360         rna_print_c_string(f, srna->name);
1361         fprintf(f, ", ");
1362         rna_print_c_string(f, srna->description);
1363         fprintf(f, ",\n");
1364
1365         prop= srna->nameproperty;
1366         if(prop) {
1367                 base= srna;
1368                 while (base->base && base->base->nameproperty==prop)
1369                         base= base->base;
1370
1371                 fprintf(f, "\t(PropertyRNA*)&rna_%s_%s, ", base->identifier, prop->identifier);
1372         }
1373         else fprintf(f, "\tNULL, ");
1374
1375         prop= srna->iteratorproperty;
1376         base= srna;
1377         while (base->base && base->base->iteratorproperty==prop)
1378                 base= base->base;
1379         fprintf(f, "(PropertyRNA*)&rna_%s_rna_properties,\n", base->identifier);
1380
1381         if(srna->base) fprintf(f, "\t&RNA_%s,\n", srna->base->identifier);
1382         else fprintf(f, "\tNULL,\n");
1383
1384         if(srna->nested) fprintf(f, "\t&RNA_%s,\n", srna->nested->identifier);
1385         else fprintf(f, "\tNULL,\n");
1386
1387         fprintf(f, "\t%s,\n", rna_function_string(srna->refine));
1388         fprintf(f, "\t%s,\n", rna_function_string(srna->path));
1389
1390         prop= srna->properties.first;
1391         if(prop) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->identifier);
1392         else fprintf(f, "\t{NULL, ");
1393
1394         prop= srna->properties.last;
1395         if(prop) fprintf(f, "(PropertyRNA*)&rna_%s_%s}\n", srna->identifier, prop->identifier);
1396         else fprintf(f, "NULL}\n");
1397
1398         fprintf(f, "};\n");
1399
1400         fprintf(f, "\n");
1401 }
1402
1403 typedef struct RNAProcessItem {
1404         char *filename;
1405         void (*define)(BlenderRNA *brna);
1406 } RNAProcessItem;
1407
1408 RNAProcessItem PROCESS_ITEMS[]= {
1409         {"rna_rna.c", RNA_def_rna},
1410         {"rna_ID.c", RNA_def_ID},
1411         {"rna_texture.c", RNA_def_texture},
1412         {"rna_action.c", RNA_def_action},
1413         {"rna_animation.c", RNA_def_animation},
1414         {"rna_actuator.c", RNA_def_actuator},
1415         {"rna_armature.c", RNA_def_armature},
1416         {"rna_brush.c", RNA_def_brush},
1417         {"rna_camera.c", RNA_def_camera},
1418         {"rna_cloth.c", RNA_def_cloth},
1419         {"rna_color.c", RNA_def_color},
1420         {"rna_constraint.c", RNA_def_constraint},
1421         {"rna_context.c", RNA_def_context},
1422         {"rna_controller.c", RNA_def_controller},
1423         {"rna_curve.c", RNA_def_curve},
1424         {"rna_fluidsim.c", RNA_def_fluidsim},
1425         {"rna_group.c", RNA_def_group},
1426         {"rna_image.c", RNA_def_image},
1427         {"rna_key.c", RNA_def_key},
1428         {"rna_lamp.c", RNA_def_lamp},
1429         {"rna_lattice.c", RNA_def_lattice},
1430         {"rna_main.c", RNA_def_main},
1431         {"rna_material.c", RNA_def_material},
1432         {"rna_mesh.c", RNA_def_mesh},
1433         {"rna_meta.c", RNA_def_meta},
1434         {"rna_modifier.c", RNA_def_modifier},
1435         {"rna_nodetree.c", RNA_def_nodetree},
1436         {"rna_object.c", RNA_def_object},
1437         {"rna_object_force.c", RNA_def_object_force},
1438         {"rna_packedfile.c", RNA_def_packedfile},
1439         {"rna_particle.c", RNA_def_particle},
1440         {"rna_pose.c", RNA_def_pose},
1441         {"rna_property.c", RNA_def_gameproperty},
1442         {"rna_radio.c", RNA_def_radio},
1443         {"rna_scene.c", RNA_def_scene},
1444         {"rna_screen.c", RNA_def_screen},
1445         {"rna_scriptlink.c", RNA_def_scriptlink},
1446         {"rna_sensor.c", RNA_def_sensor},
1447         {"rna_sequence.c", RNA_def_sequence},
1448         {"rna_space.c", RNA_def_space},
1449         {"rna_text.c", RNA_def_text},
1450         {"rna_timeline.c", RNA_def_timeline_marker},
1451         {"rna_sound.c", RNA_def_sound},
1452         {"rna_userdef.c", RNA_def_userdef},
1453         {"rna_vfont.c", RNA_def_vfont},
1454         {"rna_vpaint.c", RNA_def_vpaint},
1455         {"rna_wm.c", RNA_def_wm},
1456         {"rna_world.c", RNA_def_world}, 
1457         {NULL, NULL}};
1458
1459 static void rna_generate(BlenderRNA *brna, FILE *f, char *filename)
1460 {
1461         StructDefRNA *ds;
1462         PropertyDefRNA *dp;
1463         
1464         fprintf(f, "\n/* Automatically generated struct definitions for the Data API.\n"
1465                      "   Do not edit manually, changes will be overwritten.           */\n\n"
1466                       "#define RNA_RUNTIME\n\n");
1467
1468         fprintf(f, "#include <float.h>\n");
1469         fprintf(f, "#include <limits.h>\n");
1470         fprintf(f, "#include <string.h>\n\n");
1471
1472         fprintf(f, "#include \"BLI_blenlib.h\"\n\n");
1473
1474         fprintf(f, "#include \"BKE_utildefines.h\"\n\n");
1475
1476         fprintf(f, "#include \"RNA_define.h\"\n");
1477         fprintf(f, "#include \"RNA_types.h\"\n");
1478         fprintf(f, "#include \"rna_internal.h\"\n\n");
1479
1480         rna_generate_prototypes(brna, f);
1481
1482         fprintf(f, "#include \"%s\"\n\n", filename);
1483
1484         fprintf(f, "/* Autogenerated Functions */\n\n");
1485
1486         for(ds=DefRNA.structs.first; ds; ds=ds->next)
1487                 if(!filename || ds->filename == filename)
1488                         rna_generate_property_prototypes(brna, ds->srna, f);
1489
1490         for(ds=DefRNA.structs.first; ds; ds=ds->next)
1491                 if(!filename || ds->filename == filename)
1492                         for(dp=ds->properties.first; dp; dp=dp->next)
1493                                 rna_def_property_funcs(f, dp);
1494
1495         for(ds=DefRNA.structs.first; ds; ds=ds->next)
1496                 if(!filename || ds->filename == filename)
1497                         rna_generate_struct(brna, ds->srna, f);
1498
1499         if(strcmp(filename, "rna_ID.c") == 0) {
1500                 /* this is ugly, but we cannot have c files compiled for both
1501                  * makesrna and blender with some build systems at the moment */
1502                 fprintf(f, "#include \"rna_define.c\"\n\n");
1503
1504                 rna_generate_blender(brna, f);
1505         }
1506 }
1507
1508 static void rna_generate_header(BlenderRNA *brna, FILE *f)
1509 {
1510         StructDefRNA *ds;
1511         PropertyDefRNA *dp;
1512         StructRNA *srna;
1513
1514         fprintf(f, "\n#ifndef __RNA_BLENDER_H__\n");
1515         fprintf(f, "#define __RNA_BLENDER_H__\n\n");
1516
1517         fprintf(f, "/* Automatically generated function declarations for the Data API.\n"
1518                      "   Do not edit manually, changes will be overwritten.              */\n\n");
1519
1520         fprintf(f, "#include \"RNA_types.h\"\n\n");
1521
1522         fprintf(f, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n");
1523
1524         fprintf(f, "#define FOREACH_BEGIN(property, sptr, itemptr) \\\n");
1525         fprintf(f, "    { \\\n");
1526         fprintf(f, "            CollectionPropertyIterator rna_macro_iter; \\\n");
1527         fprintf(f, "            for(property##_begin(&rna_macro_iter, sptr); rna_macro_iter.valid; property##_next(&rna_macro_iter)) { \\\n");
1528         fprintf(f, "                    itemptr= rna_macro_iter.ptr;\n\n");
1529
1530         fprintf(f, "#define FOREACH_END(property) \\\n");
1531         fprintf(f, "            } \\\n");
1532         fprintf(f, "            property##_end(&rna_macro_iter); \\\n");
1533         fprintf(f, "    }\n\n");
1534
1535         for(ds=DefRNA.structs.first; ds; ds=ds->next) {
1536                 srna= ds->srna;
1537
1538                 fprintf(f, "/**************** %s ****************/\n\n", srna->name);
1539
1540                 while(srna) {
1541                         fprintf(f, "extern StructRNA RNA_%s;\n", srna->identifier);
1542                         srna= srna->base;
1543                 }
1544                 fprintf(f, "\n");
1545
1546                 for(dp=ds->properties.first; dp; dp=dp->next)
1547                         rna_def_property_funcs_header(f, dp);
1548         }
1549
1550         fprintf(f, "#ifdef __cplusplus\n}\n#endif\n\n");
1551
1552         fprintf(f, "#endif /* __RNA_BLENDER_H__ */\n\n");
1553 }
1554
1555 static const char *cpp_classes = ""
1556 "\n"
1557 "#include <string>\n"
1558 "\n"
1559 "namespace RNA {\n"
1560 "\n"
1561 "#define BOOLEAN_PROPERTY(sname, identifier) \\\n"
1562 "       bool sname::identifier(void) { return (bool)sname##_##identifier##_get(&ptr); }\n"
1563 "\n"
1564 "#define BOOLEAN_ARRAY_PROPERTY(sname, size, identifier) \\\n"
1565 "       Array<int,size> sname::identifier(void) \\\n"
1566 "               { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n"
1567 "\n"
1568 "#define INT_PROPERTY(sname, identifier) \\\n"
1569 "       int sname::identifier(void) { return sname##_##identifier##_get(&ptr); }\n"
1570 "\n"
1571 "#define INT_ARRAY_PROPERTY(sname, size, identifier) \\\n"
1572 "       Array<int,size> sname::identifier(void) \\\n"
1573 "               { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n"
1574 "\n"
1575 "#define FLOAT_PROPERTY(sname, identifier) \\\n"
1576 "       float sname::identifier(void) { return sname##_##identifier##_get(&ptr); }\n"
1577 "\n"
1578 "#define FLOAT_ARRAY_PROPERTY(sname, size, identifier) \\\n"
1579 "       Array<float,size> sname::identifier(void) \\\n"
1580 "               { Array<float, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n"
1581 "\n"
1582 "#define ENUM_PROPERTY(type, sname, identifier) \\\n"
1583 "       sname::type sname::identifier(void) { return (type)sname##_##identifier##_get(&ptr); }\n"
1584 "\n"
1585 "#define STRING_PROPERTY(sname, identifier) \\\n"
1586 "       std::string sname::identifier(void) { \\\n"
1587 "               int len= sname##_##identifier##_length(&ptr); \\\n"
1588 "               std::string str; str.resize(len); \\\n"
1589 "               sname##_##identifier##_get(&ptr, &str[0]); return str; } \\\n"
1590 "\n"
1591 "#define POINTER_PROPERTY(type, sname, identifier) \\\n"
1592 "       type sname::identifier(void) { return type(sname##_##identifier##_get(&ptr)); }\n"
1593 "\n"
1594 "#define COLLECTION_PROPERTY(type, sname, identifier) \\\n"
1595 "       typedef CollectionIterator<type, sname##_##identifier##_begin, \\\n"
1596 "               sname##_##identifier##_next, sname##_##identifier##_end> identifier##_iterator; \\\n"
1597 "       Collection<sname, type, sname##_##identifier##_begin, \\\n"
1598 "               sname##_##identifier##_next, sname##_##identifier##_end> identifier;\n"
1599 "\n"
1600 "class Pointer {\n"
1601 "public:\n"
1602 "       Pointer(const PointerRNA& p) : ptr(p) { }\n"
1603 "       operator const PointerRNA&() { return ptr; }\n"
1604 "       bool is_a(StructRNA *type) { return RNA_struct_is_a(&ptr, type); }\n"
1605 "       operator void*() { return ptr.data; }\n"
1606 "       operator bool() { return ptr.data != NULL; }\n"
1607 "\n"
1608 "       PointerRNA ptr;\n"
1609 "};\n"
1610 "\n"
1611 "\n"
1612 "template<typename T, int Tsize>\n"
1613 "class Array {\n"
1614 "public:\n"
1615 "       T data[Tsize];\n"
1616 "       operator T*() { return data; }\n"
1617 "};\n"
1618 "\n"
1619 "typedef void (*TBeginFunc)(CollectionPropertyIterator *iter, PointerRNA *ptr);\n"
1620 "typedef void (*TNextFunc)(CollectionPropertyIterator *iter);\n"
1621 "typedef void (*TEndFunc)(CollectionPropertyIterator *iter);\n"
1622 "\n"
1623 "template<typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n"
1624 "class CollectionIterator {\n"
1625 "public:\n"
1626 "       CollectionIterator() : t(iter.ptr), init(false) { iter.valid= false; }\n"
1627 "       ~CollectionIterator(void) { if(init) Tend(&iter); };\n"
1628 "       const CollectionIterator<T, Tbegin, Tnext, Tend>& operator=(const CollectionIterator<T, Tbegin, Tnext, Tend>& copy)\n"
1629 "       { if(init) Tend(&iter); iter= copy.iter; if(iter.internal) iter.internal= MEM_dupallocN(iter.internal); t= copy.t; init= copy.init; return *this; }\n"
1630 "\n"
1631 "       operator bool(void)\n"
1632 "       { return iter.valid != 0; }\n"
1633 "       const CollectionIterator<T, Tbegin, Tnext, Tend>& operator++() { Tnext(&iter); t = T(iter.ptr); return *this; }\n"
1634 "       T& operator*(void) { return t; }\n"
1635 "       T* operator->(void) { return &t; }\n"
1636 "       bool operator==(const CollectionIterator<T, Tbegin, Tnext, Tend>& other) { return iter.valid == other.iter.valid; }\n"
1637 "       bool operator!=(const CollectionIterator<T, Tbegin, Tnext, Tend>& other) { return iter.valid != other.iter.valid; }\n"
1638 "\n"
1639 "       void begin(const Pointer& ptr)\n"
1640 "       { if(init) Tend(&iter); Tbegin(&iter, (PointerRNA*)&ptr.ptr); t = T(iter.ptr); init = true; }\n"
1641 "\n"
1642 "private:\n"
1643 "       CollectionPropertyIterator iter;\n"
1644 "       T t;\n"
1645 "       bool init;\n"
1646 "};\n"
1647 "\n"
1648 "template<typename Tp, typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n"
1649 "class Collection {\n"
1650 "public:\n"
1651 "       Collection(const PointerRNA& p) : ptr(p) {}\n"
1652 "\n"
1653 "       CollectionIterator<T, Tbegin, Tnext, Tend> begin()\n"
1654 "       { CollectionIterator<T, Tbegin, Tnext, Tend> iter; iter.begin(ptr); return iter; }\n"
1655 "       CollectionIterator<T, Tbegin, Tnext, Tend> end()\n"
1656 "       { return CollectionIterator<T, Tbegin, Tnext, Tend>(); } /* test */ \n"
1657 "\n"
1658 "private:\n"
1659 "       PointerRNA ptr;\n"
1660 "};\n"
1661 "\n";
1662
1663 static void rna_generate_header_cpp(BlenderRNA *brna, FILE *f)
1664 {
1665         StructDefRNA *ds;
1666         PropertyDefRNA *dp;
1667         StructRNA *srna;
1668
1669         fprintf(f, "\n#ifndef __RNA_BLENDER_CPP_H__\n");
1670         fprintf(f, "#define __RNA_BLENDER_CPP_H__\n\n");
1671
1672         fprintf(f, "/* Automatically generated classes for the Data API.\n"
1673                      "   Do not edit manually, changes will be overwritten. */\n\n");
1674
1675         fprintf(f, "#include \"RNA_blender.h\"\n");
1676         fprintf(f, "#include \"RNA_types.h\"\n");
1677
1678         fprintf(f, cpp_classes);
1679
1680         fprintf(f, "/**************** Declarations ****************/\n\n");
1681
1682         for(ds=DefRNA.structs.first; ds; ds=ds->next)
1683                 fprintf(f, "class %s;\n", ds->srna->identifier);
1684         fprintf(f, "\n");
1685
1686         for(ds=DefRNA.structs.first; ds; ds=ds->next) {
1687                 srna= ds->srna;
1688
1689                 fprintf(f, "/**************** %s ****************/\n\n", srna->name);
1690
1691                 fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base)? srna->base->identifier: "Pointer");
1692                 fprintf(f, "public:\n");
1693                 fprintf(f, "\t%s(const PointerRNA& ptr) :\n\t\t%s(ptr)", srna->identifier, (srna->base)? srna->base->identifier: "Pointer");
1694                 for(dp=ds->properties.first; dp; dp=dp->next)
1695                         if(!(dp->prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN)))
1696                                 if(dp->prop->type == PROP_COLLECTION)
1697                                         fprintf(f, ",\n\t\t%s(ptr)", dp->prop->identifier);
1698                 fprintf(f, "\n\t\t{}\n\n");
1699
1700                 for(dp=ds->properties.first; dp; dp=dp->next)
1701                         rna_def_property_funcs_header_cpp(f, dp);
1702                 fprintf(f, "};\n\n");
1703         }
1704
1705
1706         fprintf(f, "/**************** Implementation ****************/\n");
1707
1708         for(ds=DefRNA.structs.first; ds; ds=ds->next) {
1709                 for(dp=ds->properties.first; dp; dp=dp->next)
1710                         rna_def_property_funcs_impl_cpp(f, dp);
1711
1712                 fprintf(f, "\n");
1713         }
1714
1715         fprintf(f, "}\n\n#endif /* __RNA_BLENDER_CPP_H__ */\n\n");
1716 }
1717
1718 static void make_bad_file(char *file)
1719 {
1720         FILE *fp= fopen(file, "w");
1721         fprintf(fp, "ERROR! Cannot make correct RNA file, STUPID!\n");
1722         fclose(fp);
1723 }
1724
1725 static int rna_preprocess(char *outfile)
1726 {
1727         BlenderRNA *brna;
1728         StructDefRNA *ds;
1729         FILE *file;
1730         char deffile[4096];
1731         int i, status;
1732
1733         /* define rna */
1734         brna= RNA_create();
1735
1736         for(i=0; PROCESS_ITEMS[i].filename; i++) {
1737                 if(PROCESS_ITEMS[i].define) {
1738                         PROCESS_ITEMS[i].define(brna);
1739
1740                         for(ds=DefRNA.structs.first; ds; ds=ds->next)
1741                                 if(!ds->filename)
1742                                         ds->filename= PROCESS_ITEMS[i].filename;
1743                 }
1744         }
1745
1746         rna_auto_types();
1747
1748
1749         /* create RNA_blender_cpp.h */
1750         strcpy(deffile, outfile);
1751         strcat(deffile, "RNA_blender_cpp.h");
1752
1753         status= (DefRNA.error != 0);
1754
1755         if(status) {
1756                 make_bad_file(deffile);
1757         }
1758         else {
1759                 file = fopen(deffile, "w");
1760
1761                 if(!file) {
1762                         printf ("Unable to open file: %s\n", deffile);
1763                         status = 1;
1764                 }
1765                 else {
1766                         rna_generate_header_cpp(brna, file);
1767                         fclose(file);
1768
1769                         status= (DefRNA.error != 0);
1770                 }
1771         }
1772
1773         rna_sort(brna);
1774
1775         /* create rna_gen_*.c files */
1776         for(i=0; PROCESS_ITEMS[i].filename; i++) {
1777                 strcpy(deffile, outfile);
1778                 strcat(deffile, PROCESS_ITEMS[i].filename);
1779                 deffile[strlen(deffile)-2] = '\0';
1780                 strcat(deffile, "_gen.c");
1781
1782                 if(status) {
1783                         make_bad_file(deffile);
1784                 }
1785                 else {
1786                         file = fopen(deffile, "w");
1787
1788                         if(!file) {
1789                                 printf ("Unable to open file: %s\n", deffile);
1790                                 status = 1;
1791                         }
1792                         else {
1793                                 rna_generate(brna, file, PROCESS_ITEMS[i].filename);
1794                                 fclose(file);
1795
1796                                 status= (DefRNA.error != 0);
1797                         }
1798                 }
1799         }
1800
1801         /* create RNA_blender.h */
1802         strcpy(deffile, outfile);
1803         strcat(deffile, "RNA_blender.h");
1804
1805         if(status) {
1806                 make_bad_file(deffile);
1807         }
1808         else {
1809                 file = fopen(deffile, "w");
1810
1811                 if(!file) {
1812                         printf ("Unable to open file: %s\n", deffile);
1813                         status = 1;
1814                 }
1815                 else {
1816                         rna_generate_header(brna, file);
1817                         fclose(file);
1818
1819                         status= (DefRNA.error != 0);
1820                 }
1821         }
1822
1823         /* free RNA */
1824         RNA_define_free(brna);
1825         RNA_free(brna);
1826
1827         return status;
1828 }
1829
1830 int main(int argc, char **argv)
1831 {
1832         int totblock, return_status = 0;
1833
1834         if (argc<2) {
1835                 printf("Usage: %s outdirectory/\n", argv[0]);
1836                 return_status = 1;
1837         }
1838         else {
1839                 printf("Running makesrna, program versions %s\n",  RNA_VERSION_DATE);
1840                 return_status= rna_preprocess(argv[1]);
1841         }
1842
1843         totblock= MEM_get_memory_blocks_in_use();
1844         if(totblock!=0) {
1845                 printf("Error Totblock: %d\n",totblock);
1846                 MEM_printmemlist();
1847         }
1848
1849         return return_status;
1850 }
1851
1852