ICU-8015 Dynamically allocate enough memory in pkgdata tool for compiler options.

X-SVN-Rev: 28760
This commit is contained in:
Michael Ow 2010-10-04 23:47:46 +00:00
parent c5e5a4c54e
commit d40ee7f0cb
2 changed files with 103 additions and 48 deletions

View file

@ -751,46 +751,61 @@ static int32_t pkg_executeOptions(UPKGOptions *o) {
static int32_t initializePkgDataFlags(UPKGOptions *o) {
UErrorCode status = U_ZERO_ERROR;
int32_t result = 0;
int32_t currentBufferSize = SMALL_BUFFER_MAX_SIZE;
/* Initialize pkgdataFlags */
pkgDataFlags = (char**)uprv_malloc(sizeof(char*) * PKGDATA_FLAGS_SIZE);
if (pkgDataFlags != NULL) {
for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) {
pkgDataFlags[i] = (char*)uprv_malloc(sizeof(char) * LARGE_BUFFER_MAX_SIZE);
if (pkgDataFlags[i] != NULL) {
pkgDataFlags[i][0] = 0;
} else {
fprintf(stderr,"Error allocating memory for pkgDataFlags.\n");
return -1;
}
}
} else {
fprintf(stderr,"Error allocating memory for pkgDataFlags.\n");
return -1;
}
if (o->options == NULL) {
return result;
}
/* If we run out of space, allocate more */
#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN)
do {
#endif
if (pkgDataFlags != NULL) {
for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) {
pkgDataFlags[i] = (char*)uprv_malloc(sizeof(char) * currentBufferSize);
if (pkgDataFlags[i] != NULL) {
pkgDataFlags[i][0] = 0;
} else {
fprintf(stderr,"Error allocating memory for pkgDataFlags.\n");
return -1;
}
}
} else {
fprintf(stderr,"Error allocating memory for pkgDataFlags.\n");
return -1;
}
if (o->options == NULL) {
return result;
}
#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN)
/* Read in options file. */
if(o->verbose) {
fprintf(stdout, "# Reading options file %s\n", o->options);
}
parseFlagsFile(o->options, pkgDataFlags, LARGE_BUFFER_MAX_SIZE, (int32_t)PKGDATA_FLAGS_SIZE, &status);
if (U_FAILURE(status)) {
fprintf(stderr,"Unable to open or read \"%s\" option file. status = %s\n", o->options, u_errorName(status));
return -1;
}
#endif
if(o->verbose) {
fprintf(stdout, "# pkgDataFlags=");
for(int32_t i=0;i<PKGDATA_FLAGS_SIZE && pkgDataFlags[i][0];i++) {
fprintf(stdout, "%c \"%s\"", (i>0)?',':' ',pkgDataFlags[i]);
/* Read in options file. */
if(o->verbose) {
fprintf(stdout, "# Reading options file %s\n", o->options);
}
fprintf(stdout, "\n");
}
status = U_ZERO_ERROR;
parseFlagsFile(o->options, pkgDataFlags, currentBufferSize, (int32_t)PKGDATA_FLAGS_SIZE, &status);
if (status == U_BUFFER_OVERFLOW_ERROR) {
for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) {
uprv_free(pkgDataFlags[i]);
}
currentBufferSize *= 2;
} else if (U_FAILURE(status)) {
fprintf(stderr,"Unable to open or read \"%s\" option file. status = %s\n", o->options, u_errorName(status));
return -1;
}
#endif
if(o->verbose) {
fprintf(stdout, "# pkgDataFlags=");
for(int32_t i=0;i<PKGDATA_FLAGS_SIZE && pkgDataFlags[i][0];i++) {
fprintf(stdout, "%c \"%s\"", (i>0)?',':' ',pkgDataFlags[i]);
}
fprintf(stdout, "\n");
}
#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN)
} while (status == U_BUFFER_OVERFLOW_ERROR);
#endif
return result;
}
@ -1183,13 +1198,23 @@ static int32_t pkg_generateLibraryFile(const char *targetDir, const char mode, c
static int32_t pkg_createWithAssemblyCode(const char *targetDir, const char mode, const char *gencFilePath) {
char tempObjectFile[SMALL_BUFFER_MAX_SIZE] = "";
char cmd[LARGE_BUFFER_MAX_SIZE] = "";
char *cmd;
int32_t result = 0;
int32_t length = 0;
/* Remove the ending .s and replace it with .o for the new object file. */
uprv_strcpy(tempObjectFile, gencFilePath);
tempObjectFile[uprv_strlen(tempObjectFile)-1] = 'o';
length = uprv_strlen(pkgDataFlags[COMPILER]) + uprv_strlen(pkgDataFlags[LIBFLAGS])
+ uprv_strlen(tempObjectFile) + uprv_strlen(gencFilePath) + 10;
cmd = (char *)uprv_malloc(sizeof(char) * length);
if (cmd == NULL) {
return -1;
}
/* Generate the object file. */
sprintf(cmd, "%s %s -o %s %s",
pkgDataFlags[COMPILER],
@ -1198,6 +1223,7 @@ static int32_t pkg_createWithAssemblyCode(const char *targetDir, const char mode
gencFilePath);
result = runCommand(cmd);
uprv_free(cmd);
if (result != 0) {
return result;
}

View file

@ -1,13 +1,15 @@
/******************************************************************************
* Copyright (C) 2009, International Business Machines
* Copyright (C) 2009-2010, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
*/
#include "flagparser.h"
#include "filestrm.h"
#include "cstring.h"
#include "cmemory.h"
#define LARGE_BUFFER_MAX_SIZE 2048
#define BUFFER_DEFAULT_SIZE 512
static void extractFlag(char* buffer, int32_t bufferSize, char* flag, int32_t flagSize, UErrorCode *status);
static int32_t getFlagOffset(const char *buffer, int32_t bufferSize);
@ -17,7 +19,9 @@ static int32_t getFlagOffset(const char *buffer, int32_t bufferSize);
*/
U_CAPI void U_EXPORT2
parseFlagsFile(const char *fileName, char **flagBuffer, int32_t flagBufferSize, int32_t numOfFlags, UErrorCode *status) {
char buffer[LARGE_BUFFER_MAX_SIZE];
int32_t currentBufferSize = BUFFER_DEFAULT_SIZE;
char* buffer = uprv_malloc(sizeof(char) * currentBufferSize);
UBool allocateMoreSpace = FALSE;
int32_t i;
FileStream *f = T_FileStream_open(fileName, "r");
@ -26,18 +30,43 @@ parseFlagsFile(const char *fileName, char **flagBuffer, int32_t flagBufferSize,
return;
}
for (i = 0; i < numOfFlags; i++) {
if (T_FileStream_readLine(f, buffer, LARGE_BUFFER_MAX_SIZE) == NULL) {
*status = U_FILE_ACCESS_ERROR;
break;
}
extractFlag(buffer, LARGE_BUFFER_MAX_SIZE, flagBuffer[i], flagBufferSize, status);
if (U_FAILURE(*status)) {
break;
}
if (buffer == NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
return;
}
do {
if (allocateMoreSpace) {
allocateMoreSpace = FALSE;
currentBufferSize *= 2;
uprv_free(buffer);
buffer = uprv_malloc(sizeof(char) * currentBufferSize);
if (buffer == NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
return;
}
}
for (i = 0; i < numOfFlags; i++) {
if (T_FileStream_readLine(f, buffer, currentBufferSize) == NULL) {
*status = U_FILE_ACCESS_ERROR;
break;
}
if (uprv_strlen(buffer) == (currentBufferSize - 1) && buffer[currentBufferSize-2] != '\n') {
/* Allocate more space for buffer if it didnot read the entrire line */
allocateMoreSpace = TRUE;
T_FileStream_rewind(f);
break;
} else {
extractFlag(buffer, currentBufferSize, flagBuffer[i], flagBufferSize, status);
if (U_FAILURE(*status)) {
break;
}
}
}
} while (allocateMoreSpace && U_SUCCESS(*status));
T_FileStream_close(f);
}