Home | History | Annotate | Download | only in genrb
      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 (at) 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  */
    685