X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..b331163bffd790ced0e88b73f44f86d49ccc48a5:/icuSources/tools/genrb/derb.c diff --git a/icuSources/tools/genrb/derb.c b/icuSources/tools/genrb/derb.c index 17d8f331..8c8fdd81 100644 --- a/icuSources/tools/genrb/derb.c +++ b/icuSources/tools/genrb/derb.c @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 1999-2003, International Business Machines +* Copyright (C) 1999-2013, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -17,6 +17,8 @@ #include "unicode/ucnv.h" #include "unicode/ustring.h" +#include "unicode/putil.h" +#include "unicode/ustdio.h" #include "uresimp.h" #include "cmemory.h" @@ -25,36 +27,24 @@ #include "toolutil.h" #include "ustrfmt.h" -#include -#include -#include +#if !UCONFIG_NO_FORMATTING -#ifdef WIN32 -#include -#include -#include -#endif - -#define DERB_VERSION "1.0" +#define DERB_VERSION "1.1" #define DERB_DEFAULT_TRUNC 80 -static UConverter *defaultConverter = 0; - static const int32_t indentsize = 4; static int32_t truncsize = DERB_DEFAULT_TRUNC; -static UBool trunc = FALSE; - -static const UChar baderror[] = { 0x0042, 0x0041, 0x0044, 0x0000 }; +static UBool opt_truncate = FALSE; static const char *getEncodingName(const char *encoding); static void reportError(const char *pname, UErrorCode *status, const char *when); static UChar *quotedString(const UChar *string); -static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status); -static void printString(FILE *out, UConverter *converter, const UChar *str, int32_t len); -static void printCString(FILE *out, UConverter *converter, const char *str, int32_t len); -static void printIndent(FILE *out, UConverter *converter, int32_t indent); -static void printHex(FILE *out, UConverter *converter, uint8_t what); +static void printOutBundle(UFILE *out, UConverter *converter, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status); +static void printString(UFILE *out, UConverter *converter, const UChar *str, int32_t len); +static void printCString(UFILE *out, UConverter *converter, const char *str, int32_t len); +static void printIndent(UFILE *out, UConverter *converter, int32_t indent); +static void printHex(UFILE *out, UConverter *converter, uint8_t what); static UOption options[]={ UOPTION_HELP_H, @@ -68,11 +58,12 @@ static UOption options[]={ /* 8 */ { "bom", NULL, NULL, NULL, 0, UOPT_NO_ARG, 0 }, /* 9 */ UOPTION_ICUDATADIR, /* 10 */ UOPTION_VERSION, -/* 11 */ { "suppressAliases", NULL, NULL, NULL, 'A', UOPT_NO_ARG, 0 } +/* 11 */ { "suppressAliases", NULL, NULL, NULL, 'A', UOPT_NO_ARG, 0 }, }; static UBool verbose = FALSE; static UBool suppressAliases = FALSE; +static UFILE *ustderr = NULL; extern int main(int argc, char* argv[]) { @@ -88,15 +79,15 @@ main(int argc, char* argv[]) { UErrorCode status = U_ZERO_ERROR; int32_t i = 0; - UConverter *converter; + UConverter *converter = NULL; // not used const char* arg; /* Get the name of tool. */ pname = uprv_strrchr(*argv, U_FILE_SEP_CHAR); -#ifdef WIN32 +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR if (!pname) { - pname = uprv_strrchr(*argv, '/'); + pname = uprv_strrchr(*argv, U_FILE_ALT_SEP_CHAR); } #endif if (!pname) { @@ -139,18 +130,22 @@ main(int argc, char* argv[]) { } if (options[3].doesOccur) { - tostdout = 1; + if(options[2].doesOccur) { + fprintf(stderr, "%s: Error: don't specify an encoding (-e) when writing to stdout (-c).\n", pname); + return 3; + } + tostdout = 1; } if(options[4].doesOccur) { - trunc = TRUE; + opt_truncate = TRUE; if(options[4].value != NULL) { truncsize = atoi(options[4].value); /* user defined printable size */ } else { truncsize = DERB_DEFAULT_TRUNC; /* we'll use default omitting size */ } } else { - trunc = FALSE; + opt_truncate = FALSE; } if(options[5].doesOccur) { @@ -177,22 +172,8 @@ main(int argc, char* argv[]) { suppressAliases = TRUE; } - converter = ucnv_open(encoding, &status); - if (U_FAILURE(status)) { - fprintf(stderr, "%s: couldn't create %s converter for encoding\n", pname, encoding ? encoding : ucnv_getDefaultName()); - return 2; - } - ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_C, 0, 0, &status); - if (U_FAILURE(status)) { - fprintf(stderr, "%s: couldn't configure converter for encoding\n", pname); - return 3; - } - - defaultConverter = ucnv_open(0, &status); - if (U_FAILURE(status)) { - fprintf(stderr, "%s: couldn't create %s converter for encoding\n", ucnv_getDefaultName(), pname); - return 2; - } + fflush(stderr); // use ustderr now. + ustderr = u_finit(stderr, NULL, NULL); for (i = 1; i < argc; ++i) { static const UChar sp[] = { 0x0020 }; /* " " */ @@ -204,40 +185,51 @@ main(int argc, char* argv[]) { arg = getLongPathname(argv[i]); if (verbose) { - printf("processing bundle \"%s\"\n", argv[i]); + u_fprintf(ustderr, "processing bundle \"%s\"\n", argv[i]); } p = uprv_strrchr(arg, U_FILE_SEP_CHAR); +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR + if (p == NULL) { + p = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR); + } +#endif if (!p) { p = arg; } else { - p++; + p++; } q = uprv_strrchr(p, '.'); if (!q) { - for (q = p; *q; ++q); + for (q = p; *q; ++q) + ; } uprv_strncpy(locale, p, q - p); locale[q - p] = 0; if (!(fromICUData = !uprv_strcmp(inputDir, "-"))) { UBool absfilename = *arg == U_FILE_SEP_CHAR; -#ifdef WIN32 +#if U_PLATFORM_HAS_WIN32_API if (!absfilename) { absfilename = (uprv_strlen(arg) > 2 && isalpha(arg[0]) - && arg[1] == ':' && arg[2] == U_FILE_SEP_CHAR); + && arg[1] == ':' && arg[2] == U_FILE_SEP_CHAR); } #endif if (absfilename) { thename = arg; } else { - q = uprv_strrchr(arg, U_FILE_SEP_CHAR); - uprv_strcpy(infile, inputDir); - if(q != NULL) { - uprv_strcat(infile, U_FILE_SEP_STRING), - strncat(infile, arg, q-arg); - } - thename = infile; + q = uprv_strrchr(arg, U_FILE_SEP_CHAR); +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR + if (q == NULL) { + q = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR); + } +#endif + uprv_strcpy(infile, inputDir); + if(q != NULL) { + uprv_strcat(infile, U_FILE_SEP_STRING); + strncat(infile, arg, q-arg); + } + thename = infile; } } status = U_ZERO_ERROR; @@ -247,17 +239,17 @@ main(int argc, char* argv[]) { bundle = ures_open(fromICUData ? 0 : inputDir, locale, &status); } if (status == U_ZERO_ERROR) { - FILE *out; + UFILE *out = NULL; const char *filename = 0; const char *ext = 0; - if (!locale || !tostdout) { + if (!locale[0] || !tostdout) { filename = uprv_strrchr(arg, U_FILE_SEP_CHAR); -#ifdef WIN32 +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR if (!filename) { - filename = uprv_strrchr(arg, '/'); + filename = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR); } #endif if (!filename) { @@ -272,13 +264,7 @@ main(int argc, char* argv[]) { } if (tostdout) { - out = stdout; -#ifdef WIN32 - if (_setmode(_fileno(out), _O_BINARY) == -1) { - fprintf(stderr, "%s: couldn't set standard output to binary mode\n, pname"); - return 4; - } -#endif + out = u_get_stdout(); } else { char thefile[4096], *tp; int32_t len; @@ -299,51 +285,56 @@ main(int argc, char* argv[]) { } uprv_strcpy(tp, "txt"); - out = fopen(thefile, "w"); + out = u_fopen(thefile, "w", NULL, encoding); if (!out) { - fprintf(stderr, "%s: couldn't create %s\n", pname, thefile); - return 4; + u_fprintf(ustderr, "%s: couldn't create %s\n", pname, thefile); + u_fclose(ustderr); + return 4; } } - if (prbom) { /* XXX: Should be done only for UTFs */ - static const UChar bom[] = { 0xFEFF }; - printString(out, converter, bom, (int32_t)(sizeof(bom)/sizeof(*bom))); + // now, set the callback. + ucnv_setFromUCallBack(u_fgetConverter(out), UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_C, 0, 0, &status); + if (U_FAILURE(status)) { + u_fprintf(ustderr, "%s: couldn't configure converter for encoding\n", pname); + u_fclose(ustderr); + if(!tostdout) { + u_fclose(out); + } + return 3; } - printCString(out, converter, "// -*- Coding: ", -1); - printCString(out, converter, encoding ? encoding : getEncodingName(ucnv_getDefaultName()), -1); - printCString(out, converter, "; -*-\n//\n", -1); - printCString(out, converter, "// This file was dumped by derb(8) from ", -1); + if (prbom) { /* XXX: Should be done only for UTFs */ + u_fputc(0xFEFF, out); + } + u_fprintf(out, "// -*- Coding: %s; -*-\n//\n", encoding ? encoding : getEncodingName(ucnv_getDefaultName())); + u_fprintf(out, "// This file was dumped by derb(8) from "); if (thename) { - printCString(out, converter, thename, -1); + u_fprintf(out, "%s", thename); } else if (fromICUData) { - printCString(out, converter, "the ICU internal ", -1); - printCString(out, converter, locale, -1); - printCString(out, converter, " locale", -1); + u_fprintf(out, "the ICU internal %s locale", locale); } - printCString(out, converter, "\n// derb(8) by Vladimir Weinstein and Yves Arrouye\n\n", -1); + u_fprintf(out, "\n// derb(8) by Vladimir Weinstein and Yves Arrouye\n\n"); - if (locale) { - printCString(out, converter, locale, -1); + if (locale[0]) { + u_fprintf(out, "%s", locale); } else { - printCString(out, converter, filename, ext - filename); - printString(out, converter, sp, (int32_t)(sizeof(sp)/sizeof(*sp))); + u_fprintf(out, "%.*s%.*S", (int32_t)(ext - filename), filename, (int32_t)(sizeof(sp)/sizeof(*sp)), sp); } printOutBundle(out, converter, bundle, 0, pname, &status); - if (out != stdout) { - fclose(out); + if (!tostdout) { + u_fclose(out); } - } else { + } + else { reportError(pname, &status, "opening resource file"); } ures_close(bundle); } - ucnv_close(defaultConverter); ucnv_close(converter); return 0; @@ -386,47 +377,19 @@ static UChar *quotedString(const UChar *string) { } -static void printString(FILE *out, UConverter *converter, const UChar *str, int32_t len) { - char buf[256]; - const UChar *strEnd; - - if (len < 0) { - len = u_strlen(str); - } - strEnd = str + len; - - do { - UErrorCode err = U_ZERO_ERROR; - char *bufp = buf, *bufend = buf + sizeof(buf) - 1 ; - - ucnv_fromUnicode(converter, &bufp, bufend, &str, strEnd, 0, 0, &err); - *bufp = 0; - - fprintf(out, "%s", buf); - } while (str < strEnd); +static void printString(UFILE *out, UConverter *converter, const UChar *str, int32_t len) { + u_file_write(str, len, out); } -static void printCString(FILE *out, UConverter *converter, const char *str, int32_t len) { - UChar buf[256]; - const char *strEnd; - - if (len < 0) { - len = (int32_t)uprv_strlen(str); - } - strEnd = str + len; - - do { - UErrorCode err = U_ZERO_ERROR; - UChar *bufp = buf, *bufend = buf + (sizeof(buf)/sizeof(buf[0])) - 1 ; - - ucnv_toUnicode(defaultConverter, &bufp, bufend, &str, strEnd, 0, 0, &err); - *bufp = 0; - - printString(out, converter, buf, bufp - buf); - } while (str < strEnd); +static void printCString(UFILE *out, UConverter *converter, const char *str, int32_t len) { + if(len==-1) { + u_fprintf(out, "%s", str); + } else { + u_fprintf(out, "%.*s", len, str); + } } -static void printIndent(FILE *out, UConverter *converter, int32_t indent) { +static void printIndent(UFILE *out, UConverter *converter, int32_t indent) { UChar inchar[256]; int32_t i = 0; for(i = 0; ipRoot, res); - if (pLength) { - *pLength=*p; - } - return (UChar *)++p; - } else { - if (pLength) { - *pLength=0; - } - return NULL; - } -} -static const char * -derb_getTableKey(const Resource *pRoot, const Resource res, uint16_t indexS) { - uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res); - if(indexS<*p) { - return ((const char *)(pRoot)+(p[indexS+1])); /*RES_GET_KEY(pRoot, p[indexS+1]);*/ - } else { - return NULL; /* indexS>itemCount */ - } -} - -static Resource -derb_getArrayItem(Resource *pRoot, Resource res, int32_t indexR) { - int32_t *p=(int32_t *)RES_GET_POINTER(pRoot, res); - if(indexR<*p) { - return ((Resource *)(p))[1+indexR]; - } else { - return RES_BOGUS; /* indexR>itemCount */ - } -} - -static Resource -derb_getTableItem(const Resource *pRoot, const Resource res, uint16_t indexR) { - uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res); - uint16_t count=*p; - if(indexRitemCount */ - } -} - - -static void printOutAlias(FILE *out, UConverter *converter, UResourceBundle *parent, Resource r, const char *key, int32_t indent, const char *pname, UErrorCode *status) { +static void printOutAlias(UFILE *out, UConverter *converter, UResourceBundle *parent, Resource r, const char *key, int32_t indent, const char *pname, UErrorCode *status) { static const UChar cr[] = { '\n' }; int32_t len = 0; - const UChar* thestr = derb_getString(&(parent->fResData), r, &len); + const UChar* thestr = res_getAlias(&(parent->fResData), r, &len); UChar *string = quotedString(thestr); - if(trunc && len > truncsize) { + if(opt_truncate && len > truncsize) { char msg[128]; printIndent(out, converter, indent); sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n", @@ -508,15 +424,15 @@ static void printOutAlias(FILE *out, UConverter *converter, UResourceBundle *pa len = truncsize; } if(U_SUCCESS(*status)) { - static const UChar open[] = { 0x003A, 0x0061, 0x006C, 0x0069, 0x0061, 0x0073, 0x0020, 0x007B, 0x0020, 0x0022 }; /* ":alias { \"" */ - static const UChar close[] = { 0x0022, 0x0020, 0x007D, 0x0020 }; /* "\" } " */ + static const UChar openStr[] = { 0x003A, 0x0061, 0x006C, 0x0069, 0x0061, 0x0073, 0x0020, 0x007B, 0x0020, 0x0022 }; /* ":alias { \"" */ + static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D, 0x0020 }; /* "\" } " */ printIndent(out, converter, indent); if(key != NULL) { printCString(out, converter, key, -1); } - printString(out, converter, open, (int32_t)(sizeof(open) / sizeof(*open))); + printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); printString(out, converter, string, len); - printString(out, converter, close, (int32_t)(sizeof(close) / sizeof(*close))); + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); if(verbose) { printCString(out, converter, " // ALIAS", -1); } @@ -524,9 +440,10 @@ static void printOutAlias(FILE *out, UConverter *converter, UResourceBundle *pa } else { reportError(pname, status, "getting binary value"); } + uprv_free(string); } -static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status) +static void printOutBundle(UFILE *out, UConverter *converter, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status) { static const UChar cr[] = { '\n' }; @@ -535,14 +452,14 @@ static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *re const char *key = ures_getKey(resource); switch(ures_getType(resource)) { - case RES_STRING : + case URES_STRING : { int32_t len=0; const UChar* thestr = ures_getString(resource, &len, status); - UChar *string = quotedString(thestr); + UChar *string = quotedString(thestr); /* TODO: String truncation */ - if(trunc && len > truncsize) { + if(opt_truncate && len > truncsize) { char msg[128]; printIndent(out, converter, indent); sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n", @@ -552,19 +469,19 @@ static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *re } printIndent(out, converter, indent); if(key != NULL) { - static const UChar open[] = { 0x0020, 0x007B, 0x0020, 0x0022 }; /* " { \"" */ - static const UChar close[] = { 0x0022, 0x0020, 0x007D }; /* "\" }" */ + static const UChar openStr[] = { 0x0020, 0x007B, 0x0020, 0x0022 }; /* " { \"" */ + static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D }; /* "\" }" */ printCString(out, converter, key, (int32_t)uprv_strlen(key)); - printString(out, converter, open, (int32_t)(sizeof(open)/sizeof(*open))); + printString(out, converter, openStr, (int32_t)(sizeof(openStr)/sizeof(*openStr))); printString(out, converter, string, len); - printString(out, converter, close, (int32_t)(sizeof(close) / sizeof(*close))); + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); } else { - static const UChar open[] = { 0x0022 }; /* "\"" */ - static const UChar close[] = { 0x0022, 0x002C }; /* "\"," */ + static const UChar openStr[] = { 0x0022 }; /* "\"" */ + static const UChar closeStr[] = { 0x0022, 0x002C }; /* "\"," */ - printString(out, converter, open, (int32_t)(sizeof(open) / sizeof(*open))); + printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); printString(out, converter, string, (int32_t)(u_strlen(string))); - printString(out, converter, close, (int32_t)(sizeof(close) / sizeof(*close))); + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); } if(verbose) { @@ -576,20 +493,20 @@ static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *re } break; - case RES_INT : + case URES_INT : { - static const UChar open[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0020, 0x007B, 0x0020 }; /* ":int { " */ - static const UChar close[] = { 0x0020, 0x007D }; /* " }" */ + static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0020, 0x007B, 0x0020 }; /* ":int { " */ + static const UChar closeStr[] = { 0x0020, 0x007D }; /* " }" */ UChar num[20]; printIndent(out, converter, indent); if(key != NULL) { printCString(out, converter, key, -1); } - printString(out, converter, open, (int32_t)(sizeof(open) / sizeof(*open))); + printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); uprv_itou(num, 20, ures_getInt(resource, status), 10, 0); printString(out, converter, num, u_strlen(num)); - printString(out, converter, close, (int32_t)(sizeof(close) / sizeof(*close))); + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); if(verbose) { printCString(out, converter, "// INT", -1); @@ -597,11 +514,11 @@ static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *re printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); break; } - case RES_BINARY : + case URES_BINARY : { int32_t len = 0; const int8_t *data = (const int8_t *)ures_getBinary(resource, &len, status); - if(trunc && len > truncsize) { + if(opt_truncate && len > truncsize) { char msg[128]; printIndent(out, converter, indent); sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n", @@ -610,17 +527,17 @@ static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *re len = truncsize; } if(U_SUCCESS(*status)) { - static const UChar open[] = { 0x003A, 0x0062, 0x0069, 0x006E, 0x0061, 0x0072, 0x0079, 0x0020, 0x007B, 0x0020 }; /* ":binary { " */ - static const UChar close[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */ + static const UChar openStr[] = { 0x003A, 0x0062, 0x0069, 0x006E, 0x0061, 0x0072, 0x0079, 0x0020, 0x007B, 0x0020 }; /* ":binary { " */ + static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */ printIndent(out, converter, indent); if(key != NULL) { printCString(out, converter, key, -1); } - printString(out, converter, open, (int32_t)(sizeof(open) / sizeof(*open))); + printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); for(i = 0; ifResData.pRoot, resource->fRes, (int16_t)i); - key = derb_getTableKey(resource->fResData.pRoot, resource->fRes, (int16_t)i); + if(isTable) { + r = res_getTableItemByIndex(&resource->fResData, resource->fRes, i, &key); } else { - r = derb_getArrayItem(resource->fResData.pRoot, resource->fRes, i); + r = res_getArrayItem(&resource->fResData, resource->fRes, i); } if(U_SUCCESS(*status)) { - if(RES_GET_TYPE(r) == RES_ALIAS) { + if(res_getPublicType(r) == URES_ALIAS) { printOutAlias(out, converter, resource, r, key, indent+indentsize, pname, status); } else { t = ures_getByIndex(resource, i, t, status); @@ -722,7 +640,7 @@ static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *re } printIndent(out, converter, indent); - printString(out, converter, close, (int32_t)(sizeof(close) / sizeof(*close))); + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); ures_close(t); } break; @@ -748,13 +666,19 @@ static const char *getEncodingName(const char *encoding) { } static void reportError(const char *pname, UErrorCode *status, const char *when) { - fprintf(stderr, "%s: error %d while %s: %s\n", pname, *status, when, u_errorName(*status)); + u_fprintf(ustderr, "%s: error %d while %s: %s\n", pname, *status, when, u_errorName(*status)); } +#else +extern int +main(int argc, char* argv[]) { + /* Changing stdio.h ustdio.h requires that formatting not be disabled. */ + return 3; +} +#endif /* !UCONFIG_NO_FORMATTING */ + /* * Local Variables: * indent-tabs-mode: nil * End: */ - -