/* ******************************************************************************* * * Copyright (C) 1999-2003, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* * file name: gennames.c * encoding: US-ASCII * tab size: 8 (not used) * indentation:4 * * created on: 1999nov01 * created by: Markus W. Scherer * * This program reads a binary file and creates a C source code file * with a byte array that contains the data of the binary file. * * 12/09/1999 weiv Added multiple file handling */ #ifdef WIN32 # define VC_EXTRALEAN # define WIN32_LEAN_AND_MEAN # define NOGDI # define NOUSER # define NOSERVICE # define NOIME # define NOMCX #include #include /* _M_IA64 should be defined in windows.h */ #if defined(_M_IA64) # define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_IA64 # define ICU_ENTRY_OFFSET 0 #elif defined(_M_AMD64) # define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64 # define ICU_ENTRY_OFFSET 0 #else # define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_I386 # define ICU_ENTRY_OFFSET 1 #endif #endif #include #include #include "unicode/utypes.h" #include "unicode/putil.h" #include "cmemory.h" #include "cstring.h" #include "filestrm.h" #include "toolutil.h" #include "unicode/uclean.h" #include "uoptions.h" #define MAX_COLUMN ((uint32_t)(0xFFFFFFFFU)) static uint32_t column=MAX_COLUMN; #ifdef WIN32 #define CAN_GENERATE_OBJECTS #endif /* prototypes --------------------------------------------------------------- */ static void writeCCode(const char *filename, const char *destdir); static void writeAssemblyCode(const char *filename, const char *destdir); #ifdef CAN_GENERATE_OBJECTS static void writeObjectCode(const char *filename, const char *destdir); #endif static void getOutFilename(const char *inFilename, const char *destdir, char *outFilename, char *entryName, const char *newSuffix); static void write8(FileStream *out, uint8_t byte); static void write32(FileStream *out, uint32_t byte); #ifdef OS400 static void write8str(FileStream *out, uint8_t byte); #endif /* -------------------------------------------------------------------------- */ enum { kOptHelpH = 0, kOptHelpQuestionMark, kOptDestDir, kOptName, kOptEntryPoint, #ifdef CAN_GENERATE_OBJECTS kOptObject, #endif kOptFilename, kOptAssembly }; /* Creating Template Files for New Platforms Let the cc compiler help you get started. Compile this program const unsigned int x[5] = {1, 2, 0xdeadbeef, 0xffffffff, 16}; with the -S option to produce assembly output This will produce a .s file, something like .file "foo.c" .version "01.01" gcc2_compiled.: .globl x .section .rodata .align 4 .type x,@object .size x,20 x: .long 1 .long 2 .long -559038737 .long -1 .long 16 .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-85)" which gives a starting point that will compile, and can be transformed to become the template, generally with some consulting of as docs and some experimentation. */ static const struct AssemblyType { const char *compiler; const char *header; const char *beginLine; } assemblyHeader[] = { {"gcc", ".globl %s\n" "\t.section .rodata\n" "\t.align 8\n" /* Either align 8 bytes or 2^8 (256) bytes. 8 bytes is needed. */ "%s:\n\n", ".long " }, {"gcc-darwin", /*"\t.section __TEXT,__text,regular,pure_instructions\n" "\t.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n"*/ ".globl _%s\n" "\t.data\n" "\t.const\n" "\t.align 4\n" /* 1<<4 = 16 */ "_%s:\n\n", ".long " }, {"gcc-cygwin", ".globl _%s\n" "\t.section .rodata\n" "\t.align 8\n" /* Either align 8 bytes or 2^8 (256) bytes. 8 bytes is needed. */ "_%s:\n\n", ".long " }, {"sun", "\t.section \".rodata\"\n" "\t.align 8\n" ".globl %s\n" "%s:\n", ".word " }, {"xlc", ".globl %s{RO}\n" "\t.toc\n" "%s:\n" "\t.csect %s{RO}, 4\n", ".long " }, {"aCC", "\t.SPACE $TEXT$\n" "\t.SUBSPA $LIT$\n" "%s\n" "\t.EXPORT %s\n" "\t.ALIGN 16\n", ".WORD " } }; static int32_t assemblyHeaderIndex = -1; static UOption options[]={ /*0*/UOPTION_HELP_H, UOPTION_HELP_QUESTION_MARK, UOPTION_DESTDIR, UOPTION_DEF("name", 'n', UOPT_REQUIRES_ARG), UOPTION_DEF("entrypoint", 'e', UOPT_REQUIRES_ARG), #ifdef CAN_GENERATE_OBJECTS /*5*/UOPTION_DEF("object", 'o', UOPT_NO_ARG), #endif UOPTION_DEF("filename", 'f', UOPT_REQUIRES_ARG), UOPTION_DEF("assembly", 'a', UOPT_REQUIRES_ARG) }; extern int main(int argc, char* argv[]) { UBool verbose = TRUE; int32_t idx; U_MAIN_INIT_ARGS(argc, argv); options[kOptDestDir].value = "."; /* read command line options */ argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options); /* error handling, printing usage message */ if(argc<0) { fprintf(stderr, "error in command line argument \"%s\"\n", argv[-argc]); } if(argc<0 || options[kOptHelpH].doesOccur || options[kOptHelpQuestionMark].doesOccur) { fprintf(stderr, "usage: %s [-options] filename1 filename2 ...\n" "\tread each binary input file and \n" "\tcreate a .c file with a byte array that contains the input file's data\n" "options:\n" "\t-h or -? or --help this usage text\n" "\t-d or --destdir destination directory, followed by the path\n" "\t-n or --name symbol prefix, followed by the prefix\n" "\t-e or --entrypoint entry point name, followed by the name\n" "\t-r or --revision Specify a version\n" #ifdef CAN_GENERATE_OBJECTS "\t-o or --object write a .obj file instead of .c\n" #endif "\t-f or --filename Specify an alternate base filename. (default: symbolname_typ)\n" , argv[0]); fprintf(stderr, "\t-a or --assembly Create assembly file. (possible values are: "); fprintf(stderr, "%s", assemblyHeader[0].compiler); for (idx = 1; idx < (int32_t)(sizeof(assemblyHeader)/sizeof(assemblyHeader[0])); idx++) { fprintf(stderr, ", %s", assemblyHeader[idx].compiler); } fprintf(stderr, ")\n"); } else { const char *message, *filename; void (*writeCode)(const char *, const char *); if(options[kOptAssembly].doesOccur) { message="generating assembly code for %s\n"; writeCode=&writeAssemblyCode; for (idx = 0; idx < (int32_t)(sizeof(assemblyHeader)/sizeof(assemblyHeader[0])); idx++) { if (uprv_strcmp(options[kOptAssembly].value, assemblyHeader[idx].compiler) == 0) { assemblyHeaderIndex = idx; break; } } if (assemblyHeaderIndex < 0) { fprintf(stderr, "Assembly type \"%s\" is unknown.\n", options[kOptAssembly].value); return -1; } } #ifdef CAN_GENERATE_OBJECTS else if(options[kOptObject].doesOccur) { message="generating object code for %s\n"; writeCode=&writeObjectCode; } #endif else { message="generating C code for %s\n"; writeCode=&writeCCode; } while(--argc) { filename=getLongPathname(argv[argc]); if (verbose) { fprintf(stdout, message, filename); } column=MAX_COLUMN; writeCode(filename, options[kOptDestDir].value); } } return 0; } static void writeAssemblyCode(const char *filename, const char *destdir) { char entry[64]; uint32_t buffer[1024]; char *bufferStr = (char *)buffer; FileStream *in, *out; size_t i, length; in=T_FileStream_open(filename, "rb"); if(in==NULL) { fprintf(stderr, "genccode: unable to open input file %s\n", filename); exit(U_FILE_ACCESS_ERROR); } getOutFilename(filename, destdir, bufferStr, entry, ".s"); out=T_FileStream_open(bufferStr, "w"); if(out==NULL) { fprintf(stderr, "genccode: unable to open output file %s\n", bufferStr); exit(U_FILE_ACCESS_ERROR); } if(options[kOptEntryPoint].doesOccur) { uprv_strcpy(entry, options[kOptEntryPoint].value); uprv_strcat(entry, "_dat"); } /* turn dashes or dots in the entry name into underscores */ length=uprv_strlen(entry); for(i=0; i= 0 ; i--) #endif { uint8_t value = ptrIdx[i]; if (value || seenNonZero) { *(s++)=hexToStr[value>>4]; *(s++)=hexToStr[value&0xF]; seenNonZero = 1; } } } *(s++)=0; T_FileStream_writeLine(out, bitFieldStr); } static void write8(FileStream *out, uint8_t byte) { char s[4]; int i=0; /* convert the byte value to a string */ if(byte>=100) { s[i++]=(char)('0'+byte/100); byte%=100; } if(i>0 || byte>=10) { s[i++]=(char)('0'+byte/10); byte%=10; } s[i++]=(char)('0'+byte); s[i]=0; /* write the value, possibly with comma and newline */ if(column==MAX_COLUMN) { /* first byte */ column=1; } else if(column<16) { T_FileStream_writeLine(out, ","); ++column; } else { T_FileStream_writeLine(out, ",\n"); column=1; } T_FileStream_writeLine(out, s); } #ifdef OS400 static void write8str(FileStream *out, uint8_t byte) { char s[8]; sprintf(s, "\\x%02X", byte); /* write the value, possibly with comma and newline */ if(column==MAX_COLUMN) { /* first byte */ column=1; T_FileStream_writeLine(out, "\""); } else if(column<16) { ++column; } else { T_FileStream_writeLine(out, "\"\n\""); column=1; } T_FileStream_writeLine(out, s); } #endif