Blender V2.61 - r43446

makesrna.c

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