1*0e209d39SAndroid Build Coastguard Worker // © 2016 and later: Unicode, Inc. and others.
2*0e209d39SAndroid Build Coastguard Worker // License & terms of use: http://www.unicode.org/copyright.html
3*0e209d39SAndroid Build Coastguard Worker /*
4*0e209d39SAndroid Build Coastguard Worker *******************************************************************************
5*0e209d39SAndroid Build Coastguard Worker *
6*0e209d39SAndroid Build Coastguard Worker * Copyright (C) 1998-2016, International Business Machines
7*0e209d39SAndroid Build Coastguard Worker * Corporation and others. All Rights Reserved.
8*0e209d39SAndroid Build Coastguard Worker *
9*0e209d39SAndroid Build Coastguard Worker *******************************************************************************
10*0e209d39SAndroid Build Coastguard Worker *
11*0e209d39SAndroid Build Coastguard Worker * File genrb.cpp
12*0e209d39SAndroid Build Coastguard Worker *
13*0e209d39SAndroid Build Coastguard Worker * Modification History:
14*0e209d39SAndroid Build Coastguard Worker *
15*0e209d39SAndroid Build Coastguard Worker * Date Name Description
16*0e209d39SAndroid Build Coastguard Worker * 05/25/99 stephen Creation.
17*0e209d39SAndroid Build Coastguard Worker * 5/10/01 Ram removed ustdio dependency
18*0e209d39SAndroid Build Coastguard Worker *******************************************************************************
19*0e209d39SAndroid Build Coastguard Worker */
20*0e209d39SAndroid Build Coastguard Worker
21*0e209d39SAndroid Build Coastguard Worker #include <fstream>
22*0e209d39SAndroid Build Coastguard Worker #include <iostream>
23*0e209d39SAndroid Build Coastguard Worker #include <list>
24*0e209d39SAndroid Build Coastguard Worker #include <string>
25*0e209d39SAndroid Build Coastguard Worker
26*0e209d39SAndroid Build Coastguard Worker #include <assert.h>
27*0e209d39SAndroid Build Coastguard Worker #include "genrb.h"
28*0e209d39SAndroid Build Coastguard Worker #include "unicode/localpointer.h"
29*0e209d39SAndroid Build Coastguard Worker #include "unicode/uclean.h"
30*0e209d39SAndroid Build Coastguard Worker #include "unicode/utf16.h"
31*0e209d39SAndroid Build Coastguard Worker #include "charstr.h"
32*0e209d39SAndroid Build Coastguard Worker #include "cmemory.h"
33*0e209d39SAndroid Build Coastguard Worker #include "filterrb.h"
34*0e209d39SAndroid Build Coastguard Worker #include "reslist.h"
35*0e209d39SAndroid Build Coastguard Worker #include "ucmndata.h" /* TODO: for reading the pool bundle */
36*0e209d39SAndroid Build Coastguard Worker #include "collationroot.h"
37*0e209d39SAndroid Build Coastguard Worker
38*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_USE
39*0e209d39SAndroid Build Coastguard Worker
40*0e209d39SAndroid Build Coastguard Worker /* Protos */
41*0e209d39SAndroid Build Coastguard Worker void processFile(const char *filename, const char* cp,
42*0e209d39SAndroid Build Coastguard Worker const char *inputDir, const char *outputDir, const char *filterDir,
43*0e209d39SAndroid Build Coastguard Worker const char *packageName,
44*0e209d39SAndroid Build Coastguard Worker SRBRoot *newPoolBundle, UBool omitBinaryCollation, UErrorCode &status);
45*0e209d39SAndroid Build Coastguard Worker static char *make_res_filename(const char *filename, const char *outputDir,
46*0e209d39SAndroid Build Coastguard Worker const char *packageName, UErrorCode &status);
47*0e209d39SAndroid Build Coastguard Worker
48*0e209d39SAndroid Build Coastguard Worker /* File suffixes */
49*0e209d39SAndroid Build Coastguard Worker #define RES_SUFFIX ".res"
50*0e209d39SAndroid Build Coastguard Worker #define COL_SUFFIX ".col"
51*0e209d39SAndroid Build Coastguard Worker
52*0e209d39SAndroid Build Coastguard Worker const char *gCurrentFileName = nullptr;
53*0e209d39SAndroid Build Coastguard Worker #ifdef XP_MAC_CONSOLE
54*0e209d39SAndroid Build Coastguard Worker #include <console.h>
55*0e209d39SAndroid Build Coastguard Worker #endif
56*0e209d39SAndroid Build Coastguard Worker
close()57*0e209d39SAndroid Build Coastguard Worker void ResFile::close() {
58*0e209d39SAndroid Build Coastguard Worker delete[] fBytes;
59*0e209d39SAndroid Build Coastguard Worker fBytes = nullptr;
60*0e209d39SAndroid Build Coastguard Worker delete fStrings;
61*0e209d39SAndroid Build Coastguard Worker fStrings = nullptr;
62*0e209d39SAndroid Build Coastguard Worker }
63*0e209d39SAndroid Build Coastguard Worker
64*0e209d39SAndroid Build Coastguard Worker enum
65*0e209d39SAndroid Build Coastguard Worker {
66*0e209d39SAndroid Build Coastguard Worker HELP1,
67*0e209d39SAndroid Build Coastguard Worker HELP2,
68*0e209d39SAndroid Build Coastguard Worker VERBOSE,
69*0e209d39SAndroid Build Coastguard Worker QUIET,
70*0e209d39SAndroid Build Coastguard Worker VERSION,
71*0e209d39SAndroid Build Coastguard Worker SOURCEDIR,
72*0e209d39SAndroid Build Coastguard Worker DESTDIR,
73*0e209d39SAndroid Build Coastguard Worker ENCODING,
74*0e209d39SAndroid Build Coastguard Worker ICUDATADIR,
75*0e209d39SAndroid Build Coastguard Worker WRITE_JAVA,
76*0e209d39SAndroid Build Coastguard Worker COPYRIGHT,
77*0e209d39SAndroid Build Coastguard Worker JAVA_PACKAGE,
78*0e209d39SAndroid Build Coastguard Worker BUNDLE_NAME,
79*0e209d39SAndroid Build Coastguard Worker WRITE_XLIFF,
80*0e209d39SAndroid Build Coastguard Worker STRICT,
81*0e209d39SAndroid Build Coastguard Worker NO_BINARY_COLLATION,
82*0e209d39SAndroid Build Coastguard Worker LANGUAGE,
83*0e209d39SAndroid Build Coastguard Worker NO_COLLATION_RULES,
84*0e209d39SAndroid Build Coastguard Worker FORMAT_VERSION,
85*0e209d39SAndroid Build Coastguard Worker WRITE_POOL_BUNDLE,
86*0e209d39SAndroid Build Coastguard Worker USE_POOL_BUNDLE,
87*0e209d39SAndroid Build Coastguard Worker INCLUDE_UNIHAN_COLL,
88*0e209d39SAndroid Build Coastguard Worker FILTERDIR,
89*0e209d39SAndroid Build Coastguard Worker ICU4X_MODE,
90*0e209d39SAndroid Build Coastguard Worker UCADATA
91*0e209d39SAndroid Build Coastguard Worker };
92*0e209d39SAndroid Build Coastguard Worker
93*0e209d39SAndroid Build Coastguard Worker UOption options[]={
94*0e209d39SAndroid Build Coastguard Worker UOPTION_HELP_H,
95*0e209d39SAndroid Build Coastguard Worker UOPTION_HELP_QUESTION_MARK,
96*0e209d39SAndroid Build Coastguard Worker UOPTION_VERBOSE,
97*0e209d39SAndroid Build Coastguard Worker UOPTION_QUIET,
98*0e209d39SAndroid Build Coastguard Worker UOPTION_VERSION,
99*0e209d39SAndroid Build Coastguard Worker UOPTION_SOURCEDIR,
100*0e209d39SAndroid Build Coastguard Worker UOPTION_DESTDIR,
101*0e209d39SAndroid Build Coastguard Worker UOPTION_ENCODING,
102*0e209d39SAndroid Build Coastguard Worker UOPTION_ICUDATADIR,
103*0e209d39SAndroid Build Coastguard Worker UOPTION_WRITE_JAVA,
104*0e209d39SAndroid Build Coastguard Worker UOPTION_COPYRIGHT,
105*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("java-package", '\x01', UOPT_REQUIRES_ARG),
106*0e209d39SAndroid Build Coastguard Worker UOPTION_BUNDLE_NAME,
107*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("write-xliff", 'x', UOPT_OPTIONAL_ARG),
108*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("strict", 'k', UOPT_NO_ARG), /* 14 */
109*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("noBinaryCollation", 'C', UOPT_NO_ARG),/* 15 */
110*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("language", 'l', UOPT_REQUIRES_ARG), /* 16 */
111*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("omitCollationRules", 'R', UOPT_NO_ARG),/* 17 */
112*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("formatVersion", '\x01', UOPT_REQUIRES_ARG),/* 18 */
113*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("writePoolBundle", '\x01', UOPT_OPTIONAL_ARG),/* 19 */
114*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("usePoolBundle", '\x01', UOPT_OPTIONAL_ARG),/* 20 */
115*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("includeUnihanColl", '\x01', UOPT_NO_ARG),/* 21 */ /* temporary, don't display in usage info */
116*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("filterDir", '\x01', UOPT_OPTIONAL_ARG), /* 22 */
117*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("icu4xMode", 'X', UOPT_NO_ARG),/* 23 */
118*0e209d39SAndroid Build Coastguard Worker UOPTION_DEF("ucadata", '\x01', UOPT_REQUIRES_ARG),/* 24 */
119*0e209d39SAndroid Build Coastguard Worker };
120*0e209d39SAndroid Build Coastguard Worker
121*0e209d39SAndroid Build Coastguard Worker static UBool write_java = false;
122*0e209d39SAndroid Build Coastguard Worker static UBool write_xliff = false;
123*0e209d39SAndroid Build Coastguard Worker static const char* outputEnc ="";
124*0e209d39SAndroid Build Coastguard Worker
125*0e209d39SAndroid Build Coastguard Worker static ResFile poolBundle;
126*0e209d39SAndroid Build Coastguard Worker
127*0e209d39SAndroid Build Coastguard Worker /*added by Jing*/
128*0e209d39SAndroid Build Coastguard Worker static const char* language = nullptr;
129*0e209d39SAndroid Build Coastguard Worker static const char* xliffOutputFileName = nullptr;
130*0e209d39SAndroid Build Coastguard Worker int
main(int argc,char * argv[])131*0e209d39SAndroid Build Coastguard Worker main(int argc,
132*0e209d39SAndroid Build Coastguard Worker char* argv[])
133*0e209d39SAndroid Build Coastguard Worker {
134*0e209d39SAndroid Build Coastguard Worker UErrorCode status = U_ZERO_ERROR;
135*0e209d39SAndroid Build Coastguard Worker const char *arg = nullptr;
136*0e209d39SAndroid Build Coastguard Worker const char *outputDir = nullptr; /* nullptr = no output directory, use current */
137*0e209d39SAndroid Build Coastguard Worker const char *inputDir = nullptr;
138*0e209d39SAndroid Build Coastguard Worker const char *filterDir = nullptr;
139*0e209d39SAndroid Build Coastguard Worker const char *encoding = "";
140*0e209d39SAndroid Build Coastguard Worker int i;
141*0e209d39SAndroid Build Coastguard Worker UBool illegalArg = false;
142*0e209d39SAndroid Build Coastguard Worker
143*0e209d39SAndroid Build Coastguard Worker U_MAIN_INIT_ARGS(argc, argv);
144*0e209d39SAndroid Build Coastguard Worker
145*0e209d39SAndroid Build Coastguard Worker options[JAVA_PACKAGE].value = "com.ibm.icu.impl.data";
146*0e209d39SAndroid Build Coastguard Worker options[BUNDLE_NAME].value = "LocaleElements";
147*0e209d39SAndroid Build Coastguard Worker argc = u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options);
148*0e209d39SAndroid Build Coastguard Worker
149*0e209d39SAndroid Build Coastguard Worker /* error handling, printing usage message */
150*0e209d39SAndroid Build Coastguard Worker if(argc<0) {
151*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "%s: error in command line argument \"%s\"\n", argv[0], argv[-argc]);
152*0e209d39SAndroid Build Coastguard Worker illegalArg = true;
153*0e209d39SAndroid Build Coastguard Worker } else if(argc<2) {
154*0e209d39SAndroid Build Coastguard Worker illegalArg = true;
155*0e209d39SAndroid Build Coastguard Worker }
156*0e209d39SAndroid Build Coastguard Worker if(options[WRITE_POOL_BUNDLE].doesOccur && options[USE_POOL_BUNDLE].doesOccur) {
157*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "%s: cannot combine --writePoolBundle and --usePoolBundle\n", argv[0]);
158*0e209d39SAndroid Build Coastguard Worker illegalArg = true;
159*0e209d39SAndroid Build Coastguard Worker }
160*0e209d39SAndroid Build Coastguard Worker if (options[ICU4X_MODE].doesOccur && !options[UCADATA].doesOccur) {
161*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "%s: --icu4xMode requires --ucadata\n", argv[0]);
162*0e209d39SAndroid Build Coastguard Worker illegalArg = true;
163*0e209d39SAndroid Build Coastguard Worker }
164*0e209d39SAndroid Build Coastguard Worker if(options[FORMAT_VERSION].doesOccur) {
165*0e209d39SAndroid Build Coastguard Worker const char *s = options[FORMAT_VERSION].value;
166*0e209d39SAndroid Build Coastguard Worker if(uprv_strlen(s) != 1 || (s[0] < '1' && '3' < s[0])) {
167*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "%s: unsupported --formatVersion %s\n", argv[0], s);
168*0e209d39SAndroid Build Coastguard Worker illegalArg = true;
169*0e209d39SAndroid Build Coastguard Worker } else if(s[0] == '1' &&
170*0e209d39SAndroid Build Coastguard Worker (options[WRITE_POOL_BUNDLE].doesOccur || options[USE_POOL_BUNDLE].doesOccur)
171*0e209d39SAndroid Build Coastguard Worker ) {
172*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "%s: cannot combine --formatVersion 1 with --writePoolBundle or --usePoolBundle\n", argv[0]);
173*0e209d39SAndroid Build Coastguard Worker illegalArg = true;
174*0e209d39SAndroid Build Coastguard Worker } else {
175*0e209d39SAndroid Build Coastguard Worker setFormatVersion(s[0] - '0');
176*0e209d39SAndroid Build Coastguard Worker }
177*0e209d39SAndroid Build Coastguard Worker }
178*0e209d39SAndroid Build Coastguard Worker
179*0e209d39SAndroid Build Coastguard Worker if((options[JAVA_PACKAGE].doesOccur || options[BUNDLE_NAME].doesOccur) &&
180*0e209d39SAndroid Build Coastguard Worker !options[WRITE_JAVA].doesOccur) {
181*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
182*0e209d39SAndroid Build Coastguard Worker "%s error: command line argument --java-package or --bundle-name "
183*0e209d39SAndroid Build Coastguard Worker "without --write-java\n",
184*0e209d39SAndroid Build Coastguard Worker argv[0]);
185*0e209d39SAndroid Build Coastguard Worker illegalArg = true;
186*0e209d39SAndroid Build Coastguard Worker }
187*0e209d39SAndroid Build Coastguard Worker
188*0e209d39SAndroid Build Coastguard Worker if(options[VERSION].doesOccur) {
189*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
190*0e209d39SAndroid Build Coastguard Worker "%s version %s (ICU version %s).\n"
191*0e209d39SAndroid Build Coastguard Worker "%s\n",
192*0e209d39SAndroid Build Coastguard Worker argv[0], GENRB_VERSION, U_ICU_VERSION, U_COPYRIGHT_STRING);
193*0e209d39SAndroid Build Coastguard Worker if(!illegalArg) {
194*0e209d39SAndroid Build Coastguard Worker return U_ZERO_ERROR;
195*0e209d39SAndroid Build Coastguard Worker }
196*0e209d39SAndroid Build Coastguard Worker }
197*0e209d39SAndroid Build Coastguard Worker
198*0e209d39SAndroid Build Coastguard Worker if(illegalArg || options[HELP1].doesOccur || options[HELP2].doesOccur) {
199*0e209d39SAndroid Build Coastguard Worker /*
200*0e209d39SAndroid Build Coastguard Worker * Broken into chunks because the C89 standard says the minimum
201*0e209d39SAndroid Build Coastguard Worker * required supported string length is 509 bytes.
202*0e209d39SAndroid Build Coastguard Worker */
203*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
204*0e209d39SAndroid Build Coastguard Worker "Usage: %s [OPTIONS] [FILES]\n"
205*0e209d39SAndroid Build Coastguard Worker "\tReads the list of resource bundle source files and creates\n"
206*0e209d39SAndroid Build Coastguard Worker "\tbinary version of resource bundles (.res files)\n",
207*0e209d39SAndroid Build Coastguard Worker argv[0]);
208*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
209*0e209d39SAndroid Build Coastguard Worker "Options:\n"
210*0e209d39SAndroid Build Coastguard Worker "\t-h or -? or --help this usage text\n"
211*0e209d39SAndroid Build Coastguard Worker "\t-q or --quiet do not display warnings\n"
212*0e209d39SAndroid Build Coastguard Worker "\t-v or --verbose print extra information when processing files\n"
213*0e209d39SAndroid Build Coastguard Worker "\t-V or --version prints out version number and exits\n"
214*0e209d39SAndroid Build Coastguard Worker "\t-c or --copyright include copyright notice\n");
215*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
216*0e209d39SAndroid Build Coastguard Worker "\t-e or --encoding encoding of source files\n"
217*0e209d39SAndroid Build Coastguard Worker "\t-d or --destdir destination directory, followed by the path, defaults to '%s'\n"
218*0e209d39SAndroid Build Coastguard Worker "\t-s or --sourcedir source directory for files followed by path, defaults to '%s'\n"
219*0e209d39SAndroid Build Coastguard Worker "\t-i or --icudatadir directory for locating any needed intermediate data files,\n"
220*0e209d39SAndroid Build Coastguard Worker "\t followed by path, defaults to '%s'\n",
221*0e209d39SAndroid Build Coastguard Worker u_getDataDirectory(), u_getDataDirectory(), u_getDataDirectory());
222*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
223*0e209d39SAndroid Build Coastguard Worker "\t-j or --write-java write a Java ListResourceBundle for ICU4J, followed by optional encoding\n"
224*0e209d39SAndroid Build Coastguard Worker "\t defaults to ASCII and \\uXXXX format.\n"
225*0e209d39SAndroid Build Coastguard Worker "\t --java-package For --write-java: package name for writing the ListResourceBundle,\n"
226*0e209d39SAndroid Build Coastguard Worker "\t defaults to com.ibm.icu.impl.data\n");
227*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
228*0e209d39SAndroid Build Coastguard Worker "\t-b or --bundle-name For --write-java: root resource bundle name for writing the ListResourceBundle,\n"
229*0e209d39SAndroid Build Coastguard Worker "\t defaults to LocaleElements\n"
230*0e209d39SAndroid Build Coastguard Worker "\t-x or --write-xliff write an XLIFF file for the resource bundle. Followed by\n"
231*0e209d39SAndroid Build Coastguard Worker "\t an optional output file name.\n"
232*0e209d39SAndroid Build Coastguard Worker "\t-k or --strict use pedantic parsing of syntax\n"
233*0e209d39SAndroid Build Coastguard Worker /*added by Jing*/
234*0e209d39SAndroid Build Coastguard Worker "\t-l or --language for XLIFF: language code compliant with BCP 47.\n");
235*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
236*0e209d39SAndroid Build Coastguard Worker "\t-C or --noBinaryCollation do not generate binary collation image;\n"
237*0e209d39SAndroid Build Coastguard Worker "\t makes .res file smaller but collator instantiation much slower;\n"
238*0e209d39SAndroid Build Coastguard Worker "\t maintains ability to get tailoring rules\n"
239*0e209d39SAndroid Build Coastguard Worker "\t-R or --omitCollationRules do not include collation (tailoring) rules;\n"
240*0e209d39SAndroid Build Coastguard Worker "\t makes .res file smaller and maintains collator instantiation speed\n"
241*0e209d39SAndroid Build Coastguard Worker "\t but tailoring rules will not be available (they are rarely used)\n");
242*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
243*0e209d39SAndroid Build Coastguard Worker "\t --formatVersion write a .res file compatible with the requested formatVersion (single digit);\n"
244*0e209d39SAndroid Build Coastguard Worker "\t for example, --formatVersion 1\n");
245*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
246*0e209d39SAndroid Build Coastguard Worker "\t --writePoolBundle [directory] write a pool.res file with all of the keys of all input bundles\n"
247*0e209d39SAndroid Build Coastguard Worker "\t --usePoolBundle [directory] point to keys from the pool.res keys pool bundle if they are available there;\n"
248*0e209d39SAndroid Build Coastguard Worker "\t makes .res files smaller but dependent on the pool bundle\n"
249*0e209d39SAndroid Build Coastguard Worker "\t (--writePoolBundle and --usePoolBundle cannot be combined)\n");
250*0e209d39SAndroid Build Coastguard Worker fprintf(stderr,
251*0e209d39SAndroid Build Coastguard Worker "\t --filterDir Input directory where filter files are available.\n"
252*0e209d39SAndroid Build Coastguard Worker "\t For more on filter files, see ICU Data Build Tool.\n");
253*0e209d39SAndroid Build Coastguard Worker
254*0e209d39SAndroid Build Coastguard Worker return illegalArg ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
255*0e209d39SAndroid Build Coastguard Worker }
256*0e209d39SAndroid Build Coastguard Worker
257*0e209d39SAndroid Build Coastguard Worker if(options[VERBOSE].doesOccur) {
258*0e209d39SAndroid Build Coastguard Worker setVerbose(true);
259*0e209d39SAndroid Build Coastguard Worker }
260*0e209d39SAndroid Build Coastguard Worker
261*0e209d39SAndroid Build Coastguard Worker if(options[QUIET].doesOccur) {
262*0e209d39SAndroid Build Coastguard Worker setShowWarning(false);
263*0e209d39SAndroid Build Coastguard Worker }
264*0e209d39SAndroid Build Coastguard Worker if(options[STRICT].doesOccur) {
265*0e209d39SAndroid Build Coastguard Worker setStrict(true);
266*0e209d39SAndroid Build Coastguard Worker }
267*0e209d39SAndroid Build Coastguard Worker if(options[COPYRIGHT].doesOccur){
268*0e209d39SAndroid Build Coastguard Worker setIncludeCopyright(true);
269*0e209d39SAndroid Build Coastguard Worker }
270*0e209d39SAndroid Build Coastguard Worker
271*0e209d39SAndroid Build Coastguard Worker if(options[SOURCEDIR].doesOccur) {
272*0e209d39SAndroid Build Coastguard Worker inputDir = options[SOURCEDIR].value;
273*0e209d39SAndroid Build Coastguard Worker }
274*0e209d39SAndroid Build Coastguard Worker
275*0e209d39SAndroid Build Coastguard Worker if(options[DESTDIR].doesOccur) {
276*0e209d39SAndroid Build Coastguard Worker outputDir = options[DESTDIR].value;
277*0e209d39SAndroid Build Coastguard Worker }
278*0e209d39SAndroid Build Coastguard Worker
279*0e209d39SAndroid Build Coastguard Worker if (options[FILTERDIR].doesOccur) {
280*0e209d39SAndroid Build Coastguard Worker filterDir = options[FILTERDIR].value;
281*0e209d39SAndroid Build Coastguard Worker }
282*0e209d39SAndroid Build Coastguard Worker
283*0e209d39SAndroid Build Coastguard Worker if(options[ENCODING].doesOccur) {
284*0e209d39SAndroid Build Coastguard Worker encoding = options[ENCODING].value;
285*0e209d39SAndroid Build Coastguard Worker }
286*0e209d39SAndroid Build Coastguard Worker
287*0e209d39SAndroid Build Coastguard Worker if(options[ICUDATADIR].doesOccur) {
288*0e209d39SAndroid Build Coastguard Worker u_setDataDirectory(options[ICUDATADIR].value);
289*0e209d39SAndroid Build Coastguard Worker }
290*0e209d39SAndroid Build Coastguard Worker /* Initialize ICU */
291*0e209d39SAndroid Build Coastguard Worker u_init(&status);
292*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status) && status != U_FILE_ACCESS_ERROR) {
293*0e209d39SAndroid Build Coastguard Worker /* Note: u_init() will try to open ICU property data.
294*0e209d39SAndroid Build Coastguard Worker * failures here are expected when building ICU from scratch.
295*0e209d39SAndroid Build Coastguard Worker * ignore them.
296*0e209d39SAndroid Build Coastguard Worker */
297*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "%s: can not initialize ICU. status = %s\n",
298*0e209d39SAndroid Build Coastguard Worker argv[0], u_errorName(status));
299*0e209d39SAndroid Build Coastguard Worker exit(1);
300*0e209d39SAndroid Build Coastguard Worker }
301*0e209d39SAndroid Build Coastguard Worker status = U_ZERO_ERROR;
302*0e209d39SAndroid Build Coastguard Worker if(options[WRITE_JAVA].doesOccur) {
303*0e209d39SAndroid Build Coastguard Worker write_java = true;
304*0e209d39SAndroid Build Coastguard Worker outputEnc = options[WRITE_JAVA].value;
305*0e209d39SAndroid Build Coastguard Worker }
306*0e209d39SAndroid Build Coastguard Worker
307*0e209d39SAndroid Build Coastguard Worker if(options[WRITE_XLIFF].doesOccur) {
308*0e209d39SAndroid Build Coastguard Worker write_xliff = true;
309*0e209d39SAndroid Build Coastguard Worker if(options[WRITE_XLIFF].value != nullptr){
310*0e209d39SAndroid Build Coastguard Worker xliffOutputFileName = options[WRITE_XLIFF].value;
311*0e209d39SAndroid Build Coastguard Worker }
312*0e209d39SAndroid Build Coastguard Worker }
313*0e209d39SAndroid Build Coastguard Worker
314*0e209d39SAndroid Build Coastguard Worker if (options[UCADATA].doesOccur) {
315*0e209d39SAndroid Build Coastguard Worker #if !UCONFIG_NO_COLLATION
316*0e209d39SAndroid Build Coastguard Worker CollationRoot::forceLoadFromFile(options[UCADATA].value, status);
317*0e209d39SAndroid Build Coastguard Worker #else
318*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "--ucadata was used with UCONFIG_NO_COLLATION\n");
319*0e209d39SAndroid Build Coastguard Worker return status;
320*0e209d39SAndroid Build Coastguard Worker #endif
321*0e209d39SAndroid Build Coastguard Worker }
322*0e209d39SAndroid Build Coastguard Worker
323*0e209d39SAndroid Build Coastguard Worker initParser();
324*0e209d39SAndroid Build Coastguard Worker
325*0e209d39SAndroid Build Coastguard Worker /*added by Jing*/
326*0e209d39SAndroid Build Coastguard Worker if(options[LANGUAGE].doesOccur) {
327*0e209d39SAndroid Build Coastguard Worker language = options[LANGUAGE].value;
328*0e209d39SAndroid Build Coastguard Worker }
329*0e209d39SAndroid Build Coastguard Worker
330*0e209d39SAndroid Build Coastguard Worker LocalPointer<SRBRoot> newPoolBundle;
331*0e209d39SAndroid Build Coastguard Worker if(options[WRITE_POOL_BUNDLE].doesOccur) {
332*0e209d39SAndroid Build Coastguard Worker newPoolBundle.adoptInsteadAndCheckErrorCode(new SRBRoot(nullptr, true, status), status);
333*0e209d39SAndroid Build Coastguard Worker if(U_FAILURE(status)) {
334*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "unable to create an empty bundle for the pool keys: %s\n", u_errorName(status));
335*0e209d39SAndroid Build Coastguard Worker return status;
336*0e209d39SAndroid Build Coastguard Worker } else {
337*0e209d39SAndroid Build Coastguard Worker const char *poolResName = "pool.res";
338*0e209d39SAndroid Build Coastguard Worker char *nameWithoutSuffix = static_cast<char *>(uprv_malloc(uprv_strlen(poolResName) + 1));
339*0e209d39SAndroid Build Coastguard Worker if (nameWithoutSuffix == nullptr) {
340*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "out of memory error\n");
341*0e209d39SAndroid Build Coastguard Worker return U_MEMORY_ALLOCATION_ERROR;
342*0e209d39SAndroid Build Coastguard Worker }
343*0e209d39SAndroid Build Coastguard Worker uprv_strcpy(nameWithoutSuffix, poolResName);
344*0e209d39SAndroid Build Coastguard Worker *uprv_strrchr(nameWithoutSuffix, '.') = 0;
345*0e209d39SAndroid Build Coastguard Worker newPoolBundle->fLocale = nameWithoutSuffix;
346*0e209d39SAndroid Build Coastguard Worker }
347*0e209d39SAndroid Build Coastguard Worker }
348*0e209d39SAndroid Build Coastguard Worker
349*0e209d39SAndroid Build Coastguard Worker if(options[USE_POOL_BUNDLE].doesOccur) {
350*0e209d39SAndroid Build Coastguard Worker const char *poolResName = "pool.res";
351*0e209d39SAndroid Build Coastguard Worker FileStream *poolFile;
352*0e209d39SAndroid Build Coastguard Worker int32_t poolFileSize;
353*0e209d39SAndroid Build Coastguard Worker int32_t indexLength;
354*0e209d39SAndroid Build Coastguard Worker /*
355*0e209d39SAndroid Build Coastguard Worker * TODO: Consolidate inputDir/filename handling from main() and processFile()
356*0e209d39SAndroid Build Coastguard Worker * into a common function, and use it here as well.
357*0e209d39SAndroid Build Coastguard Worker * Try to create toolutil functions for dealing with dir/filenames and
358*0e209d39SAndroid Build Coastguard Worker * loading ICU data files without udata_open().
359*0e209d39SAndroid Build Coastguard Worker * Share code with icupkg?
360*0e209d39SAndroid Build Coastguard Worker * Also, make_res_filename() seems to be unused. Review and remove.
361*0e209d39SAndroid Build Coastguard Worker */
362*0e209d39SAndroid Build Coastguard Worker CharString poolFileName;
363*0e209d39SAndroid Build Coastguard Worker if (options[USE_POOL_BUNDLE].value!=nullptr) {
364*0e209d39SAndroid Build Coastguard Worker poolFileName.append(options[USE_POOL_BUNDLE].value, status);
365*0e209d39SAndroid Build Coastguard Worker } else if (inputDir) {
366*0e209d39SAndroid Build Coastguard Worker poolFileName.append(inputDir, status);
367*0e209d39SAndroid Build Coastguard Worker }
368*0e209d39SAndroid Build Coastguard Worker poolFileName.appendPathPart(poolResName, status);
369*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) {
370*0e209d39SAndroid Build Coastguard Worker return status;
371*0e209d39SAndroid Build Coastguard Worker }
372*0e209d39SAndroid Build Coastguard Worker poolFile = T_FileStream_open(poolFileName.data(), "rb");
373*0e209d39SAndroid Build Coastguard Worker if (poolFile == nullptr) {
374*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "unable to open pool bundle file %s\n", poolFileName.data());
375*0e209d39SAndroid Build Coastguard Worker return 1;
376*0e209d39SAndroid Build Coastguard Worker }
377*0e209d39SAndroid Build Coastguard Worker poolFileSize = T_FileStream_size(poolFile);
378*0e209d39SAndroid Build Coastguard Worker if (poolFileSize < 32) {
379*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "the pool bundle file %s is too small\n", poolFileName.data());
380*0e209d39SAndroid Build Coastguard Worker return 1;
381*0e209d39SAndroid Build Coastguard Worker }
382*0e209d39SAndroid Build Coastguard Worker poolBundle.fBytes = new uint8_t[(poolFileSize + 15) & ~15];
383*0e209d39SAndroid Build Coastguard Worker if (poolFileSize > 0 && poolBundle.fBytes == nullptr) {
384*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "unable to allocate memory for the pool bundle file %s\n", poolFileName.data());
385*0e209d39SAndroid Build Coastguard Worker return U_MEMORY_ALLOCATION_ERROR;
386*0e209d39SAndroid Build Coastguard Worker }
387*0e209d39SAndroid Build Coastguard Worker
388*0e209d39SAndroid Build Coastguard Worker UDataSwapper *ds;
389*0e209d39SAndroid Build Coastguard Worker const DataHeader *header;
390*0e209d39SAndroid Build Coastguard Worker int32_t bytesRead = T_FileStream_read(poolFile, poolBundle.fBytes, poolFileSize);
391*0e209d39SAndroid Build Coastguard Worker if (bytesRead != poolFileSize) {
392*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "unable to read the pool bundle file %s\n", poolFileName.data());
393*0e209d39SAndroid Build Coastguard Worker return 1;
394*0e209d39SAndroid Build Coastguard Worker }
395*0e209d39SAndroid Build Coastguard Worker /*
396*0e209d39SAndroid Build Coastguard Worker * Swap the pool bundle so that a single checked-in file can be used.
397*0e209d39SAndroid Build Coastguard Worker * The swapper functions also test that the data looks like
398*0e209d39SAndroid Build Coastguard Worker * a well-formed .res file.
399*0e209d39SAndroid Build Coastguard Worker */
400*0e209d39SAndroid Build Coastguard Worker ds = udata_openSwapperForInputData(poolBundle.fBytes, bytesRead,
401*0e209d39SAndroid Build Coastguard Worker U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &status);
402*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) {
403*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "udata_openSwapperForInputData(pool bundle %s) failed: %s\n",
404*0e209d39SAndroid Build Coastguard Worker poolFileName.data(), u_errorName(status));
405*0e209d39SAndroid Build Coastguard Worker return status;
406*0e209d39SAndroid Build Coastguard Worker }
407*0e209d39SAndroid Build Coastguard Worker ures_swap(ds, poolBundle.fBytes, bytesRead, poolBundle.fBytes, &status);
408*0e209d39SAndroid Build Coastguard Worker udata_closeSwapper(ds);
409*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) {
410*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "ures_swap(pool bundle %s) failed: %s\n",
411*0e209d39SAndroid Build Coastguard Worker poolFileName.data(), u_errorName(status));
412*0e209d39SAndroid Build Coastguard Worker return status;
413*0e209d39SAndroid Build Coastguard Worker }
414*0e209d39SAndroid Build Coastguard Worker header = (const DataHeader *)poolBundle.fBytes;
415*0e209d39SAndroid Build Coastguard Worker if (header->info.formatVersion[0] < 2) {
416*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "invalid format of pool bundle file %s\n", poolFileName.data());
417*0e209d39SAndroid Build Coastguard Worker return U_INVALID_FORMAT_ERROR;
418*0e209d39SAndroid Build Coastguard Worker }
419*0e209d39SAndroid Build Coastguard Worker const int32_t *pRoot = (const int32_t *)(
420*0e209d39SAndroid Build Coastguard Worker (const char *)header + header->dataHeader.headerSize);
421*0e209d39SAndroid Build Coastguard Worker poolBundle.fIndexes = pRoot + 1;
422*0e209d39SAndroid Build Coastguard Worker indexLength = poolBundle.fIndexes[URES_INDEX_LENGTH] & 0xff;
423*0e209d39SAndroid Build Coastguard Worker if (indexLength <= URES_INDEX_POOL_CHECKSUM) {
424*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "insufficient indexes[] in pool bundle file %s\n", poolFileName.data());
425*0e209d39SAndroid Build Coastguard Worker return U_INVALID_FORMAT_ERROR;
426*0e209d39SAndroid Build Coastguard Worker }
427*0e209d39SAndroid Build Coastguard Worker int32_t keysBottom = 1 + indexLength;
428*0e209d39SAndroid Build Coastguard Worker int32_t keysTop = poolBundle.fIndexes[URES_INDEX_KEYS_TOP];
429*0e209d39SAndroid Build Coastguard Worker poolBundle.fKeys = (const char *)(pRoot + keysBottom);
430*0e209d39SAndroid Build Coastguard Worker poolBundle.fKeysLength = (keysTop - keysBottom) * 4;
431*0e209d39SAndroid Build Coastguard Worker poolBundle.fChecksum = poolBundle.fIndexes[URES_INDEX_POOL_CHECKSUM];
432*0e209d39SAndroid Build Coastguard Worker
433*0e209d39SAndroid Build Coastguard Worker for (i = 0; i < poolBundle.fKeysLength; ++i) {
434*0e209d39SAndroid Build Coastguard Worker if (poolBundle.fKeys[i] == 0) {
435*0e209d39SAndroid Build Coastguard Worker ++poolBundle.fKeysCount;
436*0e209d39SAndroid Build Coastguard Worker }
437*0e209d39SAndroid Build Coastguard Worker }
438*0e209d39SAndroid Build Coastguard Worker
439*0e209d39SAndroid Build Coastguard Worker // 16BitUnits[] begins with strings-v2.
440*0e209d39SAndroid Build Coastguard Worker // The strings-v2 may optionally be terminated by what looks like
441*0e209d39SAndroid Build Coastguard Worker // an explicit string length that exceeds the number of remaining 16-bit units.
442*0e209d39SAndroid Build Coastguard Worker int32_t stringUnitsLength = (poolBundle.fIndexes[URES_INDEX_16BIT_TOP] - keysTop) * 2;
443*0e209d39SAndroid Build Coastguard Worker if (stringUnitsLength >= 2 && getFormatVersion() >= 3) {
444*0e209d39SAndroid Build Coastguard Worker poolBundle.fStrings = new PseudoListResource(nullptr, status);
445*0e209d39SAndroid Build Coastguard Worker if (poolBundle.fStrings == nullptr) {
446*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "unable to allocate memory for the pool bundle strings %s\n",
447*0e209d39SAndroid Build Coastguard Worker poolFileName.data());
448*0e209d39SAndroid Build Coastguard Worker return U_MEMORY_ALLOCATION_ERROR;
449*0e209d39SAndroid Build Coastguard Worker }
450*0e209d39SAndroid Build Coastguard Worker // The PseudoListResource constructor call did not allocate further memory.
451*0e209d39SAndroid Build Coastguard Worker assert(U_SUCCESS(status));
452*0e209d39SAndroid Build Coastguard Worker const char16_t *p = (const char16_t *)(pRoot + keysTop);
453*0e209d39SAndroid Build Coastguard Worker int32_t remaining = stringUnitsLength;
454*0e209d39SAndroid Build Coastguard Worker do {
455*0e209d39SAndroid Build Coastguard Worker int32_t first = *p;
456*0e209d39SAndroid Build Coastguard Worker int8_t numCharsForLength;
457*0e209d39SAndroid Build Coastguard Worker int32_t length;
458*0e209d39SAndroid Build Coastguard Worker if (!U16_IS_TRAIL(first)) {
459*0e209d39SAndroid Build Coastguard Worker // NUL-terminated
460*0e209d39SAndroid Build Coastguard Worker numCharsForLength = 0;
461*0e209d39SAndroid Build Coastguard Worker for (length = 0;
462*0e209d39SAndroid Build Coastguard Worker length < remaining && p[length] != 0;
463*0e209d39SAndroid Build Coastguard Worker ++length) {}
464*0e209d39SAndroid Build Coastguard Worker } else if (first < 0xdfef) {
465*0e209d39SAndroid Build Coastguard Worker numCharsForLength = 1;
466*0e209d39SAndroid Build Coastguard Worker length = first & 0x3ff;
467*0e209d39SAndroid Build Coastguard Worker } else if (first < 0xdfff && remaining >= 2) {
468*0e209d39SAndroid Build Coastguard Worker numCharsForLength = 2;
469*0e209d39SAndroid Build Coastguard Worker length = ((first - 0xdfef) << 16) | p[1];
470*0e209d39SAndroid Build Coastguard Worker } else if (first == 0xdfff && remaining >= 3) {
471*0e209d39SAndroid Build Coastguard Worker numCharsForLength = 3;
472*0e209d39SAndroid Build Coastguard Worker length = ((int32_t)p[1] << 16) | p[2];
473*0e209d39SAndroid Build Coastguard Worker } else {
474*0e209d39SAndroid Build Coastguard Worker break; // overrun
475*0e209d39SAndroid Build Coastguard Worker }
476*0e209d39SAndroid Build Coastguard Worker // Check for overrun before changing remaining,
477*0e209d39SAndroid Build Coastguard Worker // so that it is always accurate after the loop body.
478*0e209d39SAndroid Build Coastguard Worker if ((numCharsForLength + length) >= remaining ||
479*0e209d39SAndroid Build Coastguard Worker p[numCharsForLength + length] != 0) {
480*0e209d39SAndroid Build Coastguard Worker break; // overrun or explicitly terminated
481*0e209d39SAndroid Build Coastguard Worker }
482*0e209d39SAndroid Build Coastguard Worker int32_t poolStringIndex = stringUnitsLength - remaining;
483*0e209d39SAndroid Build Coastguard Worker // Maximum pool string index when suffix-sharing the last character.
484*0e209d39SAndroid Build Coastguard Worker int32_t maxStringIndex = poolStringIndex + numCharsForLength + length - 1;
485*0e209d39SAndroid Build Coastguard Worker if (maxStringIndex >= RES_MAX_OFFSET) {
486*0e209d39SAndroid Build Coastguard Worker // pool string index overrun
487*0e209d39SAndroid Build Coastguard Worker break;
488*0e209d39SAndroid Build Coastguard Worker }
489*0e209d39SAndroid Build Coastguard Worker p += numCharsForLength;
490*0e209d39SAndroid Build Coastguard Worker remaining -= numCharsForLength;
491*0e209d39SAndroid Build Coastguard Worker if (length != 0) {
492*0e209d39SAndroid Build Coastguard Worker StringResource *sr =
493*0e209d39SAndroid Build Coastguard Worker new StringResource(poolStringIndex, numCharsForLength,
494*0e209d39SAndroid Build Coastguard Worker p, length, status);
495*0e209d39SAndroid Build Coastguard Worker if (sr == nullptr) {
496*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "unable to allocate memory for a pool bundle string %s\n",
497*0e209d39SAndroid Build Coastguard Worker poolFileName.data());
498*0e209d39SAndroid Build Coastguard Worker return U_MEMORY_ALLOCATION_ERROR;
499*0e209d39SAndroid Build Coastguard Worker }
500*0e209d39SAndroid Build Coastguard Worker poolBundle.fStrings->add(sr);
501*0e209d39SAndroid Build Coastguard Worker poolBundle.fStringIndexLimit = maxStringIndex + 1;
502*0e209d39SAndroid Build Coastguard Worker // The StringResource constructor did not allocate further memory.
503*0e209d39SAndroid Build Coastguard Worker assert(U_SUCCESS(status));
504*0e209d39SAndroid Build Coastguard Worker }
505*0e209d39SAndroid Build Coastguard Worker p += length + 1;
506*0e209d39SAndroid Build Coastguard Worker remaining -= length + 1;
507*0e209d39SAndroid Build Coastguard Worker } while (remaining > 0);
508*0e209d39SAndroid Build Coastguard Worker if (poolBundle.fStrings->fCount == 0) {
509*0e209d39SAndroid Build Coastguard Worker delete poolBundle.fStrings;
510*0e209d39SAndroid Build Coastguard Worker poolBundle.fStrings = nullptr;
511*0e209d39SAndroid Build Coastguard Worker }
512*0e209d39SAndroid Build Coastguard Worker }
513*0e209d39SAndroid Build Coastguard Worker
514*0e209d39SAndroid Build Coastguard Worker T_FileStream_close(poolFile);
515*0e209d39SAndroid Build Coastguard Worker setUsePoolBundle(true);
516*0e209d39SAndroid Build Coastguard Worker if (isVerbose() && poolBundle.fStrings != nullptr) {
517*0e209d39SAndroid Build Coastguard Worker printf("number of shared strings: %d\n", (int)poolBundle.fStrings->fCount);
518*0e209d39SAndroid Build Coastguard Worker int32_t length = poolBundle.fStringIndexLimit + 1; // incl. last NUL
519*0e209d39SAndroid Build Coastguard Worker printf("16-bit units for strings: %6d = %6d bytes\n",
520*0e209d39SAndroid Build Coastguard Worker (int)length, (int)length * 2);
521*0e209d39SAndroid Build Coastguard Worker }
522*0e209d39SAndroid Build Coastguard Worker }
523*0e209d39SAndroid Build Coastguard Worker
524*0e209d39SAndroid Build Coastguard Worker if(!options[FORMAT_VERSION].doesOccur && getFormatVersion() == 3 &&
525*0e209d39SAndroid Build Coastguard Worker poolBundle.fStrings == nullptr &&
526*0e209d39SAndroid Build Coastguard Worker !options[WRITE_POOL_BUNDLE].doesOccur) {
527*0e209d39SAndroid Build Coastguard Worker // If we just default to formatVersion 3
528*0e209d39SAndroid Build Coastguard Worker // but there are no pool bundle strings to share
529*0e209d39SAndroid Build Coastguard Worker // and we do not write a pool bundle,
530*0e209d39SAndroid Build Coastguard Worker // then write formatVersion 2 which is just as good.
531*0e209d39SAndroid Build Coastguard Worker setFormatVersion(2);
532*0e209d39SAndroid Build Coastguard Worker }
533*0e209d39SAndroid Build Coastguard Worker
534*0e209d39SAndroid Build Coastguard Worker if(options[INCLUDE_UNIHAN_COLL].doesOccur) {
535*0e209d39SAndroid Build Coastguard Worker puts("genrb option --includeUnihanColl ignored: \n"
536*0e209d39SAndroid Build Coastguard Worker "CLDR 26/ICU 54 unihan data is small, except\n"
537*0e209d39SAndroid Build Coastguard Worker "the ucadata-unihan.icu version of the collation root data\n"
538*0e209d39SAndroid Build Coastguard Worker "is about 300kB larger than the ucadata-implicithan.icu version.");
539*0e209d39SAndroid Build Coastguard Worker }
540*0e209d39SAndroid Build Coastguard Worker
541*0e209d39SAndroid Build Coastguard Worker if((argc-1)!=1) {
542*0e209d39SAndroid Build Coastguard Worker printf("genrb number of files: %d\n", argc - 1);
543*0e209d39SAndroid Build Coastguard Worker }
544*0e209d39SAndroid Build Coastguard Worker /* generate the binary files */
545*0e209d39SAndroid Build Coastguard Worker for(i = 1; i < argc; ++i) {
546*0e209d39SAndroid Build Coastguard Worker status = U_ZERO_ERROR;
547*0e209d39SAndroid Build Coastguard Worker arg = getLongPathname(argv[i]);
548*0e209d39SAndroid Build Coastguard Worker
549*0e209d39SAndroid Build Coastguard Worker CharString theCurrentFileName;
550*0e209d39SAndroid Build Coastguard Worker if (inputDir) {
551*0e209d39SAndroid Build Coastguard Worker theCurrentFileName.append(inputDir, status);
552*0e209d39SAndroid Build Coastguard Worker }
553*0e209d39SAndroid Build Coastguard Worker theCurrentFileName.appendPathPart(arg, status);
554*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) {
555*0e209d39SAndroid Build Coastguard Worker break;
556*0e209d39SAndroid Build Coastguard Worker }
557*0e209d39SAndroid Build Coastguard Worker
558*0e209d39SAndroid Build Coastguard Worker gCurrentFileName = theCurrentFileName.data();
559*0e209d39SAndroid Build Coastguard Worker if (isVerbose()) {
560*0e209d39SAndroid Build Coastguard Worker printf("Processing file \"%s\"\n", theCurrentFileName.data());
561*0e209d39SAndroid Build Coastguard Worker }
562*0e209d39SAndroid Build Coastguard Worker processFile(arg, encoding, inputDir, outputDir, filterDir, nullptr,
563*0e209d39SAndroid Build Coastguard Worker newPoolBundle.getAlias(),
564*0e209d39SAndroid Build Coastguard Worker options[NO_BINARY_COLLATION].doesOccur, status);
565*0e209d39SAndroid Build Coastguard Worker }
566*0e209d39SAndroid Build Coastguard Worker
567*0e209d39SAndroid Build Coastguard Worker poolBundle.close();
568*0e209d39SAndroid Build Coastguard Worker
569*0e209d39SAndroid Build Coastguard Worker if(U_SUCCESS(status) && options[WRITE_POOL_BUNDLE].doesOccur) {
570*0e209d39SAndroid Build Coastguard Worker const char* writePoolDir;
571*0e209d39SAndroid Build Coastguard Worker if (options[WRITE_POOL_BUNDLE].value!=nullptr) {
572*0e209d39SAndroid Build Coastguard Worker writePoolDir = options[WRITE_POOL_BUNDLE].value;
573*0e209d39SAndroid Build Coastguard Worker } else {
574*0e209d39SAndroid Build Coastguard Worker writePoolDir = outputDir;
575*0e209d39SAndroid Build Coastguard Worker }
576*0e209d39SAndroid Build Coastguard Worker char outputFileName[256];
577*0e209d39SAndroid Build Coastguard Worker newPoolBundle->write(writePoolDir, nullptr, outputFileName, sizeof(outputFileName), status);
578*0e209d39SAndroid Build Coastguard Worker if(U_FAILURE(status)) {
579*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "unable to write the pool bundle: %s\n", u_errorName(status));
580*0e209d39SAndroid Build Coastguard Worker }
581*0e209d39SAndroid Build Coastguard Worker }
582*0e209d39SAndroid Build Coastguard Worker
583*0e209d39SAndroid Build Coastguard Worker u_cleanup();
584*0e209d39SAndroid Build Coastguard Worker
585*0e209d39SAndroid Build Coastguard Worker /* Don't return warnings as a failure */
586*0e209d39SAndroid Build Coastguard Worker if (U_SUCCESS(status)) {
587*0e209d39SAndroid Build Coastguard Worker return 0;
588*0e209d39SAndroid Build Coastguard Worker }
589*0e209d39SAndroid Build Coastguard Worker
590*0e209d39SAndroid Build Coastguard Worker return status;
591*0e209d39SAndroid Build Coastguard Worker }
592*0e209d39SAndroid Build Coastguard Worker
593*0e209d39SAndroid Build Coastguard Worker /* Process a file */
594*0e209d39SAndroid Build Coastguard Worker void
processFile(const char * filename,const char * cp,const char * inputDir,const char * outputDir,const char * filterDir,const char * packageName,SRBRoot * newPoolBundle,UBool omitBinaryCollation,UErrorCode & status)595*0e209d39SAndroid Build Coastguard Worker processFile(const char *filename, const char *cp,
596*0e209d39SAndroid Build Coastguard Worker const char *inputDir, const char *outputDir, const char *filterDir,
597*0e209d39SAndroid Build Coastguard Worker const char *packageName,
598*0e209d39SAndroid Build Coastguard Worker SRBRoot *newPoolBundle,
599*0e209d39SAndroid Build Coastguard Worker UBool omitBinaryCollation, UErrorCode &status) {
600*0e209d39SAndroid Build Coastguard Worker LocalPointer<SRBRoot> data;
601*0e209d39SAndroid Build Coastguard Worker LocalUCHARBUFPointer ucbuf;
602*0e209d39SAndroid Build Coastguard Worker CharString openFileName;
603*0e209d39SAndroid Build Coastguard Worker CharString inputDirBuf;
604*0e209d39SAndroid Build Coastguard Worker
605*0e209d39SAndroid Build Coastguard Worker char outputFileName[256];
606*0e209d39SAndroid Build Coastguard Worker int32_t dirlen = 0;
607*0e209d39SAndroid Build Coastguard Worker
608*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) {
609*0e209d39SAndroid Build Coastguard Worker return;
610*0e209d39SAndroid Build Coastguard Worker }
611*0e209d39SAndroid Build Coastguard Worker if(filename==nullptr){
612*0e209d39SAndroid Build Coastguard Worker status=U_ILLEGAL_ARGUMENT_ERROR;
613*0e209d39SAndroid Build Coastguard Worker return;
614*0e209d39SAndroid Build Coastguard Worker }
615*0e209d39SAndroid Build Coastguard Worker
616*0e209d39SAndroid Build Coastguard Worker if(inputDir == nullptr) {
617*0e209d39SAndroid Build Coastguard Worker const char *filenameBegin = uprv_strrchr(filename, U_FILE_SEP_CHAR);
618*0e209d39SAndroid Build Coastguard Worker if (filenameBegin != nullptr) {
619*0e209d39SAndroid Build Coastguard Worker /*
620*0e209d39SAndroid Build Coastguard Worker * When a filename ../../../data/root.txt is specified,
621*0e209d39SAndroid Build Coastguard Worker * we presume that the input directory is ../../../data
622*0e209d39SAndroid Build Coastguard Worker * This is very important when the resource file includes
623*0e209d39SAndroid Build Coastguard Worker * another file, like UCARules.txt or thaidict.brk.
624*0e209d39SAndroid Build Coastguard Worker */
625*0e209d39SAndroid Build Coastguard Worker int32_t filenameSize = (int32_t)(filenameBegin - filename + 1);
626*0e209d39SAndroid Build Coastguard Worker inputDirBuf.append(filename, filenameSize, status);
627*0e209d39SAndroid Build Coastguard Worker
628*0e209d39SAndroid Build Coastguard Worker inputDir = inputDirBuf.data();
629*0e209d39SAndroid Build Coastguard Worker dirlen = inputDirBuf.length();
630*0e209d39SAndroid Build Coastguard Worker }
631*0e209d39SAndroid Build Coastguard Worker }else{
632*0e209d39SAndroid Build Coastguard Worker dirlen = (int32_t)uprv_strlen(inputDir);
633*0e209d39SAndroid Build Coastguard Worker
634*0e209d39SAndroid Build Coastguard Worker if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) {
635*0e209d39SAndroid Build Coastguard Worker /*
636*0e209d39SAndroid Build Coastguard Worker * append the input dir to openFileName if the first char in
637*0e209d39SAndroid Build Coastguard Worker * filename is not file separation char and the last char input directory is not '.'.
638*0e209d39SAndroid Build Coastguard Worker * This is to support :
639*0e209d39SAndroid Build Coastguard Worker * genrb -s. /home/icu/data
640*0e209d39SAndroid Build Coastguard Worker * genrb -s. icu/data
641*0e209d39SAndroid Build Coastguard Worker * The user cannot mix notations like
642*0e209d39SAndroid Build Coastguard Worker * genrb -s. /icu/data --- the absolute path specified. -s redundant
643*0e209d39SAndroid Build Coastguard Worker * user should use
644*0e209d39SAndroid Build Coastguard Worker * genrb -s. icu/data --- start from CWD and look in icu/data dir
645*0e209d39SAndroid Build Coastguard Worker */
646*0e209d39SAndroid Build Coastguard Worker if( (filename[0] != U_FILE_SEP_CHAR) && (inputDir[dirlen-1] !='.')){
647*0e209d39SAndroid Build Coastguard Worker openFileName.append(inputDir, status);
648*0e209d39SAndroid Build Coastguard Worker }
649*0e209d39SAndroid Build Coastguard Worker } else {
650*0e209d39SAndroid Build Coastguard Worker openFileName.append(inputDir, status);
651*0e209d39SAndroid Build Coastguard Worker }
652*0e209d39SAndroid Build Coastguard Worker }
653*0e209d39SAndroid Build Coastguard Worker openFileName.appendPathPart(filename, status);
654*0e209d39SAndroid Build Coastguard Worker
655*0e209d39SAndroid Build Coastguard Worker // Test for CharString failure
656*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) {
657*0e209d39SAndroid Build Coastguard Worker return;
658*0e209d39SAndroid Build Coastguard Worker }
659*0e209d39SAndroid Build Coastguard Worker
660*0e209d39SAndroid Build Coastguard Worker ucbuf.adoptInstead(ucbuf_open(openFileName.data(), &cp,getShowWarning(),true, &status));
661*0e209d39SAndroid Build Coastguard Worker if(status == U_FILE_ACCESS_ERROR) {
662*0e209d39SAndroid Build Coastguard Worker
663*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "couldn't open file %s\n", openFileName.data());
664*0e209d39SAndroid Build Coastguard Worker return;
665*0e209d39SAndroid Build Coastguard Worker }
666*0e209d39SAndroid Build Coastguard Worker if (ucbuf.isNull() || U_FAILURE(status)) {
667*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "An error occurred processing file %s. Error: %s\n",
668*0e209d39SAndroid Build Coastguard Worker openFileName.data(), u_errorName(status));
669*0e209d39SAndroid Build Coastguard Worker return;
670*0e209d39SAndroid Build Coastguard Worker }
671*0e209d39SAndroid Build Coastguard Worker /* auto detected popular encodings? */
672*0e209d39SAndroid Build Coastguard Worker if (cp!=nullptr && isVerbose()) {
673*0e209d39SAndroid Build Coastguard Worker printf("autodetected encoding %s\n", cp);
674*0e209d39SAndroid Build Coastguard Worker }
675*0e209d39SAndroid Build Coastguard Worker /* Parse the data into an SRBRoot */
676*0e209d39SAndroid Build Coastguard Worker data.adoptInstead(parse(ucbuf.getAlias(), inputDir, outputDir, filename,
677*0e209d39SAndroid Build Coastguard Worker !omitBinaryCollation, options[NO_COLLATION_RULES].doesOccur, options[ICU4X_MODE].doesOccur, &status));
678*0e209d39SAndroid Build Coastguard Worker
679*0e209d39SAndroid Build Coastguard Worker if (data.isNull() || U_FAILURE(status)) {
680*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "couldn't parse the file %s. Error:%s\n", filename, u_errorName(status));
681*0e209d39SAndroid Build Coastguard Worker return;
682*0e209d39SAndroid Build Coastguard Worker }
683*0e209d39SAndroid Build Coastguard Worker
684*0e209d39SAndroid Build Coastguard Worker // Run filtering before writing pool bundle
685*0e209d39SAndroid Build Coastguard Worker if (filterDir != nullptr) {
686*0e209d39SAndroid Build Coastguard Worker CharString filterFileName(filterDir, status);
687*0e209d39SAndroid Build Coastguard Worker filterFileName.appendPathPart(filename, status);
688*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) {
689*0e209d39SAndroid Build Coastguard Worker return;
690*0e209d39SAndroid Build Coastguard Worker }
691*0e209d39SAndroid Build Coastguard Worker
692*0e209d39SAndroid Build Coastguard Worker // Open the file and read it into filter
693*0e209d39SAndroid Build Coastguard Worker SimpleRuleBasedPathFilter filter;
694*0e209d39SAndroid Build Coastguard Worker std::ifstream f(filterFileName.data());
695*0e209d39SAndroid Build Coastguard Worker if (f.fail()) {
696*0e209d39SAndroid Build Coastguard Worker std::cerr << "genrb error: unable to open " << filterFileName.data() << std::endl;
697*0e209d39SAndroid Build Coastguard Worker status = U_FILE_ACCESS_ERROR;
698*0e209d39SAndroid Build Coastguard Worker return;
699*0e209d39SAndroid Build Coastguard Worker }
700*0e209d39SAndroid Build Coastguard Worker std::string currentLine;
701*0e209d39SAndroid Build Coastguard Worker while (std::getline(f, currentLine)) {
702*0e209d39SAndroid Build Coastguard Worker // Ignore # comments and empty lines
703*0e209d39SAndroid Build Coastguard Worker if (currentLine.empty() || currentLine[0] == '#') {
704*0e209d39SAndroid Build Coastguard Worker continue;
705*0e209d39SAndroid Build Coastguard Worker }
706*0e209d39SAndroid Build Coastguard Worker filter.addRule(currentLine, status);
707*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) {
708*0e209d39SAndroid Build Coastguard Worker return;
709*0e209d39SAndroid Build Coastguard Worker }
710*0e209d39SAndroid Build Coastguard Worker }
711*0e209d39SAndroid Build Coastguard Worker
712*0e209d39SAndroid Build Coastguard Worker if (isVerbose()) {
713*0e209d39SAndroid Build Coastguard Worker filter.print(std::cout);
714*0e209d39SAndroid Build Coastguard Worker }
715*0e209d39SAndroid Build Coastguard Worker
716*0e209d39SAndroid Build Coastguard Worker // Apply the filter to the data
717*0e209d39SAndroid Build Coastguard Worker ResKeyPath path;
718*0e209d39SAndroid Build Coastguard Worker data->fRoot->applyFilter(filter, path, data.getAlias());
719*0e209d39SAndroid Build Coastguard Worker }
720*0e209d39SAndroid Build Coastguard Worker
721*0e209d39SAndroid Build Coastguard Worker if(options[WRITE_POOL_BUNDLE].doesOccur) {
722*0e209d39SAndroid Build Coastguard Worker data->fWritePoolBundle = newPoolBundle;
723*0e209d39SAndroid Build Coastguard Worker data->compactKeys(status);
724*0e209d39SAndroid Build Coastguard Worker int32_t newKeysLength;
725*0e209d39SAndroid Build Coastguard Worker const char *newKeys = data->getKeyBytes(&newKeysLength);
726*0e209d39SAndroid Build Coastguard Worker newPoolBundle->addKeyBytes(newKeys, newKeysLength, status);
727*0e209d39SAndroid Build Coastguard Worker if(U_FAILURE(status)) {
728*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "bundle_compactKeys(%s) or bundle_getKeyBytes() failed: %s\n",
729*0e209d39SAndroid Build Coastguard Worker filename, u_errorName(status));
730*0e209d39SAndroid Build Coastguard Worker return;
731*0e209d39SAndroid Build Coastguard Worker }
732*0e209d39SAndroid Build Coastguard Worker /* count the number of just-added key strings */
733*0e209d39SAndroid Build Coastguard Worker for(const char *newKeysLimit = newKeys + newKeysLength; newKeys < newKeysLimit; ++newKeys) {
734*0e209d39SAndroid Build Coastguard Worker if(*newKeys == 0) {
735*0e209d39SAndroid Build Coastguard Worker ++newPoolBundle->fKeysCount;
736*0e209d39SAndroid Build Coastguard Worker }
737*0e209d39SAndroid Build Coastguard Worker }
738*0e209d39SAndroid Build Coastguard Worker }
739*0e209d39SAndroid Build Coastguard Worker
740*0e209d39SAndroid Build Coastguard Worker if(options[USE_POOL_BUNDLE].doesOccur) {
741*0e209d39SAndroid Build Coastguard Worker data->fUsePoolBundle = &poolBundle;
742*0e209d39SAndroid Build Coastguard Worker }
743*0e209d39SAndroid Build Coastguard Worker
744*0e209d39SAndroid Build Coastguard Worker /* Determine the target rb filename */
745*0e209d39SAndroid Build Coastguard Worker uprv_free(make_res_filename(filename, outputDir, packageName, status));
746*0e209d39SAndroid Build Coastguard Worker if(U_FAILURE(status)) {
747*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "couldn't make the res fileName for bundle %s. Error:%s\n",
748*0e209d39SAndroid Build Coastguard Worker filename, u_errorName(status));
749*0e209d39SAndroid Build Coastguard Worker return;
750*0e209d39SAndroid Build Coastguard Worker }
751*0e209d39SAndroid Build Coastguard Worker if(write_java== true){
752*0e209d39SAndroid Build Coastguard Worker bundle_write_java(data.getAlias(), outputDir, outputEnc,
753*0e209d39SAndroid Build Coastguard Worker outputFileName, sizeof(outputFileName),
754*0e209d39SAndroid Build Coastguard Worker options[JAVA_PACKAGE].value, options[BUNDLE_NAME].value, &status);
755*0e209d39SAndroid Build Coastguard Worker }else if(write_xliff ==true){
756*0e209d39SAndroid Build Coastguard Worker bundle_write_xml(data.getAlias(), outputDir, outputEnc,
757*0e209d39SAndroid Build Coastguard Worker filename, outputFileName, sizeof(outputFileName),
758*0e209d39SAndroid Build Coastguard Worker language, xliffOutputFileName, &status);
759*0e209d39SAndroid Build Coastguard Worker }else{
760*0e209d39SAndroid Build Coastguard Worker /* Write the data to the file */
761*0e209d39SAndroid Build Coastguard Worker data->write(outputDir, packageName, outputFileName, sizeof(outputFileName), status);
762*0e209d39SAndroid Build Coastguard Worker }
763*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) {
764*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, "couldn't write bundle %s. Error:%s\n", outputFileName, u_errorName(status));
765*0e209d39SAndroid Build Coastguard Worker }
766*0e209d39SAndroid Build Coastguard Worker }
767*0e209d39SAndroid Build Coastguard Worker
768*0e209d39SAndroid Build Coastguard Worker /* Generate the target .res file name from the input file name */
769*0e209d39SAndroid Build Coastguard Worker static char*
make_res_filename(const char * filename,const char * outputDir,const char * packageName,UErrorCode & status)770*0e209d39SAndroid Build Coastguard Worker make_res_filename(const char *filename,
771*0e209d39SAndroid Build Coastguard Worker const char *outputDir,
772*0e209d39SAndroid Build Coastguard Worker const char *packageName,
773*0e209d39SAndroid Build Coastguard Worker UErrorCode &status) {
774*0e209d39SAndroid Build Coastguard Worker char *basename;
775*0e209d39SAndroid Build Coastguard Worker char *dirname;
776*0e209d39SAndroid Build Coastguard Worker char *resName;
777*0e209d39SAndroid Build Coastguard Worker
778*0e209d39SAndroid Build Coastguard Worker int32_t pkgLen = 0; /* length of package prefix */
779*0e209d39SAndroid Build Coastguard Worker
780*0e209d39SAndroid Build Coastguard Worker
781*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) {
782*0e209d39SAndroid Build Coastguard Worker return nullptr;
783*0e209d39SAndroid Build Coastguard Worker }
784*0e209d39SAndroid Build Coastguard Worker
785*0e209d39SAndroid Build Coastguard Worker if(packageName != nullptr)
786*0e209d39SAndroid Build Coastguard Worker {
787*0e209d39SAndroid Build Coastguard Worker pkgLen = (int32_t)(1 + uprv_strlen(packageName));
788*0e209d39SAndroid Build Coastguard Worker }
789*0e209d39SAndroid Build Coastguard Worker
790*0e209d39SAndroid Build Coastguard Worker /* setup */
791*0e209d39SAndroid Build Coastguard Worker basename = dirname = resName = nullptr;
792*0e209d39SAndroid Build Coastguard Worker
793*0e209d39SAndroid Build Coastguard Worker /* determine basename, and compiled file names */
794*0e209d39SAndroid Build Coastguard Worker basename = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1));
795*0e209d39SAndroid Build Coastguard Worker if (basename == nullptr) {
796*0e209d39SAndroid Build Coastguard Worker status = U_MEMORY_ALLOCATION_ERROR;
797*0e209d39SAndroid Build Coastguard Worker goto finish;
798*0e209d39SAndroid Build Coastguard Worker }
799*0e209d39SAndroid Build Coastguard Worker
800*0e209d39SAndroid Build Coastguard Worker get_basename(basename, filename);
801*0e209d39SAndroid Build Coastguard Worker
802*0e209d39SAndroid Build Coastguard Worker dirname = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1));
803*0e209d39SAndroid Build Coastguard Worker if (dirname == nullptr) {
804*0e209d39SAndroid Build Coastguard Worker status = U_MEMORY_ALLOCATION_ERROR;
805*0e209d39SAndroid Build Coastguard Worker goto finish;
806*0e209d39SAndroid Build Coastguard Worker }
807*0e209d39SAndroid Build Coastguard Worker
808*0e209d39SAndroid Build Coastguard Worker get_dirname(dirname, filename);
809*0e209d39SAndroid Build Coastguard Worker
810*0e209d39SAndroid Build Coastguard Worker if (outputDir == nullptr) {
811*0e209d39SAndroid Build Coastguard Worker /* output in same dir as .txt */
812*0e209d39SAndroid Build Coastguard Worker resName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(dirname)
813*0e209d39SAndroid Build Coastguard Worker + pkgLen
814*0e209d39SAndroid Build Coastguard Worker + uprv_strlen(basename)
815*0e209d39SAndroid Build Coastguard Worker + uprv_strlen(RES_SUFFIX) + 8));
816*0e209d39SAndroid Build Coastguard Worker if (resName == nullptr) {
817*0e209d39SAndroid Build Coastguard Worker status = U_MEMORY_ALLOCATION_ERROR;
818*0e209d39SAndroid Build Coastguard Worker goto finish;
819*0e209d39SAndroid Build Coastguard Worker }
820*0e209d39SAndroid Build Coastguard Worker
821*0e209d39SAndroid Build Coastguard Worker uprv_strcpy(resName, dirname);
822*0e209d39SAndroid Build Coastguard Worker
823*0e209d39SAndroid Build Coastguard Worker if(packageName != nullptr)
824*0e209d39SAndroid Build Coastguard Worker {
825*0e209d39SAndroid Build Coastguard Worker uprv_strcat(resName, packageName);
826*0e209d39SAndroid Build Coastguard Worker uprv_strcat(resName, "_");
827*0e209d39SAndroid Build Coastguard Worker }
828*0e209d39SAndroid Build Coastguard Worker
829*0e209d39SAndroid Build Coastguard Worker uprv_strcat(resName, basename);
830*0e209d39SAndroid Build Coastguard Worker
831*0e209d39SAndroid Build Coastguard Worker } else {
832*0e209d39SAndroid Build Coastguard Worker int32_t dirlen = (int32_t)uprv_strlen(outputDir);
833*0e209d39SAndroid Build Coastguard Worker int32_t basenamelen = (int32_t)uprv_strlen(basename);
834*0e209d39SAndroid Build Coastguard Worker
835*0e209d39SAndroid Build Coastguard Worker resName = (char*) uprv_malloc(sizeof(char) * (dirlen + pkgLen + basenamelen + 8));
836*0e209d39SAndroid Build Coastguard Worker
837*0e209d39SAndroid Build Coastguard Worker if (resName == nullptr) {
838*0e209d39SAndroid Build Coastguard Worker status = U_MEMORY_ALLOCATION_ERROR;
839*0e209d39SAndroid Build Coastguard Worker goto finish;
840*0e209d39SAndroid Build Coastguard Worker }
841*0e209d39SAndroid Build Coastguard Worker
842*0e209d39SAndroid Build Coastguard Worker uprv_strcpy(resName, outputDir);
843*0e209d39SAndroid Build Coastguard Worker
844*0e209d39SAndroid Build Coastguard Worker if(outputDir[dirlen] != U_FILE_SEP_CHAR) {
845*0e209d39SAndroid Build Coastguard Worker resName[dirlen] = U_FILE_SEP_CHAR;
846*0e209d39SAndroid Build Coastguard Worker resName[dirlen + 1] = '\0';
847*0e209d39SAndroid Build Coastguard Worker }
848*0e209d39SAndroid Build Coastguard Worker
849*0e209d39SAndroid Build Coastguard Worker if(packageName != nullptr)
850*0e209d39SAndroid Build Coastguard Worker {
851*0e209d39SAndroid Build Coastguard Worker uprv_strcat(resName, packageName);
852*0e209d39SAndroid Build Coastguard Worker uprv_strcat(resName, "_");
853*0e209d39SAndroid Build Coastguard Worker }
854*0e209d39SAndroid Build Coastguard Worker
855*0e209d39SAndroid Build Coastguard Worker uprv_strcat(resName, basename);
856*0e209d39SAndroid Build Coastguard Worker }
857*0e209d39SAndroid Build Coastguard Worker
858*0e209d39SAndroid Build Coastguard Worker finish:
859*0e209d39SAndroid Build Coastguard Worker uprv_free(basename);
860*0e209d39SAndroid Build Coastguard Worker uprv_free(dirname);
861*0e209d39SAndroid Build Coastguard Worker
862*0e209d39SAndroid Build Coastguard Worker return resName;
863*0e209d39SAndroid Build Coastguard Worker }
864*0e209d39SAndroid Build Coastguard Worker
865*0e209d39SAndroid Build Coastguard Worker /*
866*0e209d39SAndroid Build Coastguard Worker * Local Variables:
867*0e209d39SAndroid Build Coastguard Worker * indent-tabs-mode: nil
868*0e209d39SAndroid Build Coastguard Worker * End:
869*0e209d39SAndroid Build Coastguard Worker */
870