2 *******************************************************************************
4 * Copyright (C) 2002-2004, 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 *******************************************************************************
19 #include "unicode/ures.h"
23 #include "unicode/ucnv.h"
29 #include "unicode/ustring.h"
30 #include "unicode/uchar.h"
35 static int tabCount
= 0;
37 static FileStream
* out
=NULL
;
38 static struct SRBRoot
* srBundle
;
39 static const char* outDir
= NULL
;
40 static const char* enc
="";
41 static UConverter
* conv
= NULL
;
43 const char* const* ISOLanguages
;
44 const char* const* ISOCountries
;
45 const char* textExt
= ".txt";
46 const char* xliffExt
= ".xlf";
48 /*write indentation for formatting*/
49 static void write_tabs(FileStream
* os
){
51 for(;i
<=tabCount
;i
++){
52 T_FileStream_write(os
," ",4);
56 /*get ID for each element. ID is globally unique.*/
57 static char* getID(const char* id
, char* curKey
, char* result
) {
59 result
= uprv_malloc(sizeof(char)*uprv_strlen(id
) + 1);
60 uprv_memset(result
, 0, sizeof(char)*uprv_strlen(id
) + 1);
61 uprv_strcpy(result
, id
);
63 result
= uprv_malloc(sizeof(char)*(uprv_strlen(id
) + 1 + uprv_strlen(curKey
)) + 1);
64 uprv_memset(result
, 0, sizeof(char)*(uprv_strlen(id
) + 1 + uprv_strlen(curKey
)) + 1);
66 uprv_strcpy(result
, id
);
67 uprv_strcat(result
, "_");
69 uprv_strcat(result
, curKey
);
74 /*compute CRC for binary code*/
75 /* The code is from http://www.theorem.com/java/CRC32.java
76 * Calculates the CRC32 - 32 bit Cyclical Redundancy Check
77 * <P> This check is used in numerous systems to verify the integrity
78 * of information. It's also used as a hashing function. Unlike a regular
79 * checksum, it's sensitive to the order of the characters.
80 * It produces a 32 bit
82 * @author Michael Lecuyer (mjl@theorem.com)
83 * @version 1.1 August 11, 1998
86 /* ICU is not endian portable, because ICU data generated on big endian machines can be
87 * ported to big endian machines but not to little endian machines and vice versa. The
88 * conversion is not portable across platforms with different endianess.
91 static uint32_t computeCRC(char *ptr
, uint32_t len
, uint32_t lastcrc
){
101 #define CRC32_POLYNOMIAL 0xEDB88320
104 for (i
= 0; i
<= 255; i
++) {
106 for (j
= 8; j
> 0; j
--) {
107 if ((crc2
& 1) == 1) {
108 crc2
= (crc2
>> 1) ^ CRC32_POLYNOMIAL
;
118 temp1
= (uint32_t)crc
>>8;
119 temp2
= crc_ta
[(crc
^*ptr
) & 0xFF];
126 /*check the language with ISO 639 standard*/
127 static UBool
checkISOLanguage(char* language
) {
131 while(ISOLanguages
[i
] != '\0') {
132 result
= uprv_strcmp(language
, ISOLanguages
[i
]);
141 /*check the language with ISO 639 standard*/
142 static UBool
checkISOCountry(char* country
) {
146 while(ISOCountries
[i
]!='\0') {
147 result
= uprv_strcmp(country
, ISOCountries
[i
]);
156 /* Parse the filename, and get its language information.
157 * If it fails to get the language information from the filename,
158 * use "en" as the default value for language
160 static char* parseFilename(const char* fileName
, char* lang
) {
170 UBool ISO_tag
= TRUE
;
172 ISOLanguages
= uloc_getISOLanguages();
173 ISOCountries
= uloc_getISOCountries();
175 pos
= uprv_strrchr(fileName
, U_FILE_SEP_CHAR
);
176 pos2
= uprv_strrchr(fileName
, '.');
181 first
= (int32_t)(pos
- fileName
);
184 second
= (int32_t)uprv_strlen(fileName
);
186 second
= (int32_t)(pos2
- fileName
);
188 index
= (int32_t)(second
- first
- 1);
189 str0
= uprv_malloc(sizeof(char) * index
+ 1);
190 uprv_memset(str0
, 0, sizeof(char) * index
+ 1);
191 uprv_strncpy(str0
, fileName
+ first
+ 1, index
);
193 pos
= uprv_strchr( str0
, '_' );
194 first
= (int32_t)(pos
- str0
);
196 str1
= uprv_malloc(sizeof(char)*uprv_strlen(str0
)+1);
197 uprv_memset(str1
, 0, sizeof(char)*uprv_strlen(str0
)+1);
198 uprv_strcpy(str1
, str0
);
200 str1
= uprv_malloc(sizeof(char)*first
+1);
201 uprv_memset(str1
, 0, sizeof(char)*first
+1);
202 uprv_strncpy(str1
, str0
, first
);
203 pos
= uprv_strrchr( str0
, '_' );
204 second
= (int32_t)(pos
- str0
);
205 if(first
!= second
&& second
-first
!= 1) {
206 index
= second
- first
-1;
207 str2
= uprv_malloc(sizeof(char)*index
+1);
208 uprv_memset(str2
, 0, sizeof(char)*index
+1);
209 uprv_strncpy(str2
, str0
+ first
+ 1, index
);
210 index
= (int32_t)(uprv_strlen(str0
) - second
-1);
211 str3
= uprv_malloc(sizeof(char)*index
+1);
212 uprv_memset(str3
, 0, sizeof(char)*index
+1);
213 uprv_strncpy(str3
, str0
+ second
+ 1, index
);
214 } else if(first
== second
) {
216 str1
= uprv_malloc(sizeof(char)*first
+1);
217 uprv_memset(str1
, 0, sizeof(char)*first
+1);
218 uprv_strncpy(str1
, str0
, index
);
219 index
= (int32_t)(uprv_strlen(str0
) - second
-1);
220 str2
= uprv_malloc(sizeof(char)*index
+1);
221 uprv_memset(str2
, 0, sizeof(char)*index
+1);
222 uprv_strncpy(str2
, str0
+ second
+ 1, index
);
226 if (str2
== NULL
&& str3
== NULL
) {
227 ISO_tag
= checkISOLanguage(str1
);
229 lang
= uprv_malloc(sizeof(char)*uprv_strlen(str1
)+1);
230 uprv_memset(lang
, 0, sizeof(char)*uprv_strlen(str1
)+1);
231 uprv_strcpy(lang
, str1
);
233 } else if(str3
== NULL
){
234 ISO_tag
= checkISOLanguage(str1
);
236 ISO_tag
= checkISOCountry(str2
);
238 lang
= uprv_malloc(sizeof(char)*uprv_strlen(str1
)+1);
239 uprv_memset(lang
, 0, sizeof(char)*uprv_strlen(str1
)+1);
240 uprv_strcpy(lang
, str1
);
243 ISO_tag
= checkISOLanguage(str2
);
245 lang
= uprv_malloc(sizeof(char)*uprv_strlen(str2
)+1);
246 uprv_memset(lang
, 0, sizeof(char)*uprv_strlen(str2
)+1);
247 uprv_strcpy(lang
, str2
);
251 ISO_tag
= checkISOLanguage(str1
);
253 ISO_tag
= checkISOCountry(str2
);
255 lang
= uprv_malloc(sizeof(char)*uprv_strlen(str1
)+1);
256 uprv_memset(lang
, 0, sizeof(char)*uprv_strlen(str1
)+1);
257 uprv_strcpy(lang
, str1
);
260 ISO_tag
= checkISOLanguage(str2
);
262 ISO_tag
= checkISOCountry(str3
);
264 lang
= uprv_malloc(sizeof(char)*uprv_strlen(str2
)+1);
265 uprv_memset(lang
, 0, sizeof(char)*uprv_strlen(str2
)+1);
266 uprv_strcpy(lang
, str2
);
288 static const char* xmlHeader
= "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
290 "SYSTEM \"http://www.oasis-open.org/committees/xliff/documents/xliff.dtd\">\n";
291 static const char* bundleStart
= "<xliff version = \"1.0\">\n";
292 static const char* bundleEnd
= "</xliff>\n";
294 void res_write_xml(struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
);
296 static char* convertAndEscape(char** pDest
, int32_t destCap
, int32_t* destLength
,
297 const UChar
* src
, int32_t srcLen
, UErrorCode
* status
){
304 if(status
==NULL
|| U_FAILURE(*status
) || pDest
==NULL
|| srcLen
==0 || src
== NULL
){
308 if(dest
==NULL
|| destCap
<=0){
309 destCap
= srcLen
* 8;
310 dest
= (char*) uprv_malloc(sizeof(char) * destCap
);
312 *status
=U_MEMORY_ALLOCATION_ERROR
;
319 while(srcIndex
<srcLen
){
320 U16_NEXT(src
, srcIndex
, srcLen
, c
);
322 if (U16_IS_LEAD(c
) || U16_IS_TRAIL(c
)) {
323 *status
= U_ILLEGAL_CHAR_FOUND
;
324 fprintf(stderr
, "Illegal Surrogate! \n");
329 if((destLen
+UTF8_CHAR_LENGTH(c
)) < destCap
){
335 uprv_strcpy(dest
+( destLen
),"&");
336 destLen
+=(int32_t)uprv_strlen("&");
339 uprv_strcpy(dest
+(destLen
),"<");
340 destLen
+=(int32_t)uprv_strlen("<");
343 uprv_strcpy(dest
+(destLen
),">");
344 destLen
+=(int32_t)uprv_strlen(">");
347 uprv_strcpy(dest
+(destLen
),""");
348 destLen
+=(int32_t)uprv_strlen(""");
351 uprv_strcpy(dest
+(destLen
),"'");
352 destLen
+=(int32_t)uprv_strlen("'");
355 /* Disallow C0 controls except TAB, CR, LF*/
388 *status
= U_ILLEGAL_CHAR_FOUND
;
389 fprintf(stderr
, "Illegal Character \\u%04X!\n",(int)c
);
393 dest
[destLen
++]=(char)c
;
396 UBool isError
= FALSE
;
397 U8_APPEND((unsigned char*)dest
,destLen
,destCap
,c
,isError
);
399 *status
= U_ILLEGAL_CHAR_FOUND
;
400 fprintf(stderr
, "Illegal Character \\U%08X!\n",(int)c
);
408 temp
= (char*) uprv_malloc(sizeof(char)*destCap
);
410 *status
=U_MEMORY_ALLOCATION_ERROR
;
413 uprv_memmove(temp
,dest
,destLen
);
421 *destLength
= destLen
;
425 #define ASTERISK 0x002A
429 #define AT_SIGN 0x0040
431 static const UChar tokens
[][11] = {
432 {0x0040, 0x0074, 0x0072, 0x0061, 0x006e, 0x0073, 0x006c, 0x0061, 0x0074, 0x0065, 0x0000}, /* @translate */
433 {0x0040, 0x006e, 0x006f, 0x0074, 0x0065, 0x0000} /* @note */
436 static const UChar yes
[] = { 0x0079, 0x0065, 0x0073, 0x0000}; /* yes */
437 static const UChar no
[] ={ 0x006e, 0x006f, 0x0000 }; /* no */
442 trim(char **src
, int32_t *len
){
446 if(src
== NULL
|| *src
== NULL
){
450 /* trim from the end */
451 for( i
=(*len
-1); i
>= 0; i
--){
469 print(UChar
* src
, int32_t srcLen
,const char *tagStart
,const char *tagEnd
, UErrorCode
*status
){
470 int32_t bufCapacity
= srcLen
*4;
474 if(U_FAILURE(*status
)){
478 buf
= (char*) (uprv_malloc(bufCapacity
));
480 fprintf(stderr
, "Could not allocate memory!!");
481 exit(U_MEMORY_ALLOCATION_ERROR
);
483 buf
= convertAndEscape(&buf
, bufCapacity
, &bufLen
, src
, srcLen
,status
);
484 if(U_SUCCESS(*status
)){
486 T_FileStream_write(out
,tagStart
, (int32_t)uprv_strlen(tagStart
));
487 T_FileStream_write(out
, buf
, bufLen
);
488 T_FileStream_write(out
,tagEnd
, (int32_t)uprv_strlen(tagEnd
));
489 T_FileStream_write(out
,"\n",1);
494 printNoteElements(struct UString
*src
, UErrorCode
*status
){
496 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
498 int32_t capacity
= 0;
507 capacity
= src
->fLength
;
508 note
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
510 count
= getCount(src
->fChars
,src
->fLength
, UPC_NOTE
, status
);
511 if(U_FAILURE(*status
)){
514 for(i
=0; i
< count
; i
++){
515 noteLen
= getAt(src
->fChars
,src
->fLength
, ¬e
, capacity
, i
, UPC_NOTE
, status
);
516 if(U_FAILURE(*status
)){
521 print(note
, noteLen
,"<note>", "</note>", status
);
527 fprintf(stderr
, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
529 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
534 printComments(struct UString
*src
, const char *resName
, UBool printTranslate
, UErrorCode
*status
){
536 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
538 int32_t capacity
= src
->fLength
;
541 const char* translateAttr
= " translate=\"";
542 UChar
* desc
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
543 UChar
* trans
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
545 int32_t descLen
= 0, transLen
=0;
546 if(status
==NULL
|| U_FAILURE(*status
)){
551 if(desc
==NULL
|| trans
==NULL
){
552 *status
= U_MEMORY_ALLOCATION_ERROR
;
557 src
->fLength
= removeCmtText(src
->fChars
, src
->fLength
, status
);
558 descLen
= getDescription(src
->fChars
,src
->fLength
, &desc
, capacity
, status
);
559 transLen
= getTranslate(src
->fChars
,src
->fLength
, &trans
, capacity
, status
);
561 /* first print translate attribute */
563 if(printTranslate
==TRUE
){
564 /* print translate attribute */
565 buf
= convertAndEscape(&buf
, 0, &bufLen
, trans
, transLen
, status
);
566 if(U_SUCCESS(*status
)){
567 T_FileStream_write(out
,translateAttr
, (int32_t)uprv_strlen(translateAttr
));
568 T_FileStream_write(out
,buf
, bufLen
);
569 T_FileStream_write(out
,"\">\n", 3);
571 }else if(getShowWarning() == TRUE
){
572 fprintf(stderr
, "Warning: Tranlate attribute for resource %s cannot be set. XLIFF prohibits it.\n", resName
);
573 /* no translate attribute .. just close the tag */
574 T_FileStream_write(out
,">\n", 2);
577 /* no translate attribute .. just close the tag */
578 T_FileStream_write(out
,">\n", 2);
582 print(desc
, descLen
, "<!--", "-->", status
);
586 fprintf(stderr
, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
588 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
591 /* Writing Functions */
593 string_write_xml(struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
599 const char* strStart
= "<trans-unit xml:space = \"preserve\" id = \"";
600 const char* valStrStart
= "<source xml:lang = \"";
601 const char* valStrEnd
= "</source>\n";
602 const char* strEnd
= "</trans-unit>\n";
604 if(status
==NULL
|| U_FAILURE(*status
)){
608 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
610 T_FileStream_write(out
,strStart
, (int32_t)uprv_strlen(strStart
));
611 sid
= getID(id
, NULL
, sid
);
612 T_FileStream_write(out
,sid
, (int32_t)uprv_strlen(sid
));
613 T_FileStream_write(out
,"\"", 1);
615 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
616 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, TRUE
, status
);
619 T_FileStream_write(out
,">\n", 2);
624 T_FileStream_write(out
,valStrStart
, (int32_t)uprv_strlen(valStrStart
));
625 T_FileStream_write(out
,language
, (int32_t)uprv_strlen(language
));
626 T_FileStream_write(out
,"\">", 2);
628 buf
= convertAndEscape(&buf
,0,&bufLen
,res
->u
.fString
.fChars
,res
->u
.fString
.fLength
,status
);
630 if(U_FAILURE(*status
)){
634 T_FileStream_write(out
,buf
,bufLen
);
635 T_FileStream_write(out
,valStrEnd
,(int32_t)uprv_strlen(valStrEnd
));
637 printNoteElements(res
->fComment
, status
);
641 T_FileStream_write(out
,strEnd
,(int32_t)uprv_strlen(strEnd
));
643 const char* keyStrStart
= "resname = \"";
647 T_FileStream_write(out
, strStart
, (int32_t)uprv_strlen(strStart
));
648 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
,sid
);
649 T_FileStream_write(out
,sid
, (int32_t)uprv_strlen(sid
));
650 T_FileStream_write(out
,"\" ", 2);
651 T_FileStream_write(out
,keyStrStart
, (int32_t)uprv_strlen(keyStrStart
));
653 T_FileStream_write(out
,srBundle
->fKeys
+res
->fKey
, (int32_t)uprv_strlen(srBundle
->fKeys
+res
->fKey
));
654 T_FileStream_write(out
,"\"", 1);
656 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
657 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, TRUE
, status
);
659 T_FileStream_write(out
,">\n", 2);
663 T_FileStream_write(out
,valStrStart
, (int32_t)uprv_strlen(valStrStart
));
665 T_FileStream_write(out
,language
, (int32_t)uprv_strlen(language
));
666 T_FileStream_write(out
,"\">", 2);
668 buf
= convertAndEscape(&buf
,0,&bufLen
,res
->u
.fString
.fChars
,res
->u
.fString
.fLength
,status
);
669 if(U_FAILURE(*status
)){
672 T_FileStream_write(out
,buf
,bufLen
);
674 T_FileStream_write(out
,valStrEnd
,(int32_t)uprv_strlen(valStrEnd
));
676 printNoteElements(res
->fComment
, status
);
680 T_FileStream_write(out
,strEnd
,(int32_t)uprv_strlen(strEnd
));
690 alias_write_xml(struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
691 static const char* startKey
= "resname=\"";
692 static const char* val
= "<source>";
693 static const char* endKey
= "</source>\n";
694 static const char* start
= "<trans-unit restype = \"alias\" xml:space = \"preserve\" id = \"";
695 static const char* end
= "</trans-unit>\n";
701 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
702 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
704 sid
= getID(id
, NULL
, sid
);
705 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
706 T_FileStream_write(out
, "\"", 1);
708 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
709 printComments(res
->fComment
,srBundle
->fKeys
+res
->fKey
, TRUE
, status
);
712 T_FileStream_write(out
,">\n", 2);
715 T_FileStream_write(out
, val
, (int32_t)uprv_strlen(val
));
717 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
718 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
719 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
720 T_FileStream_write(out
, "\" ", 2);
721 T_FileStream_write(out
, startKey
, (int32_t)uprv_strlen(startKey
));
722 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
724 T_FileStream_write(out
, "\"", 1);
726 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
727 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, TRUE
, status
);
730 T_FileStream_write(out
,">\n", 2);
735 T_FileStream_write(out
, val
, (int32_t)uprv_strlen(val
));
738 buf
= convertAndEscape(&buf
,0,&bufLen
,res
->u
.fString
.fChars
,res
->u
.fString
.fLength
,/*FALSE,*/status
);
739 if(U_FAILURE(*status
)){
742 T_FileStream_write(out
,buf
,bufLen
);
743 T_FileStream_write(out
, endKey
, (int32_t)uprv_strlen(endKey
));
745 printNoteElements(res
->fComment
, status
);
750 T_FileStream_write(out
, end
, (int32_t)uprv_strlen(end
));
756 array_write_xml( struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
757 const char* start
= "<group restype = \"array\" xml:space = \"preserve\" id = \"";
758 const char* end
= "</group>\n";
759 const char* startKey
= "resname=\"";
764 struct SResource
*current
= NULL
;
765 struct SResource
*first
=NULL
;
769 if(res
->fKey
<0 ||uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
770 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
771 sid
= getID(id
, NULL
, sid
);
772 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
773 T_FileStream_write(out
, "\"", 1);
774 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
775 printComments(res
->fComment
, sid
, FALSE
, status
);
776 printNoteElements(res
->fComment
, status
);
778 T_FileStream_write(out
,">\n", 2);
781 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
782 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
783 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
784 T_FileStream_write(out
, "\" ", 2);
785 T_FileStream_write(out
, startKey
, (int32_t)uprv_strlen(startKey
));
786 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
787 T_FileStream_write(out
, "\"", 1);
788 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
789 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, FALSE
, status
);
790 printNoteElements(res
->fComment
, status
);
792 T_FileStream_write(out
,">\n", 2);
795 current
= res
->u
.fArray
.fFirst
;
798 while (current
!= NULL
) {
801 itostr(c
, index
,10,0);
803 subId
= getID(sid
, c
, subId
);
805 res_write_xml(current
, subId
, language
, status
);
808 if(U_FAILURE(*status
)){
811 current
= current
->fNext
;
815 T_FileStream_write(out
,end
,(int32_t)uprv_strlen(end
));
821 intvector_write_xml( struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
822 const char* start
= "<group restype = \"intvector\" xml:space = \"preserve\" id = \"";
823 const char* end
= "</group>\n";
824 const char* startKey
= "resname=\"";
826 const char* intStart
= "<trans-unit restype = \"int\" xml:space = \"preserve\" translate=\"no\" id = \"";
827 const char* valIntStart
= "<source>";
828 const char* valIntEnd
= "</source>\n";
829 const char* intEnd
= "</trans-unit>\n";
835 char buf
[256] = {'0'};
839 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
840 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
841 sid
= getID(id
, NULL
, sid
);
842 T_FileStream_write(out
,sid
, (int32_t)uprv_strlen(sid
));
843 T_FileStream_write(out
, "\"", 1);
844 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
845 printComments(res
->fComment
, sid
, FALSE
, status
);
848 T_FileStream_write(out
,">\n", 2);
851 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
852 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
853 T_FileStream_write(out
,sid
, (int32_t)uprv_strlen(sid
));
854 T_FileStream_write(out
,"\" ", 2);
856 T_FileStream_write(out
, startKey
, (int32_t)uprv_strlen(startKey
));
857 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
858 T_FileStream_write(out
, "\"", 1);
859 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
860 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, FALSE
, status
);
861 printNoteElements(res
->fComment
, status
);
863 T_FileStream_write(out
,">\n", 2);
868 for(i
= 0; i
<res
->u
.fIntVector
.fCount
; i
++) {
871 ivd
= getID(sid
, c
, ivd
);
872 len
=itostr(buf
,res
->u
.fIntVector
.fArray
[i
],10,0);
875 T_FileStream_write(out
, intStart
, (int32_t)uprv_strlen(intStart
));
876 T_FileStream_write(out
, ivd
, (int32_t)uprv_strlen(ivd
));
877 T_FileStream_write(out
,"\">\n", 3);
880 T_FileStream_write(out
,valIntStart
, (int32_t)uprv_strlen(valIntStart
));
882 T_FileStream_write(out
,buf
,len
);
884 T_FileStream_write(out
,valIntEnd
, (int32_t)uprv_strlen(valIntEnd
));
887 T_FileStream_write(out
, intEnd
, (int32_t)uprv_strlen(intEnd
));
896 T_FileStream_write(out
, end
, (int32_t)uprv_strlen(end
));
902 int_write_xml(struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
903 const char* intStart
= "<trans-unit restype = \"int\" xml:space = \"preserve\" id = \"";
904 const char* valIntStart
= "<source>";
905 const char* valIntEnd
= "</source>\n";
906 const char* intEnd
= "</trans-unit>\n";
907 const char* keyIntStart
= "resname = \"";
916 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
917 T_FileStream_write(out
, intStart
, (int32_t)uprv_strlen(intStart
));
918 sid
= getID(id
, NULL
, sid
);
919 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
920 T_FileStream_write(out
,"\"", 1);
922 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
923 printComments(res
->fComment
, sid
, TRUE
, status
);
926 T_FileStream_write(out
,">\n", 2);
929 T_FileStream_write(out
,valIntStart
, (int32_t)uprv_strlen(valIntStart
));
931 T_FileStream_write(out
, intStart
, (int32_t)uprv_strlen(intStart
));
932 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
933 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
934 T_FileStream_write(out
,"\" ", 2);
935 T_FileStream_write(out
,keyIntStart
, (int32_t)uprv_strlen(keyIntStart
));
937 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
938 T_FileStream_write(out
,"\"", 1);
940 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
941 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, TRUE
, status
);
944 T_FileStream_write(out
,">\n", 2);
947 T_FileStream_write(out
, valIntStart
, (int32_t)uprv_strlen(valIntStart
));
950 len
=itostr(buf
,res
->u
.fIntValue
.fValue
,10,0);
951 T_FileStream_write(out
,buf
,len
);
953 T_FileStream_write(out
, valIntEnd
, (int32_t)uprv_strlen(valIntEnd
));
954 printNoteElements(res
->fComment
, status
);
957 T_FileStream_write(out
, intEnd
, (int32_t)uprv_strlen(intEnd
));
963 bin_write_xml( struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
964 const char* start
= "<bin-unit restype = \"bin\" id = \"";
965 const char* importStart
= "<bin-unit restype = \"import\" id = \"";
966 const char* mime
= " mime-type = ";
967 const char* key
= "\" resname = \"";
968 const char* valStart
= "<bin-source>\n";
969 const char* fileStart
= "<internal-file form = \"application\" crc = \"";
970 const char* fileEnd
= "</internal-file>\n";
971 const char* valEnd
= "</bin-source>\n";
972 const char* end
= "</bin-unit>\n";
973 const char* externalFileStart
= "<external-file href = \"";
974 const char* externalFileEnd
= "\"/>\n";
975 const char* m_type
= "\"application";
977 uint32_t crc
= 0xFFFFFFFF;
979 char fileName
[1024] ={0};
980 int32_t tLen
= ( outDir
== NULL
) ? 0 :(int32_t)uprv_strlen(outDir
);
981 char* fn
= (char*) uprv_malloc(sizeof(char) * (tLen
+1024 +
982 (res
->u
.fBinaryValue
.fFileName
!=NULL
?
983 uprv_strlen(res
->u
.fBinaryValue
.fFileName
) :0)));
984 const char* ext
= NULL
;
990 if(res
->u
.fBinaryValue
.fFileName
!=NULL
){
991 uprv_strcpy(fileName
, res
->u
.fBinaryValue
.fFileName
);
992 f
= uprv_strrchr(fileName
, '\\');
994 ext
= uprv_strrchr(fileName
, '.');
996 if(uprv_strcmp(ext
, ".jpg")==0 || uprv_strcmp(ext
, ".jpeg")==0 || uprv_strcmp(ext
, ".gif")==0 ){
998 } else if(uprv_strcmp(ext
, ".wav")==0 || uprv_strcmp(ext
, ".au")==0 ){
1000 } else if(uprv_strcmp(ext
, ".avi")==0 || uprv_strcmp(ext
, ".mpg")==0 || uprv_strcmp(ext
, ".mpeg")==0){
1002 } else if(uprv_strcmp(ext
, ".txt")==0 || uprv_strcmp(ext
, ".text")==0){
1007 T_FileStream_write(out
, importStart
, (int32_t)uprv_strlen(importStart
));
1008 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
1009 sid
= getID(id
, NULL
, sid
);
1010 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1012 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
1013 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1015 T_FileStream_write(out
, "\" ", 2);
1016 T_FileStream_write(out
, mime
, (int32_t)uprv_strlen(mime
));
1017 T_FileStream_write(out
, m_type
, (int32_t)uprv_strlen(m_type
));
1018 if(!(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0)){
1019 T_FileStream_write(out
, key
, (int32_t)uprv_strlen(key
));
1020 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
1022 T_FileStream_write(out
,"\"", 1);
1024 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
1025 printComments(res
->fComment
, sid
, TRUE
, status
);
1028 T_FileStream_write(out
,">\n", 2);
1033 T_FileStream_write(out
, valStart
, (int32_t)uprv_strlen(valStart
));
1036 T_FileStream_write(out
, externalFileStart
, (int32_t)uprv_strlen(externalFileStart
));
1037 T_FileStream_write(out
, f
, (int32_t)uprv_strlen(f
));
1038 T_FileStream_write(out
, externalFileEnd
, (int32_t)uprv_strlen(externalFileEnd
));
1041 T_FileStream_write(out
, valEnd
, (int32_t)uprv_strlen(valEnd
));
1043 printNoteElements(res
->fComment
, status
);
1046 T_FileStream_write(out
,end
,(int32_t)uprv_strlen(end
));
1048 char temp
[256] = {0};
1053 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
1054 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
1055 sid
= getID(id
, NULL
, sid
);
1056 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1058 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
1059 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1062 T_FileStream_write(out
, "\" ", 2);
1063 T_FileStream_write(out
, mime
, (int32_t)uprv_strlen(mime
));
1064 T_FileStream_write(out
, m_type
, (int32_t)uprv_strlen(m_type
));
1065 if(!(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0)){
1066 T_FileStream_write(out
, key
, (int32_t)uprv_strlen(key
));
1067 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
1069 T_FileStream_write(out
,"\"", 1);
1071 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
1072 printComments(res
->fComment
, sid
, TRUE
, status
);
1075 T_FileStream_write(out
,">\n", 2);
1079 T_FileStream_write(out
, valStart
, (int32_t)uprv_strlen(valStart
));
1082 T_FileStream_write(out
, fileStart
, (int32_t)uprv_strlen(fileStart
));
1084 while(i
<res
->u
.fBinaryValue
.fLength
){
1085 len
= itostr(temp
,res
->u
.fBinaryValue
.fData
[i
],16,2);
1086 crc
= computeCRC(temp
, len
, crc
);
1090 len
= itostr(temp
, crc
, 10, 0);
1091 T_FileStream_write(out
,temp
,len
);
1092 T_FileStream_write(out
,"\">",2);
1095 while(i
<res
->u
.fBinaryValue
.fLength
){
1096 len
= itostr(temp
,res
->u
.fBinaryValue
.fData
[i
],16,2);
1097 T_FileStream_write(out
,temp
,len
);
1100 T_FileStream_write(out
, fileEnd
, (int32_t)uprv_strlen(fileEnd
));
1103 T_FileStream_write(out
, valEnd
, (int32_t)uprv_strlen(valEnd
));
1104 printNoteElements(res
->fComment
, status
);
1108 T_FileStream_write(out
,end
,(int32_t)uprv_strlen(end
));
1119 table_write_xml(struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
1123 struct SResource
*current
= NULL
;
1124 struct SResource
*save
= NULL
;
1127 const char* start
= "<group restype = \"table\" xml:space = \"preserve\"";
1128 const char* idstr
= " id = \"";
1129 const char* end
= "</group>\n";
1130 const char* startKey
= "resname=\"";
1132 if (U_FAILURE(*status
)) {
1136 if (res
->u
.fTable
.fCount
> 0) {
1140 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
1141 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
1143 sid
= getID(id
, NULL
, sid
);
1144 /* only write the id if the sid!="" */
1146 T_FileStream_write(out
, idstr
, (int32_t)uprv_strlen(idstr
));
1147 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1148 T_FileStream_write(out
, "\" ", 2);
1152 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
1153 printComments(res
->fComment
, sid
, FALSE
, status
);
1154 printNoteElements(res
->fComment
, status
);
1156 T_FileStream_write(out
,">\n", 2);
1159 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
1160 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
1162 /* only write the id if the sid!="" */
1164 T_FileStream_write(out
, idstr
, (int32_t)uprv_strlen(idstr
));
1165 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1166 T_FileStream_write(out
, "\" ", 2);
1169 T_FileStream_write(out
, startKey
, (int32_t)uprv_strlen(startKey
));
1170 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
1171 T_FileStream_write(out
, "\" ", 2);
1173 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
1174 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, FALSE
, status
);
1175 printNoteElements(res
->fComment
, status
);
1177 T_FileStream_write(out
,">\n", 2);
1181 save
= current
= res
->u
.fTable
.fFirst
;
1183 while (current
!= NULL
) {
1184 res_write_xml(current
, sid
, language
, status
);
1186 if(U_FAILURE(*status
)){
1190 current
= current
->fNext
;
1194 T_FileStream_write(out
,end
,(int32_t)uprv_strlen(end
));
1197 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
1198 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
1199 sid
= getID(id
, NULL
, sid
);
1200 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1201 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
1202 printComments(res
->fComment
, sid
, FALSE
, status
);
1203 printNoteElements(res
->fComment
, status
);
1205 T_FileStream_write(out
,">\n", 2);
1208 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
1209 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
1210 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1211 T_FileStream_write(out
, "\" ", 2);
1212 T_FileStream_write(out
, startKey
, (int32_t)uprv_strlen(startKey
));
1213 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
1215 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
1216 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, FALSE
, status
);
1217 printNoteElements(res
->fComment
, status
);
1219 T_FileStream_write(out
,">\n", 2);
1224 T_FileStream_write(out
,end
,(int32_t)uprv_strlen(end
));
1231 res_write_xml(struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
1233 if (U_FAILURE(*status
)) {
1238 switch (res
->fType
) {
1240 string_write_xml (res
, id
, language
, status
);
1243 alias_write_xml (res
, id
, language
, status
);
1245 case URES_INT_VECTOR
:
1246 intvector_write_xml (res
, id
, language
, status
);
1249 bin_write_xml (res
, id
, language
, status
);
1252 int_write_xml (res
, id
, language
, status
);
1255 array_write_xml (res
, id
, language
, status
);
1259 table_write_xml (res
, id
, language
, status
);
1267 *status
= U_INTERNAL_PROGRAM_ERROR
;
1271 bundle_write_xml(struct SRBRoot
*bundle
, const char *outputDir
,const char* outputEnc
, const char* filename
,
1272 char *writtenFilename
, int writtenFilenameLen
,
1273 const char* language
, const char* outFileName
, UErrorCode
*status
) {
1275 char* xmlfileName
= NULL
;
1276 char* outputFileName
= NULL
;
1277 char* originalFileName
= NULL
;
1278 const char* fileStart
= "<file xml:space = \"preserve\" source-language = \"";
1279 const char* file1
= "\" datatype = \"text\" ";
1280 const char* file2
= "original = \"";
1281 const char* file3
= "\" tool = \"genrb\" ";
1282 const char* file4
= "date = \"";
1283 const char* fileEnd
= "</file>\n";
1284 const char* headerStart
= "<header>";
1285 const char* headerEnd
= "</header>\n";
1286 const char* bodyStart
= "<body>\n";
1287 const char* bodyEnd
= "</body>\n";
1293 int32_t first
, index
;
1301 pos
= uprv_strrchr(filename
, '\\');
1303 first
= (int32_t)(pos
- filename
+ 1);
1307 index
= (int32_t)(uprv_strlen(filename
) - uprv_strlen(textExt
) - first
);
1308 originalFileName
= uprv_malloc(sizeof(char)*index
+1);
1309 uprv_memset(originalFileName
, 0, sizeof(char)*index
+1);
1310 uprv_strncpy(originalFileName
, filename
+ first
, index
);
1312 if(uprv_strcmp(originalFileName
, srBundle
->fLocale
) != 0) {
1313 fprintf(stdout
, "Warning: The file name is not same as the resource name!\n");
1316 temp
= originalFileName
;
1317 originalFileName
= uprv_malloc(sizeof(char)* (uprv_strlen(temp
)+uprv_strlen(textExt
)) + 1);
1318 uprv_memset(originalFileName
, 0, sizeof(char)* (uprv_strlen(temp
)+uprv_strlen(textExt
)) + 1);
1319 uprv_strcat(originalFileName
, temp
);
1320 uprv_strcat(originalFileName
, textExt
);
1325 if (language
== NULL
) {
1326 lang
= parseFilename(filename
, lang
);
1328 /* now check if locale name is valid or not
1329 * this is to cater for situation where
1330 * pegasusServer.txt contains
1336 lang
= parseFilename(srBundle
->fLocale
, lang
);
1338 * Neither the file name nor the table name inside the
1339 * txt file contain a valid country and language codes
1341 * pegasusServer.txt contains
1348 fprintf(stderr
, "Error: The file name and table name do not contain a valid language code. Please use -l option to specify it.\n");
1349 exit(U_ILLEGAL_ARGUMENT_ERROR
);
1353 lang
= uprv_malloc(sizeof(char)*uprv_strlen(language
) +1);
1354 uprv_memset(lang
, 0, sizeof(char)*uprv_strlen(language
) +1);
1355 uprv_strcpy(lang
, language
);
1359 outputFileName
= uprv_malloc(sizeof(char)*uprv_strlen(outFileName
) + 1);
1360 uprv_memset(outputFileName
, 0, sizeof(char)*uprv_strlen(outFileName
) + 1);
1361 uprv_strcpy(outputFileName
,outFileName
);
1363 outputFileName
= uprv_malloc(sizeof(char)*uprv_strlen(srBundle
->fLocale
) + 1);
1364 uprv_memset(outputFileName
, 0, sizeof(char)*uprv_strlen(srBundle
->fLocale
) + 1);
1365 uprv_strcpy(outputFileName
,srBundle
->fLocale
);
1369 xmlfileName
= uprv_malloc(sizeof(char)*(uprv_strlen(outputDir
) + uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
) + 1) +1);
1370 uprv_memset(xmlfileName
, 0, sizeof(char)*(uprv_strlen(outputDir
)+ uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
) + 1) +1);
1372 xmlfileName
= uprv_malloc(sizeof(char)*(uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
)) +1);
1373 uprv_memset(xmlfileName
, 0, sizeof(char)*(uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
)) +1);
1377 uprv_strcpy(xmlfileName
, outputDir
);
1378 if(outputDir
[uprv_strlen(outputDir
)-1] !=U_FILE_SEP_CHAR
){
1379 uprv_strcat(xmlfileName
,U_FILE_SEP_STRING
);
1382 uprv_strcat(xmlfileName
,outputFileName
);
1383 uprv_strcat(xmlfileName
,xliffExt
);
1385 if (writtenFilename
) {
1386 uprv_strncpy(writtenFilename
, xmlfileName
, writtenFilenameLen
);
1389 if (U_FAILURE(*status
)) {
1393 out
= T_FileStream_open(xmlfileName
,"w");
1396 *status
= U_FILE_ACCESS_ERROR
;
1399 T_FileStream_write(out
,xmlHeader
, (int32_t)uprv_strlen(xmlHeader
));
1401 if(outputEnc
&& *outputEnc
!='\0'){
1402 /* store the output encoding */
1404 conv
=ucnv_open(enc
,status
);
1405 if(U_FAILURE(*status
)){
1409 T_FileStream_write(out
,bundleStart
, (int32_t)uprv_strlen(bundleStart
));
1411 T_FileStream_write(out
, fileStart
, (int32_t)uprv_strlen(fileStart
));
1412 /* check if lang and language are the same */
1413 if(language
!= NULL
&& uprv_strcmp(lang
, srBundle
->fLocale
)!=0){
1414 fprintf(stderr
,"Warning: The top level tag in the resource and language specified are not the same. Please check the input.\n");
1416 T_FileStream_write(out
,lang
, (int32_t)uprv_strlen(lang
));
1417 T_FileStream_write(out
,file1
, (int32_t)uprv_strlen(file1
));
1418 T_FileStream_write(out
,file2
, (int32_t)uprv_strlen(file2
));
1419 T_FileStream_write(out
,originalFileName
, (int32_t)uprv_strlen(originalFileName
));
1420 T_FileStream_write(out
,file3
, (int32_t)uprv_strlen(file3
));
1421 T_FileStream_write(out
,file4
, (int32_t)uprv_strlen(file4
));
1424 strftime(timeBuf
, sizeof(timeBuf
), "%Y-%m-%dT%H:%M:%SZ", gmtime(&currTime
));
1425 T_FileStream_write(out
,timeBuf
, (int32_t)uprv_strlen(timeBuf
));
1427 T_FileStream_write(out
,"\">\n", 3);
1431 T_FileStream_write(out
,headerStart
, (int32_t)uprv_strlen(headerStart
));
1432 T_FileStream_write(out
,headerEnd
, (int32_t)uprv_strlen(headerEnd
));
1435 T_FileStream_write(out
,bodyStart
, (int32_t)uprv_strlen(bodyStart
));
1438 res_write_xml(bundle
->fRoot
, srBundle
->fLocale
, lang
, status
);
1442 T_FileStream_write(out
,bodyEnd
, (int32_t)uprv_strlen(bodyEnd
));
1445 T_FileStream_write(out
,fileEnd
, (int32_t)uprv_strlen(fileEnd
));
1448 T_FileStream_write(out
,bundleEnd
,(int32_t)uprv_strlen(bundleEnd
));
1449 T_FileStream_close(out
);
1453 if(originalFileName
!= NULL
) {
1454 uprv_free(originalFileName
);
1455 originalFileName
= NULL
;
1465 if(xmlfileName
!= NULL
) {
1466 uprv_free(xmlfileName
);
1469 if(outputFileName
!= NULL
){
1470 uprv_free(outputFileName
);