xref: /openbmc/u-boot/tools/file2include.c (revision 116b49cf)
1 /*
2  * Convert a file image to a C define
3  *
4  * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  *
8  * For testing EFI disk management we need an in memory image of
9  * a disk.
10  *
11  * The tool file2include converts a file to a C include. The file
12  * is separated into strings of 8 bytes. Only the non-zero strings
13  * are written to the include. The output format has been designed
14  * to maintain readability.
15  *
16  * As the disk image needed for testing contains mostly zeroes a high
17  * compression ratio can be attained.
18  */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stdint.h>
22 #include <malloc.h>
23 
24 /* Size of the blocks written to the compressed file */
25 #define BLOCK_SIZE 8
26 
27 int main(int argc, char *argv[])
28 {
29 	FILE *file;
30 	int ret;
31 	unsigned char *buf;
32 	size_t count, i, j;
33 
34 	/* Provide usage help */
35 	if (argc != 2) {
36 		printf("Usage:\n%s FILENAME\n", argv[0]);
37 		return EXIT_FAILURE;
38 	}
39 	/* Open file */
40 	file = fopen(argv[1], "r");
41 	if (!file) {
42 		perror("fopen");
43 		return EXIT_FAILURE;
44 	}
45 	/* Get file length */
46 	ret = fseek(file, 0, SEEK_END);
47 	if (ret < 0) {
48 		perror("fseek");
49 		return EXIT_FAILURE;
50 	}
51 	count = ftell(file);
52 	if (!count) {
53 		fprintf(stderr, "File %s has length 0\n", argv[1]);
54 		return EXIT_FAILURE;
55 	}
56 	rewind(file);
57 	/* Read file */
58 	buf = malloc(count);
59 	if (!buf) {
60 		perror("calloc");
61 		return EXIT_FAILURE;
62 	}
63 	count = fread(buf, 1, count, file);
64 
65 	/* Generate output */
66 	printf("/*\n");
67 	printf(" *  Non-zero %u byte strings of a disk image\n", BLOCK_SIZE);
68 	printf(" *\n");
69 	printf(" *  Generated with tools/file2include\n");
70 	printf(" *\n");
71 	printf(" *  SPDX-License-Identifier:	GPL-2.0+\n");
72 	printf(" */\n\n");
73 	printf("#define EFI_ST_DISK_IMG { 0x%08zx, { \\\n", count);
74 
75 	for (i = 0; i < count; i += BLOCK_SIZE) {
76 		int c = 0;
77 
78 		for (j = i; j < i + BLOCK_SIZE && j < count; ++j) {
79 			if (buf[j])
80 				c = 1;
81 		}
82 		if (!c)
83 			continue;
84 		printf("\t{0x%08zx, \"", i);
85 		for (j = i; j < i + BLOCK_SIZE && j < count; ++j)
86 			printf("\\x%02x", buf[j]);
87 		printf("\"}, /* ");
88 		for (j = i; j < i + BLOCK_SIZE && j < count; ++j) {
89 			if (buf[j] >= 0x20 && buf[j] <= 0x7e)
90 				printf("%c", buf[j]);
91 			else
92 				printf(".");
93 		}
94 		printf(" */ \\\n");
95 	}
96 	printf("\t{0, NULL} } }\n");
97 
98 	/* Release resources */
99 	free(buf);
100 	ret = fclose(file);
101 	if (ret) {
102 		perror("fclose");
103 		return EXIT_FAILURE;
104 	}
105 	return EXIT_SUCCESS;
106 }
107