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