2 *******************************************************************************
4 * Copyright (C) 2002-2014, 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 *******************************************************************************
20 // Safer use of UnicodeString.
21 #ifndef UNISTR_FROM_CHAR_EXPLICIT
22 # define UNISTR_FROM_CHAR_EXPLICIT explicit
25 // Less important, but still a good idea.
26 #ifndef UNISTR_FROM_STRING_EXPLICIT
27 # define UNISTR_FROM_STRING_EXPLICIT explicit
32 #include "unicode/ures.h"
36 #include "unicode/ucnv.h"
41 #include "unicode/ustring.h"
42 #include "unicode/uchar.h"
45 #include "unicode/unistr.h"
46 #include "unicode/utf8.h"
47 #include "unicode/utf16.h"
52 static int tabCount
= 0;
54 static FileStream
* out
=NULL
;
55 static struct SRBRoot
* srBundle
;
56 static const char* outDir
= NULL
;
57 static const char* enc
="";
58 static UConverter
* conv
= NULL
;
60 const char* const* ISOLanguages
;
61 const char* const* ISOCountries
;
62 const char* textExt
= ".txt";
63 const char* xliffExt
= ".xlf";
65 static int32_t write_utf8_file(FileStream
* fileStream
, UnicodeString outString
)
67 UErrorCode status
= U_ZERO_ERROR
;
70 // preflight to get the destination buffer size
74 outString
.getBuffer(),
78 // allocate the buffer
79 char* dest
= (char*)uprv_malloc(len
);
80 status
= U_ZERO_ERROR
;
86 outString
.getBuffer(),
90 // write data to out file
91 int32_t ret
= T_FileStream_write(fileStream
, dest
, len
);
96 /*write indentation for formatting*/
97 static void write_tabs(FileStream
* os
){
99 for(;i
<=tabCount
;i
++){
100 write_utf8_file(os
,UnicodeString(" "));
104 /*get ID for each element. ID is globally unique.*/
105 static char* getID(const char* id
, const char* curKey
, char* result
) {
107 result
= (char *)uprv_malloc(sizeof(char)*uprv_strlen(id
) + 1);
108 uprv_memset(result
, 0, sizeof(char)*uprv_strlen(id
) + 1);
109 uprv_strcpy(result
, id
);
111 result
= (char *)uprv_malloc(sizeof(char)*(uprv_strlen(id
) + 1 + uprv_strlen(curKey
)) + 1);
112 uprv_memset(result
, 0, sizeof(char)*(uprv_strlen(id
) + 1 + uprv_strlen(curKey
)) + 1);
114 uprv_strcpy(result
, id
);
115 uprv_strcat(result
, "_");
117 uprv_strcat(result
, curKey
);
122 /*compute CRC for binary code*/
123 /* The code is from http://www.theorem.com/java/CRC32.java
124 * Calculates the CRC32 - 32 bit Cyclical Redundancy Check
125 * <P> This check is used in numerous systems to verify the integrity
126 * of information. It's also used as a hashing function. Unlike a regular
127 * checksum, it's sensitive to the order of the characters.
128 * It produces a 32 bit
130 * @author Michael Lecuyer (mjl@theorem.com)
131 * @version 1.1 August 11, 1998
134 /* ICU is not endian portable, because ICU data generated on big endian machines can be
135 * ported to big endian machines but not to little endian machines and vice versa. The
136 * conversion is not portable across platforms with different endianess.
139 uint32_t computeCRC(char *ptr
, uint32_t len
, uint32_t lastcrc
){
149 #define CRC32_POLYNOMIAL 0xEDB88320
152 for (i
= 0; i
<= 255; i
++) {
154 for (j
= 8; j
> 0; j
--) {
155 if ((crc2
& 1) == 1) {
156 crc2
= (crc2
>> 1) ^ CRC32_POLYNOMIAL
;
166 temp1
= (uint32_t)crc
>>8;
167 temp2
= crc_ta
[(crc
^*ptr
) & 0xFF];
174 static void strnrepchr(char* src
, int32_t srcLen
, char s
, char r
){
176 for(i
=0;i
<srcLen
;i
++){
182 /* Parse the filename, and get its language information.
183 * If it fails to get the language information from the filename,
184 * use "en" as the default value for language
186 static char* parseFilename(const char* id
, char* /*lang*/) {
187 int idLen
= (int) uprv_strlen(id
);
188 char* localeID
= (char*) uprv_malloc(idLen
);
190 int canonCapacity
= 0;
194 UErrorCode status
= U_ZERO_ERROR
;
195 const char *ext
= uprv_strchr(id
, '.');
198 pos
= (int) (ext
- id
);
202 uprv_memcpy(localeID
, id
, pos
);
203 localeID
[pos
]=0; /* NUL terminate the string */
205 canonCapacity
=pos
*3;
206 canon
= (char*) uprv_malloc(canonCapacity
);
207 canonLen
= uloc_canonicalize(localeID
, canon
, canonCapacity
, &status
);
209 if(U_FAILURE(status
)){
210 fprintf(stderr
, "Could not canonicalize the locale ID: %s. Error: %s\n", localeID
, u_errorName(status
));
213 strnrepchr(canon
, canonLen
, '_', '-');
217 static const char* xmlHeader
= "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
219 static const char* bundleStart
= "<xliff version = \"1.2\" "
220 "xmlns='urn:oasis:names:tc:xliff:document:1.2' "
221 "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
222 "xsi:schemaLocation='urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd'>\n";
224 static const char* bundleStart
= "<xliff version = \"1.1\" "
225 "xmlns='urn:oasis:names:tc:xliff:document:1.1' "
226 "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
227 "xsi:schemaLocation='urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd'>\n";
229 static const char* bundleEnd
= "</xliff>\n";
231 void res_write_xml(struct SResource
*res
, const char* id
, const char* language
, UBool isTopLevel
, UErrorCode
*status
);
233 static char* convertAndEscape(char** pDest
, int32_t destCap
, int32_t* destLength
,
234 const UChar
* src
, int32_t srcLen
, UErrorCode
* status
){
241 if(status
==NULL
|| U_FAILURE(*status
) || pDest
==NULL
|| srcLen
==0 || src
== NULL
){
245 if(dest
==NULL
|| destCap
<=0){
246 destCap
= srcLen
* 8;
247 dest
= (char*) uprv_malloc(sizeof(char) * destCap
);
249 *status
=U_MEMORY_ALLOCATION_ERROR
;
256 while(srcIndex
<srcLen
){
257 U16_NEXT(src
, srcIndex
, srcLen
, c
);
259 if (U16_IS_LEAD(c
) || U16_IS_TRAIL(c
)) {
260 *status
= U_ILLEGAL_CHAR_FOUND
;
261 fprintf(stderr
, "Illegal Surrogate! \n");
266 if((destLen
+U8_LENGTH(c
)) < destCap
){
272 uprv_strcpy(dest
+( destLen
),"\x26\x61\x6d\x70\x3b"); /* &*/
273 destLen
+=(int32_t)uprv_strlen("\x26\x61\x6d\x70\x3b");
276 uprv_strcpy(dest
+(destLen
),"\x26\x6c\x74\x3b"); /* <*/
277 destLen
+=(int32_t)uprv_strlen("\x26\x6c\x74\x3b");
280 uprv_strcpy(dest
+(destLen
),"\x26\x67\x74\x3b"); /* >*/
281 destLen
+=(int32_t)uprv_strlen("\x26\x67\x74\x3b");
284 uprv_strcpy(dest
+(destLen
),"\x26\x71\x75\x6f\x74\x3b"); /* "*/
285 destLen
+=(int32_t)uprv_strlen("\x26\x71\x75\x6f\x74\x3b");
288 uprv_strcpy(dest
+(destLen
),"\x26\x61\x70\x6f\x73\x3b"); /* ' */
289 destLen
+=(int32_t)uprv_strlen("\x26\x61\x70\x6f\x73\x3b");
292 /* Disallow C0 controls except TAB, CR, LF*/
325 *status
= U_ILLEGAL_CHAR_FOUND
;
326 fprintf(stderr
, "Illegal Character \\u%04X!\n",(int)c
);
330 dest
[destLen
++]=(char)c
;
333 UBool isError
= FALSE
;
334 U8_APPEND((unsigned char*)dest
,destLen
,destCap
,c
,isError
);
336 *status
= U_ILLEGAL_CHAR_FOUND
;
337 fprintf(stderr
, "Illegal Character \\U%08X!\n",(int)c
);
345 temp
= (char*) uprv_malloc(sizeof(char)*destCap
);
347 *status
=U_MEMORY_ALLOCATION_ERROR
;
351 uprv_memmove(temp
,dest
,destLen
);
359 *destLength
= destLen
;
363 #define ASTERISK 0x002A
367 #define AT_SIGN 0x0040
370 trim(char **src
, int32_t *len
){
374 if(src
== NULL
|| *src
== NULL
){
378 /* trim from the end */
379 for( i
=(*len
-1); i
>= 0; i
--){
397 print(UChar
* src
, int32_t srcLen
,const char *tagStart
,const char *tagEnd
, UErrorCode
*status
){
398 int32_t bufCapacity
= srcLen
*4;
402 if(U_FAILURE(*status
)){
406 buf
= (char*) (uprv_malloc(bufCapacity
));
408 fprintf(stderr
, "Could not allocate memory!!");
409 exit(U_MEMORY_ALLOCATION_ERROR
);
411 buf
= convertAndEscape(&buf
, bufCapacity
, &bufLen
, src
, srcLen
,status
);
412 if(U_SUCCESS(*status
)){
414 write_utf8_file(out
,UnicodeString(tagStart
));
415 write_utf8_file(out
,UnicodeString(buf
, bufLen
, "UTF-8"));
416 write_utf8_file(out
,UnicodeString(tagEnd
));
417 write_utf8_file(out
,UnicodeString("\n"));
422 printNoteElements(struct UString
*src
, UErrorCode
*status
){
424 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
426 int32_t capacity
= 0;
435 capacity
= src
->fLength
;
436 note
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
438 count
= getCount(src
->fChars
,src
->fLength
, UPC_NOTE
, status
);
439 if(U_FAILURE(*status
)){
443 for(i
=0; i
< count
; i
++){
444 noteLen
= getAt(src
->fChars
,src
->fLength
, ¬e
, capacity
, i
, UPC_NOTE
, status
);
445 if(U_FAILURE(*status
)){
451 print(note
, noteLen
,"<note>", "</note>", status
);
457 fprintf(stderr
, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
459 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
463 static void printAttribute(const char *name
, const char *value
, int32_t /*len*/)
465 write_utf8_file(out
, UnicodeString(" "));
466 write_utf8_file(out
, UnicodeString(name
));
467 write_utf8_file(out
, UnicodeString(" = \""));
468 write_utf8_file(out
, UnicodeString(value
));
469 write_utf8_file(out
, UnicodeString("\""));
472 static void printAttribute(const char *name
, const UnicodeString value
, int32_t /*len*/)
474 write_utf8_file(out
, UnicodeString(" "));
475 write_utf8_file(out
, UnicodeString(name
));
476 write_utf8_file(out
, UnicodeString(" = \""));
477 write_utf8_file(out
, value
);
478 write_utf8_file(out
, UnicodeString("\""));
482 printComments(struct UString
*src
, const char *resName
, UBool printTranslate
, UErrorCode
*status
){
484 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
486 if(status
==NULL
|| U_FAILURE(*status
)){
490 int32_t capacity
= src
->fLength
+ 1;
493 UChar
* desc
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
494 UChar
* trans
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
496 int32_t descLen
= 0, transLen
=0;
497 if(desc
==NULL
|| trans
==NULL
){
498 *status
= U_MEMORY_ALLOCATION_ERROR
;
503 src
->fLength
= removeCmtText(src
->fChars
, src
->fLength
, status
);
504 descLen
= getDescription(src
->fChars
,src
->fLength
, &desc
, capacity
, status
);
505 transLen
= getTranslate(src
->fChars
,src
->fLength
, &trans
, capacity
, status
);
507 /* first print translate attribute */
510 /* print translate attribute */
511 buf
= convertAndEscape(&buf
, 0, &bufLen
, trans
, transLen
, status
);
512 if(U_SUCCESS(*status
)){
513 printAttribute("translate", UnicodeString(buf
, bufLen
, "UTF-8"), bufLen
);
514 write_utf8_file(out
,UnicodeString(">\n"));
516 }else if(getShowWarning()){
517 fprintf(stderr
, "Warning: Tranlate attribute for resource %s cannot be set. XLIFF prohibits it.\n", resName
);
518 /* no translate attribute .. just close the tag */
519 write_utf8_file(out
,UnicodeString(">\n"));
522 /* no translate attribute .. just close the tag */
523 write_utf8_file(out
,UnicodeString(">\n"));
528 print(desc
, descLen
, "<!--", "-->", status
);
535 fprintf(stderr
, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
537 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
542 * Print out a containing element, like:
543 * <trans-unit id = "blah" resname = "blah" restype = "x-id-alias" translate = "no">
544 * <group id "calendar_gregorian" resname = "gregorian" restype = "x-icu-array">
546 static char *printContainer(struct SResource
*res
, const char *container
, const char *restype
, const char *mimetype
, const char *id
, UErrorCode
*status
)
548 char resKeyBuffer
[8];
549 const char *resname
= NULL
;
554 resname
= res_getKeyString(srBundle
, res
, resKeyBuffer
);
555 if (resname
!= NULL
&& *resname
!= 0) {
556 sid
= getID(id
, resname
, sid
);
558 sid
= getID(id
, NULL
, sid
);
561 write_utf8_file(out
, UnicodeString("<"));
562 write_utf8_file(out
, UnicodeString(container
));
563 printAttribute("id", sid
, (int32_t) uprv_strlen(sid
));
565 if (resname
!= NULL
) {
566 printAttribute("resname", resname
, (int32_t) uprv_strlen(resname
));
569 if (mimetype
!= NULL
) {
570 printAttribute("mime-type", mimetype
, (int32_t) uprv_strlen(mimetype
));
573 if (restype
!= NULL
) {
574 printAttribute("restype", restype
, (int32_t) uprv_strlen(restype
));
578 if (res
->fComment
.fLength
> 0) {
579 /* printComments will print the closing ">\n" */
580 printComments(&res
->fComment
, resname
, TRUE
, status
);
582 write_utf8_file(out
, UnicodeString(">\n"));
588 /* Writing Functions */
590 static const char *trans_unit
= "trans-unit";
591 static const char *close_trans_unit
= "</trans-unit>\n";
592 static const char *source
= "<source>";
593 static const char *close_source
= "</source>\n";
594 static const char *group
= "group";
595 static const char *close_group
= "</group>\n";
597 static const char *bin_unit
= "bin-unit";
598 static const char *close_bin_unit
= "</bin-unit>\n";
599 static const char *bin_source
= "<bin-source>\n";
600 static const char *close_bin_source
= "</bin-source>\n";
601 static const char *external_file
= "<external-file";
602 /*static const char *close_external_file = "</external-file>\n";*/
603 static const char *internal_file
= "<internal-file";
604 static const char *close_internal_file
= "</internal-file>\n";
606 static const char *application_mimetype
= "application"; /* add "/octet-stream"? */
608 static const char *alias_restype
= "x-icu-alias";
609 static const char *array_restype
= "x-icu-array";
610 static const char *binary_restype
= "x-icu-binary";
611 static const char *integer_restype
= "x-icu-integer";
612 static const char *intvector_restype
= "x-icu-intvector";
613 static const char *table_restype
= "x-icu-table";
616 string_write_xml(struct SResource
*res
, const char* id
, const char* /*language*/, UErrorCode
*status
) {
622 if(status
==NULL
|| U_FAILURE(*status
)){
626 sid
= printContainer(res
, trans_unit
, NULL
, NULL
, id
, status
);
630 write_utf8_file(out
, UnicodeString(source
));
632 buf
= convertAndEscape(&buf
, 0, &bufLen
, res
->u
.fString
.fChars
, res
->u
.fString
.fLength
, status
);
634 if (U_FAILURE(*status
)) {
638 write_utf8_file(out
, UnicodeString(buf
, bufLen
, "UTF-8"));
639 write_utf8_file(out
, UnicodeString(close_source
));
641 printNoteElements(&res
->fComment
, status
);
646 write_utf8_file(out
, UnicodeString(close_trans_unit
));
653 alias_write_xml(struct SResource
*res
, const char* id
, const char* /*language*/, UErrorCode
*status
) {
658 sid
= printContainer(res
, trans_unit
, alias_restype
, NULL
, id
, status
);
662 write_utf8_file(out
, UnicodeString(source
));
664 buf
= convertAndEscape(&buf
, 0, &bufLen
, res
->u
.fString
.fChars
, res
->u
.fString
.fLength
, status
);
666 if(U_FAILURE(*status
)){
669 write_utf8_file(out
, UnicodeString(buf
, bufLen
, "UTF-8"));
670 write_utf8_file(out
, UnicodeString(close_source
));
672 printNoteElements(&res
->fComment
, status
);
677 write_utf8_file(out
, UnicodeString(close_trans_unit
));
684 array_write_xml(struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
688 struct SResource
*current
= NULL
;
690 sid
= printContainer(res
, group
, array_restype
, NULL
, id
, status
);
692 current
= res
->u
.fArray
.fFirst
;
694 while (current
!= NULL
) {
698 itostr(c
, index
, 10, 0);
700 subId
= getID(sid
, c
, subId
);
702 res_write_xml(current
, subId
, language
, FALSE
, status
);
706 if(U_FAILURE(*status
)){
710 current
= current
->fNext
;
715 write_utf8_file(out
, UnicodeString(close_group
));
721 intvector_write_xml(struct SResource
*res
, const char* id
, const char* /*language*/, UErrorCode
*status
) {
726 char buf
[256] = {'0'};
728 sid
= printContainer(res
, group
, intvector_restype
, NULL
, id
, status
);
730 for(i
= 0; i
< res
->u
.fIntVector
.fCount
; i
+= 1) {
734 ivd
= getID(sid
, c
, ivd
);
735 len
= itostr(buf
, res
->u
.fIntVector
.fArray
[i
], 10, 0);
738 write_utf8_file(out
, UnicodeString("<"));
739 write_utf8_file(out
, UnicodeString(trans_unit
));
741 printAttribute("id", ivd
, (int32_t)uprv_strlen(ivd
));
742 printAttribute("restype", integer_restype
, (int32_t) strlen(integer_restype
));
744 write_utf8_file(out
, UnicodeString(">\n"));
748 write_utf8_file(out
, UnicodeString(source
));
750 write_utf8_file(out
, UnicodeString(buf
, len
));
752 write_utf8_file(out
, UnicodeString(close_source
));
755 write_utf8_file(out
, UnicodeString(close_trans_unit
));
764 write_utf8_file(out
, UnicodeString(close_group
));
770 int_write_xml(struct SResource
*res
, const char* id
, const char* /*language*/, UErrorCode
*status
) {
775 sid
= printContainer(res
, trans_unit
, integer_restype
, NULL
, id
, status
);
779 write_utf8_file(out
, UnicodeString(source
));
781 len
= itostr(buf
, res
->u
.fIntValue
.fValue
, 10, 0);
782 write_utf8_file(out
, UnicodeString(buf
, len
));
784 write_utf8_file(out
, UnicodeString(close_source
));
786 printNoteElements(&res
->fComment
, status
);
791 write_utf8_file(out
, UnicodeString(close_trans_unit
));
798 bin_write_xml(struct SResource
*res
, const char* id
, const char* /*language*/, UErrorCode
*status
) {
799 const char* m_type
= application_mimetype
;
801 uint32_t crc
= 0xFFFFFFFF;
803 char fileName
[1024] ={0};
804 int32_t tLen
= ( outDir
== NULL
) ? 0 :(int32_t)uprv_strlen(outDir
);
805 char* fn
= (char*) uprv_malloc(sizeof(char) * (tLen
+1024 +
806 (res
->u
.fBinaryValue
.fFileName
!=NULL
?
807 uprv_strlen(res
->u
.fBinaryValue
.fFileName
) :0)));
808 const char* ext
= NULL
;
814 if(res
->u
.fBinaryValue
.fFileName
!= NULL
){
815 uprv_strcpy(fileName
, res
->u
.fBinaryValue
.fFileName
);
816 f
= uprv_strrchr(fileName
, '\\');
824 ext
= uprv_strrchr(fileName
, '.');
827 fprintf(stderr
, "Error: %s is an unknown binary filename type.\n", fileName
);
828 exit(U_ILLEGAL_ARGUMENT_ERROR
);
831 if(uprv_strcmp(ext
, ".jpg")==0 || uprv_strcmp(ext
, ".jpeg")==0 || uprv_strcmp(ext
, ".gif")==0 ){
833 } else if(uprv_strcmp(ext
, ".wav")==0 || uprv_strcmp(ext
, ".au")==0 ){
835 } else if(uprv_strcmp(ext
, ".avi")==0 || uprv_strcmp(ext
, ".mpg")==0 || uprv_strcmp(ext
, ".mpeg")==0){
837 } else if(uprv_strcmp(ext
, ".txt")==0 || uprv_strcmp(ext
, ".text")==0){
841 sid
= printContainer(res
, bin_unit
, binary_restype
, m_type
, id
, status
);
845 write_utf8_file(out
, UnicodeString(bin_source
));
850 write_utf8_file(out
, UnicodeString(external_file
));
851 printAttribute("href", f
, (int32_t)uprv_strlen(f
));
852 write_utf8_file(out
, UnicodeString("/>\n"));
856 write_utf8_file(out
, UnicodeString(close_bin_source
));
858 printNoteElements(&res
->fComment
, status
);
861 write_utf8_file(out
, UnicodeString(close_bin_unit
));
863 char temp
[256] = {0};
867 sid
= printContainer(res
, bin_unit
, binary_restype
, m_type
, id
, status
);
870 write_utf8_file(out
, UnicodeString(bin_source
));
875 write_utf8_file(out
, UnicodeString(internal_file
));
876 printAttribute("form", application_mimetype
, (int32_t) uprv_strlen(application_mimetype
));
878 while(i
<res
->u
.fBinaryValue
.fLength
){
879 len
= itostr(temp
, res
->u
.fBinaryValue
.fData
[i
], 16, 2);
880 crc
= computeCRC(temp
, len
, crc
);
884 len
= itostr(temp
, crc
, 10, 0);
885 printAttribute("crc", temp
, len
);
887 write_utf8_file(out
, UnicodeString(">"));
890 while(i
<res
->u
.fBinaryValue
.fLength
){
891 len
= itostr(temp
, res
->u
.fBinaryValue
.fData
[i
], 16, 2);
892 write_utf8_file(out
, UnicodeString(temp
));
896 write_utf8_file(out
, UnicodeString(close_internal_file
));
901 write_utf8_file(out
, UnicodeString(close_bin_source
));
902 printNoteElements(&res
->fComment
, status
);
906 write_utf8_file(out
, UnicodeString(close_bin_unit
));
918 table_write_xml(struct SResource
*res
, const char* id
, const char* language
, UBool isTopLevel
, UErrorCode
*status
) {
922 struct SResource
*current
= NULL
;
925 if (U_FAILURE(*status
)) {
929 sid
= printContainer(res
, group
, table_restype
, NULL
, id
, status
);
935 current
= res
->u
.fTable
.fFirst
;
938 while (current
!= NULL
) {
939 res_write_xml(current
, sid
, language
, FALSE
, status
);
941 if(U_FAILURE(*status
)){
946 current
= current
->fNext
;
952 write_utf8_file(out
, UnicodeString(close_group
));
959 res_write_xml(struct SResource
*res
, const char* id
, const char* language
, UBool isTopLevel
, UErrorCode
*status
) {
961 if (U_FAILURE(*status
)) {
966 switch (res
->fType
) {
968 string_write_xml (res
, id
, language
, status
);
972 alias_write_xml (res
, id
, language
, status
);
975 case URES_INT_VECTOR
:
976 intvector_write_xml (res
, id
, language
, status
);
980 bin_write_xml (res
, id
, language
, status
);
984 int_write_xml (res
, id
, language
, status
);
988 array_write_xml (res
, id
, language
, status
);
992 table_write_xml (res
, id
, language
, isTopLevel
, status
);
1000 *status
= U_INTERNAL_PROGRAM_ERROR
;
1004 bundle_write_xml(struct SRBRoot
*bundle
, const char *outputDir
,const char* outputEnc
, const char* filename
,
1005 char *writtenFilename
, int writtenFilenameLen
,
1006 const char* language
, const char* outFileName
, UErrorCode
*status
) {
1008 char* xmlfileName
= NULL
;
1009 char* outputFileName
= NULL
;
1010 char* originalFileName
= NULL
;
1011 const char* fileStart
= "<file xml:space = \"preserve\" source-language = \"";
1012 const char* file1
= "\" datatype = \"x-icu-resource-bundle\" ";
1013 const char* file2
= "original = \"";
1014 const char* file4
= "\" date = \"";
1015 const char* fileEnd
= "</file>\n";
1016 const char* headerStart
= "<header>\n";
1017 const char* headerEnd
= "</header>\n";
1018 const char* bodyStart
= "<body>\n";
1019 const char* bodyEnd
= "</body>\n";
1021 const char *tool_start
= "<tool";
1022 const char *tool_id
= "genrb-" GENRB_VERSION
"-icu-" U_ICU_VERSION
;
1023 const char *tool_name
= "genrb";
1027 const char* pos
= NULL
;
1028 int32_t first
, index
;
1036 pos
= uprv_strrchr(filename
, '\\');
1038 first
= (int32_t)(pos
- filename
+ 1);
1042 index
= (int32_t)(uprv_strlen(filename
) - uprv_strlen(textExt
) - first
);
1043 originalFileName
= (char *)uprv_malloc(sizeof(char)*index
+1);
1044 uprv_memset(originalFileName
, 0, sizeof(char)*index
+1);
1045 uprv_strncpy(originalFileName
, filename
+ first
, index
);
1047 if(uprv_strcmp(originalFileName
, srBundle
->fLocale
) != 0) {
1048 fprintf(stdout
, "Warning: The file name is not same as the resource name!\n");
1051 temp
= originalFileName
;
1052 originalFileName
= (char *)uprv_malloc(sizeof(char)* (uprv_strlen(temp
)+uprv_strlen(textExt
)) + 1);
1053 uprv_memset(originalFileName
, 0, sizeof(char)* (uprv_strlen(temp
)+uprv_strlen(textExt
)) + 1);
1054 uprv_strcat(originalFileName
, temp
);
1055 uprv_strcat(originalFileName
, textExt
);
1060 if (language
== NULL
) {
1061 /* lang = parseFilename(filename, lang);
1062 if (lang == NULL) {*/
1063 /* now check if locale name is valid or not
1064 * this is to cater for situation where
1065 * pegasusServer.txt contains
1071 lang
= parseFilename(srBundle
->fLocale
, lang
);
1073 * Neither the file name nor the table name inside the
1074 * txt file contain a valid country and language codes
1076 * pegasusServer.txt contains
1083 fprintf(stderr
, "Error: The file name and table name do not contain a valid language code. Please use -l option to specify it.\n");
1084 exit(U_ILLEGAL_ARGUMENT_ERROR
);
1088 lang
= (char *)uprv_malloc(sizeof(char)*uprv_strlen(language
) +1);
1089 uprv_memset(lang
, 0, sizeof(char)*uprv_strlen(language
) +1);
1090 uprv_strcpy(lang
, language
);
1094 outputFileName
= (char *)uprv_malloc(sizeof(char)*uprv_strlen(outFileName
) + 1);
1095 uprv_memset(outputFileName
, 0, sizeof(char)*uprv_strlen(outFileName
) + 1);
1096 uprv_strcpy(outputFileName
,outFileName
);
1098 outputFileName
= (char *)uprv_malloc(sizeof(char)*uprv_strlen(srBundle
->fLocale
) + 1);
1099 uprv_memset(outputFileName
, 0, sizeof(char)*uprv_strlen(srBundle
->fLocale
) + 1);
1100 uprv_strcpy(outputFileName
,srBundle
->fLocale
);
1104 xmlfileName
= (char *)uprv_malloc(sizeof(char)*(uprv_strlen(outputDir
) + uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
) + 1) +1);
1105 uprv_memset(xmlfileName
, 0, sizeof(char)*(uprv_strlen(outputDir
)+ uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
) + 1) +1);
1107 xmlfileName
= (char *)uprv_malloc(sizeof(char)*(uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
)) +1);
1108 uprv_memset(xmlfileName
, 0, sizeof(char)*(uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
)) +1);
1112 uprv_strcpy(xmlfileName
, outputDir
);
1113 if(outputDir
[uprv_strlen(outputDir
)-1] !=U_FILE_SEP_CHAR
){
1114 uprv_strcat(xmlfileName
,U_FILE_SEP_STRING
);
1117 uprv_strcat(xmlfileName
,outputFileName
);
1118 uprv_strcat(xmlfileName
,xliffExt
);
1120 if (writtenFilename
) {
1121 uprv_strncpy(writtenFilename
, xmlfileName
, writtenFilenameLen
);
1124 if (U_FAILURE(*status
)) {
1125 goto cleanup_bundle_write_xml
;
1128 out
= T_FileStream_open(xmlfileName
,"w");
1131 *status
= U_FILE_ACCESS_ERROR
;
1132 goto cleanup_bundle_write_xml
;
1134 write_utf8_file(out
, UnicodeString(xmlHeader
));
1136 if(outputEnc
&& *outputEnc
!='\0'){
1137 /* store the output encoding */
1139 conv
=ucnv_open(enc
,status
);
1140 if(U_FAILURE(*status
)){
1141 goto cleanup_bundle_write_xml
;
1144 write_utf8_file(out
, UnicodeString(bundleStart
));
1146 write_utf8_file(out
, UnicodeString(fileStart
));
1147 /* check if lang and language are the same */
1148 if(language
!= NULL
&& uprv_strcmp(lang
, srBundle
->fLocale
)!=0){
1149 fprintf(stderr
,"Warning: The top level tag in the resource and language specified are not the same. Please check the input.\n");
1151 write_utf8_file(out
, UnicodeString(lang
));
1152 write_utf8_file(out
, UnicodeString(file1
));
1153 write_utf8_file(out
, UnicodeString(file2
));
1154 write_utf8_file(out
, UnicodeString(originalFileName
));
1155 write_utf8_file(out
, UnicodeString(file4
));
1158 strftime(timeBuf
, sizeof(timeBuf
), "%Y-%m-%dT%H:%M:%SZ", gmtime(&currTime
));
1159 write_utf8_file(out
, UnicodeString(timeBuf
));
1160 write_utf8_file(out
, UnicodeString("\">\n"));
1164 write_utf8_file(out
, UnicodeString(headerStart
));
1169 write_utf8_file(out
, UnicodeString(tool_start
));
1170 printAttribute("tool-id", tool_id
, (int32_t) uprv_strlen(tool_id
));
1171 printAttribute("tool-name", tool_name
, (int32_t) uprv_strlen(tool_name
));
1172 write_utf8_file(out
, UnicodeString("/>\n"));
1177 write_utf8_file(out
, UnicodeString(headerEnd
));
1182 write_utf8_file(out
, UnicodeString(bodyStart
));
1185 res_write_xml(bundle
->fRoot
, bundle
->fLocale
, lang
, TRUE
, status
);
1190 write_utf8_file(out
, UnicodeString(bodyEnd
));
1193 write_utf8_file(out
, UnicodeString(fileEnd
));
1196 write_utf8_file(out
, UnicodeString(bundleEnd
));
1197 T_FileStream_close(out
);
1201 cleanup_bundle_write_xml
:
1202 uprv_free(originalFileName
);
1204 if(xmlfileName
!= NULL
) {
1205 uprv_free(xmlfileName
);
1207 if(outputFileName
!= NULL
){
1208 uprv_free(outputFileName
);