2 *******************************************************************************
4 * Copyright (C) 1998-2006, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
11 * Modification History:
13 * Date Name Description
14 * 05/25/99 stephen Creation.
15 * 5/10/01 Ram removed ustdio dependency
16 *******************************************************************************
20 #include "unicode/uclean.h"
23 static void processFile(const char *filename
, const char* cp
, const char *inputDir
, const char *outputDir
, const char *packageName
, UErrorCode
*status
);
24 static char *make_res_filename(const char *filename
, const char *outputDir
,
25 const char *packageName
, UErrorCode
*status
);
28 #define RES_SUFFIX ".res"
29 #define COL_SUFFIX ".col"
31 static char theCurrentFileName
[2048];
32 const char *gCurrentFileName
= theCurrentFileName
;
61 UOPTION_HELP_QUESTION_MARK
,
73 UOPTION_DEF( "write-xliff", 'x', UOPT_OPTIONAL_ARG
),
74 UOPTION_DEF( "strict", 'k', UOPT_NO_ARG
), /* 14 */
75 UOPTION_DEF( "noBinaryCollation", 'C', UOPT_NO_ARG
),/* 15 */
76 UOPTION_DEF( "language", 'l', UOPT_REQUIRES_ARG
)
79 static UBool write_java
= FALSE
;
80 static UBool write_xliff
= FALSE
;
81 static const char* outputEnc
="";
82 static const char* gPackageName
=NULL
;
83 static const char* bundleName
=NULL
;
85 static const char* language
= NULL
;
86 static const char* xliffOutputFileName
= NULL
;
91 UErrorCode status
= U_ZERO_ERROR
;
92 const char *arg
= NULL
;
93 const char *outputDir
= NULL
; /* NULL = no output directory, use current */
94 const char *inputDir
= NULL
;
95 const char *encoding
= "";
98 U_MAIN_INIT_ARGS(argc
, argv
);
100 argc
= u_parseArgs(argc
, argv
, (int32_t)(sizeof(options
)/sizeof(options
[0])), options
);
102 /* error handling, printing usage message */
104 fprintf(stderr
, "%s: error in command line argument \"%s\"\n", argv
[0], argv
[-argc
]);
109 if(options
[VERSION
].doesOccur
) {
111 "%s version %s (ICU version %s).\n"
113 argv
[0], GENRB_VERSION
, U_ICU_VERSION
, U_COPYRIGHT_STRING
);
117 if(argc
<0 || options
[HELP1
].doesOccur
|| options
[HELP2
].doesOccur
) {
119 * Broken into chucks because the C89 standard says the minimum
120 * required supported string length is 509 bytes.
123 "Usage: %s [OPTIONS] [FILES]\n"
124 "\tReads the list of resource bundle source files and creates\n"
125 "\tbinary version of reosurce bundles (.res files)\n",
129 "\t-h or -? or --help this usage text\n"
130 "\t-q or --quiet do not display warnings\n"
131 "\t-v or --verbose print extra information when processing files\n"
132 "\t-V or --version prints out version number and exits\n"
133 "\t-c or --copyright include copyright notice\n");
135 "\t-e or --encoding encoding of source files\n"
136 "\t-d of --destdir destination directory, followed by the path, defaults to %s\n"
137 "\t-s or --sourcedir source directory for files followed by path, defaults to %s\n"
138 "\t-i or --icudatadir directory for locating any needed intermediate data files,\n"
139 "\t followed by path, defaults to %s\n",
140 u_getDataDirectory(), u_getDataDirectory(), u_getDataDirectory());
142 "\t-j or --write-java write a Java ListResourceBundle for ICU4J, followed by optional encoding\n"
143 "\t defaults to ASCII and \\uXXXX format.\n"
144 "\t-p or --package-name For ICU4J: package name for writing the ListResourceBundle for ICU4J,\n"
145 "\t defaults to com.ibm.icu.impl.data\n");
147 "\t-b or --bundle-name bundle name for writing the ListResourceBundle for ICU4J,\n"
148 "\t defaults to LocaleElements\n"
149 "\t-x or --write-xliff write a XLIFF file for the resource bundle. Followed by an optional output file name.\n"
150 "\t-k or --strict use pedantic parsing of syntax\n"
152 "\t-l or --language For XLIFF: language code compliant with ISO 639.\n");
154 return argc
< 0 ? U_ILLEGAL_ARGUMENT_ERROR
: U_ZERO_ERROR
;
157 if(options
[VERBOSE
].doesOccur
) {
161 if(options
[QUIET
].doesOccur
) {
162 setShowWarning(FALSE
);
164 if(options
[STRICT
].doesOccur
) {
167 if(options
[COPYRIGHT
].doesOccur
){
168 setIncludeCopyright(TRUE
);
171 if(options
[SOURCEDIR
].doesOccur
) {
172 inputDir
= options
[SOURCEDIR
].value
;
175 if(options
[DESTDIR
].doesOccur
) {
176 outputDir
= options
[DESTDIR
].value
;
178 if(options
[PACKAGE_NAME
].doesOccur
) {
179 gPackageName
= options
[PACKAGE_NAME
].value
;
180 if(!strcmp(gPackageName
, "ICUDATA"))
182 gPackageName
= U_ICUDATA_NAME
;
184 if(gPackageName
[0] == 0)
190 if(options
[ENCODING
].doesOccur
) {
191 encoding
= options
[ENCODING
].value
;
194 if(options
[ICUDATADIR
].doesOccur
) {
195 u_setDataDirectory(options
[ICUDATADIR
].value
);
199 if (U_FAILURE(status
) && status
!= U_FILE_ACCESS_ERROR
) {
200 /* Note: u_init() will try to open ICU property data.
201 * failures here are expected when building ICU from scratch.
204 fprintf(stderr
, "%s: can not initialize ICU. status = %s\n",
205 argv
[0], u_errorName(status
));
208 status
= U_ZERO_ERROR
;
209 if(options
[WRITE_JAVA
].doesOccur
) {
211 outputEnc
= options
[WRITE_JAVA
].value
;
214 if(options
[BUNDLE_NAME
].doesOccur
) {
215 bundleName
= options
[BUNDLE_NAME
].value
;
218 if(options
[WRITE_XLIFF
].doesOccur
) {
220 if(options
[WRITE_XLIFF
].value
!= NULL
){
221 xliffOutputFileName
= options
[WRITE_XLIFF
].value
;
225 if(options
[NO_BINARY_COLLATION
].doesOccur
) {
232 if(options
[LANGUAGE
].doesOccur
) {
233 language
= options
[LANGUAGE
].value
;
236 /* generate the binary files */
237 for(i
= 1; i
< argc
; ++i
) {
238 status
= U_ZERO_ERROR
;
239 arg
= getLongPathname(argv
[i
]);
242 uprv_strcpy(theCurrentFileName
, inputDir
);
243 uprv_strcat(theCurrentFileName
, U_FILE_SEP_STRING
);
245 *theCurrentFileName
= 0;
247 uprv_strcat(theCurrentFileName
, arg
);
250 printf("Processing file \"%s\"\n", theCurrentFileName
);
252 processFile(arg
, encoding
, inputDir
, outputDir
, gPackageName
, &status
);
260 processFile(const char *filename
, const char *cp
, const char *inputDir
, const char *outputDir
, const char *packageName
, UErrorCode
*status
) {
261 /*FileStream *in = NULL;*/
262 struct SRBRoot
*data
= NULL
;
263 UCHARBUF
*ucbuf
= NULL
;
265 char *openFileName
= NULL
;
266 char *inputDirBuf
= NULL
;
268 char outputFileName
[256];
273 if (status
==NULL
|| U_FAILURE(*status
)) {
277 *status
=U_ILLEGAL_ARGUMENT_ERROR
;
280 filelen
= (int32_t)uprv_strlen(filename
);
282 if(inputDir
== NULL
) {
283 const char *filenameBegin
= uprv_strrchr(filename
, U_FILE_SEP_CHAR
);
284 openFileName
= (char *) uprv_malloc(dirlen
+ filelen
+ 2);
285 openFileName
[0] = '\0';
286 if (filenameBegin
!= NULL
) {
288 * When a filename ../../../data/root.txt is specified,
289 * we presume that the input directory is ../../../data
290 * This is very important when the resource file includes
291 * another file, like UCARules.txt or thaidict.brk.
293 int32_t filenameSize
= (int32_t)(filenameBegin
- filename
+ 1);
294 inputDirBuf
= uprv_strncpy((char *)uprv_malloc(filenameSize
), filename
, filenameSize
);
297 if(inputDirBuf
== NULL
) {
298 *status
= U_MEMORY_ALLOCATION_ERROR
;
302 inputDirBuf
[filenameSize
- 1] = 0;
303 inputDir
= inputDirBuf
;
304 dirlen
= (int32_t)uprv_strlen(inputDir
);
307 dirlen
= (int32_t)uprv_strlen(inputDir
);
309 if(inputDir
[dirlen
-1] != U_FILE_SEP_CHAR
) {
310 openFileName
= (char *) uprv_malloc(dirlen
+ filelen
+ 2);
313 if(openFileName
== NULL
) {
314 *status
= U_MEMORY_ALLOCATION_ERROR
;
318 openFileName
[0] = '\0';
320 * append the input dir to openFileName if the first char in
321 * filename is not file seperation char and the last char input directory is not '.'.
322 * This is to support :
323 * genrb -s. /home/icu/data
325 * The user cannot mix notations like
326 * genrb -s. /icu/data --- the absolute path specified. -s redundant
328 * genrb -s. icu/data --- start from CWD and look in icu/data dir
330 if( (filename
[0] != U_FILE_SEP_CHAR
) && (inputDir
[dirlen
-1] !='.')){
331 uprv_strcpy(openFileName
, inputDir
);
332 openFileName
[dirlen
] = U_FILE_SEP_CHAR
;
334 openFileName
[dirlen
+ 1] = '\0';
336 openFileName
= (char *) uprv_malloc(dirlen
+ filelen
+ 1);
339 if(openFileName
== NULL
) {
340 *status
= U_MEMORY_ALLOCATION_ERROR
;
344 uprv_strcpy(openFileName
, inputDir
);
349 uprv_strcat(openFileName
, filename
);
351 ucbuf
= ucbuf_open(openFileName
, &cp
,getShowWarning(),TRUE
, status
);
353 if(*status
== U_FILE_ACCESS_ERROR
) {
355 fprintf(stderr
, "couldn't open file %s\n", openFileName
== NULL
? filename
: openFileName
);
358 if (ucbuf
== NULL
|| U_FAILURE(*status
)) {
359 fprintf(stderr
, "An error occured processing file %s. Error: %s\n", openFileName
== NULL
? filename
: openFileName
,u_errorName(*status
));
362 /* auto detected popular encodings? */
363 if (cp
!=NULL
&& isVerbose()) {
364 printf("autodetected encoding %s\n", cp
);
366 /* Parse the data into an SRBRoot */
367 data
= parse(ucbuf
, inputDir
, outputDir
, status
);
369 if (data
== NULL
|| U_FAILURE(*status
)) {
370 fprintf(stderr
, "couldn't parse the file %s. Error:%s\n", filename
,u_errorName(*status
));
374 /* Determine the target rb filename */
375 rbname
= make_res_filename(filename
, outputDir
, packageName
, status
);
376 if(U_FAILURE(*status
)) {
377 fprintf(stderr
, "couldn't make the res fileName for bundle %s. Error:%s\n", filename
,u_errorName(*status
));
380 if(write_java
== TRUE
){
381 bundle_write_java(data
,outputDir
,outputEnc
, outputFileName
, sizeof(outputFileName
),packageName
,bundleName
,status
);
382 }else if(write_xliff
==TRUE
){
383 bundle_write_xml(data
,outputDir
,outputEnc
, filename
, outputFileName
, sizeof(outputFileName
),language
, xliffOutputFileName
,status
);
385 /* Write the data to the file */
386 bundle_write(data
, outputDir
, packageName
, outputFileName
, sizeof(outputFileName
), status
);
388 if (U_FAILURE(*status
)) {
389 fprintf(stderr
, "couldn't write bundle %s. Error:%s\n", outputFileName
,u_errorName(*status
));
391 bundle_close(data
, status
);
395 if (inputDirBuf
!= NULL
) {
396 uprv_free(inputDirBuf
);
399 if (openFileName
!= NULL
) {
400 uprv_free(openFileName
);
412 /* Generate the target .res file name from the input file name */
414 make_res_filename(const char *filename
,
415 const char *outputDir
,
416 const char *packageName
,
417 UErrorCode
*status
) {
422 int32_t pkgLen
= 0; /* length of package prefix */
424 if (U_FAILURE(*status
)) {
428 if(packageName
!= NULL
)
430 pkgLen
= (int32_t)(1 + uprv_strlen(packageName
));
434 basename
= dirname
= resName
= 0;
436 /* determine basename, and compiled file names */
437 basename
= (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename
) + 1));
439 *status
= U_MEMORY_ALLOCATION_ERROR
;
443 get_basename(basename
, filename
);
445 dirname
= (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename
) + 1));
447 *status
= U_MEMORY_ALLOCATION_ERROR
;
451 get_dirname(dirname
, filename
);
453 if (outputDir
== NULL
) {
454 /* output in same dir as .txt */
455 resName
= (char*) uprv_malloc(sizeof(char) * (uprv_strlen(dirname
)
457 + uprv_strlen(basename
)
458 + uprv_strlen(RES_SUFFIX
) + 8));
460 *status
= U_MEMORY_ALLOCATION_ERROR
;
464 uprv_strcpy(resName
, dirname
);
466 if(packageName
!= NULL
)
468 uprv_strcat(resName
, packageName
);
469 uprv_strcat(resName
, "_");
472 uprv_strcat(resName
, basename
);
475 int32_t dirlen
= (int32_t)uprv_strlen(outputDir
);
476 int32_t basenamelen
= (int32_t)uprv_strlen(basename
);
478 resName
= (char*) uprv_malloc(sizeof(char) * (dirlen
+ pkgLen
+ basenamelen
+ 8));
480 if (resName
== NULL
) {
481 *status
= U_MEMORY_ALLOCATION_ERROR
;
485 uprv_strcpy(resName
, outputDir
);
487 if(outputDir
[dirlen
] != U_FILE_SEP_CHAR
) {
488 resName
[dirlen
] = U_FILE_SEP_CHAR
;
489 resName
[dirlen
+ 1] = '\0';
492 if(packageName
!= NULL
)
494 uprv_strcat(resName
, packageName
);
495 uprv_strcat(resName
, "_");
498 uprv_strcat(resName
, basename
);
510 * indent-tabs-mode: nil