From: Matthew Mondor Date: Wed, 25 Jun 2014 06:13:19 +0000 (+0000) Subject: Initial import; utility to replace binutils objcopy when embedding files X-Git-Url: http://git.pulsar-zone.net/?a=commitdiff_plain;h=b82d37fad221663aaa9fdca4b1d1a0c10d6523bf;p=mmondor.git Initial import; utility to replace binutils objcopy when embedding files into an application, as it was problematic on some operating systems. --- diff --git a/mmsoftware/util/file-to-c.c b/mmsoftware/util/file-to-c.c new file mode 100644 index 0000000..3eb9053 --- /dev/null +++ b/mmsoftware/util/file-to-c.c @@ -0,0 +1,194 @@ +/* $Id: file-to-c.c,v 1.1 2014/06/25 06:13:19 mmondor Exp $ */ + +/* + * Copyright (c) 2014, Matthew Mondor + * ALL RIGHTS RESERVED. + */ + +/* + * Simple program to convert a file to a C program which can then be compiled + * and linked with an application. On some operating systems, using binutils + * objcopy to do this is problematic. + */ + +#include +#include +#include +#include +#include + + +int main(int, char **); +static const char *basename(const char *); +static char *symbolname(const char *); +static long filesize(const char *); +static char *strtoupper(const char *); + + +int +main(int argc, char **argv) +{ + char *source, *target_c, *target_h, *symbol, *symbol2; + int i; + long size, count; + FILE *fhs, *fht; + + if (argc != 2) { + (void) fprintf(stderr, "Usage: %s \n", argv[0]); + exit(EXIT_FAILURE); + } + source = argv[1]; + + symbol = symbolname(basename(source)); + symbol2 = strtoupper(symbol); + i = strlen(source); + if ((target_c = malloc(i + 3)) == NULL) { + (void) fprintf(stderr, "malloc(%d) - %s\n", i + 3, + strerror(errno)); + exit(EXIT_FAILURE); + } + (void) memcpy(target_c, source, i); + target_c[i++] = '.'; + target_c[i] = 'c'; + target_c[i + 1] = '\0'; + if ((target_h = strdup(target_c)) == NULL) { + (void) fprintf(stderr, "strdup(%s) - %s\n", target_c, + strerror(errno)); + exit(EXIT_FAILURE); + } + target_h[i] = 'h'; + + size = filesize(source); + if ((fht = fopen(target_c, "w")) == NULL) { + (void) fprintf(stderr, "fopen(%s) - %s\n", target_c, + strerror(errno)); + exit(EXIT_FAILURE); + } + if ((fhs = fopen(source, "r")) == NULL) { + (void) fprintf(stderr, "fopen(%s) - %s\n", source, + strerror(errno)); + exit(EXIT_FAILURE); + } + (void) fprintf(fht, + "\n/* Autogenerated by file-to-c, do not edit */\n\n\ +#include \n\ +#include \n\ +\n\ +const uint8_t\tstatic_%s_data[] = {\n\ + ", symbol); + for (i = 0, count = 1; ; i++, count++) { + uint8_t b; + + if (i == 8) { + (void) fprintf(fht, "\n\t"); + i = 0; + } + if (fread(&b, 1, 1, fhs) != 1) + break; + (void) fprintf(fht, "0x%02X%s", b, + (count == size ? "" : ", ")); + } + (void) fclose(fhs); + (void) fprintf(fht, "\n};\n\n\ +const size_t\tstatic_%s_size = %ld;\n\n", symbol, size); + (void) fclose(fht); + + if ((fht = fopen(target_h, "w")) == NULL) { + (void) fprintf(stderr, "fopen(%s) - %s\n", target_h, + strerror(errno)); + exit(EXIT_FAILURE); + } + (void) fprintf(fht, + "\n/* Autogenerated by file-to-c, do not edit */\n\n\ +#ifndef _STATIC_%s_\n\ +#define _STATIC_%s_\n\ +\n\ +extern const uint8_t\t*static_%s_data;\n\ +extern const size_t\tstatic_%s_size;\n\ +\n\ +#endif\n\n", symbol2, symbol2, symbol, symbol); + (void) fclose(fht); + + exit(EXIT_SUCCESS); +} + +/* Not available on all systems; minimal implementation */ +static const char * +basename(const char *path) +{ + const char *cptr; + + for (;;) { + for (cptr = path; *cptr != '\0' && *cptr != '/'; cptr++) ; + if (*cptr == '/') { + path = ++cptr; + continue; + } + break; + } + + return path; +} + +static char * +symbolname(const char *string) +{ + char *symbol, *cptr; + + if ((symbol = strdup(string)) == NULL) { + (void) fprintf(stderr, "strdup(%s) - %s\n", string, + strerror(errno)); + exit(EXIT_FAILURE); + } + + for (cptr = symbol; *cptr != '\0'; cptr++) { + if (!isalnum((int)*cptr)) + *cptr = '_'; + } + + return symbol; +} + +/* stat(2)/fstat(2) not available on all systems */ +static long +filesize(const char *path) +{ + FILE *fh; + long size; + + if ((fh = fopen(path, "rb")) == NULL) { + (void) fprintf(stderr, "fopen(%s) - %s\n", path, + strerror(errno)); + exit(EXIT_FAILURE); + } + if (fseek(fh, 0, SEEK_END) == -1) { + (void) fprintf(stderr, "fseek(SEEK_END) - %s\n", + strerror(errno)); + exit(EXIT_FAILURE); + } + if ((size = ftell(fh)) == -1) { + (void) fprintf(stderr, "ftell() - %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + (void) fclose(fh); + + return size; +} + +static char * +strtoupper(const char *string) +{ + char *str, *cptr; + + if ((str = strdup(string)) == NULL) { + (void) fprintf(stderr, "strdup(%s) - %s\n", string, + strerror(errno)); + exit(EXIT_FAILURE); + } + + for (cptr = str; *cptr != '\0'; cptr++) + *cptr = toupper((int)*cptr); + + return str; +} +