intl/icu/source/tools/genrb/wrtxml.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 *******************************************************************************
michael@0 3 *
michael@0 4 * Copyright (C) 2002-2012, International Business Machines
michael@0 5 * Corporation and others. All Rights Reserved.
michael@0 6 *
michael@0 7 *******************************************************************************
michael@0 8 *
michael@0 9 * File wrtxml.cpp
michael@0 10 *
michael@0 11 * Modification History:
michael@0 12 *
michael@0 13 * Date Name Description
michael@0 14 * 10/01/02 Ram Creation.
michael@0 15 * 02/07/08 Spieth Correct XLIFF generation on EBCDIC platform
michael@0 16 *
michael@0 17 *******************************************************************************
michael@0 18 */
michael@0 19 #include "reslist.h"
michael@0 20 #include "unewdata.h"
michael@0 21 #include "unicode/ures.h"
michael@0 22 #include "errmsg.h"
michael@0 23 #include "filestrm.h"
michael@0 24 #include "cstring.h"
michael@0 25 #include "unicode/ucnv.h"
michael@0 26 #include "genrb.h"
michael@0 27 #include "rle.h"
michael@0 28 #include "ucol_tok.h"
michael@0 29 #include "uhash.h"
michael@0 30 #include "uresimp.h"
michael@0 31 #include "unicode/ustring.h"
michael@0 32 #include "unicode/uchar.h"
michael@0 33 #include "ustr.h"
michael@0 34 #include "prscmnts.h"
michael@0 35 #include "unicode/unistr.h"
michael@0 36 #include "unicode/utf8.h"
michael@0 37 #include "unicode/utf16.h"
michael@0 38 #include <time.h>
michael@0 39
michael@0 40 U_NAMESPACE_USE
michael@0 41
michael@0 42 static int tabCount = 0;
michael@0 43
michael@0 44 static FileStream* out=NULL;
michael@0 45 static struct SRBRoot* srBundle ;
michael@0 46 static const char* outDir = NULL;
michael@0 47 static const char* enc ="";
michael@0 48 static UConverter* conv = NULL;
michael@0 49
michael@0 50 const char* const* ISOLanguages;
michael@0 51 const char* const* ISOCountries;
michael@0 52 const char* textExt = ".txt";
michael@0 53 const char* xliffExt = ".xlf";
michael@0 54
michael@0 55 static int32_t write_utf8_file(FileStream* fileStream, UnicodeString outString)
michael@0 56 {
michael@0 57 UErrorCode status = U_ZERO_ERROR;
michael@0 58 int32_t len = 0;
michael@0 59
michael@0 60 // preflight to get the destination buffer size
michael@0 61 u_strToUTF8(NULL,
michael@0 62 0,
michael@0 63 &len,
michael@0 64 outString.getBuffer(),
michael@0 65 outString.length(),
michael@0 66 &status);
michael@0 67
michael@0 68 // allocate the buffer
michael@0 69 char* dest = (char*)uprv_malloc(len);
michael@0 70 status = U_ZERO_ERROR;
michael@0 71
michael@0 72 // convert the data
michael@0 73 u_strToUTF8(dest,
michael@0 74 len,
michael@0 75 &len,
michael@0 76 outString.getBuffer(),
michael@0 77 outString.length(),
michael@0 78 &status);
michael@0 79
michael@0 80 // write data to out file
michael@0 81 int32_t ret = T_FileStream_write(fileStream, dest, len);
michael@0 82 uprv_free(dest);
michael@0 83 return (ret);
michael@0 84 }
michael@0 85
michael@0 86 /*write indentation for formatting*/
michael@0 87 static void write_tabs(FileStream* os){
michael@0 88 int i=0;
michael@0 89 for(;i<=tabCount;i++){
michael@0 90 write_utf8_file(os,UnicodeString(" "));
michael@0 91 }
michael@0 92 }
michael@0 93
michael@0 94 /*get ID for each element. ID is globally unique.*/
michael@0 95 static char* getID(const char* id, const char* curKey, char* result) {
michael@0 96 if(curKey == NULL) {
michael@0 97 result = (char *)uprv_malloc(sizeof(char)*uprv_strlen(id) + 1);
michael@0 98 uprv_memset(result, 0, sizeof(char)*uprv_strlen(id) + 1);
michael@0 99 uprv_strcpy(result, id);
michael@0 100 } else {
michael@0 101 result = (char *)uprv_malloc(sizeof(char)*(uprv_strlen(id) + 1 + uprv_strlen(curKey)) + 1);
michael@0 102 uprv_memset(result, 0, sizeof(char)*(uprv_strlen(id) + 1 + uprv_strlen(curKey)) + 1);
michael@0 103 if(id[0]!='\0'){
michael@0 104 uprv_strcpy(result, id);
michael@0 105 uprv_strcat(result, "_");
michael@0 106 }
michael@0 107 uprv_strcat(result, curKey);
michael@0 108 }
michael@0 109 return result;
michael@0 110 }
michael@0 111
michael@0 112 /*compute CRC for binary code*/
michael@0 113 /* The code is from http://www.theorem.com/java/CRC32.java
michael@0 114 * Calculates the CRC32 - 32 bit Cyclical Redundancy Check
michael@0 115 * <P> This check is used in numerous systems to verify the integrity
michael@0 116 * of information. It's also used as a hashing function. Unlike a regular
michael@0 117 * checksum, it's sensitive to the order of the characters.
michael@0 118 * It produces a 32 bit
michael@0 119 *
michael@0 120 * @author Michael Lecuyer (mjl@theorem.com)
michael@0 121 * @version 1.1 August 11, 1998
michael@0 122 */
michael@0 123
michael@0 124 /* ICU is not endian portable, because ICU data generated on big endian machines can be
michael@0 125 * ported to big endian machines but not to little endian machines and vice versa. The
michael@0 126 * conversion is not portable across platforms with different endianess.
michael@0 127 */
michael@0 128
michael@0 129 uint32_t computeCRC(char *ptr, uint32_t len, uint32_t lastcrc){
michael@0 130 int32_t crc;
michael@0 131 uint32_t temp1;
michael@0 132 uint32_t temp2;
michael@0 133
michael@0 134 int32_t crc_ta[256];
michael@0 135 int i = 0;
michael@0 136 int j = 0;
michael@0 137 uint32_t crc2 = 0;
michael@0 138
michael@0 139 #define CRC32_POLYNOMIAL 0xEDB88320
michael@0 140
michael@0 141 /*build crc table*/
michael@0 142 for (i = 0; i <= 255; i++) {
michael@0 143 crc2 = i;
michael@0 144 for (j = 8; j > 0; j--) {
michael@0 145 if ((crc2 & 1) == 1) {
michael@0 146 crc2 = (crc2 >> 1) ^ CRC32_POLYNOMIAL;
michael@0 147 } else {
michael@0 148 crc2 >>= 1;
michael@0 149 }
michael@0 150 }
michael@0 151 crc_ta[i] = crc2;
michael@0 152 }
michael@0 153
michael@0 154 crc = lastcrc;
michael@0 155 while(len--!=0) {
michael@0 156 temp1 = (uint32_t)crc>>8;
michael@0 157 temp2 = crc_ta[(crc^*ptr) & 0xFF];
michael@0 158 crc = temp1^temp2;
michael@0 159 ptr++;
michael@0 160 }
michael@0 161 return(crc);
michael@0 162 }
michael@0 163
michael@0 164 static void strnrepchr(char* src, int32_t srcLen, char s, char r){
michael@0 165 int32_t i = 0;
michael@0 166 for(i=0;i<srcLen;i++){
michael@0 167 if(src[i]==s){
michael@0 168 src[i]=r;
michael@0 169 }
michael@0 170 }
michael@0 171 }
michael@0 172 /* Parse the filename, and get its language information.
michael@0 173 * If it fails to get the language information from the filename,
michael@0 174 * use "en" as the default value for language
michael@0 175 */
michael@0 176 static char* parseFilename(const char* id, char* /*lang*/) {
michael@0 177 int idLen = (int) uprv_strlen(id);
michael@0 178 char* localeID = (char*) uprv_malloc(idLen);
michael@0 179 int pos = 0;
michael@0 180 int canonCapacity = 0;
michael@0 181 char* canon = NULL;
michael@0 182 int canonLen = 0;
michael@0 183 /*int i;*/
michael@0 184 UErrorCode status = U_ZERO_ERROR;
michael@0 185 const char *ext = uprv_strchr(id, '.');
michael@0 186
michael@0 187 if(ext != NULL){
michael@0 188 pos = (int) (ext - id);
michael@0 189 } else {
michael@0 190 pos = idLen;
michael@0 191 }
michael@0 192 uprv_memcpy(localeID, id, pos);
michael@0 193 localeID[pos]=0; /* NUL terminate the string */
michael@0 194
michael@0 195 canonCapacity =pos*3;
michael@0 196 canon = (char*) uprv_malloc(canonCapacity);
michael@0 197 canonLen = uloc_canonicalize(localeID, canon, canonCapacity, &status);
michael@0 198
michael@0 199 if(U_FAILURE(status)){
michael@0 200 fprintf(stderr, "Could not canonicalize the locale ID: %s. Error: %s\n", localeID, u_errorName(status));
michael@0 201 exit(status);
michael@0 202 }
michael@0 203 strnrepchr(canon, canonLen, '_', '-');
michael@0 204 return canon;
michael@0 205 }
michael@0 206
michael@0 207 static const char* xmlHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
michael@0 208 #if 0
michael@0 209 static const char* bundleStart = "<xliff version = \"1.2\" "
michael@0 210 "xmlns='urn:oasis:names:tc:xliff:document:1.2' "
michael@0 211 "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
michael@0 212 "xsi:schemaLocation='urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd'>\n";
michael@0 213 #else
michael@0 214 static const char* bundleStart = "<xliff version = \"1.1\" "
michael@0 215 "xmlns='urn:oasis:names:tc:xliff:document:1.1' "
michael@0 216 "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
michael@0 217 "xsi:schemaLocation='urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd'>\n";
michael@0 218 #endif
michael@0 219 static const char* bundleEnd = "</xliff>\n";
michael@0 220
michael@0 221 void res_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status);
michael@0 222
michael@0 223 static char* convertAndEscape(char** pDest, int32_t destCap, int32_t* destLength,
michael@0 224 const UChar* src, int32_t srcLen, UErrorCode* status){
michael@0 225 int32_t srcIndex=0;
michael@0 226 char* dest=NULL;
michael@0 227 char* temp=NULL;
michael@0 228 int32_t destLen=0;
michael@0 229 UChar32 c = 0;
michael@0 230
michael@0 231 if(status==NULL || U_FAILURE(*status) || pDest==NULL || srcLen==0 || src == NULL){
michael@0 232 return NULL;
michael@0 233 }
michael@0 234 dest =*pDest;
michael@0 235 if(dest==NULL || destCap <=0){
michael@0 236 destCap = srcLen * 8;
michael@0 237 dest = (char*) uprv_malloc(sizeof(char) * destCap);
michael@0 238 if(dest==NULL){
michael@0 239 *status=U_MEMORY_ALLOCATION_ERROR;
michael@0 240 return NULL;
michael@0 241 }
michael@0 242 }
michael@0 243
michael@0 244 dest[0]=0;
michael@0 245
michael@0 246 while(srcIndex<srcLen){
michael@0 247 U16_NEXT(src, srcIndex, srcLen, c);
michael@0 248
michael@0 249 if (U16_IS_LEAD(c) || U16_IS_TRAIL(c)) {
michael@0 250 *status = U_ILLEGAL_CHAR_FOUND;
michael@0 251 fprintf(stderr, "Illegal Surrogate! \n");
michael@0 252 uprv_free(dest);
michael@0 253 return NULL;
michael@0 254 }
michael@0 255
michael@0 256 if((destLen+U8_LENGTH(c)) < destCap){
michael@0 257
michael@0 258 /* ASCII Range */
michael@0 259 if(c <=0x007F){
michael@0 260 switch(c) {
michael@0 261 case '\x26':
michael@0 262 uprv_strcpy(dest+( destLen),"\x26\x61\x6d\x70\x3b"); /* &amp;*/
michael@0 263 destLen+=(int32_t)uprv_strlen("\x26\x61\x6d\x70\x3b");
michael@0 264 break;
michael@0 265 case '\x3c':
michael@0 266 uprv_strcpy(dest+(destLen),"\x26\x6c\x74\x3b"); /* &lt;*/
michael@0 267 destLen+=(int32_t)uprv_strlen("\x26\x6c\x74\x3b");
michael@0 268 break;
michael@0 269 case '\x3e':
michael@0 270 uprv_strcpy(dest+(destLen),"\x26\x67\x74\x3b"); /* &gt;*/
michael@0 271 destLen+=(int32_t)uprv_strlen("\x26\x67\x74\x3b");
michael@0 272 break;
michael@0 273 case '\x22':
michael@0 274 uprv_strcpy(dest+(destLen),"\x26\x71\x75\x6f\x74\x3b"); /* &quot;*/
michael@0 275 destLen+=(int32_t)uprv_strlen("\x26\x71\x75\x6f\x74\x3b");
michael@0 276 break;
michael@0 277 case '\x27':
michael@0 278 uprv_strcpy(dest+(destLen),"\x26\x61\x70\x6f\x73\x3b"); /* &apos; */
michael@0 279 destLen+=(int32_t)uprv_strlen("\x26\x61\x70\x6f\x73\x3b");
michael@0 280 break;
michael@0 281
michael@0 282 /* Disallow C0 controls except TAB, CR, LF*/
michael@0 283 case 0x00:
michael@0 284 case 0x01:
michael@0 285 case 0x02:
michael@0 286 case 0x03:
michael@0 287 case 0x04:
michael@0 288 case 0x05:
michael@0 289 case 0x06:
michael@0 290 case 0x07:
michael@0 291 case 0x08:
michael@0 292 /*case 0x09:*/
michael@0 293 /*case 0x0A: */
michael@0 294 case 0x0B:
michael@0 295 case 0x0C:
michael@0 296 /*case 0x0D:*/
michael@0 297 case 0x0E:
michael@0 298 case 0x0F:
michael@0 299 case 0x10:
michael@0 300 case 0x11:
michael@0 301 case 0x12:
michael@0 302 case 0x13:
michael@0 303 case 0x14:
michael@0 304 case 0x15:
michael@0 305 case 0x16:
michael@0 306 case 0x17:
michael@0 307 case 0x18:
michael@0 308 case 0x19:
michael@0 309 case 0x1A:
michael@0 310 case 0x1B:
michael@0 311 case 0x1C:
michael@0 312 case 0x1D:
michael@0 313 case 0x1E:
michael@0 314 case 0x1F:
michael@0 315 *status = U_ILLEGAL_CHAR_FOUND;
michael@0 316 fprintf(stderr, "Illegal Character \\u%04X!\n",(int)c);
michael@0 317 uprv_free(dest);
michael@0 318 return NULL;
michael@0 319 default:
michael@0 320 dest[destLen++]=(char)c;
michael@0 321 }
michael@0 322 }else{
michael@0 323 UBool isError = FALSE;
michael@0 324 U8_APPEND((unsigned char*)dest,destLen,destCap,c,isError);
michael@0 325 if(isError){
michael@0 326 *status = U_ILLEGAL_CHAR_FOUND;
michael@0 327 fprintf(stderr, "Illegal Character \\U%08X!\n",(int)c);
michael@0 328 uprv_free(dest);
michael@0 329 return NULL;
michael@0 330 }
michael@0 331 }
michael@0 332 }else{
michael@0 333 destCap += destLen;
michael@0 334
michael@0 335 temp = (char*) uprv_malloc(sizeof(char)*destCap);
michael@0 336 if(temp==NULL){
michael@0 337 *status=U_MEMORY_ALLOCATION_ERROR;
michael@0 338 uprv_free(dest);
michael@0 339 return NULL;
michael@0 340 }
michael@0 341 uprv_memmove(temp,dest,destLen);
michael@0 342 destLen=0;
michael@0 343 uprv_free(dest);
michael@0 344 dest=temp;
michael@0 345 temp=NULL;
michael@0 346 }
michael@0 347
michael@0 348 }
michael@0 349 *destLength = destLen;
michael@0 350 return dest;
michael@0 351 }
michael@0 352
michael@0 353 #define ASTERISK 0x002A
michael@0 354 #define SPACE 0x0020
michael@0 355 #define CR 0x000A
michael@0 356 #define LF 0x000D
michael@0 357 #define AT_SIGN 0x0040
michael@0 358
michael@0 359 static void
michael@0 360 trim(char **src, int32_t *len){
michael@0 361
michael@0 362 char *s = NULL;
michael@0 363 int32_t i = 0;
michael@0 364 if(src == NULL || *src == NULL){
michael@0 365 return;
michael@0 366 }
michael@0 367 s = *src;
michael@0 368 /* trim from the end */
michael@0 369 for( i=(*len-1); i>= 0; i--){
michael@0 370 switch(s[i]){
michael@0 371 case ASTERISK:
michael@0 372 case SPACE:
michael@0 373 case CR:
michael@0 374 case LF:
michael@0 375 s[i] = 0;
michael@0 376 continue;
michael@0 377 default:
michael@0 378 break;
michael@0 379 }
michael@0 380 break;
michael@0 381
michael@0 382 }
michael@0 383 *len = i+1;
michael@0 384 }
michael@0 385
michael@0 386 static void
michael@0 387 print(UChar* src, int32_t srcLen,const char *tagStart,const char *tagEnd, UErrorCode *status){
michael@0 388 int32_t bufCapacity = srcLen*4;
michael@0 389 char *buf = NULL;
michael@0 390 int32_t bufLen = 0;
michael@0 391
michael@0 392 if(U_FAILURE(*status)){
michael@0 393 return;
michael@0 394 }
michael@0 395
michael@0 396 buf = (char*) (uprv_malloc(bufCapacity));
michael@0 397 if(buf==0){
michael@0 398 fprintf(stderr, "Could not allocate memory!!");
michael@0 399 exit(U_MEMORY_ALLOCATION_ERROR);
michael@0 400 }
michael@0 401 buf = convertAndEscape(&buf, bufCapacity, &bufLen, src, srcLen,status);
michael@0 402 if(U_SUCCESS(*status)){
michael@0 403 trim(&buf,&bufLen);
michael@0 404 write_utf8_file(out,UnicodeString(tagStart));
michael@0 405 write_utf8_file(out,UnicodeString(buf, bufLen, "UTF-8"));
michael@0 406 write_utf8_file(out,UnicodeString(tagEnd));
michael@0 407 write_utf8_file(out,UnicodeString("\n"));
michael@0 408
michael@0 409 }
michael@0 410 }
michael@0 411 static void
michael@0 412 printNoteElements(struct UString *src, UErrorCode *status){
michael@0 413
michael@0 414 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
michael@0 415
michael@0 416 int32_t capacity = 0;
michael@0 417 UChar* note = NULL;
michael@0 418 int32_t noteLen = 0;
michael@0 419 int32_t count = 0,i;
michael@0 420
michael@0 421 if(src == NULL){
michael@0 422 return;
michael@0 423 }
michael@0 424
michael@0 425 capacity = src->fLength;
michael@0 426 note = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * capacity);
michael@0 427
michael@0 428 count = getCount(src->fChars,src->fLength, UPC_NOTE, status);
michael@0 429 if(U_FAILURE(*status)){
michael@0 430 uprv_free(note);
michael@0 431 return;
michael@0 432 }
michael@0 433 for(i=0; i < count; i++){
michael@0 434 noteLen = getAt(src->fChars,src->fLength, &note, capacity, i, UPC_NOTE, status);
michael@0 435 if(U_FAILURE(*status)){
michael@0 436 uprv_free(note);
michael@0 437 return;
michael@0 438 }
michael@0 439 if(noteLen > 0){
michael@0 440 write_tabs(out);
michael@0 441 print(note, noteLen,"<note>", "</note>", status);
michael@0 442 }
michael@0 443 }
michael@0 444 uprv_free(note);
michael@0 445 #else
michael@0 446
michael@0 447 fprintf(stderr, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
michael@0 448
michael@0 449 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
michael@0 450
michael@0 451 }
michael@0 452
michael@0 453 static void printAttribute(const char *name, const char *value, int32_t /*len*/)
michael@0 454 {
michael@0 455 write_utf8_file(out, UnicodeString(" "));
michael@0 456 write_utf8_file(out, UnicodeString(name));
michael@0 457 write_utf8_file(out, UnicodeString(" = \""));
michael@0 458 write_utf8_file(out, UnicodeString(value));
michael@0 459 write_utf8_file(out, UnicodeString("\""));
michael@0 460 }
michael@0 461
michael@0 462 static void printAttribute(const char *name, const UnicodeString value, int32_t /*len*/)
michael@0 463 {
michael@0 464 write_utf8_file(out, UnicodeString(" "));
michael@0 465 write_utf8_file(out, UnicodeString(name));
michael@0 466 write_utf8_file(out, UnicodeString(" = \""));
michael@0 467 write_utf8_file(out, value);
michael@0 468 write_utf8_file(out, UnicodeString("\""));
michael@0 469 }
michael@0 470
michael@0 471 static void
michael@0 472 printComments(struct UString *src, const char *resName, UBool printTranslate, UErrorCode *status){
michael@0 473
michael@0 474 #if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */
michael@0 475
michael@0 476 if(status==NULL || U_FAILURE(*status)){
michael@0 477 return;
michael@0 478 }
michael@0 479
michael@0 480 int32_t capacity = src->fLength + 1;
michael@0 481 char* buf = NULL;
michael@0 482 int32_t bufLen = 0;
michael@0 483 UChar* desc = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * capacity);
michael@0 484 UChar* trans = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * capacity);
michael@0 485
michael@0 486 int32_t descLen = 0, transLen=0;
michael@0 487 if(desc==NULL || trans==NULL){
michael@0 488 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 489 uprv_free(desc);
michael@0 490 uprv_free(trans);
michael@0 491 return;
michael@0 492 }
michael@0 493 src->fLength = removeCmtText(src->fChars, src->fLength, status);
michael@0 494 descLen = getDescription(src->fChars,src->fLength, &desc, capacity, status);
michael@0 495 transLen = getTranslate(src->fChars,src->fLength, &trans, capacity, status);
michael@0 496
michael@0 497 /* first print translate attribute */
michael@0 498 if(transLen > 0){
michael@0 499 if(printTranslate){
michael@0 500 /* print translate attribute */
michael@0 501 buf = convertAndEscape(&buf, 0, &bufLen, trans, transLen, status);
michael@0 502 if(U_SUCCESS(*status)){
michael@0 503 printAttribute("translate", UnicodeString(buf, bufLen, "UTF-8"), bufLen);
michael@0 504 write_utf8_file(out,UnicodeString(">\n"));
michael@0 505 }
michael@0 506 }else if(getShowWarning()){
michael@0 507 fprintf(stderr, "Warning: Tranlate attribute for resource %s cannot be set. XLIFF prohibits it.\n", resName);
michael@0 508 /* no translate attribute .. just close the tag */
michael@0 509 write_utf8_file(out,UnicodeString(">\n"));
michael@0 510 }
michael@0 511 }else{
michael@0 512 /* no translate attribute .. just close the tag */
michael@0 513 write_utf8_file(out,UnicodeString(">\n"));
michael@0 514 }
michael@0 515
michael@0 516 if(descLen > 0){
michael@0 517 write_tabs(out);
michael@0 518 print(desc, descLen, "<!--", "-->", status);
michael@0 519 }
michael@0 520
michael@0 521 uprv_free(desc);
michael@0 522 uprv_free(trans);
michael@0 523 #else
michael@0 524
michael@0 525 fprintf(stderr, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n");
michael@0 526
michael@0 527 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */
michael@0 528
michael@0 529 }
michael@0 530
michael@0 531 /*
michael@0 532 * Print out a containing element, like:
michael@0 533 * <trans-unit id = "blah" resname = "blah" restype = "x-id-alias" translate = "no">
michael@0 534 * <group id "calendar_gregorian" resname = "gregorian" restype = "x-icu-array">
michael@0 535 */
michael@0 536 static char *printContainer(struct SResource *res, const char *container, const char *restype, const char *mimetype, const char *id, UErrorCode *status)
michael@0 537 {
michael@0 538 char resKeyBuffer[8];
michael@0 539 const char *resname = NULL;
michael@0 540 char *sid = NULL;
michael@0 541
michael@0 542 write_tabs(out);
michael@0 543
michael@0 544 resname = res_getKeyString(srBundle, res, resKeyBuffer);
michael@0 545 if (resname != NULL && *resname != 0) {
michael@0 546 sid = getID(id, resname, sid);
michael@0 547 } else {
michael@0 548 sid = getID(id, NULL, sid);
michael@0 549 }
michael@0 550
michael@0 551 write_utf8_file(out, UnicodeString("<"));
michael@0 552 write_utf8_file(out, UnicodeString(container));
michael@0 553 printAttribute("id", sid, (int32_t) uprv_strlen(sid));
michael@0 554
michael@0 555 if (resname != NULL) {
michael@0 556 printAttribute("resname", resname, (int32_t) uprv_strlen(resname));
michael@0 557 }
michael@0 558
michael@0 559 if (mimetype != NULL) {
michael@0 560 printAttribute("mime-type", mimetype, (int32_t) uprv_strlen(mimetype));
michael@0 561 }
michael@0 562
michael@0 563 if (restype != NULL) {
michael@0 564 printAttribute("restype", restype, (int32_t) uprv_strlen(restype));
michael@0 565 }
michael@0 566
michael@0 567 tabCount += 1;
michael@0 568 if (res->fComment.fLength > 0) {
michael@0 569 /* printComments will print the closing ">\n" */
michael@0 570 printComments(&res->fComment, resname, TRUE, status);
michael@0 571 } else {
michael@0 572 write_utf8_file(out, UnicodeString(">\n"));
michael@0 573 }
michael@0 574
michael@0 575 return sid;
michael@0 576 }
michael@0 577
michael@0 578 /* Writing Functions */
michael@0 579
michael@0 580 static const char *trans_unit = "trans-unit";
michael@0 581 static const char *close_trans_unit = "</trans-unit>\n";
michael@0 582 static const char *source = "<source>";
michael@0 583 static const char *close_source = "</source>\n";
michael@0 584 static const char *group = "group";
michael@0 585 static const char *close_group = "</group>\n";
michael@0 586
michael@0 587 static const char *bin_unit = "bin-unit";
michael@0 588 static const char *close_bin_unit = "</bin-unit>\n";
michael@0 589 static const char *bin_source = "<bin-source>\n";
michael@0 590 static const char *close_bin_source = "</bin-source>\n";
michael@0 591 static const char *external_file = "<external-file";
michael@0 592 /*static const char *close_external_file = "</external-file>\n";*/
michael@0 593 static const char *internal_file = "<internal-file";
michael@0 594 static const char *close_internal_file = "</internal-file>\n";
michael@0 595
michael@0 596 static const char *application_mimetype = "application"; /* add "/octet-stream"? */
michael@0 597
michael@0 598 static const char *alias_restype = "x-icu-alias";
michael@0 599 static const char *array_restype = "x-icu-array";
michael@0 600 static const char *binary_restype = "x-icu-binary";
michael@0 601 static const char *integer_restype = "x-icu-integer";
michael@0 602 static const char *intvector_restype = "x-icu-intvector";
michael@0 603 static const char *table_restype = "x-icu-table";
michael@0 604
michael@0 605 static void
michael@0 606 string_write_xml(struct SResource *res, const char* id, const char* /*language*/, UErrorCode *status) {
michael@0 607
michael@0 608 char *sid = NULL;
michael@0 609 char* buf = NULL;
michael@0 610 int32_t bufLen = 0;
michael@0 611
michael@0 612 if(status==NULL || U_FAILURE(*status)){
michael@0 613 return;
michael@0 614 }
michael@0 615
michael@0 616 sid = printContainer(res, trans_unit, NULL, NULL, id, status);
michael@0 617
michael@0 618 write_tabs(out);
michael@0 619
michael@0 620 write_utf8_file(out, UnicodeString(source));
michael@0 621
michael@0 622 buf = convertAndEscape(&buf, 0, &bufLen, res->u.fString.fChars, res->u.fString.fLength, status);
michael@0 623
michael@0 624 if (U_FAILURE(*status)) {
michael@0 625 return;
michael@0 626 }
michael@0 627
michael@0 628 write_utf8_file(out, UnicodeString(buf, bufLen, "UTF-8"));
michael@0 629 write_utf8_file(out, UnicodeString(close_source));
michael@0 630
michael@0 631 printNoteElements(&res->fComment, status);
michael@0 632
michael@0 633 tabCount -= 1;
michael@0 634 write_tabs(out);
michael@0 635
michael@0 636 write_utf8_file(out, UnicodeString(close_trans_unit));
michael@0 637
michael@0 638 uprv_free(buf);
michael@0 639 uprv_free(sid);
michael@0 640 }
michael@0 641
michael@0 642 static void
michael@0 643 alias_write_xml(struct SResource *res, const char* id, const char* /*language*/, UErrorCode *status) {
michael@0 644 char *sid = NULL;
michael@0 645 char* buf = NULL;
michael@0 646 int32_t bufLen=0;
michael@0 647
michael@0 648 sid = printContainer(res, trans_unit, alias_restype, NULL, id, status);
michael@0 649
michael@0 650 write_tabs(out);
michael@0 651
michael@0 652 write_utf8_file(out, UnicodeString(source));
michael@0 653
michael@0 654 buf = convertAndEscape(&buf, 0, &bufLen, res->u.fString.fChars, res->u.fString.fLength, status);
michael@0 655
michael@0 656 if(U_FAILURE(*status)){
michael@0 657 return;
michael@0 658 }
michael@0 659 write_utf8_file(out, UnicodeString(buf, bufLen, "UTF-8"));
michael@0 660 write_utf8_file(out, UnicodeString(close_source));
michael@0 661
michael@0 662 printNoteElements(&res->fComment, status);
michael@0 663
michael@0 664 tabCount -= 1;
michael@0 665 write_tabs(out);
michael@0 666
michael@0 667 write_utf8_file(out, UnicodeString(close_trans_unit));
michael@0 668
michael@0 669 uprv_free(buf);
michael@0 670 uprv_free(sid);
michael@0 671 }
michael@0 672
michael@0 673 static void
michael@0 674 array_write_xml(struct SResource *res, const char* id, const char* language, UErrorCode *status) {
michael@0 675 char* sid = NULL;
michael@0 676 int index = 0;
michael@0 677
michael@0 678 struct SResource *current = NULL;
michael@0 679
michael@0 680 sid = printContainer(res, group, array_restype, NULL, id, status);
michael@0 681
michael@0 682 current = res->u.fArray.fFirst;
michael@0 683
michael@0 684 while (current != NULL) {
michael@0 685 char c[256] = {0};
michael@0 686 char* subId = NULL;
michael@0 687
michael@0 688 itostr(c, index, 10, 0);
michael@0 689 index += 1;
michael@0 690 subId = getID(sid, c, subId);
michael@0 691
michael@0 692 res_write_xml(current, subId, language, FALSE, status);
michael@0 693 uprv_free(subId);
michael@0 694 subId = NULL;
michael@0 695
michael@0 696 if(U_FAILURE(*status)){
michael@0 697 return;
michael@0 698 }
michael@0 699
michael@0 700 current = current->fNext;
michael@0 701 }
michael@0 702
michael@0 703 tabCount -= 1;
michael@0 704 write_tabs(out);
michael@0 705 write_utf8_file(out, UnicodeString(close_group));
michael@0 706
michael@0 707 uprv_free(sid);
michael@0 708 }
michael@0 709
michael@0 710 static void
michael@0 711 intvector_write_xml(struct SResource *res, const char* id, const char* /*language*/, UErrorCode *status) {
michael@0 712 char* sid = NULL;
michael@0 713 char* ivd = NULL;
michael@0 714 uint32_t i=0;
michael@0 715 uint32_t len=0;
michael@0 716 char buf[256] = {'0'};
michael@0 717
michael@0 718 sid = printContainer(res, group, intvector_restype, NULL, id, status);
michael@0 719
michael@0 720 for(i = 0; i < res->u.fIntVector.fCount; i += 1) {
michael@0 721 char c[256] = {0};
michael@0 722
michael@0 723 itostr(c, i, 10, 0);
michael@0 724 ivd = getID(sid, c, ivd);
michael@0 725 len = itostr(buf, res->u.fIntVector.fArray[i], 10, 0);
michael@0 726
michael@0 727 write_tabs(out);
michael@0 728 write_utf8_file(out, UnicodeString("<"));
michael@0 729 write_utf8_file(out, UnicodeString(trans_unit));
michael@0 730
michael@0 731 printAttribute("id", ivd, (int32_t)uprv_strlen(ivd));
michael@0 732 printAttribute("restype", integer_restype, (int32_t) strlen(integer_restype));
michael@0 733
michael@0 734 write_utf8_file(out, UnicodeString(">\n"));
michael@0 735
michael@0 736 tabCount += 1;
michael@0 737 write_tabs(out);
michael@0 738 write_utf8_file(out, UnicodeString(source));
michael@0 739
michael@0 740 write_utf8_file(out, UnicodeString(buf, len));
michael@0 741
michael@0 742 write_utf8_file(out, UnicodeString(close_source));
michael@0 743 tabCount -= 1;
michael@0 744 write_tabs(out);
michael@0 745 write_utf8_file(out, UnicodeString(close_trans_unit));
michael@0 746
michael@0 747 uprv_free(ivd);
michael@0 748 ivd = NULL;
michael@0 749 }
michael@0 750
michael@0 751 tabCount -= 1;
michael@0 752 write_tabs(out);
michael@0 753
michael@0 754 write_utf8_file(out, UnicodeString(close_group));
michael@0 755 uprv_free(sid);
michael@0 756 sid = NULL;
michael@0 757 }
michael@0 758
michael@0 759 static void
michael@0 760 int_write_xml(struct SResource *res, const char* id, const char* /*language*/, UErrorCode *status) {
michael@0 761 char* sid = NULL;
michael@0 762 char buf[256] = {0};
michael@0 763 uint32_t len = 0;
michael@0 764
michael@0 765 sid = printContainer(res, trans_unit, integer_restype, NULL, id, status);
michael@0 766
michael@0 767 write_tabs(out);
michael@0 768
michael@0 769 write_utf8_file(out, UnicodeString(source));
michael@0 770
michael@0 771 len = itostr(buf, res->u.fIntValue.fValue, 10, 0);
michael@0 772 write_utf8_file(out, UnicodeString(buf, len));
michael@0 773
michael@0 774 write_utf8_file(out, UnicodeString(close_source));
michael@0 775
michael@0 776 printNoteElements(&res->fComment, status);
michael@0 777
michael@0 778 tabCount -= 1;
michael@0 779 write_tabs(out);
michael@0 780
michael@0 781 write_utf8_file(out, UnicodeString(close_trans_unit));
michael@0 782
michael@0 783 uprv_free(sid);
michael@0 784 sid = NULL;
michael@0 785 }
michael@0 786
michael@0 787 static void
michael@0 788 bin_write_xml(struct SResource *res, const char* id, const char* /*language*/, UErrorCode *status) {
michael@0 789 const char* m_type = application_mimetype;
michael@0 790 char* sid = NULL;
michael@0 791 uint32_t crc = 0xFFFFFFFF;
michael@0 792
michael@0 793 char fileName[1024] ={0};
michael@0 794 int32_t tLen = ( outDir == NULL) ? 0 :(int32_t)uprv_strlen(outDir);
michael@0 795 char* fn = (char*) uprv_malloc(sizeof(char) * (tLen+1024 +
michael@0 796 (res->u.fBinaryValue.fFileName !=NULL ?
michael@0 797 uprv_strlen(res->u.fBinaryValue.fFileName) :0)));
michael@0 798 const char* ext = NULL;
michael@0 799
michael@0 800 char* f = NULL;
michael@0 801
michael@0 802 fn[0]=0;
michael@0 803
michael@0 804 if(res->u.fBinaryValue.fFileName != NULL){
michael@0 805 uprv_strcpy(fileName, res->u.fBinaryValue.fFileName);
michael@0 806 f = uprv_strrchr(fileName, '\\');
michael@0 807
michael@0 808 if (f != NULL) {
michael@0 809 f++;
michael@0 810 } else {
michael@0 811 f = fileName;
michael@0 812 }
michael@0 813
michael@0 814 ext = uprv_strrchr(fileName, '.');
michael@0 815
michael@0 816 if (ext == NULL) {
michael@0 817 fprintf(stderr, "Error: %s is an unknown binary filename type.\n", fileName);
michael@0 818 exit(U_ILLEGAL_ARGUMENT_ERROR);
michael@0 819 }
michael@0 820
michael@0 821 if(uprv_strcmp(ext, ".jpg")==0 || uprv_strcmp(ext, ".jpeg")==0 || uprv_strcmp(ext, ".gif")==0 ){
michael@0 822 m_type = "image";
michael@0 823 } else if(uprv_strcmp(ext, ".wav")==0 || uprv_strcmp(ext, ".au")==0 ){
michael@0 824 m_type = "audio";
michael@0 825 } else if(uprv_strcmp(ext, ".avi")==0 || uprv_strcmp(ext, ".mpg")==0 || uprv_strcmp(ext, ".mpeg")==0){
michael@0 826 m_type = "video";
michael@0 827 } else if(uprv_strcmp(ext, ".txt")==0 || uprv_strcmp(ext, ".text")==0){
michael@0 828 m_type = "text";
michael@0 829 }
michael@0 830
michael@0 831 sid = printContainer(res, bin_unit, binary_restype, m_type, id, status);
michael@0 832
michael@0 833 write_tabs(out);
michael@0 834
michael@0 835 write_utf8_file(out, UnicodeString(bin_source));
michael@0 836
michael@0 837 tabCount+= 1;
michael@0 838 write_tabs(out);
michael@0 839
michael@0 840 write_utf8_file(out, UnicodeString(external_file));
michael@0 841 printAttribute("href", f, (int32_t)uprv_strlen(f));
michael@0 842 write_utf8_file(out, UnicodeString("/>\n"));
michael@0 843 tabCount -= 1;
michael@0 844 write_tabs(out);
michael@0 845
michael@0 846 write_utf8_file(out, UnicodeString(close_bin_source));
michael@0 847
michael@0 848 printNoteElements(&res->fComment, status);
michael@0 849 tabCount -= 1;
michael@0 850 write_tabs(out);
michael@0 851 write_utf8_file(out, UnicodeString(close_bin_unit));
michael@0 852 } else {
michael@0 853 char temp[256] = {0};
michael@0 854 uint32_t i = 0;
michael@0 855 int32_t len=0;
michael@0 856
michael@0 857 sid = printContainer(res, bin_unit, binary_restype, m_type, id, status);
michael@0 858
michael@0 859 write_tabs(out);
michael@0 860 write_utf8_file(out, UnicodeString(bin_source));
michael@0 861
michael@0 862 tabCount += 1;
michael@0 863 write_tabs(out);
michael@0 864
michael@0 865 write_utf8_file(out, UnicodeString(internal_file));
michael@0 866 printAttribute("form", application_mimetype, (int32_t) uprv_strlen(application_mimetype));
michael@0 867
michael@0 868 while(i <res->u.fBinaryValue.fLength){
michael@0 869 len = itostr(temp, res->u.fBinaryValue.fData[i], 16, 2);
michael@0 870 crc = computeCRC(temp, len, crc);
michael@0 871 i++;
michael@0 872 }
michael@0 873
michael@0 874 len = itostr(temp, crc, 10, 0);
michael@0 875 printAttribute("crc", temp, len);
michael@0 876
michael@0 877 write_utf8_file(out, UnicodeString(">"));
michael@0 878
michael@0 879 i = 0;
michael@0 880 while(i <res->u.fBinaryValue.fLength){
michael@0 881 len = itostr(temp, res->u.fBinaryValue.fData[i], 16, 2);
michael@0 882 write_utf8_file(out, UnicodeString(temp));
michael@0 883 i += 1;
michael@0 884 }
michael@0 885
michael@0 886 write_utf8_file(out, UnicodeString(close_internal_file));
michael@0 887
michael@0 888 tabCount -= 2;
michael@0 889 write_tabs(out);
michael@0 890
michael@0 891 write_utf8_file(out, UnicodeString(close_bin_source));
michael@0 892 printNoteElements(&res->fComment, status);
michael@0 893
michael@0 894 tabCount -= 1;
michael@0 895 write_tabs(out);
michael@0 896 write_utf8_file(out, UnicodeString(close_bin_unit));
michael@0 897
michael@0 898 uprv_free(sid);
michael@0 899 sid = NULL;
michael@0 900 }
michael@0 901
michael@0 902 uprv_free(fn);
michael@0 903 }
michael@0 904
michael@0 905
michael@0 906
michael@0 907 static void
michael@0 908 table_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status) {
michael@0 909
michael@0 910 uint32_t i = 0;
michael@0 911
michael@0 912 struct SResource *current = NULL;
michael@0 913 char* sid = NULL;
michael@0 914
michael@0 915 if (U_FAILURE(*status)) {
michael@0 916 return ;
michael@0 917 }
michael@0 918
michael@0 919 sid = printContainer(res, group, table_restype, NULL, id, status);
michael@0 920
michael@0 921 if(isTopLevel) {
michael@0 922 sid[0] = '\0';
michael@0 923 }
michael@0 924
michael@0 925 current = res->u.fTable.fFirst;
michael@0 926 i = 0;
michael@0 927
michael@0 928 while (current != NULL) {
michael@0 929 res_write_xml(current, sid, language, FALSE, status);
michael@0 930
michael@0 931 if(U_FAILURE(*status)){
michael@0 932 return;
michael@0 933 }
michael@0 934
michael@0 935 i += 1;
michael@0 936 current = current->fNext;
michael@0 937 }
michael@0 938
michael@0 939 tabCount -= 1;
michael@0 940 write_tabs(out);
michael@0 941
michael@0 942 write_utf8_file(out, UnicodeString(close_group));
michael@0 943
michael@0 944 uprv_free(sid);
michael@0 945 sid = NULL;
michael@0 946 }
michael@0 947
michael@0 948 void
michael@0 949 res_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status) {
michael@0 950
michael@0 951 if (U_FAILURE(*status)) {
michael@0 952 return ;
michael@0 953 }
michael@0 954
michael@0 955 if (res != NULL) {
michael@0 956 switch (res->fType) {
michael@0 957 case URES_STRING:
michael@0 958 string_write_xml (res, id, language, status);
michael@0 959 return;
michael@0 960
michael@0 961 case URES_ALIAS:
michael@0 962 alias_write_xml (res, id, language, status);
michael@0 963 return;
michael@0 964
michael@0 965 case URES_INT_VECTOR:
michael@0 966 intvector_write_xml (res, id, language, status);
michael@0 967 return;
michael@0 968
michael@0 969 case URES_BINARY:
michael@0 970 bin_write_xml (res, id, language, status);
michael@0 971 return;
michael@0 972
michael@0 973 case URES_INT:
michael@0 974 int_write_xml (res, id, language, status);
michael@0 975 return;
michael@0 976
michael@0 977 case URES_ARRAY:
michael@0 978 array_write_xml (res, id, language, status);
michael@0 979 return;
michael@0 980
michael@0 981 case URES_TABLE:
michael@0 982 table_write_xml (res, id, language, isTopLevel, status);
michael@0 983 return;
michael@0 984
michael@0 985 default:
michael@0 986 break;
michael@0 987 }
michael@0 988 }
michael@0 989
michael@0 990 *status = U_INTERNAL_PROGRAM_ERROR;
michael@0 991 }
michael@0 992
michael@0 993 void
michael@0 994 bundle_write_xml(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc, const char* filename,
michael@0 995 char *writtenFilename, int writtenFilenameLen,
michael@0 996 const char* language, const char* outFileName, UErrorCode *status) {
michael@0 997
michael@0 998 char* xmlfileName = NULL;
michael@0 999 char* outputFileName = NULL;
michael@0 1000 char* originalFileName = NULL;
michael@0 1001 const char* fileStart = "<file xml:space = \"preserve\" source-language = \"";
michael@0 1002 const char* file1 = "\" datatype = \"x-icu-resource-bundle\" ";
michael@0 1003 const char* file2 = "original = \"";
michael@0 1004 const char* file4 = "\" date = \"";
michael@0 1005 const char* fileEnd = "</file>\n";
michael@0 1006 const char* headerStart = "<header>\n";
michael@0 1007 const char* headerEnd = "</header>\n";
michael@0 1008 const char* bodyStart = "<body>\n";
michael@0 1009 const char* bodyEnd = "</body>\n";
michael@0 1010
michael@0 1011 const char *tool_start = "<tool";
michael@0 1012 const char *tool_id = "genrb-" GENRB_VERSION "-icu-" U_ICU_VERSION;
michael@0 1013 const char *tool_name = "genrb";
michael@0 1014
michael@0 1015 char* temp = NULL;
michael@0 1016 char* lang = NULL;
michael@0 1017 const char* pos = NULL;
michael@0 1018 int32_t first, index;
michael@0 1019 time_t currTime;
michael@0 1020 char timeBuf[128];
michael@0 1021
michael@0 1022 outDir = outputDir;
michael@0 1023
michael@0 1024 srBundle = bundle;
michael@0 1025
michael@0 1026 pos = uprv_strrchr(filename, '\\');
michael@0 1027 if(pos != NULL) {
michael@0 1028 first = (int32_t)(pos - filename + 1);
michael@0 1029 } else {
michael@0 1030 first = 0;
michael@0 1031 }
michael@0 1032 index = (int32_t)(uprv_strlen(filename) - uprv_strlen(textExt) - first);
michael@0 1033 originalFileName = (char *)uprv_malloc(sizeof(char)*index+1);
michael@0 1034 uprv_memset(originalFileName, 0, sizeof(char)*index+1);
michael@0 1035 uprv_strncpy(originalFileName, filename + first, index);
michael@0 1036
michael@0 1037 if(uprv_strcmp(originalFileName, srBundle->fLocale) != 0) {
michael@0 1038 fprintf(stdout, "Warning: The file name is not same as the resource name!\n");
michael@0 1039 }
michael@0 1040
michael@0 1041 temp = originalFileName;
michael@0 1042 originalFileName = (char *)uprv_malloc(sizeof(char)* (uprv_strlen(temp)+uprv_strlen(textExt)) + 1);
michael@0 1043 uprv_memset(originalFileName, 0, sizeof(char)* (uprv_strlen(temp)+uprv_strlen(textExt)) + 1);
michael@0 1044 uprv_strcat(originalFileName, temp);
michael@0 1045 uprv_strcat(originalFileName, textExt);
michael@0 1046 uprv_free(temp);
michael@0 1047 temp = NULL;
michael@0 1048
michael@0 1049
michael@0 1050 if (language == NULL) {
michael@0 1051 /* lang = parseFilename(filename, lang);
michael@0 1052 if (lang == NULL) {*/
michael@0 1053 /* now check if locale name is valid or not
michael@0 1054 * this is to cater for situation where
michael@0 1055 * pegasusServer.txt contains
michael@0 1056 *
michael@0 1057 * en{
michael@0 1058 * ..
michael@0 1059 * }
michael@0 1060 */
michael@0 1061 lang = parseFilename(srBundle->fLocale, lang);
michael@0 1062 /*
michael@0 1063 * Neither the file name nor the table name inside the
michael@0 1064 * txt file contain a valid country and language codes
michael@0 1065 * throw an error.
michael@0 1066 * pegasusServer.txt contains
michael@0 1067 *
michael@0 1068 * testelements{
michael@0 1069 * ....
michael@0 1070 * }
michael@0 1071 */
michael@0 1072 if(lang==NULL){
michael@0 1073 fprintf(stderr, "Error: The file name and table name do not contain a valid language code. Please use -l option to specify it.\n");
michael@0 1074 exit(U_ILLEGAL_ARGUMENT_ERROR);
michael@0 1075 }
michael@0 1076 /* }*/
michael@0 1077 } else {
michael@0 1078 lang = (char *)uprv_malloc(sizeof(char)*uprv_strlen(language) +1);
michael@0 1079 uprv_memset(lang, 0, sizeof(char)*uprv_strlen(language) +1);
michael@0 1080 uprv_strcpy(lang, language);
michael@0 1081 }
michael@0 1082
michael@0 1083 if(outFileName) {
michael@0 1084 outputFileName = (char *)uprv_malloc(sizeof(char)*uprv_strlen(outFileName) + 1);
michael@0 1085 uprv_memset(outputFileName, 0, sizeof(char)*uprv_strlen(outFileName) + 1);
michael@0 1086 uprv_strcpy(outputFileName,outFileName);
michael@0 1087 } else {
michael@0 1088 outputFileName = (char *)uprv_malloc(sizeof(char)*uprv_strlen(srBundle->fLocale) + 1);
michael@0 1089 uprv_memset(outputFileName, 0, sizeof(char)*uprv_strlen(srBundle->fLocale) + 1);
michael@0 1090 uprv_strcpy(outputFileName,srBundle->fLocale);
michael@0 1091 }
michael@0 1092
michael@0 1093 if(outputDir) {
michael@0 1094 xmlfileName = (char *)uprv_malloc(sizeof(char)*(uprv_strlen(outputDir) + uprv_strlen(outputFileName) + uprv_strlen(xliffExt) + 1) +1);
michael@0 1095 uprv_memset(xmlfileName, 0, sizeof(char)*(uprv_strlen(outputDir)+ uprv_strlen(outputFileName) + uprv_strlen(xliffExt) + 1) +1);
michael@0 1096 } else {
michael@0 1097 xmlfileName = (char *)uprv_malloc(sizeof(char)*(uprv_strlen(outputFileName) + uprv_strlen(xliffExt)) +1);
michael@0 1098 uprv_memset(xmlfileName, 0, sizeof(char)*(uprv_strlen(outputFileName) + uprv_strlen(xliffExt)) +1);
michael@0 1099 }
michael@0 1100
michael@0 1101 if(outputDir){
michael@0 1102 uprv_strcpy(xmlfileName, outputDir);
michael@0 1103 if(outputDir[uprv_strlen(outputDir)-1] !=U_FILE_SEP_CHAR){
michael@0 1104 uprv_strcat(xmlfileName,U_FILE_SEP_STRING);
michael@0 1105 }
michael@0 1106 }
michael@0 1107 uprv_strcat(xmlfileName,outputFileName);
michael@0 1108 uprv_strcat(xmlfileName,xliffExt);
michael@0 1109
michael@0 1110 if (writtenFilename) {
michael@0 1111 uprv_strncpy(writtenFilename, xmlfileName, writtenFilenameLen);
michael@0 1112 }
michael@0 1113
michael@0 1114 if (U_FAILURE(*status)) {
michael@0 1115 goto cleanup_bundle_write_xml;
michael@0 1116 }
michael@0 1117
michael@0 1118 out= T_FileStream_open(xmlfileName,"w");
michael@0 1119
michael@0 1120 if(out==NULL){
michael@0 1121 *status = U_FILE_ACCESS_ERROR;
michael@0 1122 goto cleanup_bundle_write_xml;
michael@0 1123 }
michael@0 1124 write_utf8_file(out, xmlHeader);
michael@0 1125
michael@0 1126 if(outputEnc && *outputEnc!='\0'){
michael@0 1127 /* store the output encoding */
michael@0 1128 enc = outputEnc;
michael@0 1129 conv=ucnv_open(enc,status);
michael@0 1130 if(U_FAILURE(*status)){
michael@0 1131 goto cleanup_bundle_write_xml;
michael@0 1132 }
michael@0 1133 }
michael@0 1134 write_utf8_file(out, bundleStart);
michael@0 1135 write_tabs(out);
michael@0 1136 write_utf8_file(out, fileStart);
michael@0 1137 /* check if lang and language are the same */
michael@0 1138 if(language != NULL && uprv_strcmp(lang, srBundle->fLocale)!=0){
michael@0 1139 fprintf(stderr,"Warning: The top level tag in the resource and language specified are not the same. Please check the input.\n");
michael@0 1140 }
michael@0 1141 write_utf8_file(out, UnicodeString(lang));
michael@0 1142 write_utf8_file(out, UnicodeString(file1));
michael@0 1143 write_utf8_file(out, UnicodeString(file2));
michael@0 1144 write_utf8_file(out, UnicodeString(originalFileName));
michael@0 1145 write_utf8_file(out, UnicodeString(file4));
michael@0 1146
michael@0 1147 time(&currTime);
michael@0 1148 strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&currTime));
michael@0 1149 write_utf8_file(out, UnicodeString(timeBuf));
michael@0 1150 write_utf8_file(out, UnicodeString("\">\n"));
michael@0 1151
michael@0 1152 tabCount += 1;
michael@0 1153 write_tabs(out);
michael@0 1154 write_utf8_file(out, headerStart);
michael@0 1155
michael@0 1156 tabCount += 1;
michael@0 1157 write_tabs(out);
michael@0 1158
michael@0 1159 write_utf8_file(out, tool_start);
michael@0 1160 printAttribute("tool-id", tool_id, (int32_t) uprv_strlen(tool_id));
michael@0 1161 printAttribute("tool-name", tool_name, (int32_t) uprv_strlen(tool_name));
michael@0 1162 write_utf8_file(out, UnicodeString("/>\n"));
michael@0 1163
michael@0 1164 tabCount -= 1;
michael@0 1165 write_tabs(out);
michael@0 1166
michael@0 1167 write_utf8_file(out, UnicodeString(headerEnd));
michael@0 1168
michael@0 1169 write_tabs(out);
michael@0 1170 tabCount += 1;
michael@0 1171
michael@0 1172 write_utf8_file(out, UnicodeString(bodyStart));
michael@0 1173
michael@0 1174
michael@0 1175 res_write_xml(bundle->fRoot, bundle->fLocale, lang, TRUE, status);
michael@0 1176
michael@0 1177 tabCount -= 1;
michael@0 1178 write_tabs(out);
michael@0 1179
michael@0 1180 write_utf8_file(out, UnicodeString(bodyEnd));
michael@0 1181 tabCount--;
michael@0 1182 write_tabs(out);
michael@0 1183 write_utf8_file(out, UnicodeString(fileEnd));
michael@0 1184 tabCount--;
michael@0 1185 write_tabs(out);
michael@0 1186 write_utf8_file(out, UnicodeString(bundleEnd));
michael@0 1187 T_FileStream_close(out);
michael@0 1188
michael@0 1189 ucnv_close(conv);
michael@0 1190
michael@0 1191 cleanup_bundle_write_xml:
michael@0 1192 uprv_free(originalFileName);
michael@0 1193 uprv_free(lang);
michael@0 1194 if(xmlfileName != NULL) {
michael@0 1195 uprv_free(xmlfileName);
michael@0 1196 }
michael@0 1197 if(outputFileName != NULL){
michael@0 1198 uprv_free(outputFileName);
michael@0 1199 }
michael@0 1200 }

mercurial