2 *******************************************************************************
4 * © 2016 and later: Unicode, Inc. and others.
5 * License & terms of use: http://www.unicode.org/copyright.html#License
7 *******************************************************************************
8 *******************************************************************************
10 * Copyright (C) 1999-2007, International Business Machines
11 * Corporation and others. All Rights Reserved.
13 *******************************************************************************
16 * tab size: 8 (not used)
19 * created on: 2000sep6
20 * created by: Vladimir Weinstein
23 /******************************************************************************
24 * This program prints out resource bundles - example for
26 * TODO: make a complete i18n layout for this program.
27 ******************************************************************************/
29 #include "unicode/putil.h"
30 #include "unicode/ures.h"
31 #include "unicode/ustdio.h"
32 #include "unicode/uloc.h"
33 #include "unicode/ustring.h"
45 #define URESB_DEFAULTTRUNC 40
47 static char *currdir
= NULL
;
48 /*--locale sr_YU and --encoding cp855
49 * are interesting on Win32
52 static const char *locale
= NULL
;
53 static const char *encoding
= NULL
;
54 static const char *resPath
= NULL
;
55 static const int32_t indentsize
= 4;
56 static UFILE
*outerr
= NULL
;
57 static int32_t truncsize
= URESB_DEFAULTTRUNC
;
58 static UBool trunc
= FALSE
;
60 const UChar baderror
[] = { 0x0042, 0x0041, 0x0044, 0x0000 };
62 const UChar
*getErrorName(UErrorCode errorNumber
);
63 void reportError(UErrorCode
*status
);
64 static UChar
*quotedString(const UChar
*string
);
65 void printOutBundle(UFILE
*out
, UResourceBundle
*resource
, int32_t indent
, UErrorCode
*status
);
66 void printIndent(UFILE
*out
, int32_t indent
);
67 void printHex(UFILE
*out
, const int8_t *what
);
69 static UOption options
[]={
71 UOPTION_HELP_QUESTION_MARK
,
72 { "locale", NULL
, NULL
, NULL
, 'l', UOPT_REQUIRES_ARG
, 0 },
74 { "path", NULL
, NULL
, NULL
, 'p', UOPT_OPTIONAL_ARG
, 0 },
75 { "truncate", NULL
, NULL
, NULL
, 't', UOPT_OPTIONAL_ARG
, 0 },
79 static UBool VERBOSE
= FALSE
;
82 main(int argc
, char* argv
[]) {
84 UResourceBundle
*bundle
= NULL
;
85 UErrorCode status
= U_ZERO_ERROR
;
89 char resPathBuffer
[1024];
91 currdir
= _getcwd(NULL
, 0);
93 currdir
= getcwd(NULL
, 0);
96 argc
=u_parseArgs(argc
, argv
, sizeof(options
)/sizeof(options
[0]), options
);
98 /* error handling, printing usage message */
101 "error in command line argument \"%s\"\n",
104 if(argc
<2 || options
[0].doesOccur
|| options
[1].doesOccur
) {
106 "usage: %s [-options] locale(s)\n",
108 return argc
<0 ? U_ILLEGAL_ARGUMENT_ERROR
: U_ZERO_ERROR
;
111 if(options
[2].doesOccur
) {
112 locale
= options
[2].value
;
117 if(options
[3].doesOccur
) {
118 encoding
= options
[3].value
;
123 if(options
[4].doesOccur
) {
124 if(options
[4].value
!= NULL
) {
125 resPath
= options
[4].value
; /* we'll use users resources */
127 resPath
= NULL
; /* we'll use ICU system resources for dumping */
130 strcpy(resPathBuffer
, currdir
);
131 /*strcat(resPathBuffer, U_FILE_SEP_STRING);
132 strcat(resPathBuffer, "uresb");*/
133 resPath
= resPathBuffer
; /* we'll just dump uresb samples resources */
136 if(options
[5].doesOccur
) {
138 if(options
[5].value
!= NULL
) {
139 truncsize
= atoi(options
[5].value
); /* user defined printable size */
141 truncsize
= URESB_DEFAULTTRUNC
; /* we'll use default omitting size */
147 if(options
[6].doesOccur
) {
151 outerr
= u_finit(stderr
, locale
, encoding
);
152 out
= u_finit(stdout
, locale
, encoding
);
154 for(i
= 1; i
< argc
; ++i
) {
155 status
= U_ZERO_ERROR
;
156 arg
= getLongPathname(argv
[i
]);
158 u_fprintf(out
, "uresb: processing file \"%s\" in path \"%s\"\n", arg
, resPath
);
159 bundle
= ures_open(resPath
, arg
, &status
);
160 if(U_SUCCESS(status
)) {
161 u_fprintf(out
, "%s\n", arg
);
162 printOutBundle(out
, bundle
, 0, &status
);
164 reportError(&status
);
177 void printIndent(UFILE
*out
, int32_t indent
) {
180 for(i
= 0; i
<indent
; i
++) {
183 inchar
[indent
] = '\0';
184 u_fprintf(out
, "%s", inchar
);
187 void printHex(UFILE
*out
, const int8_t *what
) {
188 u_fprintf(out
, "%02X", (uint8_t)*what
);
191 static UChar
*quotedString(const UChar
*string
) {
192 int len
= u_strlen(string
);
197 for (sp
= string
; *sp
; ++sp
) {
206 newstr
= (UChar
*) malloc((1 + alen
) * sizeof(*newstr
));
207 for (sp
= string
, np
= newstr
; *sp
; ++sp
) {
227 void printOutBundle(UFILE
*out
, UResourceBundle
*resource
, int32_t indent
, UErrorCode
*status
) {
229 const char *key
= ures_getKey(resource
);
231 switch(ures_getType(resource
)) {
235 const UChar
*thestr
= ures_getString(resource
, &len
, status
);
236 UChar
*string
= quotedString(thestr
);
238 /* TODO: String truncation */
240 if(trunc && len > truncsize) {
241 printIndent(out, indent);
242 u_fprintf(out, "// WARNING: this string, size %d is truncated to %d\n", len, truncsize/2);
246 printIndent(out
, indent
);
248 u_fprintf(out
, "%s { \"%S\" } ", key
, string
);
250 u_fprintf(out
, "\"%S\",", string
);
253 u_fprintf(out
, " // STRING");
255 u_fprintf(out
, "\n");
260 printIndent(out
, indent
);
262 u_fprintf(out
, "%s", key
);
264 u_fprintf(out
, ":int { %li } ", ures_getInt(resource
, status
));
267 u_fprintf(out
, " // INT");
269 u_fprintf(out
, "\n");
274 const int8_t *data
= (const int8_t *)ures_getBinary(resource
, &len
, status
);
275 if(trunc
&& len
> truncsize
) {
276 printIndent(out
, indent
);
277 u_fprintf(out
, "// WARNING: this resource, size %li is truncated to %li\n", len
, truncsize
/2);
280 if(U_SUCCESS(*status
)) {
281 printIndent(out
, indent
);
283 u_fprintf(out
, "%s", key
);
285 u_fprintf(out
, ":binary { ");
286 for(i
= 0; i
<len
; i
++) {
287 printHex(out
, data
++);
289 u_fprintf(out
, " }");
291 u_fprintf(out
, " // BINARY");
293 u_fprintf(out
, "\n");
300 case URES_INT_VECTOR
:
303 const int32_t *data
= ures_getIntVector(resource
, &len
, status
);
304 if(U_SUCCESS(*status
)) {
305 printIndent(out
, indent
);
307 u_fprintf(out
, "%s", key
);
309 u_fprintf(out
, ":intvector { ");
310 for(i
= 0; i
<len
-1; i
++) {
311 u_fprintf(out
, "%d, ", data
[i
]);
314 u_fprintf(out
, "%d ", data
[len
-1]);
318 u_fprintf(out
, " // INTVECTOR");
320 u_fprintf(out
, "\n");
330 UResourceBundle
*t
= NULL
;
331 ures_resetIterator(resource
);
332 printIndent(out
, indent
);
334 u_fprintf(out
, "%s ", key
);
338 if(ures_getType(resource
) == URES_TABLE
) {
339 u_fprintf(out
, " // TABLE");
341 u_fprintf(out
, " // ARRAY");
344 u_fprintf(out
, "\n");
346 while(ures_hasNext(resource
)) {
347 t
= ures_getNextResource(resource
, t
, status
);
348 printOutBundle(out
, t
, indent
+indentsize
, status
);
351 printIndent(out
, indent
);
352 u_fprintf(out
, "}\n");
362 void reportError(UErrorCode
*status
) {
363 u_fprintf(outerr
, "Error %d(%s) : %U happened!\n", *status
, u_errorName(*status
), getErrorName(*status
));
367 const UChar
*getErrorName(UErrorCode errorNumber
) {
368 UErrorCode status
= U_ZERO_ERROR
;
371 UResourceBundle
*error
= ures_open(currdir
, locale
, &status
);
373 UResourceBundle
*errorcodes
= ures_getByKey(error
, "errorcodes", NULL
, &status
);
375 const UChar
*result
= ures_getStringByIndex(errorcodes
, errorNumber
, &len
, &status
);
377 ures_close(errorcodes
);
380 if(U_SUCCESS(status
)) {