genccode.c (8139B)
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 <stdbool.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include "unicode/putil.h" 55 #include "cmemory.h" 56 #include "cstring.h" 57 #include "filestrm.h" 58 #include "toolutil.h" 59 #include "unicode/uclean.h" 60 #include "uoptions.h" 61 #include "pkg_genc.h" 62 63 enum { 64 kOptHelpH = 0, 65 kOptHelpQuestionMark, 66 kOptDestDir, 67 kOptQuiet, 68 kOptName, 69 kOptEntryPoint, 70 #ifdef CAN_GENERATE_OBJECTS 71 kOptObject, 72 kOptMatchArch, 73 kOptCpuArch, 74 kOptSkipDllExport, 75 #endif 76 kOptFilename, 77 kOptAssembly 78 }; 79 80 static UOption options[]={ 81 /*0*/UOPTION_HELP_H, 82 UOPTION_HELP_QUESTION_MARK, 83 UOPTION_DESTDIR, 84 UOPTION_QUIET, 85 UOPTION_DEF("name", 'n', UOPT_REQUIRES_ARG), 86 UOPTION_DEF("entrypoint", 'e', UOPT_REQUIRES_ARG), 87 #ifdef CAN_GENERATE_OBJECTS 88 /*6*/UOPTION_DEF("object", 'o', UOPT_NO_ARG), 89 UOPTION_DEF("match-arch", 'm', UOPT_REQUIRES_ARG), 90 UOPTION_DEF("cpu-arch", 'c', UOPT_REQUIRES_ARG), 91 UOPTION_DEF("skip-dll-export", '\0', UOPT_NO_ARG), 92 #endif 93 UOPTION_DEF("filename", 'f', UOPT_REQUIRES_ARG), 94 UOPTION_DEF("assembly", 'a', UOPT_REQUIRES_ARG) 95 }; 96 97 #define CALL_WRITECCODE 'c' 98 #define CALL_WRITEASSEMBLY 'a' 99 #define CALL_WRITEOBJECT 'o' 100 extern int 101 main(int argc, char* argv[]) { 102 UBool verbose = true; 103 char writeCode; 104 105 U_MAIN_INIT_ARGS(argc, argv); 106 107 options[kOptDestDir].value = "."; 108 109 /* read command line options */ 110 argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options); 111 112 /* error handling, printing usage message */ 113 if(argc<0) { 114 fprintf(stderr, 115 "error in command line argument \"%s\"\n", 116 argv[-argc]); 117 } 118 if(argc<0 || options[kOptHelpH].doesOccur || options[kOptHelpQuestionMark].doesOccur) { 119 fprintf(stderr, 120 "usage: %s [-options] filename1 filename2 ...\n" 121 "\tread each binary input file and \n" 122 "\tcreate a .c file with a byte array that contains the input file's data\n" 123 "options:\n" 124 "\t-h or -? or --help this usage text\n" 125 "\t-d or --destdir destination directory, followed by the path\n" 126 "\t-q or --quiet do not display warnings and progress\n" 127 "\t-n or --name symbol prefix, followed by the prefix\n" 128 "\t-e or --entrypoint entry point name, followed by the name (_dat will be appended)\n" 129 "\t-r or --revision Specify a version\n" 130 , argv[0]); 131 #ifdef CAN_GENERATE_OBJECTS 132 fprintf(stderr, 133 "\t-o or --object write a .obj file instead of .c\n" 134 "\t-m or --match-arch file.o match the architecture (CPU, 32/64 bits) of the specified .o\n" 135 "\t ELF format defaults to i386. Windows defaults to the native platform.\n" 136 "\t-c or --cpu-arch Specify a CPU architecture for which to write a .obj file for ClangCL on Windows\n" 137 "\t Valid values for this opton are x64, x86 and arm64.\n" 138 "\t--skip-dll-export Don't export the ICU data entry point symbol (for use when statically linking)\n"); 139 #endif 140 fprintf(stderr, 141 "\t-f or --filename Specify an alternate base filename. (default: symbolname_typ)\n" 142 "\t-a or --assembly Create assembly file. (possible values are: "); 143 144 printAssemblyHeadersToStdErr(); 145 } else { 146 const char *message, *filename; 147 /* TODO: remove void (*writeCode)(const char *, const char *); */ 148 149 if(options[kOptAssembly].doesOccur) { 150 message="generating assembly code for %s\n"; 151 writeCode = CALL_WRITEASSEMBLY; 152 /* TODO: remove writeCode=&writeAssemblyCode; */ 153 154 if (!checkAssemblyHeaderName(options[kOptAssembly].value)) { 155 fprintf(stderr, 156 "Assembly type \"%s\" is unknown.\n", options[kOptAssembly].value); 157 return -1; 158 } 159 } 160 #ifdef CAN_GENERATE_OBJECTS 161 else if(options[kOptObject].doesOccur) { 162 message="generating object code for %s\n"; 163 writeCode = CALL_WRITEOBJECT; 164 /* TODO: remove writeCode=&writeObjectCode; */ 165 } 166 #endif 167 else 168 { 169 message="generating C code for %s\n"; 170 writeCode = CALL_WRITECCODE; 171 /* TODO: remove writeCode=&writeCCode; */ 172 } 173 if (options[kOptQuiet].doesOccur) { 174 verbose = false; 175 } 176 while(--argc) { 177 filename=getLongPathname(argv[argc]); 178 if (verbose) { 179 fprintf(stdout, message, filename); 180 } 181 182 switch (writeCode) { 183 case CALL_WRITECCODE: 184 writeCCode(filename, options[kOptDestDir].value, 185 options[kOptEntryPoint].doesOccur ? options[kOptEntryPoint].value : NULL, 186 options[kOptName].doesOccur ? options[kOptName].value : NULL, 187 options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL, 188 NULL, 189 0); 190 break; 191 case CALL_WRITEASSEMBLY: 192 writeAssemblyCode(filename, options[kOptDestDir].value, 193 options[kOptEntryPoint].doesOccur ? options[kOptEntryPoint].value : NULL, 194 options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL, 195 NULL, 196 0); 197 break; 198 #ifdef CAN_GENERATE_OBJECTS 199 case CALL_WRITEOBJECT: 200 if(options[kOptCpuArch].doesOccur) { 201 if (!checkCpuArchitecture(options[kOptCpuArch].value)) { 202 fprintf(stderr, 203 "CPU architecture \"%s\" is unknown.\n", options[kOptCpuArch].value); 204 return -1; 205 } 206 } 207 writeObjectCode(filename, options[kOptDestDir].value, 208 options[kOptEntryPoint].doesOccur ? options[kOptEntryPoint].value : NULL, 209 options[kOptMatchArch].doesOccur ? options[kOptMatchArch].value : NULL, 210 options[kOptCpuArch].doesOccur ? options[kOptCpuArch].value : NULL, 211 options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL, 212 NULL, 213 0, 214 !options[kOptSkipDllExport].doesOccur); 215 break; 216 #endif 217 default: 218 /* Should never occur. */ 219 break; 220 } 221 /* TODO: remove writeCode(filename, options[kOptDestDir].value); */ 222 } 223 } 224 225 return 0; 226 }