2 *******************************************************************************
4 * Copyright (C) 2002-2008, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
11 * Modification History:
13 * Date Name Description
14 * 10/01/02 Ram Creation.
15 * 02/07/08 Spieth Correct XLIFF generation on EBCDIC platform
17 *******************************************************************************
21 #include "unicode/ures.h"
25 #include "unicode/ucnv.h"
31 #include "unicode/ustring.h"
32 #include "unicode/uchar.h"
35 #include "unicode/unistr.h"
40 static int tabCount
= 0;
42 static FileStream
* out
=NULL
;
43 static struct SRBRoot
* srBundle
;
44 static const char* outDir
= NULL
;
45 static const char* enc
="";
46 static UConverter
* conv
= NULL
;
48 const char* const* ISOLanguages
;
49 const char* const* ISOCountries
;
50 const char* textExt
= ".txt";
51 const char* xliffExt
= ".xlf";
53 static void write_utf8_file(UnicodeString outString
, FileStream
* outFile
, UErrorCode
*status
){
54 char* dest
= (char*)uprv_malloc((outString
.length() * 3 /2));
56 u_strToUTF8(dest
,outString
.length() * 3 /2,&len
,outString
.getBuffer(),outString
.length(),status
);
58 T_FileStream_write(outFile
, dest
, len
);
63 /*write indentation for formatting*/
64 static void write_tabs(UnicodeString
*Accumulator
){
66 for(;i
<=tabCount
;i
++){
67 Accumulator
->append(UnicodeString(" "));
68 //FileStream_write(os," ",4);
72 /*get ID for each element. ID is globally unique.*/
73 static char* getID(const char* id
, char* curKey
, char* result
) {
75 result
= (char *)uprv_malloc(sizeof(char)*uprv_strlen(id
) + 1);
76 uprv_memset(result
, 0, sizeof(char)*uprv_strlen(id
) + 1);
77 uprv_strcpy(result
, id
);
79 result
= (char *)uprv_malloc(sizeof(char)*(uprv_strlen(id
) + 1 + uprv_strlen(curKey
)) + 1);
80 uprv_memset(result
, 0, sizeof(char)*(uprv_strlen(id
) + 1 + uprv_strlen(curKey
)) + 1);
82 uprv_strcpy(result
, id
);
83 uprv_strcat(result
, "_");
85 uprv_strcat(result
, curKey
);
90 /*compute CRC for binary code*/
91 /* The code is from http://www.theorem.com/java/CRC32.java
92 * Calculates the CRC32 - 32 bit Cyclical Redundancy Check
93 * <P> This check is used in numerous systems to verify the integrity
94 * of information. It's also used as a hashing function. Unlike a regular
95 * checksum, it's sensitive to the order of the characters.
96 * It produces a 32 bit
98 * @author Michael Lecuyer (mjl@theorem.com)
99 * @version 1.1 August 11, 1998
102 /* ICU is not endian portable, because ICU data generated on big endian machines can be
103 * ported to big endian machines but not to little endian machines and vice versa. The
104 * conversion is not portable across platforms with different endianess.
107 static uint32_t computeCRC(char *ptr
, uint32_t len
, uint32_t lastcrc
){
117 #define CRC32_POLYNOMIAL 0xEDB88320
120 for (i
= 0; i
<= 255; i
++) {
122 for (j
= 8; j
> 0; j
--) {
123 if ((crc2
& 1) == 1) {
124 crc2
= (crc2
>> 1) ^ CRC32_POLYNOMIAL
;
134 temp1
= (uint32_t)crc
>>8;
135 temp2
= crc_ta
[(crc
^*ptr
) & 0xFF];
142 static void strnrepchr(char* src
, int32_t srcLen
, char s
, char r
){
144 for(i
=0;i
<srcLen
;i
++){
150 /* Parse the filename, and get its language information.
151 * If it fails to get the language information from the filename,
152 * use "en" as the default value for language
154 static char* parseFilename(const char* id
, char* lang
) {
155 int idLen
= (int) uprv_strlen(id
);
156 char* localeID
= (char*) uprv_malloc(idLen
);
158 int canonCapacity
= 0;
162 UErrorCode status
= U_ZERO_ERROR
;
163 const char *ext
= uprv_strchr(id
, '.');
166 pos
= (int) (ext
- id
);
170 uprv_memcpy(localeID
, id
, pos
);
171 localeID
[pos
]=0; /* NUL terminate the string */
173 canonCapacity
=pos
*3;
174 canon
= (char*) uprv_malloc(canonCapacity
);
175 canonLen
= uloc_canonicalize(localeID
, canon
, canonCapacity
, &status
);
177 if(U_FAILURE(status
)){
178 fprintf(stderr
, "Could not canonicalize the locale ID: %s. Error: %s\n", localeID
, u_errorName(status
));
181 strnrepchr(canon
, canonLen
, '_', '-');
185 static const char* xmlHeader
= "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
187 static const char* bundleStart
= "<xliff version = \"1.2\" "
188 "xmlns='urn:oasis:names:tc:xliff:document:1.2' "
189 "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
190 "xsi:schemaLocation='urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd'>\n";
192 static const char* bundleStart
= "<xliff version = \"1.1\" "
193 "xmlns='urn:oasis:names:tc:xliff:document:1.1' "
194 "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
195 "xsi:schemaLocation='urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd'>\n";
197 static const char* bundleEnd
= "</xliff>\n";
199 void res_write_xml(UnicodeString
*Accumulator
, struct SResource
*res
, const char* id
, const char* language
, UBool isTopLevel
, UErrorCode
*status
);
201 static char* convertAndEscape(char** pDest
, int32_t destCap
, int32_t* destLength
,
202 const UChar
* src
, int32_t srcLen
, UErrorCode
* status
){
209 if(status
==NULL
|| U_FAILURE(*status
) || pDest
==NULL
|| srcLen
==0 || src
== NULL
){
213 if(dest
==NULL
|| destCap
<=0){
214 destCap
= srcLen
* 8;
215 dest
= (char*) uprv_malloc(sizeof(char) * destCap
);
217 *status
=U_MEMORY_ALLOCATION_ERROR
;
224 while(srcIndex
<srcLen
){
225 U16_NEXT(src
, srcIndex
, srcLen
, c
);
227 if (U16_IS_LEAD(c
) || U16_IS_TRAIL(c
)) {
228 *status
= U_ILLEGAL_CHAR_FOUND
;
229 fprintf(stderr
, "Illegal Surrogate! \n");
234 if((destLen
+UTF8_CHAR_LENGTH(c
)) < destCap
){
240 uprv_strcpy(dest
+( destLen
),"\x26\x61\x6d\x70\x3b"); /* &*/
241 destLen
+=(int32_t)uprv_strlen("\x26\x61\x6d\x70\x3b");
244 uprv_strcpy(dest
+(destLen
),"\x26\x6c\x74\x3b"); /* <*/
245 destLen
+=(int32_t)uprv_strlen("\x26\x6c\x74\x3b");
248 uprv_strcpy(dest
+(destLen
),"\x26\x67\x74\x3b"); /* >*/
249 destLen
+=(int32_t)uprv_strlen("\x26\x67\x74\x3b");
252 uprv_strcpy(dest
+(destLen
),"\x26\x71\x75\x6f\x74\x3b"); /* "*/
253 destLen
+=(int32_t)uprv_strlen("\x26\x71\x75\x6f\x74\x3b");
256 uprv_strcpy(dest
+(destLen
),"\x26\x61\x70\x6f\x73\x3b"); /* ' */
257 destLen
+=(int32_t)uprv_strlen("\x26\x61\x70\x6f\x73\x3b");
260 /* Disallow C0 controls except TAB, CR, LF*/
293 *status
= U_ILLEGAL_CHAR_FOUND
;
294 fprintf(stderr
, "Illegal Character \\u%04X!\n",(int)c
);
298 dest
[destLen
++]=(char)c
;
301 UBool isError
= FALSE
;
302 U8_APPEND((unsigned char*)dest
,destLen
,destCap
,c
,isError
);
304 *status
= U_ILLEGAL_CHAR_FOUND
;
305 fprintf(stderr
, "Illegal Character \\U%08X!\n",(int)c
);
313 temp
= (char*) uprv_malloc(sizeof(char)*destCap
);
315 *status
=U_MEMORY_ALLOCATION_ERROR
;
319 uprv_memmove(temp
,dest
,destLen
);
327 *destLength
= destLen
;
331 #define ASTERISK 0x002A
335 #define AT_SIGN 0x0040
338 trim(char **src
, int32_t *len
){
342 if(src
== NULL
|| *src
== NULL
){
346 /* trim from the end */
347 for( i
=(*len
-1); i
>= 0; i
--){
365 print(UnicodeString
*Accumulator
, UChar
* src
, int32_t srcLen
,const char *tagStart
,const char *tagEnd
, UErrorCode
*status
){
366 int32_t bufCapacity
= srcLen
*4;
370 if(U_FAILURE(*status
)){
374 buf
= (char*) (uprv_malloc(bufCapacity
));
376 fprintf(stderr
, "Could not allocate memory!!");
377 exit(U_MEMORY_ALLOCATION_ERROR
);
379 buf
= convertAndEscape(&buf
, bufCapacity
, &bufLen
, src
, srcLen
,status
);
380 if(U_SUCCESS(*status
)){
382 Accumulator
->append(UnicodeString(tagStart
));
383 Accumulator
->append(UnicodeString(buf
, bufLen
, "UTF-8"));
384 Accumulator
->append(UnicodeString(tagEnd
));
385 Accumulator
->append(UnicodeString("\n"));
386 //T_FileStream_write(out,tagStart, (int32_t)uprv_strlen(tagStart));
387 //T_FileStream_write(out, buf, bufLen);
388 //T_FileStream_write(out,tagEnd, (int32_t)uprv_strlen(tagEnd));
389 //T_FileStream_write(out,"\n",1);
394 printNoteElements(UnicodeString
*Accumulator
, struct UString
*src
, UErrorCode
*status
){
396 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
398 int32_t capacity
= 0;
407 capacity
= src
->fLength
;
408 note
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
410 count
= getCount(src
->fChars
,src
->fLength
, UPC_NOTE
, status
);
411 if(U_FAILURE(*status
)){
415 for(i
=0; i
< count
; i
++){
416 noteLen
= getAt(src
->fChars
,src
->fLength
, ¬e
, capacity
, i
, UPC_NOTE
, status
);
417 if(U_FAILURE(*status
)){
422 write_tabs(Accumulator
);
423 print(Accumulator
, note
, noteLen
,"<note>", "</note>", status
);
429 fprintf(stderr
, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
431 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
435 static void printAttribute(UnicodeString
*Accumulator
, const char *name
, const char *value
, int32_t len
)
437 Accumulator
->append(UnicodeString(" "));
438 Accumulator
->append(UnicodeString(name
));
439 Accumulator
->append(UnicodeString(" = \""));
440 Accumulator
->append(UnicodeString(value
));
441 Accumulator
->append(UnicodeString("\""));
442 //T_FileStream_write(out, " ", 1);
443 //T_FileStream_write(out, name, (int32_t) uprv_strlen(name));
444 //T_FileStream_write(out, " = \"", 4);
445 //T_FileStream_write(out, value, (int32_t) len);
446 //T_FileStream_write(out, "\"", 1);
449 static void printAttribute(UnicodeString
*Accumulator
, const char *name
, const UnicodeString value
, int32_t len
)
451 Accumulator
->append(UnicodeString(" "));
452 Accumulator
->append(UnicodeString(name
));
453 Accumulator
->append(UnicodeString(" = \""));
454 Accumulator
->append(value
);
455 Accumulator
->append(UnicodeString("\""));
456 //T_FileStream_write(out, " ", 1);
457 //T_FileStream_write(out, name, (int32_t) uprv_strlen(name));
458 //T_FileStream_write(out, " = \"", 4);
459 //T_FileStream_write(out, value, (int32_t) len);
460 //T_FileStream_write(out, "\"", 1);
464 printComments(UnicodeString
*Accumulator
, struct UString
*src
, const char *resName
, UBool printTranslate
, UErrorCode
*status
){
466 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
468 if(status
==NULL
|| U_FAILURE(*status
)){
472 int32_t capacity
= src
->fLength
+ 1;
475 UChar
* desc
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
476 UChar
* trans
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
478 int32_t descLen
= 0, transLen
=0;
479 if(desc
==NULL
|| trans
==NULL
){
480 *status
= U_MEMORY_ALLOCATION_ERROR
;
485 src
->fLength
= removeCmtText(src
->fChars
, src
->fLength
, status
);
486 descLen
= getDescription(src
->fChars
,src
->fLength
, &desc
, capacity
, status
);
487 transLen
= getTranslate(src
->fChars
,src
->fLength
, &trans
, capacity
, status
);
489 /* first print translate attribute */
492 /* print translate attribute */
493 buf
= convertAndEscape(&buf
, 0, &bufLen
, trans
, transLen
, status
);
494 if(U_SUCCESS(*status
)){
495 printAttribute(Accumulator
, "translate", UnicodeString(buf
, bufLen
, "UTF-8"), bufLen
);
496 Accumulator
->append(UnicodeString(">\n"));
497 //T_FileStream_write(out,">\n", 2);
499 }else if(getShowWarning()){
500 fprintf(stderr
, "Warning: Tranlate attribute for resource %s cannot be set. XLIFF prohibits it.\n", resName
);
501 /* no translate attribute .. just close the tag */
502 Accumulator
->append(UnicodeString(">\n"));
503 //T_FileStream_write(out,">\n", 2);
506 /* no translate attribute .. just close the tag */
507 Accumulator
->append(UnicodeString(">\n"));
508 //T_FileStream_write(out,">\n", 2);
512 write_tabs(Accumulator
);
513 print(Accumulator
, desc
, descLen
, "<!--", "-->", status
);
520 fprintf(stderr
, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
522 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
527 * Print out a containing element, like:
528 * <trans-unit id = "blah" resname = "blah" restype = "x-id-alias" translate = "no">
529 * <group id "calendar_gregorian" resname = "gregorian" restype = "x-icu-array">
531 static char *printContainer(UnicodeString
*Accumulator
, struct SResource
*res
, const char *container
, const char *restype
, const char *mimetype
, const char *id
, UErrorCode
*status
)
533 char *resname
= NULL
;
536 write_tabs(Accumulator
);
538 if (res
->fKey
>= 0 && uprv_strcmp(srBundle
->fKeys
+ res
->fKey
, "") != 0) {
539 resname
= srBundle
->fKeys
+ res
->fKey
;
540 sid
= getID(id
, resname
, sid
);
542 sid
= getID(id
, NULL
, sid
);
545 Accumulator
->append(UnicodeString("<"));
546 Accumulator
->append(UnicodeString(container
));
547 //T_FileStream_write(out, "<", 1);
548 //T_FileStream_write(out, container, (int32_t) uprv_strlen(container));
549 printAttribute(Accumulator
, "id", sid
, (int32_t) uprv_strlen(sid
));
551 if (resname
!= NULL
) {
552 printAttribute(Accumulator
,"resname", resname
, (int32_t) uprv_strlen(resname
));
555 if (mimetype
!= NULL
) {
556 printAttribute(Accumulator
,"mime-type", mimetype
, (int32_t) uprv_strlen(mimetype
));
559 if (restype
!= NULL
) {
560 printAttribute(Accumulator
,"restype", restype
, (int32_t) uprv_strlen(restype
));
564 if (res
->fComment
.fLength
> 0) {
565 /* printComments will print the closing ">\n" */
566 printComments(Accumulator
, &res
->fComment
, resname
, TRUE
, status
);
568 Accumulator
->append(UnicodeString(">\n"));
569 //T_FileStream_write(out, ">\n", 2);
575 /* Writing Functions */
577 static const char *trans_unit
= "trans-unit";
578 static const char *close_trans_unit
= "</trans-unit>\n";
579 static const char *source
= "<source>";
580 static const char *close_source
= "</source>\n";
581 static const char *group
= "group";
582 static const char *close_group
= "</group>\n";
584 static const char *bin_unit
= "bin-unit";
585 static const char *close_bin_unit
= "</bin-unit>\n";
586 static const char *bin_source
= "<bin-source>\n";
587 static const char *close_bin_source
= "</bin-source>\n";
588 static const char *external_file
= "<external-file";
589 /*static const char *close_external_file = "</external-file>\n";*/
590 static const char *internal_file
= "<internal-file";
591 static const char *close_internal_file
= "</internal-file>\n";
593 static const char *application_mimetype
= "application"; /* add "/octet-stream"? */
595 static const char *alias_restype
= "x-icu-alias";
596 static const char *array_restype
= "x-icu-array";
597 static const char *binary_restype
= "x-icu-binary";
598 static const char *integer_restype
= "x-icu-integer";
599 static const char *intvector_restype
= "x-icu-intvector";
600 static const char *table_restype
= "x-icu-table";
603 string_write_xml(UnicodeString
*Accumulator
, struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
609 if(status
==NULL
|| U_FAILURE(*status
)){
613 sid
= printContainer(Accumulator
, res
, trans_unit
, NULL
, NULL
, id
, status
);
615 write_tabs(Accumulator
);
617 Accumulator
->append(UnicodeString(source
));
618 //T_FileStream_write(out, source, (int32_t) uprv_strlen(source));
620 buf
= convertAndEscape(&buf
, 0, &bufLen
, res
->u
.fString
.fChars
, res
->u
.fString
.fLength
, status
);
622 if (U_FAILURE(*status
)) {
626 Accumulator
->append(UnicodeString(buf
, bufLen
, "UTF-8"));
627 Accumulator
->append(UnicodeString(close_source
));
628 //T_FileStream_write(out, buf, bufLen);
629 //T_FileStream_write(out, close_source, (int32_t) uprv_strlen(close_source));
631 printNoteElements(Accumulator
, &res
->fComment
, status
);
634 write_tabs(Accumulator
);
636 Accumulator
->append(UnicodeString(close_trans_unit
));
637 //T_FileStream_write(out, close_trans_unit, (int32_t) uprv_strlen(close_trans_unit));
644 alias_write_xml(UnicodeString
*Accumulator
, struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
649 sid
= printContainer(Accumulator
, res
, trans_unit
, alias_restype
, NULL
, id
, status
);
651 write_tabs(Accumulator
);
653 Accumulator
->append(UnicodeString(source
));
654 //T_FileStream_write(out, source, (int32_t) uprv_strlen(source));
656 buf
= convertAndEscape(&buf
, 0, &bufLen
, res
->u
.fString
.fChars
, res
->u
.fString
.fLength
, status
);
658 if(U_FAILURE(*status
)){
661 Accumulator
->append(UnicodeString(buf
, bufLen
, "UTF-8"));
662 //T_FileStream_write(out, buf, bufLen);
663 Accumulator
->append(UnicodeString(close_source
));
664 //T_FileStream_write(out, close_source, (int32_t)uprv_strlen(close_source));
666 printNoteElements(Accumulator
, &res
->fComment
, status
);
669 write_tabs(Accumulator
);
671 Accumulator
->append(UnicodeString(close_trans_unit
));
672 //T_FileStream_write(out, close_trans_unit, (int32_t)uprv_strlen(close_trans_unit));
679 array_write_xml(UnicodeString
*Accumulator
, struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
683 struct SResource
*current
= NULL
;
684 struct SResource
*first
=NULL
;
686 sid
= printContainer(Accumulator
, res
, group
, array_restype
, NULL
, id
, status
);
688 current
= res
->u
.fArray
.fFirst
;
691 while (current
!= NULL
) {
695 itostr(c
, index
, 10, 0);
697 subId
= getID(sid
, c
, subId
);
699 res_write_xml(Accumulator
, current
, subId
, language
, FALSE
, status
);
703 if(U_FAILURE(*status
)){
707 current
= current
->fNext
;
711 write_tabs(Accumulator
);
712 Accumulator
->append(UnicodeString(close_group
));
713 //T_FileStream_write(out, close_group, (int32_t) uprv_strlen(close_group));
719 intvector_write_xml(UnicodeString
*Accumulator
, struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
724 char buf
[256] = {'0'};
726 sid
= printContainer(Accumulator
, res
, group
, intvector_restype
, NULL
, id
, status
);
728 for(i
= 0; i
< res
->u
.fIntVector
.fCount
; i
+= 1) {
732 ivd
= getID(sid
, c
, ivd
);
733 len
= itostr(buf
, res
->u
.fIntVector
.fArray
[i
], 10, 0);
735 write_tabs(Accumulator
);
736 Accumulator
->append(UnicodeString("<"));
737 //T_FileStream_write(out, "<", 1);
738 Accumulator
->append(UnicodeString(trans_unit
));
739 //T_FileStream_write(out, trans_unit, (int32_t)uprv_strlen(trans_unit));
741 printAttribute(Accumulator
, "id", ivd
, (int32_t)uprv_strlen(ivd
));
742 printAttribute(Accumulator
, "restype", integer_restype
, (int32_t) strlen(integer_restype
));
744 Accumulator
->append(UnicodeString(">\n"));
745 //T_FileStream_write(out,">\n", 2);
748 write_tabs(Accumulator
);
749 Accumulator
->append(UnicodeString(source
));
750 //T_FileStream_write(out, source, (int32_t)uprv_strlen(source));
752 Accumulator
->append(UnicodeString(buf
, len
));
753 //T_FileStream_write(out, buf, len);
755 Accumulator
->append(UnicodeString(close_source
));
756 //T_FileStream_write(out, close_source, (int32_t)uprv_strlen(close_source));
758 write_tabs(Accumulator
);
759 Accumulator
->append(UnicodeString(close_trans_unit
));
760 //T_FileStream_write(out, close_trans_unit, (int32_t)uprv_strlen(close_trans_unit));
767 write_tabs(Accumulator
);
769 Accumulator
->append(UnicodeString(close_group
));
770 //T_FileStream_write(out, close_group, (int32_t)uprv_strlen(close_group));
776 int_write_xml(UnicodeString
*Accumulator
, struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
781 sid
= printContainer(Accumulator
, res
, trans_unit
, integer_restype
, NULL
, id
, status
);
783 write_tabs(Accumulator
);
785 Accumulator
->append(UnicodeString(source
));
786 //T_FileStream_write(out, source, (int32_t) uprv_strlen(source));
788 len
= itostr(buf
, res
->u
.fIntValue
.fValue
, 10, 0);
789 Accumulator
->append(UnicodeString(buf
, len
));
790 //T_FileStream_write(out, buf, len);
792 Accumulator
->append(UnicodeString(close_source
));
793 //T_FileStream_write(out, close_source, (int32_t)uprv_strlen(close_source));
795 printNoteElements(Accumulator
, &res
->fComment
, status
);
798 write_tabs(Accumulator
);
800 Accumulator
->append(UnicodeString(close_trans_unit
));
801 //T_FileStream_write(out, close_trans_unit, (int32_t)uprv_strlen(close_trans_unit));
808 bin_write_xml(UnicodeString
*Accumulator
, struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
809 const char* m_type
= application_mimetype
;
811 uint32_t crc
= 0xFFFFFFFF;
813 char fileName
[1024] ={0};
814 int32_t tLen
= ( outDir
== NULL
) ? 0 :(int32_t)uprv_strlen(outDir
);
815 char* fn
= (char*) uprv_malloc(sizeof(char) * (tLen
+1024 +
816 (res
->u
.fBinaryValue
.fFileName
!=NULL
?
817 uprv_strlen(res
->u
.fBinaryValue
.fFileName
) :0)));
818 const char* ext
= NULL
;
824 if(res
->u
.fBinaryValue
.fFileName
!= NULL
){
825 uprv_strcpy(fileName
, res
->u
.fBinaryValue
.fFileName
);
826 f
= uprv_strrchr(fileName
, '\\');
834 ext
= uprv_strrchr(fileName
, '.');
837 fprintf(stderr
, "Error: %s is an unknown binary filename type.\n", fileName
);
838 exit(U_ILLEGAL_ARGUMENT_ERROR
);
841 if(uprv_strcmp(ext
, ".jpg")==0 || uprv_strcmp(ext
, ".jpeg")==0 || uprv_strcmp(ext
, ".gif")==0 ){
843 } else if(uprv_strcmp(ext
, ".wav")==0 || uprv_strcmp(ext
, ".au")==0 ){
845 } else if(uprv_strcmp(ext
, ".avi")==0 || uprv_strcmp(ext
, ".mpg")==0 || uprv_strcmp(ext
, ".mpeg")==0){
847 } else if(uprv_strcmp(ext
, ".txt")==0 || uprv_strcmp(ext
, ".text")==0){
851 sid
= printContainer(Accumulator
, res
, bin_unit
, binary_restype
, m_type
, id
, status
);
853 write_tabs(Accumulator
);
855 Accumulator
->append(UnicodeString(bin_source
));
856 //T_FileStream_write(out, bin_source, (int32_t)uprv_strlen(bin_source));
859 write_tabs(Accumulator
);
861 Accumulator
->append(UnicodeString(external_file
));
862 //T_FileStream_write(out, external_file, (int32_t)uprv_strlen(external_file));
863 printAttribute(Accumulator
, "href", f
, (int32_t)uprv_strlen(f
));
864 Accumulator
->append(UnicodeString("/>\n"));
865 //T_FileStream_write(out, "/>\n", 3);
867 write_tabs(Accumulator
);
869 Accumulator
->append(UnicodeString(close_bin_source
));
870 //T_FileStream_write(out, close_bin_source, (int32_t)uprv_strlen(close_bin_source));
872 printNoteElements(Accumulator
, &res
->fComment
, status
);
874 write_tabs(Accumulator
);
875 Accumulator
->append(UnicodeString(close_bin_unit
));
876 //T_FileStream_write(out, close_bin_unit, (int32_t)uprv_strlen(close_bin_unit));
878 char temp
[256] = {0};
882 sid
= printContainer(Accumulator
, res
, bin_unit
, binary_restype
, m_type
, id
, status
);
884 write_tabs(Accumulator
);
885 Accumulator
->append(UnicodeString(bin_source
));
886 //T_FileStream_write(out, bin_source, (int32_t)uprv_strlen(bin_source));
889 write_tabs(Accumulator
);
891 Accumulator
->append(UnicodeString(internal_file
));
892 //T_FileStream_write(out, internal_file, (int32_t)uprv_strlen(internal_file));
893 printAttribute(Accumulator
, "form", application_mimetype
, (int32_t) uprv_strlen(application_mimetype
));
895 while(i
<res
->u
.fBinaryValue
.fLength
){
896 len
= itostr(temp
, res
->u
.fBinaryValue
.fData
[i
], 16, 2);
897 crc
= computeCRC(temp
, len
, crc
);
901 len
= itostr(temp
, crc
, 10, 0);
902 printAttribute(Accumulator
, "crc", temp
, len
);
904 Accumulator
->append(UnicodeString(">"));
905 //T_FileStream_write(out, ">", 1);
908 while(i
<res
->u
.fBinaryValue
.fLength
){
909 len
= itostr(temp
, res
->u
.fBinaryValue
.fData
[i
], 16, 2);
910 Accumulator
->append(UnicodeString(temp
));
911 //T_FileStream_write(out ,temp ,len);
915 Accumulator
->append(UnicodeString(close_internal_file
));
916 //T_FileStream_write(out, close_internal_file, (int32_t)uprv_strlen(close_internal_file));
919 write_tabs(Accumulator
);
921 Accumulator
->append(UnicodeString(close_bin_source
));
922 //T_FileStream_write(out, close_bin_source, (int32_t)uprv_strlen(close_bin_source));
923 printNoteElements(Accumulator
, &res
->fComment
, status
);
926 write_tabs(Accumulator
);
927 Accumulator
->append(UnicodeString(close_bin_unit
));
928 //T_FileStream_write(out, close_bin_unit, (int32_t)uprv_strlen(close_bin_unit));
940 table_write_xml(UnicodeString
*Accumulator
, struct SResource
*res
, const char* id
, const char* language
, UBool isTopLevel
, UErrorCode
*status
) {
944 struct SResource
*current
= NULL
;
945 struct SResource
*save
= NULL
;
948 if (U_FAILURE(*status
)) {
952 sid
= printContainer(Accumulator
, res
, group
, table_restype
, NULL
, id
, status
);
958 save
= current
= res
->u
.fTable
.fFirst
;
961 while (current
!= NULL
) {
962 res_write_xml(Accumulator
, current
, sid
, language
, FALSE
, status
);
964 if(U_FAILURE(*status
)){
969 current
= current
->fNext
;
973 write_tabs(Accumulator
);
975 Accumulator
->append(UnicodeString(close_group
));
976 //T_FileStream_write(out, close_group,(int32_t)uprv_strlen(close_group));
983 res_write_xml(UnicodeString
*Accumulator
, struct SResource
*res
, const char* id
, const char* language
, UBool isTopLevel
, UErrorCode
*status
) {
985 if (U_FAILURE(*status
)) {
990 switch (res
->fType
) {
992 string_write_xml (Accumulator
, res
, id
, language
, status
);
996 alias_write_xml (Accumulator
, res
, id
, language
, status
);
999 case URES_INT_VECTOR
:
1000 intvector_write_xml (Accumulator
, res
, id
, language
, status
);
1004 bin_write_xml (Accumulator
, res
, id
, language
, status
);
1008 int_write_xml (Accumulator
, res
, id
, language
, status
);
1012 array_write_xml (Accumulator
, res
, id
, language
, status
);
1017 table_write_xml (Accumulator
, res
, id
, language
, isTopLevel
, status
);
1025 *status
= U_INTERNAL_PROGRAM_ERROR
;
1029 bundle_write_xml(struct SRBRoot
*bundle
, const char *outputDir
,const char* outputEnc
, const char* filename
,
1030 char *writtenFilename
, int writtenFilenameLen
,
1031 const char* language
, const char* outFileName
, UErrorCode
*status
) {
1033 UnicodeString Accumulator
;
1034 char* xmlfileName
= NULL
;
1035 char* outputFileName
= NULL
;
1036 char* originalFileName
= NULL
;
1037 const char* fileStart
= "<file xml:space = \"preserve\" source-language = \"";
1038 const char* file1
= "\" datatype = \"x-icu-resource-bundle\" ";
1039 const char* file2
= "original = \"";
1040 const char* file4
= "\" date = \"";
1041 const char* fileEnd
= "</file>\n";
1042 const char* headerStart
= "<header>\n";
1043 const char* headerEnd
= "</header>\n";
1044 const char* bodyStart
= "<body>\n";
1045 const char* bodyEnd
= "</body>\n";
1047 const char *tool_start
= "<tool";
1048 const char *tool_id
= "genrb-" GENRB_VERSION
"-icu-" U_ICU_VERSION
;
1049 const char *tool_name
= "genrb";
1053 const char* pos
= NULL
;
1054 int32_t first
, index
;
1062 pos
= uprv_strrchr(filename
, '\\');
1064 first
= (int32_t)(pos
- filename
+ 1);
1068 index
= (int32_t)(uprv_strlen(filename
) - uprv_strlen(textExt
) - first
);
1069 originalFileName
= (char *)uprv_malloc(sizeof(char)*index
+1);
1070 uprv_memset(originalFileName
, 0, sizeof(char)*index
+1);
1071 uprv_strncpy(originalFileName
, filename
+ first
, index
);
1073 if(uprv_strcmp(originalFileName
, srBundle
->fLocale
) != 0) {
1074 fprintf(stdout
, "Warning: The file name is not same as the resource name!\n");
1077 temp
= originalFileName
;
1078 originalFileName
= (char *)uprv_malloc(sizeof(char)* (uprv_strlen(temp
)+uprv_strlen(textExt
)) + 1);
1079 uprv_memset(originalFileName
, 0, sizeof(char)* (uprv_strlen(temp
)+uprv_strlen(textExt
)) + 1);
1080 uprv_strcat(originalFileName
, temp
);
1081 uprv_strcat(originalFileName
, textExt
);
1086 if (language
== NULL
) {
1087 /* lang = parseFilename(filename, lang);
1088 if (lang == NULL) {*/
1089 /* now check if locale name is valid or not
1090 * this is to cater for situation where
1091 * pegasusServer.txt contains
1097 lang
= parseFilename(srBundle
->fLocale
, lang
);
1099 * Neither the file name nor the table name inside the
1100 * txt file contain a valid country and language codes
1102 * pegasusServer.txt contains
1109 fprintf(stderr
, "Error: The file name and table name do not contain a valid language code. Please use -l option to specify it.\n");
1110 exit(U_ILLEGAL_ARGUMENT_ERROR
);
1114 lang
= (char *)uprv_malloc(sizeof(char)*uprv_strlen(language
) +1);
1115 uprv_memset(lang
, 0, sizeof(char)*uprv_strlen(language
) +1);
1116 uprv_strcpy(lang
, language
);
1120 outputFileName
= (char *)uprv_malloc(sizeof(char)*uprv_strlen(outFileName
) + 1);
1121 uprv_memset(outputFileName
, 0, sizeof(char)*uprv_strlen(outFileName
) + 1);
1122 uprv_strcpy(outputFileName
,outFileName
);
1124 outputFileName
= (char *)uprv_malloc(sizeof(char)*uprv_strlen(srBundle
->fLocale
) + 1);
1125 uprv_memset(outputFileName
, 0, sizeof(char)*uprv_strlen(srBundle
->fLocale
) + 1);
1126 uprv_strcpy(outputFileName
,srBundle
->fLocale
);
1130 xmlfileName
= (char *)uprv_malloc(sizeof(char)*(uprv_strlen(outputDir
) + uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
) + 1) +1);
1131 uprv_memset(xmlfileName
, 0, sizeof(char)*(uprv_strlen(outputDir
)+ uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
) + 1) +1);
1133 xmlfileName
= (char *)uprv_malloc(sizeof(char)*(uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
)) +1);
1134 uprv_memset(xmlfileName
, 0, sizeof(char)*(uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
)) +1);
1138 uprv_strcpy(xmlfileName
, outputDir
);
1139 if(outputDir
[uprv_strlen(outputDir
)-1] !=U_FILE_SEP_CHAR
){
1140 uprv_strcat(xmlfileName
,U_FILE_SEP_STRING
);
1143 uprv_strcat(xmlfileName
,outputFileName
);
1144 uprv_strcat(xmlfileName
,xliffExt
);
1146 if (writtenFilename
) {
1147 uprv_strncpy(writtenFilename
, xmlfileName
, writtenFilenameLen
);
1150 if (U_FAILURE(*status
)) {
1151 goto cleanup_bundle_write_xml
;
1154 out
= T_FileStream_open(xmlfileName
,"w");
1157 *status
= U_FILE_ACCESS_ERROR
;
1158 goto cleanup_bundle_write_xml
;
1160 Accumulator
.append(xmlHeader
);
1161 //T_FileStream_write(out,xmlHeader, (int32_t)uprv_strlen(xmlHeader));
1163 if(outputEnc
&& *outputEnc
!='\0'){
1164 /* store the output encoding */
1166 conv
=ucnv_open(enc
,status
);
1167 if(U_FAILURE(*status
)){
1168 goto cleanup_bundle_write_xml
;
1171 Accumulator
.append(bundleStart
);
1172 //T_FileStream_write(out,bundleStart, (int32_t)uprv_strlen(bundleStart));
1173 write_tabs(&Accumulator
);
1174 Accumulator
.append(fileStart
);
1175 //T_FileStream_write(out, fileStart, (int32_t)uprv_strlen(fileStart));
1176 /* check if lang and language are the same */
1177 if(language
!= NULL
&& uprv_strcmp(lang
, srBundle
->fLocale
)!=0){
1178 fprintf(stderr
,"Warning: The top level tag in the resource and language specified are not the same. Please check the input.\n");
1180 Accumulator
.append(UnicodeString(lang
));
1181 //T_FileStream_write(out,lang, (int32_t)uprv_strlen(lang));
1182 Accumulator
.append(UnicodeString(file1
));
1183 //T_FileStream_write(out,file1, (int32_t)uprv_strlen(file1));
1184 Accumulator
.append(UnicodeString(file2
));
1185 //T_FileStream_write(out,file2, (int32_t)uprv_strlen(file2));
1186 Accumulator
.append(UnicodeString(originalFileName
));
1187 //T_FileStream_write(out,originalFileName, (int32_t)uprv_strlen(originalFileName));
1188 Accumulator
.append(UnicodeString(file4
));
1189 //T_FileStream_write(out,file4, (int32_t)uprv_strlen(file4));
1192 strftime(timeBuf
, sizeof(timeBuf
), "%Y-%m-%dT%H:%M:%SZ", gmtime(&currTime
));
1194 Accumulator
.append(UnicodeString(timeBuf
));
1195 Accumulator
.append(UnicodeString("\">\n"));
1196 //T_FileStream_write(out,timeBuf, (int32_t)uprv_strlen(timeBuf));
1198 //T_FileStream_write(out,"\">\n", 3);
1201 write_tabs(&Accumulator
);
1202 Accumulator
.append(headerStart
);
1203 //T_FileStream_write(out,headerStart, (int32_t)uprv_strlen(headerStart));
1206 write_tabs(&Accumulator
);
1208 Accumulator
.append(tool_start
);
1209 //T_FileStream_write(out, tool_start, (int32_t) uprv_strlen(tool_start));
1210 printAttribute(&Accumulator
, "tool-id", tool_id
, (int32_t) uprv_strlen(tool_id
));
1211 printAttribute(&Accumulator
, "tool-name", tool_name
, (int32_t) uprv_strlen(tool_name
));
1213 Accumulator
.append(UnicodeString("/>\n"));
1214 //T_FileStream_write(out, "/>\n", 3);
1217 write_tabs(&Accumulator
);
1219 Accumulator
.append(UnicodeString(headerEnd
));
1220 //T_FileStream_write(out,headerEnd, (int32_t)uprv_strlen(headerEnd));
1222 write_tabs(&Accumulator
);
1225 Accumulator
.append(UnicodeString(bodyStart
));
1226 //T_FileStream_write(out,bodyStart, (int32_t)uprv_strlen(bodyStart));
1229 res_write_xml(&Accumulator
, bundle
->fRoot
, bundle
->fLocale
, lang
, TRUE
, status
);
1232 write_tabs(&Accumulator
);
1234 Accumulator
.append(UnicodeString(bodyEnd
));
1235 //T_FileStream_write(out,bodyEnd, (int32_t)uprv_strlen(bodyEnd));
1237 write_tabs(&Accumulator
);
1239 Accumulator
.append(UnicodeString(fileEnd
));
1240 //T_FileStream_write(out,fileEnd, (int32_t)uprv_strlen(fileEnd));
1242 write_tabs(&Accumulator
);
1243 Accumulator
.append(UnicodeString(bundleEnd
));
1244 //T_FileStream_write(out,bundleEnd,(int32_t)uprv_strlen(bundleEnd));
1246 write_utf8_file(Accumulator
, out
, status
);
1247 T_FileStream_close(out
);
1251 cleanup_bundle_write_xml
:
1252 uprv_free(originalFileName
);
1254 if(xmlfileName
!= NULL
) {
1255 uprv_free(xmlfileName
);
1257 if(outputFileName
!= NULL
){
1258 uprv_free(outputFileName
);