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