#include #include #include #include // the program writes generated text to stdout // other messages must be sent to stderr #define printf USE_FPRINTF!!! #define exit_with_error(FORMAT, ARGS...) ({ \ fprintf(stderr, "\e[91m\nerror: "FORMAT"\n", ## ARGS); \ exit(4); \ }) #define argis(STR) streq(arg, STR) || \ streq(arg, "-"STR) || \ streq(arg, "--"STR) //////////////////////////////////////////////// // STR FUNCTIONS // //////////////////////////////////////////////// bool streq(const char* key0,const char* key1){ if(!key0) return key1 ? false : true; if(!key1) return false; while(*key0&&*key1) if(*key0++ != *key1++) return false; return true; } char* basedir_exclude(const char* path, const char* basename){ int len=strlen(path); int base_len=strlen(basename); int i=0; if(len>0 && base_len>0){ if(basename[base_len-1]=='/' || basename[base_len-1]=='\\') base_len--; // remove trailing path separator if(len>base_len){ while(i spaces char* mult_space(int count){ char* _mult_space_buf=malloc(count+1); _mult_space_buf[count]=0; memset(_mult_space_buf, ' ', count); return _mult_space_buf; } void print_line(bool print_lines, bool start_new_line){ if(!print_lines) return; fflush(stdout); if(start_new_line) fprintf(stderr, "\n"); fprintf(stderr, "------------------------------------------------------------\n"); fflush(stderr); } //////////////////////////////////////////////// // WRITE CODE // //////////////////////////////////////////////// bool _first_file_processed=false; unsigned int _input_files_n=0; void process_file(const char* input_file_path, const char* embedded_file_path, FILE* out_file, const char* out_file_path) { bool print_lines=streq(out_file_path, "this_file"); if(!_first_file_processed){ print_line(print_lines, false); int onml=strlen(out_file_path); if(onml>43) onml=0; char* _sp1=mult_space(43-onml); fprintf(out_file, // "////////////////////////////////////////////////////////////\n" // "// //\n" // "//%s%s%s//\n" // "// //\n" "////////////////////////////////////////////////////////////\n" "// This file has been generated by resource_embedder //\n" "// src: https://github.com/Timerix22/resource_embedder //\n" "////////////////////////////////////////////////////////////\n" "// USAGE: //\n" "// Put inside any .c file //\n" "// #define EMBEDDED_RESOURCE_POSTFIX your_postfix //\n" "// #include \"%s\"%s//\n" "// //\n" "// Then you can access embedded files through //\n" "// EmbeddedResourceFile_table_your_postfix. You can put //\n" "// table content into a hashtable or get it by index. //\n" "////////////////////////////////////////////////////////////\n" "\n", // mult_space(28-onml/2), outname, mult_space(28-onml/2+onml%2), out_file_path, _sp1); free(_sp1); fprintf(out_file, "typedef unsigned char _byte;\n" "\n" "typedef struct {\n" " char* path;\n" " _byte* data;\n" " unsigned long long size;\n" "} EmbeddedResourceFile;\n" "\n" "#ifndef _EmbeddedResourceFile_table\n" "#ifdef EMBEDDED_RESOURCE_POSTFIX\n" " #define _EmbeddedResourceFile_table \\\n" " EmbeddedResourceFile_table##EMBEDDED_RESOURCE_POSTFIX\n" " #define _EmbeddedResourceFile_table_count \\\n" " EmbeddedResourceFile_table##EMBEDDED_RESOURCE_POSTFIX##_count\n" "#else\n" " #define _EmbeddedResourceFile_table \\\n" " EmbeddedResourceFile_table\n" " #define _EmbeddedResourceFile_table_count \\\n" " EmbeddedResourceFile_table_count\n" "#endif\n" "#endif\n" "extern EmbeddedResourceFile _EmbeddedResourceFile_table[];\n" "extern unsigned int _EmbeddedResourceFile_table_count;" "\n" "\n" "EmbeddedResourceFile _EmbeddedResourceFile_table[]={\n"); print_line(print_lines, false); } fprintf(stderr, "reading file %s\n", input_file_path); print_line(print_lines, false); FILE* input_file=fopen(input_file_path, "rb"); if(input_file==NULL) exit_with_error("can't open file %s", input_file_path); if(_first_file_processed) fprintf(out_file, ",\n"); // writing input file code header fprintf(out_file, " {\n" " .path=(char*)\"%s\",\n" " .data=(_byte[]){", embedded_file_path); // writing input file content int byte=0; unsigned long long size=0; while( (byte=fgetc(input_file)) != EOF ){ if(size!=0) fprintf(out_file, ","); if(size%16==0) fprintf(out_file, "\n "); fprintf(out_file, "0x%X", byte); size+=1; } fprintf(out_file, "\n },\n" " .size=%llu\n" " }", size); fflush(out_file); print_line(print_lines,true); if(ferror(input_file)){ perror("unexpected end of stream: "); exit_with_error("input read error"); } fclose(input_file); fprintf(stderr, "read %llu bytes\n", size); _first_file_processed=true; _input_files_n++; } //////////////////////////////////////////////// // MAIN // //////////////////////////////////////////////// int main(const int argc, const char * const* argv){ FILE* out_file=NULL; const char* out_file_path=NULL; const char* basedir=""; for(int i=1; i