aboutsummaryrefslogtreecommitdiffstats
path: root/bie.c
diff options
context:
space:
mode:
Diffstat (limited to 'bie.c')
-rw-r--r--bie.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/bie.c b/bie.c
new file mode 100644
index 0000000..66c97c9
--- /dev/null
+++ b/bie.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2018 Tomasz Kramkowski <tk@the-tk.com>
+ * SPDX-License-Identifier: MIT
+ */
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "eprintf.h"
+
+#ifndef VERSION
+#define VERSION "v0.1"
+#endif
+
+enum {
+ ALIGN = 16,
+};
+
+static const char *usage = "[-hv] [--] output map input...";
+
+static void help(void)
+{
+ fprintf(stderr,
+ "Options:\n"
+ " -h Show this help.\n"
+ " -v Show version and license information.\n"
+ "\n"
+ "Please check the bie(1) man page for more information.\n");
+}
+
+static void version(void)
+{
+ fprintf(stderr,
+ "bie %s\n"
+ "Copyright (C) 2018 Tomasz Kramkowski <tk@the-tk.com>\n"
+ "Licensed under the MIT license <https://opensource.org/licenses/MIT>\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ VERSION);
+}
+
+static void slug(FILE *f, const char *text)
+{
+ bool leading = true;
+ int c;
+
+ while (c = *text++, c != '\0') {
+ if (isalpha(c)) {
+ leading = false;
+ fputc(c, f);
+ continue;
+ }
+ if (leading) continue;
+ if (isdigit(c))
+ fputc(c, f);
+ else if (ispunct(c) || isspace(c))
+ fputc('_', f);
+ }
+}
+
+static void mapentry(FILE *map, const char *name, size_t pos, size_t size)
+{
+ fprintf(map, "BIE_ENTRY(");
+ slug(map, name);
+ fprintf(map, ", %zu, %zu)\n", pos, size);
+}
+
+static size_t dumpfile(FILE *dest, FILE *src)
+{
+ size_t size = 0;
+ int c;
+
+ while (c = fgetc(src), c != EOF) {
+ size++;
+ fputc(c, dest);
+ }
+
+ return size;
+}
+
+int main(int argc, char **argv)
+{
+ const char *argv0 = argv[0] != NULL ? argv[0] : "bie";
+ FILE *dest, *map;
+ size_t pos = 0;
+
+ setprogname(argv0);
+
+ for (argv++, argc--; argv[0] != NULL && argv[0][0] == '-' &&
+ argv[0][1] != '-' && argv[0][2] == '\0'; argv++, argc--) {
+ switch (argv[0][1]) {
+ case 'h':
+ fprintf(stderr, "Usage: %s %s\n", argv0, usage);
+ help();
+ return EXIT_SUCCESS;
+ case 'v':
+ version();
+ return EXIT_SUCCESS;
+ }
+ }
+
+ if (argc < 3)
+ eprintf("Invalid argument count\nUsage: %s %s", argv0, usage);
+
+ dest = fopen(argv[0], "wb");
+ if (dest == NULL)
+ eprintf("Could not open `%s':", argv[0]);
+
+ map = fopen(argv[1], "w");
+ if (map == NULL)
+ eprintf("Could not open `%s':", argv[1]);
+
+ for (int i = 2; i < argc; i++) {
+ size_t size;
+ FILE *src;
+
+ src = fopen(argv[i], "rb");
+ if (src == NULL)
+ eprintf("Could not open `%s':", argv[i]);
+ size = dumpfile(dest, src);
+ fclose(src);
+ mapentry(map, argv[i], pos, size);
+ pos += size;
+ if (pos % ALIGN) {
+ size_t pad = ALIGN - pos % ALIGN;
+ for (size_t i = 0; i < pad; i++)
+ fputc(0, dest);
+ pos += pad;
+ }
+ }
+
+ fclose(map);
+ fclose(dest);
+}