1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ******************************************************************************* 5 * Copyright (C) 1999-2016, International Business Machines 6 * Corporation and others. All Rights Reserved. 7 ******************************************************************************* 8 * file name: gennames.c 9 * encoding: UTF-8 10 * tab size: 8 (not used) 11 * indentation:4 12 * 13 * created on: 1999nov01 14 * created by: Markus W. Scherer 15 * 16 * This program reads a binary file and creates a C source code file 17 * with a byte array that contains the data of the binary file. 18 * 19 * 12/09/1999 weiv Added multiple file handling 20 */ 21 22 #include "unicode/utypes.h" 23 24 #if U_PLATFORM_HAS_WIN32_API 25 # define VC_EXTRALEAN 26 # define WIN32_LEAN_AND_MEAN 27 # define NOUSER 28 # define NOSERVICE 29 # define NOIME 30 # define NOMCX 31 #include <windows.h> 32 #include <time.h> 33 #endif 34 35 #if U_PLATFORM_IS_LINUX_BASED && U_HAVE_ELF_H 36 # define U_ELF 37 #endif 38 39 #ifdef U_ELF 40 # include <elf.h> 41 # if defined(ELFCLASS64) 42 # define U_ELF64 43 # endif 44 /* Old elf.h headers may not have EM_X86_64, or have EM_X8664 instead. */ 45 # ifndef EM_X86_64 46 # define EM_X86_64 62 47 # endif 48 # define ICU_ENTRY_OFFSET 0 49 #endif 50 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include "unicode/putil.h" 54 #include "cmemory.h" 55 #include "cstring.h" 56 #include "filestrm.h" 57 #include "toolutil.h" 58 #include "unicode/uclean.h" 59 #include "uoptions.h" 60 #include "pkg_genc.h" 61 62 enum { 63 kOptHelpH = 0, 64 kOptHelpQuestionMark, 65 kOptDestDir, 66 kOptName, 67 kOptEntryPoint, 68 #ifdef CAN_GENERATE_OBJECTS 69 kOptObject, 70 kOptMatchArch, 71 #endif 72 kOptFilename, 73 kOptAssembly 74 }; 75 76 static UOption options[]={ 77 /*0*/UOPTION_HELP_H, 78 UOPTION_HELP_QUESTION_MARK, 79 UOPTION_DESTDIR, 80 UOPTION_DEF("name", 'n', UOPT_REQUIRES_ARG), 81 UOPTION_DEF("entrypoint", 'e', UOPT_REQUIRES_ARG), 82 #ifdef CAN_GENERATE_OBJECTS 83 /*5*/UOPTION_DEF("object", 'o', UOPT_NO_ARG), 84 UOPTION_DEF("match-arch", 'm', UOPT_REQUIRES_ARG), 85 #endif 86 UOPTION_DEF("filename", 'f', UOPT_REQUIRES_ARG), 87 UOPTION_DEF("assembly", 'a', UOPT_REQUIRES_ARG) 88 }; 89 90 #define CALL_WRITECCODE 'c' 91 #define CALL_WRITEASSEMBLY 'a' 92 #define CALL_WRITEOBJECT 'o' 93 extern int 94 main(int argc, char* argv[]) { 95 UBool verbose = TRUE; 96 char writeCode; 97 98 U_MAIN_INIT_ARGS(argc, argv); 99 100 options[kOptDestDir].value = "."; 101 102 /* read command line options */ 103 argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options); 104 105 /* error handling, printing usage message */ 106 if(argc<0) { 107 fprintf(stderr, 108 "error in command line argument \"%s\"\n", 109 argv[-argc]); 110 } 111 if(argc<0 || options[kOptHelpH].doesOccur || options[kOptHelpQuestionMark].doesOccur) { 112 fprintf(stderr, 113 "usage: %s [-options] filename1 filename2 ...\n" 114 "\tread each binary input file and \n" 115 "\tcreate a .c file with a byte array that contains the input file's data\n" 116 "options:\n" 117 "\t-h or -? or --help this usage text\n" 118 "\t-d or --destdir destination directory, followed by the path\n" 119 "\t-n or --name symbol prefix, followed by the prefix\n" 120 "\t-e or --entrypoint entry point name, followed by the name (_dat will be appended)\n" 121 "\t-r or --revision Specify a version\n" 122 , argv[0]); 123 #ifdef CAN_GENERATE_OBJECTS 124 fprintf(stderr, 125 "\t-o or --object write a .obj file instead of .c\n" 126 "\t-m or --match-arch file.o match the architecture (CPU, 32/64 bits) of the specified .o\n" 127 "\t ELF format defaults to i386. Windows defaults to the native platform.\n"); 128 #endif 129 fprintf(stderr, 130 "\t-f or --filename Specify an alternate base filename. (default: symbolname_typ)\n" 131 "\t-a or --assembly Create assembly file. (possible values are: "); 132 133 printAssemblyHeadersToStdErr(); 134 } else { 135 const char *message, *filename; 136 /* TODO: remove void (*writeCode)(const char *, const char *); */ 137 138 if(options[kOptAssembly].doesOccur) { 139 message="generating assembly code for %s\n"; 140 writeCode = CALL_WRITEASSEMBLY; 141 /* TODO: remove writeCode=&writeAssemblyCode; */ 142 143 if (!checkAssemblyHeaderName(options[kOptAssembly].value)) { 144 fprintf(stderr, 145 "Assembly type \"%s\" is unknown.\n", options[kOptAssembly].value); 146 return -1; 147 } 148 } 149 #ifdef CAN_GENERATE_OBJECTS 150 else if(options[kOptObject].doesOccur) { 151 message="generating object code for %s\n"; 152 writeCode = CALL_WRITEOBJECT; 153 /* TODO: remove writeCode=&writeObjectCode; */ 154 } 155 #endif 156 else 157 { 158 message="generating C code for %s\n"; 159 writeCode = CALL_WRITECCODE; 160 /* TODO: remove writeCode=&writeCCode; */ 161 } 162 while(--argc) { 163 filename=getLongPathname(argv[argc]); 164 if (verbose) { 165 fprintf(stdout, message, filename); 166 } 167 168 switch (writeCode) { 169 case CALL_WRITECCODE: 170 writeCCode(filename, options[kOptDestDir].value, 171 options[kOptName].doesOccur ? options[kOptName].value : NULL, 172 options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL, 173 NULL); 174 break; 175 case CALL_WRITEASSEMBLY: 176 writeAssemblyCode(filename, options[kOptDestDir].value, 177 options[kOptEntryPoint].doesOccur ? options[kOptEntryPoint].value : NULL, 178 options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL, 179 NULL); 180 break; 181 #ifdef CAN_GENERATE_OBJECTS 182 case CALL_WRITEOBJECT: 183 writeObjectCode(filename, options[kOptDestDir].value, 184 options[kOptEntryPoint].doesOccur ? options[kOptEntryPoint].value : NULL, 185 options[kOptMatchArch].doesOccur ? options[kOptMatchArch].value : NULL, 186 options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL, 187 NULL); 188 break; 189 #endif 190 default: 191 /* Should never occur. */ 192 break; 193 } 194 /* TODO: remove writeCode(filename, options[kOptDestDir].value); */ 195 } 196 } 197 198 return 0; 199 } 200