/*
*******************************************************************************
*
-* Copyright (C) 1999-2008, International Business Machines
+* Copyright (C) 1999-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
#include "unicode/ucnv.h"
#include "unicode/ustring.h"
#include "unicode/putil.h"
+#include "unicode/ustdio.h"
#include "uresimp.h"
#include "cmemory.h"
#include "toolutil.h"
#include "ustrfmt.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#if defined(U_WINDOWS) || defined(U_CYGWIN)
-#include <io.h>
-#include <fcntl.h>
-#define USE_FILENO_BINARY_MODE 1
-/* Windows likes to rename Unix-like functions */
-#ifndef fileno
-#define fileno _fileno
-#endif
-#ifndef setmode
-#define setmode _setmode
-#endif
-#ifndef O_BINARY
-#define O_BINARY _O_BINARY
-#endif
-#endif
+#if !UCONFIG_NO_FORMATTING
-#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 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,
/* 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[]) {
UErrorCode status = U_ZERO_ERROR;
int32_t i = 0;
- UConverter *converter;
+ UConverter *converter = NULL; // not used
const char* arg;
}
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) {
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 }; /* " " */
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 (!(fromICUData = !uprv_strcmp(inputDir, "-"))) {
UBool absfilename = *arg == U_FILE_SEP_CHAR;
-#ifdef U_WINDOWS
+#if U_PLATFORM_HAS_WIN32_API
if (!absfilename) {
absfilename = (uprv_strlen(arg) > 2 && isalpha(arg[0])
&& arg[1] == ':' && arg[2] == U_FILE_SEP_CHAR);
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);
#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR
}
if (tostdout) {
- out = stdout;
-#if defined(U_WINDOWS) || defined(U_CYGWIN)
- 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;
}
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, (int32_t)(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 {
ures_close(bundle);
}
- ucnv_close(defaultConverter);
ucnv_close(converter);
return 0;
}
-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, (int32_t)(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; i<indent; i++) {
printString(out, converter, inchar, indent);
}
-static void printHex(FILE *out, UConverter *converter, uint8_t what) {
+static void printHex(UFILE *out, UConverter *converter, uint8_t what) {
static const char map[] = "0123456789ABCDEF";
UChar hex[2];
printString(out, converter, hex, (int32_t)(sizeof(hex)/sizeof(*hex)));
}
-static const UChar *
-derb_getString(const ResourceData *pResData, const Resource res, int32_t *pLength) {
- if(res!=RES_BOGUS) {
- int32_t *p=(int32_t *)RES_GET_POINTER(pResData->pRoot, 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(indexR<count) {
- return ((Resource *)(p+1+count+(~count&1)))[indexR];
- } else {
- return RES_BOGUS; /* indexR>itemCount */
- }
-}
-
-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",
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' };
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);
/* 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",
}
break;
- case RES_INT :
+ case URES_INT :
{
static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0020, 0x007B, 0x0020 }; /* ":int { " */
static const UChar closeStr[] = { 0x0020, 0x007D }; /* " }" */
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",
}
}
break;
- case RES_INT_VECTOR :
+ case URES_INT_VECTOR :
{
int32_t len = 0;
const int32_t *data = ures_getIntVector(resource, &len, status);
}
}
break;
- case RES_TABLE :
- case RES_ARRAY :
+ case URES_TABLE :
+ case URES_ARRAY :
{
static const UChar openStr[] = { 0x007B }; /* "{" */
static const UChar closeStr[] = { 0x007D, '\n' }; /* "}\n" */
}
printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
if(verbose) {
- if(ures_getType(resource) == RES_TABLE) {
+ if(ures_getType(resource) == URES_TABLE) {
printCString(out, converter, "// TABLE", -1);
} else {
printCString(out, converter, "// ARRAY", -1);
}
}
} else { /* we have to use low level access to do this */
- Resource r = RES_BOGUS;
- for(i = 0; i < ures_getSize(resource); i++) {
+ Resource r;
+ int32_t resSize = ures_getSize(resource);
+ UBool isTable = (UBool)(ures_getType(resource) == URES_TABLE);
+ for(i = 0; i < resSize; i++) {
/* need to know if it's an alias */
- if(ures_getType(resource) == RES_TABLE) {
- r = derb_getTableItem(resource->fResData.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);
}
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:
*/
-
-