OLD | NEW |
| (Empty) |
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 *r
esource, int32_t indent, const char *pname, UErrorCode *status); | |
44 static void printString(UFILE *out, UConverter *converter, const UChar *str, int
32_t len); | |
45 static void printCString(UFILE *out, UConverter *converter, const char *str, int
32_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_ESC
APE, 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, int
32_t len) { | |
381 u_file_write(str, len, out); | |
382 } | |
383 | |
384 static void printCString(UFILE *out, UConverter *converter, const char *str, int
32_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 *p
arent, Resource r, const char *key, int32_t indent, const char *pname, UErrorCod
e *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) / sizeo
f(*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 *r
esource, 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 t
o %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)/s
izeof(*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, 0x0
020, 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) / siz
eof(*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) / s
izeof(*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 t
o %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(*c
r))); | |
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(*c
r))); | |
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) / siz
eof(*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->fRe
s, 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+inden
tsize, 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) / s
izeof(*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_erro
rName(*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 */ | |
OLD | NEW |