]> git.saurik.com Git - apple/icu.git/blame - icuSources/tools/genccode/genccode.c
ICU-6.2.22.tar.gz
[apple/icu.git] / icuSources / tools / genccode / genccode.c
CommitLineData
b75a7d8f
A
1/*
2*******************************************************************************
3*
374ca955 4* Copyright (C) 1999-2004, International Business Machines
b75a7d8f
A
5* Corporation and others. All Rights Reserved.
6*
7*******************************************************************************
8* file name: gennames.c
9* encoding: US-ASCII
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#ifdef WIN32
23# define VC_EXTRALEAN
24# define WIN32_LEAN_AND_MEAN
b75a7d8f
A
25# define NOUSER
26# define NOSERVICE
27# define NOIME
28# define NOMCX
29#include <windows.h>
30#include <time.h>
31
32/* _M_IA64 should be defined in windows.h */
374ca955 33#if defined(_M_IA64)
b75a7d8f
A
34# define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_IA64
35# define ICU_ENTRY_OFFSET 0
374ca955
A
36#elif defined(_M_AMD64)
37# define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64
38# define ICU_ENTRY_OFFSET 0
b75a7d8f
A
39#else
40# define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_I386
41# define ICU_ENTRY_OFFSET 1
42#endif
43
44#endif
45
46#include <stdio.h>
47#include <stdlib.h>
48#include "unicode/utypes.h"
49#include "unicode/putil.h"
50#include "cmemory.h"
51#include "cstring.h"
52#include "filestrm.h"
53#include "toolutil.h"
374ca955 54#include "unicode/uclean.h"
b75a7d8f
A
55#include "uoptions.h"
56
57#define MAX_COLUMN ((uint32_t)(0xFFFFFFFFU))
58
59static uint32_t column=MAX_COLUMN;
60
61#ifdef WIN32
62#define CAN_GENERATE_OBJECTS
63#endif
64
65/* prototypes --------------------------------------------------------------- */
66
67static void
68writeCCode(const char *filename, const char *destdir);
69
374ca955
A
70static void
71writeAssemblyCode(const char *filename, const char *destdir);
72
b75a7d8f
A
73#ifdef CAN_GENERATE_OBJECTS
74static void
75writeObjectCode(const char *filename, const char *destdir);
76#endif
77
78static void
79getOutFilename(const char *inFilename, const char *destdir, char *outFilename, char *entryName, const char *newSuffix);
80
81static void
82write8(FileStream *out, uint8_t byte);
83
374ca955
A
84static void
85write32(FileStream *out, uint32_t byte);
86
b75a7d8f
A
87#ifdef OS400
88static void
89write8str(FileStream *out, uint8_t byte);
90#endif
91/* -------------------------------------------------------------------------- */
92
374ca955
A
93enum {
94 kOptHelpH = 0,
95 kOptHelpQuestionMark,
96 kOptDestDir,
97 kOptName,
98 kOptEntryPoint,
99#ifdef CAN_GENERATE_OBJECTS
100 kOptObject,
101#endif
102 kOptFilename,
103 kOptAssembly
104};
105
106/*
107Creating Template Files for New Platforms
108
109Let the cc compiler help you get started.
110Compile this program
111 const unsigned int x[5] = {1, 2, 0xdeadbeef, 0xffffffff, 16};
112with the -S option to produce assembly output.
113
114For example, this will generate array.s:
115gcc -S array.c
116
117This will produce a .s file that may look like this:
118
119 .file "array.c"
120 .version "01.01"
121gcc2_compiled.:
122 .globl x
123 .section .rodata
124 .align 4
125 .type x,@object
126 .size x,20
127x:
128 .long 1
129 .long 2
130 .long -559038737
131 .long -1
132 .long 16
133 .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-85)"
134
135which gives a starting point that will compile, and can be transformed
136to become the template, generally with some consulting of as docs and
137some experimentation.
138
139If you want ICU to automatically use this assembly, you should
140specify "GENCCODE_ASSEMBLY=-a name" in the specific config/mh-* file,
141where the name is the compiler or platform that you used in this
142assemblyHeader data structure.
143*/
144static const struct AssemblyType {
145 const char *name;
146 const char *header;
147 const char *beginLine;
148} assemblyHeader[] = {
149 {"gcc",
150 ".globl %s\n"
151 "\t.section .rodata\n"
152 "\t.align 8\n" /* Either align 8 bytes or 2^8 (256) bytes. 8 bytes is needed. */
153 "%s:\n\n",
154
155 ".long "
156 },
157 {"gcc-darwin",
158 /*"\t.section __TEXT,__text,regular,pure_instructions\n"
159 "\t.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n"*/
160 ".globl _%s\n"
161 "\t.data\n"
162 "\t.const\n"
163 "\t.align 4\n" /* 1<<4 = 16 */
164 "_%s:\n\n",
165
166 ".long "
167 },
168 {"gcc-cygwin",
169 ".globl _%s\n"
170 "\t.section .rodata\n"
171 "\t.align 8\n" /* Either align 8 bytes or 2^8 (256) bytes. 8 bytes is needed. */
172 "_%s:\n\n",
173
174 ".long "
175 },
176 {"sun",
177 "\t.section \".rodata\"\n"
178 "\t.align 8\n"
179 ".globl %s\n"
180 "%s:\n",
181
182 ".word "
183 },
184 {"xlc",
185 ".globl %s{RO}\n"
186 "\t.toc\n"
187 "%s:\n"
188 "\t.csect %s{RO}, 4\n",
189
190 ".long "
191 },
192 {"aCC",
193 "\t.SPACE $TEXT$\n"
194 "\t.SUBSPA $LIT$\n"
195 "%s\n"
196 "\t.EXPORT %s\n"
197 "\t.ALIGN 16\n",
198
199 ".WORD "
200 }
201};
202
203static int32_t assemblyHeaderIndex = -1;
204
b75a7d8f
A
205static UOption options[]={
206/*0*/UOPTION_HELP_H,
207 UOPTION_HELP_QUESTION_MARK,
208 UOPTION_DESTDIR,
209 UOPTION_DEF("name", 'n', UOPT_REQUIRES_ARG),
374ca955 210 UOPTION_DEF("entrypoint", 'e', UOPT_REQUIRES_ARG),
b75a7d8f 211#ifdef CAN_GENERATE_OBJECTS
374ca955 212/*5*/UOPTION_DEF("object", 'o', UOPT_NO_ARG),
b75a7d8f 213#endif
374ca955
A
214 UOPTION_DEF("filename", 'f', UOPT_REQUIRES_ARG),
215 UOPTION_DEF("assembly", 'a', UOPT_REQUIRES_ARG)
b75a7d8f
A
216};
217
b75a7d8f
A
218extern int
219main(int argc, char* argv[]) {
220 UBool verbose = TRUE;
374ca955 221 int32_t idx;
b75a7d8f
A
222
223 U_MAIN_INIT_ARGS(argc, argv);
224
374ca955 225 options[kOptDestDir].value = ".";
b75a7d8f
A
226
227 /* read command line options */
228 argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);
229
b75a7d8f
A
230 /* error handling, printing usage message */
231 if(argc<0) {
232 fprintf(stderr,
233 "error in command line argument \"%s\"\n",
234 argv[-argc]);
235 }
374ca955 236 if(argc<0 || options[kOptHelpH].doesOccur || options[kOptHelpQuestionMark].doesOccur) {
b75a7d8f
A
237 fprintf(stderr,
238 "usage: %s [-options] filename1 filename2 ...\n"
239 "\tread each binary input file and \n"
240 "\tcreate a .c file with a byte array that contains the input file's data\n"
241 "options:\n"
242 "\t-h or -? or --help this usage text\n"
243 "\t-d or --destdir destination directory, followed by the path\n"
244 "\t-n or --name symbol prefix, followed by the prefix\n"
245 "\t-e or --entrypoint entry point name, followed by the name\n"
246 "\t-r or --revision Specify a version\n"
247#ifdef CAN_GENERATE_OBJECTS
248 "\t-o or --object write a .obj file instead of .c\n"
249#endif
374ca955 250 "\t-f or --filename Specify an alternate base filename. (default: symbolname_typ)\n"
b75a7d8f 251 , argv[0]);
374ca955
A
252 fprintf(stderr,
253 "\t-a or --assembly Create assembly file. (possible values are: ");
254
255 fprintf(stderr, "%s", assemblyHeader[0].name);
256 for (idx = 1; idx < (int32_t)(sizeof(assemblyHeader)/sizeof(assemblyHeader[0])); idx++) {
257 fprintf(stderr, ", %s", assemblyHeader[idx].name);
258 }
259 fprintf(stderr,
260 ")\n");
b75a7d8f
A
261 } else {
262 const char *message, *filename;
263 void (*writeCode)(const char *, const char *);
374ca955
A
264
265 if(options[kOptAssembly].doesOccur) {
266 message="generating assembly code for %s\n";
267 writeCode=&writeAssemblyCode;
268 for (idx = 0; idx < (int32_t)(sizeof(assemblyHeader)/sizeof(assemblyHeader[0])); idx++) {
269 if (uprv_strcmp(options[kOptAssembly].value, assemblyHeader[idx].name) == 0) {
270 assemblyHeaderIndex = idx;
271 break;
272 }
273 }
274 if (assemblyHeaderIndex < 0) {
275 fprintf(stderr,
276 "Assembly type \"%s\" is unknown.\n", options[kOptAssembly].value);
277 return -1;
278 }
279 }
b75a7d8f 280#ifdef CAN_GENERATE_OBJECTS
374ca955 281 else if(options[kOptObject].doesOccur) {
b75a7d8f
A
282 message="generating object code for %s\n";
283 writeCode=&writeObjectCode;
374ca955 284 }
b75a7d8f 285#endif
374ca955 286 else
b75a7d8f
A
287 {
288 message="generating C code for %s\n";
289 writeCode=&writeCCode;
290 }
291 while(--argc) {
292 filename=getLongPathname(argv[argc]);
293 if (verbose) {
294 fprintf(stdout, message, filename);
295 }
296 column=MAX_COLUMN;
374ca955 297 writeCode(filename, options[kOptDestDir].value);
b75a7d8f
A
298 }
299 }
300
301 return 0;
302}
303
374ca955
A
304static void
305writeAssemblyCode(const char *filename, const char *destdir) {
306 char entry[64];
307 uint32_t buffer[1024];
308 char *bufferStr = (char *)buffer;
309 FileStream *in, *out;
310 size_t i, length;
311
312 in=T_FileStream_open(filename, "rb");
313 if(in==NULL) {
314 fprintf(stderr, "genccode: unable to open input file %s\n", filename);
315 exit(U_FILE_ACCESS_ERROR);
316 }
317
318 getOutFilename(filename, destdir, bufferStr, entry, ".s");
319 out=T_FileStream_open(bufferStr, "w");
320 if(out==NULL) {
321 fprintf(stderr, "genccode: unable to open output file %s\n", bufferStr);
322 exit(U_FILE_ACCESS_ERROR);
323 }
324
325 if(options[kOptEntryPoint].doesOccur) {
326 uprv_strcpy(entry, options[kOptEntryPoint].value);
327 uprv_strcat(entry, "_dat");
328 }
329
330 /* turn dashes or dots in the entry name into underscores */
331 length=uprv_strlen(entry);
332 for(i=0; i<length; ++i) {
333 if(entry[i]=='-' || entry[i]=='.') {
334 entry[i]='_';
335 }
336 }
337
338 sprintf(bufferStr, assemblyHeader[assemblyHeaderIndex].header,
339 entry, entry, entry, entry,
340 entry, entry, entry, entry);
341 T_FileStream_writeLine(out, bufferStr);
342 T_FileStream_writeLine(out, assemblyHeader[assemblyHeaderIndex].beginLine);
343
344 for(;;) {
345 length=T_FileStream_read(in, buffer, sizeof(buffer));
346 if(length==0) {
347 break;
348 }
349 if (length != sizeof(buffer)) {
350 /* pad with extra 0's when at the end of the file */
351 for(i=0; i < (length % sizeof(uint32_t)); ++i) {
352 buffer[length+i] = 0;
353 }
354 }
355 for(i=0; i<(length/sizeof(buffer[0])); i++) {
356 write32(out, buffer[i]);
357 }
358 }
359
360 T_FileStream_writeLine(out, "\n");
361
362 if(T_FileStream_error(in)) {
363 fprintf(stderr, "genccode: file read error while generating from file %s\n", filename);
364 exit(U_FILE_ACCESS_ERROR);
365 }
366
367 if(T_FileStream_error(out)) {
368 fprintf(stderr, "genccode: file write error while generating from file %s\n", filename);
369 exit(U_FILE_ACCESS_ERROR);
370 }
371
372 T_FileStream_close(out);
373 T_FileStream_close(in);
374}
375
b75a7d8f
A
376static void
377writeCCode(const char *filename, const char *destdir) {
374ca955 378 char buffer[4096], entry[64];
b75a7d8f
A
379 FileStream *in, *out;
380 size_t i, length;
381
382 in=T_FileStream_open(filename, "rb");
383 if(in==NULL) {
384 fprintf(stderr, "genccode: unable to open input file %s\n", filename);
385 exit(U_FILE_ACCESS_ERROR);
386 }
387
374ca955
A
388 if(options[kOptName].doesOccur) { /* prepend 'icudt28_' */
389 strcpy(entry, options[kOptName].value);
390 strcat(entry, "_");
391 } else {
392 entry[0] = 0;
393 }
394
395 getOutFilename(filename, destdir, buffer, entry+uprv_strlen(entry), ".c");
b75a7d8f
A
396 out=T_FileStream_open(buffer, "w");
397 if(out==NULL) {
398 fprintf(stderr, "genccode: unable to open output file %s\n", buffer);
399 exit(U_FILE_ACCESS_ERROR);
400 }
401
402 /* turn dashes or dots in the entry name into underscores */
403 length=uprv_strlen(entry);
404 for(i=0; i<length; ++i) {
405 if(entry[i]=='-' || entry[i]=='.') {
406 entry[i]='_';
407 }
408 }
374ca955 409
b75a7d8f
A
410#ifdef OS400
411 /*
412 TODO: Fix this once the compiler implements this feature. Keep in sync with udatamem.c
413
414 This is here because this platform can't currently put
415 const data into the read-only pages of an object or
416 shared library (service program). Only strings are allowed in read-only
417 pages, so we use char * strings to store the data.
418
419 In order to prevent the beginning of the data from ever matching the
420 magic numbers we must still use the initial double.
421 [grhoten 4/24/2003]
422 */
423 sprintf(buffer,
424 "#define U_DISABLE_RENAMING 1\n"
425 "#include \"unicode/umachine.h\"\n"
426 "U_CDECL_BEGIN\n"
427 "const struct {\n"
428 " double bogus;\n"
429 " const char *bytes; \n"
374ca955
A
430 "} %s={ 0.0, \n",
431 entry);
b75a7d8f
A
432 T_FileStream_writeLine(out, buffer);
433
434 for(;;) {
435 length=T_FileStream_read(in, buffer, sizeof(buffer));
436 if(length==0) {
437 break;
438 }
439 for(i=0; i<length; ++i) {
440 write8str(out, (uint8_t)buffer[i]);
441 }
442 }
443
444 T_FileStream_writeLine(out, "\"\n};\nU_CDECL_END\n");
445#else
446 /* Function renaming shouldn't be done in data */
447 sprintf(buffer,
448 "#define U_DISABLE_RENAMING 1\n"
449 "#include \"unicode/umachine.h\"\n"
450 "U_CDECL_BEGIN\n"
451 "const struct {\n"
452 " double bogus;\n"
453 " uint8_t bytes[%ld]; \n"
374ca955
A
454 "} %s={ 0.0, {\n",
455 (long)T_FileStream_size(in), entry);
b75a7d8f
A
456 T_FileStream_writeLine(out, buffer);
457
458 for(;;) {
459 length=T_FileStream_read(in, buffer, sizeof(buffer));
460 if(length==0) {
461 break;
462 }
463 for(i=0; i<length; ++i) {
464 write8(out, (uint8_t)buffer[i]);
465 }
466 }
467
468 T_FileStream_writeLine(out, "\n}\n};\nU_CDECL_END\n");
469#endif
470
471 if(T_FileStream_error(in)) {
472 fprintf(stderr, "genccode: file read error while generating from file %s\n", filename);
473 exit(U_FILE_ACCESS_ERROR);
474 }
475
476 if(T_FileStream_error(out)) {
477 fprintf(stderr, "genccode: file write error while generating from file %s\n", filename);
478 exit(U_FILE_ACCESS_ERROR);
479 }
480
481 T_FileStream_close(out);
482 T_FileStream_close(in);
483}
484
485#ifdef CAN_GENERATE_OBJECTS
486static void
487writeObjectCode(const char *filename, const char *destdir) {
488#ifdef WIN32
489 char buffer[4096], entry[40];
490 struct {
491 IMAGE_FILE_HEADER fileHeader;
492 IMAGE_SECTION_HEADER sections[2];
493 char linkerOptions[100];
494 } objHeader;
495 IMAGE_SYMBOL symbols[1];
496 struct {
497 DWORD sizeofLongNames;
498 char longNames[100];
499 } symbolNames;
500 FileStream *in, *out;
374ca955 501 DWORD i, entryLength, length, size;
b75a7d8f
A
502
503 in=T_FileStream_open(filename, "rb");
504 if(in==NULL) {
505 fprintf(stderr, "genccode: unable to open input file %s\n", filename);
506 exit(U_FILE_ACCESS_ERROR);
507 }
508
509 /* entry have a leading '_' */
510 entry[0]='_';
511 getOutFilename(filename, destdir, buffer, entry+ICU_ENTRY_OFFSET, ".obj");
512
374ca955
A
513 if(options[kOptEntryPoint].doesOccur) {
514 uprv_strcpy(entry+ICU_ENTRY_OFFSET, options[kOptEntryPoint].value);
b75a7d8f
A
515 uprv_strcat(entry, "_dat");
516 }
517 /* turn dashes in the entry name into underscores */
374ca955 518 entryLength=(int32_t)uprv_strlen(entry);
b75a7d8f
A
519 for(i=0; i<entryLength; ++i) {
520 if(entry[i]=='-') {
521 entry[i]='_';
522 }
523 }
524
525 /* open the output file */
526 out=T_FileStream_open(buffer, "wb");
527 if(out==NULL) {
528 fprintf(stderr, "genccode: unable to open output file %s\n", buffer);
529 exit(U_FILE_ACCESS_ERROR);
530 }
531
532 /* populate the .obj headers */
533 uprv_memset(&objHeader, 0, sizeof(objHeader));
534 uprv_memset(&symbols, 0, sizeof(symbols));
535 uprv_memset(&symbolNames, 0, sizeof(symbolNames));
536 size=T_FileStream_size(in);
537
538 /* write the linker export directive */
539 uprv_strcpy(objHeader.linkerOptions, "-export:");
540 length=8;
541 uprv_strcpy(objHeader.linkerOptions+length, entry);
542 length+=entryLength;
543 uprv_strcpy(objHeader.linkerOptions+length, ",data ");
544 length+=6;
545
546 /* set the file header */
547 objHeader.fileHeader.Machine=ICU_OBJECT_MACHINE_TYPE;
548 objHeader.fileHeader.NumberOfSections=2;
549 objHeader.fileHeader.TimeDateStamp=time(NULL);
550 objHeader.fileHeader.PointerToSymbolTable=IMAGE_SIZEOF_FILE_HEADER+2*IMAGE_SIZEOF_SECTION_HEADER+length+size; /* start of symbol table */
551 objHeader.fileHeader.NumberOfSymbols=1;
552
553 /* set the section for the linker options */
554 uprv_strncpy((char *)objHeader.sections[0].Name, ".drectve", 8);
555 objHeader.sections[0].SizeOfRawData=length;
556 objHeader.sections[0].PointerToRawData=IMAGE_SIZEOF_FILE_HEADER+2*IMAGE_SIZEOF_SECTION_HEADER;
557 objHeader.sections[0].Characteristics=IMAGE_SCN_LNK_INFO|IMAGE_SCN_LNK_REMOVE|IMAGE_SCN_ALIGN_1BYTES;
558
559 /* set the data section */
560 uprv_strncpy((char *)objHeader.sections[1].Name, ".rdata", 6);
561 objHeader.sections[1].SizeOfRawData=size;
562 objHeader.sections[1].PointerToRawData=IMAGE_SIZEOF_FILE_HEADER+2*IMAGE_SIZEOF_SECTION_HEADER+length;
563 objHeader.sections[1].Characteristics=IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_ALIGN_16BYTES|IMAGE_SCN_MEM_READ;
564
565 /* set the symbol table */
566 if(entryLength<=8) {
567 uprv_strncpy((char *)symbols[0].N.ShortName, entry, entryLength);
568 symbolNames.sizeofLongNames=4;
569 } else {
570 symbols[0].N.Name.Short=0;
571 symbols[0].N.Name.Long=4;
572 symbolNames.sizeofLongNames=4+entryLength+1;
573 uprv_strcpy(symbolNames.longNames, entry);
574 }
575 symbols[0].SectionNumber=2;
576 symbols[0].StorageClass=IMAGE_SYM_CLASS_EXTERNAL;
577
578 /* write the file header and the linker options section */
579 T_FileStream_write(out, &objHeader, objHeader.sections[1].PointerToRawData);
580
581 /* copy the data file into section 2 */
582 for(;;) {
583 length=T_FileStream_read(in, buffer, sizeof(buffer));
584 if(length==0) {
585 break;
586 }
374ca955 587 T_FileStream_write(out, buffer, (int32_t)length);
b75a7d8f
A
588 }
589
590 /* write the symbol table */
591 T_FileStream_write(out, symbols, IMAGE_SIZEOF_SYMBOL);
592 T_FileStream_write(out, &symbolNames, symbolNames.sizeofLongNames);
593
594 if(T_FileStream_error(in)) {
595 fprintf(stderr, "genccode: file read error while generating from file %s\n", filename);
596 exit(U_FILE_ACCESS_ERROR);
597 }
598
599 if(T_FileStream_error(out)) {
600 fprintf(stderr, "genccode: file write error while generating from file %s\n", filename);
601 exit(U_FILE_ACCESS_ERROR);
602 }
603
604 T_FileStream_close(out);
605 T_FileStream_close(in);
606#endif
607}
608#endif
609
610static void
611getOutFilename(const char *inFilename, const char *destdir, char *outFilename, char *entryName, const char *newSuffix) {
612 const char *basename=findBasename(inFilename), *suffix=uprv_strrchr(basename, '.');
613
614 /* copy path */
615 if(destdir!=NULL && *destdir!=0) {
616 do {
617 *outFilename++=*destdir++;
618 } while(*destdir!=0);
619 if(*(outFilename-1)!=U_FILE_SEP_CHAR) {
620 *outFilename++=U_FILE_SEP_CHAR;
621 }
622 inFilename=basename;
623 } else {
624 while(inFilename<basename) {
625 *outFilename++=*inFilename++;
626 }
627 }
628
629 if(suffix==NULL) {
630 /* the filename does not have a suffix */
631 uprv_strcpy(entryName, inFilename);
374ca955
A
632 if(options[kOptFilename].doesOccur) {
633 uprv_strcpy(outFilename, options[kOptFilename].value);
634 } else {
635 uprv_strcpy(outFilename, inFilename);
636 }
b75a7d8f
A
637 uprv_strcat(outFilename, newSuffix);
638 } else {
374ca955 639 char *saveOutFilename = outFilename;
b75a7d8f
A
640 /* copy basename */
641 while(inFilename<suffix) {
642 if(*inFilename=='-') {
643 /* iSeries cannot have '-' in the .o objects. */
644 *outFilename++=*entryName++='_';
645 inFilename++;
646 }
647 else {
648 *outFilename++=*entryName++=*inFilename++;
649 }
650 }
651
652 /* replace '.' by '_' */
653 *outFilename++=*entryName++='_';
654 ++inFilename;
655
656 /* copy suffix */
657 while(*inFilename!=0) {
658 *outFilename++=*entryName++=*inFilename++;
659 }
660
661 *entryName=0;
662
374ca955
A
663 if(options[kOptFilename].doesOccur) {
664 uprv_strcpy(saveOutFilename, options[kOptFilename].value);
665 uprv_strcat(saveOutFilename, newSuffix);
666 } else {
667 /* add ".c" */
668 uprv_strcpy(outFilename, newSuffix);
669 }
b75a7d8f
A
670 }
671}
672
374ca955
A
673static void
674write32(FileStream *out, uint32_t bitField) {
675 int32_t i;
676 char bitFieldStr[64]; /* This is more bits than needed for a 32-bit number */
677 char *s = bitFieldStr;
678 uint8_t *ptrIdx = (uint8_t *)&bitField;
679 static const char hexToStr[16] = {
680 '0','1','2','3',
681 '4','5','6','7',
682 '8','9','A','B',
683 'C','D','E','F'
684 };
685
686 /* write the value, possibly with comma and newline */
687 if(column==MAX_COLUMN) {
688 /* first byte */
689 column=1;
690 } else if(column<32) {
691 *(s++)=',';
692 ++column;
693 } else {
694 *(s++)='\n';
695 uprv_strcpy(s, assemblyHeader[assemblyHeaderIndex].beginLine);
696 s+=uprv_strlen(s);
697 column=1;
698 }
699
700 if (bitField < 10) {
701 /* It's a small number. Don't waste the space for 0x */
702 *(s++)=hexToStr[bitField];
703 }
704 else {
705 int seenNonZero = 0; /* This is used to remove leading zeros */
706
707 *(s++)='0';
708 *(s++)='x';
709
710 /* This creates a 32-bit field */
711#if U_IS_BIG_ENDIAN
712 for (i = 0; i < sizeof(uint32_t); i++)
713#else
714 for (i = sizeof(uint32_t)-1; i >= 0 ; i--)
715#endif
716 {
717 uint8_t value = ptrIdx[i];
718 if (value || seenNonZero) {
719 *(s++)=hexToStr[value>>4];
720 *(s++)=hexToStr[value&0xF];
721 seenNonZero = 1;
722 }
723 }
724 }
725
726 *(s++)=0;
727 T_FileStream_writeLine(out, bitFieldStr);
728}
729
b75a7d8f
A
730static void
731write8(FileStream *out, uint8_t byte) {
732 char s[4];
733 int i=0;
734
735 /* convert the byte value to a string */
736 if(byte>=100) {
737 s[i++]=(char)('0'+byte/100);
738 byte%=100;
739 }
740 if(i>0 || byte>=10) {
741 s[i++]=(char)('0'+byte/10);
742 byte%=10;
743 }
744 s[i++]=(char)('0'+byte);
745 s[i]=0;
746
747 /* write the value, possibly with comma and newline */
748 if(column==MAX_COLUMN) {
749 /* first byte */
750 column=1;
751 } else if(column<16) {
752 T_FileStream_writeLine(out, ",");
753 ++column;
754 } else {
755 T_FileStream_writeLine(out, ",\n");
756 column=1;
757 }
758 T_FileStream_writeLine(out, s);
759}
760
761#ifdef OS400
762static void
763write8str(FileStream *out, uint8_t byte) {
764 char s[8];
765
374ca955
A
766 if (byte > 7)
767 sprintf(s, "\\x%X", byte);
768 else
769 sprintf(s, "\\%X", byte);
b75a7d8f
A
770
771 /* write the value, possibly with comma and newline */
772 if(column==MAX_COLUMN) {
773 /* first byte */
774 column=1;
775 T_FileStream_writeLine(out, "\"");
374ca955 776 } else if(column<24) {
b75a7d8f
A
777 ++column;
778 } else {
779 T_FileStream_writeLine(out, "\"\n\"");
780 column=1;
781 }
782 T_FileStream_writeLine(out, s);
783}
784#endif
785