Blender  V2.59
makesrna.c
Go to the documentation of this file.
00001 /*
00002  * $Id: makesrna.c 37749 2011-06-23 07:50:28Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * Contributor(s): Blender Foundation (2008).
00021  *
00022  * ***** END GPL LICENSE BLOCK *****
00023  */
00024 
00030 #include <float.h>
00031 #include <limits.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <errno.h>
00036 
00037 #include "MEM_guardedalloc.h"
00038 
00039 #include "RNA_access.h"
00040 #include "RNA_define.h"
00041 #include "RNA_types.h"
00042 
00043 #include "rna_internal.h"
00044 
00045 #define RNA_VERSION_DATE "$Id: makesrna.c 37749 2011-06-23 07:50:28Z campbellbarton $"
00046 
00047 #ifdef _WIN32
00048 #ifndef snprintf
00049 #define snprintf _snprintf
00050 #endif
00051 #endif
00052 
00053 /* Replace if different */
00054 #define TMP_EXT ".tmp"
00055 
00056 
00057 /* copied from BLI_file_older */
00058 #include <sys/stat.h>
00059 static int file_older(const char *file1, const char *file2)
00060 {
00061         struct stat st1, st2;
00062         // printf("compare: %s %s\n", file1, file2);
00063 
00064         if(stat(file1, &st1)) return 0;
00065         if(stat(file2, &st2)) return 0;
00066 
00067         return (st1.st_mtime < st2.st_mtime);
00068 }
00069 const char *makesrna_path= NULL;
00070 
00071 static int replace_if_different(char *tmpfile, const char *dep_files[])
00072 {
00073         // return 0; // use for testing had edited rna
00074 
00075 #define REN_IF_DIFF \
00076         { \
00077                 FILE *file_test= fopen(orgfile, "rb"); \
00078                 if(file_test) { \
00079                         fclose(file_test); \
00080                         if(fp_org) fclose(fp_org); \
00081                         if(fp_new) fclose(fp_new); \
00082                         if(remove(orgfile) != 0) { \
00083                                 fprintf(stderr, "%s:%d, Remove Error (%s): \"%s\"\n", __FILE__, __LINE__, strerror(errno), orgfile); \
00084                                 return -1; \
00085                         } \
00086                 } \
00087         } \
00088         if(rename(tmpfile, orgfile) != 0) { \
00089                 fprintf(stderr, "%s:%d, Rename Error (%s): \"%s\" -> \"%s\"\n", __FILE__, __LINE__, strerror(errno), tmpfile, orgfile); \
00090                 return -1; \
00091         } \
00092         remove(tmpfile); \
00093         return 1; \
00094 /* end REN_IF_DIFF */
00095 
00096 
00097         FILE *fp_new= NULL, *fp_org= NULL;
00098         int len_new, len_org;
00099         char *arr_new, *arr_org;
00100         int cmp;
00101 
00102         char orgfile[4096];
00103 
00104         strcpy(orgfile, tmpfile);
00105         orgfile[strlen(orgfile) - strlen(TMP_EXT)] = '\0'; /* strip '.tmp' */
00106 
00107         fp_org= fopen(orgfile, "rb");
00108 
00109         if(fp_org==NULL) {
00110                 REN_IF_DIFF;
00111         }
00112 
00113 
00114         /* XXX, trick to work around dependancy problem
00115          * assumes dep_files is in the same dir as makesrna.c, which is true for now. */
00116 
00117         if(1) {
00118                 /* first check if makesrna.c is newer then generated files
00119                  * for development on makesrna.c you may want to disable this */
00120                 if(file_older(orgfile, __FILE__)) {
00121                         REN_IF_DIFF;
00122                 }
00123 
00124                 if(file_older(orgfile, makesrna_path)) {
00125                         REN_IF_DIFF;
00126                 }
00127 
00128                 /* now check if any files we depend on are newer then any generated files */
00129                 if(dep_files) {
00130                         int pass;
00131                         for(pass=0; dep_files[pass]; pass++) {
00132                                 char from_path[4096]= __FILE__;
00133                                 char *p1, *p2;
00134 
00135                                 /* dir only */
00136                                 p1= strrchr(from_path, '/');
00137                                 p2= strrchr(from_path, '\\');
00138                                 strcpy((p1 > p2 ? p1 : p2)+1, dep_files[pass]);
00139                                 /* account for build deps, if makesrna.c (this file) is newer */
00140                                 if(file_older(orgfile, from_path)) {
00141                                         REN_IF_DIFF;
00142                                 }
00143                         }
00144                 }
00145         }
00146         /* XXX end dep trick */
00147 
00148 
00149         fp_new= fopen(tmpfile, "rb");
00150 
00151         if(fp_new==NULL) {
00152                 /* shouldn't happen, just to be safe */
00153                 fprintf(stderr, "%s:%d, open error: \"%s\"\n", __FILE__, __LINE__, tmpfile);
00154                 fclose(fp_org);
00155                 return -1;
00156         }
00157 
00158         fseek(fp_new, 0L, SEEK_END); len_new = ftell(fp_new); fseek(fp_new, 0L, SEEK_SET);
00159         fseek(fp_org, 0L, SEEK_END); len_org = ftell(fp_org); fseek(fp_org, 0L, SEEK_SET);
00160 
00161 
00162         if(len_new != len_org) {
00163                 fclose(fp_new);
00164                 fclose(fp_org);
00165                 REN_IF_DIFF;
00166         }
00167 
00168         /* now compare the files... */
00169         arr_new= MEM_mallocN(sizeof(char)*len_new, "rna_cmp_file_new");
00170         arr_org= MEM_mallocN(sizeof(char)*len_org, "rna_cmp_file_org");
00171 
00172         if(fread(arr_new, sizeof(char), len_new, fp_new) != len_new)
00173                 fprintf(stderr, "%s:%d, error reading file %s for comparison.\n", __FILE__, __LINE__, tmpfile);
00174         if(fread(arr_org, sizeof(char), len_org, fp_org) != len_org)
00175                 fprintf(stderr, "%s:%d, error reading file %s for comparison.\n", __FILE__, __LINE__, orgfile);
00176 
00177         fclose(fp_new);
00178         fclose(fp_org);
00179 
00180         cmp= memcmp(arr_new, arr_org, len_new);
00181 
00182         MEM_freeN(arr_new);
00183         MEM_freeN(arr_org);
00184 
00185         if(cmp) {
00186                 REN_IF_DIFF;
00187         }
00188         else {
00189                 remove(tmpfile);
00190                 return 0;
00191         }
00192 
00193 #undef REN_IF_DIFF
00194 }
00195 
00196 /* Helper to solve keyword problems with C/C++ */
00197 
00198 static const char *rna_safe_id(const char *id)
00199 {
00200         if(strcmp(id, "default") == 0)
00201                 return "default_value";
00202         else if(strcmp(id, "operator") == 0)
00203                 return "operator_value";
00204 
00205         return id;
00206 }
00207 
00208 /* Sorting */
00209 
00210 static int cmp_struct(const void *a, const void *b)
00211 {
00212         const StructRNA *structa= *(const StructRNA**)a;
00213         const StructRNA *structb= *(const StructRNA**)b;
00214 
00215         return strcmp(structa->identifier, structb->identifier);
00216 }
00217 
00218 static int cmp_property(const void *a, const void *b)
00219 {
00220         const PropertyRNA *propa= *(const PropertyRNA**)a;
00221         const PropertyRNA *propb= *(const PropertyRNA**)b;
00222 
00223         if(strcmp(propa->identifier, "rna_type") == 0) return -1;
00224         else if(strcmp(propb->identifier, "rna_type") == 0) return 1;
00225 
00226         if(strcmp(propa->identifier, "name") == 0) return -1;
00227         else if(strcmp(propb->identifier, "name") == 0) return 1;
00228 
00229         return strcmp(propa->name, propb->name);
00230 }
00231 
00232 static int cmp_def_struct(const void *a, const void *b)
00233 {
00234         const StructDefRNA *dsa= *(const StructDefRNA**)a;
00235         const StructDefRNA *dsb= *(const StructDefRNA**)b;
00236 
00237         return cmp_struct(&dsa->srna, &dsb->srna);
00238 }
00239 
00240 static int cmp_def_property(const void *a, const void *b)
00241 {
00242         const PropertyDefRNA *dpa= *(const PropertyDefRNA**)a;
00243         const PropertyDefRNA *dpb= *(const PropertyDefRNA**)b;
00244 
00245         return cmp_property(&dpa->prop, &dpb->prop);
00246 }
00247 
00248 static void rna_sortlist(ListBase *listbase, int(*cmp)(const void*, const void*))
00249 {
00250         Link *link;
00251         void **array;
00252         int a, size;
00253         
00254         if(listbase->first == listbase->last)
00255                 return;
00256 
00257         for(size=0, link=listbase->first; link; link=link->next)
00258                 size++;
00259 
00260         array= MEM_mallocN(sizeof(void*)*size, "rna_sortlist");
00261         for(a=0, link=listbase->first; link; link=link->next, a++)
00262                 array[a]= link;
00263 
00264         qsort(array, size, sizeof(void*), cmp);
00265 
00266         listbase->first= listbase->last= NULL;
00267         for(a=0; a<size; a++) {
00268                 link= array[a];
00269                 link->next= link->prev= NULL;
00270                 rna_addtail(listbase, link);
00271         }
00272 
00273         MEM_freeN(array);
00274 }
00275 
00276 /* Preprocessing */
00277 
00278 static void rna_print_c_string(FILE *f, const char *str)
00279 {
00280         static const char *escape[] = {"\''", "\"\"", "\??", "\\\\","\aa", "\bb", "\ff", "\nn", "\rr", "\tt", "\vv", NULL};
00281         int i, j;
00282 
00283         if(!str) {
00284                 fprintf(f, "NULL");
00285                 return;
00286         }
00287 
00288         fprintf(f, "\"");
00289         for(i=0; str[i]; i++) {
00290                 for(j=0; escape[j]; j++)
00291                         if(str[i] == escape[j][0])
00292                                 break;
00293 
00294                 if(escape[j]) fprintf(f, "\\%c", escape[j][1]);
00295                 else fprintf(f, "%c", str[i]);
00296         }
00297         fprintf(f, "\"");
00298 }
00299 
00300 static void rna_print_data_get(FILE *f, PropertyDefRNA *dp)
00301 {
00302         if(dp->dnastructfromname && dp->dnastructfromprop)
00303                 fprintf(f, "    %s *data= (%s*)(((%s*)ptr->data)->%s);\n", dp->dnastructname, dp->dnastructname, dp->dnastructfromname, dp->dnastructfromprop);
00304         else
00305                 fprintf(f, "    %s *data= (%s*)(ptr->data);\n", dp->dnastructname, dp->dnastructname);
00306 }
00307 
00308 static void rna_print_id_get(FILE *f, PropertyDefRNA *dp)
00309 {
00310         fprintf(f, "    ID *id= ptr->id.data;\n");
00311 }
00312 
00313 static char *rna_alloc_function_name(const char *structname, const char *propname, const char *type)
00314 {
00315         AllocDefRNA *alloc;
00316         char buffer[2048];
00317         char *result;
00318 
00319         snprintf(buffer, sizeof(buffer), "%s_%s_%s", structname, propname, type);
00320         result= MEM_callocN(sizeof(char)*strlen(buffer)+1, "rna_alloc_function_name");
00321         strcpy(result, buffer);
00322 
00323         alloc= MEM_callocN(sizeof(AllocDefRNA), "AllocDefRNA");
00324         alloc->mem= result;
00325         rna_addtail(&DefRNA.allocs, alloc);
00326 
00327         return result;
00328 }
00329 
00330 static StructRNA *rna_find_struct(const char *identifier)
00331 {
00332         StructDefRNA *ds;
00333 
00334         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next)
00335                 if(strcmp(ds->srna->identifier, identifier)==0)
00336                         return ds->srna;
00337 
00338         return NULL;
00339 }
00340 
00341 static const char *rna_find_type(const char *type)
00342 {
00343         StructDefRNA *ds;
00344 
00345         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next)
00346                 if(ds->dnaname && strcmp(ds->dnaname, type)==0)
00347                         return ds->srna->identifier;
00348 
00349         return NULL;
00350 }
00351 
00352 static const char *rna_find_dna_type(const char *type)
00353 {
00354         StructDefRNA *ds;
00355 
00356         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next)
00357                 if(strcmp(ds->srna->identifier, type)==0)
00358                         return ds->dnaname;
00359 
00360         return NULL;
00361 }
00362 
00363 static const char *rna_type_type_name(PropertyRNA *prop)
00364 {
00365         switch(prop->type) {
00366                 case PROP_BOOLEAN:
00367                 case PROP_INT:
00368                 case PROP_ENUM:
00369                         return "int";
00370                 case PROP_FLOAT:
00371                         return "float";
00372                 case PROP_STRING:
00373                         if(prop->flag & PROP_THICK_WRAP) {
00374                                 return "char*";
00375                         }
00376                         else {
00377                                 return "const char*";
00378                         }
00379                 default:
00380                         return NULL;
00381         }
00382 }
00383 
00384 static const char *rna_type_type(PropertyRNA *prop)
00385 {
00386         const char *type;
00387 
00388         type= rna_type_type_name(prop);
00389 
00390         if(type)
00391                 return type;
00392 
00393         return "PointerRNA";
00394 }
00395 
00396 static const char *rna_type_struct(PropertyRNA *prop)
00397 {
00398         const char *type;
00399 
00400         type= rna_type_type_name(prop);
00401 
00402         if(type)
00403                 return "";
00404 
00405         return "struct ";
00406 }
00407 
00408 static const char *rna_parameter_type_name(PropertyRNA *parm)
00409 {
00410         const char *type;
00411 
00412         type= rna_type_type_name(parm);
00413 
00414         if(type)
00415                 return type;
00416 
00417         switch(parm->type) {
00418                 case PROP_POINTER:  {
00419                         PointerPropertyRNA *pparm= (PointerPropertyRNA*)parm;
00420 
00421                         if(parm->flag & PROP_RNAPTR)
00422                                 return "PointerRNA";
00423                         else
00424                                 return rna_find_dna_type((const char *)pparm->type);
00425                 }
00426                 case PROP_COLLECTION: {
00427                         return "ListBase";
00428                 }
00429                 default:
00430                         return "<error, no type specified>";
00431         }
00432 }
00433 
00434 static int rna_enum_bitmask(PropertyRNA *prop)
00435 {
00436         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
00437         int a, mask= 0;
00438 
00439         if(eprop->item) {
00440                 for(a=0; a<eprop->totitem; a++)
00441                         if(eprop->item[a].identifier[0])
00442                                 mask |= eprop->item[a].value;
00443         }
00444         
00445         return mask;
00446 }
00447 
00448 static int rna_color_quantize(PropertyRNA *prop, PropertyDefRNA *dp)
00449 {
00450         if(prop->type == PROP_FLOAT && (prop->subtype==PROP_COLOR || prop->subtype==PROP_COLOR_GAMMA))
00451                 if(strcmp(dp->dnatype, "float") != 0 && strcmp(dp->dnatype, "double") != 0)
00452                         return 1;
00453         
00454         return 0;
00455 }
00456 
00457 static const char *rna_function_string(void *func)
00458 {
00459         return (func)? (const char*)func: "NULL";
00460 }
00461 
00462 static void rna_float_print(FILE *f, float num)
00463 {
00464         if(num == -FLT_MAX) fprintf(f, "-FLT_MAX");
00465         else if(num == FLT_MAX) fprintf(f, "FLT_MAX");
00466         else if((int)num == num) fprintf(f, "%.1ff", num);
00467         else fprintf(f, "%.10ff", num);
00468 }
00469 
00470 static void rna_int_print(FILE *f, int num)
00471 {
00472         if(num == INT_MIN) fprintf(f, "INT_MIN");
00473         else if(num == INT_MAX) fprintf(f, "INT_MAX");
00474         else fprintf(f, "%d", num);
00475 }
00476 
00477 static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, const char *manualfunc)
00478 {
00479         char *func;
00480 
00481         if(prop->flag & PROP_IDPROPERTY && manualfunc==NULL)
00482                 return NULL;
00483 
00484         if(!manualfunc) {
00485                 if(!dp->dnastructname || !dp->dnaname) {
00486                         fprintf(stderr, "rna_def_property_get_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
00487                         DefRNA.error= 1;
00488                         return NULL;
00489                 }
00490 
00491                 /* typecheck,  */
00492                 if(dp->dnatype && *dp->dnatype) {
00493 
00494                         if(prop->type == PROP_FLOAT) {
00495                                 if(IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) {
00496                                         if(prop->subtype != PROP_COLOR_GAMMA) { /* colors are an exception. these get translated */
00497                                                 fprintf(stderr, "rna_def_property_get_func1: %s.%s is a '%s' but wrapped as type '%s'.\n", srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
00498                                                 DefRNA.error= 1;
00499                                                 return NULL;
00500                                         }
00501                                 }
00502                         }
00503                         else if(prop->type == PROP_INT || prop->type == PROP_BOOLEAN || prop->type == PROP_ENUM) {
00504                                 if(IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
00505                                         fprintf(stderr, "rna_def_property_get_func2: %s.%s is a '%s' but wrapped as type '%s'.\n", srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
00506                                         DefRNA.error= 1;
00507                                         return NULL;
00508                                 }
00509                         }
00510                 }
00511 
00512         }
00513 
00514         func= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get");
00515 
00516         switch(prop->type) {
00517                 case PROP_STRING: {
00518                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
00519                         fprintf(f, "void %s(PointerRNA *ptr, char *value)\n", func);
00520                         fprintf(f, "{\n");
00521                         if(manualfunc) {
00522                                 fprintf(f, "    %s(ptr, value);\n", manualfunc);
00523                         }
00524                         else {
00525                                 rna_print_data_get(f, dp);
00526                                 if(sprop->maxlength)
00527                                         fprintf(f, "    BLI_strncpy(value, data->%s, %d);\n", dp->dnaname, sprop->maxlength);
00528                                 else
00529                                         fprintf(f, "    BLI_strncpy(value, data->%s, sizeof(data->%s));\n", dp->dnaname, dp->dnaname);
00530                         }
00531                         fprintf(f, "}\n\n");
00532                         break;
00533                 }
00534                 case PROP_POINTER: {
00535                         fprintf(f, "PointerRNA %s(PointerRNA *ptr)\n", func);
00536                         fprintf(f, "{\n");
00537                         if(manualfunc) {
00538                                 fprintf(f, "    return %s(ptr);\n", manualfunc);
00539                         }
00540                         else {
00541                                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
00542                                 rna_print_data_get(f, dp);
00543                                 if(dp->dnapointerlevel == 0)
00544                                         fprintf(f, "    return rna_pointer_inherit_refine(ptr, &RNA_%s, &data->%s);\n", (char*)pprop->type, dp->dnaname);
00545                                 else
00546                                         fprintf(f, "    return rna_pointer_inherit_refine(ptr, &RNA_%s, data->%s);\n", (char*)pprop->type, dp->dnaname);
00547                         }
00548                         fprintf(f, "}\n\n");
00549                         break;
00550                 }
00551                 case PROP_COLLECTION: {
00552                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
00553 
00554                         fprintf(f, "static PointerRNA %s(CollectionPropertyIterator *iter)\n", func);
00555                         fprintf(f, "{\n");
00556                         if(manualfunc) {
00557                                 if(strcmp(manualfunc, "rna_iterator_listbase_get") == 0 ||
00558                                    strcmp(manualfunc, "rna_iterator_array_get") == 0 ||
00559                                    strcmp(manualfunc, "rna_iterator_array_dereference_get") == 0)
00560                                         fprintf(f, "    return rna_pointer_inherit_refine(&iter->parent, &RNA_%s, %s(iter));\n", (cprop->item_type)? (char*)cprop->item_type: "UnknownType", manualfunc);
00561                                 else
00562                                         fprintf(f, "    return %s(iter);\n", manualfunc);
00563                         }
00564                         fprintf(f, "}\n\n");
00565                         break;
00566                 }
00567                 default:
00568                         if(prop->arraydimension) {
00569                                 if(prop->flag & PROP_DYNAMIC)
00570                                         fprintf(f, "void %s(PointerRNA *ptr, %s values[])\n", func, rna_type_type(prop));
00571                                 else
00572                                         fprintf(f, "void %s(PointerRNA *ptr, %s values[%d])\n", func, rna_type_type(prop), prop->totarraylength);
00573                                 fprintf(f, "{\n");
00574 
00575                                 if(manualfunc) {
00576                                         fprintf(f, "    %s(ptr, values);\n", manualfunc);
00577                                 }
00578                                 else {
00579                                         rna_print_data_get(f, dp);
00580 
00581                                         if(prop->flag & PROP_DYNAMIC) {
00582                                                 char *lenfunc= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get_length");
00583                                                 fprintf(f, "    int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n");
00584                                                 fprintf(f, "    int len= %s(ptr, arraylen);\n\n", lenfunc);
00585                                                 fprintf(f, "    for(i=0; i<len; i++) {\n");
00586                                                 MEM_freeN(lenfunc);
00587                                         }
00588                                         else {
00589                                                 fprintf(f, "    int i;\n\n");
00590                                                 fprintf(f, "    for(i=0; i<%d; i++) {\n", prop->totarraylength);
00591                                         }
00592 
00593                                         if(dp->dnaarraylength == 1) {
00594                                                 if(prop->type == PROP_BOOLEAN && dp->booleanbit)
00595                                                         fprintf(f, "            values[i]= %s((data->%s & (%d<<i)) != 0);\n", (dp->booleannegative)? "!": "", dp->dnaname, dp->booleanbit);
00596                                                 else
00597                                                         fprintf(f, "            values[i]= (%s)%s((&data->%s)[i]);\n", rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnaname);
00598                                         }
00599                                         else {
00600                                                 if(prop->type == PROP_BOOLEAN && dp->booleanbit) {
00601                                                         fprintf(f, "            values[i]= %s((data->%s[i] & ", (dp->booleannegative)? "!": "", dp->dnaname);
00602                                                         rna_int_print(f, dp->booleanbit);
00603                                                         fprintf(f, ") != 0);\n");
00604                                                 }
00605                                                 else if(rna_color_quantize(prop, dp))
00606                                                         fprintf(f, "            values[i]= (%s)(data->%s[i]*(1.0f/255.0f));\n", rna_type_type(prop), dp->dnaname);
00607                                                 else if(dp->dnatype)
00608                                                         fprintf(f, "            values[i]= (%s)%s(((%s*)data->%s)[i]);\n", rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnatype, dp->dnaname);
00609                                                 else
00610                                                         fprintf(f, "            values[i]= (%s)%s((data->%s)[i]);\n", rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnaname);
00611                                         }
00612                                         fprintf(f, "    }\n");
00613                                 }
00614                                 fprintf(f, "}\n\n");
00615                         }
00616                         else {
00617                                 fprintf(f, "%s %s(PointerRNA *ptr)\n", rna_type_type(prop), func);
00618                                 fprintf(f, "{\n");
00619 
00620                                 if(manualfunc) {
00621                                         fprintf(f, "    return %s(ptr);\n", manualfunc);
00622                                 }
00623                                 else {
00624                                         rna_print_data_get(f, dp);
00625                                         if(prop->type == PROP_BOOLEAN && dp->booleanbit) {
00626                                                 fprintf(f, "    return %s(((data->%s) & ", (dp->booleannegative)? "!": "", dp->dnaname);
00627                                                 rna_int_print(f, dp->booleanbit);
00628                                                 fprintf(f, ") != 0);\n");
00629                                         }
00630                                         else if(prop->type == PROP_ENUM && dp->enumbitflags) {
00631                                                 fprintf(f, "    return ((data->%s) & ", dp->dnaname);
00632                                                 rna_int_print(f, rna_enum_bitmask(prop));
00633                                                 fprintf(f, ");\n");
00634                                         }
00635                                         else
00636                                                 fprintf(f, "    return (%s)%s(data->%s);\n", rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnaname);
00637                                 }
00638 
00639                                 fprintf(f, "}\n\n");
00640                         }
00641                         break;
00642         }
00643 
00644         return func;
00645 }
00646 
00647 /* defined min/max variables to be used by rna_clamp_value() */
00648 static void rna_clamp_value_range(FILE *f, PropertyRNA *prop)
00649 {
00650         if(prop->type == PROP_FLOAT) {
00651                 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
00652                 if(fprop->range) {
00653                         fprintf(f, "    float prop_clamp_min, prop_clamp_max;\n");
00654                         fprintf(f, "    %s(ptr, &prop_clamp_min, &prop_clamp_max);\n", rna_function_string(fprop->range));
00655                 }
00656         }
00657         else if(prop->type == PROP_INT) {
00658                 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
00659                 if(iprop->range) {
00660                         fprintf(f, "    int prop_clamp_min, prop_clamp_max;\n");
00661                         fprintf(f, "    %s(ptr, &prop_clamp_min, &prop_clamp_max);\n", rna_function_string(iprop->range));
00662                 }
00663         }
00664 }
00665 
00666 static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array)
00667 {
00668         if(prop->type == PROP_INT) {
00669                 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
00670 
00671                 if(iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX) {
00672                         if(array) fprintf(f, "CLAMPIS(values[i], ");
00673                         else fprintf(f, "CLAMPIS(value, ");
00674                         if(iprop->range) {
00675                                 fprintf(f, "prop_clamp_min, prop_clamp_max);");
00676                         }
00677                         else {
00678                                 rna_int_print(f, iprop->hardmin); fprintf(f, ", ");
00679                                 rna_int_print(f, iprop->hardmax); fprintf(f, ");\n");
00680                         }
00681                         return;
00682                 }
00683         }
00684         else if(prop->type == PROP_FLOAT) {
00685                 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
00686 
00687                 if(fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX) {
00688                         if(array) fprintf(f, "CLAMPIS(values[i], ");
00689                         else fprintf(f, "CLAMPIS(value, ");
00690                         if(fprop->range) {
00691                                 fprintf(f, "prop_clamp_min, prop_clamp_max);");
00692                         }
00693                         else {
00694                                 rna_float_print(f, fprop->hardmin); fprintf(f, ", ");
00695                                 rna_float_print(f, fprop->hardmax); fprintf(f, ");\n");
00696                         }
00697                         return;
00698                 }
00699         }
00700 
00701         if(array)
00702                 fprintf(f, "values[i];\n");
00703         else
00704                 fprintf(f, "value;\n");
00705 }
00706 
00707 static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc)
00708 {
00709         char *func;
00710 
00711         if(!(prop->flag & PROP_EDITABLE))
00712                 return NULL;
00713         if(prop->flag & PROP_IDPROPERTY && manualfunc==NULL)
00714                 return NULL;
00715 
00716         if(!manualfunc) {
00717                 if(!dp->dnastructname || !dp->dnaname) {
00718                         if(prop->flag & PROP_EDITABLE) {
00719                                 fprintf(stderr, "rna_def_property_set_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
00720                                 DefRNA.error= 1;
00721                         }
00722                         return NULL;
00723                 }
00724         }
00725 
00726         func= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "set");
00727 
00728         switch(prop->type) {
00729                 case PROP_STRING: {
00730                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
00731                         fprintf(f, "void %s(PointerRNA *ptr, const char *value)\n", func);
00732                         fprintf(f, "{\n");
00733                         if(manualfunc) {
00734                                 fprintf(f, "    %s(ptr, value);\n", manualfunc);
00735                         }
00736                         else {
00737                                 rna_print_data_get(f, dp);
00738                                 if(sprop->maxlength)
00739                                         fprintf(f, "    BLI_strncpy(data->%s, value, %d);\n", dp->dnaname, sprop->maxlength);
00740                                 else
00741                                         fprintf(f, "    BLI_strncpy(data->%s, value, sizeof(data->%s));\n", dp->dnaname, dp->dnaname);
00742                         }
00743                         fprintf(f, "}\n\n");
00744                         break;
00745                 }
00746                 case PROP_POINTER: {
00747                         fprintf(f, "void %s(PointerRNA *ptr, PointerRNA value)\n", func);
00748                         fprintf(f, "{\n");
00749                         if(manualfunc) {
00750                                 fprintf(f, "    %s(ptr, value);\n", manualfunc);
00751                         }
00752                         else {
00753                                 rna_print_data_get(f, dp);
00754 
00755                                 if(prop->flag & PROP_ID_SELF_CHECK) {
00756                                         rna_print_id_get(f, dp);
00757                                         fprintf(f, "    if(id==value.data) return;\n\n");
00758                                 }
00759 
00760                                 if(prop->flag & PROP_ID_REFCOUNT) {
00761                                         fprintf(f, "\n  if(data->%s)\n", dp->dnaname);
00762                                         fprintf(f, "            id_us_min((ID*)data->%s);\n", dp->dnaname);
00763                                         fprintf(f, "    if(value.data)\n");
00764                                         fprintf(f, "            id_us_plus((ID*)value.data);\n\n");
00765                                 }
00766                                 else {
00767                                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)dp->prop;
00768                                         StructRNA *type= rna_find_struct((char*)pprop->type);
00769                                         if(type && (type->flag & STRUCT_ID)) {
00770                                                 fprintf(f, "    if(value.data)\n");
00771                                                 fprintf(f, "            id_lib_extern((ID*)value.data);\n\n");
00772                                         }
00773                                 }
00774 
00775                                 fprintf(f, "    data->%s= value.data;\n", dp->dnaname);
00776 
00777                         }
00778                         fprintf(f, "}\n\n");
00779                         break;
00780                 }
00781                 default:
00782                         if(prop->arraydimension) {
00783                                 if(prop->flag & PROP_DYNAMIC)
00784                                         fprintf(f, "void %s(PointerRNA *ptr, const %s values[])\n", func, rna_type_type(prop));
00785                                 else
00786                                         fprintf(f, "void %s(PointerRNA *ptr, const %s values[%d])\n", func, rna_type_type(prop), prop->totarraylength);
00787                                 fprintf(f, "{\n");
00788 
00789                                 if(manualfunc) {
00790                                         fprintf(f, "    %s(ptr, values);\n", manualfunc);
00791                                 }
00792                                 else {
00793                                         rna_print_data_get(f, dp);
00794 
00795                                         if(prop->flag & PROP_DYNAMIC) {
00796                                                 char *lenfunc= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "set_length");
00797                                                 fprintf(f, "    int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n");
00798                                                 fprintf(f, "    int len= %s(ptr, arraylen);\n\n", lenfunc);
00799                                                 rna_clamp_value_range(f, prop);
00800                                                 fprintf(f, "    for(i=0; i<len; i++) {\n");
00801                                                 MEM_freeN(lenfunc);
00802                                         }
00803                                         else {
00804                                                 fprintf(f, "    int i;\n\n");
00805                                                 rna_clamp_value_range(f, prop);
00806                                                 fprintf(f, "    for(i=0; i<%d; i++) {\n", prop->totarraylength);
00807                                         }
00808 
00809                                         if(dp->dnaarraylength == 1) {
00810                                                 if(prop->type == PROP_BOOLEAN && dp->booleanbit) {
00811                                                         fprintf(f, "            if(%svalues[i]) data->%s |= (%d<<i);\n", (dp->booleannegative)? "!": "", dp->dnaname, dp->booleanbit);
00812                                                         fprintf(f, "            else data->%s &= ~(%d<<i);\n", dp->dnaname, dp->booleanbit);
00813                                                 }
00814                                                 else {
00815                                                         fprintf(f, "            (&data->%s)[i]= %s", dp->dnaname, (dp->booleannegative)? "!": "");
00816                                                         rna_clamp_value(f, prop, 1);
00817                                                 }
00818                                         }
00819                                         else {
00820                                                 if(prop->type == PROP_BOOLEAN && dp->booleanbit) {
00821                                                         fprintf(f, "            if(%svalues[i]) data->%s[i] |= ", (dp->booleannegative)? "!": "", dp->dnaname);
00822                                                         rna_int_print(f, dp->booleanbit);
00823                                                         fprintf(f, ";\n");
00824                                                         fprintf(f, "            else data->%s[i] &= ~", dp->dnaname);
00825                                                         rna_int_print(f, dp->booleanbit);
00826                                                         fprintf(f, ";\n");
00827                                                 }
00828                                                 else if(rna_color_quantize(prop, dp)) {
00829                                                         fprintf(f, "            data->%s[i]= FTOCHAR(values[i]);\n", dp->dnaname);
00830                                                 }
00831                                                 else {
00832                                                         if(dp->dnatype)
00833                                                                 fprintf(f, "            ((%s*)data->%s)[i]= %s", dp->dnatype, dp->dnaname, (dp->booleannegative)? "!": "");
00834                                                         else
00835                                                                 fprintf(f, "            (data->%s)[i]= %s", dp->dnaname, (dp->booleannegative)? "!": "");
00836                                                         rna_clamp_value(f, prop, 1);
00837                                                 }
00838                                         }
00839                                         fprintf(f, "    }\n");
00840                                 }
00841                                 fprintf(f, "}\n\n");
00842                         }
00843                         else {
00844                                 fprintf(f, "void %s(PointerRNA *ptr, %s value)\n", func, rna_type_type(prop));
00845                                 fprintf(f, "{\n");
00846 
00847                                 if(manualfunc) {
00848                                         fprintf(f, "    %s(ptr, value);\n", manualfunc);
00849                                 }
00850                                 else {
00851                                         rna_print_data_get(f, dp);
00852                                         if(prop->type == PROP_BOOLEAN && dp->booleanbit) {
00853                                                 fprintf(f, "    if(%svalue) data->%s |= ", (dp->booleannegative)? "!": "", dp->dnaname);
00854                                                 rna_int_print(f, dp->booleanbit);
00855                                                 fprintf(f, ";\n");
00856                                                 fprintf(f, "    else data->%s &= ~", dp->dnaname);
00857                                                 rna_int_print(f, dp->booleanbit);
00858                                                 fprintf(f, ";\n");
00859                                         }
00860                                         else if(prop->type == PROP_ENUM && dp->enumbitflags) {
00861                                                 fprintf(f, "    data->%s &= ~", dp->dnaname);
00862                                                 rna_int_print(f, rna_enum_bitmask(prop));
00863                                                 fprintf(f, ";\n");
00864                                                 fprintf(f, "    data->%s |= value;\n", dp->dnaname);
00865                                         }
00866                                         else {
00867                                                 rna_clamp_value_range(f, prop);
00868                                                 fprintf(f, "    data->%s= %s", dp->dnaname, (dp->booleannegative)? "!": "");
00869                                                 rna_clamp_value(f, prop, 0);
00870                                         }
00871                                 }
00872                                 fprintf(f, "}\n\n");
00873                         }
00874                         break;
00875         }
00876 
00877         return func;
00878 }
00879 
00880 static char *rna_def_property_length_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc)
00881 {
00882         char *func= NULL;
00883 
00884         if(prop->flag & PROP_IDPROPERTY && manualfunc==NULL)
00885                 return NULL;
00886 
00887         if(prop->type == PROP_STRING) {
00888                 if(!manualfunc) {
00889                         if(!dp->dnastructname || !dp->dnaname) {
00890                                 fprintf(stderr, "rna_def_property_length_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
00891                                 DefRNA.error= 1;
00892                                 return NULL;
00893                         }
00894                 }
00895 
00896                 func= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "length");
00897 
00898                 fprintf(f, "int %s(PointerRNA *ptr)\n", func);
00899                 fprintf(f, "{\n");
00900                 if(manualfunc) {
00901                         fprintf(f, "    return %s(ptr);\n", manualfunc);
00902                 }
00903                 else {
00904                         rna_print_data_get(f, dp);
00905                         fprintf(f, "    return strlen(data->%s);\n", dp->dnaname);
00906                 }
00907                 fprintf(f, "}\n\n");
00908         }
00909         else if(prop->type == PROP_COLLECTION) {
00910                 if(!manualfunc) {
00911                         if(prop->type == PROP_COLLECTION && (!(dp->dnalengthname || dp->dnalengthfixed)|| !dp->dnaname)) {
00912                                 fprintf(stderr, "rna_def_property_length_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
00913                                 DefRNA.error= 1;
00914                                 return NULL;
00915                         }
00916                 }
00917 
00918                 func= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "length");
00919 
00920                 fprintf(f, "int %s(PointerRNA *ptr)\n", func);
00921                 fprintf(f, "{\n");
00922                 if(manualfunc) {
00923                         fprintf(f, "    return %s(ptr);\n", manualfunc);
00924                 }
00925                 else {
00926                         rna_print_data_get(f, dp);
00927                         if(dp->dnalengthname)
00928                                 fprintf(f, "    return (data->%s == NULL)? 0: data->%s;\n", dp->dnaname, dp->dnalengthname);
00929                         else
00930                                 fprintf(f, "    return (data->%s == NULL)? 0: %d;\n", dp->dnaname, dp->dnalengthfixed);
00931                 }
00932                 fprintf(f, "}\n\n");
00933         }
00934 
00935         return func;
00936 }
00937 
00938 static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc)
00939 {
00940         char *func, *getfunc;
00941 
00942         if(prop->flag & PROP_IDPROPERTY && manualfunc==NULL)
00943                 return NULL;
00944 
00945         if(!manualfunc) {
00946                 if(!dp->dnastructname || !dp->dnaname) {
00947                         fprintf(stderr, "rna_def_property_begin_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
00948                         DefRNA.error= 1;
00949                         return NULL;
00950                 }
00951         }
00952 
00953         func= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "begin");
00954 
00955         fprintf(f, "void %s(CollectionPropertyIterator *iter, PointerRNA *ptr)\n", func);
00956         fprintf(f, "{\n");
00957 
00958         if(!manualfunc)
00959                 rna_print_data_get(f, dp);
00960 
00961         fprintf(f, "\n  memset(iter, 0, sizeof(*iter));\n");
00962         fprintf(f, "    iter->parent= *ptr;\n");
00963         fprintf(f, "    iter->prop= (PropertyRNA*)&rna_%s_%s;\n", srna->identifier, prop->identifier);
00964 
00965         if(dp->dnalengthname || dp->dnalengthfixed) {
00966                 if(manualfunc) {
00967                         fprintf(f, "\n  %s(iter, ptr);\n", manualfunc);
00968                 }
00969                 else {
00970                         if(dp->dnalengthname)
00971                                 fprintf(f, "\n  rna_iterator_array_begin(iter, data->%s, sizeof(data->%s[0]), data->%s, 0, NULL);\n", dp->dnaname, dp->dnaname, dp->dnalengthname);
00972                         else
00973                                 fprintf(f, "\n  rna_iterator_array_begin(iter, data->%s, sizeof(data->%s[0]), %d, 0, NULL);\n", dp->dnaname, dp->dnaname, dp->dnalengthfixed);
00974                 }
00975         }
00976         else {
00977                 if(manualfunc)
00978                         fprintf(f, "\n  %s(iter, ptr);\n", manualfunc);
00979                 else if(dp->dnapointerlevel == 0)
00980                         fprintf(f, "\n  rna_iterator_listbase_begin(iter, &data->%s, NULL);\n", dp->dnaname);
00981                 else
00982                         fprintf(f, "\n  rna_iterator_listbase_begin(iter, data->%s, NULL);\n", dp->dnaname);
00983         }
00984 
00985         getfunc= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get");
00986 
00987         fprintf(f, "\n  if(iter->valid)\n");
00988         fprintf(f, "            iter->ptr= %s(iter);\n", getfunc);
00989 
00990         fprintf(f, "}\n\n");
00991 
00992 
00993         return func;
00994 }
00995 
00996 static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc, char *nextfunc)
00997 {
00998         /* note on indices, this is for external functions and ignores skipped values.
00999          * so the the index can only be checked against the length when there is no 'skip' funcion. */
01000         char *func;
01001 
01002         if(prop->flag & PROP_IDPROPERTY && manualfunc==NULL)
01003                 return NULL;
01004 
01005         if(!manualfunc) {
01006                 if(!dp->dnastructname || !dp->dnaname)
01007                         return NULL;
01008 
01009                 /* only supported in case of standard next functions */
01010                 if(strcmp(nextfunc, "rna_iterator_array_next") == 0);
01011                 else if(strcmp(nextfunc, "rna_iterator_listbase_next") == 0);
01012                 else return NULL;
01013         }
01014 
01015         func= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "lookup_int");
01016 
01017         fprintf(f, "int %s(PointerRNA *ptr, int index, PointerRNA *r_ptr)\n", func);
01018         fprintf(f, "{\n");
01019 
01020         if(manualfunc) {
01021                 fprintf(f, "\n  return %s(ptr, index, r_ptr);\n", manualfunc);
01022                 fprintf(f, "}\n\n");
01023                 return func;
01024         }
01025 
01026         fprintf(f, "    int found= 0;\n");
01027         fprintf(f, "    CollectionPropertyIterator iter;\n\n");
01028 
01029         fprintf(f, "    %s_%s_begin(&iter, ptr);\n\n", srna->identifier, rna_safe_id(prop->identifier));
01030         fprintf(f, "    if(iter.valid){\n");
01031 
01032         if(strcmp(nextfunc, "rna_iterator_array_next") == 0) {
01033                 fprintf(f, "            ArrayIterator *internal= iter.internal;\n");
01034                 fprintf(f, "            if(index < 0 || index >= internal->length) {\n");
01035                 fprintf(f, "#ifdef __GNUC__\n");
01036                 fprintf(f, "                    printf(\"Array iterator out of range: %%s (index %%d)\\n\", __func__, index);\n");
01037                 fprintf(f, "#else\n");
01038                 fprintf(f, "                    printf(\"Array iterator out of range: (index %%d)\\n\", index);\n");
01039                 fprintf(f, "#endif\n");
01040                 fprintf(f, "            }\n");
01041                 fprintf(f, "            else if(internal->skip) {\n");
01042                 fprintf(f, "                    while(index-- > 0 && iter.valid) {\n");
01043                 fprintf(f, "                            rna_iterator_array_next(&iter);\n");
01044                 fprintf(f, "                    }\n");
01045                 fprintf(f, "                    found= (index == -1 && iter.valid);\n");
01046                 fprintf(f, "            }\n");
01047                 fprintf(f, "            else {\n");
01048                 fprintf(f, "                    internal->ptr += internal->itemsize*index;\n");
01049                 fprintf(f, "                    found= 1;\n");
01050                 fprintf(f, "            }\n");
01051         }
01052         else if(strcmp(nextfunc, "rna_iterator_listbase_next") == 0) {
01053                 fprintf(f, "            ListBaseIterator *internal= iter.internal;\n");
01054                 fprintf(f, "            if(internal->skip) {\n");
01055                 fprintf(f, "                    while(index-- > 0 && iter.valid) {\n");
01056                 fprintf(f, "                            rna_iterator_listbase_next(&iter);\n");
01057                 fprintf(f, "                    }\n");
01058                 fprintf(f, "                    found= (index == -1 && iter.valid);\n");
01059                 fprintf(f, "            }\n");
01060                 fprintf(f, "            else {\n");
01061                 fprintf(f, "                    while(index-- > 0 && internal->link)\n");
01062                 fprintf(f, "                            internal->link= internal->link->next;\n");
01063                 fprintf(f, "                    found= (index == -1 && internal->link);\n");
01064                 fprintf(f, "            }\n");
01065         }
01066 
01067         fprintf(f, "            if(found) *r_ptr = %s_%s_get(&iter);\n", srna->identifier, rna_safe_id(prop->identifier));
01068         fprintf(f, "    }\n\n");
01069         fprintf(f, "    %s_%s_end(&iter);\n\n", srna->identifier, rna_safe_id(prop->identifier));
01070 
01071         fprintf(f, "    return found;\n");
01072 
01073 #if 0
01074         rna_print_data_get(f, dp);
01075         item_type= (cprop->item_type)? (char*)cprop->item_type: "UnknownType";
01076 
01077         if(dp->dnalengthname || dp->dnalengthfixed) {
01078                 if(dp->dnalengthname)
01079                         fprintf(f, "\n  rna_array_lookup_int(ptr, &RNA_%s, data->%s, sizeof(data->%s[0]), data->%s, index);\n", item_type, dp->dnaname, dp->dnaname, dp->dnalengthname);
01080                 else
01081                         fprintf(f, "\n  rna_array_lookup_int(ptr, &RNA_%s, data->%s, sizeof(data->%s[0]), %d, index);\n", item_type, dp->dnaname, dp->dnaname, dp->dnalengthfixed);
01082         }
01083         else {
01084                 if(dp->dnapointerlevel == 0)
01085                         fprintf(f, "\n  return rna_listbase_lookup_int(ptr, &RNA_%s, &data->%s, index);\n", item_type, dp->dnaname);
01086                 else
01087                         fprintf(f, "\n  return rna_listbase_lookup_int(ptr, &RNA_%s, data->%s, index);\n", item_type, dp->dnaname);
01088         }
01089 #endif
01090 
01091         fprintf(f, "}\n\n");
01092 
01093         return func;
01094 }
01095 
01096 static char *rna_def_property_next_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc)
01097 {
01098         char *func, *getfunc;
01099 
01100         if(prop->flag & PROP_IDPROPERTY && manualfunc==NULL)
01101                 return NULL;
01102 
01103         if(!manualfunc)
01104                 return NULL;
01105 
01106         func= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "next");
01107 
01108         fprintf(f, "void %s(CollectionPropertyIterator *iter)\n", func);
01109         fprintf(f, "{\n");
01110         fprintf(f, "    %s(iter);\n", manualfunc);
01111 
01112         getfunc= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get");
01113 
01114         fprintf(f, "\n  if(iter->valid)\n");
01115         fprintf(f, "            iter->ptr= %s(iter);\n", getfunc);
01116 
01117         fprintf(f, "}\n\n");
01118 
01119         return func;
01120 }
01121 
01122 static char *rna_def_property_end_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc)
01123 {
01124         char *func;
01125 
01126         if(prop->flag & PROP_IDPROPERTY && manualfunc==NULL)
01127                 return NULL;
01128 
01129         func= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "end");
01130 
01131         fprintf(f, "void %s(CollectionPropertyIterator *iter)\n", func);
01132         fprintf(f, "{\n");
01133         if(manualfunc)
01134                 fprintf(f, "    %s(iter);\n", manualfunc);
01135         fprintf(f, "}\n\n");
01136 
01137         return func;
01138 }
01139 
01140 static void rna_set_raw_property(PropertyDefRNA *dp, PropertyRNA *prop)
01141 {
01142         if(dp->dnapointerlevel != 0)
01143                 return;
01144         if(!dp->dnatype || !dp->dnaname || !dp->dnastructname)
01145                 return;
01146         
01147         if(strcmp(dp->dnatype, "char") == 0) {
01148                 prop->rawtype= PROP_RAW_CHAR;
01149                 prop->flag |= PROP_RAW_ACCESS;
01150         }
01151         else if(strcmp(dp->dnatype, "short") == 0) {
01152                 prop->rawtype= PROP_RAW_SHORT;
01153                 prop->flag |= PROP_RAW_ACCESS;
01154         }
01155         else if(strcmp(dp->dnatype, "int") == 0) {
01156                 prop->rawtype= PROP_RAW_INT;
01157                 prop->flag |= PROP_RAW_ACCESS;
01158         }
01159         else if(strcmp(dp->dnatype, "float") == 0) {
01160                 prop->rawtype= PROP_RAW_FLOAT;
01161                 prop->flag |= PROP_RAW_ACCESS;
01162         }
01163         else if(strcmp(dp->dnatype, "double") == 0) {
01164                 prop->rawtype= PROP_RAW_DOUBLE;
01165                 prop->flag |= PROP_RAW_ACCESS;
01166         }
01167 }
01168 
01169 static void rna_set_raw_offset(FILE *f, StructRNA *srna, PropertyRNA *prop)
01170 {
01171         PropertyDefRNA *dp= rna_find_struct_property_def(srna, prop);
01172 
01173         fprintf(f, "\toffsetof(%s, %s), %d", dp->dnastructname, dp->dnaname, prop->rawtype);
01174 }
01175 
01176 static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
01177 {
01178         PropertyRNA *prop;
01179 
01180         prop= dp->prop;
01181 
01182         switch(prop->type) {
01183                 case PROP_BOOLEAN: {
01184                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
01185 
01186                         if(!prop->arraydimension) {
01187                                 if(!bprop->get && !bprop->set && !dp->booleanbit)
01188                                         rna_set_raw_property(dp, prop);
01189 
01190                                 bprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)bprop->get);
01191                                 bprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)bprop->set);
01192                         }
01193                         else {
01194                                 bprop->getarray= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)bprop->getarray);
01195                                 bprop->setarray= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)bprop->setarray);
01196                         }
01197                         break;
01198                 }
01199                 case PROP_INT: {
01200                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
01201 
01202                         if(!prop->arraydimension) {
01203                                 if(!iprop->get && !iprop->set)
01204                                         rna_set_raw_property(dp, prop);
01205 
01206                                 iprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)iprop->get);
01207                                 iprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)iprop->set);
01208                         }
01209                         else {
01210                                 if(!iprop->getarray && !iprop->setarray)
01211                                         rna_set_raw_property(dp, prop);
01212 
01213                                 iprop->getarray= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)iprop->getarray);
01214                                 iprop->setarray= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)iprop->setarray);
01215                         }
01216                         break;
01217                 }
01218                 case PROP_FLOAT: {
01219                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
01220 
01221                         if(!prop->arraydimension) {
01222                                 if(!fprop->get && !fprop->set)
01223                                         rna_set_raw_property(dp, prop);
01224 
01225                                 fprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)fprop->get);
01226                                 fprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)fprop->set);
01227                         }
01228                         else {
01229                                 if(!fprop->getarray && !fprop->setarray)
01230                                         rna_set_raw_property(dp, prop);
01231 
01232                                 fprop->getarray= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)fprop->getarray);
01233                                 fprop->setarray= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)fprop->setarray);
01234                         }
01235                         break;
01236                 }
01237                 case PROP_ENUM: {
01238                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
01239 
01240                         eprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)eprop->get);
01241                         eprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)eprop->set);
01242                         break;
01243                 }
01244                 case PROP_STRING: {
01245                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
01246 
01247                         sprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)sprop->get);
01248                         sprop->length= (void*)rna_def_property_length_func(f, srna, prop, dp, (char*)sprop->length);
01249                         sprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)sprop->set);
01250                         break;
01251                 }
01252                 case PROP_POINTER: {
01253                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
01254 
01255                         pprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)pprop->get);
01256                         pprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)pprop->set);
01257                         if(!pprop->type) {
01258                                 fprintf(stderr, "rna_def_property_funcs: %s.%s, pointer must have a struct type.\n", srna->identifier, prop->identifier);
01259                                 DefRNA.error= 1;
01260                         }
01261                         break;
01262                 }
01263                 case PROP_COLLECTION: {
01264                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
01265                         char *nextfunc= (char*)cprop->next;
01266 
01267                         if(dp->dnatype && strcmp(dp->dnatype, "ListBase")==0);
01268                         else if(dp->dnalengthname || dp->dnalengthfixed)
01269                                 cprop->length= (void*)rna_def_property_length_func(f, srna, prop, dp, (char*)cprop->length);
01270 
01271                         /* test if we can allow raw array access, if it is using our standard
01272                          * array get/next function, we can be sure it is an actual array */
01273                         if(cprop->next && cprop->get)
01274                                 if(strcmp((char*)cprop->next, "rna_iterator_array_next") == 0 &&
01275                                    strcmp((char*)cprop->get, "rna_iterator_array_get") == 0)
01276                                         prop->flag |= PROP_RAW_ARRAY;
01277 
01278                         cprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)cprop->get);
01279                         cprop->begin= (void*)rna_def_property_begin_func(f, srna, prop, dp, (char*)cprop->begin);
01280                         cprop->next= (void*)rna_def_property_next_func(f, srna, prop, dp, (char*)cprop->next);
01281                         cprop->end= (void*)rna_def_property_end_func(f, srna, prop, dp, (char*)cprop->end);
01282                         cprop->lookupint= (void*)rna_def_property_lookup_int_func(f, srna, prop, dp, (char*)cprop->lookupint, nextfunc);
01283 
01284                         if(!(prop->flag & PROP_IDPROPERTY)) {
01285                                 if(!cprop->begin) {
01286                                         fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a begin function.\n", srna->identifier, prop->identifier);
01287                                         DefRNA.error= 1;
01288                                 }
01289                                 if(!cprop->next) {
01290                                         fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a next function.\n", srna->identifier, prop->identifier);
01291                                         DefRNA.error= 1;
01292                                 }
01293                                 if(!cprop->get) {
01294                                         fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a get function.\n", srna->identifier, prop->identifier);
01295                                         DefRNA.error= 1;
01296                                 }
01297                         }
01298                         if(!cprop->item_type) {
01299                                 fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a struct type.\n", srna->identifier, prop->identifier);
01300                                 DefRNA.error= 1;
01301                         }
01302                         break;
01303                 }
01304         }
01305 }
01306 
01307 static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
01308 {
01309         PropertyRNA *prop;
01310         char *func;
01311 
01312         prop= dp->prop;
01313 
01314         if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN))
01315                 return;
01316 
01317         func= rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "");
01318 
01319         switch(prop->type) {
01320                 case PROP_BOOLEAN:
01321                 case PROP_INT: {
01322                         if(!prop->arraydimension) {
01323                                 fprintf(f, "int %sget(PointerRNA *ptr);\n", func);
01324                                 //fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func);
01325                         }
01326                         else if(prop->arraydimension && prop->totarraylength) {
01327                                 fprintf(f, "void %sget(PointerRNA *ptr, int values[%d]);\n", func, prop->totarraylength);
01328                                 //fprintf(f, "void %sset(PointerRNA *ptr, const int values[%d]);\n", func, prop->arraylength);
01329                         }
01330                         else {
01331                                 fprintf(f, "void %sget(PointerRNA *ptr, int values[]);\n", func);
01332                                 //fprintf(f, "void %sset(PointerRNA *ptr, const int values[]);\n", func);
01333                         }
01334                         break;
01335                 }
01336                 case PROP_FLOAT: {
01337                         if(!prop->arraydimension) {
01338                                 fprintf(f, "float %sget(PointerRNA *ptr);\n", func);
01339                                 //fprintf(f, "void %sset(PointerRNA *ptr, float value);\n", func);
01340                         }
01341                         else if(prop->arraydimension && prop->totarraylength) {
01342                                 fprintf(f, "void %sget(PointerRNA *ptr, float values[%d]);\n", func, prop->totarraylength);
01343                                 //fprintf(f, "void %sset(PointerRNA *ptr, const float values[%d]);\n", func, prop->arraylength);
01344                         }
01345                         else {
01346                                 fprintf(f, "void %sget(PointerRNA *ptr, float values[]);\n", func);
01347                                 //fprintf(f, "void %sset(PointerRNA *ptr, const float values[]);\n", func);
01348                         }
01349                         break;
01350                 }
01351                 case PROP_ENUM: {
01352                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
01353                         int i;
01354 
01355                         if(eprop->item) {
01356                                 fprintf(f, "enum {\n");
01357 
01358                                 for(i=0; i<eprop->totitem; i++)
01359                                         if(eprop->item[i].identifier[0])
01360                                                 fprintf(f, "\t%s_%s_%s = %d,\n", srna->identifier, prop->identifier, eprop->item[i].identifier, eprop->item[i].value);
01361 
01362                                 fprintf(f, "};\n\n");
01363                         }
01364 
01365                         fprintf(f, "int %sget(PointerRNA *ptr);\n", func);
01366                         //fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func);
01367 
01368                         break;
01369                 }
01370                 case PROP_STRING: {
01371                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
01372 
01373                         if(sprop->maxlength) {
01374                                 fprintf(f, "#define %s_%s_MAX %d\n\n", srna->identifier, prop->identifier, sprop->maxlength);
01375                         }
01376                         
01377                         fprintf(f, "void %sget(PointerRNA *ptr, char *value);\n", func);
01378                         fprintf(f, "int %slength(PointerRNA *ptr);\n", func);
01379                         //fprintf(f, "void %sset(PointerRNA *ptr, const char *value);\n", func);
01380 
01381                         break;
01382                 }
01383                 case PROP_POINTER: {
01384                         fprintf(f, "PointerRNA %sget(PointerRNA *ptr);\n", func);
01385                         //fprintf(f, "void %sset(PointerRNA *ptr, PointerRNA value);\n", func);
01386                         break;
01387                 }
01388                 case PROP_COLLECTION: {
01389                         fprintf(f, "void %sbegin(CollectionPropertyIterator *iter, PointerRNA *ptr);\n", func);
01390                         fprintf(f, "void %snext(CollectionPropertyIterator *iter);\n", func);
01391                         fprintf(f, "void %send(CollectionPropertyIterator *iter);\n", func);
01392                         //fprintf(f, "int %slength(PointerRNA *ptr);\n", func);
01393                         //fprintf(f, "void %slookup_int(PointerRNA *ptr, int key, StructRNA **type);\n", func);
01394                         //fprintf(f, "void %slookup_string(PointerRNA *ptr, const char *key, StructRNA **type);\n", func);
01395                         break;
01396                 }
01397         }
01398 
01399         fprintf(f, "\n");
01400 }
01401 
01402 static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
01403 {
01404         PropertyRNA *prop;
01405 
01406         prop= dp->prop;
01407 
01408         if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN))
01409                 return;
01410         
01411         if(prop->name && prop->description && strcmp(prop->description, "") != 0)
01412                 fprintf(f, "\t/* %s: %s */\n", prop->name, prop->description);
01413         else if(prop->name)
01414                 fprintf(f, "\t/* %s */\n", prop->name);
01415         else
01416                 fprintf(f, "\t/* */\n");
01417 
01418         switch(prop->type) {
01419                 case PROP_BOOLEAN: {
01420                         if(!prop->arraydimension)
01421                                 fprintf(f, "\tinline bool %s(void);", rna_safe_id(prop->identifier));
01422                         else
01423                                 fprintf(f, "\tinline Array<int, %d> %s(void);", prop->totarraylength, rna_safe_id(prop->identifier));
01424                         break;
01425                 }
01426                 case PROP_INT: {
01427                         if(!prop->arraydimension)
01428                                 fprintf(f, "\tinline int %s(void);", rna_safe_id(prop->identifier));
01429                         else
01430                                 fprintf(f, "\tinline Array<int, %d> %s(void);", prop->totarraylength, rna_safe_id(prop->identifier));
01431                         break;
01432                 }
01433                 case PROP_FLOAT: {
01434                         if(!prop->arraydimension)
01435                                 fprintf(f, "\tinline float %s(void);", rna_safe_id(prop->identifier));
01436                         else
01437                                 fprintf(f, "\tinline Array<float, %d> %s(void);", prop->totarraylength, rna_safe_id(prop->identifier));
01438                         break;
01439                 }
01440                 case PROP_ENUM: {
01441                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
01442                         int i;
01443 
01444                         if(eprop->item) {
01445                                 fprintf(f, "\tenum %s_enum {\n", rna_safe_id(prop->identifier));
01446 
01447                                 for(i=0; i<eprop->totitem; i++)
01448                                         if(eprop->item[i].identifier[0])
01449                                                 fprintf(f, "\t\t%s_%s = %d,\n", rna_safe_id(prop->identifier), eprop->item[i].identifier, eprop->item[i].value);
01450 
01451                                 fprintf(f, "\t};\n");
01452                         }
01453 
01454                         fprintf(f, "\tinline %s_enum %s(void);", rna_safe_id(prop->identifier), rna_safe_id(prop->identifier));
01455                         break;
01456                 }
01457                 case PROP_STRING: {
01458                         fprintf(f, "\tinline std::string %s(void);", rna_safe_id(prop->identifier));
01459                         break;
01460                 }
01461                 case PROP_POINTER: {
01462                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)dp->prop;
01463 
01464                         if(pprop->type)
01465                                 fprintf(f, "\tinline %s %s(void);", (char*)pprop->type, rna_safe_id(prop->identifier));
01466                         else
01467                                 fprintf(f, "\tinline %s %s(void);", "UnknownType", rna_safe_id(prop->identifier));
01468                         break;
01469                 }
01470                 case PROP_COLLECTION: {
01471                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)dp->prop;
01472 
01473                         if(cprop->item_type)
01474                                 fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", (char*)cprop->item_type, srna->identifier, rna_safe_id(prop->identifier));
01475                         else
01476                                 fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, rna_safe_id(prop->identifier));
01477                         break;
01478                 }
01479         }
01480 
01481         fprintf(f, "\n");
01482 }
01483 
01484 static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
01485 {
01486         PropertyRNA *prop;
01487 
01488         prop= dp->prop;
01489 
01490         if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN))
01491                 return;
01492 
01493         switch(prop->type) {
01494                 case PROP_BOOLEAN: {
01495                         if(!prop->arraydimension)
01496                                 fprintf(f, "\tBOOLEAN_PROPERTY(%s, %s)", srna->identifier, rna_safe_id(prop->identifier));
01497                         else
01498                                 fprintf(f, "\tBOOLEAN_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->totarraylength, rna_safe_id(prop->identifier));
01499                         break;
01500                 }
01501                 case PROP_INT: {
01502                         if(!prop->arraydimension)
01503                                 fprintf(f, "\tINT_PROPERTY(%s, %s)", srna->identifier, rna_safe_id(prop->identifier));
01504                         else
01505                                 fprintf(f, "\tINT_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->totarraylength, rna_safe_id(prop->identifier));
01506                         break;
01507                 }
01508                 case PROP_FLOAT: {
01509                         if(!prop->arraydimension)
01510                                 fprintf(f, "\tFLOAT_PROPERTY(%s, %s)", srna->identifier, rna_safe_id(prop->identifier));
01511                         else
01512                                 fprintf(f, "\tFLOAT_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->totarraylength, rna_safe_id(prop->identifier));
01513                         break;
01514                 }
01515                 case PROP_ENUM: {
01516                         fprintf(f, "\tENUM_PROPERTY(%s_enum, %s, %s)", rna_safe_id(prop->identifier), srna->identifier, rna_safe_id(prop->identifier));
01517 
01518                         break;
01519                 }
01520                 case PROP_STRING: {
01521                         fprintf(f, "\tSTRING_PROPERTY(%s, %s)", srna->identifier, rna_safe_id(prop->identifier));
01522                         break;
01523                 }
01524                 case PROP_POINTER: {
01525                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)dp->prop;
01526 
01527                         if(pprop->type)
01528                                 fprintf(f, "\tPOINTER_PROPERTY(%s, %s, %s)", (char*)pprop->type, srna->identifier, rna_safe_id(prop->identifier));
01529                         else
01530                                 fprintf(f, "\tPOINTER_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, rna_safe_id(prop->identifier));
01531                         break;
01532                 }
01533                 case PROP_COLLECTION: {
01534                         /*CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)dp->prop;
01535 
01536                         if(cprop->type)
01537                                 fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", (char*)cprop->type, srna->identifier, prop->identifier);
01538                         else
01539                                 fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, prop->identifier);*/
01540                         break;
01541                 }
01542         }
01543 
01544         fprintf(f, "\n");
01545 }
01546 
01547 static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA *dfunc)
01548 {
01549         StructRNA *srna;
01550         FunctionRNA *func;
01551         PropertyDefRNA *dparm;
01552         PropertyType type;
01553         const char *funcname, *valstr;
01554         const char *ptrstr;
01555         const short has_data= (dfunc->cont.properties.first != NULL);
01556         int flag, pout, cptr, first;
01557 
01558         srna= dsrna->srna;
01559         func= dfunc->func;
01560 
01561         if(!dfunc->call)
01562                 return;
01563 
01564         funcname= rna_alloc_function_name(srna->identifier, func->identifier, "call");
01565 
01566         /* function definition */
01567         fprintf(f, "void %s(bContext *C, ReportList *reports, PointerRNA *_ptr, ParameterList *_parms)", funcname);
01568         fprintf(f, "\n{\n");
01569 
01570         /* variable definitions */
01571         
01572         if(func->flag & FUNC_USE_SELF_ID) {
01573                 fprintf(f, "\tstruct ID *_selfid;\n");
01574         }
01575 
01576         if((func->flag & FUNC_NO_SELF)==0) {
01577                 if(dsrna->dnaname) fprintf(f, "\tstruct %s *_self;\n", dsrna->dnaname);
01578                 else fprintf(f, "\tstruct %s *_self;\n", srna->identifier);
01579         }
01580 
01581         dparm= dfunc->cont.properties.first;
01582         for(; dparm; dparm= dparm->next) {
01583                 type = dparm->prop->type;
01584                 flag = dparm->prop->flag;
01585                 pout = (flag & PROP_OUTPUT);
01586                 cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR));
01587 
01588                 if(dparm->prop==func->c_ret)
01589                         ptrstr= cptr || dparm->prop->arraydimension ? "*" : "";
01590                 /* XXX only arrays and strings are allowed to be dynamic, is this checked anywhere? */
01591                 else if (cptr || (flag & PROP_DYNAMIC))
01592                         ptrstr= pout ? "**" : "*";
01593                 /* fixed size arrays and RNA pointers are pre-allocated on the ParameterList stack, pass a pointer to it */
01594                 else if (type == PROP_POINTER || dparm->prop->arraydimension)
01595                         ptrstr= "*";
01596                 /* PROP_THICK_WRAP strings are pre-allocated on the ParameterList stack, but type name for string props is already char*, so leave empty */
01597                 else if (type == PROP_STRING && (flag & PROP_THICK_WRAP))
01598                         ptrstr= "";
01599                 else
01600                         ptrstr= pout ? "*" : "";
01601 
01602                 /* for dynamic parameters we pass an additional int for the length of the parameter */
01603                 if (flag & PROP_DYNAMIC)
01604                         fprintf(f, "\tint %s%s_len;\n", pout ? "*" : "", dparm->prop->identifier);
01605                 
01606                 fprintf(f, "\t%s%s %s%s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier);
01607         }
01608 
01609         if(has_data) {
01610                 fprintf(f, "\tchar *_data");
01611                 if(func->c_ret) fprintf(f, ", *_retdata");
01612                 fprintf(f, ";\n");
01613                 fprintf(f, "\t\n");
01614         }
01615 
01616         /* assign self */
01617         if(func->flag & FUNC_USE_SELF_ID) {
01618                 fprintf(f, "\t_selfid= (struct ID*)_ptr->id.data;\n");
01619         }
01620         
01621         if((func->flag & FUNC_NO_SELF)==0) {
01622                 if(dsrna->dnaname) fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", dsrna->dnaname);
01623                 else fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", srna->identifier);
01624         }
01625 
01626         if(has_data) {
01627                 fprintf(f, "\t_data= (char *)_parms->data;\n");
01628         }
01629 
01630         dparm= dfunc->cont.properties.first;
01631         for(; dparm; dparm= dparm->next) {
01632                 type = dparm->prop->type;
01633                 flag = dparm->prop->flag;
01634                 pout = (flag & PROP_OUTPUT);
01635                 cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR));
01636 
01637                 if(dparm->prop==func->c_ret)
01638                         fprintf(f, "\t_retdata= _data;\n");
01639                 else  {
01640                         const char *data_str;
01641                         if (cptr || (flag & PROP_DYNAMIC)) {
01642                                 ptrstr= "**";
01643                                 valstr= "*";
01644                         }
01645                         else if (type == PROP_POINTER || dparm->prop->arraydimension) {
01646                                 ptrstr= "*";
01647                                 valstr= "";
01648                         }
01649                         else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) {
01650                                 ptrstr= "";
01651                                 valstr= "";
01652                         }
01653                         else {
01654                                 ptrstr= "*";
01655                                 valstr= "*";
01656                         }
01657 
01658                         /* this must be kept in sync with RNA_parameter_length_get_data, we could just call the function directly, but this is faster */
01659                         if (flag & PROP_DYNAMIC) {
01660                                 fprintf(f, "\t%s_len= %s((int *)_data);\n", dparm->prop->identifier, pout ? "" : "*");
01661                                 data_str= "(&(((char *)_data)[sizeof(void *)]))";
01662                         }
01663                         else {
01664                                 data_str= "_data";
01665                         }
01666                         fprintf(f, "\t%s= ", dparm->prop->identifier);
01667 
01668                         if (!pout)
01669                                 fprintf(f, "%s", valstr);
01670 
01671                         fprintf(f, "((%s%s%s)%s);\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, data_str);
01672                 }
01673 
01674                 if(dparm->next)
01675                         fprintf(f, "\t_data+= %d;\n", rna_parameter_size_alloc(dparm->prop));
01676         }
01677 
01678         if(dfunc->call) {
01679                 fprintf(f, "\t\n");
01680                 fprintf(f, "\t");
01681                 if(func->c_ret) fprintf(f, "%s= ", func->c_ret->identifier);
01682                 fprintf(f, "%s(", dfunc->call);
01683 
01684                 first= 1;
01685 
01686                 if(func->flag & FUNC_USE_SELF_ID) {
01687                         fprintf(f, "_selfid");
01688                         first= 0;
01689                 }
01690 
01691                 if((func->flag & FUNC_NO_SELF)==0) {
01692                         if(!first) fprintf(f, ", ");
01693                         fprintf(f, "_self");
01694                         first= 0;
01695                 }
01696 
01697                 if(func->flag & FUNC_USE_CONTEXT) {
01698                         if(!first) fprintf(f, ", ");
01699                         first= 0;
01700                         fprintf(f, "C");
01701                 }
01702 
01703                 if(func->flag & FUNC_USE_REPORTS) {
01704                         if(!first) fprintf(f, ", ");
01705                         first= 0;
01706                         fprintf(f, "reports");
01707                 }
01708 
01709                 dparm= dfunc->cont.properties.first;
01710                 for(; dparm; dparm= dparm->next) {
01711                         if(dparm->prop==func->c_ret)
01712                                 continue;
01713 
01714                         if(!first) fprintf(f, ", ");
01715                         first= 0;
01716 
01717                         if (dparm->prop->flag & PROP_DYNAMIC)
01718                                 fprintf(f, "%s_len, %s", dparm->prop->identifier, dparm->prop->identifier);
01719                         else
01720                                 fprintf(f, "%s", dparm->prop->identifier);
01721                 }
01722 
01723                 fprintf(f, ");\n");
01724 
01725                 if(func->c_ret) {
01726                         dparm= rna_find_parameter_def(func->c_ret);
01727                         ptrstr= (((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR)) || (dparm->prop->arraydimension))? "*": "";
01728                         fprintf(f, "\t*((%s%s%s*)_retdata)= %s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, func->c_ret->identifier);
01729                 }
01730         }
01731 
01732         fprintf(f, "}\n\n");
01733 
01734         dfunc->gencall= funcname;
01735 }
01736 
01737 static void rna_auto_types(void)
01738 {
01739         StructDefRNA *ds;
01740         PropertyDefRNA *dp;
01741 
01742         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) {
01743                 /* DNA name for Screen is patched in 2.5, we do the reverse here .. */
01744                 if(ds->dnaname && strcmp(ds->dnaname, "Screen") == 0)
01745                         ds->dnaname= "bScreen";
01746 
01747                 for(dp=ds->cont.properties.first; dp; dp=dp->next) {
01748                         if(dp->dnastructname && strcmp(dp->dnastructname, "Screen") == 0)
01749                                 dp->dnastructname= "bScreen";
01750 
01751                         if(dp->dnatype) {
01752                                 if(dp->prop->type == PROP_POINTER) {
01753                                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)dp->prop;
01754                                         StructRNA *type;
01755 
01756                                         if(!pprop->type && !pprop->get)
01757                                                 pprop->type= (StructRNA*)rna_find_type(dp->dnatype);
01758 
01759                                         if(pprop->type) {
01760                                                 type= rna_find_struct((char*)pprop->type);
01761                                                 if(type && (type->flag & STRUCT_ID_REFCOUNT))
01762                                                         pprop->property.flag |= PROP_ID_REFCOUNT;
01763                                         }
01764                                 }
01765                                 else if(dp->prop->type== PROP_COLLECTION) {
01766                                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)dp->prop;
01767 
01768                                         if(!cprop->item_type && !cprop->get && strcmp(dp->dnatype, "ListBase")==0)
01769                                                 cprop->item_type= (StructRNA*)rna_find_type(dp->dnatype);
01770                                 }
01771                         }
01772                 }
01773         }
01774 }
01775 
01776 static void rna_sort(BlenderRNA *brna)
01777 {
01778         StructDefRNA *ds;
01779         StructRNA *srna;
01780 
01781         rna_sortlist(&brna->structs, cmp_struct);
01782         rna_sortlist(&DefRNA.structs, cmp_def_struct);
01783 
01784         for(srna=brna->structs.first; srna; srna=srna->cont.next)
01785                 rna_sortlist(&srna->cont.properties, cmp_property);
01786 
01787         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next)
01788                 rna_sortlist(&ds->cont.properties, cmp_def_property);
01789 }
01790 
01791 static const char *rna_property_structname(PropertyType type)
01792 {
01793         switch(type) {
01794                 case PROP_BOOLEAN: return "BooleanPropertyRNA";
01795                 case PROP_INT: return "IntPropertyRNA";
01796                 case PROP_FLOAT: return "FloatPropertyRNA";
01797                 case PROP_STRING: return "StringPropertyRNA";
01798                 case PROP_ENUM: return "EnumPropertyRNA";
01799                 case PROP_POINTER: return "PointerPropertyRNA";
01800                 case PROP_COLLECTION: return "CollectionPropertyRNA";
01801                 default: return "UnknownPropertyRNA";
01802         }
01803 }
01804 
01805 static const char *rna_property_subtypename(PropertySubType type)
01806 {
01807         switch(type) {
01808                 case PROP_NONE: return "PROP_NONE";
01809                 case PROP_FILEPATH: return "PROP_FILEPATH";
01810                 case PROP_FILENAME: return "PROP_FILENAME";
01811                 case PROP_DIRPATH: return "PROP_DIRPATH";
01812                 case PROP_UNSIGNED: return "PROP_UNSIGNED";
01813                 case PROP_PERCENTAGE: return "PROP_PERCENTAGE";
01814                 case PROP_FACTOR: return "PROP_FACTOR";
01815                 case PROP_ANGLE: return "PROP_ANGLE";
01816                 case PROP_TIME: return "PROP_TIME";
01817                 case PROP_DISTANCE: return "PROP_DISTANCE";
01818                 case PROP_COLOR: return "PROP_COLOR";
01819                 case PROP_TRANSLATION: return "PROP_TRANSLATION";
01820                 case PROP_DIRECTION: return "PROP_DIRECTION";
01821                 case PROP_MATRIX: return "PROP_MATRIX";
01822                 case PROP_EULER: return "PROP_EULER";
01823                 case PROP_QUATERNION: return "PROP_QUATERNION";
01824                 case PROP_AXISANGLE: return "PROP_AXISANGLE";
01825                 case PROP_VELOCITY: return "PROP_VELOCITY";
01826                 case PROP_ACCELERATION: return "PROP_ACCELERATION";
01827                 case PROP_XYZ: return "PROP_XYZ";
01828                 case PROP_COLOR_GAMMA: return "PROP_COLOR_GAMMA";
01829                 case PROP_COORDS: return "PROP_COORDS";
01830                 case PROP_LAYER: return "PROP_LAYER";
01831                 case PROP_LAYER_MEMBER: return "PROP_LAYER_MEMBER";
01832                 default: {
01833                         /* incase we dont have a type preset that includes the subtype */
01834                         if(RNA_SUBTYPE_UNIT(type)) {
01835                                 return rna_property_subtypename(type & ~RNA_SUBTYPE_UNIT(type));
01836                         }
01837                         else {
01838                                 return "PROP_SUBTYPE_UNKNOWN";
01839                         }
01840                 }
01841         }
01842 }
01843 
01844 static const char *rna_property_subtype_unit(PropertySubType type)
01845 {
01846         switch(RNA_SUBTYPE_UNIT(type)) {
01847                 case PROP_UNIT_NONE:            return "PROP_UNIT_NONE";
01848                 case PROP_UNIT_LENGTH:          return "PROP_UNIT_LENGTH";
01849                 case PROP_UNIT_AREA:            return "PROP_UNIT_AREA";
01850                 case PROP_UNIT_VOLUME:          return "PROP_UNIT_VOLUME";
01851                 case PROP_UNIT_MASS:            return "PROP_UNIT_MASS";
01852                 case PROP_UNIT_ROTATION:        return "PROP_UNIT_ROTATION";
01853                 case PROP_UNIT_TIME:            return "PROP_UNIT_TIME";
01854                 case PROP_UNIT_VELOCITY:        return "PROP_UNIT_VELOCITY";
01855                 case PROP_UNIT_ACCELERATION:return "PROP_UNIT_ACCELERATION";
01856                 default:                                        return "PROP_UNIT_UNKNOWN";
01857         }
01858 }
01859 
01860 static void rna_generate_prototypes(BlenderRNA *brna, FILE *f)
01861 {
01862         StructRNA *srna;
01863 
01864         for(srna=brna->structs.first; srna; srna=srna->cont.next)
01865                 fprintf(f, "extern StructRNA RNA_%s;\n", srna->identifier);
01866         fprintf(f, "\n");
01867 }
01868 
01869 static void rna_generate_blender(BlenderRNA *brna, FILE *f)
01870 {
01871         StructRNA *srna;
01872 
01873         fprintf(f, "BlenderRNA BLENDER_RNA = {");
01874 
01875         srna= brna->structs.first;
01876         if(srna) fprintf(f, "{&RNA_%s, ", srna->identifier);
01877         else fprintf(f, "{NULL, ");
01878 
01879         srna= brna->structs.last;
01880         if(srna) fprintf(f, "&RNA_%s}", srna->identifier);
01881         else fprintf(f, "NULL}");
01882 
01883         fprintf(f, "};\n\n");
01884 }
01885 
01886 static void rna_generate_property_prototypes(BlenderRNA *brna, StructRNA *srna, FILE *f)
01887 {
01888         PropertyRNA *prop;
01889         StructRNA *base;
01890 
01891         base= srna->base;
01892         while (base) {
01893                 fprintf(f, "\n");
01894                 for(prop=base->cont.properties.first; prop; prop=prop->next)
01895                         fprintf(f, "%s%s rna_%s_%s;\n", "extern ", rna_property_structname(prop->type), base->identifier, prop->identifier);
01896                 base= base->base;
01897         }
01898 
01899         if(srna->cont.properties.first)
01900                 fprintf(f, "\n");
01901 
01902         for(prop=srna->cont.properties.first; prop; prop=prop->next)
01903                 fprintf(f, "%s%s rna_%s_%s;\n", (prop->flag & PROP_EXPORT)? "": "", rna_property_structname(prop->type), srna->identifier, prop->identifier);
01904         fprintf(f, "\n");
01905 }
01906 
01907 static void rna_generate_parameter_prototypes(BlenderRNA *brna, StructRNA *srna, FunctionRNA *func, FILE *f)
01908 {
01909         PropertyRNA *parm;
01910 
01911         for(parm= func->cont.properties.first; parm; parm= parm->next)
01912                 fprintf(f, "%s%s rna_%s_%s_%s;\n", "extern ", rna_property_structname(parm->type), srna->identifier, func->identifier, parm->identifier);
01913 
01914         if(func->cont.properties.first)
01915                 fprintf(f, "\n");
01916 }
01917 
01918 static void rna_generate_function_prototypes(BlenderRNA *brna, StructRNA *srna, FILE *f)
01919 {
01920         FunctionRNA *func;
01921         StructRNA *base;
01922 
01923         base= srna->base;
01924         while (base) {
01925                 for(func= base->functions.first; func; func= func->cont.next) {
01926                         fprintf(f, "%s%s rna_%s_%s_func;\n", "extern ", "FunctionRNA", base->identifier, func->identifier);
01927                         rna_generate_parameter_prototypes(brna, base, func, f);
01928                 }
01929 
01930                 if(base->functions.first)
01931                         fprintf(f, "\n");
01932 
01933                 base= base->base;
01934         }
01935 
01936         for(func= srna->functions.first; func; func= func->cont.next) {
01937                 fprintf(f, "%s%s rna_%s_%s_func;\n", "extern ", "FunctionRNA", srna->identifier, func->identifier);
01938                 rna_generate_parameter_prototypes(brna, srna, func, f);
01939         }
01940 
01941         if(srna->functions.first)
01942                 fprintf(f, "\n");
01943 }
01944 
01945 static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA *srna, FunctionDefRNA *dfunc, FILE *f)
01946 {
01947         FunctionRNA *func;
01948         PropertyDefRNA *dparm;
01949         StructDefRNA *dsrna;
01950         PropertyType type;
01951         int flag, pout, cptr, first;
01952         const char *ptrstr;
01953 
01954         dsrna= rna_find_struct_def(srna);
01955         func= dfunc->func;
01956 
01957         /* return type */
01958         for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
01959                 if(dparm->prop==func->c_ret) {
01960                         if(dparm->prop->arraydimension)
01961                                 fprintf(f, "XXX no array return types yet"); /* XXX not supported */
01962                         else if(dparm->prop->type == PROP_POINTER && !(dparm->prop->flag & PROP_RNAPTR))
01963                                 fprintf(f, "%s%s *", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
01964                         else
01965                                 fprintf(f, "%s%s ", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
01966 
01967                         break;
01968                 }
01969         }
01970 
01971         /* void if nothing to return */
01972         if(!dparm)
01973                 fprintf(f, "void ");
01974 
01975         /* function name */
01976         fprintf(f, "%s(", dfunc->call);
01977 
01978         first= 1;
01979 
01980         /* self, context and reports parameters */
01981         if(func->flag & FUNC_USE_SELF_ID) {
01982                 fprintf(f, "struct ID *_selfid");
01983                 first= 0;               
01984         }
01985         
01986         if((func->flag & FUNC_NO_SELF)==0) {
01987                 if(!first) fprintf(f, ", ");
01988                 if(dsrna->dnaname) fprintf(f, "struct %s *_self", dsrna->dnaname);
01989                 else fprintf(f, "struct %s *_self", srna->identifier);
01990                 first= 0;
01991         }
01992 
01993         if(func->flag & FUNC_USE_CONTEXT) {
01994                 if(!first) fprintf(f, ", ");
01995                 first= 0;
01996                 fprintf(f, "bContext *C");
01997         }
01998 
01999         if(func->flag & FUNC_USE_REPORTS) {
02000                 if(!first) fprintf(f, ", ");
02001                 first= 0;
02002                 fprintf(f, "ReportList *reports");
02003         }
02004 
02005         /* defined parameters */
02006         for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
02007                 type = dparm->prop->type;
02008                 flag = dparm->prop->flag;
02009                 pout = (flag & PROP_OUTPUT);
02010                 cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR));
02011 
02012                 if(dparm->prop==func->c_ret)
02013                         continue;
02014 
02015                 if (cptr || (flag & PROP_DYNAMIC))
02016                         ptrstr= pout ? "**" : "*";
02017                 else if (type == PROP_POINTER || dparm->prop->arraydimension)
02018                         ptrstr= "*";
02019                 else if (type == PROP_STRING && (flag & PROP_THICK_WRAP))
02020                         ptrstr= "";
02021                 else
02022                         ptrstr= pout ? "*" : "";
02023 
02024                 if(!first) fprintf(f, ", ");
02025                 first= 0;
02026 
02027                 if (flag & PROP_DYNAMIC)
02028                         fprintf(f, "int %s%s_len, ", pout ? "*" : "", dparm->prop->identifier);
02029 
02030                 if(!(flag & PROP_DYNAMIC) && dparm->prop->arraydimension)
02031                         fprintf(f, "%s%s %s[%d]", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier, dparm->prop->totarraylength);
02032                 else
02033                         fprintf(f, "%s%s %s%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier);
02034 
02035         }
02036 
02037         fprintf(f, ");\n");
02038 }
02039 
02040 static void rna_generate_static_function_prototypes(BlenderRNA *brna, StructRNA *srna, FILE *f)
02041 {
02042         FunctionRNA *func;
02043         FunctionDefRNA *dfunc;
02044         int first= 1;
02045 
02046         for(func= srna->functions.first; func; func= func->cont.next) {
02047                 dfunc= rna_find_function_def(func);
02048 
02049                 if(dfunc->call) {
02050                         if(first) {
02051                                 fprintf(f, "/* Repeated prototypes to detect errors */\n\n");
02052                                 first= 0;
02053                         }
02054 
02055                         rna_generate_static_parameter_prototypes(brna, srna, dfunc, f);
02056                 }
02057         }
02058 
02059         fprintf(f, "\n");
02060 }
02061 
02062 static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, PropertyRNA *prop) 
02063 {
02064         char *strnest= "", *errnest= "";
02065         int len, freenest= 0;
02066         
02067         if(nest != NULL) {
02068                 len= strlen(nest);
02069 
02070                 strnest= MEM_mallocN(sizeof(char)*(len+2), "rna_generate_property -> strnest");
02071                 errnest= MEM_mallocN(sizeof(char)*(len+2), "rna_generate_property -> errnest");
02072 
02073                 strcpy(strnest, "_"); strcat(strnest, nest);
02074                 strcpy(errnest, "."); strcat(errnest, nest);
02075 
02076                 freenest= 1;
02077         }
02078 
02079         switch(prop->type) {
02080                         case PROP_ENUM: {
02081                                 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
02082                                 int i, defaultfound= 0, totflag= 0;
02083 
02084                                 if(eprop->item) {
02085                                         fprintf(f, "static EnumPropertyItem rna_%s%s_%s_items[%d] = {\n\t", srna->identifier, strnest, prop->identifier, eprop->totitem+1);
02086 
02087                                         for(i=0; i<eprop->totitem; i++) {
02088                                                 fprintf(f, "{%d, ", eprop->item[i].value);
02089                                                 rna_print_c_string(f, eprop->item[i].identifier); fprintf(f, ", ");
02090                                                 fprintf(f, "%d, ", eprop->item[i].icon);
02091                                                 rna_print_c_string(f, eprop->item[i].name); fprintf(f, ", ");
02092                                                 rna_print_c_string(f, eprop->item[i].description); fprintf(f, "},\n\t");
02093 
02094                                                 if(eprop->item[i].identifier[0]) {
02095                                                         if(prop->flag & PROP_ENUM_FLAG) {
02096                                                                 totflag |= eprop->item[i].value;
02097                                                         }
02098                                                         else {
02099                                                                 if(eprop->defaultvalue == eprop->item[i].value) {
02100                                                                         defaultfound= 1;
02101                                                                 }
02102                                                         }
02103                                                 }
02104                                         }
02105 
02106                                         fprintf(f, "{0, NULL, 0, NULL, NULL}\n};\n\n");
02107 
02108                                         if(prop->flag & PROP_ENUM_FLAG) {
02109                                                 if(eprop->defaultvalue & ~totflag) {
02110                                                         fprintf(stderr, "rna_generate_structs: %s%s.%s, enum default includes unused bits (%d).\n", srna->identifier, errnest, prop->identifier, eprop->defaultvalue & ~totflag);
02111                                                         DefRNA.error= 1;
02112                                                 }
02113                                         }
02114                                         else {
02115                                                 if(!defaultfound) {
02116                                                         fprintf(stderr, "rna_generate_structs: %s%s.%s, enum default is not in items.\n", srna->identifier, errnest, prop->identifier);
02117                                                         DefRNA.error= 1;
02118                                                 }
02119                                         }
02120                                 }
02121                                 else {
02122                                         fprintf(stderr, "rna_generate_structs: %s%s.%s, enum must have items defined.\n", srna->identifier, errnest, prop->identifier);
02123                                         DefRNA.error= 1;
02124                                 }
02125                                 break;
02126                         }
02127                         case PROP_BOOLEAN: {
02128                                 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
02129                                 unsigned int i;
02130 
02131                                 if(prop->arraydimension && prop->totarraylength) {
02132                                         fprintf(f, "static int rna_%s%s_%s_default[%d] = {\n\t", srna->identifier, strnest, prop->identifier, prop->totarraylength);
02133 
02134                                         for(i=0; i<prop->totarraylength; i++) {
02135                                                 if(bprop->defaultarray)
02136                                                         fprintf(f, "%d", bprop->defaultarray[i]);
02137                                                 else
02138                                                         fprintf(f, "%d", bprop->defaultvalue);
02139                                                 if(i != prop->totarraylength-1)
02140                                                         fprintf(f, ",\n\t");
02141                                         }
02142 
02143                                         fprintf(f, "\n};\n\n");
02144                                 }
02145                                 break;
02146                         }
02147                         case PROP_INT: {
02148                                 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
02149                                 unsigned int i;
02150 
02151                                 if(prop->arraydimension && prop->totarraylength) {
02152                                         fprintf(f, "static int rna_%s%s_%s_default[%d] = {\n\t", srna->identifier, strnest, prop->identifier, prop->totarraylength);
02153 
02154                                         for(i=0; i<prop->totarraylength; i++) {
02155                                                 if(iprop->defaultarray)
02156                                                         fprintf(f, "%d", iprop->defaultarray[i]);
02157                                                 else
02158                                                         fprintf(f, "%d", iprop->defaultvalue);
02159                                                 if(i != prop->totarraylength-1)
02160                                                         fprintf(f, ",\n\t");
02161                                         }
02162 
02163                                         fprintf(f, "\n};\n\n");
02164                                 }
02165                                 break;
02166                         }
02167                         case PROP_FLOAT: {
02168                                 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
02169                                 unsigned int i;
02170 
02171                                 if(prop->arraydimension && prop->totarraylength) {
02172                                         fprintf(f, "static float rna_%s%s_%s_default[%d] = {\n\t", srna->identifier, strnest, prop->identifier, prop->totarraylength);
02173 
02174                                         for(i=0; i<prop->totarraylength; i++) {
02175                                                 if(fprop->defaultarray)
02176                                                         rna_float_print(f, fprop->defaultarray[i]);
02177                                                 else
02178                                                         rna_float_print(f, fprop->defaultvalue);
02179                                                 if(i != prop->totarraylength-1)
02180                                                         fprintf(f, ",\n\t");
02181                                         }
02182 
02183                                         fprintf(f, "\n};\n\n");
02184                                 }
02185                                 break;
02186                         }
02187                         default:
02188                                 break;
02189         }
02190 
02191         fprintf(f, "%s%s rna_%s%s_%s = {\n", (prop->flag & PROP_EXPORT)? "": "", rna_property_structname(prop->type), srna->identifier, strnest, prop->identifier);
02192 
02193         if(prop->next) fprintf(f, "\t{(PropertyRNA*)&rna_%s%s_%s, ", srna->identifier, strnest, prop->next->identifier);
02194         else fprintf(f, "\t{NULL, ");
02195         if(prop->prev) fprintf(f, "(PropertyRNA*)&rna_%s%s_%s,\n", srna->identifier, strnest, prop->prev->identifier);
02196         else fprintf(f, "NULL,\n");
02197         fprintf(f, "\t%d, ", prop->magic);
02198         rna_print_c_string(f, prop->identifier);
02199         fprintf(f, ", %d, ", prop->flag);
02200         rna_print_c_string(f, prop->name); fprintf(f, ",\n\t");
02201         rna_print_c_string(f, prop->description); fprintf(f, ",\n\t");
02202         fprintf(f, "%d,\n", prop->icon);
02203         fprintf(f, "\t%s, %s|%s, %s, %d, {%d, %d, %d}, %d,\n", RNA_property_typename(prop->type), rna_property_subtypename(prop->subtype), rna_property_subtype_unit(prop->subtype), rna_function_string(prop->getlength), prop->arraydimension, prop->arraylength[0], prop->arraylength[1], prop->arraylength[2], prop->totarraylength);
02204         fprintf(f, "\t%s%s, %d, %s, %s,\n", (prop->flag & PROP_CONTEXT_UPDATE)? "(UpdateFunc)": "", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable), rna_function_string(prop->itemeditable));
02205 
02206         if(prop->flag & PROP_RAW_ACCESS) rna_set_raw_offset(f, srna, prop);
02207         else fprintf(f, "\t0, -1");
02208 
02209         /* our own type - collections/arrays only */
02210         if(prop->srna) fprintf(f, ", &RNA_%s", (char*)prop->srna);
02211         else fprintf(f, ", NULL");
02212 
02213         fprintf(f, "},\n");
02214 
02215         switch(prop->type) {
02216                         case PROP_BOOLEAN: {
02217                                 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
02218                                 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);
02219                                 if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
02220                                 else fprintf(f, "NULL\n");
02221                                 break;
02222                         }
02223                         case PROP_INT: {
02224                                 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
02225                                 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));
02226                                 rna_int_print(f, iprop->softmin); fprintf(f, ", ");
02227                                 rna_int_print(f, iprop->softmax); fprintf(f, ", ");
02228                                 rna_int_print(f, iprop->hardmin); fprintf(f, ", ");
02229                                 rna_int_print(f, iprop->hardmax); fprintf(f, ", ");
02230                                 rna_int_print(f, iprop->step); fprintf(f, ", ");
02231                                 rna_int_print(f, iprop->defaultvalue); fprintf(f, ", ");
02232                                 if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
02233                                 else fprintf(f, "NULL\n");
02234                                 break;
02235                          }
02236                         case PROP_FLOAT: {
02237                                 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
02238                                 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));
02239                                 rna_float_print(f, fprop->softmin); fprintf(f, ", ");
02240                                 rna_float_print(f, fprop->softmax); fprintf(f, ", ");
02241                                 rna_float_print(f, fprop->hardmin); fprintf(f, ", ");
02242                                 rna_float_print(f, fprop->hardmax); fprintf(f, ", ");
02243                                 rna_float_print(f, fprop->step); fprintf(f, ", ");
02244                                 rna_int_print(f, (int)fprop->precision); fprintf(f, ", ");
02245                                 rna_float_print(f, fprop->defaultvalue); fprintf(f, ", ");
02246                                 if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
02247                                 else fprintf(f, "NULL\n");
02248                                 break;
02249                          }
02250                         case PROP_STRING: {
02251                                 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
02252                                 fprintf(f, "\t%s, %s, %s, %d, ", rna_function_string(sprop->get), rna_function_string(sprop->length), rna_function_string(sprop->set), sprop->maxlength);
02253                                 rna_print_c_string(f, sprop->defaultvalue); fprintf(f, "\n");
02254                                 break;
02255                         }
02256                         case PROP_ENUM: {
02257                                 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
02258                                 fprintf(f, "\t%s, %s, %s, NULL, ", rna_function_string(eprop->get), rna_function_string(eprop->set), rna_function_string(eprop->itemf));
02259                                 if(eprop->item)
02260                                         fprintf(f, "rna_%s%s_%s_items, ", srna->identifier, strnest, prop->identifier);
02261                                 else
02262                                         fprintf(f, "NULL, ");
02263                                 fprintf(f, "%d, %d\n", eprop->totitem, eprop->defaultvalue);
02264                                 break;
02265                         }
02266                         case PROP_POINTER: {
02267                                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
02268                                 fprintf(f, "\t%s, %s, %s, %s,", rna_function_string(pprop->get), rna_function_string(pprop->set), rna_function_string(pprop->typef), rna_function_string(pprop->poll));
02269                                 if(pprop->type) fprintf(f, "&RNA_%s\n", (char*)pprop->type);
02270                                 else fprintf(f, "NULL\n");
02271                                 break;
02272                          }
02273                         case PROP_COLLECTION: {
02274                                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
02275                                 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));
02276                                 if(cprop->item_type) fprintf(f, "&RNA_%s\n", (char*)cprop->item_type);
02277                                 else fprintf(f, "NULL\n");
02278                                 break;
02279                         }
02280         }
02281 
02282         fprintf(f, "};\n\n");
02283 
02284         if(freenest) {
02285                 MEM_freeN(strnest);
02286                 MEM_freeN(errnest);
02287         }
02288 }
02289 
02290 static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
02291 {
02292         FunctionRNA *func;
02293         FunctionDefRNA *dfunc;
02294         PropertyRNA *prop, *parm;
02295         StructRNA *base;
02296 
02297         fprintf(f, "/* %s */\n", srna->name);
02298 
02299         for(prop= srna->cont.properties.first; prop; prop= prop->next)
02300                 rna_generate_property(f, srna, NULL, prop);
02301 
02302         for(func= srna->functions.first; func; func= func->cont.next) {
02303                 for(parm= func->cont.properties.first; parm; parm= parm->next)
02304                         rna_generate_property(f, srna, func->identifier, parm);
02305 
02306                 fprintf(f, "%s%s rna_%s_%s_func = {\n", "", "FunctionRNA", srna->identifier, func->identifier);
02307 
02308                 if(func->cont.next) fprintf(f, "\t{(FunctionRNA*)&rna_%s_%s_func, ", srna->identifier, ((FunctionRNA*)func->cont.next)->identifier);
02309                 else fprintf(f, "\t{NULL, ");
02310                 if(func->cont.prev) fprintf(f, "(FunctionRNA*)&rna_%s_%s_func,\n", srna->identifier, ((FunctionRNA*)func->cont.prev)->identifier);
02311                 else fprintf(f, "NULL,\n");
02312 
02313                 fprintf(f, "\tNULL,\n");
02314 
02315                 parm= func->cont.properties.first;
02316                 if(parm) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s_%s, ", srna->identifier, func->identifier, parm->identifier);
02317                 else fprintf(f, "\t{NULL, ");
02318 
02319                 parm= func->cont.properties.last;
02320                 if(parm) fprintf(f, "(PropertyRNA*)&rna_%s_%s_%s}},\n", srna->identifier, func->identifier, parm->identifier);
02321                 else fprintf(f, "NULL}},\n");
02322 
02323                 fprintf(f, "\t");
02324                 rna_print_c_string(f, func->identifier);
02325                 fprintf(f, ", %d, ", func->flag);
02326                 rna_print_c_string(f, func->description); fprintf(f, ",\n");
02327 
02328                 dfunc= rna_find_function_def(func);
02329                 if(dfunc->gencall) fprintf(f, "\t%s,\n", dfunc->gencall);
02330                 else fprintf(f, "\tNULL,\n");
02331 
02332                 if(func->c_ret) fprintf(f, "\t(PropertyRNA*)&rna_%s_%s_%s\n", srna->identifier, func->identifier, func->c_ret->identifier);
02333                 else fprintf(f, "\tNULL\n");
02334 
02335                 fprintf(f, "};\n");
02336                 fprintf(f, "\n");
02337         }
02338 
02339         fprintf(f, "StructRNA RNA_%s = {\n", srna->identifier);
02340 
02341         if(srna->cont.next) fprintf(f, "\t{(ContainerRNA *)&RNA_%s, ", ((StructRNA*)srna->cont.next)->identifier);
02342         else fprintf(f, "\t{NULL, ");
02343         if(srna->cont.prev) fprintf(f, "(ContainerRNA *)&RNA_%s,\n", ((StructRNA*)srna->cont.prev)->identifier);
02344         else fprintf(f, "NULL,\n");
02345 
02346         fprintf(f, "\tNULL,\n");
02347 
02348         prop= srna->cont.properties.first;
02349         if(prop) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->identifier);
02350         else fprintf(f, "\t{NULL, ");
02351 
02352         prop= srna->cont.properties.last;
02353         if(prop) fprintf(f, "(PropertyRNA*)&rna_%s_%s}},\n", srna->identifier, prop->identifier);
02354         else fprintf(f, "NULL}},\n");
02355         fprintf(f, "\t");
02356         rna_print_c_string(f, srna->identifier);
02357         fprintf(f, "\t, NULL,NULL\n"); /* PyType - Cant initialize here */
02358         fprintf(f, ", %d, ", srna->flag);
02359         rna_print_c_string(f, srna->name);
02360         fprintf(f, ", ");
02361         rna_print_c_string(f, srna->description);
02362         fprintf(f, ",\n\t%d,\n", srna->icon);
02363 
02364         prop= srna->nameproperty;
02365         if(prop) {
02366                 base= srna;
02367                 while (base->base && base->base->nameproperty==prop)
02368                         base= base->base;
02369 
02370                 fprintf(f, "\t(PropertyRNA*)&rna_%s_%s, ", base->identifier, prop->identifier);
02371         }
02372         else fprintf(f, "\tNULL, ");
02373 
02374         prop= srna->iteratorproperty;
02375         base= srna;
02376         while (base->base && base->base->iteratorproperty==prop)
02377                 base= base->base;
02378         fprintf(f, "(PropertyRNA*)&rna_%s_rna_properties,\n", base->identifier);
02379 
02380         if(srna->base) fprintf(f, "\t&RNA_%s,\n", srna->base->identifier);
02381         else fprintf(f, "\tNULL,\n");
02382 
02383         if(srna->nested) fprintf(f, "\t&RNA_%s,\n", srna->nested->identifier);
02384         else fprintf(f, "\tNULL,\n");
02385 
02386         fprintf(f, "\t%s,\n", rna_function_string(srna->refine));
02387         fprintf(f, "\t%s,\n", rna_function_string(srna->path));
02388         fprintf(f, "\t%s,\n", rna_function_string(srna->reg));
02389         fprintf(f, "\t%s,\n", rna_function_string(srna->unreg));
02390         fprintf(f, "\t%s,\n", rna_function_string(srna->instance));
02391         fprintf(f, "\t%s,\n", rna_function_string(srna->idproperties));
02392 
02393         if(srna->reg && !srna->refine) {
02394                 fprintf(stderr, "rna_generate_struct: %s has a register function, must also have refine function.\n", srna->identifier);
02395                 DefRNA.error= 1;
02396         }
02397 
02398         func= srna->functions.first;
02399         if(func) fprintf(f, "\t{(FunctionRNA*)&rna_%s_%s_func, ", srna->identifier, func->identifier);
02400         else fprintf(f, "\t{NULL, ");
02401 
02402         func= srna->functions.last;
02403         if(func) fprintf(f, "(FunctionRNA*)&rna_%s_%s_func}\n", srna->identifier, func->identifier);
02404         else fprintf(f, "NULL}\n");
02405 
02406         fprintf(f, "};\n");
02407 
02408         fprintf(f, "\n");
02409 }
02410 
02411 typedef struct RNAProcessItem {
02412         const char *filename;
02413         const char *api_filename;
02414         void (*define)(BlenderRNA *brna);
02415 } RNAProcessItem;
02416 
02417 static RNAProcessItem PROCESS_ITEMS[]= {
02418         {"rna_rna.c", NULL, RNA_def_rna},
02419         {"rna_ID.c", NULL, RNA_def_ID},
02420         {"rna_texture.c", NULL, RNA_def_texture},
02421         {"rna_action.c", "rna_action_api.c", RNA_def_action},
02422         {"rna_animation.c", "rna_animation_api.c", RNA_def_animation},
02423         {"rna_animviz.c", NULL, RNA_def_animviz},
02424         {"rna_actuator.c", "rna_actuator_api.c", RNA_def_actuator},
02425         {"rna_armature.c", "rna_armature_api.c", RNA_def_armature},
02426         {"rna_boid.c", NULL, RNA_def_boid},
02427         {"rna_brush.c", NULL, RNA_def_brush},
02428         {"rna_camera.c", NULL, RNA_def_camera},
02429         {"rna_cloth.c", NULL, RNA_def_cloth},
02430         {"rna_color.c", NULL, RNA_def_color},
02431         {"rna_constraint.c", NULL, RNA_def_constraint},
02432         {"rna_context.c", NULL, RNA_def_context},
02433         {"rna_controller.c", "rna_controller_api.c", RNA_def_controller},
02434         {"rna_curve.c", NULL, RNA_def_curve},
02435         {"rna_fcurve.c", "rna_fcurve_api.c", RNA_def_fcurve},
02436         {"rna_fluidsim.c", NULL, RNA_def_fluidsim},
02437         {"rna_gpencil.c", NULL, RNA_def_gpencil},
02438         {"rna_group.c", NULL, RNA_def_group},
02439         {"rna_image.c", "rna_image_api.c", RNA_def_image},
02440         {"rna_key.c", NULL, RNA_def_key},
02441         {"rna_lamp.c", NULL, RNA_def_lamp},
02442         {"rna_lattice.c", NULL, RNA_def_lattice},
02443         {"rna_main.c", "rna_main_api.c", RNA_def_main},
02444         {"rna_material.c", "rna_material_api.c", RNA_def_material},
02445         {"rna_mesh.c", "rna_mesh_api.c", RNA_def_mesh},
02446         {"rna_meta.c", NULL, RNA_def_meta},
02447         {"rna_modifier.c", NULL, RNA_def_modifier},
02448         {"rna_nla.c", NULL, RNA_def_nla},
02449         {"rna_nodetree.c", NULL, RNA_def_nodetree},
02450         {"rna_object.c", "rna_object_api.c", RNA_def_object},
02451         {"rna_object_force.c", NULL, RNA_def_object_force},
02452         {"rna_packedfile.c", NULL, RNA_def_packedfile},
02453         {"rna_particle.c", NULL, RNA_def_particle},
02454         {"rna_pose.c", "rna_pose_api.c", RNA_def_pose},
02455         {"rna_property.c", NULL, RNA_def_gameproperty},
02456         {"rna_render.c", NULL, RNA_def_render},
02457         {"rna_scene.c", "rna_scene_api.c", RNA_def_scene},
02458         {"rna_screen.c", NULL, RNA_def_screen},
02459         {"rna_sculpt_paint.c", NULL, RNA_def_sculpt_paint},
02460         {"rna_sensor.c", "rna_sensor_api.c", RNA_def_sensor},
02461         {"rna_sequencer.c", "rna_sequencer_api.c", RNA_def_sequencer},
02462         {"rna_smoke.c", NULL, RNA_def_smoke},
02463         {"rna_space.c", NULL, RNA_def_space},
02464         {"rna_test.c", NULL, RNA_def_test},
02465         {"rna_text.c", NULL, RNA_def_text},
02466         {"rna_timeline.c", NULL, RNA_def_timeline_marker},
02467         {"rna_sound.c", NULL, RNA_def_sound},
02468         {"rna_ui.c", "rna_ui_api.c", RNA_def_ui},
02469         {"rna_userdef.c", NULL, RNA_def_userdef},
02470         {"rna_vfont.c", NULL, RNA_def_vfont},
02471         {"rna_wm.c", "rna_wm_api.c", RNA_def_wm},
02472         {"rna_world.c", NULL, RNA_def_world},   
02473         {NULL, NULL}};
02474 
02475 static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const char *api_filename)
02476 {
02477         StructDefRNA *ds;
02478         PropertyDefRNA *dp;
02479         FunctionDefRNA *dfunc;
02480         
02481         fprintf(f, "\n/* Automatically generated struct definitions for the Data API.\n"
02482                                  "   Do not edit manually, changes will be overwritten.           */\n\n"
02483                                   "#define RNA_RUNTIME\n\n");
02484 
02485         fprintf(f, "#include <float.h>\n");
02486         fprintf(f, "#include <stdio.h>\n");
02487         fprintf(f, "#include <limits.h>\n");
02488         fprintf(f, "#include <string.h>\n\n");
02489         fprintf(f, "#include <stddef.h>\n\n");
02490 
02491         fprintf(f, "#include \"DNA_ID.h\"\n");
02492         fprintf(f, "#include \"DNA_scene_types.h\"\n");
02493 
02494         fprintf(f, "#include \"BLI_blenlib.h\"\n\n");
02495         fprintf(f, "#include \"BLI_utildefines.h\"\n\n");
02496 
02497         fprintf(f, "#include \"BKE_context.h\"\n");
02498         fprintf(f, "#include \"BKE_library.h\"\n");
02499         fprintf(f, "#include \"BKE_main.h\"\n");
02500         fprintf(f, "#include \"BKE_report.h\"\n");
02501 
02502         fprintf(f, "#include \"RNA_define.h\"\n");
02503         fprintf(f, "#include \"RNA_types.h\"\n");
02504         fprintf(f, "#include \"rna_internal.h\"\n\n");
02505 
02506         rna_generate_prototypes(brna, f);
02507 
02508         fprintf(f, "#include \"%s\"\n", filename);
02509         if(api_filename)
02510                 fprintf(f, "#include \"%s\"\n", api_filename);
02511         fprintf(f, "\n");
02512 
02513         fprintf(f, "/* Autogenerated Functions */\n\n");
02514 
02515         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) {
02516                 if(!filename || ds->filename == filename) {
02517                         rna_generate_property_prototypes(brna, ds->srna, f);
02518                         rna_generate_function_prototypes(brna, ds->srna, f);
02519                 }
02520         }
02521 
02522         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next)
02523                 if(!filename || ds->filename == filename)
02524                         for(dp=ds->cont.properties.first; dp; dp=dp->next)
02525                                 rna_def_property_funcs(f, ds->srna, dp);
02526 
02527         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) {
02528                 if(!filename || ds->filename == filename) {
02529                         for(dfunc=ds->functions.first; dfunc; dfunc= dfunc->cont.next)
02530                                 rna_def_function_funcs(f, ds, dfunc);
02531 
02532                         rna_generate_static_function_prototypes(brna, ds->srna, f);
02533                 }
02534         }
02535 
02536         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next)
02537                 if(!filename || ds->filename == filename)
02538                         rna_generate_struct(brna, ds->srna, f);
02539 
02540         if(strcmp(filename, "rna_ID.c") == 0) {
02541                 /* this is ugly, but we cannot have c files compiled for both
02542                  * makesrna and blender with some build systems at the moment */
02543                 fprintf(f, "#include \"rna_define.c\"\n\n");
02544 
02545                 rna_generate_blender(brna, f);
02546         }
02547 }
02548 
02549 static void rna_generate_header(BlenderRNA *brna, FILE *f)
02550 {
02551         StructDefRNA *ds;
02552         PropertyDefRNA *dp;
02553         StructRNA *srna;
02554 
02555         fprintf(f, "\n#ifndef __RNA_BLENDER_H__\n");
02556         fprintf(f, "#define __RNA_BLENDER_H__\n\n");
02557 
02558         fprintf(f, "/* Automatically generated function declarations for the Data API.\n"
02559                                  "   Do not edit manually, changes will be overwritten.              */\n\n");
02560 
02561         fprintf(f, "#include \"RNA_types.h\"\n\n");
02562 
02563         fprintf(f, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n");
02564 
02565         fprintf(f, "#define FOREACH_BEGIN(property, sptr, itemptr) \\\n");
02566         fprintf(f, "    { \\\n");
02567         fprintf(f, "            CollectionPropertyIterator rna_macro_iter; \\\n");
02568         fprintf(f, "            for(property##_begin(&rna_macro_iter, sptr); rna_macro_iter.valid; property##_next(&rna_macro_iter)) { \\\n");
02569         fprintf(f, "                    itemptr= rna_macro_iter.ptr;\n\n");
02570 
02571         fprintf(f, "#define FOREACH_END(property) \\\n");
02572         fprintf(f, "            } \\\n");
02573         fprintf(f, "            property##_end(&rna_macro_iter); \\\n");
02574         fprintf(f, "    }\n\n");
02575 
02576         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) {
02577                 srna= ds->srna;
02578 
02579                 fprintf(f, "/**************** %s ****************/\n\n", srna->name);
02580 
02581                 while(srna) {
02582                         fprintf(f, "extern StructRNA RNA_%s;\n", srna->identifier);
02583                         srna= srna->base;
02584                 }
02585                 fprintf(f, "\n");
02586 
02587                 for(dp=ds->cont.properties.first; dp; dp=dp->next)
02588                         rna_def_property_funcs_header(f, ds->srna, dp);
02589         }
02590 
02591         fprintf(f, "#ifdef __cplusplus\n}\n#endif\n\n");
02592 
02593         fprintf(f, "#endif /* __RNA_BLENDER_H__ */\n\n");
02594 }
02595 
02596 static const char *cpp_classes = ""
02597 "\n"
02598 "#include <string>\n"
02599 "\n"
02600 "namespace BL {\n"
02601 "\n"
02602 "#define BOOLEAN_PROPERTY(sname, identifier) \\\n"
02603 "       inline bool sname::identifier(void) { return sname##_##identifier##_get(&ptr)? true: false; }\n"
02604 "\n"
02605 "#define BOOLEAN_ARRAY_PROPERTY(sname, size, identifier) \\\n"
02606 "       inline Array<int,size> sname::identifier(void) \\\n"
02607 "               { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n"
02608 "\n"
02609 "#define INT_PROPERTY(sname, identifier) \\\n"
02610 "       inline int sname::identifier(void) { return sname##_##identifier##_get(&ptr); }\n"
02611 "\n"
02612 "#define INT_ARRAY_PROPERTY(sname, size, identifier) \\\n"
02613 "       inline Array<int,size> sname::identifier(void) \\\n"
02614 "               { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n"
02615 "\n"
02616 "#define FLOAT_PROPERTY(sname, identifier) \\\n"
02617 "       inline float sname::identifier(void) { return sname##_##identifier##_get(&ptr); }\n"
02618 "\n"
02619 "#define FLOAT_ARRAY_PROPERTY(sname, size, identifier) \\\n"
02620 "       inline Array<float,size> sname::identifier(void) \\\n"
02621 "               { Array<float, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n"
02622 "\n"
02623 "#define ENUM_PROPERTY(type, sname, identifier) \\\n"
02624 "       inline sname::type sname::identifier(void) { return (type)sname##_##identifier##_get(&ptr); }\n"
02625 "\n"
02626 "#define STRING_PROPERTY(sname, identifier) \\\n"
02627 "       inline std::string sname::identifier(void) { \\\n"
02628 "               int len= sname##_##identifier##_length(&ptr); \\\n"
02629 "               std::string str; str.resize(len); \\\n"
02630 "               sname##_##identifier##_get(&ptr, &str[0]); return str; } \\\n"
02631 "\n"
02632 "#define POINTER_PROPERTY(type, sname, identifier) \\\n"
02633 "       inline type sname::identifier(void) { return type(sname##_##identifier##_get(&ptr)); }\n"
02634 "\n"
02635 "#define COLLECTION_PROPERTY(type, sname, identifier) \\\n"
02636 "       typedef CollectionIterator<type, sname##_##identifier##_begin, \\\n"
02637 "               sname##_##identifier##_next, sname##_##identifier##_end> identifier##_iterator; \\\n"
02638 "       Collection<sname, type, sname##_##identifier##_begin, \\\n"
02639 "               sname##_##identifier##_next, sname##_##identifier##_end> identifier;\n"
02640 "\n"
02641 "class Pointer {\n"
02642 "public:\n"
02643 "       Pointer(const PointerRNA& p) : ptr(p) { }\n"
02644 "       operator const PointerRNA&() { return ptr; }\n"
02645 "       bool is_a(StructRNA *type) { return RNA_struct_is_a(ptr.type, type)? true: false; }\n"
02646 "       operator void*() { return ptr.data; }\n"
02647 "       operator bool() { return ptr.data != NULL; }\n"
02648 "\n"
02649 "       PointerRNA ptr;\n"
02650 "};\n"
02651 "\n"
02652 "\n"
02653 "template<typename T, int Tsize>\n"
02654 "class Array {\n"
02655 "public:\n"
02656 "       T data[Tsize];\n"
02657 "       operator T*() { return data; }\n"
02658 "};\n"
02659 "\n"
02660 "typedef void (*TBeginFunc)(CollectionPropertyIterator *iter, PointerRNA *ptr);\n"
02661 "typedef void (*TNextFunc)(CollectionPropertyIterator *iter);\n"
02662 "typedef void (*TEndFunc)(CollectionPropertyIterator *iter);\n"
02663 "\n"
02664 "template<typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n"
02665 "class CollectionIterator {\n"
02666 "public:\n"
02667 "       CollectionIterator() : t(iter.ptr), init(false) { iter.valid= false; }\n"
02668 "       ~CollectionIterator(void) { if(init) Tend(&iter); };\n"
02669 "\n"
02670 "       operator bool(void)\n"
02671 "       { return iter.valid != 0; }\n"
02672 "       const CollectionIterator<T, Tbegin, Tnext, Tend>& operator++() { Tnext(&iter); t = T(iter.ptr); return *this; }\n"
02673 "       const CollectionIterator<T, Tbegin, Tnext, Tend>& operator=(const CollectionIterator<T, Tbegin, Tnext, Tend>& copy)\n"
02674 "       { 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"
02675 "\n"
02676 "       T& operator*(void) { return t; }\n"
02677 "       T* operator->(void) { return &t; }\n"
02678 "       bool operator==(const CollectionIterator<T, Tbegin, Tnext, Tend>& other) { return iter.valid == other.iter.valid; }\n"
02679 "       bool operator!=(const CollectionIterator<T, Tbegin, Tnext, Tend>& other) { return iter.valid != other.iter.valid; }\n"
02680 "\n"
02681 "       void begin(const Pointer& ptr)\n"
02682 "       { if(init) Tend(&iter); Tbegin(&iter, (PointerRNA*)&ptr.ptr); t = T(iter.ptr); init = true; }\n"
02683 "\n"
02684 "private:\n"
02685 "       CollectionPropertyIterator iter;\n"
02686 "       T t;\n"
02687 "       bool init;\n"
02688 "};\n"
02689 "\n"
02690 "template<typename Tp, typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n"
02691 "class Collection {\n"
02692 "public:\n"
02693 "       Collection(const PointerRNA& p) : ptr(p) {}\n"
02694 "\n"
02695 "       CollectionIterator<T, Tbegin, Tnext, Tend> begin()\n"
02696 "       { CollectionIterator<T, Tbegin, Tnext, Tend> iter; iter.begin(ptr); return iter; }\n"
02697 "       CollectionIterator<T, Tbegin, Tnext, Tend> end()\n"
02698 "       { return CollectionIterator<T, Tbegin, Tnext, Tend>(); } /* test */ \n"
02699 "\n"
02700 "private:\n"
02701 "       PointerRNA ptr;\n"
02702 "};\n"
02703 "\n";
02704 
02705 static void rna_generate_header_cpp(BlenderRNA *brna, FILE *f)
02706 {
02707         StructDefRNA *ds;
02708         PropertyDefRNA *dp;
02709         StructRNA *srna;
02710 
02711         fprintf(f, "\n#ifndef __RNA_BLENDER_CPP_H__\n");
02712         fprintf(f, "#define __RNA_BLENDER_CPP_H__\n\n");
02713 
02714         fprintf(f, "/* Automatically generated classes for the Data API.\n"
02715                                  "   Do not edit manually, changes will be overwritten. */\n\n");
02716         
02717         fprintf(f, "#include \"RNA_blender.h\"\n");
02718         fprintf(f, "#include \"RNA_types.h\"\n");
02719 
02720         fprintf(f, "%s", cpp_classes);
02721 
02722         fprintf(f, "/**************** Declarations ****************/\n\n");
02723 
02724         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next)
02725                 fprintf(f, "class %s;\n", ds->srna->identifier);
02726         fprintf(f, "\n");
02727 
02728         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) {
02729                 srna= ds->srna;
02730 
02731                 fprintf(f, "/**************** %s ****************/\n\n", srna->name);
02732 
02733                 fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base)? srna->base->identifier: "Pointer");
02734                 fprintf(f, "public:\n");
02735                 fprintf(f, "\t%s(const PointerRNA& ptr) :\n\t\t%s(ptr)", srna->identifier, (srna->base)? srna->base->identifier: "Pointer");
02736                 for(dp=ds->cont.properties.first; dp; dp=dp->next)
02737                         if(!(dp->prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN)))
02738                                 if(dp->prop->type == PROP_COLLECTION)
02739                                         fprintf(f, ",\n\t\t%s(ptr)", dp->prop->identifier);
02740                 fprintf(f, "\n\t\t{}\n\n");
02741 
02742                 for(dp=ds->cont.properties.first; dp; dp=dp->next)
02743                         rna_def_property_funcs_header_cpp(f, ds->srna, dp);
02744                 fprintf(f, "};\n\n");
02745         }
02746 
02747 
02748         fprintf(f, "/**************** Implementation ****************/\n");
02749 
02750         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next) {
02751                 for(dp=ds->cont.properties.first; dp; dp=dp->next)
02752                         rna_def_property_funcs_impl_cpp(f, ds->srna, dp);
02753 
02754                 fprintf(f, "\n");
02755         }
02756 
02757         fprintf(f, "}\n\n#endif /* __RNA_BLENDER_CPP_H__ */\n\n");
02758 }
02759 
02760 static void make_bad_file(char *file, int line)
02761 {
02762         FILE *fp= fopen(file, "w");
02763         fprintf(fp, "#error \"Error! can't make correct RNA file from %s:%d, STUPID!\"\n", __FILE__, line);
02764         fclose(fp);
02765 }
02766 
02767 static int rna_preprocess(char *outfile)
02768 {
02769         BlenderRNA *brna;
02770         StructDefRNA *ds;
02771         FILE *file;
02772         char deffile[4096];
02773         int i, status;
02774         const char *deps[3]; /* expand as needed */
02775 
02776         /* define rna */
02777         brna= RNA_create();
02778 
02779         for(i=0; PROCESS_ITEMS[i].filename; i++) {
02780                 if(PROCESS_ITEMS[i].define) {
02781                         PROCESS_ITEMS[i].define(brna);
02782 
02783                         for(ds=DefRNA.structs.first; ds; ds=ds->cont.next)
02784                                 if(!ds->filename)
02785                                         ds->filename= PROCESS_ITEMS[i].filename;
02786                 }
02787         }
02788 
02789         rna_auto_types();
02790 
02791 
02792         /* create RNA_blender_cpp.h */
02793         strcpy(deffile, outfile);
02794         strcat(deffile, "RNA_blender_cpp.h" TMP_EXT);
02795 
02796         status= (DefRNA.error != 0);
02797 
02798         if(status) {
02799                 make_bad_file(deffile, __LINE__);
02800         }
02801         else {
02802                 file = fopen(deffile, "w");
02803 
02804                 if(!file) {
02805                         printf ("Unable to open file: %s\n", deffile);
02806                         status = 1;
02807                 }
02808                 else {
02809                         rna_generate_header_cpp(brna, file);
02810                         fclose(file);
02811                         status= (DefRNA.error != 0);
02812                 }
02813         }
02814 
02815         replace_if_different(deffile, NULL);
02816 
02817         rna_sort(brna);
02818 
02819         /* create rna_gen_*.c files */
02820         for(i=0; PROCESS_ITEMS[i].filename; i++) {
02821                 strcpy(deffile, outfile);
02822                 strcat(deffile, PROCESS_ITEMS[i].filename);
02823                 deffile[strlen(deffile)-2] = '\0';
02824                 strcat(deffile, "_gen.c" TMP_EXT);
02825 
02826                 if(status) {
02827                         make_bad_file(deffile, __LINE__);
02828                 }
02829                 else {
02830                         file = fopen(deffile, "w");
02831 
02832                         if(!file) {
02833                                 printf ("Unable to open file: %s\n", deffile);
02834                                 status = 1;
02835                         }
02836                         else {
02837                                 rna_generate(brna, file, PROCESS_ITEMS[i].filename, PROCESS_ITEMS[i].api_filename);
02838                                 fclose(file);
02839                                 status= (DefRNA.error != 0);
02840                         }
02841                 }
02842 
02843                 /* avoid unneeded rebuilds */
02844                 deps[0]= PROCESS_ITEMS[i].filename;
02845                 deps[1]= PROCESS_ITEMS[i].api_filename;
02846                 deps[2]= NULL;
02847 
02848                 replace_if_different(deffile, deps);
02849         }
02850 
02851         /* create RNA_blender.h */
02852         strcpy(deffile, outfile);
02853         strcat(deffile, "RNA_blender.h" TMP_EXT);
02854 
02855         if(status) {
02856                 make_bad_file(deffile, __LINE__);
02857         }
02858         else {
02859                 file = fopen(deffile, "w");
02860 
02861                 if(!file) {
02862                         printf ("Unable to open file: %s\n", deffile);
02863                         status = 1;
02864                 }
02865                 else {
02866                         rna_generate_header(brna, file);
02867                         fclose(file);
02868                         status= (DefRNA.error != 0);
02869                 }
02870         }
02871 
02872         replace_if_different(deffile, NULL);
02873 
02874         /* free RNA */
02875         RNA_define_free(brna);
02876         RNA_free(brna);
02877 
02878         return status;
02879 }
02880 
02881 static void mem_error_cb(const char *errorStr)
02882 {
02883         fprintf(stderr, "%s", errorStr);
02884         fflush(stderr);
02885 }
02886 
02887 int main(int argc, char **argv)
02888 {
02889         int totblock, return_status = 0;
02890 
02891         if(argc<2) {
02892                 printf("Usage: %s outdirectory/\n", argv[0]);
02893                 return_status = 1;
02894         }
02895         else {
02896                 printf("Running makesrna, program versions %s\n",  RNA_VERSION_DATE);
02897                 makesrna_path= argv[0];
02898                 return_status= rna_preprocess(argv[1]);
02899         }
02900 
02901         totblock= MEM_get_memory_blocks_in_use();
02902         if(totblock!=0) {
02903                 printf("Error Totblock: %d\n",totblock);
02904                 MEM_set_error_callback(mem_error_cb);
02905                 MEM_printmemlist();
02906         }
02907 
02908         return return_status;
02909 }
02910 
02911