mirror of https://github.com/tstack/lnav
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
4.6 KiB
C
216 lines
4.6 KiB
C
// bin2c.c
|
|
//
|
|
// convert a binary file into a C source vector
|
|
//
|
|
// THE "BEER-WARE LICENSE" (Revision 3.1415):
|
|
// sandro AT sigala DOT it wrote this file. As long as you retain this notice you can do
|
|
// whatever you want with this stuff. If we meet some day, and you think this stuff is
|
|
// worth it, you can buy me a beer in return. Sandro Sigala
|
|
|
|
#include <ctype.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <getopt.h>
|
|
#include <libgen.h>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <zlib.h>
|
|
|
|
#ifndef PATH_MAX
|
|
#define PATH_MAX 1024
|
|
#endif
|
|
|
|
const char *name = NULL;
|
|
|
|
static const char *HEADER_FMT =
|
|
"#ifndef bin2c_%s_h\n"
|
|
"#define bin2c_%s_h\n"
|
|
"\n"
|
|
"#include \"bin2c.hh\"\n"
|
|
"\n"
|
|
"extern struct bin_src_file %s%s;\n"
|
|
"\n"
|
|
"#endif\n"
|
|
"\n";
|
|
|
|
struct file_meta {
|
|
const char *fm_name;
|
|
unsigned int fm_compressed_size;
|
|
unsigned int fm_size;
|
|
};
|
|
|
|
void symname(char *dst, const char *fname)
|
|
{
|
|
strcpy(dst, fname);
|
|
for (int lpc = 0; dst[lpc]; lpc++) {
|
|
if (!isalnum(dst[lpc])) {
|
|
dst[lpc] = '_';
|
|
}
|
|
}
|
|
}
|
|
|
|
void process(struct file_meta *fm, FILE *ofile)
|
|
{
|
|
struct stat st;
|
|
|
|
if (stat(fm->fm_name, &st) == -1) {
|
|
perror("unable to stat file");
|
|
exit(1);
|
|
}
|
|
|
|
unsigned char *buf = malloc(st.st_size);
|
|
unsigned char *dest = malloc(st.st_size);
|
|
|
|
int fd = open(fm->fm_name, O_RDONLY);
|
|
if (fd == -1) {
|
|
perror("unable to open file");
|
|
exit(1);
|
|
}
|
|
|
|
int rc;
|
|
while ((rc = read(fd, &buf[fm->fm_size], (st.st_size - fm->fm_size))) > 0) {
|
|
fm->fm_size += rc;
|
|
}
|
|
|
|
uLongf destLen = st.st_size;
|
|
compress(dest, &destLen, buf, st.st_size);
|
|
fm->fm_compressed_size = destLen;
|
|
|
|
int c, col = 1;
|
|
char sym[1024];
|
|
|
|
symname(sym, basename((char *) fm->fm_name));
|
|
fprintf(ofile, "static const unsigned char %s_data[] = {\n", sym);
|
|
for (int lpc = 0; lpc < destLen; lpc++) {
|
|
c = dest[lpc];
|
|
if (col >= 78 - 6)
|
|
{
|
|
fputc('\n', ofile);
|
|
col = 1;
|
|
}
|
|
fprintf(ofile, "0x%.2x, ", c);
|
|
col += 6;
|
|
}
|
|
fprintf(ofile, "0x00\n");
|
|
fprintf(ofile, "\n};\n");
|
|
|
|
free(buf);
|
|
free(dest);
|
|
}
|
|
|
|
void usage()
|
|
{
|
|
fprintf(stderr, "usage: bin2c [-n name] <output_file> [input_file1 ...]\n");
|
|
exit(1);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int c;
|
|
|
|
while ((c = getopt(argc, argv, "hn:")) != -1) {
|
|
switch (c) {
|
|
case 'n':
|
|
name = optarg;
|
|
break;
|
|
default:
|
|
usage();
|
|
break;
|
|
}
|
|
}
|
|
|
|
argc -= optind;
|
|
argv += optind;
|
|
|
|
if (argc < 1) {
|
|
usage();
|
|
}
|
|
|
|
const char *out_base_name = argv[0];
|
|
char hname[PATH_MAX], cname[PATH_MAX];
|
|
|
|
argc -= 1;
|
|
argv += 1;
|
|
|
|
snprintf(hname, sizeof(hname), "%s.h", out_base_name);
|
|
|
|
FILE *hfile = fopen(hname, "wb");
|
|
if (hfile == NULL)
|
|
{
|
|
fprintf(stderr, "cannot open %s for writing\n", hname);
|
|
exit(1);
|
|
}
|
|
|
|
snprintf(cname, sizeof(cname), "%s.cc", out_base_name);
|
|
FILE *cfile = fopen(cname, "wb");
|
|
if (cfile == NULL)
|
|
{
|
|
fprintf(stderr, "cannot open %s for writing\n", cname);
|
|
exit(1);
|
|
}
|
|
|
|
char sym[1024];
|
|
if (name) {
|
|
strcpy(sym, name);
|
|
} else {
|
|
const char *in_base = basename(argv[0]);
|
|
|
|
symname(sym, in_base);
|
|
}
|
|
|
|
int array = argc > 1 || name;
|
|
char trailer[16];
|
|
|
|
if (array) {
|
|
snprintf(trailer, sizeof(trailer), "[%d]", argc);
|
|
} else {
|
|
trailer[0] = '\0';
|
|
}
|
|
fprintf(hfile, HEADER_FMT,
|
|
sym,
|
|
sym,
|
|
sym,
|
|
trailer);
|
|
fclose(hfile);
|
|
|
|
fprintf(cfile, "#include \"bin2c.hh\"\n");
|
|
fprintf(cfile, "\n");
|
|
|
|
struct file_meta *meta = alloca(sizeof(struct file_meta) * argc);
|
|
|
|
memset(meta, 0, sizeof(struct file_meta) * argc);
|
|
for (int lpc = 0; lpc < argc; lpc++) {
|
|
meta[lpc].fm_name = argv[lpc];
|
|
process(&meta[lpc], cfile);
|
|
}
|
|
|
|
fprintf(cfile,
|
|
"struct bin_src_file %s%s = {\n",
|
|
sym,
|
|
trailer);
|
|
for (int lpc = 0; lpc < argc; lpc++) {
|
|
char sym[1024];
|
|
|
|
symname(sym, basename((char *) meta[lpc].fm_name));
|
|
fprintf(cfile, " ");
|
|
if (array) {
|
|
fprintf(cfile, "{ ");
|
|
}
|
|
fprintf(cfile, "\"%s\", %s_data, %d, %d",
|
|
basename((char *) meta[lpc].fm_name),
|
|
sym,
|
|
meta[lpc].fm_compressed_size,
|
|
meta[lpc].fm_size);
|
|
if (array) {
|
|
fprintf(cfile, " },");
|
|
}
|
|
fprintf(cfile, "\n");
|
|
}
|
|
fprintf(cfile, "};\n");
|
|
fclose(cfile);
|
|
|
|
return 0;
|
|
}
|