1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5int main(int argc, char *argv[]) {
6    // Arguments
7    if (argc != 4 || (argc == 2 && strcmp(argv[1], "--help") == 0)) {
8        fprintf(stderr, "Usage: %s PREFIX OUTFILE INFILE\n", argv[0]);
9        exit(EXIT_FAILURE);
10    }
11
12    char const *prefix = argv[1];
13    char const *infile_name = argv[3];
14    char const *outfile_name = argv[2];
15
16    // Open Files
17    FILE *infile = fopen(infile_name, "rb");
18
19    if (!infile) {
20        fprintf(stderr, "Unable to open input file: %s\n", infile_name);
21        exit(EXIT_FAILURE);
22    }
23
24    FILE *outfile = fopen(outfile_name, "w");
25
26    if (!outfile) {
27        fprintf(stderr, "Uanble to open output file: %s\n", outfile_name);
28        fclose(infile);
29        exit(EXIT_FAILURE);
30    }
31
32
33    // Generate Header Guard Begin
34    fprintf(outfile, "#ifndef %s_data_pack_h\n", prefix);
35    fprintf(outfile, "#define %s_data_pack_h\n\n", prefix);
36
37
38    // Generate Include Directive
39    fprintf(outfile, "#include <stddef.h>\n\n");
40
41
42    // Generate Encoded Data
43    fprintf(outfile, "static const char %s_data[] =\n", prefix);
44
45    size_t data_size = 0;
46    for (;;) {
47        unsigned char buf[256];
48        unsigned char *ptr = buf;
49
50        size_t nread = fread(buf, sizeof(char), sizeof(buf), infile);
51        size_t line_count = nread / 16;
52        size_t i;
53
54        data_size += nread;
55
56        for (i = 0; i < line_count; ++i, ptr += 16) {
57            fprintf(outfile,
58                    "\""
59                    "\\x%02x\\x%02x\\x%02x\\x%02x"
60                    "\\x%02x\\x%02x\\x%02x\\x%02x"
61                    "\\x%02x\\x%02x\\x%02x\\x%02x"
62                    "\\x%02x\\x%02x\\x%02x\\x%02x"
63                    "\"\n",
64                    ptr[0], ptr[1], ptr[2], ptr[3],
65                    ptr[4], ptr[5], ptr[6], ptr[7],
66                    ptr[8], ptr[9], ptr[10], ptr[11],
67                    ptr[12], ptr[13], ptr[14], ptr[15]);
68        }
69
70        if (nread % 16 != 0) {
71            fprintf(outfile, "\"");
72
73            for (i = line_count * 16; i < nread; ++i) {
74                fprintf(outfile, "\\x%02x", buf[i]);
75            }
76
77            fprintf(outfile, "\"\n");
78        }
79
80        if (nread != sizeof(buf)) {
81            // End of file reached
82            break;
83        }
84    }
85
86    fprintf(outfile, ";\n\n");
87
88
89    // Generate Data Size
90    fprintf(outfile, "static const size_t %s_size = %lu;\n",
91            prefix, (unsigned long)data_size);
92
93
94    // Generate Header Guard End
95    fprintf(outfile, "\n#endif\n");
96
97
98    // Close Files
99    fclose(infile);
100    fclose(outfile);
101
102    return EXIT_SUCCESS;
103}
104