Mercurial > hg > dmlib
view data2inc.c @ 410:e4b2f689aff6
Stdint -> SDL types conversion.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 03 Nov 2012 02:41:15 +0200 |
parents | 59244a7ae37f |
children | 9d668e48961c |
line wrap: on
line source
/* * data2inc - Convert binary data to "C"-source or XA-compatible include file * Programmed and designed by Matti 'ccr' Hamalainen * (C) Copyright 2003,2009-2012 Tecnic Software productions (TNSP) * * Please read file 'COPYING' for information on license and distribution. */ #include <errno.h> #include "dmlib.h" #include "dmargs.h" #include "dmmutex.h" #define RA_LINEBUF (16) enum { FMT_AUTO = 0, FMT_C, FMT_ASM }; char *optInFilename = NULL, *optOutFilename = NULL, *optObjName = "default_object", *optDataType = NULL, *optAddLine = NULL; int optIndentation = -1; int optFormat = FMT_AUTO; BOOL optHexMode = FALSE, optQuiet = FALSE, optExtraData = FALSE, optFormatting = TRUE; void (*writeHeader) (FILE *, char *) = NULL; void (*writeDecl) (FILE *, size_t, char *) = NULL; void (*writeData) (FILE *, Uint8 *, size_t) = NULL; void (*writeFooter) (FILE *, size_t, char *) = NULL; static DMOptArg optList[] = { { 0, '?', "help", "Show this help", OPT_NONE }, { 4, 'A', "format-asm", "Output in XA-compatible asm", OPT_NONE }, { 5, 'C', "format-c", "Output in ANSI C", OPT_NONE }, { 1, 'n', "name", "Set object name", OPT_ARGREQ }, { 2, 't', "type", "Set datatype (unsigned char/byte)", OPT_ARGREQ }, { 3, 'a', "add-line", "Add this line to start of file", OPT_ARGREQ }, { 6, 'x', "hexadecimal", "Use hexadecimal output", OPT_NONE }, { 7, 'q', "quiet", "Do not add comments", OPT_NONE }, { 8, 'f', "no-formatting", "Disable additional output formatting", OPT_NONE }, { 9, 'i', "indentation", "Set indentation (negative value = tab)", OPT_ARGREQ }, { 10, 'e', "extra-data", "Add object end labels and size in asm output", OPT_NONE }, }; static const int optListN = sizeof(optList) / sizeof(optList[0]); void argShowHelp() { dmPrintBanner(stdout, dmProgName, "[options] [sourcefile] [destfile]"); dmArgsPrintHelp(stdout, optList, optListN); printf( "\n" "To convert a data file to a C structure using 'Uint8' as type:\n" "$ data2inc -C -n variable_name -t Uint8 input.bin output.h\n" "\n" ); } BOOL argHandleOpt(const int optN, char *optArg, char *currArg) { switch (optN) { case 0: argShowHelp(); exit(0); break; case 1: optObjName = optArg; break; case 2: optDataType = optArg; break; case 3: optAddLine = optArg; break; case 4: optFormat = FMT_ASM; break; case 5: optFormat = FMT_C; break; case 6: optHexMode = TRUE; break; case 7: optQuiet = TRUE; break; case 8: optFormatting = FALSE; break; case 9: optIndentation = atoi(optArg); break; case 10: optExtraData = TRUE; break; default: dmError("Unknown option '%s'.\n", currArg); return FALSE; } return TRUE; } BOOL argHandleFile(char * currArg) { if (!optInFilename) optInFilename = currArg; else if (!optOutFilename) optOutFilename = currArg; else dmError("Source and destination filenames already specified, extraneous argument '%s'.\n", currArg); return TRUE; } /* Assembler include data output functions */ void writeHeader_ASM(FILE * f, char *name) { if (name) fprintf(f, "; '%s'", name); else fprintf(f, "; Generated"); fprintf(f, " by %s v%s\n", dmProgName, dmProgVersion); } void writeDecl_ASM(FILE * f, size_t len, char *name) { if (optExtraData) fprintf(f, "%s_size = %u\n", name, len); fprintf(f, "%s:\n", name); } void writeData_ASM(FILE * f, Uint8 * buf, size_t len) { size_t i; fprintf(f, "%s ", optDataType); for (i = 0; i < len; i++) { if (optFormatting) { if (optHexMode) fprintf(f, "$%.2x", buf[i]); else fprintf(f, "%3d", buf[i]); } else { if (optHexMode) fprintf(f, "$%x", buf[i]); else fprintf(f, "%d", buf[i]); } if (i < (len - 1)) fprintf(f, ","); } } void writeFooter_ASM(FILE * f, size_t len, char *name) { (void) len; if (optExtraData) fprintf(f, "%s_end: \n", name); else fprintf(f, "\n"); } /* ANSI-C include data output functions */ void writeHeader_C(FILE * f, char *name) { if (name) fprintf(f, "/* '%s' generated", name); else fprintf(f, "/* Generated"); fprintf(f, " by %s v%s\n" " */\n", dmProgName, dmProgVersion); } void writeDecl_C(FILE * f, size_t len, char *name) { fprintf(f, "const %s %s[%u] = {\n", optDataType, name, len); printf("extern const %s %s[%u];\n", optDataType, name, len); } void writeData_C(FILE * f, Uint8 * buf, size_t len) { size_t i; for (i = 0; i < len; i++) { if (optFormatting) { if (optHexMode) fprintf(f, "0x%.2x", buf[i]); else fprintf(f, "%3d", buf[i]); } else { if (optHexMode) fprintf(f, "0x%x", buf[i]); else fprintf(f, "%d", buf[i]); } fprintf(f, ","); } } void writeFooter_C(FILE * f, size_t len, char *name) { (void) len; (void) name; fprintf(f, "};\n"); } off_t dmGetFileSize(FILE *f) { off_t len, pos = ftell(f); fseeko(f, 0, SEEK_END); len = ftell(f); fseek(f, pos, SEEK_SET); return len; } int main(int argc, char *argv[]) { FILE *sfile = NULL, *dfile = NULL; off_t inSize; Uint8 inBuf[RA_LINEBUF]; int tmpRes; /* Initialize */ dmInitProg("data2inc", "Data to include converter", "0.6", NULL, NULL); dmVerbosity = 0; /* Parse arguments */ if (!dmArgsProcess(argc, argv, optList, optListN, argHandleOpt, argHandleFile, TRUE)) exit(1); /* Determine output type, if not specified */ if (optFormat == FMT_AUTO) { char *dext; if (optOutFilename == NULL) { dmError("Output format not specified and no output filename given (try --help)\n"); exit(1); } /* Check filename extension */ dext = strrchr(optOutFilename, '.'); if (dext) { dext++; if (!strcasecmp(dext, "c") || !strcasecmp(dext, "h") || !strcasecmp(dext, "cc") || !strcasecmp(dext, "cpp") || !strcasecmp(dext, "hpp") || !strcasecmp(dext, "c++")) optFormat = FMT_C; else optFormat = FMT_ASM; } else optFormat = FMT_ASM; } /* Set functions */ switch (optFormat) { case FMT_ASM: if (!optDataType) optDataType = ".byte"; writeHeader = writeHeader_ASM; writeDecl = writeDecl_ASM; writeData = writeData_ASM; writeFooter = writeFooter_ASM; break; case FMT_C: if (!optDataType) optDataType = "unsigned char"; writeHeader = writeHeader_C; writeDecl = writeDecl_C; writeData = writeData_C; writeFooter = writeFooter_C; break; case FMT_AUTO: default: dmError("Internal error, FMT_AUTO at output function init.\n"); exit(2); } /* Open the files */ if (optInFilename == NULL) sfile = stdin; else if ((sfile = fopen(optInFilename, "rb")) == NULL) { tmpRes = errno; dmError("Error opening input file '%s'. (%s)\n", optInFilename, strerror(tmpRes)); exit(3); } if (optOutFilename == NULL) dfile = stdout; else if ((dfile = fopen(optOutFilename, "wa")) == NULL) { tmpRes = errno; dmError("Error creating output file '%s'. (%s)\n", optOutFilename, strerror(tmpRes)); exit(4); } /* Get sourcefile size */ inSize = dmGetFileSize(sfile); /* Output header */ if (!optQuiet) writeHeader(dfile, optOutFilename); if (optAddLine) fprintf(dfile, "%s\n", optAddLine); /* Output declaration */ writeDecl(dfile, inSize, optObjName); /* Output data */ while (!feof(sfile)) { tmpRes = fread(inBuf, sizeof(Uint8), RA_LINEBUF, sfile); if (tmpRes > 0) { if (optIndentation < 0) fprintf(dfile, "\t"); else if (optIndentation > 0) { int i; for (i = 0; i < optIndentation; i++) fputs(" ", dfile); } writeData(dfile, inBuf, tmpRes); fprintf(dfile, "\n"); } } /* Output footer */ writeFooter(dfile, inSize, optObjName); /* Exit */ fclose(sfile); fclose(dfile); exit(0); return 0; }