OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ******************************************************************************* |
| 3 * |
| 4 * Copyright (C) 1999-2010, International Business Machines |
| 5 * Corporation and others. All Rights Reserved. |
| 6 * |
| 7 ******************************************************************************* |
| 8 * file name: derb.c |
| 9 * encoding: US-ASCII |
| 10 * tab size: 8 (not used) |
| 11 * indentation:4 |
| 12 * |
| 13 * created on: 2000sep6 |
| 14 * created by: Vladimir Weinstein as an ICU workshop example |
| 15 * maintained by: Yves Arrouye <yves@realnames.com> |
| 16 */ |
| 17 |
| 18 #include "unicode/ucnv.h" |
| 19 #include "unicode/ustring.h" |
| 20 #include "unicode/putil.h" |
| 21 |
| 22 #include "uresimp.h" |
| 23 #include "cmemory.h" |
| 24 #include "cstring.h" |
| 25 #include "uoptions.h" |
| 26 #include "toolutil.h" |
| 27 #include "ustrfmt.h" |
| 28 |
| 29 #include <stdlib.h> |
| 30 #include <stdio.h> |
| 31 #include <ctype.h> |
| 32 |
| 33 #if defined(U_WINDOWS) || defined(U_CYGWIN) |
| 34 #include <io.h> |
| 35 #include <fcntl.h> |
| 36 #define USE_FILENO_BINARY_MODE 1 |
| 37 /* Windows likes to rename Unix-like functions */ |
| 38 #ifndef fileno |
| 39 #define fileno _fileno |
| 40 #endif |
| 41 #ifndef setmode |
| 42 #define setmode _setmode |
| 43 #endif |
| 44 #ifndef O_BINARY |
| 45 #define O_BINARY _O_BINARY |
| 46 #endif |
| 47 #endif |
| 48 |
| 49 #define DERB_VERSION "1.0" |
| 50 |
| 51 #define DERB_DEFAULT_TRUNC 80 |
| 52 |
| 53 static UConverter *defaultConverter = 0; |
| 54 |
| 55 static const int32_t indentsize = 4; |
| 56 static int32_t truncsize = DERB_DEFAULT_TRUNC; |
| 57 static UBool trunc = FALSE; |
| 58 |
| 59 static const char *getEncodingName(const char *encoding); |
| 60 static void reportError(const char *pname, UErrorCode *status, const char *when)
; |
| 61 static UChar *quotedString(const UChar *string); |
| 62 static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *re
source, int32_t indent, const char *pname, UErrorCode *status); |
| 63 static void printString(FILE *out, UConverter *converter, const UChar *str, int3
2_t len); |
| 64 static void printCString(FILE *out, UConverter *converter, const char *str, int3
2_t len); |
| 65 static void printIndent(FILE *out, UConverter *converter, int32_t indent); |
| 66 static void printHex(FILE *out, UConverter *converter, uint8_t what); |
| 67 |
| 68 static UOption options[]={ |
| 69 UOPTION_HELP_H, |
| 70 UOPTION_HELP_QUESTION_MARK, |
| 71 /* 2 */ UOPTION_ENCODING, |
| 72 /* 3 */ { "to-stdout", NULL, NULL, NULL, 'c', UOPT_NO_ARG, 0 } , |
| 73 /* 4 */ { "truncate", NULL, NULL, NULL, 't', UOPT_OPTIONAL_ARG, 0 }, |
| 74 /* 5 */ UOPTION_VERBOSE, |
| 75 /* 6 */ UOPTION_DESTDIR, |
| 76 /* 7 */ UOPTION_SOURCEDIR, |
| 77 /* 8 */ { "bom", NULL, NULL, NULL, 0, UOPT_NO_ARG, 0 }, |
| 78 /* 9 */ UOPTION_ICUDATADIR, |
| 79 /* 10 */ UOPTION_VERSION, |
| 80 /* 11 */ { "suppressAliases", NULL, NULL, NULL, 'A', UOPT_NO_ARG, 0 } |
| 81 }; |
| 82 |
| 83 static UBool verbose = FALSE; |
| 84 static UBool suppressAliases = FALSE; |
| 85 |
| 86 extern int |
| 87 main(int argc, char* argv[]) { |
| 88 const char *encoding = NULL; |
| 89 const char *outputDir = NULL; /* NULL = no output directory, use current */ |
| 90 const char *inputDir = "."; |
| 91 int tostdout = 0; |
| 92 int prbom = 0; |
| 93 |
| 94 const char *pname; |
| 95 |
| 96 UResourceBundle *bundle = NULL; |
| 97 UErrorCode status = U_ZERO_ERROR; |
| 98 int32_t i = 0; |
| 99 |
| 100 UConverter *converter; |
| 101 |
| 102 const char* arg; |
| 103 |
| 104 /* Get the name of tool. */ |
| 105 pname = uprv_strrchr(*argv, U_FILE_SEP_CHAR); |
| 106 #if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR |
| 107 if (!pname) { |
| 108 pname = uprv_strrchr(*argv, U_FILE_ALT_SEP_CHAR); |
| 109 } |
| 110 #endif |
| 111 if (!pname) { |
| 112 pname = *argv; |
| 113 } else { |
| 114 ++pname; |
| 115 } |
| 116 |
| 117 /* error handling, printing usage message */ |
| 118 argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options); |
| 119 |
| 120 /* error handling, printing usage message */ |
| 121 if(argc<0) { |
| 122 fprintf(stderr, |
| 123 "%s: error in command line argument \"%s\"\n", pname, |
| 124 argv[-argc]); |
| 125 } |
| 126 if(argc<0 || options[0].doesOccur || options[1].doesOccur) { |
| 127 fprintf(argc < 0 ? stderr : stdout, |
| 128 "%csage: %s [ -h, -?, --help ] [ -V, --version ]\n" |
| 129 " [ -v, --verbose ] [ -e, --encoding encoding ] [ --bom ]\n" |
| 130 " [ -t, --truncate [ size ] ]\n" |
| 131 " [ -s, --sourcedir source ] [ -d, --destdir destination ]\n" |
| 132 " [ -i, --icudatadir directory ] [ -c, --to-stdout ]\n" |
| 133 " [ -A, --suppressAliases]\n" |
| 134 " bundle ...\n", argc < 0 ? 'u' : 'U', |
| 135 pname); |
| 136 return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR; |
| 137 } |
| 138 |
| 139 if(options[10].doesOccur) { |
| 140 fprintf(stderr, |
| 141 "%s version %s (ICU version %s).\n" |
| 142 "%s\n", |
| 143 pname, DERB_VERSION, U_ICU_VERSION, U_COPYRIGHT_STRING); |
| 144 return U_ZERO_ERROR; |
| 145 } |
| 146 if(options[2].doesOccur) { |
| 147 encoding = options[2].value; |
| 148 } |
| 149 |
| 150 if (options[3].doesOccur) { |
| 151 tostdout = 1; |
| 152 } |
| 153 |
| 154 if(options[4].doesOccur) { |
| 155 trunc = TRUE; |
| 156 if(options[4].value != NULL) { |
| 157 truncsize = atoi(options[4].value); /* user defined printable size *
/ |
| 158 } else { |
| 159 truncsize = DERB_DEFAULT_TRUNC; /* we'll use default omitting size *
/ |
| 160 } |
| 161 } else { |
| 162 trunc = FALSE; |
| 163 } |
| 164 |
| 165 if(options[5].doesOccur) { |
| 166 verbose = TRUE; |
| 167 } |
| 168 |
| 169 if (options[6].doesOccur) { |
| 170 outputDir = options[6].value; |
| 171 } |
| 172 |
| 173 if(options[7].doesOccur) { |
| 174 inputDir = options[7].value; /* we'll use users resources */ |
| 175 } |
| 176 |
| 177 if (options[8].doesOccur) { |
| 178 prbom = 1; |
| 179 } |
| 180 |
| 181 if (options[9].doesOccur) { |
| 182 u_setDataDirectory(options[9].value); |
| 183 } |
| 184 |
| 185 if (options[11].doesOccur) { |
| 186 suppressAliases = TRUE; |
| 187 } |
| 188 |
| 189 converter = ucnv_open(encoding, &status); |
| 190 if (U_FAILURE(status)) { |
| 191 fprintf(stderr, "%s: couldn't create %s converter for encoding\n", pname
, encoding ? encoding : ucnv_getDefaultName()); |
| 192 return 2; |
| 193 } |
| 194 ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_C,
0, 0, &status); |
| 195 if (U_FAILURE(status)) { |
| 196 fprintf(stderr, "%s: couldn't configure converter for encoding\n", pname
); |
| 197 return 3; |
| 198 } |
| 199 |
| 200 defaultConverter = ucnv_open(0, &status); |
| 201 if (U_FAILURE(status)) { |
| 202 fprintf(stderr, "%s: couldn't create %s converter for encoding\n", ucnv_
getDefaultName(), pname); |
| 203 return 2; |
| 204 } |
| 205 |
| 206 for (i = 1; i < argc; ++i) { |
| 207 static const UChar sp[] = { 0x0020 }; /* " " */ |
| 208 char infile[4096]; /* XXX Sloppy. */ |
| 209 char locale[64]; |
| 210 const char *thename = 0, *p, *q; |
| 211 UBool fromICUData = FALSE; |
| 212 |
| 213 arg = getLongPathname(argv[i]); |
| 214 |
| 215 if (verbose) { |
| 216 printf("processing bundle \"%s\"\n", argv[i]); |
| 217 } |
| 218 |
| 219 p = uprv_strrchr(arg, U_FILE_SEP_CHAR); |
| 220 #if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR |
| 221 if (p == NULL) { |
| 222 p = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR); |
| 223 } |
| 224 #endif |
| 225 if (!p) { |
| 226 p = arg; |
| 227 } else { |
| 228 p++; |
| 229 } |
| 230 q = uprv_strrchr(p, '.'); |
| 231 if (!q) { |
| 232 for (q = p; *q; ++q) |
| 233 ; |
| 234 } |
| 235 uprv_strncpy(locale, p, q - p); |
| 236 locale[q - p] = 0; |
| 237 |
| 238 if (!(fromICUData = !uprv_strcmp(inputDir, "-"))) { |
| 239 UBool absfilename = *arg == U_FILE_SEP_CHAR; |
| 240 #ifdef U_WINDOWS |
| 241 if (!absfilename) { |
| 242 absfilename = (uprv_strlen(arg) > 2 && isalpha(arg[0]) |
| 243 && arg[1] == ':' && arg[2] == U_FILE_SEP_CHAR); |
| 244 } |
| 245 #endif |
| 246 if (absfilename) { |
| 247 thename = arg; |
| 248 } else { |
| 249 q = uprv_strrchr(arg, U_FILE_SEP_CHAR); |
| 250 #if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR |
| 251 if (q == NULL) { |
| 252 q = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR); |
| 253 } |
| 254 #endif |
| 255 uprv_strcpy(infile, inputDir); |
| 256 if(q != NULL) { |
| 257 uprv_strcat(infile, U_FILE_SEP_STRING); |
| 258 strncat(infile, arg, q-arg); |
| 259 } |
| 260 thename = infile; |
| 261 } |
| 262 } |
| 263 status = U_ZERO_ERROR; |
| 264 if (thename) { |
| 265 bundle = ures_openDirect(thename, locale, &status); |
| 266 } else { |
| 267 bundle = ures_open(fromICUData ? 0 : inputDir, locale, &status); |
| 268 } |
| 269 if (status == U_ZERO_ERROR) { |
| 270 FILE *out; |
| 271 |
| 272 const char *filename = 0; |
| 273 const char *ext = 0; |
| 274 |
| 275 if (!locale[0] || !tostdout) { |
| 276 filename = uprv_strrchr(arg, U_FILE_SEP_CHAR); |
| 277 |
| 278 #if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR |
| 279 if (!filename) { |
| 280 filename = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR); |
| 281 } |
| 282 #endif |
| 283 if (!filename) { |
| 284 filename = arg; |
| 285 } else { |
| 286 ++filename; |
| 287 } |
| 288 ext = uprv_strrchr(arg, '.'); |
| 289 if (!ext) { |
| 290 ext = filename + uprv_strlen(filename); |
| 291 } |
| 292 } |
| 293 |
| 294 if (tostdout) { |
| 295 out = stdout; |
| 296 #if defined(U_WINDOWS) || defined(U_CYGWIN) |
| 297 if (setmode(fileno(out), O_BINARY) == -1) { |
| 298 fprintf(stderr, "%s: couldn't set standard output to binary
mode\n", pname); |
| 299 return 4; |
| 300 } |
| 301 #endif |
| 302 } else { |
| 303 char thefile[4096], *tp; |
| 304 int32_t len; |
| 305 |
| 306 if (outputDir) { |
| 307 uprv_strcpy(thefile, outputDir); |
| 308 uprv_strcat(thefile, U_FILE_SEP_STRING); |
| 309 } else { |
| 310 *thefile = 0; |
| 311 } |
| 312 uprv_strcat(thefile, filename); |
| 313 tp = thefile + uprv_strlen(thefile); |
| 314 len = (int32_t)uprv_strlen(ext); |
| 315 if (len) { |
| 316 tp -= len - 1; |
| 317 } else { |
| 318 *tp++ = '.'; |
| 319 } |
| 320 uprv_strcpy(tp, "txt"); |
| 321 |
| 322 out = fopen(thefile, "w"); |
| 323 if (!out) { |
| 324 fprintf(stderr, "%s: couldn't create %s\n", pname, thefile); |
| 325 return 4; |
| 326 } |
| 327 } |
| 328 |
| 329 if (prbom) { /* XXX: Should be done only for UTFs */ |
| 330 static const UChar bom[] = { 0xFEFF }; |
| 331 printString(out, converter, bom, (int32_t)(sizeof(bom)/sizeof(*b
om))); |
| 332 } |
| 333 |
| 334 printCString(out, converter, "// -*- Coding: ", -1); |
| 335 printCString(out, converter, encoding ? encoding : getEncodingName(u
cnv_getDefaultName()), -1); |
| 336 printCString(out, converter, "; -*-\n//\n", -1); |
| 337 printCString(out, converter, "// This file was dumped by derb(8) fro
m ", -1); |
| 338 if (thename) { |
| 339 printCString(out, converter, thename, -1); |
| 340 } else if (fromICUData) { |
| 341 printCString(out, converter, "the ICU internal ", -1); |
| 342 printCString(out, converter, locale, -1); |
| 343 printCString(out, converter, " locale", -1); |
| 344 } |
| 345 |
| 346 printCString(out, converter, "\n// derb(8) by Vladimir Weinstein and
Yves Arrouye\n\n", -1); |
| 347 |
| 348 if (locale[0]) { |
| 349 printCString(out, converter, locale, -1); |
| 350 } else { |
| 351 printCString(out, converter, filename, (int32_t)(ext - filename)
); |
| 352 printString(out, converter, sp, (int32_t)(sizeof(sp)/sizeof(*sp)
)); |
| 353 } |
| 354 printOutBundle(out, converter, bundle, 0, pname, &status); |
| 355 |
| 356 if (out != stdout) { |
| 357 fclose(out); |
| 358 } |
| 359 } |
| 360 else { |
| 361 reportError(pname, &status, "opening resource file"); |
| 362 } |
| 363 |
| 364 ures_close(bundle); |
| 365 } |
| 366 |
| 367 ucnv_close(defaultConverter); |
| 368 ucnv_close(converter); |
| 369 |
| 370 return 0; |
| 371 } |
| 372 |
| 373 static UChar *quotedString(const UChar *string) { |
| 374 int len = u_strlen(string); |
| 375 int alen = len; |
| 376 const UChar *sp; |
| 377 UChar *newstr, *np; |
| 378 |
| 379 for (sp = string; *sp; ++sp) { |
| 380 switch (*sp) { |
| 381 case '\n': |
| 382 case 0x0022: |
| 383 ++alen; |
| 384 break; |
| 385 } |
| 386 } |
| 387 |
| 388 newstr = (UChar *) uprv_malloc((1 + alen) * sizeof(*newstr)); |
| 389 for (sp = string, np = newstr; *sp; ++sp) { |
| 390 switch (*sp) { |
| 391 case '\n': |
| 392 *np++ = 0x005C; |
| 393 *np++ = 0x006E; |
| 394 break; |
| 395 |
| 396 case 0x0022: |
| 397 *np++ = 0x005C; |
| 398 |
| 399 default: |
| 400 *np++ = *sp; |
| 401 break; |
| 402 } |
| 403 } |
| 404 *np = 0; |
| 405 |
| 406 return newstr; |
| 407 } |
| 408 |
| 409 |
| 410 static void printString(FILE *out, UConverter *converter, const UChar *str, int3
2_t len) { |
| 411 char buf[256]; |
| 412 const UChar *strEnd; |
| 413 |
| 414 if (len < 0) { |
| 415 len = u_strlen(str); |
| 416 } |
| 417 strEnd = str + len; |
| 418 |
| 419 do { |
| 420 UErrorCode err = U_ZERO_ERROR; |
| 421 char *bufp = buf, *bufend = buf + sizeof(buf) - 1 ; |
| 422 |
| 423 ucnv_fromUnicode(converter, &bufp, bufend, &str, strEnd, 0, 0, &err); |
| 424 *bufp = 0; |
| 425 |
| 426 fprintf(out, "%s", buf); |
| 427 } while (str < strEnd); |
| 428 } |
| 429 |
| 430 static void printCString(FILE *out, UConverter *converter, const char *str, int3
2_t len) { |
| 431 UChar buf[256]; |
| 432 const char *strEnd; |
| 433 |
| 434 if (len < 0) { |
| 435 len = (int32_t)uprv_strlen(str); |
| 436 } |
| 437 strEnd = str + len; |
| 438 |
| 439 do { |
| 440 UErrorCode err = U_ZERO_ERROR; |
| 441 UChar *bufp = buf, *bufend = buf + (sizeof(buf)/sizeof(buf[0])) - 1 ; |
| 442 |
| 443 ucnv_toUnicode(defaultConverter, &bufp, bufend, &str, strEnd, 0, 0, &err
); |
| 444 *bufp = 0; |
| 445 |
| 446 printString(out, converter, buf, (int32_t)(bufp - buf)); |
| 447 } while (str < strEnd); |
| 448 } |
| 449 |
| 450 static void printIndent(FILE *out, UConverter *converter, int32_t indent) { |
| 451 UChar inchar[256]; |
| 452 int32_t i = 0; |
| 453 for(i = 0; i<indent; i++) { |
| 454 inchar[i] = 0x0020; |
| 455 } |
| 456 inchar[indent] = 0; |
| 457 |
| 458 printString(out, converter, inchar, indent); |
| 459 } |
| 460 |
| 461 static void printHex(FILE *out, UConverter *converter, uint8_t what) { |
| 462 static const char map[] = "0123456789ABCDEF"; |
| 463 UChar hex[2]; |
| 464 |
| 465 hex[0] = map[what >> 4]; |
| 466 hex[1] = map[what & 0xf]; |
| 467 |
| 468 printString(out, converter, hex, (int32_t)(sizeof(hex)/sizeof(*hex))); |
| 469 } |
| 470 |
| 471 static void printOutAlias(FILE *out, UConverter *converter, UResourceBundle *pa
rent, Resource r, const char *key, int32_t indent, const char *pname, UErrorCode
*status) { |
| 472 static const UChar cr[] = { '\n' }; |
| 473 int32_t len = 0; |
| 474 const UChar* thestr = res_getAlias(&(parent->fResData), r, &len); |
| 475 UChar *string = quotedString(thestr); |
| 476 if(trunc && len > truncsize) { |
| 477 char msg[128]; |
| 478 printIndent(out, converter, indent); |
| 479 sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n"
, |
| 480 (long)len, (long)truncsize/2); |
| 481 printCString(out, converter, msg, -1); |
| 482 len = truncsize; |
| 483 } |
| 484 if(U_SUCCESS(*status)) { |
| 485 static const UChar openStr[] = { 0x003A, 0x0061, 0x006C, 0x0069, 0x0061,
0x0073, 0x0020, 0x007B, 0x0020, 0x0022 }; /* ":alias { \"" */ |
| 486 static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D, 0x0020 }; /* "
\" } " */ |
| 487 printIndent(out, converter, indent); |
| 488 if(key != NULL) { |
| 489 printCString(out, converter, key, -1); |
| 490 } |
| 491 printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(
*openStr))); |
| 492 printString(out, converter, string, len); |
| 493 printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeo
f(*closeStr))); |
| 494 if(verbose) { |
| 495 printCString(out, converter, " // ALIAS", -1); |
| 496 } |
| 497 printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); |
| 498 } else { |
| 499 reportError(pname, status, "getting binary value"); |
| 500 } |
| 501 uprv_free(string); |
| 502 } |
| 503 |
| 504 static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *re
source, int32_t indent, const char *pname, UErrorCode *status) |
| 505 { |
| 506 static const UChar cr[] = { '\n' }; |
| 507 |
| 508 /* int32_t noOfElements = ures_getSize(resource);*/ |
| 509 int32_t i = 0; |
| 510 const char *key = ures_getKey(resource); |
| 511 |
| 512 switch(ures_getType(resource)) { |
| 513 case URES_STRING : |
| 514 { |
| 515 int32_t len=0; |
| 516 const UChar* thestr = ures_getString(resource, &len, status); |
| 517 UChar *string = quotedString(thestr); |
| 518 |
| 519 /* TODO: String truncation */ |
| 520 if(trunc && len > truncsize) { |
| 521 char msg[128]; |
| 522 printIndent(out, converter, indent); |
| 523 sprintf(msg, "// WARNING: this resource, size %li is truncated t
o %li\n", |
| 524 (long)len, (long)(truncsize/2)); |
| 525 printCString(out, converter, msg, -1); |
| 526 len = truncsize/2; |
| 527 } |
| 528 printIndent(out, converter, indent); |
| 529 if(key != NULL) { |
| 530 static const UChar openStr[] = { 0x0020, 0x007B, 0x0020, 0x0022
}; /* " { \"" */ |
| 531 static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D }; /* "
\" }" */ |
| 532 printCString(out, converter, key, (int32_t)uprv_strlen(key)); |
| 533 printString(out, converter, openStr, (int32_t)(sizeof(openStr)/s
izeof(*openStr))); |
| 534 printString(out, converter, string, len); |
| 535 printString(out, converter, closeStr, (int32_t)(sizeof(closeStr)
/ sizeof(*closeStr))); |
| 536 } else { |
| 537 static const UChar openStr[] = { 0x0022 }; /* "\"" */ |
| 538 static const UChar closeStr[] = { 0x0022, 0x002C }; /* "\"," */ |
| 539 |
| 540 printString(out, converter, openStr, (int32_t)(sizeof(openStr) /
sizeof(*openStr))); |
| 541 printString(out, converter, string, (int32_t)(u_strlen(string)))
; |
| 542 printString(out, converter, closeStr, (int32_t)(sizeof(closeStr)
/ sizeof(*closeStr))); |
| 543 } |
| 544 |
| 545 if(verbose) { |
| 546 printCString(out, converter, "// STRING", -1); |
| 547 } |
| 548 printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)))
; |
| 549 |
| 550 uprv_free(string); |
| 551 } |
| 552 break; |
| 553 |
| 554 case URES_INT : |
| 555 { |
| 556 static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0
020, 0x007B, 0x0020 }; /* ":int { " */ |
| 557 static const UChar closeStr[] = { 0x0020, 0x007D }; /* " }" */ |
| 558 UChar num[20]; |
| 559 |
| 560 printIndent(out, converter, indent); |
| 561 if(key != NULL) { |
| 562 printCString(out, converter, key, -1); |
| 563 } |
| 564 printString(out, converter, openStr, (int32_t)(sizeof(openStr) / siz
eof(*openStr))); |
| 565 uprv_itou(num, 20, ures_getInt(resource, status), 10, 0); |
| 566 printString(out, converter, num, u_strlen(num)); |
| 567 printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / s
izeof(*closeStr))); |
| 568 |
| 569 if(verbose) { |
| 570 printCString(out, converter, "// INT", -1); |
| 571 } |
| 572 printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)))
; |
| 573 break; |
| 574 } |
| 575 case URES_BINARY : |
| 576 { |
| 577 int32_t len = 0; |
| 578 const int8_t *data = (const int8_t *)ures_getBinary(resource, &len,
status); |
| 579 if(trunc && len > truncsize) { |
| 580 char msg[128]; |
| 581 printIndent(out, converter, indent); |
| 582 sprintf(msg, "// WARNING: this resource, size %li is truncated t
o %li\n", |
| 583 (long)len, (long)(truncsize/2)); |
| 584 printCString(out, converter, msg, -1); |
| 585 len = truncsize; |
| 586 } |
| 587 if(U_SUCCESS(*status)) { |
| 588 static const UChar openStr[] = { 0x003A, 0x0062, 0x0069, 0x006E,
0x0061, 0x0072, 0x0079, 0x0020, 0x007B, 0x0020 }; /* ":binary { " */ |
| 589 static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* "
} " */ |
| 590 printIndent(out, converter, indent); |
| 591 if(key != NULL) { |
| 592 printCString(out, converter, key, -1); |
| 593 } |
| 594 printString(out, converter, openStr, (int32_t)(sizeof(openStr) /
sizeof(*openStr))); |
| 595 for(i = 0; i<len; i++) { |
| 596 printHex(out, converter, *data++); |
| 597 } |
| 598 printString(out, converter, closeStr, (int32_t)(sizeof(closeStr)
/ sizeof(*closeStr))); |
| 599 if(verbose) { |
| 600 printCString(out, converter, " // BINARY", -1); |
| 601 } |
| 602 printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*c
r))); |
| 603 } else { |
| 604 reportError(pname, status, "getting binary value"); |
| 605 } |
| 606 } |
| 607 break; |
| 608 case URES_INT_VECTOR : |
| 609 { |
| 610 int32_t len = 0; |
| 611 const int32_t *data = ures_getIntVector(resource, &len, status); |
| 612 if(U_SUCCESS(*status)) { |
| 613 static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074,
0x0076, 0x0065, 0x0063, 0x0074, 0x006F, 0x0072, 0x0020, 0x007B, 0x0020 }; /* ":
intvector { " */ |
| 614 static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* "
} " */ |
| 615 UChar num[20]; |
| 616 |
| 617 printIndent(out, converter, indent); |
| 618 if(key != NULL) { |
| 619 printCString(out, converter, key, -1); |
| 620 } |
| 621 printString(out, converter, openStr, (int32_t)(sizeof(openStr) /
sizeof(*openStr))); |
| 622 for(i = 0; i < len - 1; i++) { |
| 623 int32_t numLen = uprv_itou(num, 20, data[i], 10, 0); |
| 624 num[numLen++] = 0x002C; /* ',' */ |
| 625 num[numLen++] = 0x0020; /* ' ' */ |
| 626 num[numLen] = 0; |
| 627 printString(out, converter, num, u_strlen(num)); |
| 628 } |
| 629 if(len > 0) { |
| 630 uprv_itou(num, 20, data[len - 1], 10, 0); |
| 631 printString(out, converter, num, u_strlen(num)); |
| 632 } |
| 633 printString(out, converter, closeStr, (int32_t)(sizeof(closeStr)
/ sizeof(*closeStr))); |
| 634 if(verbose) { |
| 635 printCString(out, converter, "// INTVECTOR", -1); |
| 636 } |
| 637 printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*c
r))); |
| 638 } else { |
| 639 reportError(pname, status, "getting int vector"); |
| 640 } |
| 641 } |
| 642 break; |
| 643 case URES_TABLE : |
| 644 case URES_ARRAY : |
| 645 { |
| 646 static const UChar openStr[] = { 0x007B }; /* "{" */ |
| 647 static const UChar closeStr[] = { 0x007D, '\n' }; /* "}\n" */ |
| 648 |
| 649 UResourceBundle *t = NULL; |
| 650 ures_resetIterator(resource); |
| 651 printIndent(out, converter, indent); |
| 652 if(key != NULL) { |
| 653 printCString(out, converter, key, -1); |
| 654 } |
| 655 printString(out, converter, openStr, (int32_t)(sizeof(openStr) / siz
eof(*openStr))); |
| 656 if(verbose) { |
| 657 if(ures_getType(resource) == URES_TABLE) { |
| 658 printCString(out, converter, "// TABLE", -1); |
| 659 } else { |
| 660 printCString(out, converter, "// ARRAY", -1); |
| 661 } |
| 662 } |
| 663 printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)))
; |
| 664 |
| 665 if(suppressAliases == FALSE) { |
| 666 while(U_SUCCESS(*status) && ures_hasNext(resource)) { |
| 667 t = ures_getNextResource(resource, t, status); |
| 668 if(U_SUCCESS(*status)) { |
| 669 printOutBundle(out, converter, t, indent+indentsize, pname,
status); |
| 670 } else { |
| 671 reportError(pname, status, "While processing table"); |
| 672 *status = U_ZERO_ERROR; |
| 673 } |
| 674 } |
| 675 } else { /* we have to use low level access to do this */ |
| 676 Resource r; |
| 677 int32_t resSize = ures_getSize(resource); |
| 678 UBool isTable = (UBool)(ures_getType(resource) == URES_TABLE); |
| 679 for(i = 0; i < resSize; i++) { |
| 680 /* need to know if it's an alias */ |
| 681 if(isTable) { |
| 682 r = res_getTableItemByIndex(&resource->fResData, resource->fRe
s, i, &key); |
| 683 } else { |
| 684 r = res_getArrayItem(&resource->fResData, resource->fRes, i); |
| 685 } |
| 686 if(U_SUCCESS(*status)) { |
| 687 if(res_getPublicType(r) == URES_ALIAS) { |
| 688 printOutAlias(out, converter, resource, r, key, indent+inden
tsize, pname, status); |
| 689 } else { |
| 690 t = ures_getByIndex(resource, i, t, status); |
| 691 printOutBundle(out, converter, t, indent+indentsize, pname,
status); |
| 692 } |
| 693 } else { |
| 694 reportError(pname, status, "While processing table"); |
| 695 *status = U_ZERO_ERROR; |
| 696 } |
| 697 } |
| 698 } |
| 699 |
| 700 printIndent(out, converter, indent); |
| 701 printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / s
izeof(*closeStr))); |
| 702 ures_close(t); |
| 703 } |
| 704 break; |
| 705 default: |
| 706 break; |
| 707 } |
| 708 |
| 709 } |
| 710 |
| 711 static const char *getEncodingName(const char *encoding) { |
| 712 UErrorCode err; |
| 713 const char *enc; |
| 714 |
| 715 err = U_ZERO_ERROR; |
| 716 if (!(enc = ucnv_getStandardName(encoding, "MIME", &err))) { |
| 717 err = U_ZERO_ERROR; |
| 718 if (!(enc = ucnv_getStandardName(encoding, "IANA", &err))) { |
| 719 ; |
| 720 } |
| 721 } |
| 722 |
| 723 return enc; |
| 724 } |
| 725 |
| 726 static void reportError(const char *pname, UErrorCode *status, const char *when)
{ |
| 727 fprintf(stderr, "%s: error %d while %s: %s\n", pname, *status, when, u_error
Name(*status)); |
| 728 } |
| 729 |
| 730 /* |
| 731 * Local Variables: |
| 732 * indent-tabs-mode: nil |
| 733 * End: |
| 734 */ |
| 735 |
| 736 |
OLD | NEW |