2 *******************************************************************************
4 * Copyright (C) 2002-2006, 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 static void strnrepchr(char* src
, int32_t srcLen
, char s
, char r
){
128 for(i
=0;i
<srcLen
;i
++){
134 /* Parse the filename, and get its language information.
135 * If it fails to get the language information from the filename,
136 * use "en" as the default value for language
138 static char* parseFilename(const char* id
, char* lang
) {
139 int idLen
= uprv_strlen(id
);
140 char* localeID
= (char*) uprv_malloc(idLen
);
142 int canonCapacity
= 0;
146 UErrorCode status
= U_ZERO_ERROR
;
147 char *ext
= uprv_strchr(id
, '.');
153 uprv_memcpy(localeID
, id
, pos
);
154 localeID
[pos
]=0; /* NUL terminate the string */
156 canonCapacity
=pos
*3;
157 canon
= (char*) uprv_malloc(canonCapacity
);
158 canonLen
= uloc_canonicalize(localeID
, canon
, canonCapacity
, &status
);
160 if(U_FAILURE(status
)){
161 fprintf(stderr
, "Could not canonicalize the locale ID: %s. Error: %s\n", localeID
, u_errorName(status
));
164 strnrepchr(canon
, canonLen
, '_', '-');
168 static const char* xmlHeader
= "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
170 "SYSTEM \"http://www.oasis-open.org/committees/xliff/documents/xliff.dtd\">\n";
171 static const char* bundleStart
= "<xliff version = \"1.0\">\n";
172 static const char* bundleEnd
= "</xliff>\n";
174 void res_write_xml(struct SResource
*res
, const char* id
, const char* language
, UBool isTopLevel
, UErrorCode
*status
);
176 static char* convertAndEscape(char** pDest
, int32_t destCap
, int32_t* destLength
,
177 const UChar
* src
, int32_t srcLen
, UErrorCode
* status
){
184 if(status
==NULL
|| U_FAILURE(*status
) || pDest
==NULL
|| srcLen
==0 || src
== NULL
){
188 if(dest
==NULL
|| destCap
<=0){
189 destCap
= srcLen
* 8;
190 dest
= (char*) uprv_malloc(sizeof(char) * destCap
);
192 *status
=U_MEMORY_ALLOCATION_ERROR
;
199 while(srcIndex
<srcLen
){
200 U16_NEXT(src
, srcIndex
, srcLen
, c
);
202 if (U16_IS_LEAD(c
) || U16_IS_TRAIL(c
)) {
203 *status
= U_ILLEGAL_CHAR_FOUND
;
204 fprintf(stderr
, "Illegal Surrogate! \n");
209 if((destLen
+UTF8_CHAR_LENGTH(c
)) < destCap
){
215 uprv_strcpy(dest
+( destLen
),"&");
216 destLen
+=(int32_t)uprv_strlen("&");
219 uprv_strcpy(dest
+(destLen
),"<");
220 destLen
+=(int32_t)uprv_strlen("<");
223 uprv_strcpy(dest
+(destLen
),">");
224 destLen
+=(int32_t)uprv_strlen(">");
227 uprv_strcpy(dest
+(destLen
),""");
228 destLen
+=(int32_t)uprv_strlen(""");
231 uprv_strcpy(dest
+(destLen
),"'");
232 destLen
+=(int32_t)uprv_strlen("'");
235 /* Disallow C0 controls except TAB, CR, LF*/
268 *status
= U_ILLEGAL_CHAR_FOUND
;
269 fprintf(stderr
, "Illegal Character \\u%04X!\n",(int)c
);
273 dest
[destLen
++]=(char)c
;
276 UBool isError
= FALSE
;
277 U8_APPEND((unsigned char*)dest
,destLen
,destCap
,c
,isError
);
279 *status
= U_ILLEGAL_CHAR_FOUND
;
280 fprintf(stderr
, "Illegal Character \\U%08X!\n",(int)c
);
288 temp
= (char*) uprv_malloc(sizeof(char)*destCap
);
290 *status
=U_MEMORY_ALLOCATION_ERROR
;
294 uprv_memmove(temp
,dest
,destLen
);
302 *destLength
= destLen
;
306 #define ASTERISK 0x002A
310 #define AT_SIGN 0x0040
317 trim(char **src
, int32_t *len
){
321 if(src
== NULL
|| *src
== NULL
){
325 /* trim from the end */
326 for( i
=(*len
-1); i
>= 0; i
--){
344 print(UChar
* src
, int32_t srcLen
,const char *tagStart
,const char *tagEnd
, UErrorCode
*status
){
345 int32_t bufCapacity
= srcLen
*4;
349 if(U_FAILURE(*status
)){
353 buf
= (char*) (uprv_malloc(bufCapacity
));
355 fprintf(stderr
, "Could not allocate memory!!");
356 exit(U_MEMORY_ALLOCATION_ERROR
);
358 buf
= convertAndEscape(&buf
, bufCapacity
, &bufLen
, src
, srcLen
,status
);
359 if(U_SUCCESS(*status
)){
361 T_FileStream_write(out
,tagStart
, (int32_t)uprv_strlen(tagStart
));
362 T_FileStream_write(out
, buf
, bufLen
);
363 T_FileStream_write(out
,tagEnd
, (int32_t)uprv_strlen(tagEnd
));
364 T_FileStream_write(out
,"\n",1);
369 printNoteElements(struct UString
*src
, UErrorCode
*status
){
371 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
373 int32_t capacity
= 0;
382 capacity
= src
->fLength
;
383 note
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
385 count
= getCount(src
->fChars
,src
->fLength
, UPC_NOTE
, status
);
386 if(U_FAILURE(*status
)){
389 for(i
=0; i
< count
; i
++){
390 noteLen
= getAt(src
->fChars
,src
->fLength
, ¬e
, capacity
, i
, UPC_NOTE
, status
);
391 if(U_FAILURE(*status
)){
396 print(note
, noteLen
,"<note>", "</note>", status
);
402 fprintf(stderr
, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
404 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
409 printComments(struct UString
*src
, const char *resName
, UBool printTranslate
, UErrorCode
*status
){
411 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
413 int32_t capacity
= src
->fLength
;
416 const char* translateAttr
= " translate=\"";
417 UChar
* desc
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
418 UChar
* trans
= (UChar
*) uprv_malloc(U_SIZEOF_UCHAR
* capacity
);
420 int32_t descLen
= 0, transLen
=0;
421 if(status
==NULL
|| U_FAILURE(*status
)){
426 if(desc
==NULL
|| trans
==NULL
){
427 *status
= U_MEMORY_ALLOCATION_ERROR
;
432 src
->fLength
= removeCmtText(src
->fChars
, src
->fLength
, status
);
433 descLen
= getDescription(src
->fChars
,src
->fLength
, &desc
, capacity
, status
);
434 transLen
= getTranslate(src
->fChars
,src
->fLength
, &trans
, capacity
, status
);
436 /* first print translate attribute */
438 if(printTranslate
==TRUE
){
439 /* print translate attribute */
440 buf
= convertAndEscape(&buf
, 0, &bufLen
, trans
, transLen
, status
);
441 if(U_SUCCESS(*status
)){
442 T_FileStream_write(out
,translateAttr
, (int32_t)uprv_strlen(translateAttr
));
443 T_FileStream_write(out
,buf
, bufLen
);
444 T_FileStream_write(out
,"\">\n", 3);
446 }else if(getShowWarning() == TRUE
){
447 fprintf(stderr
, "Warning: Tranlate attribute for resource %s cannot be set. XLIFF prohibits it.\n", resName
);
448 /* no translate attribute .. just close the tag */
449 T_FileStream_write(out
,">\n", 2);
452 /* no translate attribute .. just close the tag */
453 T_FileStream_write(out
,">\n", 2);
457 print(desc
, descLen
, "<!--", "-->", status
);
461 fprintf(stderr
, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
463 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
466 /* Writing Functions */
468 string_write_xml(struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
474 const char* strStart
= "<trans-unit xml:space = \"preserve\" id = \"";
475 const char* valStrStart
= "<source ";
476 const char* valStrEnd
= "</source>\n";
477 const char* strEnd
= "</trans-unit>\n";
479 if(status
==NULL
|| U_FAILURE(*status
)){
483 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
485 T_FileStream_write(out
,strStart
, (int32_t)uprv_strlen(strStart
));
486 sid
= getID(id
, NULL
, sid
);
487 T_FileStream_write(out
,sid
, (int32_t)uprv_strlen(sid
));
488 T_FileStream_write(out
,"\"", 1);
490 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
491 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, TRUE
, status
);
494 T_FileStream_write(out
,">\n", 2);
499 T_FileStream_write(out
,valStrStart
, (int32_t)uprv_strlen(valStrStart
));
500 /* T_FileStream_write(out,language, (int32_t)uprv_strlen(language)); */
501 T_FileStream_write(out
,">", 1);
503 buf
= convertAndEscape(&buf
,0,&bufLen
,res
->u
.fString
.fChars
,res
->u
.fString
.fLength
,status
);
505 if(U_FAILURE(*status
)){
509 T_FileStream_write(out
,buf
,bufLen
);
510 T_FileStream_write(out
,valStrEnd
,(int32_t)uprv_strlen(valStrEnd
));
512 printNoteElements(res
->fComment
, status
);
516 T_FileStream_write(out
,strEnd
,(int32_t)uprv_strlen(strEnd
));
518 const char* keyStrStart
= "resname = \"";
522 T_FileStream_write(out
, strStart
, (int32_t)uprv_strlen(strStart
));
523 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
,sid
);
524 T_FileStream_write(out
,sid
, (int32_t)uprv_strlen(sid
));
525 T_FileStream_write(out
,"\" ", 2);
526 T_FileStream_write(out
,keyStrStart
, (int32_t)uprv_strlen(keyStrStart
));
528 T_FileStream_write(out
,srBundle
->fKeys
+res
->fKey
, (int32_t)uprv_strlen(srBundle
->fKeys
+res
->fKey
));
529 T_FileStream_write(out
,"\"", 1);
531 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
532 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, TRUE
, status
);
534 T_FileStream_write(out
,">\n", 2);
538 T_FileStream_write(out
,valStrStart
, (int32_t)uprv_strlen(valStrStart
));
540 /*T_FileStream_write(out,language, (int32_t)uprv_strlen(language));*/
541 T_FileStream_write(out
,">", 1);
543 buf
= convertAndEscape(&buf
,0,&bufLen
,res
->u
.fString
.fChars
,res
->u
.fString
.fLength
,status
);
544 if(U_FAILURE(*status
)){
547 T_FileStream_write(out
,buf
,bufLen
);
549 T_FileStream_write(out
,valStrEnd
,(int32_t)uprv_strlen(valStrEnd
));
551 printNoteElements(res
->fComment
, status
);
555 T_FileStream_write(out
,strEnd
,(int32_t)uprv_strlen(strEnd
));
565 alias_write_xml(struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
566 static const char* startKey
= "resname=\"";
567 static const char* val
= "<source>";
568 static const char* endKey
= "</source>\n";
569 static const char* start
= "<trans-unit restype = \"alias\" xml:space = \"preserve\" id = \"";
570 static const char* end
= "</trans-unit>\n";
576 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
577 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
579 sid
= getID(id
, NULL
, sid
);
580 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
581 T_FileStream_write(out
, "\"", 1);
583 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
584 printComments(res
->fComment
,srBundle
->fKeys
+res
->fKey
, TRUE
, status
);
587 T_FileStream_write(out
,">\n", 2);
590 T_FileStream_write(out
, val
, (int32_t)uprv_strlen(val
));
592 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
593 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
594 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
595 T_FileStream_write(out
, "\" ", 2);
596 T_FileStream_write(out
, startKey
, (int32_t)uprv_strlen(startKey
));
597 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
599 T_FileStream_write(out
, "\"", 1);
601 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
602 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, TRUE
, status
);
605 T_FileStream_write(out
,">\n", 2);
610 T_FileStream_write(out
, val
, (int32_t)uprv_strlen(val
));
613 buf
= convertAndEscape(&buf
,0,&bufLen
,res
->u
.fString
.fChars
,res
->u
.fString
.fLength
,/*FALSE,*/status
);
614 if(U_FAILURE(*status
)){
617 T_FileStream_write(out
,buf
,bufLen
);
618 T_FileStream_write(out
, endKey
, (int32_t)uprv_strlen(endKey
));
620 printNoteElements(res
->fComment
, status
);
625 T_FileStream_write(out
, end
, (int32_t)uprv_strlen(end
));
631 array_write_xml( struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
632 const char* start
= "<group restype = \"array\" xml:space = \"preserve\" id = \"";
633 const char* end
= "</group>\n";
634 const char* startKey
= "resname=\"";
639 struct SResource
*current
= NULL
;
640 struct SResource
*first
=NULL
;
644 if(res
->fKey
<0 ||uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
645 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
646 sid
= getID(id
, NULL
, sid
);
647 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
648 T_FileStream_write(out
, "\"", 1);
649 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
650 printComments(res
->fComment
, sid
, FALSE
, status
);
651 printNoteElements(res
->fComment
, status
);
653 T_FileStream_write(out
,">\n", 2);
656 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
657 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
658 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
659 T_FileStream_write(out
, "\" ", 2);
660 T_FileStream_write(out
, startKey
, (int32_t)uprv_strlen(startKey
));
661 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
662 T_FileStream_write(out
, "\"", 1);
663 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
664 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, FALSE
, status
);
665 printNoteElements(res
->fComment
, status
);
667 T_FileStream_write(out
,">\n", 2);
670 current
= res
->u
.fArray
.fFirst
;
673 while (current
!= NULL
) {
676 itostr(c
, index
,10,0);
678 subId
= getID(sid
, c
, subId
);
680 res_write_xml(current
, subId
, language
, FALSE
, status
);
683 if(U_FAILURE(*status
)){
686 current
= current
->fNext
;
690 T_FileStream_write(out
,end
,(int32_t)uprv_strlen(end
));
696 intvector_write_xml( struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
697 const char* start
= "<group restype = \"intvector\" xml:space = \"preserve\" id = \"";
698 const char* end
= "</group>\n";
699 const char* startKey
= "resname=\"";
701 const char* intStart
= "<trans-unit restype = \"int\" xml:space = \"preserve\" id = \"";
702 const char* valIntStart
= "<source>";
703 const char* valIntEnd
= "</source>\n";
704 const char* intEnd
= "</trans-unit>\n";
710 char buf
[256] = {'0'};
714 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
715 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
716 sid
= getID(id
, NULL
, sid
);
717 T_FileStream_write(out
,sid
, (int32_t)uprv_strlen(sid
));
718 T_FileStream_write(out
, "\"", 1);
719 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
720 printComments(res
->fComment
, sid
, FALSE
, status
);
723 T_FileStream_write(out
,">\n", 2);
726 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
727 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
728 T_FileStream_write(out
,sid
, (int32_t)uprv_strlen(sid
));
729 T_FileStream_write(out
,"\" ", 2);
731 T_FileStream_write(out
, startKey
, (int32_t)uprv_strlen(startKey
));
732 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
733 T_FileStream_write(out
, "\"", 1);
734 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
735 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, FALSE
, status
);
736 printNoteElements(res
->fComment
, status
);
738 T_FileStream_write(out
,">\n", 2);
743 for(i
= 0; i
<res
->u
.fIntVector
.fCount
; i
++) {
746 ivd
= getID(sid
, c
, ivd
);
747 len
=itostr(buf
,res
->u
.fIntVector
.fArray
[i
],10,0);
750 T_FileStream_write(out
, intStart
, (int32_t)uprv_strlen(intStart
));
751 T_FileStream_write(out
, ivd
, (int32_t)uprv_strlen(ivd
));
752 T_FileStream_write(out
,"\">\n", 3);
755 T_FileStream_write(out
,valIntStart
, (int32_t)uprv_strlen(valIntStart
));
757 T_FileStream_write(out
,buf
,len
);
759 T_FileStream_write(out
,valIntEnd
, (int32_t)uprv_strlen(valIntEnd
));
762 T_FileStream_write(out
, intEnd
, (int32_t)uprv_strlen(intEnd
));
771 T_FileStream_write(out
, end
, (int32_t)uprv_strlen(end
));
777 int_write_xml(struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
778 const char* intStart
= "<trans-unit restype = \"int\" xml:space = \"preserve\" id = \"";
779 const char* valIntStart
= "<source>";
780 const char* valIntEnd
= "</source>\n";
781 const char* intEnd
= "</trans-unit>\n";
782 const char* keyIntStart
= "resname = \"";
791 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
792 T_FileStream_write(out
, intStart
, (int32_t)uprv_strlen(intStart
));
793 sid
= getID(id
, NULL
, sid
);
794 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
795 T_FileStream_write(out
,"\"", 1);
797 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
798 printComments(res
->fComment
, sid
, TRUE
, status
);
801 T_FileStream_write(out
,">\n", 2);
804 T_FileStream_write(out
,valIntStart
, (int32_t)uprv_strlen(valIntStart
));
806 T_FileStream_write(out
, intStart
, (int32_t)uprv_strlen(intStart
));
807 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
808 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
809 T_FileStream_write(out
,"\" ", 2);
810 T_FileStream_write(out
,keyIntStart
, (int32_t)uprv_strlen(keyIntStart
));
812 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
813 T_FileStream_write(out
,"\"", 1);
815 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
816 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, TRUE
, status
);
819 T_FileStream_write(out
,">\n", 2);
822 T_FileStream_write(out
, valIntStart
, (int32_t)uprv_strlen(valIntStart
));
825 len
=itostr(buf
,res
->u
.fIntValue
.fValue
,10,0);
826 T_FileStream_write(out
,buf
,len
);
828 T_FileStream_write(out
, valIntEnd
, (int32_t)uprv_strlen(valIntEnd
));
829 printNoteElements(res
->fComment
, status
);
832 T_FileStream_write(out
, intEnd
, (int32_t)uprv_strlen(intEnd
));
838 bin_write_xml( struct SResource
*res
, const char* id
, const char* language
, UErrorCode
*status
) {
839 const char* start
= "<bin-unit restype = \"bin\" id = \"";
840 const char* importStart
= "<bin-unit restype = \"import\" id = \"";
841 const char* mime
= " mime-type = ";
842 const char* key
= "\" resname = \"";
843 const char* valStart
= "<bin-source>\n";
844 const char* fileStart
= "<internal-file form = \"application\" crc = \"";
845 const char* fileEnd
= "</internal-file>\n";
846 const char* valEnd
= "</bin-source>\n";
847 const char* end
= "</bin-unit>\n";
848 const char* externalFileStart
= "<external-file href = \"";
849 const char* externalFileEnd
= "\"/>\n";
850 const char* m_type
= "\"application";
852 uint32_t crc
= 0xFFFFFFFF;
854 char fileName
[1024] ={0};
855 int32_t tLen
= ( outDir
== NULL
) ? 0 :(int32_t)uprv_strlen(outDir
);
856 char* fn
= (char*) uprv_malloc(sizeof(char) * (tLen
+1024 +
857 (res
->u
.fBinaryValue
.fFileName
!=NULL
?
858 uprv_strlen(res
->u
.fBinaryValue
.fFileName
) :0)));
859 const char* ext
= NULL
;
865 if(res
->u
.fBinaryValue
.fFileName
!=NULL
){
866 uprv_strcpy(fileName
, res
->u
.fBinaryValue
.fFileName
);
867 f
= uprv_strrchr(fileName
, '\\');
874 ext
= uprv_strrchr(fileName
, '.');
877 fprintf(stderr
, "Error: %s is an unknown binary filename type.\n", fileName
);
878 exit(U_ILLEGAL_ARGUMENT_ERROR
);
880 if(uprv_strcmp(ext
, ".jpg")==0 || uprv_strcmp(ext
, ".jpeg")==0 || uprv_strcmp(ext
, ".gif")==0 ){
882 } else if(uprv_strcmp(ext
, ".wav")==0 || uprv_strcmp(ext
, ".au")==0 ){
884 } else if(uprv_strcmp(ext
, ".avi")==0 || uprv_strcmp(ext
, ".mpg")==0 || uprv_strcmp(ext
, ".mpeg")==0){
886 } else if(uprv_strcmp(ext
, ".txt")==0 || uprv_strcmp(ext
, ".text")==0){
891 T_FileStream_write(out
, importStart
, (int32_t)uprv_strlen(importStart
));
892 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
893 sid
= getID(id
, NULL
, sid
);
894 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
896 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
897 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
899 T_FileStream_write(out
, "\" ", 2);
900 T_FileStream_write(out
, mime
, (int32_t)uprv_strlen(mime
));
901 T_FileStream_write(out
, m_type
, (int32_t)uprv_strlen(m_type
));
902 if(!(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0)){
903 T_FileStream_write(out
, key
, (int32_t)uprv_strlen(key
));
904 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
906 T_FileStream_write(out
,"\"", 1);
908 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
909 printComments(res
->fComment
, sid
, TRUE
, status
);
912 T_FileStream_write(out
,">\n", 2);
917 T_FileStream_write(out
, valStart
, (int32_t)uprv_strlen(valStart
));
920 T_FileStream_write(out
, externalFileStart
, (int32_t)uprv_strlen(externalFileStart
));
921 T_FileStream_write(out
, f
, (int32_t)uprv_strlen(f
));
922 T_FileStream_write(out
, externalFileEnd
, (int32_t)uprv_strlen(externalFileEnd
));
925 T_FileStream_write(out
, valEnd
, (int32_t)uprv_strlen(valEnd
));
927 printNoteElements(res
->fComment
, status
);
930 T_FileStream_write(out
,end
,(int32_t)uprv_strlen(end
));
932 char temp
[256] = {0};
937 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
938 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
939 sid
= getID(id
, NULL
, sid
);
940 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
942 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
943 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
946 T_FileStream_write(out
, "\" ", 2);
947 T_FileStream_write(out
, mime
, (int32_t)uprv_strlen(mime
));
948 T_FileStream_write(out
, m_type
, (int32_t)uprv_strlen(m_type
));
949 if(!(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0)){
950 T_FileStream_write(out
, key
, (int32_t)uprv_strlen(key
));
951 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
953 T_FileStream_write(out
,"\"", 1);
955 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
956 printComments(res
->fComment
, sid
, TRUE
, status
);
959 T_FileStream_write(out
,">\n", 2);
963 T_FileStream_write(out
, valStart
, (int32_t)uprv_strlen(valStart
));
966 T_FileStream_write(out
, fileStart
, (int32_t)uprv_strlen(fileStart
));
968 while(i
<res
->u
.fBinaryValue
.fLength
){
969 len
= itostr(temp
,res
->u
.fBinaryValue
.fData
[i
],16,2);
970 crc
= computeCRC(temp
, len
, crc
);
974 len
= itostr(temp
, crc
, 10, 0);
975 T_FileStream_write(out
,temp
,len
);
976 T_FileStream_write(out
,"\">",2);
979 while(i
<res
->u
.fBinaryValue
.fLength
){
980 len
= itostr(temp
,res
->u
.fBinaryValue
.fData
[i
],16,2);
981 T_FileStream_write(out
,temp
,len
);
984 T_FileStream_write(out
, fileEnd
, (int32_t)uprv_strlen(fileEnd
));
987 T_FileStream_write(out
, valEnd
, (int32_t)uprv_strlen(valEnd
));
988 printNoteElements(res
->fComment
, status
);
992 T_FileStream_write(out
,end
,(int32_t)uprv_strlen(end
));
1003 table_write_xml(struct SResource
*res
, const char* id
, const char* language
, UBool isTopLevel
, UErrorCode
*status
) {
1007 struct SResource
*current
= NULL
;
1008 struct SResource
*save
= NULL
;
1011 const char* start
= "<group restype = \"table\" xml:space = \"preserve\"";
1012 const char* idstr
= " id = \"";
1013 const char* end
= "</group>\n";
1014 const char* startKey
= "resname=\"";
1016 if (U_FAILURE(*status
)) {
1020 if (res
->u
.fTable
.fCount
> 0) {
1024 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
1025 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
1028 int32_t len
= uprv_strlen(id
);
1029 T_FileStream_write(out
, idstr
, (int32_t)uprv_strlen(idstr
));
1030 T_FileStream_write(out
, id
,len
);
1031 T_FileStream_write(out
, "\" ", 2);
1034 sid
= getID(id
, NULL
, sid
);
1035 /* only write the id if the sid!="" */
1037 T_FileStream_write(out
, idstr
, (int32_t)uprv_strlen(idstr
));
1038 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1039 T_FileStream_write(out
, "\" ", 2);
1044 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
1045 printComments(res
->fComment
, sid
, FALSE
, status
);
1046 printNoteElements(res
->fComment
, status
);
1048 T_FileStream_write(out
,">\n", 2);
1051 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
1052 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
1054 /* only write the id if the sid!="" */
1056 T_FileStream_write(out
, idstr
, (int32_t)uprv_strlen(idstr
));
1057 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1058 T_FileStream_write(out
, "\" ", 2);
1061 T_FileStream_write(out
, startKey
, (int32_t)uprv_strlen(startKey
));
1062 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
1063 T_FileStream_write(out
, "\" ", 2);
1065 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
1066 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, FALSE
, status
);
1067 printNoteElements(res
->fComment
, status
);
1069 T_FileStream_write(out
,">\n", 2);
1073 save
= current
= res
->u
.fTable
.fFirst
;
1075 while (current
!= NULL
) {
1076 res_write_xml(current
, sid
, language
, FALSE
, status
);
1078 if(U_FAILURE(*status
)){
1082 current
= current
->fNext
;
1086 T_FileStream_write(out
,end
,(int32_t)uprv_strlen(end
));
1089 if(res
->fKey
<0 || uprv_strcmp(srBundle
->fKeys
+res
->fKey
,"")==0){
1090 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
1091 sid
= getID(id
, NULL
, sid
);
1092 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1093 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
1094 printComments(res
->fComment
, sid
, FALSE
, status
);
1095 printNoteElements(res
->fComment
, status
);
1097 T_FileStream_write(out
,">\n", 2);
1100 T_FileStream_write(out
, start
, (int32_t)uprv_strlen(start
));
1101 sid
= getID(id
, srBundle
->fKeys
+res
->fKey
, sid
);
1102 T_FileStream_write(out
, sid
, (int32_t)uprv_strlen(sid
));
1103 T_FileStream_write(out
, "\" ", 2);
1104 T_FileStream_write(out
, startKey
, (int32_t)uprv_strlen(startKey
));
1105 T_FileStream_write(out
, srBundle
->fKeys
+res
->fKey
, (int32_t) uprv_strlen(srBundle
->fKeys
+res
->fKey
));
1107 if(res
->fComment
!=NULL
&& res
->fComment
->fChars
!= NULL
){
1108 printComments(res
->fComment
, srBundle
->fKeys
+res
->fKey
, FALSE
, status
);
1109 printNoteElements(res
->fComment
, status
);
1111 T_FileStream_write(out
,">\n", 2);
1116 T_FileStream_write(out
,end
,(int32_t)uprv_strlen(end
));
1123 res_write_xml(struct SResource
*res
, const char* id
, const char* language
, UBool isTopLevel
, UErrorCode
*status
) {
1125 if (U_FAILURE(*status
)) {
1130 switch (res
->fType
) {
1132 string_write_xml (res
, id
, language
, status
);
1135 alias_write_xml (res
, id
, language
, status
);
1137 case URES_INT_VECTOR
:
1138 intvector_write_xml (res
, id
, language
, status
);
1141 bin_write_xml (res
, id
, language
, status
);
1144 int_write_xml (res
, id
, language
, status
);
1147 array_write_xml (res
, id
, language
, status
);
1151 table_write_xml (res
, id
, language
, isTopLevel
, status
);
1159 *status
= U_INTERNAL_PROGRAM_ERROR
;
1163 bundle_write_xml(struct SRBRoot
*bundle
, const char *outputDir
,const char* outputEnc
, const char* filename
,
1164 char *writtenFilename
, int writtenFilenameLen
,
1165 const char* language
, const char* outFileName
, UErrorCode
*status
) {
1167 char* xmlfileName
= NULL
;
1168 char* outputFileName
= NULL
;
1169 char* originalFileName
= NULL
;
1170 const char* fileStart
= "<file xml:space = \"preserve\" source-language = \"";
1171 const char* file1
= "\" datatype = \"ICUResourceBundle\" ";
1172 const char* file2
= "original = \"";
1173 const char* file3
= "\" tool = \"genrb\" ";
1174 const char* file4
= "date = \"";
1175 const char* fileEnd
= "</file>\n";
1176 const char* headerStart
= "<header>";
1177 const char* headerEnd
= "</header>\n";
1178 const char* bodyStart
= "<body>\n";
1179 const char* bodyEnd
= "</body>\n";
1185 int32_t first
, index
;
1193 pos
= uprv_strrchr(filename
, '\\');
1195 first
= (int32_t)(pos
- filename
+ 1);
1199 index
= (int32_t)(uprv_strlen(filename
) - uprv_strlen(textExt
) - first
);
1200 originalFileName
= uprv_malloc(sizeof(char)*index
+1);
1201 uprv_memset(originalFileName
, 0, sizeof(char)*index
+1);
1202 uprv_strncpy(originalFileName
, filename
+ first
, index
);
1204 if(uprv_strcmp(originalFileName
, srBundle
->fLocale
) != 0) {
1205 fprintf(stdout
, "Warning: The file name is not same as the resource name!\n");
1208 temp
= originalFileName
;
1209 originalFileName
= uprv_malloc(sizeof(char)* (uprv_strlen(temp
)+uprv_strlen(textExt
)) + 1);
1210 uprv_memset(originalFileName
, 0, sizeof(char)* (uprv_strlen(temp
)+uprv_strlen(textExt
)) + 1);
1211 uprv_strcat(originalFileName
, temp
);
1212 uprv_strcat(originalFileName
, textExt
);
1217 if (language
== NULL
) {
1218 /* lang = parseFilename(filename, lang);
1219 if (lang == NULL) {*/
1220 /* now check if locale name is valid or not
1221 * this is to cater for situation where
1222 * pegasusServer.txt contains
1228 lang
= parseFilename(srBundle
->fLocale
, lang
);
1230 * Neither the file name nor the table name inside the
1231 * txt file contain a valid country and language codes
1233 * pegasusServer.txt contains
1240 fprintf(stderr
, "Error: The file name and table name do not contain a valid language code. Please use -l option to specify it.\n");
1241 exit(U_ILLEGAL_ARGUMENT_ERROR
);
1245 lang
= uprv_malloc(sizeof(char)*uprv_strlen(language
) +1);
1246 uprv_memset(lang
, 0, sizeof(char)*uprv_strlen(language
) +1);
1247 uprv_strcpy(lang
, language
);
1251 outputFileName
= uprv_malloc(sizeof(char)*uprv_strlen(outFileName
) + 1);
1252 uprv_memset(outputFileName
, 0, sizeof(char)*uprv_strlen(outFileName
) + 1);
1253 uprv_strcpy(outputFileName
,outFileName
);
1255 outputFileName
= uprv_malloc(sizeof(char)*uprv_strlen(srBundle
->fLocale
) + 1);
1256 uprv_memset(outputFileName
, 0, sizeof(char)*uprv_strlen(srBundle
->fLocale
) + 1);
1257 uprv_strcpy(outputFileName
,srBundle
->fLocale
);
1261 xmlfileName
= uprv_malloc(sizeof(char)*(uprv_strlen(outputDir
) + uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
) + 1) +1);
1262 uprv_memset(xmlfileName
, 0, sizeof(char)*(uprv_strlen(outputDir
)+ uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
) + 1) +1);
1264 xmlfileName
= uprv_malloc(sizeof(char)*(uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
)) +1);
1265 uprv_memset(xmlfileName
, 0, sizeof(char)*(uprv_strlen(outputFileName
) + uprv_strlen(xliffExt
)) +1);
1269 uprv_strcpy(xmlfileName
, outputDir
);
1270 if(outputDir
[uprv_strlen(outputDir
)-1] !=U_FILE_SEP_CHAR
){
1271 uprv_strcat(xmlfileName
,U_FILE_SEP_STRING
);
1274 uprv_strcat(xmlfileName
,outputFileName
);
1275 uprv_strcat(xmlfileName
,xliffExt
);
1277 if (writtenFilename
) {
1278 uprv_strncpy(writtenFilename
, xmlfileName
, writtenFilenameLen
);
1281 if (U_FAILURE(*status
)) {
1282 goto cleanup_bundle_write_xml
;
1285 out
= T_FileStream_open(xmlfileName
,"w");
1288 *status
= U_FILE_ACCESS_ERROR
;
1289 goto cleanup_bundle_write_xml
;
1291 T_FileStream_write(out
,xmlHeader
, (int32_t)uprv_strlen(xmlHeader
));
1293 if(outputEnc
&& *outputEnc
!='\0'){
1294 /* store the output encoding */
1296 conv
=ucnv_open(enc
,status
);
1297 if(U_FAILURE(*status
)){
1298 goto cleanup_bundle_write_xml
;
1301 T_FileStream_write(out
,bundleStart
, (int32_t)uprv_strlen(bundleStart
));
1303 T_FileStream_write(out
, fileStart
, (int32_t)uprv_strlen(fileStart
));
1304 /* check if lang and language are the same */
1305 if(language
!= NULL
&& uprv_strcmp(lang
, srBundle
->fLocale
)!=0){
1306 fprintf(stderr
,"Warning: The top level tag in the resource and language specified are not the same. Please check the input.\n");
1308 T_FileStream_write(out
,lang
, (int32_t)uprv_strlen(lang
));
1309 T_FileStream_write(out
,file1
, (int32_t)uprv_strlen(file1
));
1310 T_FileStream_write(out
,file2
, (int32_t)uprv_strlen(file2
));
1311 T_FileStream_write(out
,originalFileName
, (int32_t)uprv_strlen(originalFileName
));
1312 T_FileStream_write(out
,file3
, (int32_t)uprv_strlen(file3
));
1313 T_FileStream_write(out
,file4
, (int32_t)uprv_strlen(file4
));
1316 strftime(timeBuf
, sizeof(timeBuf
), "%Y-%m-%dT%H:%M:%SZ", gmtime(&currTime
));
1317 T_FileStream_write(out
,timeBuf
, (int32_t)uprv_strlen(timeBuf
));
1319 T_FileStream_write(out
,"\">\n", 3);
1323 T_FileStream_write(out
,headerStart
, (int32_t)uprv_strlen(headerStart
));
1324 T_FileStream_write(out
,headerEnd
, (int32_t)uprv_strlen(headerEnd
));
1327 T_FileStream_write(out
,bodyStart
, (int32_t)uprv_strlen(bodyStart
));
1330 res_write_xml(bundle
->fRoot
, bundle
->fLocale
, lang
, TRUE
, status
);
1334 T_FileStream_write(out
,bodyEnd
, (int32_t)uprv_strlen(bodyEnd
));
1337 T_FileStream_write(out
,fileEnd
, (int32_t)uprv_strlen(fileEnd
));
1340 T_FileStream_write(out
,bundleEnd
,(int32_t)uprv_strlen(bundleEnd
));
1341 T_FileStream_close(out
);
1345 cleanup_bundle_write_xml
:
1346 if(originalFileName
!= NULL
) {
1347 uprv_free(originalFileName
);
1348 originalFileName
= NULL
;
1358 if(xmlfileName
!= NULL
) {
1359 uprv_free(xmlfileName
);
1362 if(outputFileName
!= NULL
){
1363 uprv_free(outputFileName
);