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