Initial import; utility to replace binutils objcopy when embedding files
authorMatthew Mondor <mmondor@pulsar-zone.net>
Wed, 25 Jun 2014 06:13:19 +0000 (06:13 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Wed, 25 Jun 2014 06:13:19 +0000 (06:13 +0000)
into an application, as it was problematic on some operating systems.

mmsoftware/util/file-to-c.c [new file with mode: 0644]

diff --git a/mmsoftware/util/file-to-c.c b/mmsoftware/util/file-to-c.c
new file mode 100644 (file)
index 0000000..3eb9053
--- /dev/null
@@ -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 <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;
+}
+