Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: source/tools/genrb/genrb.cpp

Issue 1621843002: ICU 56 update step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@561
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/tools/genrb/genrb.c ('k') | source/tools/genrb/genrb.vcxproj » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ******************************************************************************* 2 *******************************************************************************
3 * 3 *
4 * Copyright (C) 1998-2014, International Business Machines 4 * Copyright (C) 1998-2015, International Business Machines
5 * Corporation and others. All Rights Reserved. 5 * Corporation and others. All Rights Reserved.
6 * 6 *
7 ******************************************************************************* 7 *******************************************************************************
8 * 8 *
9 * File genrb.c 9 * File genrb.cpp
10 * 10 *
11 * Modification History: 11 * Modification History:
12 * 12 *
13 * Date Name Description 13 * Date Name Description
14 * 05/25/99 stephen Creation. 14 * 05/25/99 stephen Creation.
15 * 5/10/01 Ram removed ustdio dependency 15 * 5/10/01 Ram removed ustdio dependency
16 ******************************************************************************* 16 *******************************************************************************
17 */ 17 */
18 18
19 #include <assert.h>
19 #include "genrb.h" 20 #include "genrb.h"
21 #include "unicode/localpointer.h"
20 #include "unicode/uclean.h" 22 #include "unicode/uclean.h"
23 #include "unicode/utf16.h"
24 #include "charstr.h"
25 #include "reslist.h"
26 #include "ucmndata.h" /* TODO: for reading the pool bundle */
21 27
22 #include "ucmndata.h" /* TODO: for reading the pool bundle */ 28 U_NAMESPACE_USE
23 29
24 /* Protos */ 30 /* Protos */
25 void processFile(const char *filename, const char* cp, const char *inputDir, co nst char *outputDir, 31 void processFile(const char *filename, const char* cp, const char *inputDir, co nst char *outputDir,
26 const char *packageName, UBool omitBinaryCollation, UErrorCode *status); 32 const char *packageName,
33 SRBRoot *newPoolBundle, UBool omitBinaryCollation, UErrorCode &status);
27 static char *make_res_filename(const char *filename, const char *outputDir, 34 static char *make_res_filename(const char *filename, const char *outputDir,
28 const char *packageName, UErrorCode *status); 35 const char *packageName, UErrorCode &status);
29 36
30 /* File suffixes */ 37 /* File suffixes */
31 #define RES_SUFFIX ".res" 38 #define RES_SUFFIX ".res"
32 #define COL_SUFFIX ".col" 39 #define COL_SUFFIX ".col"
33 40
34 static char theCurrentFileName[2048]; 41 const char *gCurrentFileName = NULL;
35 const char *gCurrentFileName = theCurrentFileName;
36 #ifdef XP_MAC_CONSOLE 42 #ifdef XP_MAC_CONSOLE
37 #include <console.h> 43 #include <console.h>
38 #endif 44 #endif
39 45
46 void ResFile::close() {
47 delete[] fBytes;
48 fBytes = NULL;
49 delete fStrings;
50 fStrings = NULL;
51 }
52
40 enum 53 enum
41 { 54 {
42 HELP1, 55 HELP1,
43 HELP2, 56 HELP2,
44 VERBOSE, 57 VERBOSE,
45 QUIET, 58 QUIET,
46 VERSION, 59 VERSION,
47 SOURCEDIR, 60 SOURCEDIR,
48 DESTDIR, 61 DESTDIR,
49 ENCODING, 62 ENCODING,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 UOPTION_DEF("omitCollationRules", 'R', UOPT_NO_ARG),/* 17 */ 97 UOPTION_DEF("omitCollationRules", 'R', UOPT_NO_ARG),/* 17 */
85 UOPTION_DEF("formatVersion", '\x01', UOPT_REQUIRES_ARG),/* 18 */ 98 UOPTION_DEF("formatVersion", '\x01', UOPT_REQUIRES_ARG),/* 18 */
86 UOPTION_DEF("writePoolBundle", '\x01', UOPT_NO_ARG),/* 19 */ 99 UOPTION_DEF("writePoolBundle", '\x01', UOPT_NO_ARG),/* 19 */
87 UOPTION_DEF("usePoolBundle", '\x01', UOPT_OPTIONAL_ARG),/* 20 */ 100 UOPTION_DEF("usePoolBundle", '\x01', UOPT_OPTIONAL_ARG),/* 20 */
88 UOPTION_DEF("includeUnihanColl", '\x01', UOPT_NO_ARG),/* 2 1 */ /* temporary, don't display in usage info */ 101 UOPTION_DEF("includeUnihanColl", '\x01', UOPT_NO_ARG),/* 2 1 */ /* temporary, don't display in usage info */
89 }; 102 };
90 103
91 static UBool write_java = FALSE; 104 static UBool write_java = FALSE;
92 static UBool write_xliff = FALSE; 105 static UBool write_xliff = FALSE;
93 static const char* outputEnc =""; 106 static const char* outputEnc ="";
94 static struct SRBRoot *newPoolBundle = NULL;
95 107
96 /* TODO: separate header file for ResFile? */ 108 static ResFile poolBundle;
97 typedef struct ResFile {
98 uint8_t *fBytes;
99 const int32_t *fIndexes;
100 const char *fKeys;
101 int32_t fKeysLength;
102 int32_t fKeysCount;
103 int32_t fChecksum;
104 } ResFile;
105
106 static ResFile poolBundle = { NULL };
107 109
108 /*added by Jing*/ 110 /*added by Jing*/
109 static const char* language = NULL; 111 static const char* language = NULL;
110 static const char* xliffOutputFileName = NULL; 112 static const char* xliffOutputFileName = NULL;
111 int 113 int
112 main(int argc, 114 main(int argc,
113 char* argv[]) 115 char* argv[])
114 { 116 {
115 UErrorCode status = U_ZERO_ERROR; 117 UErrorCode status = U_ZERO_ERROR;
116 const char *arg = NULL; 118 const char *arg = NULL;
117 const char *outputDir = NULL; /* NULL = no output directory, use current */ 119 const char *outputDir = NULL; /* NULL = no output directory, use current */
118 const char *inputDir = NULL; 120 const char *inputDir = NULL;
119 const char *encoding = ""; 121 const char *encoding = "";
120 int i; 122 int i;
121 UBool illegalArg = FALSE; 123 UBool illegalArg = FALSE;
122 124
123 U_MAIN_INIT_ARGS(argc, argv); 125 U_MAIN_INIT_ARGS(argc, argv);
124 126
125 options[JAVA_PACKAGE].value = "com.ibm.icu.impl.data"; 127 options[JAVA_PACKAGE].value = "com.ibm.icu.impl.data";
126 options[BUNDLE_NAME].value = "LocaleElements"; 128 options[BUNDLE_NAME].value = "LocaleElements";
127 argc = u_parseArgs(argc, argv, (int32_t)(sizeof(options)/sizeof(options[0])) , options); 129 argc = u_parseArgs(argc, argv, (int32_t)(sizeof(options)/sizeof(options[0])) , options);
128 130
129 /* error handling, printing usage message */ 131 /* error handling, printing usage message */
130 if(argc<0) { 132 if(argc<0) {
131 fprintf(stderr, "%s: error in command line argument \"%s\"\n", argv[0], argv[-argc]); 133 fprintf(stderr, "%s: error in command line argument \"%s\"\n", argv[0], argv[-argc]);
134 illegalArg = TRUE;
132 } else if(argc<2) { 135 } else if(argc<2) {
133 argc = -1; 136 illegalArg = TRUE;
134 } 137 }
135 if(options[WRITE_POOL_BUNDLE].doesOccur && options[USE_POOL_BUNDLE].doesOccu r) { 138 if(options[WRITE_POOL_BUNDLE].doesOccur && options[USE_POOL_BUNDLE].doesOccu r) {
136 fprintf(stderr, "%s: cannot combine --writePoolBundle and --usePoolBundl e\n", argv[0]); 139 fprintf(stderr, "%s: cannot combine --writePoolBundle and --usePoolBundl e\n", argv[0]);
137 argc = -1; 140 illegalArg = TRUE;
138 } 141 }
139 if(options[FORMAT_VERSION].doesOccur) { 142 if(options[FORMAT_VERSION].doesOccur) {
140 const char *s = options[FORMAT_VERSION].value; 143 const char *s = options[FORMAT_VERSION].value;
141 if(uprv_strlen(s) != 1 || (s[0] != '1' && s[0] != '2')) { 144 if(uprv_strlen(s) != 1 || (s[0] < '1' && '3' < s[0])) {
142 fprintf(stderr, "%s: unsupported --formatVersion %s\n", argv[0], s); 145 fprintf(stderr, "%s: unsupported --formatVersion %s\n", argv[0], s);
143 argc = -1; 146 illegalArg = TRUE;
144 } else if(s[0] == '1' && 147 } else if(s[0] == '1' &&
145 (options[WRITE_POOL_BUNDLE].doesOccur || options[USE_POOL_BUND LE].doesOccur) 148 (options[WRITE_POOL_BUNDLE].doesOccur || options[USE_POOL_BUND LE].doesOccur)
146 ) { 149 ) {
147 fprintf(stderr, "%s: cannot combine --formatVersion 1 with --writePo olBundle or --usePoolBundle\n", argv[0]); 150 fprintf(stderr, "%s: cannot combine --formatVersion 1 with --writePo olBundle or --usePoolBundle\n", argv[0]);
148 argc = -1; 151 illegalArg = TRUE;
149 } else { 152 } else {
150 setFormatVersion(s[0] - '0'); 153 setFormatVersion(s[0] - '0');
151 } 154 }
152 } 155 }
153 156
154 if(options[VERSION].doesOccur) { 157 if((options[JAVA_PACKAGE].doesOccur || options[BUNDLE_NAME].doesOccur) &&
155 fprintf(stderr, 158 !options[WRITE_JAVA].doesOccur) {
156 "%s version %s (ICU version %s).\n"
157 "%s\n",
158 argv[0], GENRB_VERSION, U_ICU_VERSION, U_COPYRIGHT_STRING);
159 return U_ZERO_ERROR;
160 }
161
162 if(argc<0) {
163 illegalArg = TRUE;
164 } else if((options[JAVA_PACKAGE].doesOccur || options[BUNDLE_NAME].doesOccur ) &&
165 !options[WRITE_JAVA].doesOccur) {
166 fprintf(stderr, 159 fprintf(stderr,
167 "%s error: command line argument --java-package or --bundle-name " 160 "%s error: command line argument --java-package or --bundle-name "
168 "without --write-java\n", 161 "without --write-java\n",
169 argv[0]); 162 argv[0]);
170 illegalArg = TRUE; 163 illegalArg = TRUE;
171 } 164 }
172 165
166 if(options[VERSION].doesOccur) {
167 fprintf(stderr,
168 "%s version %s (ICU version %s).\n"
169 "%s\n",
170 argv[0], GENRB_VERSION, U_ICU_VERSION, U_COPYRIGHT_STRING);
171 if(!illegalArg) {
172 return U_ZERO_ERROR;
173 }
174 }
175
173 if(illegalArg || options[HELP1].doesOccur || options[HELP2].doesOccur) { 176 if(illegalArg || options[HELP1].doesOccur || options[HELP2].doesOccur) {
174 /* 177 /*
175 * Broken into chunks because the C89 standard says the minimum 178 * Broken into chunks because the C89 standard says the minimum
176 * required supported string length is 509 bytes. 179 * required supported string length is 509 bytes.
177 */ 180 */
178 fprintf(stderr, 181 fprintf(stderr,
179 "Usage: %s [OPTIONS] [FILES]\n" 182 "Usage: %s [OPTIONS] [FILES]\n"
180 "\tReads the list of resource bundle source files and creates\n" 183 "\tReads the list of resource bundle source files and creates\n"
181 "\tbinary version of resource bundles (.res files)\n", 184 "\tbinary version of resource bundles (.res files)\n",
182 argv[0]); 185 argv[0]);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 282 }
280 } 283 }
281 284
282 initParser(); 285 initParser();
283 286
284 /*added by Jing*/ 287 /*added by Jing*/
285 if(options[LANGUAGE].doesOccur) { 288 if(options[LANGUAGE].doesOccur) {
286 language = options[LANGUAGE].value; 289 language = options[LANGUAGE].value;
287 } 290 }
288 291
292 LocalPointer<SRBRoot> newPoolBundle;
289 if(options[WRITE_POOL_BUNDLE].doesOccur) { 293 if(options[WRITE_POOL_BUNDLE].doesOccur) {
290 newPoolBundle = bundle_open(NULL, TRUE, &status); 294 newPoolBundle.adoptInsteadAndCheckErrorCode(new SRBRoot(NULL, TRUE, stat us), status);
291 if(U_FAILURE(status)) { 295 if(U_FAILURE(status)) {
292 fprintf(stderr, "unable to create an empty bundle for the pool keys: %s\n", u_errorName(status)); 296 fprintf(stderr, "unable to create an empty bundle for the pool keys: %s\n", u_errorName(status));
293 return status; 297 return status;
294 } else { 298 } else {
295 const char *poolResName = "pool.res"; 299 const char *poolResName = "pool.res";
296 char *nameWithoutSuffix = uprv_malloc(uprv_strlen(poolResName) + 1); 300 char *nameWithoutSuffix = static_cast<char *>(uprv_malloc(uprv_strle n(poolResName) + 1));
297 if (nameWithoutSuffix == NULL) { 301 if (nameWithoutSuffix == NULL) {
298 fprintf(stderr, "out of memory error\n"); 302 fprintf(stderr, "out of memory error\n");
299 return U_MEMORY_ALLOCATION_ERROR; 303 return U_MEMORY_ALLOCATION_ERROR;
300 } 304 }
301 uprv_strcpy(nameWithoutSuffix, poolResName); 305 uprv_strcpy(nameWithoutSuffix, poolResName);
302 *uprv_strrchr(nameWithoutSuffix, '.') = 0; 306 *uprv_strrchr(nameWithoutSuffix, '.') = 0;
303 newPoolBundle->fLocale = nameWithoutSuffix; 307 newPoolBundle->fLocale = nameWithoutSuffix;
304 } 308 }
305 } 309 }
306 310
307 if(options[USE_POOL_BUNDLE].doesOccur) { 311 if(options[USE_POOL_BUNDLE].doesOccur) {
308 const char *poolResName = "pool.res"; 312 const char *poolResName = "pool.res";
309 FileStream *poolFile; 313 FileStream *poolFile;
310 int32_t poolFileSize; 314 int32_t poolFileSize;
311 int32_t indexLength; 315 int32_t indexLength;
312 /* 316 /*
313 * TODO: Consolidate inputDir/filename handling from main() and processF ile() 317 * TODO: Consolidate inputDir/filename handling from main() and processF ile()
314 * into a common function, and use it here as well. 318 * into a common function, and use it here as well.
315 * Try to create toolutil functions for dealing with dir/filenames and 319 * Try to create toolutil functions for dealing with dir/filenames and
316 * loading ICU data files without udata_open(). 320 * loading ICU data files without udata_open().
317 * Share code with icupkg? 321 * Share code with icupkg?
318 * Also, make_res_filename() seems to be unused. Review and remove. 322 * Also, make_res_filename() seems to be unused. Review and remove.
319 */ 323 */
324 CharString poolFileName;
320 if (options[USE_POOL_BUNDLE].value!=NULL) { 325 if (options[USE_POOL_BUNDLE].value!=NULL) {
321 uprv_strcpy(theCurrentFileName, options[USE_POOL_BUNDLE].value); 326 poolFileName.append(options[USE_POOL_BUNDLE].value, status);
322 uprv_strcat(theCurrentFileName, U_FILE_SEP_STRING);
323 } else if (inputDir) { 327 } else if (inputDir) {
324 uprv_strcpy(theCurrentFileName, inputDir); 328 poolFileName.append(inputDir, status);
325 uprv_strcat(theCurrentFileName, U_FILE_SEP_STRING);
326 } else {
327 *theCurrentFileName = 0;
328 } 329 }
329 uprv_strcat(theCurrentFileName, poolResName); 330 poolFileName.appendPathPart(poolResName, status);
330 poolFile = T_FileStream_open(theCurrentFileName, "rb"); 331 if (U_FAILURE(status)) {
332 return status;
333 }
334 poolFile = T_FileStream_open(poolFileName.data(), "rb");
331 if (poolFile == NULL) { 335 if (poolFile == NULL) {
332 fprintf(stderr, "unable to open pool bundle file %s\n", theCurrentFi leName); 336 fprintf(stderr, "unable to open pool bundle file %s\n", poolFileName .data());
333 return 1; 337 return 1;
334 } 338 }
335 poolFileSize = T_FileStream_size(poolFile); 339 poolFileSize = T_FileStream_size(poolFile);
336 if (poolFileSize < 32) { 340 if (poolFileSize < 32) {
337 fprintf(stderr, "the pool bundle file %s is too small\n", theCurrent FileName); 341 fprintf(stderr, "the pool bundle file %s is too small\n", poolFileNa me.data());
338 return 1; 342 return 1;
339 } 343 }
340 poolBundle.fBytes = (uint8_t *)uprv_malloc((poolFileSize + 15) & ~15); 344 poolBundle.fBytes = new uint8_t[(poolFileSize + 15) & ~15];
341 if (poolFileSize > 0 && poolBundle.fBytes == NULL) { 345 if (poolFileSize > 0 && poolBundle.fBytes == NULL) {
342 fprintf(stderr, "unable to allocate memory for the pool bundle file %s\n", theCurrentFileName); 346 fprintf(stderr, "unable to allocate memory for the pool bundle file %s\n", poolFileName.data());
343 return U_MEMORY_ALLOCATION_ERROR; 347 return U_MEMORY_ALLOCATION_ERROR;
344 } else {
345 UDataSwapper *ds;
346 const DataHeader *header;
347 int32_t bytesRead = T_FileStream_read(poolFile, poolBundle.fBytes, p oolFileSize);
348 int32_t keysBottom;
349 if (bytesRead != poolFileSize) {
350 fprintf(stderr, "unable to read the pool bundle file %s\n", theC urrentFileName);
351 return 1;
352 }
353 /*
354 * Swap the pool bundle so that a single checked-in file can be used .
355 * The swapper functions also test that the data looks like
356 * a well-formed .res file.
357 */
358 ds = udata_openSwapperForInputData(poolBundle.fBytes, bytesRead,
359 U_IS_BIG_ENDIAN, U_CHARSET_FAMILY , &status);
360 if (U_FAILURE(status)) {
361 fprintf(stderr, "udata_openSwapperForInputData(pool bundle %s) f ailed: %s\n",
362 theCurrentFileName, u_errorName(status));
363 return status;
364 }
365 ures_swap(ds, poolBundle.fBytes, bytesRead, poolBundle.fBytes, &stat us);
366 udata_closeSwapper(ds);
367 if (U_FAILURE(status)) {
368 fprintf(stderr, "ures_swap(pool bundle %s) failed: %s\n",
369 theCurrentFileName, u_errorName(status));
370 return status;
371 }
372 header = (const DataHeader *)poolBundle.fBytes;
373 if (header->info.formatVersion[0]!=2) {
374 fprintf(stderr, "invalid format of pool bundle file %s\n", theCu rrentFileName);
375 return U_INVALID_FORMAT_ERROR;
376 }
377 poolBundle.fKeys = (const char *)header + header->dataHeader.headerS ize;
378 poolBundle.fIndexes = (const int32_t *)poolBundle.fKeys + 1;
379 indexLength = poolBundle.fIndexes[URES_INDEX_LENGTH] & 0xff;
380 if (indexLength <= URES_INDEX_POOL_CHECKSUM) {
381 fprintf(stderr, "insufficient indexes[] in pool bundle file %s\n ", theCurrentFileName);
382 return U_INVALID_FORMAT_ERROR;
383 }
384 keysBottom = (1 + indexLength) * 4;
385 poolBundle.fKeys += keysBottom;
386 poolBundle.fKeysLength = (poolBundle.fIndexes[URES_INDEX_KEYS_TOP] * 4) - keysBottom;
387 poolBundle.fChecksum = poolBundle.fIndexes[URES_INDEX_POOL_CHECKSUM] ;
388 } 348 }
349
350 UDataSwapper *ds;
351 const DataHeader *header;
352 int32_t bytesRead = T_FileStream_read(poolFile, poolBundle.fBytes, poolF ileSize);
353 if (bytesRead != poolFileSize) {
354 fprintf(stderr, "unable to read the pool bundle file %s\n", poolFile Name.data());
355 return 1;
356 }
357 /*
358 * Swap the pool bundle so that a single checked-in file can be used.
359 * The swapper functions also test that the data looks like
360 * a well-formed .res file.
361 */
362 ds = udata_openSwapperForInputData(poolBundle.fBytes, bytesRead,
363 U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &s tatus);
364 if (U_FAILURE(status)) {
365 fprintf(stderr, "udata_openSwapperForInputData(pool bundle %s) faile d: %s\n",
366 poolFileName.data(), u_errorName(status));
367 return status;
368 }
369 ures_swap(ds, poolBundle.fBytes, bytesRead, poolBundle.fBytes, &status);
370 udata_closeSwapper(ds);
371 if (U_FAILURE(status)) {
372 fprintf(stderr, "ures_swap(pool bundle %s) failed: %s\n",
373 poolFileName.data(), u_errorName(status));
374 return status;
375 }
376 header = (const DataHeader *)poolBundle.fBytes;
377 if (header->info.formatVersion[0] < 2) {
378 fprintf(stderr, "invalid format of pool bundle file %s\n", poolFileN ame.data());
379 return U_INVALID_FORMAT_ERROR;
380 }
381 const int32_t *pRoot = (const int32_t *)(
382 (const char *)header + header->dataHeader.headerSize);
383 poolBundle.fIndexes = pRoot + 1;
384 indexLength = poolBundle.fIndexes[URES_INDEX_LENGTH] & 0xff;
385 if (indexLength <= URES_INDEX_POOL_CHECKSUM) {
386 fprintf(stderr, "insufficient indexes[] in pool bundle file %s\n", p oolFileName.data());
387 return U_INVALID_FORMAT_ERROR;
388 }
389 int32_t keysBottom = 1 + indexLength;
390 int32_t keysTop = poolBundle.fIndexes[URES_INDEX_KEYS_TOP];
391 poolBundle.fKeys = (const char *)(pRoot + keysBottom);
392 poolBundle.fKeysLength = (keysTop - keysBottom) * 4;
393 poolBundle.fChecksum = poolBundle.fIndexes[URES_INDEX_POOL_CHECKSUM];
394
389 for (i = 0; i < poolBundle.fKeysLength; ++i) { 395 for (i = 0; i < poolBundle.fKeysLength; ++i) {
390 if (poolBundle.fKeys[i] == 0) { 396 if (poolBundle.fKeys[i] == 0) {
391 ++poolBundle.fKeysCount; 397 ++poolBundle.fKeysCount;
392 } 398 }
393 } 399 }
400
401 // 16BitUnits[] begins with strings-v2.
402 // The strings-v2 may optionally be terminated by what looks like
403 // an explicit string length that exceeds the number of remaining 16-bit units.
404 int32_t stringUnitsLength = (poolBundle.fIndexes[URES_INDEX_16BIT_TOP] - keysTop) * 2;
405 if (stringUnitsLength >= 2 && getFormatVersion() >= 3) {
406 poolBundle.fStrings = new PseudoListResource(NULL, status);
407 if (poolBundle.fStrings == NULL) {
408 fprintf(stderr, "unable to allocate memory for the pool bundle s trings %s\n",
409 poolFileName.data());
410 return U_MEMORY_ALLOCATION_ERROR;
411 }
412 // The PseudoListResource constructor call did not allocate further memory.
413 assert(U_SUCCESS(status));
414 const UChar *p = (const UChar *)(pRoot + keysTop);
415 int32_t remaining = stringUnitsLength;
416 do {
417 int32_t first = *p;
418 int8_t numCharsForLength;
419 int32_t length;
420 if (!U16_IS_TRAIL(first)) {
421 // NUL-terminated
422 numCharsForLength = 0;
423 for (length = 0;
424 length < remaining && p[length] != 0;
425 ++length) {}
426 } else if (first < 0xdfef) {
427 numCharsForLength = 1;
428 length = first & 0x3ff;
429 } else if (first < 0xdfff && remaining >= 2) {
430 numCharsForLength = 2;
431 length = ((first - 0xdfef) << 16) | p[1];
432 } else if (first == 0xdfff && remaining >= 3) {
433 numCharsForLength = 3;
434 length = ((int32_t)p[1] << 16) | p[2];
435 } else {
436 break; // overrun
437 }
438 // Check for overrun before changing remaining,
439 // so that it is always accurate after the loop body.
440 if ((numCharsForLength + length) >= remaining ||
441 p[numCharsForLength + length] != 0) {
442 break; // overrun or explicitly terminated
443 }
444 int32_t poolStringIndex = stringUnitsLength - remaining;
445 // Maximum pool string index when suffix-sharing the last charac ter.
446 int32_t maxStringIndex = poolStringIndex + numCharsForLength + l ength - 1;
447 if (maxStringIndex >= RES_MAX_OFFSET) {
448 // pool string index overrun
449 break;
450 }
451 p += numCharsForLength;
452 remaining -= numCharsForLength;
453 if (length != 0) {
454 StringResource *sr =
455 new StringResource(poolStringIndex, numCharsForLengt h,
456 p, length, status);
457 if (sr == NULL) {
458 fprintf(stderr, "unable to allocate memory for a pool bu ndle string %s\n",
459 poolFileName.data());
460 return U_MEMORY_ALLOCATION_ERROR;
461 }
462 poolBundle.fStrings->add(sr);
463 poolBundle.fStringIndexLimit = maxStringIndex + 1;
464 // The StringResource constructor did not allocate further m emory.
465 assert(U_SUCCESS(status));
466 }
467 p += length + 1;
468 remaining -= length + 1;
469 } while (remaining > 0);
470 if (poolBundle.fStrings->fCount == 0) {
471 delete poolBundle.fStrings;
472 poolBundle.fStrings = NULL;
473 }
474 }
475
394 T_FileStream_close(poolFile); 476 T_FileStream_close(poolFile);
395 setUsePoolBundle(TRUE); 477 setUsePoolBundle(TRUE);
478 if (isVerbose() && poolBundle.fStrings != NULL) {
479 printf("number of shared strings: %d\n", (int)poolBundle.fStrings->f Count);
480 int32_t length = poolBundle.fStringIndexLimit + 1; // incl. last NU L
481 printf("16-bit units for strings: %6d = %6d bytes\n",
482 (int)length, (int)length * 2);
483 }
484 }
485
486 if(!options[FORMAT_VERSION].doesOccur && getFormatVersion() == 3 &&
487 poolBundle.fStrings == NULL &&
488 !options[WRITE_POOL_BUNDLE].doesOccur) {
489 // If we just default to formatVersion 3
490 // but there are no pool bundle strings to share
491 // and we do not write a pool bundle,
492 // then write formatVersion 2 which is just as good.
493 setFormatVersion(2);
396 } 494 }
397 495
398 if(options[INCLUDE_UNIHAN_COLL].doesOccur) { 496 if(options[INCLUDE_UNIHAN_COLL].doesOccur) {
399 puts("genrb option --includeUnihanColl ignored: \n" 497 puts("genrb option --includeUnihanColl ignored: \n"
400 "CLDR 26/ICU 54 unihan data is small, except\n" 498 "CLDR 26/ICU 54 unihan data is small, except\n"
401 "the ucadata-unihan.icu version of the collation root data\n" 499 "the ucadata-unihan.icu version of the collation root data\n"
402 "is about 300kB larger than the ucadata-implicithan.icu version. "); 500 "is about 300kB larger than the ucadata-implicithan.icu version. ");
403 } 501 }
404 502
405 if((argc-1)!=1) { 503 if((argc-1)!=1) {
406 printf("genrb number of files: %d\n", argc - 1); 504 printf("genrb number of files: %d\n", argc - 1);
407 } 505 }
408 /* generate the binary files */ 506 /* generate the binary files */
409 for(i = 1; i < argc; ++i) { 507 for(i = 1; i < argc; ++i) {
410 status = U_ZERO_ERROR; 508 status = U_ZERO_ERROR;
411 arg = getLongPathname(argv[i]); 509 arg = getLongPathname(argv[i]);
412 510
511 CharString theCurrentFileName;
413 if (inputDir) { 512 if (inputDir) {
414 uprv_strcpy(theCurrentFileName, inputDir); 513 theCurrentFileName.append(inputDir, status);
415 uprv_strcat(theCurrentFileName, U_FILE_SEP_STRING);
416 } else {
417 *theCurrentFileName = 0;
418 } 514 }
419 uprv_strcat(theCurrentFileName, arg); 515 theCurrentFileName.appendPathPart(arg, status);
516 if (U_FAILURE(status)) {
517 break;
518 }
420 519
520 gCurrentFileName = theCurrentFileName.data();
421 if (isVerbose()) { 521 if (isVerbose()) {
422 printf("Processing file \"%s\"\n", theCurrentFileName); 522 printf("Processing file \"%s\"\n", theCurrentFileName.data());
423 } 523 }
424 processFile(arg, encoding, inputDir, outputDir, NULL, 524 processFile(arg, encoding, inputDir, outputDir, NULL,
425 options[NO_BINARY_COLLATION].doesOccur, 525 newPoolBundle.getAlias(),
426 &status); 526 options[NO_BINARY_COLLATION].doesOccur, status);
427 } 527 }
428 528
429 uprv_free(poolBundle.fBytes); 529 poolBundle.close();
430 530
431 if(options[WRITE_POOL_BUNDLE].doesOccur) { 531 if(U_SUCCESS(status) && options[WRITE_POOL_BUNDLE].doesOccur) {
432 char outputFileName[256]; 532 char outputFileName[256];
433 bundle_write(newPoolBundle, outputDir, NULL, outputFileName, sizeof(outp utFileName), &status); 533 newPoolBundle->write(outputDir, NULL, outputFileName, sizeof(outputFileN ame), status);
434 bundle_close(newPoolBundle, &status);
435 if(U_FAILURE(status)) { 534 if(U_FAILURE(status)) {
436 fprintf(stderr, "unable to write the pool bundle: %s\n", u_errorName (status)); 535 fprintf(stderr, "unable to write the pool bundle: %s\n", u_errorName (status));
437 } 536 }
438 } 537 }
439 538
440 u_cleanup(); 539 u_cleanup();
441 540
442 /* Dont return warnings as a failure */ 541 /* Dont return warnings as a failure */
443 if (U_SUCCESS(status)) { 542 if (U_SUCCESS(status)) {
444 return 0; 543 return 0;
445 } 544 }
446 545
447 return status; 546 return status;
448 } 547 }
449 548
450 /* Process a file */ 549 /* Process a file */
451 void 550 void
452 processFile( 551 processFile(const char *filename, const char *cp,
453 const char *filename, const char *cp, const char *inputDir, const char *outp utDir, const char *packageName, 552 const char *inputDir, const char *outputDir, const char *packageName ,
454 UBool omitBinaryCollation, UErrorCode *status) { 553 SRBRoot *newPoolBundle,
455 /*FileStream *in = NULL;*/ 554 UBool omitBinaryCollation, UErrorCode &status) {
456 struct SRBRoot *data = NULL; 555 LocalPointer<SRBRoot> data;
457 UCHARBUF *ucbuf = NULL; 556 UCHARBUF *ucbuf = NULL;
458 char *rbname = NULL; 557 char *rbname = NULL;
459 char *openFileName = NULL; 558 char *openFileName = NULL;
460 char *inputDirBuf = NULL; 559 char *inputDirBuf = NULL;
461 560
462 char outputFileName[256]; 561 char outputFileName[256];
463 562
464 int32_t dirlen = 0; 563 int32_t dirlen = 0;
465 int32_t filelen = 0; 564 int32_t filelen = 0;
466 565
467 566 if (U_FAILURE(status)) {
468 if (status==NULL || U_FAILURE(*status)) {
469 return; 567 return;
470 } 568 }
471 if(filename==NULL){ 569 if(filename==NULL){
472 *status=U_ILLEGAL_ARGUMENT_ERROR; 570 status=U_ILLEGAL_ARGUMENT_ERROR;
473 return; 571 return;
474 }else{ 572 }else{
475 filelen = (int32_t)uprv_strlen(filename); 573 filelen = (int32_t)uprv_strlen(filename);
476 } 574 }
477 575
478 if(inputDir == NULL) { 576 if(inputDir == NULL) {
479 const char *filenameBegin = uprv_strrchr(filename, U_FILE_SEP_CHAR); 577 const char *filenameBegin = uprv_strrchr(filename, U_FILE_SEP_CHAR);
480 openFileName = (char *) uprv_malloc(dirlen + filelen + 2); 578 openFileName = (char *) uprv_malloc(dirlen + filelen + 2);
481 openFileName[0] = '\0'; 579 openFileName[0] = '\0';
482 if (filenameBegin != NULL) { 580 if (filenameBegin != NULL) {
483 /* 581 /*
484 * When a filename ../../../data/root.txt is specified, 582 * When a filename ../../../data/root.txt is specified,
485 * we presume that the input directory is ../../../data 583 * we presume that the input directory is ../../../data
486 * This is very important when the resource file includes 584 * This is very important when the resource file includes
487 * another file, like UCARules.txt or thaidict.brk. 585 * another file, like UCARules.txt or thaidict.brk.
488 */ 586 */
489 int32_t filenameSize = (int32_t)(filenameBegin - filename + 1); 587 int32_t filenameSize = (int32_t)(filenameBegin - filename + 1);
490 inputDirBuf = uprv_strncpy((char *)uprv_malloc(filenameSize), filena me, filenameSize); 588 inputDirBuf = uprv_strncpy((char *)uprv_malloc(filenameSize), filena me, filenameSize);
491 589
492 /* test for NULL */ 590 /* test for NULL */
493 if(inputDirBuf == NULL) { 591 if(inputDirBuf == NULL) {
494 *status = U_MEMORY_ALLOCATION_ERROR; 592 status = U_MEMORY_ALLOCATION_ERROR;
495 goto finish; 593 goto finish;
496 } 594 }
497 595
498 inputDirBuf[filenameSize - 1] = 0; 596 inputDirBuf[filenameSize - 1] = 0;
499 inputDir = inputDirBuf; 597 inputDir = inputDirBuf;
500 dirlen = (int32_t)uprv_strlen(inputDir); 598 dirlen = (int32_t)uprv_strlen(inputDir);
501 } 599 }
502 }else{ 600 }else{
503 dirlen = (int32_t)uprv_strlen(inputDir); 601 dirlen = (int32_t)uprv_strlen(inputDir);
504 602
505 if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) { 603 if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) {
506 openFileName = (char *) uprv_malloc(dirlen + filelen + 2); 604 openFileName = (char *) uprv_malloc(dirlen + filelen + 2);
507 605
508 /* test for NULL */ 606 /* test for NULL */
509 if(openFileName == NULL) { 607 if(openFileName == NULL) {
510 *status = U_MEMORY_ALLOCATION_ERROR; 608 status = U_MEMORY_ALLOCATION_ERROR;
511 goto finish; 609 goto finish;
512 } 610 }
513 611
514 openFileName[0] = '\0'; 612 openFileName[0] = '\0';
515 /* 613 /*
516 * append the input dir to openFileName if the first char in 614 * append the input dir to openFileName if the first char in
517 * filename is not file seperation char and the last char input dire ctory is not '.'. 615 * filename is not file seperation char and the last char input dire ctory is not '.'.
518 * This is to support : 616 * This is to support :
519 * genrb -s. /home/icu/data 617 * genrb -s. /home/icu/data
520 * genrb -s. icu/data 618 * genrb -s. icu/data
521 * The user cannot mix notations like 619 * The user cannot mix notations like
522 * genrb -s. /icu/data --- the absolute path specified. -s redundant 620 * genrb -s. /icu/data --- the absolute path specified. -s redundant
523 * user should use 621 * user should use
524 * genrb -s. icu/data --- start from CWD and look in icu/data dir 622 * genrb -s. icu/data --- start from CWD and look in icu/data dir
525 */ 623 */
526 if( (filename[0] != U_FILE_SEP_CHAR) && (inputDir[dirlen-1] !='.')){ 624 if( (filename[0] != U_FILE_SEP_CHAR) && (inputDir[dirlen-1] !='.')){
527 uprv_strcpy(openFileName, inputDir); 625 uprv_strcpy(openFileName, inputDir);
528 openFileName[dirlen] = U_FILE_SEP_CHAR; 626 openFileName[dirlen] = U_FILE_SEP_CHAR;
529 } 627 }
530 openFileName[dirlen + 1] = '\0'; 628 openFileName[dirlen + 1] = '\0';
531 } else { 629 } else {
532 openFileName = (char *) uprv_malloc(dirlen + filelen + 1); 630 openFileName = (char *) uprv_malloc(dirlen + filelen + 1);
533 631
534 /* test for NULL */ 632 /* test for NULL */
535 if(openFileName == NULL) { 633 if(openFileName == NULL) {
536 *status = U_MEMORY_ALLOCATION_ERROR; 634 status = U_MEMORY_ALLOCATION_ERROR;
537 goto finish; 635 goto finish;
538 } 636 }
539 637
540 uprv_strcpy(openFileName, inputDir); 638 uprv_strcpy(openFileName, inputDir);
541 639
542 } 640 }
543 } 641 }
544 642
545 uprv_strcat(openFileName, filename); 643 uprv_strcat(openFileName, filename);
546 644
547 ucbuf = ucbuf_open(openFileName, &cp,getShowWarning(),TRUE, status); 645 ucbuf = ucbuf_open(openFileName, &cp,getShowWarning(),TRUE, &status);
548 if(*status == U_FILE_ACCESS_ERROR) { 646 if(status == U_FILE_ACCESS_ERROR) {
549 647
550 fprintf(stderr, "couldn't open file %s\n", openFileName == NULL ? filena me : openFileName); 648 fprintf(stderr, "couldn't open file %s\n", openFileName == NULL ? filena me : openFileName);
551 goto finish; 649 goto finish;
552 } 650 }
553 if (ucbuf == NULL || U_FAILURE(*status)) { 651 if (ucbuf == NULL || U_FAILURE(status)) {
554 fprintf(stderr, "An error occured processing file %s. Error: %s\n", open FileName == NULL ? filename : openFileName,u_errorName(*status)); 652 fprintf(stderr, "An error occured processing file %s. Error: %s\n",
653 openFileName == NULL ? filename : openFileName, u_errorName(stat us));
555 goto finish; 654 goto finish;
556 } 655 }
557 /* auto detected popular encodings? */ 656 /* auto detected popular encodings? */
558 if (cp!=NULL && isVerbose()) { 657 if (cp!=NULL && isVerbose()) {
559 printf("autodetected encoding %s\n", cp); 658 printf("autodetected encoding %s\n", cp);
560 } 659 }
561 /* Parse the data into an SRBRoot */ 660 /* Parse the data into an SRBRoot */
562 data = parse(ucbuf, inputDir, outputDir, filename, 661 data.adoptInstead(parse(ucbuf, inputDir, outputDir, filename,
563 !omitBinaryCollation, options[NO_COLLATION_RULES].doesOccur, st atus); 662 !omitBinaryCollation, options[NO_COLLATION_RULES].doesOccur, &status ));
564 663
565 if (data == NULL || U_FAILURE(*status)) { 664 if (data.isNull() || U_FAILURE(status)) {
566 fprintf(stderr, "couldn't parse the file %s. Error:%s\n", filename,u_err orName(*status)); 665 fprintf(stderr, "couldn't parse the file %s. Error:%s\n", filename, u_er rorName(status));
567 goto finish; 666 goto finish;
568 } 667 }
569 if(options[WRITE_POOL_BUNDLE].doesOccur) { 668 if(options[WRITE_POOL_BUNDLE].doesOccur) {
669 data->fWritePoolBundle = newPoolBundle;
670 data->compactKeys(status);
570 int32_t newKeysLength; 671 int32_t newKeysLength;
571 const char *newKeys, *newKeysLimit; 672 const char *newKeys = data->getKeyBytes(&newKeysLength);
572 bundle_compactKeys(data, status); 673 newPoolBundle->addKeyBytes(newKeys, newKeysLength, status);
573 newKeys = bundle_getKeyBytes(data, &newKeysLength); 674 if(U_FAILURE(status)) {
574 bundle_addKeyBytes(newPoolBundle, newKeys, newKeysLength, status);
575 if(U_FAILURE(*status)) {
576 fprintf(stderr, "bundle_compactKeys(%s) or bundle_getKeyBytes() fail ed: %s\n", 675 fprintf(stderr, "bundle_compactKeys(%s) or bundle_getKeyBytes() fail ed: %s\n",
577 filename, u_errorName(*status)); 676 filename, u_errorName(status));
578 goto finish; 677 goto finish;
579 } 678 }
580 /* count the number of just-added key strings */ 679 /* count the number of just-added key strings */
581 for(newKeysLimit = newKeys + newKeysLength; newKeys < newKeysLimit; ++ne wKeys) { 680 for(const char *newKeysLimit = newKeys + newKeysLength; newKeys < newKey sLimit; ++newKeys) {
582 if(*newKeys == 0) { 681 if(*newKeys == 0) {
583 ++newPoolBundle->fKeysCount; 682 ++newPoolBundle->fKeysCount;
584 } 683 }
585 } 684 }
586 } 685 }
587 686
588 if(options[USE_POOL_BUNDLE].doesOccur) { 687 if(options[USE_POOL_BUNDLE].doesOccur) {
589 data->fPoolBundleKeys = poolBundle.fKeys; 688 data->fUsePoolBundle = &poolBundle;
590 data->fPoolBundleKeysLength = poolBundle.fKeysLength;
591 data->fPoolBundleKeysCount = poolBundle.fKeysCount;
592 data->fPoolChecksum = poolBundle.fChecksum;
593 } 689 }
594 690
595 /* Determine the target rb filename */ 691 /* Determine the target rb filename */
596 rbname = make_res_filename(filename, outputDir, packageName, status); 692 rbname = make_res_filename(filename, outputDir, packageName, status);
597 if(U_FAILURE(*status)) { 693 if(U_FAILURE(status)) {
598 fprintf(stderr, "couldn't make the res fileName for bundle %s. Error:%s \n", filename,u_errorName(*status)); 694 fprintf(stderr, "couldn't make the res fileName for bundle %s. Error:%s \n",
695 filename, u_errorName(status));
599 goto finish; 696 goto finish;
600 } 697 }
601 if(write_java== TRUE){ 698 if(write_java== TRUE){
602 bundle_write_java(data,outputDir,outputEnc, outputFileName, sizeof(outpu tFileName), 699 bundle_write_java(data.getAlias(), outputDir, outputEnc,
603 options[JAVA_PACKAGE].value, options[BUNDLE_NAME].valu e, status); 700 outputFileName, sizeof(outputFileName),
701 options[JAVA_PACKAGE].value, options[BUNDLE_NAME].valu e, &status);
604 }else if(write_xliff ==TRUE){ 702 }else if(write_xliff ==TRUE){
605 bundle_write_xml(data,outputDir,outputEnc, filename, outputFileName, siz eof(outputFileName),language, xliffOutputFileName,status); 703 bundle_write_xml(data.getAlias(), outputDir, outputEnc,
704 filename, outputFileName, sizeof(outputFileName),
705 language, xliffOutputFileName, &status);
606 }else{ 706 }else{
607 /* Write the data to the file */ 707 /* Write the data to the file */
608 bundle_write(data, outputDir, packageName, outputFileName, sizeof(output FileName), status); 708 data->write(outputDir, packageName, outputFileName, sizeof(outputFileNam e), status);
609 } 709 }
610 if (U_FAILURE(*status)) { 710 if (U_FAILURE(status)) {
611 fprintf(stderr, "couldn't write bundle %s. Error:%s\n", outputFileName,u _errorName(*status)); 711 fprintf(stderr, "couldn't write bundle %s. Error:%s\n", outputFileName, u_errorName(status));
612 } 712 }
613 bundle_close(data, status);
614 713
615 finish: 714 finish:
616 715
617 if (inputDirBuf != NULL) { 716 if (inputDirBuf != NULL) {
618 uprv_free(inputDirBuf); 717 uprv_free(inputDirBuf);
619 } 718 }
620 719
621 if (openFileName != NULL) { 720 if (openFileName != NULL) {
622 uprv_free(openFileName); 721 uprv_free(openFileName);
623 } 722 }
624 723
625 if(ucbuf) { 724 if(ucbuf) {
626 ucbuf_close(ucbuf); 725 ucbuf_close(ucbuf);
627 } 726 }
628 727
629 if (rbname) { 728 if (rbname) {
630 uprv_free(rbname); 729 uprv_free(rbname);
631 } 730 }
632 } 731 }
633 732
634 /* Generate the target .res file name from the input file name */ 733 /* Generate the target .res file name from the input file name */
635 static char* 734 static char*
636 make_res_filename(const char *filename, 735 make_res_filename(const char *filename,
637 const char *outputDir, 736 const char *outputDir,
638 const char *packageName, 737 const char *packageName,
639 UErrorCode *status) { 738 UErrorCode &status) {
640 char *basename; 739 char *basename;
641 char *dirname; 740 char *dirname;
642 char *resName; 741 char *resName;
643 742
644 int32_t pkgLen = 0; /* length of package prefix */ 743 int32_t pkgLen = 0; /* length of package prefix */
645 744
646 745
647 if (U_FAILURE(*status)) { 746 if (U_FAILURE(status)) {
648 return 0; 747 return 0;
649 } 748 }
650 749
651 if(packageName != NULL) 750 if(packageName != NULL)
652 { 751 {
653 pkgLen = (int32_t)(1 + uprv_strlen(packageName)); 752 pkgLen = (int32_t)(1 + uprv_strlen(packageName));
654 } 753 }
655 754
656 /* setup */ 755 /* setup */
657 basename = dirname = resName = 0; 756 basename = dirname = resName = 0;
658 757
659 /* determine basename, and compiled file names */ 758 /* determine basename, and compiled file names */
660 basename = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)); 759 basename = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1));
661 if(basename == 0) { 760 if(basename == 0) {
662 *status = U_MEMORY_ALLOCATION_ERROR; 761 status = U_MEMORY_ALLOCATION_ERROR;
663 goto finish; 762 goto finish;
664 } 763 }
665 764
666 get_basename(basename, filename); 765 get_basename(basename, filename);
667 766
668 dirname = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)); 767 dirname = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1));
669 if(dirname == 0) { 768 if(dirname == 0) {
670 *status = U_MEMORY_ALLOCATION_ERROR; 769 status = U_MEMORY_ALLOCATION_ERROR;
671 goto finish; 770 goto finish;
672 } 771 }
673 772
674 get_dirname(dirname, filename); 773 get_dirname(dirname, filename);
675 774
676 if (outputDir == NULL) { 775 if (outputDir == NULL) {
677 /* output in same dir as .txt */ 776 /* output in same dir as .txt */
678 resName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(dirname) 777 resName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(dirname)
679 + pkgLen 778 + pkgLen
680 + uprv_strlen(basename) 779 + uprv_strlen(basename)
681 + uprv_strlen(RES_SUFFIX) + 8)); 780 + uprv_strlen(RES_SUFFIX) + 8));
682 if(resName == 0) { 781 if(resName == 0) {
683 *status = U_MEMORY_ALLOCATION_ERROR; 782 status = U_MEMORY_ALLOCATION_ERROR;
684 goto finish; 783 goto finish;
685 } 784 }
686 785
687 uprv_strcpy(resName, dirname); 786 uprv_strcpy(resName, dirname);
688 787
689 if(packageName != NULL) 788 if(packageName != NULL)
690 { 789 {
691 uprv_strcat(resName, packageName); 790 uprv_strcat(resName, packageName);
692 uprv_strcat(resName, "_"); 791 uprv_strcat(resName, "_");
693 } 792 }
694 793
695 uprv_strcat(resName, basename); 794 uprv_strcat(resName, basename);
696 795
697 } else { 796 } else {
698 int32_t dirlen = (int32_t)uprv_strlen(outputDir); 797 int32_t dirlen = (int32_t)uprv_strlen(outputDir);
699 int32_t basenamelen = (int32_t)uprv_strlen(basename); 798 int32_t basenamelen = (int32_t)uprv_strlen(basename);
700 799
701 resName = (char*) uprv_malloc(sizeof(char) * (dirlen + pkgLen + basename len + 8)); 800 resName = (char*) uprv_malloc(sizeof(char) * (dirlen + pkgLen + basename len + 8));
702 801
703 if (resName == NULL) { 802 if (resName == NULL) {
704 *status = U_MEMORY_ALLOCATION_ERROR; 803 status = U_MEMORY_ALLOCATION_ERROR;
705 goto finish; 804 goto finish;
706 } 805 }
707 806
708 uprv_strcpy(resName, outputDir); 807 uprv_strcpy(resName, outputDir);
709 808
710 if(outputDir[dirlen] != U_FILE_SEP_CHAR) { 809 if(outputDir[dirlen] != U_FILE_SEP_CHAR) {
711 resName[dirlen] = U_FILE_SEP_CHAR; 810 resName[dirlen] = U_FILE_SEP_CHAR;
712 resName[dirlen + 1] = '\0'; 811 resName[dirlen + 1] = '\0';
713 } 812 }
714 813
(...skipping 11 matching lines...) Expand all
726 uprv_free(dirname); 825 uprv_free(dirname);
727 826
728 return resName; 827 return resName;
729 } 828 }
730 829
731 /* 830 /*
732 * Local Variables: 831 * Local Variables:
733 * indent-tabs-mode: nil 832 * indent-tabs-mode: nil
734 * End: 833 * End:
735 */ 834 */
OLDNEW
« no previous file with comments | « source/tools/genrb/genrb.c ('k') | source/tools/genrb/genrb.vcxproj » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698