/* * Copyright (C) 2018 Tomasz Kramkowski * SPDX-License-Identifier: MIT */ #include #include #include #include #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 \n" "Licensed under the MIT license \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); }