]> git.saurik.com Git - apple/icu.git/blob - icuSources/tools/genrb/wrtxml.c
ICU-8.11.1.tar.gz
[apple/icu.git] / icuSources / tools / genrb / wrtxml.c
1 /*
2 *******************************************************************************
3 *
4 * Copyright (C) 2002-2006, International Business Machines
5 * Corporation and others. All Rights Reserved.
6 *
7 *******************************************************************************
8 *
9 * File wrtxml.c
10 *
11 * Modification History:
12 *
13 * Date Name Description
14 * 10/01/02 Ram Creation.
15 *******************************************************************************
16 */
17 #include "reslist.h"
18 #include "unewdata.h"
19 #include "unicode/ures.h"
20 #include "errmsg.h"
21 #include "filestrm.h"
22 #include "cstring.h"
23 #include "unicode/ucnv.h"
24 #include "genrb.h"
25 #include "rle.h"
26 #include "ucol_tok.h"
27 #include "uhash.h"
28 #include "uresimp.h"
29 #include "unicode/ustring.h"
30 #include "unicode/uchar.h"
31 #include "ustr.h"
32 #include "prscmnts.h"
33 #include <time.h>
34
35 static int tabCount = 0;
36
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;
42
43 const char* const* ISOLanguages;
44 const char* const* ISOCountries;
45 const char* textExt = ".txt";
46 const char* xliffExt = ".xlf";
47
48 /*write indentation for formatting*/
49 static void write_tabs(FileStream* os){
50 int i=0;
51 for(;i<=tabCount;i++){
52 T_FileStream_write(os," ",4);
53 }
54 }
55
56 /*get ID for each element. ID is globally unique.*/
57 static char* getID(const char* id, char* curKey, char* result) {
58 if(curKey == NULL) {
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);
62 } else {
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);
65 if(id[0]!='\0'){
66 uprv_strcpy(result, id);
67 uprv_strcat(result, "_");
68 }
69 uprv_strcat(result, curKey);
70 }
71 return result;
72 }
73
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
81 *
82 * @author Michael Lecuyer (mjl@theorem.com)
83 * @version 1.1 August 11, 1998
84 */
85
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.
89 */
90
91 static uint32_t computeCRC(char *ptr, uint32_t len, uint32_t lastcrc){
92 int32_t crc;
93 uint32_t temp1;
94 uint32_t temp2;
95
96 int32_t crc_ta[256];
97 int i = 0;
98 int j = 0;
99 uint32_t crc2 = 0;
100
101 #define CRC32_POLYNOMIAL 0xEDB88320
102
103 /*build crc table*/
104 for (i = 0; i <= 255; i++) {
105 crc2 = i;
106 for (j = 8; j > 0; j--) {
107 if ((crc2 & 1) == 1) {
108 crc2 = (crc2 >> 1) ^ CRC32_POLYNOMIAL;
109 } else {
110 crc2 >>= 1;
111 }
112 }
113 crc_ta[i] = crc2;
114 }
115
116 crc = lastcrc;
117 while(len--!=0) {
118 temp1 = (uint32_t)crc>>8;
119 temp2 = crc_ta[(crc^*ptr) & 0xFF];
120 crc = temp1^temp2;
121 ptr++;
122 }
123 return(crc);
124 }
125
126 static void strnrepchr(char* src, int32_t srcLen, char s, char r){
127 int32_t i = 0;
128 for(i=0;i<srcLen;i++){
129 if(src[i]==s){
130 src[i]=r;
131 }
132 }
133 }
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
137 */
138 static char* parseFilename(const char* id, char* lang) {
139 int idLen = uprv_strlen(id);
140 char* localeID = (char*) uprv_malloc(idLen);
141 int pos = 0;
142 int canonCapacity = 0;
143 char* canon = NULL;
144 int canonLen = 0;
145 /*int i;*/
146 UErrorCode status = U_ZERO_ERROR;
147 char *ext = uprv_strchr(id, '.');
148 if(ext!=NULL){
149 pos = ext-id;
150 }else{
151 pos = idLen;
152 }
153 uprv_memcpy(localeID, id, pos);
154 localeID[pos]=0; /* NUL terminate the string */
155
156 canonCapacity =pos*3;
157 canon = (char*) uprv_malloc(canonCapacity);
158 canonLen = uloc_canonicalize(localeID, canon, canonCapacity, &status);
159
160 if(U_FAILURE(status)){
161 fprintf(stderr, "Could not canonicalize the locale ID: %s. Error: %s\n", localeID, u_errorName(status));
162 exit(status);
163 }
164 strnrepchr(canon, canonLen, '_', '-');
165 return canon;
166 }
167
168 static const char* xmlHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
169 "<!DOCTYPE xliff "
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";
173
174 void res_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status);
175
176 static char* convertAndEscape(char** pDest, int32_t destCap, int32_t* destLength,
177 const UChar* src, int32_t srcLen, UErrorCode* status){
178 int32_t srcIndex=0;
179 char* dest=NULL;
180 char* temp=NULL;
181 int32_t destLen=0;
182 UChar32 c = 0;
183
184 if(status==NULL || U_FAILURE(*status) || pDest==NULL || srcLen==0 || src == NULL){
185 return NULL;
186 }
187 dest =*pDest;
188 if(dest==NULL || destCap <=0){
189 destCap = srcLen * 8;
190 dest = (char*) uprv_malloc(sizeof(char) * destCap);
191 if(dest==NULL){
192 *status=U_MEMORY_ALLOCATION_ERROR;
193 return NULL;
194 }
195 }
196
197 dest[0]=0;
198
199 while(srcIndex<srcLen){
200 U16_NEXT(src, srcIndex, srcLen, c);
201
202 if (U16_IS_LEAD(c) || U16_IS_TRAIL(c)) {
203 *status = U_ILLEGAL_CHAR_FOUND;
204 fprintf(stderr, "Illegal Surrogate! \n");
205 uprv_free(dest);
206 return NULL;
207 }
208
209 if((destLen+UTF8_CHAR_LENGTH(c)) < destCap){
210
211 /* ASCII Range */
212 if(c <=0x007F){
213 switch(c) {
214 case '&':
215 uprv_strcpy(dest+( destLen),"&amp;");
216 destLen+=(int32_t)uprv_strlen("&amp;");
217 break;
218 case '<':
219 uprv_strcpy(dest+(destLen),"&lt;");
220 destLen+=(int32_t)uprv_strlen("&lt;");
221 break;
222 case '>':
223 uprv_strcpy(dest+(destLen),"&gt;");
224 destLen+=(int32_t)uprv_strlen("&gt;");
225 break;
226 case '"':
227 uprv_strcpy(dest+(destLen),"&quot;");
228 destLen+=(int32_t)uprv_strlen("&quot;");
229 break;
230 case '\'':
231 uprv_strcpy(dest+(destLen),"&apos;");
232 destLen+=(int32_t)uprv_strlen("&apos;");
233 break;
234
235 /* Disallow C0 controls except TAB, CR, LF*/
236 case 0x00:
237 case 0x01:
238 case 0x02:
239 case 0x03:
240 case 0x04:
241 case 0x05:
242 case 0x06:
243 case 0x07:
244 case 0x08:
245 /*case 0x09:*/
246 /*case 0x0A: */
247 case 0x0B:
248 case 0x0C:
249 /*case 0x0D:*/
250 case 0x0E:
251 case 0x0F:
252 case 0x10:
253 case 0x11:
254 case 0x12:
255 case 0x13:
256 case 0x14:
257 case 0x15:
258 case 0x16:
259 case 0x17:
260 case 0x18:
261 case 0x19:
262 case 0x1A:
263 case 0x1B:
264 case 0x1C:
265 case 0x1D:
266 case 0x1E:
267 case 0x1F:
268 *status = U_ILLEGAL_CHAR_FOUND;
269 fprintf(stderr, "Illegal Character \\u%04X!\n",(int)c);
270 uprv_free(dest);
271 return NULL;
272 default:
273 dest[destLen++]=(char)c;
274 }
275 }else{
276 UBool isError = FALSE;
277 U8_APPEND((unsigned char*)dest,destLen,destCap,c,isError);
278 if(isError){
279 *status = U_ILLEGAL_CHAR_FOUND;
280 fprintf(stderr, "Illegal Character \\U%08X!\n",(int)c);
281 uprv_free(dest);
282 return NULL;
283 }
284 }
285 }else{
286 destCap += destLen;
287
288 temp = (char*) uprv_malloc(sizeof(char)*destCap);
289 if(temp==NULL){
290 *status=U_MEMORY_ALLOCATION_ERROR;
291 uprv_free(dest);
292 return NULL;
293 }
294 uprv_memmove(temp,dest,destLen);
295 destLen=0;
296 uprv_free(dest);
297 dest=temp;
298 temp=NULL;
299 }
300
301 }
302 *destLength = destLen;
303 return dest;
304 }
305
306 #define ASTERISK 0x002A
307 #define SPACE 0x0020
308 #define CR 0x000A
309 #define LF 0x000D
310 #define AT_SIGN 0x0040
311
312
313
314
315
316 static void
317 trim(char **src, int32_t *len){
318
319 char *s = NULL;
320 int32_t i = 0;
321 if(src == NULL || *src == NULL){
322 return;
323 }
324 s = *src;
325 /* trim from the end */
326 for( i=(*len-1); i>= 0; i--){
327 switch(s[i]){
328 case ASTERISK:
329 case SPACE:
330 case CR:
331 case LF:
332 s[i] = 0;
333 continue;
334 default:
335 break;
336 }
337 break;
338
339 }
340 *len = i+1;
341 }
342
343 static void
344 print(UChar* src, int32_t srcLen,const char *tagStart,const char *tagEnd, UErrorCode *status){
345 int32_t bufCapacity = srcLen*4;
346 char *buf = NULL;
347 int32_t bufLen = 0;
348
349 if(U_FAILURE(*status)){
350 return;
351 }
352
353 buf = (char*) (uprv_malloc(bufCapacity));
354 if(buf==0){
355 fprintf(stderr, "Could not allocate memory!!");
356 exit(U_MEMORY_ALLOCATION_ERROR);
357 }
358 buf = convertAndEscape(&buf, bufCapacity, &bufLen, src, srcLen,status);
359 if(U_SUCCESS(*status)){
360 trim(&buf,&bufLen);
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);
365
366 }
367 }
368 static void
369 printNoteElements(struct UString *src, UErrorCode *status){
370
371 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
372
373 int32_t capacity = 0;
374 UChar* note = NULL;
375 int32_t noteLen = 0;
376 int32_t count = 0,i;
377
378 if(src == NULL){
379 return;
380 }
381
382 capacity = src->fLength;
383 note = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * capacity);
384
385 count = getCount(src->fChars,src->fLength, UPC_NOTE, status);
386 if(U_FAILURE(*status)){
387 return;
388 }
389 for(i=0; i < count; i++){
390 noteLen = getAt(src->fChars,src->fLength, &note, capacity, i, UPC_NOTE, status);
391 if(U_FAILURE(*status)){
392 return;
393 }
394 if(noteLen > 0){
395 write_tabs(out);
396 print(note, noteLen,"<note>", "</note>", status);
397 }
398 }
399 uprv_free(note);
400 #else
401
402 fprintf(stderr, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
403
404 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
405
406 }
407
408 static void
409 printComments(struct UString *src, const char *resName, UBool printTranslate, UErrorCode *status){
410
411 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
412
413 int32_t capacity = src->fLength;
414 char* buf = NULL;
415 int32_t bufLen = 0;
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);
419
420 int32_t descLen = 0, transLen=0;
421 if(status==NULL || U_FAILURE(*status)){
422 uprv_free(desc);
423 uprv_free(trans);
424 return;
425 }
426 if(desc==NULL || trans==NULL){
427 *status = U_MEMORY_ALLOCATION_ERROR;
428 uprv_free(desc);
429 uprv_free(trans);
430 return;
431 }
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);
435
436 /* first print translate attribute */
437 if(transLen > 0){
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);
445 }
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);
450 }
451 }else{
452 /* no translate attribute .. just close the tag */
453 T_FileStream_write(out,">\n", 2);
454 }
455 if(descLen > 0){
456 write_tabs(out);
457 print(desc, descLen, "<!--", "-->", status);
458 }
459 #else
460
461 fprintf(stderr, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
462
463 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
464
465 }
466 /* Writing Functions */
467 static void
468 string_write_xml(struct SResource *res, const char* id, const char* language, UErrorCode *status) {
469
470 char* buf = NULL;
471 int32_t bufLen = 0;
472
473 char* sid = NULL;
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";
478
479 if(status==NULL || U_FAILURE(*status)){
480 return;
481 }
482
483 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
484 write_tabs(out);
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);
489 tabCount++;
490 if(res->fComment!=NULL && res->fComment->fChars != NULL){
491 printComments(res->fComment, srBundle->fKeys+res->fKey, TRUE, status);
492
493 }else{
494 T_FileStream_write(out,">\n", 2);
495 }
496
497 write_tabs(out);
498
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);
502
503 buf = convertAndEscape(&buf,0,&bufLen,res->u.fString.fChars,res->u.fString.fLength,status);
504
505 if(U_FAILURE(*status)){
506 return;
507 }
508
509 T_FileStream_write(out,buf,bufLen);
510 T_FileStream_write(out,valStrEnd,(int32_t)uprv_strlen(valStrEnd));
511
512 printNoteElements(res->fComment, status);
513
514 tabCount--;
515 write_tabs(out);
516 T_FileStream_write(out,strEnd,(int32_t)uprv_strlen(strEnd));
517 }else{
518 const char* keyStrStart = "resname = \"";
519
520 write_tabs(out);
521
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));
527
528 T_FileStream_write(out,srBundle->fKeys+res->fKey, (int32_t)uprv_strlen(srBundle->fKeys+res->fKey));
529 T_FileStream_write(out,"\"", 1);
530 tabCount++;
531 if(res->fComment!=NULL && res->fComment->fChars != NULL){
532 printComments(res->fComment, srBundle->fKeys+res->fKey, TRUE, status);
533 }else{
534 T_FileStream_write(out,">\n", 2);
535 }
536
537 write_tabs(out);
538 T_FileStream_write(out,valStrStart, (int32_t)uprv_strlen(valStrStart));
539
540 /*T_FileStream_write(out,language, (int32_t)uprv_strlen(language));*/
541 T_FileStream_write(out,">", 1);
542
543 buf = convertAndEscape(&buf,0,&bufLen,res->u.fString.fChars,res->u.fString.fLength,status);
544 if(U_FAILURE(*status)){
545 return;
546 }
547 T_FileStream_write(out,buf,bufLen);
548
549 T_FileStream_write(out,valStrEnd,(int32_t)uprv_strlen(valStrEnd));
550
551 printNoteElements(res->fComment, status);
552
553 tabCount--;
554 write_tabs(out);
555 T_FileStream_write(out,strEnd,(int32_t)uprv_strlen(strEnd));
556 }
557 uprv_free(sid);
558 sid = NULL;
559
560 uprv_free(buf);
561 buf = NULL;
562 }
563
564 static void
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";
571 char* sid = NULL;
572
573 char* buf = NULL;
574 int32_t bufLen=0;
575 write_tabs(out);
576 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
577 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
578
579 sid = getID(id, NULL, sid);
580 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
581 T_FileStream_write(out, "\"", 1);
582 tabCount++;
583 if(res->fComment!=NULL && res->fComment->fChars != NULL){
584 printComments(res->fComment,srBundle->fKeys+res->fKey, TRUE, status);
585
586 }else{
587 T_FileStream_write(out,">\n", 2);
588 }
589 write_tabs(out);
590 T_FileStream_write(out, val, (int32_t)uprv_strlen(val));
591 }else{
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));
598
599 T_FileStream_write(out, "\"", 1);
600 tabCount++;
601 if(res->fComment!=NULL && res->fComment->fChars != NULL){
602 printComments(res->fComment, srBundle->fKeys+res->fKey, TRUE, status);
603
604 }else{
605 T_FileStream_write(out,">\n", 2);
606 }
607
608 write_tabs(out);
609
610 T_FileStream_write(out, val, (int32_t)uprv_strlen(val));
611 }
612
613 buf = convertAndEscape(&buf,0,&bufLen,res->u.fString.fChars,res->u.fString.fLength,/*FALSE,*/status);
614 if(U_FAILURE(*status)){
615 return;
616 }
617 T_FileStream_write(out,buf,bufLen);
618 T_FileStream_write(out, endKey, (int32_t)uprv_strlen(endKey));
619
620 printNoteElements(res->fComment, status);
621
622 tabCount--;
623 write_tabs(out);
624
625 T_FileStream_write(out, end, (int32_t)uprv_strlen(end));
626 uprv_free(buf);
627 uprv_free(sid);
628 }
629
630 static void
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=\"";
635
636 char* sid = NULL;
637 int index = 0;
638
639 struct SResource *current = NULL;
640 struct SResource *first =NULL;
641
642 write_tabs(out);
643 tabCount++;
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);
652 }else{
653 T_FileStream_write(out,">\n", 2);
654 }
655 }else{
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);
666 }else{
667 T_FileStream_write(out,">\n", 2);
668 }
669 }
670 current = res->u.fArray.fFirst;
671 first=current;
672
673 while (current != NULL) {
674 char c[256] = {0};
675 char* subId = NULL;
676 itostr(c, index,10,0);
677 index++;
678 subId = getID(sid, c, subId);
679
680 res_write_xml(current, subId, language, FALSE, status);
681 uprv_free(subId);
682 subId = NULL;
683 if(U_FAILURE(*status)){
684 return;
685 }
686 current = current->fNext;
687 }
688 tabCount--;
689 write_tabs(out);
690 T_FileStream_write(out,end,(int32_t)uprv_strlen(end));
691 uprv_free(sid);
692 sid = NULL;
693 }
694
695 static void
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=\"";
700
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";
705 char* sid = NULL;
706 char* ivd = NULL;
707
708 uint32_t i=0;
709 uint32_t len=0;
710 char buf[256] = {'0'};
711 write_tabs(out);
712 tabCount++;
713
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);
721
722 }else{
723 T_FileStream_write(out,">\n", 2);
724 }
725 }else{
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);
730
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);
737 }else{
738 T_FileStream_write(out,">\n", 2);
739 }
740 }
741
742
743 for(i = 0; i<res->u.fIntVector.fCount; i++) {
744 char c[256] = {0};
745 itostr(c, i,10,0);
746 ivd = getID(sid, c, ivd);
747 len=itostr(buf,res->u.fIntVector.fArray[i],10,0);
748
749 write_tabs(out);
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);
753 tabCount++;
754 write_tabs(out);
755 T_FileStream_write(out,valIntStart, (int32_t)uprv_strlen(valIntStart));
756
757 T_FileStream_write(out,buf,len);
758
759 T_FileStream_write(out,valIntEnd, (int32_t)uprv_strlen(valIntEnd));
760 tabCount--;
761 write_tabs(out);
762 T_FileStream_write(out, intEnd, (int32_t)uprv_strlen(intEnd));
763
764 uprv_free(ivd);
765 ivd = NULL;
766 }
767
768 tabCount--;
769 write_tabs(out);
770
771 T_FileStream_write(out, end, (int32_t)uprv_strlen(end));
772 uprv_free(sid);
773 sid = NULL;
774 }
775
776 static void
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 = \"";
783 char* sid = NULL;
784 char buf[256] = {0};
785
786 uint32_t len=0;
787 write_tabs(out);
788
789 tabCount++;
790
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);
796
797 if(res->fComment!=NULL && res->fComment->fChars != NULL){
798 printComments(res->fComment, sid, TRUE, status);
799
800 }else{
801 T_FileStream_write(out,">\n", 2);
802 }
803 write_tabs(out);
804 T_FileStream_write(out,valIntStart, (int32_t)uprv_strlen(valIntStart));
805 }else{
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));
811
812 T_FileStream_write(out, srBundle->fKeys+res->fKey, (int32_t) uprv_strlen(srBundle->fKeys+res->fKey));
813 T_FileStream_write(out,"\"", 1);
814
815 if(res->fComment!=NULL && res->fComment->fChars != NULL){
816 printComments(res->fComment, srBundle->fKeys+res->fKey, TRUE, status);
817
818 }else{
819 T_FileStream_write(out,">\n", 2);
820 }
821 write_tabs(out);
822 T_FileStream_write(out, valIntStart, (int32_t)uprv_strlen(valIntStart));
823
824 }
825 len=itostr(buf,res->u.fIntValue.fValue,10,0);
826 T_FileStream_write(out,buf,len);
827
828 T_FileStream_write(out, valIntEnd, (int32_t)uprv_strlen(valIntEnd));
829 printNoteElements(res->fComment, status);
830 tabCount--;
831 write_tabs(out);
832 T_FileStream_write(out, intEnd, (int32_t)uprv_strlen(intEnd));
833 uprv_free(sid);
834 sid = NULL;
835 }
836
837 static void
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";
851 char* sid = NULL;
852 uint32_t crc = 0xFFFFFFFF;
853
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;
860
861 char* f = NULL;
862
863 fn[0]=0;
864
865 if(res->u.fBinaryValue.fFileName!=NULL){
866 uprv_strcpy(fileName, res->u.fBinaryValue.fFileName);
867 f = uprv_strrchr(fileName, '\\');
868 if (f != NULL) {
869 f++;
870 }
871 else {
872 f = fileName;
873 }
874 ext = uprv_strrchr(fileName, '.');
875
876 if (ext == NULL) {
877 fprintf(stderr, "Error: %s is an unknown binary filename type.\n", fileName);
878 exit(U_ILLEGAL_ARGUMENT_ERROR);
879 }
880 if(uprv_strcmp(ext, ".jpg")==0 || uprv_strcmp(ext, ".jpeg")==0 || uprv_strcmp(ext, ".gif")==0 ){
881 m_type = "\"image";
882 } else if(uprv_strcmp(ext, ".wav")==0 || uprv_strcmp(ext, ".au")==0 ){
883 m_type = "\"audio";
884 } else if(uprv_strcmp(ext, ".avi")==0 || uprv_strcmp(ext, ".mpg")==0 || uprv_strcmp(ext, ".mpeg")==0){
885 m_type = "\"video";
886 } else if(uprv_strcmp(ext, ".txt")==0 || uprv_strcmp(ext, ".text")==0){
887 m_type = "\"text";
888 }
889
890 write_tabs(out);
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));
895 } else {
896 sid = getID(id, srBundle->fKeys+res->fKey, sid);
897 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
898 }
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));
905 }
906 T_FileStream_write(out,"\"", 1);
907 tabCount++;
908 if(res->fComment!=NULL && res->fComment->fChars != NULL){
909 printComments(res->fComment, sid, TRUE, status);
910
911 }else{
912 T_FileStream_write(out,">\n", 2);
913 }
914
915 write_tabs(out);
916
917 T_FileStream_write(out, valStart, (int32_t)uprv_strlen(valStart));
918 tabCount++;
919 write_tabs(out);
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));
923 tabCount--;
924 write_tabs(out);
925 T_FileStream_write(out, valEnd, (int32_t)uprv_strlen(valEnd));
926
927 printNoteElements(res->fComment, status);
928 tabCount--;
929 write_tabs(out);
930 T_FileStream_write(out,end,(int32_t)uprv_strlen(end));
931 } else {
932 char temp[256] = {0};
933 uint32_t i = 0;
934 int32_t len=0;
935
936 write_tabs(out);
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));
941 } else {
942 sid = getID(id, srBundle->fKeys+res->fKey, sid);
943 T_FileStream_write(out, sid, (int32_t)uprv_strlen(sid));
944 }
945
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));
952 }
953 T_FileStream_write(out,"\"", 1);
954 tabCount++;
955 if(res->fComment!=NULL && res->fComment->fChars != NULL){
956 printComments(res->fComment, sid, TRUE, status);
957
958 }else{
959 T_FileStream_write(out,">\n", 2);
960 }
961
962 write_tabs(out);
963 T_FileStream_write(out, valStart, (int32_t)uprv_strlen(valStart));
964 tabCount++;
965 write_tabs(out);
966 T_FileStream_write(out, fileStart, (int32_t)uprv_strlen(fileStart));
967
968 while(i <res->u.fBinaryValue.fLength){
969 len = itostr(temp,res->u.fBinaryValue.fData[i],16,2);
970 crc = computeCRC(temp, len, crc);
971 i++;
972 }
973
974 len = itostr(temp, crc, 10, 0);
975 T_FileStream_write(out,temp,len);
976 T_FileStream_write(out,"\">",2);
977
978 i = 0;
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);
982 i++;
983 }
984 T_FileStream_write(out, fileEnd, (int32_t)uprv_strlen(fileEnd));
985 tabCount--;
986 write_tabs(out);
987 T_FileStream_write(out, valEnd, (int32_t)uprv_strlen(valEnd));
988 printNoteElements(res->fComment, status);
989
990 tabCount--;
991 write_tabs(out);
992 T_FileStream_write(out,end,(int32_t)uprv_strlen(end));
993
994 uprv_free(sid);
995 sid = NULL;
996 }
997 uprv_free(fn);
998 }
999
1000
1001
1002 static void
1003 table_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status) {
1004
1005 uint32_t i = 0;
1006
1007 struct SResource *current = NULL;
1008 struct SResource *save = NULL;
1009
1010 char* sid = 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=\"";
1015
1016 if (U_FAILURE(*status)) {
1017 return ;
1018 }
1019
1020 if (res->u.fTable.fCount > 0) {
1021 write_tabs(out);
1022 tabCount++;
1023
1024 if(res->fKey<0 || uprv_strcmp(srBundle->fKeys+res->fKey ,"")==0){
1025 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
1026
1027 if(isTopLevel){
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);
1032 id="";
1033 }
1034 sid = getID(id, NULL, sid);
1035 /* only write the id if the sid!="" */
1036 if(sid[0]!='\0'){
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);
1040
1041 }
1042
1043
1044 if(res->fComment!=NULL && res->fComment->fChars != NULL){
1045 printComments(res->fComment, sid, FALSE, status);
1046 printNoteElements(res->fComment, status);
1047 }else{
1048 T_FileStream_write(out,">\n", 2);
1049 }
1050 }else{
1051 T_FileStream_write(out, start, (int32_t)uprv_strlen(start));
1052 sid = getID(id, srBundle->fKeys+res->fKey, sid);
1053
1054 /* only write the id if the sid!="" */
1055 if(sid[0]!='\0'){
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);
1059 }
1060
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);
1064
1065 if(res->fComment!=NULL && res->fComment->fChars != NULL){
1066 printComments(res->fComment, srBundle->fKeys+res->fKey, FALSE, status);
1067 printNoteElements(res->fComment, status);
1068 }else{
1069 T_FileStream_write(out,">\n", 2);
1070 }
1071 }
1072
1073 save = current = res->u.fTable.fFirst;
1074 i = 0;
1075 while (current != NULL) {
1076 res_write_xml(current, sid, language, FALSE, status);
1077
1078 if(U_FAILURE(*status)){
1079 return;
1080 }
1081 i++;
1082 current = current->fNext;
1083 }
1084 tabCount--;
1085 write_tabs(out);
1086 T_FileStream_write(out,end,(int32_t)uprv_strlen(end));
1087 } else {
1088 write_tabs(out);
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);
1096 }else{
1097 T_FileStream_write(out,">\n", 2);
1098 }
1099 }else{
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));
1106
1107 if(res->fComment!=NULL && res->fComment->fChars != NULL){
1108 printComments(res->fComment, srBundle->fKeys+res->fKey, FALSE, status);
1109 printNoteElements(res->fComment, status);
1110 }else{
1111 T_FileStream_write(out,">\n", 2);
1112 }
1113 }
1114
1115 write_tabs(out);
1116 T_FileStream_write(out,end,(int32_t)uprv_strlen(end));
1117 }
1118 uprv_free(sid);
1119 sid = NULL;
1120 }
1121
1122 void
1123 res_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status) {
1124
1125 if (U_FAILURE(*status)) {
1126 return ;
1127 }
1128
1129 if (res != NULL) {
1130 switch (res->fType) {
1131 case URES_STRING:
1132 string_write_xml (res, id, language, status);
1133 return;
1134 case URES_ALIAS:
1135 alias_write_xml (res, id, language, status);
1136 return;
1137 case URES_INT_VECTOR:
1138 intvector_write_xml (res, id, language, status);
1139 return;
1140 case URES_BINARY:
1141 bin_write_xml (res, id, language, status);
1142 return;
1143 case URES_INT:
1144 int_write_xml (res, id, language, status);
1145 return;
1146 case URES_ARRAY:
1147 array_write_xml (res, id, language, status);
1148 return;
1149 case URES_TABLE:
1150 case URES_TABLE32:
1151 table_write_xml (res, id, language, isTopLevel, status);
1152 return;
1153
1154 default:
1155 break;
1156 }
1157 }
1158
1159 *status = U_INTERNAL_PROGRAM_ERROR;
1160 }
1161
1162 void
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) {
1166
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";
1180
1181 char* pid = NULL;
1182 char* temp = NULL;
1183 char* lang = NULL;
1184 char* pos;
1185 int32_t first, index;
1186 time_t currTime;
1187 char timeBuf[128];
1188
1189 outDir = outputDir;
1190
1191 srBundle = bundle;
1192
1193 pos = uprv_strrchr(filename, '\\');
1194 if(pos != NULL) {
1195 first = (int32_t)(pos - filename + 1);
1196 } else {
1197 first = 0;
1198 }
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);
1203
1204 if(uprv_strcmp(originalFileName, srBundle->fLocale) != 0) {
1205 fprintf(stdout, "Warning: The file name is not same as the resource name!\n");
1206 }
1207
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);
1213 uprv_free(temp);
1214 temp = NULL;
1215
1216
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
1223 *
1224 * en{
1225 * ..
1226 * }
1227 */
1228 lang = parseFilename(srBundle->fLocale, lang);
1229 /*
1230 * Neither the file name nor the table name inside the
1231 * txt file contain a valid country and language codes
1232 * throw an error.
1233 * pegasusServer.txt contains
1234 *
1235 * testelements{
1236 * ....
1237 * }
1238 */
1239 if(lang==NULL){
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);
1242 }
1243 /* }*/
1244 } else {
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);
1248 }
1249
1250 if(outFileName) {
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);
1254 } else {
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);
1258 }
1259
1260 if(outputDir) {
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);
1263 } else {
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);
1266 }
1267
1268 if(outputDir){
1269 uprv_strcpy(xmlfileName, outputDir);
1270 if(outputDir[uprv_strlen(outputDir)-1] !=U_FILE_SEP_CHAR){
1271 uprv_strcat(xmlfileName,U_FILE_SEP_STRING);
1272 }
1273 }
1274 uprv_strcat(xmlfileName,outputFileName);
1275 uprv_strcat(xmlfileName,xliffExt);
1276
1277 if (writtenFilename) {
1278 uprv_strncpy(writtenFilename, xmlfileName, writtenFilenameLen);
1279 }
1280
1281 if (U_FAILURE(*status)) {
1282 goto cleanup_bundle_write_xml;
1283 }
1284
1285 out= T_FileStream_open(xmlfileName,"w");
1286
1287 if(out==NULL){
1288 *status = U_FILE_ACCESS_ERROR;
1289 goto cleanup_bundle_write_xml;
1290 }
1291 T_FileStream_write(out,xmlHeader, (int32_t)uprv_strlen(xmlHeader));
1292
1293 if(outputEnc && *outputEnc!='\0'){
1294 /* store the output encoding */
1295 enc = outputEnc;
1296 conv=ucnv_open(enc,status);
1297 if(U_FAILURE(*status)){
1298 goto cleanup_bundle_write_xml;
1299 }
1300 }
1301 T_FileStream_write(out,bundleStart, (int32_t)uprv_strlen(bundleStart));
1302 write_tabs(out);
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");
1307 }
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));
1314
1315 time(&currTime);
1316 strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&currTime));
1317 T_FileStream_write(out,timeBuf, (int32_t)uprv_strlen(timeBuf));
1318
1319 T_FileStream_write(out,"\">\n", 3);
1320
1321 tabCount++;
1322 write_tabs(out);
1323 T_FileStream_write(out,headerStart, (int32_t)uprv_strlen(headerStart));
1324 T_FileStream_write(out,headerEnd, (int32_t)uprv_strlen(headerEnd));
1325 write_tabs(out);
1326 tabCount++;
1327 T_FileStream_write(out,bodyStart, (int32_t)uprv_strlen(bodyStart));
1328
1329
1330 res_write_xml(bundle->fRoot, bundle->fLocale, lang, TRUE, status);
1331
1332 tabCount--;
1333 write_tabs(out);
1334 T_FileStream_write(out,bodyEnd, (int32_t)uprv_strlen(bodyEnd));
1335 tabCount--;
1336 write_tabs(out);
1337 T_FileStream_write(out,fileEnd, (int32_t)uprv_strlen(fileEnd));
1338 tabCount--;
1339 write_tabs(out);
1340 T_FileStream_write(out,bundleEnd,(int32_t)uprv_strlen(bundleEnd));
1341 T_FileStream_close(out);
1342
1343 ucnv_close(conv);
1344
1345 cleanup_bundle_write_xml:
1346 if(originalFileName!= NULL) {
1347 uprv_free(originalFileName);
1348 originalFileName = NULL;
1349 }
1350 if(lang != NULL) {
1351 uprv_free(lang);
1352 lang = NULL;
1353 }
1354 if(pid != NULL) {
1355 uprv_free(pid);
1356 pid = NULL;
1357 }
1358 if(xmlfileName != NULL) {
1359 uprv_free(xmlfileName);
1360 pid = NULL;
1361 }
1362 if(outputFileName != NULL){
1363 uprv_free(outputFileName);
1364 pid = NULL;
1365 }
1366 }