#include #include #include #include #include "object.h" #include "utils.h" #include "errors.h" typedef enum build_function_t { BUILD_OBJECT, BUILD_ASSET_FILE } build_function_t; void print_usage(void) { puts("\033[33musage\033[m:"); puts("\tasset_builder output_object_file -c input_file"); puts("\tasset_builder output_asset_file input_object_file [input_object_file2 ...]"); } int main(int argc, char *argv[]) { // Parse args if(argc < 3) { print_usage(); return EXIT_FAILURE; } const build_function_t build_function = strcmp(argv[2], "-c") ? BUILD_ASSET_FILE : BUILD_OBJECT; const char *output_file_path = argv[1]; FILE *output_file = fopen(output_file_path, "wb"); if(!output_file) { error_printf("Failed to open output file : %d", errno); return EXIT_FAILURE; } if(build_function == BUILD_OBJECT) { if(argc != 4) { print_usage(); return EXIT_FAILURE; } const char *input_file_path = argv[3]; if(build_object(input_file_path, output_file)) goto_failure; } else if(build_function == BUILD_ASSET_FILE) { uint32_t header_size = 0; const int nb_input_object_files = argc - 2; if(file_write(&nb_input_object_files, sizeof(nb_input_object_files), 1, output_file)) goto_failure; header_size += sizeof(nb_input_object_files); FILE *input_object_files[nb_input_object_files]; uint32_t input_object_files_sizes[nb_input_object_files]; uint32_t input_object_files_offsets[nb_input_object_files]; for(int i = 0; i < nb_input_object_files; i++) { const char *input_object_file_path = argv[i + 2]; input_object_files[i] = fopen(input_object_file_path, "rb"); if(!input_object_files[i]) { error_printf("Failed to open input object file : %d", errno); for(; i >= 0; i--) if(fclose(input_object_files[i])) error_printf("Failed to close input object file : %d", errno); goto_failure; } if(file_read(&input_object_files_sizes[i], sizeof(*input_object_files_sizes), 1, input_object_files[i])) { for(; i >= 0; i--) if(fclose(input_object_files[i])) error_printf("Failed to close input object file : %d", errno); goto_failure; } const char *input_object_file_slash = strrchr(input_object_file_path, '/'); const char *input_object_file_name = input_object_file_slash ? input_object_file_slash + 1 : input_object_file_path; const char *input_object_file_ext = strchr(input_object_file_path, '.'); uint32_t input_object_file_base_name_length = strlen(input_object_file_name) - strlen(input_object_file_ext) + 1; header_size += input_object_file_base_name_length * sizeof(*input_object_file_name); header_size += sizeof(*input_object_files_offsets); } input_object_files_offsets[0] = header_size; for(int i = 0; i < nb_input_object_files; i++) { if(i) input_object_files_offsets[i] = input_object_files_offsets[i - 1] + input_object_files_sizes[i - 1]; char *input_object_file_path = argv[i + 2]; const char *input_object_file_slash = strrchr(input_object_file_path, '/'); const char *input_object_file_name = input_object_file_slash ? input_object_file_slash + 1 : input_object_file_path; char *input_object_file_ext = strchr(input_object_file_path, '.'); input_object_file_ext[0] = '\00'; uint32_t input_object_file_base_name_length = strlen(input_object_file_name) - strlen(input_object_file_ext) + 1; if(file_write(input_object_file_name, sizeof(*input_object_file_name), input_object_file_base_name_length, output_file)) { for(i = 0; i < nb_input_object_files; i++) if(fclose(input_object_files[i])) error_printf("Failed to close input object file : %d", errno); goto_failure; } if(file_write(&input_object_files_offsets[i], sizeof(*input_object_files_offsets), 1, output_file)) { for(i = 0; i < nb_input_object_files; i++) if(fclose(input_object_files[i])) error_printf("Failed to close input object file : %d", errno); goto_failure; } } for(int i = 0; i < nb_input_object_files; i++) { char buffer[input_object_files_sizes[i]]; if(file_read(buffer, sizeof(*buffer), input_object_files_sizes[i], input_object_files[i])) { for(i = 0; i < nb_input_object_files; i++) if(fclose(input_object_files[i])) error_printf("Failed to close input object file : %d", errno); goto_failure; } if(file_write(buffer, sizeof(*buffer), input_object_files_sizes[i], output_file)) { for(i = 0; i < nb_input_object_files; i++) if(fclose(input_object_files[i])) error_printf("Failed to close input object file : %d", errno); goto_failure; } } for(int i = 0; i < nb_input_object_files; i++) { if(fclose(input_object_files[i])) { error_printf("Failed to close input object file : %d", errno); for(i++; i < nb_input_object_files; i++) if(fclose(input_object_files[i])) error_printf("Failed to close input object file : %d", errno); goto_failure; } } } if(fclose(output_file)) { error_printf("Failed to close output file : %d", errno); return EXIT_FAILURE; } return EXIT_SUCCESS; failure: if(fclose(output_file)) error_printf("Failed to close output file : %d", errno); return EXIT_FAILURE; }