/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 2002 by NaN Holding BV. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ /** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 2002 by NaN Holding BV. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ /* genfile.c juni 94 MIXED MODEL * * - pas op: geen beveiling tegen dubbele structen * - struct niet in DNA file: twee hekjes erboven (##) * */ #include "blender.h" #include "screen.h" #include "file.h" /* Internal prototypes */ void calculate_structlens(void); /* Aanmaken structDNA: alleen wanneer includes wijzigen. File Syntax: SDNA (4 bytes) (voor fileherkenning) NAME (4 bytes) (4 bytes) aantal namen (int) ... ... TYPE (4 bytes) aantal types (int) ... ... TLEN (4 bytes) (short) ... ... STRC (4 bytes) aantal structen (int) ... !!Denk aan integer en short aligned schrijven/lezen!! Bij het wegschrijven van files worden namen structen aangegeven met type= findstruct_nr(SDNA *, char *), 'type' correspondeert met nummer structarray in structDNA. Voor het moment: complete DNA file appenden achter blenderfile. In toekomst nadenken over slimmere methode (alleen gebruikte structen?, voorgeprepareerde DNA files? (TOT, OB, MAT ) TOEGESTANE EN GETESTE WIJZIGINGEN IN STRUCTS: - type verandering (bij chars naar float wordt door 255 gedeeld) - plek in struct (alles kan door elkaar) - struct in struct (in struct etc, is recursief) - nieuwe elementen toevoegen (standaard op 0) - elementen eruit (worden niet meer ingelezen) - array's groter/kleiner - verschillende typepointers met zelfde naam worden altijd gekopieerd. (NOG) NIET: - float-array (vec[3]) naar struct van floats (vec3f) GEDAAN: - DNA file in (achter) blender-executable plakken voor upward compatibility Gebruikte methode: het makesdna programma schrijft een c-file met een met spaties gevuld char-array van de juiste lengte. Makesdna maakt er een .o van en vult de spaties met de DNA file. - endian compatibility - 32 bits en 64 bits pointers LET OP: - uint mag niet in een struct, gebruik unsigned int. (backwards compatibility vanwege 64 bits code!) - structen moeten altijd (intern) 4/8-aligned en short-aligned zijn. de SDNA routine test hierop en print duidelijke errors. DNA files met align errors zijn onbruikbaar! - switch_endian doet alleen long long pointers, zodat ze veilig gecast kunnen worden naar 32 bits - casten van 64 naar 32 bits poinetrs: >>3. */ struct SDNA cur_sdna={0, 0, }, old_sdna={0, 0, }; int maxdata= 100000, maxnr= 5000; int switch_endian= 0; int nr_names=0; int nr_types=0; int nr_structs=0; char **names, *namedata; /* op adres names[a] staat string a */ char **types, *typedata; /* op adres types[a] staat string a */ short *typelens; /* op typelens[a] staat de lengte van type a */ short **structs, *structdata; /* op sp= structs[a] staat eerste adres structdefinitie sp[0] is typenummer sp[1] is aantal elementen sp[2] sp[3] is typenr, namenr (enz) */ char *compflags=0; /* ************************* MAKEN DNA ********************** */ int add_type(char *str, int len) { int nr; char *cp; if(str[0]==0) return -1; /* zoek typearray door */ for(nr=0; nr=maxnr) { printf("too many types\n"); return nr_types-1;; } nr_types++; return nr_types-1; } int add_name(char *str) { int nr; char *cp; if(str[0]==0) return -1; /* zoek name array door */ for(nr=0; nr=maxnr) { printf("too many names\n"); return nr_names-1; } nr_names++; return nr_names-1; } short *add_struct(int namecode) { int len; short *sp; if(nr_structs==0) { structs[0]= structdata; } else { sp= structs[nr_structs-1]; len= sp[1]; structs[nr_structs]= sp+ 2*len+2; } sp= structs[nr_structs]; sp[0]= namecode; if(nr_structs>=maxnr) { printf("too many structs\n"); return sp; } nr_structs++; return sp; } int preprocess_include(char *maindata, int len) { int a, newlen, comment; char *cp, *temp, *md; temp= mallocN(len, "preprocess_include"); memcpy(temp, maindata, len); /* alle enters/tabs/etc vervangen door spaties */ cp= temp; a= len; while(a--) { if( *cp<32 || *cp>128 ) *cp= 32; cp++; } /* data uit temp naar maindata kopieeren, verwijder commentaar en dubbele spaties */ cp= temp; md= maindata; newlen= 0; comment= 0; a= len; while(a--) { if(cp[0]=='/' && cp[1]=='*') { comment= 1; cp[0]=cp[1]= 32; } if(cp[0]=='*' && cp[1]=='/') { comment= 0; cp[0]=cp[1]= 32; } /* niet kopieeren als: */ if(comment); else if( cp[0]==' ' && cp[1]==' ' ); else if( cp[-1]=='*' && cp[0]==' ' ); /* pointers met spatie */ else { md[0]= cp[0]; md++; newlen++; } cp++; } freeN(temp); return newlen; } void convert_include(char *filename) { /* lees includefile, sla structen over die op regel ervoor '#' hebben. sla alle data op in tijdelijke arrays. */ int a, file, filelen, count, overslaan, slen, type, name, strct; short *structpoin, *sp; char *maindata, *mainend, *md, *md1; file= open(filename, O_BINARY|O_RDONLY); if(file== -1) { printf("Can't read file %s\n", filename); } else { filelen= filesize(file); md= maindata= mallocN(filelen, "convert_include"); read(file, maindata, filelen); close(file); filelen= preprocess_include(maindata, filelen); mainend= maindata+filelen-1; /* we zoeken naar '{' en dan terug naar 'struct' */ count= 0; overslaan= 0; while(count ((long)mainend) ) break; if(*md1==',' || *md1==' ') *md1= 0; md1++; } /* types en namen lezen tot eerste karakter niet '}' */ md1= md+1; while( *md1 != '}' ) { if( ((long)md1) > ((long)mainend) ) break; /* als er 'struct' of 'unsigned' staat, overslaan */ if(*md1) { if( strncmp(md1, "struct", 6)==0 ) md1+= 7; if( strncmp(md1, "unsigned", 6)==0 ) md1+= 9; /* type te pakken! */ type= add_type(md1, 0); md1+= strlen(md1); /* doorlezen tot ';' */ while( *md1 != ';' ) { if( ((long)md1) > ((long)mainend) ) break; if(*md1) { /* name te pakken */ slen= strlen(md1); if( md1[slen-1]==';' ) { md1[slen-1]= 0; name= add_name(md1); sp[0]= type; sp[1]= name; structpoin[1]++; sp+= 2; md1+= slen; break; } name= add_name(md1); sp[0]= type; sp[1]= name; structpoin[1]++; sp+= 2; md1+= slen; } md1++; } } md1++; } } } } count++; md++; } freeN(maindata); } } int arraysize(char *astr, int len) { int a, mul=1; char str[100], *cp=0; memcpy(str, astr, len+1); for(a=0; a3 && (len % 4) ) { printf("Align 4 error in struct: %s %s\n", types[structtype], cp); } else if(typelens[type]==2 && (len % 2) ) { printf("Align 2 error in struct: %s %s\n", types[structtype], cp); } len+= mul*typelens[type]; } else { len= 0; break; } } if(len==0) unknown++; else { typelens[structtype]= len; } } } if(unknown==lastunknown) break; } if(unknown) { printf("error: still %d structs unknown\n", unknown); for(a=0; adata) { freeN(sdna->data); sdna->data= 0; freeN(sdna->names); sdna->names= 0; freeN(sdna->types); sdna->types= 0; freeN(sdna->structs); sdna->structs= 0; } } void freestructDNA_all() { freestructDNA(&old_sdna); if(cur_sdna.data) { freeN(cur_sdna.names); cur_sdna.names= 0; freeN(cur_sdna.types); cur_sdna.types= 0; freeN(cur_sdna.structs); cur_sdna.structs= 0; } if(compflags) freeN(compflags); compflags= 0; } int elementsize(struct SDNA *sdna, short type, short name) /* aanroepen met nummers uit struct-array */ { int mul, namelen, len; char *cp; cp= sdna->names[name]; len= 0; namelen= strlen(cp); /* is het een pointer of functiepointer? */ if(cp[0]=='*' || cp[1]=='*') { /* heeft de naam een extra lente? (array) */ mul= 1; if( cp[namelen-1]==']') mul= arraysize(cp, namelen); len= sdna->pointerlen*mul; } else if( sdna->typelens[type] ) { /* heeft de naam een extra lente? (array) */ mul= 1; if( cp[namelen-1]==']') mul= arraysize(cp, namelen); len= mul*sdna->typelens[type]; } return len; } void printstruct(struct SDNA *sdna, short strnr) { /* geef het structnummer door, is voor debug */ int b, nr; short *sp; sp= sdna->structs[strnr]; printf("struct %s\n", sdna->types[ sp[0] ]); nr= sp[1]; sp+= 2; for(b=0; b< nr; b++, sp+= 2) { printf(" %s %s\n", sdna->types[sp[0]], sdna->names[sp[1]]); } } short *findstruct_name(struct SDNA *sdna, char *str) { int a; short *sp=0; for(a=0; anr_structs; a++) { sp= sdna->structs[a]; if(strcmp( sdna->types[ sp[0] ], str )==0) return sp; } return 0; } int findstruct_nr(struct SDNA *sdna, char *str) { static int lasta=0; int a; short *sp=0; if(lastanr_structs) { sp= sdna->structs[lasta]; if(strcmp( sdna->types[ sp[0] ], str )==0) return lasta; } for(a=0; anr_structs; a++) { sp= sdna->structs[a]; if(strcmp( sdna->types[ sp[0] ], str )==0) { lasta= a; return a; } } return -1; } /* ************************* END DIV ********************** */ /* ************************* LEZEN DNA ********************** */ void init_structDNA(struct SDNA *sdna) /* in sdna->data staat de data, uit elkaar pulken */ { int *data, *verg; long nr; short *sp; static char str[8], *cp; if(sdna->data==0) { bzero(sdna, sizeof(struct SDNA)); return; } verg= (int *)str; data= (int *)sdna->data; strcpy(str, "SDNA"); if( *data == *verg ) { data++; /* laad namen array */ strcpy(str, "NAME"); if( *data == *verg ) { data++; if(switch_endian) sdna->nr_names= le_int(*data); else sdna->nr_names= *data; data++; sdna->names= callocN( sizeof(void *)*sdna->nr_names, "sdnanames"); } else { printf("NAME error in SDNA file\n"); return; } nr= 0; cp= (char *)data; while(nrnr_names) { sdna->names[nr]= cp; while( *cp) cp++; cp++; nr++; } nr= (long)cp; /* BUS error voorkomen */ nr= (nr+3) & ~3; cp= (char *)nr; /* laad typenamen array */ data= (int *)cp; strcpy(str, "TYPE"); if( *data == *verg ) { data++; if(switch_endian) sdna->nr_types= le_int(*data); else sdna->nr_types= *data; data++; sdna->types= callocN( sizeof(void *)*sdna->nr_types, "sdnatypes"); } else { printf("TYPE error in SDNA file\n"); return; } nr= 0; cp= (char *)data; while(nrnr_types) { sdna->types[nr]= cp; /* met deze patch kunnen structnamen gewijzigd worden */ /* alleen gebruiken voor conflicten met systeem-structen (opengl/X) */ if( *cp == 'b') { /* struct Screen was already used by X, 'bScreen' replaces the old IrisGL 'Screen' struct */ if( strcmp("bScreen", cp)==0 ) sdna->types[nr]= cp+1; } while( *cp) cp++; cp++; nr++; } nr= (long)cp; /* BUS error voorkomen */ nr= (nr+3) & ~3; cp= (char *)nr; /* laad typelen array */ data= (int *)cp; strcpy(str, "TLEN"); if( *data == *verg ) { data++; sp= (short *)data; sdna->typelens= sp; if(switch_endian) { short a, *spo= sp; a= sdna->nr_types; while(a--) { spo[0]= le_short(spo[0]); spo++; } } sp+= sdna->nr_types; } else { printf("TLEN error in SDNA file\n"); return; } if(sdna->nr_types & 1) sp++; /* BUS error voorkomen */ /* laad structen array */ data= (int *)sp; strcpy(str, "STRC"); if( *data == *verg ) { data++; if(switch_endian) sdna->nr_structs= le_int(*data); else sdna->nr_structs= *data; data++; sdna->structs= callocN( sizeof(void *)*sdna->nr_types, "sdnatypes"); } else { printf("STRC error in SDNA file\n"); return; } nr= 0; sp= (short *)data; while(nrnr_structs) { sdna->structs[nr]= sp; if(switch_endian) { short a; sp[0]= le_short(sp[0]); sp[1]= le_short(sp[1]); a= sp[1]; sp+= 2; while(a--) { sp[0]= le_short(sp[0]); sp[1]= le_short(sp[1]); sp+= 2; } } else { sp+= 2*sp[1]+2; } nr++; } /* finally pointerlen: use struct ListBase to test it, never change the size of it! */ /* the global pointerlen from readfile.c can't be used here... */ sp= findstruct_name(sdna, "ListBase"); sdna->pointerlen= sdna->typelens[ sp[0] ]/2; if(sp[1]!=2 || (sdna->pointerlen!=4 && sdna->pointerlen!=8)) { printf("ListBase struct error! Needs it to calculate pointerize.\n"); exit(0); } } } void read_structDNA(struct SDNA *sdna, char *filename) { int file, filelen; file= open(filename, O_BINARY|O_RDONLY); if(file== -1) { printf("Can't read DNA file\n"); } else { filelen= filesize(file); sdna->datalen= filelen; sdna->data= mallocN(filelen, "convert_include"); read(file, sdna->data, filelen); close(file); init_structDNA(sdna); } } void findstruct_ext(char *str1, char *str2) { int a, offset; short *sp; /* eerst inlezen DNA file */ read_structDNA(&cur_sdna, "DNA"); sp= findstruct_name(&cur_sdna, str1); if(sp) { a= sp[1]; /* aantal elems */ sp+= 2; offset= 0; while(a--) { if( strcmp( cur_sdna.names[ sp[1] ], str2 )==0 ) { printf("type %s offset %d\n", cur_sdna.types[ sp[0] ], offset); return; } offset+= elementsize(&cur_sdna, sp[0], sp[1]); sp+= 2; } printf("Element bestaat niet\n"); } else printf("Struct bestaat niet\n"); } int findstruct_offset(char *structname, char *member) { int a, offset; short *sp; sp= findstruct_name(&cur_sdna, structname); if(sp) { a= sp[1]; /* aantal elems */ sp+= 2; offset= 0; while(a--) { if(strcmp(cur_sdna.names[sp[1]], member)==0) return offset; offset+= elementsize(&cur_sdna, sp[0], sp[1]); sp+= 2; } } return -1; } /* ******************** END LEZEN DNA ********************** */ /* ******************* AFHANDELEN DNA ***************** */ int struct_compare(char *stype, void *one, void *two) /* van struct 'stype' worden one en two vergeleken: pointers detecteren!!! */ { int namelen, a, nr, elemcount, elen, firststructtypenr; short *spc; char *type, *p1, *p2, *name; if(one==0 || two==0) return 0; nr= findstruct_nr(&cur_sdna, stype); if(nr == -1) return 0; firststructtypenr= *(cur_sdna.structs[0]); spc= cur_sdna.structs[nr]; elemcount= spc[1]; spc+= 2; p1= one; p2= two; for(a=0; a=firststructtypenr) { if( struct_compare(type, p1, p2)==0) return 0; } else { if(memcmp(p1, p2, elen)) return 0; } } p1+= elen; p2+= elen; } return 1; } void recurs_test_compflags(int structnr) { int a, b, typenr, elems; short *sp; char *cp; /* loop alle structen af en test of deze struct in andere zit */ sp= old_sdna.structs[structnr]; typenr= sp[0]; for(a=0; a 0) { str1= cur_sdna.types[spcur[0]]; str2= old_sdna.types[spold[0]]; if(strcmp(str1, str2)!=0) break; str1= cur_sdna.names[spcur[1]]; str2= old_sdna.names[spold[1]]; if(strcmp(str1, str2)!=0) break; /* naam gelijk, type gelijk, nu nog pointersize, dit geval komt haast nooit voor! */ if(str1[0]=='*') { if(old_sdna.pointerlen!=cur_sdna.pointerlen) break; } b--; spold+= 2; spcur+= 2; } if(b==0) compflags[a]= 1; } } } } /* eerste struct in util.h is struct Link, deze wordt in de compflags overgeslagen (als # 0). * Vuile patch! Nog oplossen.... */ compflags[0]= 1; /* Aangezien structen in structen kunnen zitten gaan we recursief * vlaggen zetten als er een struct veranderd is */ for(a=0; a0) { switch(otypenr) { case 0: val= *olddata; break; case 1: val= *( (uchar *)olddata); break; case 2: val= *( (short *)olddata); break; case 3: val= *( (ushort *)olddata); break; case 4: val= *( (int *)olddata); break; case 5: val= *( (int *)olddata); break; case 6: val= *( (uint *)olddata); break; case 7: val= *( (float *)olddata); break; case 8: val= *( (double *)olddata); break; } switch(ctypenr) { case 0: *curdata= val; break; case 1: *( (uchar *)curdata)= val; break; case 2: *( (short *)curdata)= val; break; case 3: *( (ushort *)curdata)= val; break; case 4: *( (int *)curdata)= val; break; case 5: *( (int *)curdata)= val; break; case 6: *( (uint *)curdata)= val; break; case 7: if(otypenr<2) val/= 255; *( (float *)curdata)= val; break; case 8: if(otypenr<2) val/= 255; *( (double *)curdata)= val; break; } olddata+= oldlen; curdata+= curlen; arrlen--; } } void cast_pointer(int curlen, int oldlen, char *name, char *curdata, char *olddata) { #ifdef WIN32 DWORDLONG lval; #else long long lval; #endif int arrlen; arrlen= arraysize(name, strlen(name)); while(arrlen>0) { if(curlen==oldlen) { memcpy(curdata, olddata, curlen); } else if(curlen==4 && oldlen==8) { #ifdef WIN32 lval= *( (DWORDLONG *)olddata ); #else lval= *( (long long *)olddata ); #endif *((int *)curdata) = lval>>3; /* is natuurlijk een beetje een gok! */ } else if(curlen==8 && oldlen==4) { #ifdef WIN32 *( (DWORDLONG *)curdata ) = *((int *)olddata); #else *( (long long *)curdata ) = *((int *)olddata); #endif } else { /* voor debug */ printf("errpr: illegal pointersize! \n"); } olddata+= oldlen; curdata+= curlen; arrlen--; } } int elem_strcmp(char *name, char *oname) { int a=0; /* strcmp without array part */ while(TRUE) { if(name[a] != oname[a]) return 1; if(name[a]=='[') break; if(name[a]==0) break; a++; } if(name[a] != oname[a]) return 1; return 0; } char *find_elem(char *type, char *name, short *old, char *olddata, short **sppo) { int a, elemcount, len; char *otype, *oname; /* without arraypart, so names can differ: return old namenr and type */ /* in old staat de oude struct */ elemcount= old[1]; old+= 2; for(a=0; aoldsize) cast_pointer(cur_sdna.pointerlen, old_sdna.pointerlen, oname, curdata, olddata); else cast_pointer(cur_sdna.pointerlen, old_sdna.pointerlen, name, curdata, olddata); } else if(name[0]=='*' || strcmp(type, otype)==0 ) { /* type gelijk */ mul= len/oldsize; mul*= MIN2(cursize, oldsize); memcpy(curdata, olddata, mul); } else { if(cursize>oldsize) cast_elem(type, otype, oname, curdata, olddata); else cast_elem(type, otype, name, curdata, olddata); } return; } } olddata+= len; } } void reconstruct_struct(int oldSDNAnr, char *data, int curSDNAnr, char *cur) { /* Recursief! * Per element van cur_struct data lezen uit old_struct. * Als element een struct is, recursief aanroepen. */ int a, elemcount, elen, eleno, mul, mulo, firststructtypenr; short *spo, *spc, *sppo; char *name, *nameo, *type, *cpo, *cpc; if(oldSDNAnr== -1) return; if(curSDNAnr== -1) return; if( compflags[oldSDNAnr]==1 ) { /* bij recurs: testen op gelijk */ spo= old_sdna.structs[oldSDNAnr]; elen= old_sdna.typelens[ spo[0] ]; memcpy( cur, data, elen); return; } firststructtypenr= *(cur_sdna.structs[0]); spo= old_sdna.structs[oldSDNAnr]; spc= cur_sdna.structs[curSDNAnr]; elemcount= spc[1]; spc+= 2; cpc= cur; for(a=0; a=firststructtypenr && name[0]!='*') { /* waar start de oude struct data (is ie er wel?) */ cpo= find_elem(type, name, spo, data, &sppo); if(cpo) { oldSDNAnr= findstruct_nr(&old_sdna, type); curSDNAnr= findstruct_nr(&cur_sdna, type); /* array! */ mul= arraysize(name, strlen(name)); nameo= old_sdna.names[sppo[1]]; mulo= arraysize(nameo, strlen(nameo)); eleno= elementsize(&old_sdna, sppo[0], sppo[1]); elen/= mul; eleno/= mulo; while(mul--) { reconstruct_struct(oldSDNAnr, cpo, curSDNAnr, cpc); cpo+= eleno; cpc+= elen; /* new struct array larger than old */ mulo--; if(mulo<=0) break; } } else cpc+= elen; } else { reconstruct_elem(type, name, cpc, spo, data); cpc+= elen; } } } void switch_endian_struct(int oldSDNAnr, char *data) { /* Recursief! * Als element een struct is, recursief aanroepen. */ int a, mul, elemcount, elen, elena, firststructtypenr, curSDNAnr; short *spo, *spc, skip; char *name, *type, *cpo, *cur, cval; if(oldSDNAnr== -1) return; firststructtypenr= *(old_sdna.structs[0]); spo= spc= old_sdna.structs[oldSDNAnr]; elemcount= spo[1]; spc+= 2; cur= data; for(a=0; a=firststructtypenr && name[0]!='*') { /* waar start de oude struct data (is ie er wel?) */ cpo= find_elem(type, name, spo, data, 0); if(cpo) { oldSDNAnr= findstruct_nr(&old_sdna, type); mul= arraysize(name, strlen(name)); elena= elen/mul; while(mul--) { switch_endian_struct(oldSDNAnr, cpo); cpo += elena; } } } else { if( name[0]=='*' ) { if(old_sdna.pointerlen==8) { mul= arraysize(name, strlen(name)); cpo= cur; while(mul--) { cval= cpo[0]; cpo[0]= cpo[7]; cpo[7]= cval; cval= cpo[1]; cpo[1]= cpo[6]; cpo[6]= cval; cval= cpo[2]; cpo[2]= cpo[5]; cpo[5]= cval; cval= cpo[3]; cpo[3]= cpo[4]; cpo[4]= cval; cpo+= 8; } } } else { if( spc[0]==2 || spc[0]==3 ) { /* short-ushort */ /* uitzondering: variable die blocktype/ipowin heet: van ID_ afgeleid */ skip= 0; if(name[0]=='b' && name[1]=='l') { if(strcmp(name, "blocktype")==0) skip= 1; } else if(name[0]=='i' && name[1]=='p') { if(strcmp(name, "ipowin")==0) skip= 1; } if(skip==0) { mul= arraysize(name, strlen(name)); cpo= cur; while(mul--) { cval= cpo[0]; cpo[0]= cpo[1]; cpo[1]= cval; cpo+= 2; } } } else if(spc[0]>3 && spc[0]<8) { /* int-long-ulong-float */ mul= arraysize(name, strlen(name)); cpo= cur; while(mul--) { cval= cpo[0]; cpo[0]= cpo[3]; cpo[3]= cval; cval= cpo[1]; cpo[1]= cpo[2]; cpo[2]= cval; cpo+= 4; } } } } cur+= elen; } } void reconstruct(int oldSDNAnr, int blocks, void **data) { int a, curSDNAnr, curlen=0, oldlen; short *spo, *spc; char *cur, *type, *cpc, *cpo; /* oldSDNAnr == structnr, we zoeken het corresponderende 'cur' nummer */ spo= old_sdna.structs[oldSDNAnr]; type= old_sdna.types[ spo[0] ]; oldlen= old_sdna.typelens[ spo[0] ]; curSDNAnr= findstruct_nr(&cur_sdna, type); /* data goedzetten en nieuwe calloc doen */ if(curSDNAnr >= 0) { spc= cur_sdna.structs[curSDNAnr]; curlen= cur_sdna.typelens[ spc[0] ]; } if(curlen==0) { freeN(*data); *data= 0; return; } cur= callocN( blocks*curlen, "reconstruct"); cpc= cur; cpo= *data; for(a=0; a