Esempio n. 1
0
static int make_structDNA(const char *baseDirectory, FILE *file)
{
	int len, i;
	const short *sp;
	/* str contains filenames. Since we now include paths, I stretched       */
	/* it a bit. Hope this is enough :) -nzc-                                */
	char str[SDNA_MAX_FILENAME_LENGTH], *cp;
	int firststruct;
	
	if (debugSDNA > -1) {
		fflush(stdout);
		printf("Running makesdna at debug level %d\n", debugSDNA);
	}
		
	/* the longest known struct is 50k, so we assume 100k is sufficent! */
	namedata = MEM_callocN(maxdata, "namedata");
	typedata = MEM_callocN(maxdata, "typedata");
	structdata = MEM_callocN(maxdata, "structdata");
	
	/* a maximum of 5000 variables, must be sufficient? */
	names = MEM_callocN(sizeof(char *) * maxnr, "names");
	types = MEM_callocN(sizeof(char *) * maxnr, "types");
	typelens_native = MEM_callocN(sizeof(short) * maxnr, "typelens_native");
	typelens_32 = MEM_callocN(sizeof(short) * maxnr, "typelens_32");
	typelens_64 = MEM_callocN(sizeof(short) * maxnr, "typelens_64");
	structs = MEM_callocN(sizeof(short *) * maxnr, "structs");

	/**
	 * Insertion of all known types.
	 *
	 * \warning Order of function calls here must be aligned with #eSDNA_Type.
	 * \warning uint is not allowed! use in structs an unsigned int.
	 * \warning sizes must match #DNA_elem_type_size().
	 */
	add_type("char", 1);     /* SDNA_TYPE_CHAR */
	add_type("uchar", 1);    /* SDNA_TYPE_UCHAR */
	add_type("short", 2);    /* SDNA_TYPE_SHORT */
	add_type("ushort", 2);   /* SDNA_TYPE_USHORT */
	add_type("int", 4);      /* SDNA_TYPE_INT */

	/* note, long isn't supported,
	 * these are place-holders to maintain alignment with eSDNA_Type*/
	add_type("long", 4);     /* SDNA_TYPE_LONG */
	add_type("ulong", 4);    /* SDNA_TYPE_ULONG */

	add_type("float", 4);    /* SDNA_TYPE_FLOAT */
	add_type("double", 8);   /* SDNA_TYPE_DOUBLE */
	add_type("int64_t", 8);  /* SDNA_TYPE_INT64 */
	add_type("uint64_t", 8); /* SDNA_TYPE_UINT64 */
	add_type("void", 0);     /* SDNA_TYPE_VOID */

	/* the defines above shouldn't be output in the padding file... */
	firststruct = nr_types;
	
	/* add all include files defined in the global array                     */
	/* Since the internal file+path name buffer has limited length, I do a   */
	/* little test first...                                                  */
	/* Mind the breaking condition here!                                     */
	if (debugSDNA) printf("\tStart of header scan:\n"); 
	for (i = 0; *(includefiles[i]) != '\0'; i++) {
		sprintf(str, "%s%s", baseDirectory, includefiles[i]);
		if (debugSDNA) printf("\t|-- Converting %s\n", str);
		if (convert_include(str)) {
			return (1);
		}
	}
	if (debugSDNA) printf("\tFinished scanning %d headers.\n", i); 

	if (calculate_structlens(firststruct)) {
		/* error */
		return(1);
	}

	/* FOR DEBUG */
	if (debugSDNA > 1) {
		int a, b;
		/* short *elem; */
		short num_types;

		printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs);
		for (a = 0; a < nr_names; a++) {
			printf(" %s\n", names[a]);
		}
		printf("\n");
		
		sp = typelens_native;
		for (a = 0; a < nr_types; a++, sp++) {
			printf(" %s %d\n", types[a], *sp);
		}
		printf("\n");
		
		for (a = 0; a < nr_structs; a++) {
			sp = structs[a];
			printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], typelens_native[sp[0]]);
			num_types  = sp[1];
			sp += 2;
			/* ? num_types was elem? */
			for (b = 0; b < num_types; b++, sp += 2) {
				printf("   %s %s\n", types[sp[0]], names[sp[1]]);
			}
		}
	}

	/* file writing */

	if (debugSDNA > -1) printf("Writing file ... ");
		
	if (nr_names == 0 || nr_structs == 0) {
		/* pass */
	}
	else {
		dna_write(file, "SDNA", 4);
		
		/* write names */
		dna_write(file, "NAME", 4);
		len = nr_names;
		dna_write(file, &len, 4);
		
		/* calculate size of datablock with strings */
		cp = names[nr_names - 1];
		cp += strlen(names[nr_names - 1]) + 1;         /* +1: null-terminator */
		len = (intptr_t) (cp - (char *) names[0]);
		len = (len + 3) & ~3;
		dna_write(file, names[0], len);
		
		/* write TYPES */
		dna_write(file, "TYPE", 4);
		len = nr_types;
		dna_write(file, &len, 4);
	
		/* calculate datablock size */
		cp = types[nr_types - 1];
		cp += strlen(types[nr_types - 1]) + 1;     /* +1: null-terminator */
		len = (intptr_t) (cp - (char *) types[0]);
		len = (len + 3) & ~3;
		
		dna_write(file, types[0], len);
		
		/* WRITE TYPELENGTHS */
		dna_write(file, "TLEN", 4);
		
		len = 2 * nr_types;
		if (nr_types & 1) len += 2;
		dna_write(file, typelens_native, len);
		
		/* WRITE STRUCTS */
		dna_write(file, "STRC", 4);
		len = nr_structs;
		dna_write(file, &len, 4);
	
		/* calc datablock size */
		sp = structs[nr_structs - 1];
		sp += 2 + 2 * (sp[1]);
		len = (intptr_t) ((char *) sp - (char *) structs[0]);
		len = (len + 3) & ~3;
		
		dna_write(file, structs[0], len);
	
		/* a simple dna padding test */
		if (0) {
			FILE *fp;
			int a;
			
			fp = fopen("padding.c", "w");
			if (fp == NULL) {
				/* pass */
			}
			else {

				/* add all include files defined in the global array */
				for (i = 0; *(includefiles[i]) != '\0'; i++) {
					fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]);
				}

				fprintf(fp, "main() {\n");
				sp = typelens_native;
				sp += firststruct;
				for (a = firststruct; a < nr_types; a++, sp++) {
					if (*sp) {
						fprintf(fp, "\tif (sizeof(struct %s) - %d) printf(\"ALIGN ERROR:", types[a], *sp);
						fprintf(fp, "%%d %s %d ", types[a], *sp);
						fprintf(fp, "\\n\",  sizeof(struct %s) - %d);\n", types[a], *sp);
					}
				}
				fprintf(fp, "}\n");
				fclose(fp);
			}
		}
		/*	end end padding test */
	}
	
	
	MEM_freeN(namedata);
	MEM_freeN(typedata);
	MEM_freeN(structdata);
	MEM_freeN(names);
	MEM_freeN(types);
	MEM_freeN(typelens_native);
	MEM_freeN(typelens_32);
	MEM_freeN(typelens_64);
	MEM_freeN(structs);

	if (debugSDNA > -1) printf("done.\n");
	
	return(0);
}
Esempio n. 2
0
int make_structDNA(char *baseDirectory, FILE *file)
{
	int len, i;
	short *sp;
	/* str contains filenames. Since we now include paths, I stretched       */
	/* it a bit. Hope this is enough :) -nzc-                                */
	char str[SDNA_MAX_FILENAME_LENGTH], *cp;
	int firststruct;
	
	if (debugSDNA > -1) {
		fflush(stdout);
		printf("Running makesdna at debug level %d\n", debugSDNA);
		
	}
		
	/* the longest known struct is 50k, so we assume 100k is sufficent! */
	namedata= (char*)malloc_and_setzero(maxdata);
	typedata= (char*)malloc_and_setzero(maxdata);
	structdata= (short*)malloc_and_setzero(maxdata);
	
	/* a maximum of 5000 variables, must be sufficient? */
	names= (char**)malloc_and_setzero(sizeof(char *)*maxnr);
	types= (char**)malloc_and_setzero(sizeof(char *)*maxnr);
	typelens= (short*) malloc_and_setzero(sizeof(short)*maxnr);
	alphalens= (short*)malloc_and_setzero(sizeof(short)*maxnr);
	structs= (short**)malloc_and_setzero(sizeof(short)*maxnr);

	/* insertion of all known types */
	/* watch it: uint is not allowed! use in structs an unsigned int */
	add_type("char", 1);	/* 0 */
	add_type("uchar", 1);	/* 1 */
	add_type("short", 2);	/* 2 */
	add_type("ushort", 2);	/* 3 */
	add_type("int", 4);		/* 4 */
	add_type("long", 4);	/* 5 */		/* should it be 8 on 64 bits? */
	add_type("ulong", 4);	/* 6 */
	add_type("float", 4);	/* 7 */
	add_type("double", 8);	/* 8 */
	add_type("void", 0);	/* 9 */

	// the defines above shouldn't be output in the padding file...
	firststruct = nr_types;
	
	/* add all include files defined in the global array                     */
	/* Since the internal file+path name buffer has limited length, I do a   */
	/* little test first...                                                  */
	/* Mind the breaking condition here!                                     */
	if (debugSDNA) printf("\tStart of header scan:\n"); 
	for (i = 0; strlen(includefiles[i]); i++) {
		sprintf(str, "%s%s", baseDirectory, includefiles[i]);
  		if (debugSDNA) printf("\t|-- Converting %s\n", str); 
		if (convert_include(str)) {
			return (1);
		}
	}
	if (debugSDNA) printf("\tFinished scanning %d headers.\n", i); 

	if (calculate_structlens(firststruct)) {
		// error
		return(1);
	}


	/* FOR DEBUG */
	if (debugSDNA > 1)
	{
		int a,b;
/*  		short *elem; */
		short num_types;

		printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs);
		for(a=0; a<nr_names; a++) { 
			printf(" %s \n", names[a]);
		}
		printf("\n");
		
		sp= typelens;
		for(a=0; a<nr_types; a++, sp++) { 
			printf(" %s %d\n", types[a], *sp);
		}
		printf("\n");
		
		for(a=0; a<nr_structs; a++) {
			sp= structs[a];
			printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1],typelens[sp[0]]);
			num_types  = sp[1];
			sp+= 2;
			/* ? num_types was elem? */
			for(b=0; b< num_types; b++, sp+= 2) {
				printf("   %s %s\n", types[sp[0]], names[sp[1]]);
			}
		}
	}

	/* file writing */

	if (debugSDNA > -1) printf("Writing file ... ");
		
	if(nr_names==0 || nr_structs==0);
	else {
		strcpy(str, "SDNA");
		dna_write(file, str, 4);
		
		/* write names */
		strcpy(str, "NAME");
		dna_write(file, str, 4);
		len= nr_names;
		dna_write(file, &len, 4);
		
		/* calculate size of datablock with strings */
		cp= names[nr_names-1];
		cp+= strlen(names[nr_names-1]) + 1;			/* +1: null-terminator */
		len= (intptr_t) (cp - (char*) names[0]);
		len= (len+3) & ~3;
		dna_write(file, names[0], len);
		
		/* write TYPES */
		strcpy(str, "TYPE");
		dna_write(file, str, 4);
		len= nr_types;
		dna_write(file, &len, 4);
	
		/* calculate datablock size */
		cp= types[nr_types-1];
		cp+= strlen(types[nr_types-1]) + 1;		/* +1: null-terminator */
		len= (intptr_t) (cp - (char*) types[0]);
		len= (len+3) & ~3;
		
		dna_write(file, types[0], len);
		
		/* WRITE TYPELENGTHS */
		strcpy(str, "TLEN");
		dna_write(file, str, 4);
		
		len= 2*nr_types;
		if(nr_types & 1) len+= 2;
		dna_write(file, typelens, len);
		
		/* WRITE STRUCTS */
		strcpy(str, "STRC");
		dna_write(file, str, 4);
		len= nr_structs;
		dna_write(file, &len, 4);
	
		/* calc datablock size */
		sp= structs[nr_structs-1];
		sp+= 2+ 2*( sp[1] );
		len= (intptr_t) ((char*) sp - (char*) structs[0]);
		len= (len+3) & ~3;
		
		dna_write(file, structs[0], len);
	
		/* a simple dna padding test */
		if (0) {
			FILE *fp;
			int a;
			
			fp= fopen("padding.c", "w");
			if(fp==NULL);
			else {

				// add all include files defined in the global array
				for (i = 0; strlen(includefiles[i]); i++) {
					fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]);
				}

				fprintf(fp, "main(){\n");
				sp = typelens;
				sp += firststruct;
				for(a=firststruct; a<nr_types; a++, sp++) { 
					if(*sp) {
						fprintf(fp, "\tif(sizeof(struct %s) - %d) printf(\"ALIGN ERROR:", types[a], *sp);
						fprintf(fp, "%%d %s %d ", types[a], *sp);
						fprintf(fp, "\\n\",  sizeof(struct %s) - %d);\n", types[a], *sp);
					}
				}
				fprintf(fp, "}\n");
				fclose(fp);
			}
		}
		/*	end end padding test */
	}
	
	
	free(namedata);
	free(typedata);
	free(structdata);
	free(names);
	free(types);
	free(typelens);
	free(structs);

	if (debugSDNA > -1) printf("done.\n");
	
	return(0);
}