Changeset View
Changeset View
Standalone View
Standalone View
source/blender/makesdna/intern/makesdna.c
| Context not available. | |||||
| static struct { | static struct { | ||||
| GHash *struct_map_alias_from_static; | GHash *struct_map_alias_from_static; | ||||
| GHash *struct_map_static_from_alias; | GHash *struct_map_static_from_alias; | ||||
| GHash *elem_map_alias_from_static; | |||||
| GHash *elem_map_static_from_alias; | GHash *elem_map_static_from_alias; | ||||
| } g_version_data = {NULL}; | } g_version_data = {NULL}; | ||||
| Context not available. | |||||
| /** | /** | ||||
| * Determine how many bytes are needed for each struct. | * Determine how many bytes are needed for each struct. | ||||
| */ | */ | ||||
| static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char *base_directory); | static int calculate_struct_sizes(int); | ||||
| /** | /** | ||||
| * Construct the DNA.c file | * Construct the DNA.c file | ||||
| Context not available. | |||||
| return elem_alias_full; | return elem_alias_full; | ||||
| } | } | ||||
| static const char *version_elem_name_alias_from_static( | |||||
| const int strct, const char *elem_static_full) | |||||
| { | |||||
| const uint elem_static_full_len = strlen(elem_static_full); | |||||
| char *elem_static = alloca(elem_static_full_len + 1); | |||||
| DNA_elem_id_strip_copy(elem_static, elem_static_full); | |||||
| const char *str_pair[2] = {types[strct], elem_static}; | |||||
| const char *elem_alias = BLI_ghash_lookup(g_version_data.elem_map_alias_from_static, str_pair); | |||||
| return (elem_alias) ? elem_alias : elem_static; /* TODO: alloca */ | |||||
| } | |||||
| /** | /** | ||||
| * Enforce '_pad123' naming convention, disallow 'pad123' or 'pad_123', | * Enforce '_pad123' naming convention, disallow 'pad123' or 'pad_123', | ||||
| * special exception for [a-z] after since there is a 'pad_rot_angle' preference. | * special exception for [a-z] after since there is a 'pad_rot_angle' preference. | ||||
| Context not available. | |||||
| a -= 13; | a -= 13; | ||||
| cp += 13; | cp += 13; | ||||
| } | } | ||||
| else if (strncmp("DNA_PRIVATE_WORKSPACE", cp, 21) == 0) { | |||||
| /* Check for DNA_PRIVATE_WORKSPACE_READ_WRITE */ | |||||
| if (strncmp("_READ_WRITE", cp + 21, 11) == 0) { | |||||
| a -= 31; | |||||
| cp += 31; | |||||
| } | |||||
| else { | |||||
| a -= 20; | |||||
| cp += 20; | |||||
| } | |||||
| } | |||||
| else { | else { | ||||
| md[0] = cp[0]; | md[0] = cp[0]; | ||||
| md++; | md++; | ||||
| Context not available. | |||||
| return result; | return result; | ||||
| } | } | ||||
| static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char *base_directory) | static int calculate_struct_sizes(int firststruct) | ||||
| { | { | ||||
| int unknown = nr_structs, lastunknown; | int unknown = nr_structs, lastunknown; | ||||
| bool dna_error = false; | bool dna_error = false; | ||||
| /* Write test to verify sizes are accurate. */ | |||||
| fprintf(file_verify, "/* Verify struct sizes and member offsets are as expected by DNA. */\n"); | |||||
| fprintf(file_verify, "#include \"BLI_assert.h\"\n\n"); | |||||
| fprintf(file_verify, "#define DNA_DEPRECATED\n"); | |||||
| for (int i = 0; *(includefiles[i]) != '\0'; i++) { | |||||
| fprintf(file_verify, "#include \"%s%s\"\n", base_directory, includefiles[i]); | |||||
| } | |||||
| fprintf(file_verify, "\n"); | |||||
| /* Multiple iterations to handle nested structs. */ | |||||
| while (unknown) { | while (unknown) { | ||||
| lastunknown = unknown; | lastunknown = unknown; | ||||
| unknown = 0; | unknown = 0; | ||||
| Context not available. | |||||
| for (int a = 0; a < nr_structs; a++) { | for (int a = 0; a < nr_structs; a++) { | ||||
| const short *structpoin = structs[a]; | const short *structpoin = structs[a]; | ||||
| const int structtype = structpoin[0]; | const int structtype = structpoin[0]; | ||||
| const char *structname = version_struct_alias_from_static(types[structtype]); | |||||
| /* when length is not known... */ | /* when length is not known... */ | ||||
| if (types_size_native[structtype] == 0) { | if (types_size_native[structtype] == 0) { | ||||
| Context not available. | |||||
| for (int b = 0; b < structpoin[1]; b++, sp += 2) { | for (int b = 0; b < structpoin[1]; b++, sp += 2) { | ||||
| int type = sp[0]; | int type = sp[0]; | ||||
| const char *cp = names[sp[1]]; | const char *cp = names[sp[1]]; | ||||
| int namelen = (int)strlen(cp); | |||||
| /* Write size verification to file. */ | |||||
| const char *name_alias = version_elem_name_alias_from_static(structtype, cp); | |||||
| fprintf(file_verify, "BLI_STATIC_ASSERT(offsetof(struct %s, %s) == %d, \"DNA member offset verify\");\n", structname, name_alias, size_native); | |||||
| int namelen = (int)strlen(cp); | |||||
| /* is it a pointer or function pointer? */ | /* is it a pointer or function pointer? */ | ||||
| if (cp[0] == '*' || cp[1] == '*') { | if (cp[0] == '*' || cp[1] == '*') { | ||||
| has_pointer = 1; | has_pointer = 1; | ||||
| Context not available. | |||||
| dna_error = 1; | dna_error = 1; | ||||
| } | } | ||||
| /* Write size verification to file. */ | |||||
| fprintf(file_verify, "BLI_STATIC_ASSERT(sizeof(struct %s) == %d, \"DNA struct size verify\");\n\n", structname, size_native); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| } | } | ||||
| static int make_structDNA(const char *base_directory, FILE *file, FILE *file_offsets, FILE *file_verify) | static int make_structDNA(const char *baseDirectory, FILE *file, FILE *file_offsets) | ||||
| { | { | ||||
| int i; | int i; | ||||
| const short *sp; | const short *sp; | ||||
| Context not available. | |||||
| DNA_alias_maps( | DNA_alias_maps( | ||||
| DNA_RENAME_ALIAS_FROM_STATIC, | DNA_RENAME_ALIAS_FROM_STATIC, | ||||
| &g_version_data.struct_map_alias_from_static, | &g_version_data.struct_map_alias_from_static, | ||||
| &g_version_data.elem_map_alias_from_static); | NULL); | ||||
| DNA_alias_maps( | DNA_alias_maps( | ||||
| DNA_RENAME_STATIC_FROM_ALIAS, | DNA_RENAME_STATIC_FROM_ALIAS, | ||||
| &g_version_data.struct_map_static_from_alias, | &g_version_data.struct_map_static_from_alias, | ||||
| Context not available. | |||||
| /* Mind the breaking condition here! */ | /* Mind the breaking condition here! */ | ||||
| DEBUG_PRINTF(0, "\tStart of header scan:\n"); | DEBUG_PRINTF(0, "\tStart of header scan:\n"); | ||||
| for (i = 0; *(includefiles[i]) != '\0'; i++) { | for (i = 0; *(includefiles[i]) != '\0'; i++) { | ||||
| sprintf(str, "%s%s", base_directory, includefiles[i]); | sprintf(str, "%s%s", baseDirectory, includefiles[i]); | ||||
| DEBUG_PRINTF(0, "\t|-- Converting %s\n", str); | DEBUG_PRINTF(0, "\t|-- Converting %s\n", str); | ||||
| if (convert_include(str)) { | if (convert_include(str)) { | ||||
| return 1; | return 1; | ||||
| Context not available. | |||||
| } | } | ||||
| DEBUG_PRINTF(0, "\tFinished scanning %d headers.\n", i); | DEBUG_PRINTF(0, "\tFinished scanning %d headers.\n", i); | ||||
| if (calculate_struct_sizes(firststruct, file_verify, base_directory)) { | if (calculate_struct_sizes(firststruct)) { | ||||
| /* error */ | /* error */ | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| Context not available. | |||||
| dna_write(file, structs[0], len); | 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 = types_size_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 */ | |||||
| } | } | ||||
| /* write a simple enum with all structs offsets, | /* write a simple enum with all structs offsets, | ||||
| Context not available. | |||||
| fprintf(file_offsets, "\t_SDNA_TYPE_%s = %d,\n", version_struct_alias_from_static(types[structtype]), i); | fprintf(file_offsets, "\t_SDNA_TYPE_%s = %d,\n", version_struct_alias_from_static(types[structtype]), i); | ||||
| } | } | ||||
| fprintf(file_offsets, "\tSDNA_TYPE_MAX = %d,\n", nr_structs); | fprintf(file_offsets, "\tSDNA_TYPE_MAX = %d,\n", nr_structs); | ||||
| fprintf(file_offsets, "};\n\n"); | fprintf(file_offsets, "};\n"); | ||||
| } | } | ||||
| /* Check versioning errors which could cause duplicate names, | /* Check versioning errors which could cause duplicate names, | ||||
| Context not available. | |||||
| BLI_ghash_free(g_version_data.struct_map_alias_from_static, NULL, NULL); | BLI_ghash_free(g_version_data.struct_map_alias_from_static, NULL, NULL); | ||||
| BLI_ghash_free(g_version_data.struct_map_static_from_alias, NULL, NULL); | BLI_ghash_free(g_version_data.struct_map_static_from_alias, NULL, NULL); | ||||
| BLI_ghash_free(g_version_data.elem_map_static_from_alias, MEM_freeN, NULL); | BLI_ghash_free(g_version_data.elem_map_static_from_alias, MEM_freeN, NULL); | ||||
| BLI_ghash_free(g_version_data.elem_map_alias_from_static, MEM_freeN, NULL); | |||||
| DEBUG_PRINTF(0, "done.\n"); | DEBUG_PRINTF(0, "done.\n"); | ||||
| Context not available. | |||||
| { | { | ||||
| int return_status = 0; | int return_status = 0; | ||||
| if (argc != 4 && argc != 5) { | if (argc != 3 && argc != 4) { | ||||
| printf("Usage: %s dna.c dna_struct_offsets.h [base directory]\n", argv[0]); | printf("Usage: %s dna.c dna_struct_offsets.h [base directory]\n", argv[0]); | ||||
| return_status = 1; | return_status = 1; | ||||
| } | } | ||||
| else { | else { | ||||
| FILE *file_dna = fopen(argv[1], "w"); | FILE *file_dna = fopen(argv[1], "w"); | ||||
| FILE *file_dna_offsets = fopen(argv[2], "w"); | FILE *file_dna_offsets = fopen(argv[2], "w"); | ||||
| FILE *file_dna_verify = fopen(argv[3], "w"); | |||||
| if (!file_dna) { | if (!file_dna) { | ||||
| printf("Unable to open file: %s\n", argv[1]); | printf("Unable to open file: %s\n", argv[1]); | ||||
| return_status = 1; | return_status = 1; | ||||
| Context not available. | |||||
| printf("Unable to open file: %s\n", argv[2]); | printf("Unable to open file: %s\n", argv[2]); | ||||
| return_status = 1; | return_status = 1; | ||||
| } | } | ||||
| else if (!file_dna_verify) { | |||||
| printf("Unable to open file: %s\n", argv[3]); | |||||
| return_status = 1; | |||||
| } | |||||
| else { | else { | ||||
| const char *base_directory; | const char *baseDirectory; | ||||
| if (argc == 5) { | if (argc == 4) { | ||||
| base_directory = argv[4]; | baseDirectory = argv[3]; | ||||
| } | } | ||||
| else { | else { | ||||
| base_directory = BASE_HEADER; | baseDirectory = BASE_HEADER; | ||||
| } | } | ||||
| fprintf(file_dna, "extern const unsigned char DNAstr[];\n"); | fprintf(file_dna, "extern const unsigned char DNAstr[];\n"); | ||||
| fprintf(file_dna, "const unsigned char DNAstr[] = {\n"); | fprintf(file_dna, "const unsigned char DNAstr[] = {\n"); | ||||
| if (make_structDNA(base_directory, file_dna, file_dna_offsets, file_dna_verify)) { | if (make_structDNA(baseDirectory, file_dna, file_dna_offsets)) { | ||||
| /* error */ | /* error */ | ||||
| fclose(file_dna); | fclose(file_dna); | ||||
| file_dna = NULL; | file_dna = NULL; | ||||
| Context not available. | |||||
| if (file_dna_offsets) { | if (file_dna_offsets) { | ||||
| fclose(file_dna_offsets); | fclose(file_dna_offsets); | ||||
| } | } | ||||
| if (file_dna_verify) { | |||||
| fclose(file_dna_verify); | |||||
| } | |||||
| } | } | ||||
| Context not available. | |||||