]> git.saurik.com Git - apple/icu.git/blob - icuSources/tools/genccode/genccode.c
ICU-6.2.15.tar.gz
[apple/icu.git] / icuSources / tools / genccode / genccode.c
1 /*
2 *******************************************************************************
3 *
4 * Copyright (C) 1999-2004, International Business Machines
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
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 */
33 #if defined(_M_IA64)
34 # define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_IA64
35 # define ICU_ENTRY_OFFSET 0
36 #elif defined(_M_AMD64)
37 # define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64
38 # define ICU_ENTRY_OFFSET 0
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"
54 #include "unicode/uclean.h"
55 #include "uoptions.h"
56
57 #define MAX_COLUMN ((uint32_t)(0xFFFFFFFFU))
58
59 static uint32_t column=MAX_COLUMN;
60
61 #ifdef WIN32
62 #define CAN_GENERATE_OBJECTS
63 #endif
64
65 /* prototypes --------------------------------------------------------------- */
66
67 static void
68 writeCCode(const char *filename, const char *destdir);
69
70 static void
71 writeAssemblyCode(const char *filename, const char *destdir);
72
73 #ifdef CAN_GENERATE_OBJECTS
74 static void
75 writeObjectCode(const char *filename, const char *destdir);
76 #endif
77
78 static void
79 getOutFilename(const char *inFilename, const char *destdir, char *outFilename, char *entryName, const char *newSuffix);
80
81 static void
82 write8(FileStream *out, uint8_t byte);
83
84 static void
85 write32(FileStream *out, uint32_t byte);
86
87 #ifdef OS400
88 static void
89 write8str(FileStream *out, uint8_t byte);
90 #endif
91 /* -------------------------------------------------------------------------- */
92
93 enum {
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 /*
107 Creating Template Files for New Platforms
108
109 Let the cc compiler help you get started.
110 Compile this program
111 const unsigned int x[5] = {1, 2, 0xdeadbeef, 0xffffffff, 16};
112 with the -S option to produce assembly output.
113
114 For example, this will generate array.s:
115 gcc -S array.c
116
117 This will produce a .s file that may look like this:
118
119 .file "array.c"
120 .version "01.01"
121 gcc2_compiled.:
122 .globl x
123 .section .rodata
124 .align 4
125 .type x,@object
126 .size x,20
127 x:
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
135 which gives a starting point that will compile, and can be transformed
136 to become the template, generally with some consulting of as docs and
137 some experimentation.
138
139 If you want ICU to automatically use this assembly, you should
140 specify "GENCCODE_ASSEMBLY=-a name" in the specific config/mh-* file,
141 where the name is the compiler or platform that you used in this
142 assemblyHeader data structure.
143 */
144 static 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
203 static int32_t assemblyHeaderIndex = -1;
204
205 static UOption options[]={
206 /*0*/UOPTION_HELP_H,
207 UOPTION_HELP_QUESTION_MARK,
208 UOPTION_DESTDIR,
209 UOPTION_DEF("name", 'n', UOPT_REQUIRES_ARG),
210 UOPTION_DEF("entrypoint", 'e', UOPT_REQUIRES_ARG),
211 #ifdef CAN_GENERATE_OBJECTS
212 /*5*/UOPTION_DEF("object", 'o', UOPT_NO_ARG),
213 #endif
214 UOPTION_DEF("filename", 'f', UOPT_REQUIRES_ARG),
215 UOPTION_DEF("assembly", 'a', UOPT_REQUIRES_ARG)
216 };
217
218 extern int
219 main(int argc, char* argv[]) {
220 UBool verbose = TRUE;
221 int32_t idx;
222
223 U_MAIN_INIT_ARGS(argc, argv);
224
225 options[kOptDestDir].value = ".";
226
227 /* read command line options */
228 argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);
229
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 }
236 if(argc<0 || options[kOptHelpH].doesOccur || options[kOptHelpQuestionMark].doesOccur) {
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
250 "\t-f or --filename Specify an alternate base filename. (default: symbolname_typ)\n"
251 , argv[0]);
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");
261 } else {
262 const char *message, *filename;
263 void (*writeCode)(const char *, const char *);
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 }
280 #ifdef CAN_GENERATE_OBJECTS
281 else if(options[kOptObject].doesOccur) {
282 message="generating object code for %s\n";
283 writeCode=&writeObjectCode;
284 }
285 #endif
286 else
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;
297 writeCode(filename, options[kOptDestDir].value);
298 }
299 }
300
301 return 0;
302 }
303
304 static void
305 writeAssemblyCode(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
376 static void
377 writeCCode(const char *filename, const char *destdir) {
378 char buffer[4096], entry[64];
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
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");
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 }
409
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"
430 "} %s={ 0.0, \n",
431 entry);
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"
454 "} %s={ 0.0, {\n",
455 (long)T_FileStream_size(in), entry);
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
486 static void
487 writeObjectCode(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;
501 DWORD i, entryLength, length, size;
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
513 if(options[kOptEntryPoint].doesOccur) {
514 uprv_strcpy(entry+ICU_ENTRY_OFFSET, options[kOptEntryPoint].value);
515 uprv_strcat(entry, "_dat");
516 }
517 /* turn dashes in the entry name into underscores */
518 entryLength=(int32_t)uprv_strlen(entry);
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 }
587 T_FileStream_write(out, buffer, (int32_t)length);
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
610 static void
611 getOutFilename(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);
632 if(options[kOptFilename].doesOccur) {
633 uprv_strcpy(outFilename, options[kOptFilename].value);
634 } else {
635 uprv_strcpy(outFilename, inFilename);
636 }
637 uprv_strcat(outFilename, newSuffix);
638 } else {
639 char *saveOutFilename = outFilename;
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
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 }
670 }
671 }
672
673 static void
674 write32(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
730 static void
731 write8(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
762 static void
763 write8str(FileStream *out, uint8_t byte) {
764 char s[8];
765
766 if (byte > 7)
767 sprintf(s, "\\x%X", byte);
768 else
769 sprintf(s, "\\%X", byte);
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, "\"");
776 } else if(column<24) {
777 ++column;
778 } else {
779 T_FileStream_writeLine(out, "\"\n\"");
780 column=1;
781 }
782 T_FileStream_writeLine(out, s);
783 }
784 #endif
785