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