intl/icu/source/tools/genrb/derb.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/intl/icu/source/tools/genrb/derb.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,684 @@
     1.4 +/*
     1.5 +*******************************************************************************
     1.6 +*
     1.7 +*   Copyright (C) 1999-2013, International Business Machines
     1.8 +*   Corporation and others.  All Rights Reserved.
     1.9 +*
    1.10 +*******************************************************************************
    1.11 +*   file name:  derb.c
    1.12 +*   encoding:   US-ASCII
    1.13 +*   tab size:   8 (not used)
    1.14 +*   indentation:4
    1.15 +*
    1.16 +*   created on: 2000sep6
    1.17 +*   created by: Vladimir Weinstein as an ICU workshop example
    1.18 +*   maintained by: Yves Arrouye <yves@realnames.com>
    1.19 +*/
    1.20 +
    1.21 +#include "unicode/ucnv.h"
    1.22 +#include "unicode/ustring.h"
    1.23 +#include "unicode/putil.h"
    1.24 +#include "unicode/ustdio.h"
    1.25 +
    1.26 +#include "uresimp.h"
    1.27 +#include "cmemory.h"
    1.28 +#include "cstring.h"
    1.29 +#include "uoptions.h"
    1.30 +#include "toolutil.h"
    1.31 +#include "ustrfmt.h"
    1.32 +
    1.33 +#if !UCONFIG_NO_FORMATTING
    1.34 +
    1.35 +#define DERB_VERSION "1.1"
    1.36 +
    1.37 +#define DERB_DEFAULT_TRUNC 80
    1.38 +
    1.39 +static const int32_t indentsize = 4;
    1.40 +static int32_t truncsize = DERB_DEFAULT_TRUNC;
    1.41 +static UBool opt_truncate = FALSE;
    1.42 +
    1.43 +static const char *getEncodingName(const char *encoding);
    1.44 +static void reportError(const char *pname, UErrorCode *status, const char *when);
    1.45 +static UChar *quotedString(const UChar *string);
    1.46 +static void printOutBundle(UFILE *out, UConverter *converter, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status);
    1.47 +static void printString(UFILE *out, UConverter *converter, const UChar *str, int32_t len);
    1.48 +static void printCString(UFILE *out, UConverter *converter, const char *str, int32_t len);
    1.49 +static void printIndent(UFILE *out, UConverter *converter, int32_t indent);
    1.50 +static void printHex(UFILE *out, UConverter *converter, uint8_t what);
    1.51 +
    1.52 +static UOption options[]={
    1.53 +    UOPTION_HELP_H,
    1.54 +    UOPTION_HELP_QUESTION_MARK,
    1.55 +/* 2 */    UOPTION_ENCODING,
    1.56 +/* 3 */    { "to-stdout", NULL, NULL, NULL, 'c', UOPT_NO_ARG, 0 } ,
    1.57 +/* 4 */    { "truncate", NULL, NULL, NULL, 't', UOPT_OPTIONAL_ARG, 0 },
    1.58 +/* 5 */    UOPTION_VERBOSE,
    1.59 +/* 6 */    UOPTION_DESTDIR,
    1.60 +/* 7 */    UOPTION_SOURCEDIR,
    1.61 +/* 8 */    { "bom", NULL, NULL, NULL, 0, UOPT_NO_ARG, 0 },
    1.62 +/* 9 */    UOPTION_ICUDATADIR,
    1.63 +/* 10 */   UOPTION_VERSION,
    1.64 +/* 11 */   { "suppressAliases", NULL, NULL, NULL, 'A', UOPT_NO_ARG, 0 },
    1.65 +};
    1.66 +
    1.67 +static UBool verbose = FALSE;
    1.68 +static UBool suppressAliases = FALSE;
    1.69 +static UFILE *ustderr = NULL;
    1.70 +
    1.71 +extern int
    1.72 +main(int argc, char* argv[]) {
    1.73 +    const char *encoding = NULL;
    1.74 +    const char *outputDir = NULL; /* NULL = no output directory, use current */
    1.75 +    const char *inputDir  = ".";
    1.76 +    int tostdout = 0;
    1.77 +    int prbom = 0;
    1.78 +
    1.79 +    const char *pname;
    1.80 +
    1.81 +    UResourceBundle *bundle = NULL;
    1.82 +    UErrorCode status = U_ZERO_ERROR;
    1.83 +    int32_t i = 0;
    1.84 +
    1.85 +    UConverter *converter = NULL; // not used
    1.86 +
    1.87 +    const char* arg;
    1.88 +
    1.89 +    /* Get the name of tool. */
    1.90 +    pname = uprv_strrchr(*argv, U_FILE_SEP_CHAR);
    1.91 +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR
    1.92 +    if (!pname) {
    1.93 +        pname = uprv_strrchr(*argv, U_FILE_ALT_SEP_CHAR);
    1.94 +    }
    1.95 +#endif
    1.96 +    if (!pname) {
    1.97 +        pname = *argv;
    1.98 +    } else {
    1.99 +        ++pname;
   1.100 +    }
   1.101 +
   1.102 +    /* error handling, printing usage message */
   1.103 +    argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);
   1.104 +
   1.105 +    /* error handling, printing usage message */
   1.106 +    if(argc<0) {
   1.107 +        fprintf(stderr,
   1.108 +            "%s: error in command line argument \"%s\"\n", pname,
   1.109 +            argv[-argc]);
   1.110 +    }
   1.111 +    if(argc<0 || options[0].doesOccur || options[1].doesOccur) {
   1.112 +        fprintf(argc < 0 ? stderr : stdout,
   1.113 +            "%csage: %s [ -h, -?, --help ] [ -V, --version ]\n"
   1.114 +            " [ -v, --verbose ] [ -e, --encoding encoding ] [ --bom ]\n"
   1.115 +            " [ -t, --truncate [ size ] ]\n"
   1.116 +            " [ -s, --sourcedir source ] [ -d, --destdir destination ]\n"
   1.117 +            " [ -i, --icudatadir directory ] [ -c, --to-stdout ]\n"
   1.118 +            " [ -A, --suppressAliases]\n"
   1.119 +            " bundle ...\n", argc < 0 ? 'u' : 'U',
   1.120 +            pname);
   1.121 +        return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
   1.122 +    }
   1.123 +
   1.124 +    if(options[10].doesOccur) {
   1.125 +        fprintf(stderr,
   1.126 +                "%s version %s (ICU version %s).\n"
   1.127 +                "%s\n",
   1.128 +                pname, DERB_VERSION, U_ICU_VERSION, U_COPYRIGHT_STRING);
   1.129 +        return U_ZERO_ERROR;
   1.130 +    }
   1.131 +    if(options[2].doesOccur) {
   1.132 +        encoding = options[2].value;
   1.133 +    }
   1.134 +
   1.135 +    if (options[3].doesOccur) {
   1.136 +      if(options[2].doesOccur) {
   1.137 +        fprintf(stderr, "%s: Error: don't specify an encoding (-e) when writing to stdout (-c).\n", pname);
   1.138 +        return 3;
   1.139 +      }
   1.140 +      tostdout = 1;
   1.141 +    }
   1.142 +
   1.143 +    if(options[4].doesOccur) {
   1.144 +        opt_truncate = TRUE;
   1.145 +        if(options[4].value != NULL) {
   1.146 +            truncsize = atoi(options[4].value); /* user defined printable size */
   1.147 +        } else {
   1.148 +            truncsize = DERB_DEFAULT_TRUNC; /* we'll use default omitting size */
   1.149 +        }
   1.150 +    } else {
   1.151 +        opt_truncate = FALSE;
   1.152 +    }
   1.153 +
   1.154 +    if(options[5].doesOccur) {
   1.155 +        verbose = TRUE;
   1.156 +    }
   1.157 +
   1.158 +    if (options[6].doesOccur) {
   1.159 +        outputDir = options[6].value;
   1.160 +    }
   1.161 +
   1.162 +    if(options[7].doesOccur) {
   1.163 +        inputDir = options[7].value; /* we'll use users resources */
   1.164 +    }
   1.165 +
   1.166 +    if (options[8].doesOccur) {
   1.167 +        prbom = 1;
   1.168 +    }
   1.169 +
   1.170 +    if (options[9].doesOccur) {
   1.171 +        u_setDataDirectory(options[9].value);
   1.172 +    }
   1.173 +
   1.174 +    if (options[11].doesOccur) {
   1.175 +      suppressAliases = TRUE;
   1.176 +    }
   1.177 +
   1.178 +    fflush(stderr); // use ustderr now.
   1.179 +    ustderr = u_finit(stderr, NULL, NULL);
   1.180 +
   1.181 +    for (i = 1; i < argc; ++i) {
   1.182 +        static const UChar sp[] = { 0x0020 }; /* " " */
   1.183 +        char infile[4096]; /* XXX Sloppy. */
   1.184 +        char locale[64];
   1.185 +        const char *thename = 0, *p, *q;
   1.186 +        UBool fromICUData = FALSE;
   1.187 +
   1.188 +        arg = getLongPathname(argv[i]);
   1.189 +
   1.190 +        if (verbose) {
   1.191 +          u_fprintf(ustderr, "processing bundle \"%s\"\n", argv[i]);
   1.192 +        }
   1.193 +
   1.194 +        p = uprv_strrchr(arg, U_FILE_SEP_CHAR);
   1.195 +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR
   1.196 +        if (p == NULL) {
   1.197 +            p = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR);
   1.198 +        }
   1.199 +#endif
   1.200 +        if (!p) {
   1.201 +            p = arg;
   1.202 +        } else {
   1.203 +            p++;
   1.204 +        }
   1.205 +        q = uprv_strrchr(p, '.');
   1.206 +        if (!q) {
   1.207 +            for (q = p; *q; ++q)
   1.208 +                ;
   1.209 +        }
   1.210 +        uprv_strncpy(locale, p, q - p);
   1.211 +        locale[q - p] = 0;
   1.212 +
   1.213 +        if (!(fromICUData = !uprv_strcmp(inputDir, "-"))) {
   1.214 +            UBool absfilename = *arg == U_FILE_SEP_CHAR;
   1.215 +#if U_PLATFORM_HAS_WIN32_API
   1.216 +            if (!absfilename) {
   1.217 +                absfilename = (uprv_strlen(arg) > 2 && isalpha(arg[0])
   1.218 +                    && arg[1] == ':' && arg[2] == U_FILE_SEP_CHAR);
   1.219 +            }
   1.220 +#endif
   1.221 +            if (absfilename) {
   1.222 +                thename = arg;
   1.223 +            } else {
   1.224 +                q = uprv_strrchr(arg, U_FILE_SEP_CHAR);
   1.225 +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR
   1.226 +                if (q == NULL) {
   1.227 +                    q = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR);
   1.228 +                }
   1.229 +#endif
   1.230 +                uprv_strcpy(infile, inputDir);
   1.231 +                if(q != NULL) {
   1.232 +                    uprv_strcat(infile, U_FILE_SEP_STRING);
   1.233 +                    strncat(infile, arg, q-arg);
   1.234 +                }
   1.235 +                thename = infile;
   1.236 +            }
   1.237 +        }
   1.238 +        status = U_ZERO_ERROR;
   1.239 +        if (thename) {
   1.240 +            bundle = ures_openDirect(thename, locale, &status);
   1.241 +        } else {
   1.242 +            bundle = ures_open(fromICUData ? 0 : inputDir, locale, &status);
   1.243 +        }
   1.244 +        if (status == U_ZERO_ERROR) {
   1.245 +            UFILE *out = NULL;
   1.246 +
   1.247 +            const char *filename = 0;
   1.248 +            const char *ext = 0;
   1.249 +
   1.250 +            if (!locale[0] || !tostdout) {
   1.251 +                filename = uprv_strrchr(arg, U_FILE_SEP_CHAR);
   1.252 +
   1.253 +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR
   1.254 +                if (!filename) {
   1.255 +                    filename = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR);
   1.256 +                }
   1.257 +#endif
   1.258 +                if (!filename) {
   1.259 +                    filename = arg;
   1.260 +                } else {
   1.261 +                    ++filename;
   1.262 +                }
   1.263 +                ext = uprv_strrchr(arg, '.');
   1.264 +                if (!ext) {
   1.265 +                    ext = filename + uprv_strlen(filename);
   1.266 +                }
   1.267 +            }
   1.268 +
   1.269 +            if (tostdout) {
   1.270 +                out = u_get_stdout();
   1.271 +            } else {
   1.272 +                char thefile[4096], *tp;
   1.273 +                int32_t len;
   1.274 +
   1.275 +                if (outputDir) {
   1.276 +                    uprv_strcpy(thefile, outputDir);
   1.277 +                    uprv_strcat(thefile, U_FILE_SEP_STRING);
   1.278 +                } else {
   1.279 +                    *thefile = 0;
   1.280 +                }
   1.281 +                uprv_strcat(thefile, filename);
   1.282 +                tp = thefile + uprv_strlen(thefile);
   1.283 +                len = (int32_t)uprv_strlen(ext);
   1.284 +                if (len) {
   1.285 +                    tp -= len - 1;
   1.286 +                } else {
   1.287 +                    *tp++ = '.';
   1.288 +                }
   1.289 +                uprv_strcpy(tp, "txt");
   1.290 +
   1.291 +                out = u_fopen(thefile, "w", NULL, encoding);
   1.292 +                if (!out) {
   1.293 +                  u_fprintf(ustderr, "%s: couldn't create %s\n", pname, thefile);
   1.294 +                  u_fclose(ustderr);
   1.295 +                  return 4;
   1.296 +                }
   1.297 +            }
   1.298 +
   1.299 +            // now, set the callback.
   1.300 +            ucnv_setFromUCallBack(u_fgetConverter(out), UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_C, 0, 0, &status);
   1.301 +            if (U_FAILURE(status)) {
   1.302 +              u_fprintf(ustderr, "%s: couldn't configure converter for encoding\n", pname);
   1.303 +              u_fclose(ustderr);
   1.304 +              if(!tostdout) {
   1.305 +                u_fclose(out);
   1.306 +              }
   1.307 +              return 3;
   1.308 +            }
   1.309 +
   1.310 +            if (prbom) { /* XXX: Should be done only for UTFs */
   1.311 +              u_fputc(0xFEFF, out);
   1.312 +            }
   1.313 +            u_fprintf(out, "// -*- Coding: %s; -*-\n//\n", encoding ? encoding : getEncodingName(ucnv_getDefaultName()));
   1.314 +            u_fprintf(out, "// This file was dumped by derb(8) from ");
   1.315 +            if (thename) {
   1.316 +              u_fprintf(out, "%s", thename);
   1.317 +            } else if (fromICUData) {
   1.318 +              u_fprintf(out, "the ICU internal %s locale", locale);
   1.319 +            }
   1.320 +
   1.321 +            u_fprintf(out, "\n// derb(8) by Vladimir Weinstein and Yves Arrouye\n\n");
   1.322 +
   1.323 +            if (locale[0]) {
   1.324 +              u_fprintf(out, "%s", locale);
   1.325 +            } else {
   1.326 +              u_fprintf(out, "%.*s%.*S", (int32_t)(ext - filename),  filename, (int32_t)(sizeof(sp)/sizeof(*sp)), sp);
   1.327 +            }
   1.328 +            printOutBundle(out, converter, bundle, 0, pname, &status);
   1.329 +
   1.330 +            if (!tostdout) {
   1.331 +                u_fclose(out);
   1.332 +            }
   1.333 +        }
   1.334 +        else {
   1.335 +            reportError(pname, &status, "opening resource file");
   1.336 +        }
   1.337 +
   1.338 +        ures_close(bundle);
   1.339 +    }
   1.340 +
   1.341 +    ucnv_close(converter);
   1.342 +
   1.343 +    return 0;
   1.344 +}
   1.345 +
   1.346 +static UChar *quotedString(const UChar *string) {
   1.347 +    int len = u_strlen(string);
   1.348 +    int alen = len;
   1.349 +    const UChar *sp;
   1.350 +    UChar *newstr, *np;
   1.351 +
   1.352 +    for (sp = string; *sp; ++sp) {
   1.353 +        switch (*sp) {
   1.354 +            case '\n':
   1.355 +            case 0x0022:
   1.356 +                ++alen;
   1.357 +                break;
   1.358 +        }
   1.359 +    }
   1.360 +
   1.361 +    newstr = (UChar *) uprv_malloc((1 + alen) * sizeof(*newstr));
   1.362 +    for (sp = string, np = newstr; *sp; ++sp) {
   1.363 +        switch (*sp) {
   1.364 +            case '\n':
   1.365 +                *np++ = 0x005C;
   1.366 +                *np++ = 0x006E;
   1.367 +                break;
   1.368 +
   1.369 +            case 0x0022:
   1.370 +                *np++ = 0x005C;
   1.371 +
   1.372 +            default:
   1.373 +                *np++ = *sp;
   1.374 +                break;
   1.375 +        }
   1.376 +    }
   1.377 +    *np = 0;
   1.378 +
   1.379 +    return newstr;
   1.380 +}
   1.381 +
   1.382 +
   1.383 +static void printString(UFILE *out, UConverter *converter, const UChar *str, int32_t len) {
   1.384 +  u_file_write(str, len, out);
   1.385 +}
   1.386 +
   1.387 +static void printCString(UFILE *out, UConverter *converter, const char *str, int32_t len) {
   1.388 +  if(len==-1) {
   1.389 +    u_fprintf(out, "%s", str);
   1.390 +  } else {
   1.391 +    u_fprintf(out, "%.*s", len, str);
   1.392 +  }
   1.393 +}
   1.394 +
   1.395 +static void printIndent(UFILE *out, UConverter *converter, int32_t indent) {
   1.396 +    UChar inchar[256];
   1.397 +    int32_t i = 0;
   1.398 +    for(i = 0; i<indent; i++) {
   1.399 +        inchar[i] = 0x0020;
   1.400 +    }
   1.401 +    inchar[indent] = 0;
   1.402 +
   1.403 +    printString(out, converter, inchar, indent);
   1.404 +}
   1.405 +
   1.406 +static void printHex(UFILE *out, UConverter *converter, uint8_t what) {
   1.407 +    static const char map[] = "0123456789ABCDEF";
   1.408 +    UChar hex[2];
   1.409 +
   1.410 +    hex[0] = map[what >> 4];
   1.411 +    hex[1] = map[what & 0xf];
   1.412 +
   1.413 +    printString(out, converter, hex, (int32_t)(sizeof(hex)/sizeof(*hex)));
   1.414 +}
   1.415 +
   1.416 +static void printOutAlias(UFILE *out,  UConverter *converter, UResourceBundle *parent, Resource r, const char *key, int32_t indent, const char *pname, UErrorCode *status) {
   1.417 +    static const UChar cr[] = { '\n' };
   1.418 +    int32_t len = 0;
   1.419 +    const UChar* thestr = res_getAlias(&(parent->fResData), r, &len);
   1.420 +    UChar *string = quotedString(thestr);
   1.421 +    if(opt_truncate && len > truncsize) {
   1.422 +        char msg[128];
   1.423 +        printIndent(out, converter, indent);
   1.424 +        sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n",
   1.425 +            (long)len, (long)truncsize/2);
   1.426 +        printCString(out, converter, msg, -1);
   1.427 +        len = truncsize;
   1.428 +    }
   1.429 +    if(U_SUCCESS(*status)) {
   1.430 +        static const UChar openStr[] = { 0x003A, 0x0061, 0x006C, 0x0069, 0x0061, 0x0073, 0x0020, 0x007B, 0x0020, 0x0022 }; /* ":alias { \"" */
   1.431 +        static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D, 0x0020 }; /* "\" } " */
   1.432 +        printIndent(out, converter, indent);
   1.433 +        if(key != NULL) {
   1.434 +            printCString(out, converter, key, -1);
   1.435 +        }
   1.436 +        printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
   1.437 +        printString(out, converter, string, len);
   1.438 +        printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
   1.439 +        if(verbose) {
   1.440 +            printCString(out, converter, " // ALIAS", -1);
   1.441 +        }
   1.442 +        printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));
   1.443 +    } else {
   1.444 +        reportError(pname, status, "getting binary value");
   1.445 +    }
   1.446 +    uprv_free(string);
   1.447 +}
   1.448 +
   1.449 +static void printOutBundle(UFILE *out, UConverter *converter, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status)
   1.450 +{
   1.451 +    static const UChar cr[] = { '\n' };
   1.452 +
   1.453 +/*    int32_t noOfElements = ures_getSize(resource);*/
   1.454 +    int32_t i = 0;
   1.455 +    const char *key = ures_getKey(resource);
   1.456 +
   1.457 +    switch(ures_getType(resource)) {
   1.458 +    case URES_STRING :
   1.459 +        {
   1.460 +            int32_t len=0;
   1.461 +            const UChar* thestr = ures_getString(resource, &len, status);
   1.462 +            UChar *string = quotedString(thestr);
   1.463 +
   1.464 +            /* TODO: String truncation */
   1.465 +            if(opt_truncate && len > truncsize) {
   1.466 +                char msg[128];
   1.467 +                printIndent(out, converter, indent);
   1.468 +                sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n",
   1.469 +                        (long)len, (long)(truncsize/2));
   1.470 +                printCString(out, converter, msg, -1);
   1.471 +                len = truncsize/2;
   1.472 +            }
   1.473 +            printIndent(out, converter, indent);
   1.474 +            if(key != NULL) {
   1.475 +                static const UChar openStr[] = { 0x0020, 0x007B, 0x0020, 0x0022 }; /* " { \"" */
   1.476 +                static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D }; /* "\" }" */
   1.477 +                printCString(out, converter, key, (int32_t)uprv_strlen(key));
   1.478 +                printString(out, converter, openStr, (int32_t)(sizeof(openStr)/sizeof(*openStr)));
   1.479 +                printString(out, converter, string, len);
   1.480 +                printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
   1.481 +            } else {
   1.482 +                static const UChar openStr[] = { 0x0022 }; /* "\"" */
   1.483 +                static const UChar closeStr[] = { 0x0022, 0x002C }; /* "\"," */
   1.484 +
   1.485 +                printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
   1.486 +                printString(out, converter, string, (int32_t)(u_strlen(string)));
   1.487 +                printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
   1.488 +            }
   1.489 +
   1.490 +            if(verbose) {
   1.491 +                printCString(out, converter, "// STRING", -1);
   1.492 +            }
   1.493 +            printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));
   1.494 +
   1.495 +            uprv_free(string);
   1.496 +        }
   1.497 +        break;
   1.498 +
   1.499 +    case URES_INT :
   1.500 +        {
   1.501 +            static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0020, 0x007B, 0x0020 }; /* ":int { " */
   1.502 +            static const UChar closeStr[] = { 0x0020, 0x007D }; /* " }" */
   1.503 +            UChar num[20];
   1.504 +
   1.505 +            printIndent(out, converter, indent);
   1.506 +            if(key != NULL) {
   1.507 +                printCString(out, converter, key, -1);
   1.508 +            }
   1.509 +            printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
   1.510 +            uprv_itou(num, 20, ures_getInt(resource, status), 10, 0);
   1.511 +            printString(out, converter, num, u_strlen(num));
   1.512 +            printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
   1.513 +
   1.514 +            if(verbose) {
   1.515 +                printCString(out, converter, "// INT", -1);
   1.516 +            }
   1.517 +            printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));
   1.518 +            break;
   1.519 +        }
   1.520 +    case URES_BINARY :
   1.521 +        {
   1.522 +            int32_t len = 0;
   1.523 +            const int8_t *data = (const int8_t *)ures_getBinary(resource, &len, status);
   1.524 +            if(opt_truncate && len > truncsize) {
   1.525 +                char msg[128];
   1.526 +                printIndent(out, converter, indent);
   1.527 +                sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n",
   1.528 +                        (long)len, (long)(truncsize/2));
   1.529 +                printCString(out, converter, msg, -1);
   1.530 +                len = truncsize;
   1.531 +            }
   1.532 +            if(U_SUCCESS(*status)) {
   1.533 +                static const UChar openStr[] = { 0x003A, 0x0062, 0x0069, 0x006E, 0x0061, 0x0072, 0x0079, 0x0020, 0x007B, 0x0020 }; /* ":binary { " */
   1.534 +                static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */
   1.535 +                printIndent(out, converter, indent);
   1.536 +                if(key != NULL) {
   1.537 +                    printCString(out, converter, key, -1);
   1.538 +                }
   1.539 +                printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
   1.540 +                for(i = 0; i<len; i++) {
   1.541 +                    printHex(out, converter, *data++);
   1.542 +                }
   1.543 +                printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
   1.544 +                if(verbose) {
   1.545 +                    printCString(out, converter, " // BINARY", -1);
   1.546 +                }
   1.547 +                printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));
   1.548 +            } else {
   1.549 +                reportError(pname, status, "getting binary value");
   1.550 +            }
   1.551 +        }
   1.552 +        break;
   1.553 +    case URES_INT_VECTOR :
   1.554 +        {
   1.555 +            int32_t len = 0;
   1.556 +            const int32_t *data = ures_getIntVector(resource, &len, status);
   1.557 +            if(U_SUCCESS(*status)) {
   1.558 +                static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0076, 0x0065, 0x0063, 0x0074, 0x006F, 0x0072, 0x0020, 0x007B, 0x0020 }; /* ":intvector { " */
   1.559 +                static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */
   1.560 +                UChar num[20];
   1.561 +
   1.562 +                printIndent(out, converter, indent);
   1.563 +                if(key != NULL) {
   1.564 +                    printCString(out, converter, key, -1);
   1.565 +                }
   1.566 +                printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
   1.567 +                for(i = 0; i < len - 1; i++) {
   1.568 +                    int32_t numLen =  uprv_itou(num, 20, data[i], 10, 0);
   1.569 +                    num[numLen++] = 0x002C; /* ',' */
   1.570 +                    num[numLen++] = 0x0020; /* ' ' */
   1.571 +                    num[numLen] = 0;
   1.572 +                    printString(out, converter, num, u_strlen(num));
   1.573 +                }
   1.574 +                if(len > 0) {
   1.575 +                    uprv_itou(num, 20, data[len - 1], 10, 0);
   1.576 +                    printString(out, converter, num, u_strlen(num));
   1.577 +                }
   1.578 +                printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
   1.579 +                if(verbose) {
   1.580 +                    printCString(out, converter, "// INTVECTOR", -1);
   1.581 +                }
   1.582 +                printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));
   1.583 +            } else {
   1.584 +                reportError(pname, status, "getting int vector");
   1.585 +            }
   1.586 +      }
   1.587 +      break;
   1.588 +    case URES_TABLE :
   1.589 +    case URES_ARRAY :
   1.590 +        {
   1.591 +            static const UChar openStr[] = { 0x007B }; /* "{" */
   1.592 +            static const UChar closeStr[] = { 0x007D, '\n' }; /* "}\n" */
   1.593 +
   1.594 +            UResourceBundle *t = NULL;
   1.595 +            ures_resetIterator(resource);
   1.596 +            printIndent(out, converter, indent);
   1.597 +            if(key != NULL) {
   1.598 +                printCString(out, converter, key, -1);
   1.599 +            }
   1.600 +            printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
   1.601 +            if(verbose) {
   1.602 +                if(ures_getType(resource) == URES_TABLE) {
   1.603 +                    printCString(out, converter, "// TABLE", -1);
   1.604 +                } else {
   1.605 +                    printCString(out, converter, "// ARRAY", -1);
   1.606 +                }
   1.607 +            }
   1.608 +            printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));
   1.609 +
   1.610 +            if(suppressAliases == FALSE) {
   1.611 +              while(U_SUCCESS(*status) && ures_hasNext(resource)) {
   1.612 +                  t = ures_getNextResource(resource, t, status);
   1.613 +                  if(U_SUCCESS(*status)) {
   1.614 +                    printOutBundle(out, converter, t, indent+indentsize, pname, status);
   1.615 +                  } else {
   1.616 +                    reportError(pname, status, "While processing table");
   1.617 +                    *status = U_ZERO_ERROR;
   1.618 +                  }
   1.619 +              }
   1.620 +            } else { /* we have to use low level access to do this */
   1.621 +              Resource r;
   1.622 +              int32_t resSize = ures_getSize(resource);
   1.623 +              UBool isTable = (UBool)(ures_getType(resource) == URES_TABLE);
   1.624 +              for(i = 0; i < resSize; i++) {
   1.625 +                /* need to know if it's an alias */
   1.626 +                if(isTable) {
   1.627 +                  r = res_getTableItemByIndex(&resource->fResData, resource->fRes, i, &key);
   1.628 +                } else {
   1.629 +                  r = res_getArrayItem(&resource->fResData, resource->fRes, i);
   1.630 +                }
   1.631 +                if(U_SUCCESS(*status)) {
   1.632 +                  if(res_getPublicType(r) == URES_ALIAS) {
   1.633 +                    printOutAlias(out, converter, resource, r, key, indent+indentsize, pname, status);
   1.634 +                  } else {
   1.635 +                    t = ures_getByIndex(resource, i, t, status);
   1.636 +                    printOutBundle(out, converter, t, indent+indentsize, pname, status);
   1.637 +                  }
   1.638 +                } else {
   1.639 +                  reportError(pname, status, "While processing table");
   1.640 +                  *status = U_ZERO_ERROR;
   1.641 +                }
   1.642 +              }
   1.643 +            }
   1.644 +
   1.645 +            printIndent(out, converter, indent);
   1.646 +            printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
   1.647 +            ures_close(t);
   1.648 +        }
   1.649 +        break;
   1.650 +    default:
   1.651 +        break;
   1.652 +    }
   1.653 +
   1.654 +}
   1.655 +
   1.656 +static const char *getEncodingName(const char *encoding) {
   1.657 +    UErrorCode err;
   1.658 +    const char *enc;
   1.659 +
   1.660 +    err = U_ZERO_ERROR;
   1.661 +    if (!(enc = ucnv_getStandardName(encoding, "MIME", &err))) {
   1.662 +        err = U_ZERO_ERROR;
   1.663 +        if (!(enc = ucnv_getStandardName(encoding, "IANA", &err))) {
   1.664 +            ;
   1.665 +        }
   1.666 +    }
   1.667 +
   1.668 +    return enc;
   1.669 +}
   1.670 +
   1.671 +static void reportError(const char *pname, UErrorCode *status, const char *when) {
   1.672 +  u_fprintf(ustderr, "%s: error %d while %s: %s\n", pname, *status, when, u_errorName(*status));
   1.673 +}
   1.674 +
   1.675 +#else
   1.676 +extern int
   1.677 +main(int argc, char* argv[]) {
   1.678 +    /* Changing stdio.h ustdio.h requires that formatting not be disabled. */
   1.679 +    return 3;
   1.680 +}
   1.681 +#endif /* !UCONFIG_NO_FORMATTING */
   1.682 +
   1.683 +/*
   1.684 + * Local Variables:
   1.685 + * indent-tabs-mode: nil
   1.686 + * End:
   1.687 + */

mercurial