// BIN2C.CPP
// by Jonathon Fowler (jf@jonof.id.au)

// Converts a binary file to C source
// This is a DOS program originally written with Borland Turbo C++ for DOS 3.1


#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <dir.h>
#include <io.h>
#include <stdlib.h>


char defsrcext[] = ".DAT";
char defoutext[] = ".C";

char source[MAXPATH], output[MAXPATH], bytesize;


int PathAddExt(char *path, char *ext);


int main(int argc, char *argv[])
{
    printf("BIN2C - Binary to C data converter\n"
             "Copyright (c) 1999 Jonathon Fowler\n\n");

    if (argc < 4)
    {
        printf("Usage:\n"
                 "   BIN2C source<.DAT> output<.C> b|w\n\n"
                 "   source<.DAT>   Binary source file\n"
                 "   output<.C>     Output C code file\n"
                 "   b|w            Byte or word-sized data\n\n");
        exit(0);
    }

    int arg;
    FILE *in, *out;
    char datab1, datab2;
    int across=0, maxacross;
    int length, written=0;


    // get the source file
    strcpy(source, argv[1]);
    strupr(source);
    PathAddExt(source, defsrcext);
    printf("þ Source file:  %s\n", source);

    // get the output file
    strcpy(output, argv[2]);
    strupr(output);
    PathAddExt(output, defoutext);
    printf("þ Output file:  %s\n", output);

    // get byte/word data
    switch (tolower(argv[3][0]))
    {
        case 'b':
            printf("þ Byte data.\n");
            bytesize=1;
            break;

        case 'w':
            printf("þ Word data.\n");
            bytesize=0;
            break;

        default:
            printf("þ Unknown data size specified. Defaulting to byte.\n");
            bytesize=1;
            break;
    }

    // open the input file
    in = fopen(source, "rb");
    if (!in)
    {
        printf("Error opening %s\n", source);
        exit(1);
    }

    // open the output file
    out = fopen(output, "w+t");
    if (!out)
    {
        printf("Error creating %s\n", output);
        exit(1);
    }

    length = filelength(fileno(in));

    // write a header out to the output file
    fprintf(out, "// %s\n\n// Generated by BIN2C.EXE\n// By Jonathon Fowler\n\n", output);

    // start a data block
    fprintf(out, "%s datablock[] = {\n // %ld bytes", (bytesize) ? "char" : "unsigned", length);

    if (bytesize)
        maxacross = 12;
    else
        maxacross = 9;
    across = maxacross;

    // convert the data
    for (written=0; written<length; written++) {
        if (across == maxacross)
        {
            fprintf(out, "\n  ");
            across = 0;
        }

        if (bytesize)
        {
            datab1 = fgetc(in);
            fprintf(out, " 0x%02X%c", datab1, ((length-written)>1) ? ',' : '\n');
        } else {
            datab1 = fgetc(in);
            datab2 = fgetc(in);
            fprintf(out, " 0x%02X%02X%c", datab2, datab1, ((length-written)>2) ? ',' : '\n');
        }

        across++;

        if (!bytesize) written++;
    }


    fprintf(out, "  };");

    fclose(out);
    fclose(in);

    return 0;
}


// Add an extention to a path if one doesn't exist
int PathAddExt(char *path, char *ext)
{
    char drive[MAXDRIVE], dir[MAXDIR], name[MAXFILE], extn[MAXEXT];
    int flags;

    flags = fnsplit(path, drive, dir, name, extn);

    if (!(flags & EXTENSION))    // tack on an extension
        strcat(path, ext);

    return ((flags & EXTENSION) == 0);
}
