--- /dev/null
+/* $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 <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+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 <file>\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 <stddef.h>\n\
+#include <stdint.h>\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;
+}
+