/*
 * This C program takes a filename and an array name, and prints to
 * stdout an array of the data contained in the file.
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>

int main(int argc, char *argv[])
{
    char *arrayname, *filename;
    unsigned char *src;
    struct stat stat_buf;
    int length, fd, i, n;

    if (argc != 3) {
        fprintf(stderr, "usage: %s [filename] [arrayname]\n", argv[0]);
        return 1;
    }
    
    filename = argv[1];
    arrayname = argv[2];
    
    /* open the file */

    fd = open(filename, O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "unable to open(2) %s (%s)\n",
                filename, strerror(errno));
        return 1;
    }

    /* get the length of the file */

    if (fstat(fd, &stat_buf) != 0) {
        fprintf(stderr, "unable to stat(2) %s (%s)\n",
                filename, strerror(errno));
        return 1;
    }

    length = stat_buf.st_size;

    /* map the file */

    src = mmap(0, length, PROT_READ, MAP_SHARED, fd, 0);
    if (src == (void *) -1) {
        fprintf(stderr, "unable to mmap(2) %s (%s)\n",
                filename, strerror(errno));
        return 1;
    }

    /* print the header */

    printf("/*\n");
    printf( " * THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT\n");
    printf( " *\n");
    printf( " * This file contains the contents of the file \"%s\"\n",
            filename);
    printf( " * as the byte array %s[].\n", arrayname);
    printf( " */\n\n");

    /* print a separate variable that stores the size */

    printf("const int %s_size = %d;\n\n", arrayname, length);

    /* print the array name */

    printf("const unsigned char %s[%d] = {\n", arrayname, length);

    for (i = 0, n = 0; i < length; i++, n++) {
        if (n == 0) printf("    ");
        printf("0x%02x, ", src[i]);
        if (n >= 11) { printf("\n"); n = -1; }
    }
    
    printf("\n};\n\n");

    /* unmap the file */

    munmap(src, length);

    /* close the file */

    close(fd);


    return 0;
}
