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