From 06d5ee2949a837deb0347e08fa23be9d1ddf4ee2 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Wed, 17 Jul 2002 03:56:50 +0000 Subject: [PATCH] ICU-1992 data packaging changes X-SVN-Rev: 9223 --- icu4c/source/data/makedata.mak | 106 ++++++------- icu4c/source/stubdata/stubdata.dsp | 22 +-- icu4c/source/test/cintltst/cintltst.c | 132 ++++++++-------- icu4c/source/test/cintltst/cintltst.h | 5 + icu4c/source/test/cintltst/creststn.c | 13 +- icu4c/source/test/cintltst/udatatst.c | 201 +++++++++---------------- icu4c/source/test/testdata/testdata.mk | 54 ++++--- icu4c/source/tools/genbrk/genbrk.cpp | 2 + icu4c/source/tools/genccode/genccode.c | 15 +- icu4c/source/tools/gencmn/gencmn.c | 13 +- icu4c/source/tools/gencnval/gencnval.c | 4 +- icu4c/source/tools/gennames/gennames.c | 4 +- icu4c/source/tools/gennorm/gennorm.c | 2 +- icu4c/source/tools/gennorm/store.c | 4 +- icu4c/source/tools/genprops/store.c | 2 +- icu4c/source/tools/genrb/genrb.c | 102 +++++++++++-- icu4c/source/tools/genrb/reslist.c | 24 ++- icu4c/source/tools/genrb/reslist.h | 2 +- icu4c/source/tools/gentest/gentest.c | 5 +- icu4c/source/tools/gentz/gentz.cpp | 6 +- icu4c/source/tools/genuca/genuca.cpp | 20 ++- icu4c/source/tools/makeconv/makeconv.c | 95 +++++++++++- icu4c/source/tools/pkgdata/pkgdata.c | 115 ++++++++++++-- icu4c/source/tools/pkgdata/pkgtypes.c | 9 +- icu4c/source/tools/pkgdata/sttcmode.c | 3 + 25 files changed, 599 insertions(+), 361 deletions(-) diff --git a/icu4c/source/data/makedata.mak b/icu4c/source/data/makedata.mak index 9d21a3014a1..2391e29bdc5 100644 --- a/icu4c/source/data/makedata.mak +++ b/icu4c/source/data/makedata.mak @@ -29,6 +29,10 @@ UNICODE_VERSION=3.2 ICUBLD=$(ICUMAKE)\out\build ICUOUT=$(ICUMAKE)\out +# ICUDT +# the prefix "icudt21_" for use in filenames +ICUPKG=$(U_ICUDATA_NAME)$(U_ICUDATA_ENDIAN_SUFFIX) +ICUDT=$(ICUPKG)_ # ICUP # The root of the ICU source directory tree @@ -219,13 +223,13 @@ ALL_RES = $(RB_FILES) $(TRANSLIT_FILES) # Building the common dll in $(ICUBLD) unconditionally copies it to $(DLL_OUTPUT) too. # ############################################################################# -ALL : GODATA "$(DLL_OUTPUT)\$(U_ICUDATA_NAME).dll" "$(TESTDATAOUT)\testdata.dat" "$(TESTDATAOUT)\test1.cnv" "$(TESTDATAOUT)\test3.cnv" "$(TESTDATAOUT)\test4.cnv" +ALL : GODATA "$(DLL_OUTPUT)\$(U_ICUDATA_NAME).dll" "$(TESTDATAOUT)\testdata.dat" @echo All targets are up to date # # testdata - nmake will invoke pkgdata, which will create testdata.dat # -"$(TESTDATAOUT)\testdata.dat": ucadata.dat $(TRANSLIT_FILES) $(RB_FILES) {"$(ICUTOOLS)\genrb\$(CFG)"}genrb.exe +"$(TESTDATAOUT)\testdata.dat": $(ICUDT)ucadata.dat $(TRANSLIT_FILES) $(RB_FILES) {"$(ICUTOOLS)\genrb\$(CFG)"}genrb.exe @cd "$(TESTDATA)" @echo building testdata... nmake /nologo /f "$(TESTDATA)\testdata.mk" TESTDATA=. ICUTOOLS="$(ICUTOOLS)" PKGOPT="$(PKGOPT)" CFG=$(CFG) TESTDATAOUT="$(TESTDATAOUT)" ICUDATA="$(ICUDATA)" TESTDATABLD="$(TESTDATABLD)" @@ -233,24 +237,24 @@ ALL : GODATA "$(DLL_OUTPUT)\$(U_ICUDATA_NAME).dll" "$(TESTDATAOUT)\testdata.dat" # # Break iterator data files. # -BRK_FILES = "$(ICUBLD)\sent.brk" "$(ICUBLD)\char.brk" "$(ICUBLD)\line.brk" "$(ICUBLD)\word.brk" "$(ICUBLD)\title.brk" "$(ICUBLD)\line_th.brk" "$(ICUBLD)\word_th.brk" +BRK_FILES = "$(ICUBLD)\$(ICUDT)sent.brk" "$(ICUBLD)\$(ICUDT)char.brk" "$(ICUBLD)\$(ICUDT)line.brk" "$(ICUBLD)\$(ICUDT)word.brk" "$(ICUBLD)\$(ICUDT)title.brk" "$(ICUBLD)\$(ICUDT)line_th.brk" "$(ICUBLD)\$(ICUDT)word_th.brk" #invoke pkgdata for ICU common data # pkgdata will drop all output files (.dat, .dll, .lib) into the target (ICUBLD) directory. # move the .dll and .lib files to their final destination afterwards. # The $(U_ICUDATA_NAME).lib and $(U_ICUDATA_NAME).exp should already be in the right place due to stubdata. # -"$(DLL_OUTPUT)\$(U_ICUDATA_NAME).dll" : "$(ICUTOOLS)\pkgdata\$(CFG)\pkgdata.exe" $(CNV_FILES) $(BRK_FILES) "$(ICUBLD)\uprops.dat" "$(ICUBLD)\unames.dat" "$(ICUBLD)\unorm.dat" "$(ICUBLD)\cnvalias.icu" "$(ICUBLD)\tz.dat" "$(ICUBLD)\ucadata.dat" "$(ICUBLD)\invuca.dat" $(ALL_RES) "$(ICUBLD)\icudata.res" "$(ICUP)\source\stubdata\stubdatabuilt.txt" +"$(DLL_OUTPUT)\$(U_ICUDATA_NAME).dll" : "$(ICUTOOLS)\pkgdata\$(CFG)\pkgdata.exe" $(CNV_FILES) $(BRK_FILES) "$(ICUBLD)\$(ICUDT)uprops.dat" "$(ICUBLD)\$(ICUDT)unames.dat" "$(ICUBLD)\$(ICUDT)unorm.dat" "$(ICUBLD)\$(ICUDT)cnvalias.icu" "$(ICUBLD)\$(ICUDT)tz.dat" "$(ICUBLD)\$(ICUDT)ucadata.dat" "$(ICUBLD)\$(ICUDT)invuca.dat" $(ALL_RES) "$(ICUBLD)\$(ICUDT)icudata.res" "$(ICUP)\source\stubdata\stubdatabuilt.txt" @echo Building icu data @cd "$(ICUBLD)" - "$(ICUTOOLS)\pkgdata\$(CFG)\pkgdata" -e $(U_ICUDATA_NAME) -v -m dll -c -p $(U_ICUDATA_NAME) -O "$(PKGOPT)" -d "$(ICUBLD)" -s . < 1022) + { + newPath = malloc(newLen); + } + + strcpy(newPath, oldPath); + strcpy(newPath+oldLen, U_PATH_SEP_STRING); + strcpy(newPath+oldLen+1, toAppend); + + u_setDataDirectory(newPath); + + if(newPath != newBuf) + { + free(newPath); + } + } +} + + void ctest_pathnameInContext( char* fullname, int32_t maxsize, const char* relPath ) { char mainDirBuffer[1024]; char* mainDir = NULL; - const char *dataDirectory = u_getDataDirectory(); + const char *dataDirectory = ctest_dataOutDir(); const char inpSepChar = '|'; char* tmp; int32_t lenMainDir; @@ -228,22 +266,13 @@ ctest_pathnameInContext( char* fullname, int32_t maxsize, const char* relPath ) } } +/* returns the path to icu/source/data/out */ +const char *ctest_dataOutDir() +{ + static char *dataOutDir = NULL; -/* ctest_setICU_DATA - if the ICU_DATA environment variable is not already - * set, try to deduce the directory in which ICU was built, - * and set ICU_DATA to "icu/source/data" in that location. - * The intent is to allow the tests to have a good chance - * of running without requiring that the user manually set - * ICU_DATA. Common data isn't a problem, since it is - * picked up via a static (build time) reference, but the - * tests dynamically load some data. - */ -void ctest_setICU_DATA() { - const char *original_ICU_DATA = getenv("ICU_DATA"); - - if (original_ICU_DATA != NULL && *original_ICU_DATA != 0) { - /* If the user set ICU_DATA, don't second-guess the person. */ - return; + if(dataOutDir) { + return dataOutDir; } /* U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst @@ -256,9 +285,7 @@ void ctest_setICU_DATA() { */ #if defined (U_TOPBUILDDIR) { - static char env_string[] = U_TOPBUILDDIR U_FILE_SEP_STRING "data"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING; - u_setDataDirectory(env_string); - return; + dataOutDir = U_TOPBUILDDIR U_FILE_SEP_STRING "data"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING; } #else @@ -267,7 +294,7 @@ void ctest_setICU_DATA() { * Change to "wherever\icu\source\data" */ { - char p[sizeof(__FILE__) + 10]; + static char p[sizeof(__FILE__) + 10]; char *pBackSlash; int i; @@ -286,12 +313,27 @@ void ctest_setICU_DATA() { * Now append "source\data" and set the environment */ strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING); - u_setDataDirectory(p); /* p is "ICU_DATA=wherever\icu\source\data" */ - return; + dataOutDir = p; } } #endif + return dataOutDir; + +} + +/* ctest_setICU_DATA - if the ICU_DATA environment variable is not already + * set, try to deduce the directory in which ICU was built, + * and set ICU_DATA to "icu/source/data" in that location. + * The intent is to allow the tests to have a good chance + * of running without requiring that the user manually set + * ICU_DATA. Common data isn't a problem, since it is + * picked up via a static (build time) reference, but the + * tests dynamically load some data. + */ +void ctest_setICU_DATA() { + + /* No location for the data dir was identifiable. * Add other fallbacks for the test data location here if the need arises */ @@ -349,10 +391,10 @@ const char* loadTestData(UErrorCode* err){ const char* directory=NULL; UResourceBundle* test =NULL; char* tdpath=NULL; - const char* tdrelativepath = ".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING; + const char* tdrelativepath = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING; if( _testDataPath == NULL){ - directory= u_getDataDirectory(); - + directory= ctest_dataOutDir(); + tdpath = (char*) ctst_malloc(sizeof(char) *(( strlen(directory) * strlen(tdrelativepath)) + 10)); @@ -369,41 +411,11 @@ const char* loadTestData(UErrorCode* err){ test=ures_open(tdpath, "testtypes", err); - /* we could not find the data in tdpath - * try tdpathFallback - */ - if(U_FAILURE(*err)) - { - strcpy(tdpath,directory); - strcat(tdpath,".."U_FILE_SEP_STRING); - strcat(tdpath, tdrelativepath); - strcat(tdpath,"testdata"); - *err =U_ZERO_ERROR; - test=ures_open(tdpath, "testtypes", err); - /* we could not find the data in tdpath - * try one more tdpathFallback - */ - if(U_FAILURE(*err)){ - strcpy(tdpath,directory); - strcat(tdpath,".."U_FILE_SEP_STRING); - strcat(tdpath,".."U_FILE_SEP_STRING); - strcat(tdpath, tdrelativepath); - strcat(tdpath,"testdata"); - *err =U_ZERO_ERROR; - test=ures_open(tdpath, "testtypes", err); - /* Fall back did not succeed either so return */ - if(U_FAILURE(*err)){ - *err = U_FILE_ACCESS_ERROR; - log_err("construction of NULL did not succeed : %s \n", u_errorName(*err)); - return ""; - } - ures_close(test); - _testDataPath = tdpath; - return _testDataPath; - } - ures_close(test); - _testDataPath = tdpath; - return _testDataPath; + /* Fall back did not succeed either so return */ + if(U_FAILURE(*err)){ + *err = U_FILE_ACCESS_ERROR; + log_err("Could not load testtypes.res in testdata bundle with path %s - %as\n", tdpath, u_errorName(*err)); + return ""; } ures_close(test); _testDataPath = tdpath; diff --git a/icu4c/source/test/cintltst/cintltst.h b/icu4c/source/test/cintltst/cintltst.h index 1658a4fd611..66cf07bd95e 100644 --- a/icu4c/source/test/cintltst/cintltst.h +++ b/icu4c/source/test/cintltst/cintltst.h @@ -28,6 +28,11 @@ The main root for C API tests U_CFUNC void addAllTests(TestNode** root); +/** + * Return the path to the icu/source/data/out directory + */ +U_CFUNC const char* ctest_dataOutDir(); + /** *complete a relative path to a full pathname, and convert to platform-specific syntax. * The character seperating directories for the relative path is '|'. diff --git a/icu4c/source/test/cintltst/creststn.c b/icu4c/source/test/cintltst/creststn.c index 519c82cd477..af29b1ca45b 100644 --- a/icu4c/source/test/cintltst/creststn.c +++ b/icu4c/source/test/cintltst/creststn.c @@ -262,10 +262,7 @@ static void TestDecodedBundle(){ /* pre-flight */ int32_t num =0; - char testdatapath[256]; - const char *directory= u_getDataDirectory(); - strcpy(testdatapath, directory); - strcat(testdatapath, "testdata"); + const char *testdatapath = loadTestData(&error); resB = ures_open(testdatapath, "ja_data", &error); srcFromRes=ures_getStringByKey(resB,"str",&len,&error); @@ -299,6 +296,7 @@ static void TestNewTypes() { UChar uExpect[200]; testdatapath=loadTestData(&status); + if(U_FAILURE(status)) { log_err("Could not load testdata.dat %s \n",myErrorName(status)); @@ -448,7 +446,6 @@ static void TestEmptyTypes() { const int32_t *zeroIntVect; strcpy(action, "Construction of testtypes bundle"); - testdatapath=loadTestData(&status); if(U_FAILURE(status)) { @@ -1147,13 +1144,11 @@ static void TestConstruction2() const char* directory; const char* locale="te_IN"; wchar_t widedirectory[256]; - char testdatapath[256]; + const char *testdatapath; int32_t len=0; char verboseOutput[256]; - directory= u_getDataDirectory(); - uprv_strcpy(testdatapath, directory); - uprv_strcat(testdatapath, "testdata"); + testdatapath= loadTestData(&err); mbstowcs(widedirectory, testdatapath, 256); log_verbose("Testing ures_openW().......\n"); diff --git a/icu4c/source/test/cintltst/udatatst.c b/icu4c/source/test/cintltst/udatatst.c index 75a3bbaba74..483039330c9 100644 --- a/icu4c/source/test/cintltst/udatatst.c +++ b/icu4c/source/test/cintltst/udatatst.c @@ -62,6 +62,19 @@ addUDataTest(TestNode** root) } +#if 0 +static void lots_of_mallocs() +{ + int q; + for(q=1;q<100;q++) + { + free(malloc(q)); + malloc(q*2); + } + +} +#endif + static void TestUDataOpen(){ UDataMemory *result; UErrorCode status=U_ZERO_ERROR; @@ -75,7 +88,7 @@ static void TestUDataOpen(){ const char* type = "dat"; const char dirSepString[] = {U_FILE_SEP_CHAR, 0}; - char* path=(char*)malloc(sizeof(char) * (strlen(u_getDataDirectory()) + char* path=(char*)malloc(sizeof(char) * (strlen(ctest_dataOutDir()) + strlen(U_ICUDATA_NAME) + strlen("/build")+1 ) ); @@ -84,7 +97,9 @@ static void TestUDataOpen(){ const char* testPath=loadTestData(&status); - strcat(strcpy(path, u_getDataDirectory()), U_ICUDATA_NAME); + /* lots_of_mallocs(); */ + + strcat(strcpy(path, ctest_dataOutDir()), U_ICUDATA_NAME); log_verbose("Testing udata_open()\n"); result=udata_open(testPath, type, name, &status); @@ -103,11 +118,13 @@ static void TestUDataOpen(){ icuDataFilePath = (char *)malloc(strlen(path) + 10); strcpy(icuDataFilePath, path); strcat(icuDataFilePath, ".dat"); + /* lots_of_mallocs(); */ if (stat(icuDataFilePath, &stat_buf) == 0) { int i; log_verbose("Testing udata_open() on %s\n", icuDataFilePath); for(i=0; ifLocale); if (len > writtenFilenameLen) { len = writtenFilenameLen; @@ -319,7 +328,18 @@ void bundle_write(struct SRBRoot *bundle, const char *outputDir, char *writtenFi } } - mem = udata_create(outputDir, "res", bundle->fLocale, &dataInfo, (gIncludeCopyright==TRUE)? U_COPYRIGHT_STRING:NULL, status); + if(outputPkg) + { + uprv_strcpy(dataName, outputPkg); + uprv_strcat(dataName, "_"); + uprv_strcat(dataName, bundle->fLocale); + } + else + { + uprv_strcpy(dataName, bundle->fLocale); + } + + mem = udata_create(outputDir, "res", dataName, &dataInfo, (gIncludeCopyright==TRUE)? U_COPYRIGHT_STRING:NULL, status); pad = calcPadding(bundle->fKeyPoint); diff --git a/icu4c/source/tools/genrb/reslist.h b/icu4c/source/tools/genrb/reslist.h index f9205073e35..7bafb1653c8 100644 --- a/icu4c/source/tools/genrb/reslist.h +++ b/icu4c/source/tools/genrb/reslist.h @@ -41,7 +41,7 @@ struct SRBRoot { }; struct SRBRoot *bundle_open(UErrorCode *status); -void bundle_write(struct SRBRoot *bundle, const char *outputDir, char *writtenFilename, int writtenFilenameLen, UErrorCode *status); +void bundle_write(struct SRBRoot *bundle, const char *outputDir, const char *outputPkg, char *writtenFilename, int writtenFilenameLen, UErrorCode *status); /* write a java resource file */ void bundle_write_java(struct SRBRoot *bundle, const char *outputDir, const char* outputEnc, char *writtenFilename, diff --git a/icu4c/source/tools/gentest/gentest.c b/icu4c/source/tools/gentest/gentest.c index 7777be4cbd6..f2b79daf18f 100644 --- a/icu4c/source/tools/gentest/gentest.c +++ b/icu4c/source/tools/gentest/gentest.c @@ -26,6 +26,7 @@ #include "cstring.h" #include "uoptions.h" +#define DATA_PKG "testdata" #define DATA_NAME "test" #define DATA_TYPE "dat" @@ -67,7 +68,7 @@ main(int argc, char* argv[]) { if(argc<0 || options[0].doesOccur || options[1].doesOccur) { fprintf(stderr, "usage: %s [-options]\n" - "\tcreate the test file " DATA_NAME "." DATA_TYPE "\n" + "\tcreate the test file " DATA_PKG "_" DATA_NAME "." DATA_TYPE "\n" "\toptions:\n" "\t\t-h or -? or --help this usage text\n" "\t\t-d or --destdir destination directory, followed by the path\n", @@ -91,7 +92,7 @@ createData(const char* outputDirectory) { long dataLength; uint32_t size; - pData=udata_create(outputDirectory, DATA_TYPE, DATA_NAME, &dataInfo, + pData=udata_create(outputDirectory, DATA_TYPE, DATA_PKG "_" DATA_NAME, &dataInfo, U_COPYRIGHT_STRING, &errorCode); if(U_FAILURE(errorCode)) { fprintf(stderr, "gentest: unable to create data memory, error %d\n", errorCode); diff --git a/icu4c/source/tools/gentz/gentz.cpp b/icu4c/source/tools/gentz/gentz.cpp index 408f525443d..0377e02efd4 100644 --- a/icu4c/source/tools/gentz/gentz.cpp +++ b/icu4c/source/tools/gentz/gentz.cpp @@ -187,7 +187,7 @@ int gentz::MMain(int argc, char* argv[]) { if(argc<0 || options[0].doesOccur || options[1].doesOccur) { fprintf(stderr, "usage: %s [-options] timezone-file\n" - "\tread the timezone file produced by tz.pl and create " TZ_DATA_NAME "." TZ_DATA_TYPE "\n" + "\tread the timezone file produced by tz.pl and create " U_ICUDATA_NAME "_" TZ_DATA_NAME "." TZ_DATA_TYPE "\n" "options:\n" "\t-h or -? or --help this usage text\n" "\t-v or --verbose turn on verbose output\n" @@ -224,7 +224,7 @@ int gentz::MMain(int argc, char* argv[]) { int32_t wlen = writeTzDatFile(options[3].value); if (verbose) { fprintf(stdout, "Output file: %s.%s, %ld bytes\n", - TZ_DATA_NAME, TZ_DATA_TYPE, (long)wlen); + U_ICUDATA_NAME "_" TZ_DATA_NAME, TZ_DATA_TYPE, (long)wlen); } return 0; // success @@ -266,7 +266,7 @@ int32_t gentz::writeTzDatFile(const char *destdir) { *(uint16_t*)&(dataInfo.dataVersion[0]) = header.versionYear; *(uint16_t*)&(dataInfo.dataVersion[2]) = header.versionSuffix; - pdata = udata_create(destdir, TZ_DATA_TYPE, TZ_DATA_NAME, &dataInfo, + pdata = udata_create(destdir, TZ_DATA_TYPE, U_ICUDATA_NAME "_" TZ_DATA_NAME, &dataInfo, useCopyright ? U_COPYRIGHT_STRING : 0, &status); if (U_FAILURE(status)) { die("Unable to create data memory"); diff --git a/icu4c/source/tools/genuca/genuca.cpp b/icu4c/source/tools/genuca/genuca.cpp index f96017a6ff1..357b4950722 100644 --- a/icu4c/source/tools/genuca/genuca.cpp +++ b/icu4c/source/tools/genuca/genuca.cpp @@ -299,7 +299,7 @@ static void writeOutInverseData(InverseTableHeader *data, long dataLength; - pData=udata_create(outputDir, INVC_DATA_TYPE, INVC_DATA_NAME, &invUcaDataInfo, + pData=udata_create(outputDir, INVC_DATA_TYPE, U_ICUDATA_NAME "_" INVC_DATA_NAME, &invUcaDataInfo, copyright, status); if(U_FAILURE(*status)) { @@ -310,7 +310,7 @@ static void writeOutInverseData(InverseTableHeader *data, /* write the data to the file */ if (VERBOSE) { fprintf(stdout, "Writing out inverse UCA table: %s%c%s.%s\n", outputDir, U_FILE_SEP_CHAR, - INVC_DATA_NAME, + U_ICUDATA_NAME "_" INVC_DATA_NAME, INVC_DATA_TYPE); } udata_writeBlock(pData, data, data->byteSize); @@ -627,7 +627,7 @@ void writeOutData(UCATableHeader *data, long dataLength; - pData=udata_create(outputDir, UCA_DATA_TYPE, UCA_DATA_NAME, &ucaDataInfo, + pData=udata_create(outputDir, UCA_DATA_TYPE, U_ICUDATA_NAME "_" UCA_DATA_NAME, &ucaDataInfo, copyright, status); if(U_FAILURE(*status)) { @@ -639,7 +639,7 @@ void writeOutData(UCATableHeader *data, if (VERBOSE) { fprintf(stdout, "Writing out UCA table: %s%c%s.%s\n", outputDir, U_FILE_SEP_CHAR, - UCA_DATA_NAME, + U_ICUDATA_NAME "_" UCA_DATA_NAME, UCA_DATA_TYPE); } udata_writeBlock(pData, data, size); @@ -743,6 +743,11 @@ write_uca_table(const char *filename, myD->jamoSpecial = FALSE; tempUCATable *t = uprv_uca_initTempTable(myD, opts, NULL, IMPLICIT_TAG, status); + if(U_FAILURE(*status)) + { + fprintf(stderr, "Failed to init UCA temp table: %s\n", u_errorName(*status)); + return -1; + } #if 0 IMPLICIT_TAG = 9, @@ -971,6 +976,13 @@ int main(int argc, char* argv[]) { uprv_strcpy(basename, getLongPathname(*argv)); } +#if 0 + if(u_getCombiningClass(0x0053) == 0) + { + fprintf(stderr, "SEVERE ERROR: Normalization data is not functioning! Bailing out. Was not able to load unorm.dat.\n"); + exit(1); + } +#endif return write_uca_table(filename, destdir, copyright, &status); } diff --git a/icu4c/source/tools/makeconv/makeconv.c b/icu4c/source/tools/makeconv/makeconv.c index 79ca8070af0..98a2f8a3940 100644 --- a/icu4c/source/tools/makeconv/makeconv.c +++ b/icu4c/source/tools/makeconv/makeconv.c @@ -44,6 +44,7 @@ extern const UConverterStaticData * ucnv_converterStaticData[UCNV_NUMBER_OF_SUPP * Global - verbosity */ UBool VERBOSE = FALSE; +UBool TOUCHFILE = FALSE; /*Reads the header of the table file and fills in basic knowledge about the converter *in "converter" @@ -247,7 +248,9 @@ static UOption options[]={ UOPTION_COPYRIGHT, /* 2 */ UOPTION_VERSION, /* 3 */ UOPTION_DESTDIR, /* 4 */ - UOPTION_VERBOSE /* 5 */ + UOPTION_VERBOSE, /* 5 */ + UOPTION_PACKAGE_NAME, /* 6 */ + UOPTION_DEF( "touchfile", 't', UOPT_NO_ARG) /* 7 */ }; int main(int argc, char* argv[]) @@ -255,10 +258,13 @@ int main(int argc, char* argv[]) UConverterSharedData* mySharedData = NULL; UErrorCode err = U_ZERO_ERROR; char outFileName[UCNV_MAX_FULL_FILE_NAME_LENGTH]; + char touchFileName[UCNV_MAX_FULL_FILE_NAME_LENGTH]; const char* destdir, *arg; + const char *pkgName = NULL; size_t destdirlen; char* dot = NULL, *outBasename; char cnvName[UCNV_MAX_FULL_FILE_NAME_LENGTH]; + char cnvNameWithPkg[UCNV_MAX_FULL_FILE_NAME_LENGTH]; UVersionInfo icuVersion; U_MAIN_INIT_ARGS(argc, argv); @@ -289,6 +295,9 @@ int main(int argc, char* argv[]) "\t-c or --copyright include a copyright notice\n" "\t-d or --destdir destination directory, followed by the path\n" "\t-v or --verbose Turn on verbose output\n", + "\t-p or --pkgname sets the 'package' name for output files. If ICUDATA, then the default\n" + "\t icu package name will be used.\n" + "\t-t or --touchfile Generate additional small file without packagename, for nmake\n", argv[0]); return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR; } @@ -301,6 +310,34 @@ int main(int argc, char* argv[]) exit(0); } + TOUCHFILE = options[7].doesOccur; + + if(!options[6].doesOccur) + { + fprintf(stderr, "%s : option -p (package name) is required.\n", + argv[0]); + exit(1); + } + else + { + pkgName =options[6].value; + if(!strcmp(pkgName, "ICUDATA")) + { + pkgName = U_ICUDATA_NAME; + } + if(pkgName[0] == 0) + { + pkgName = NULL; + + if(TOUCHFILE) + { + fprintf(stderr, "%s: Don't use touchfile option with an empty packagename.\n", + argv[0]); + exit(1); + } + } + } + /* get the options values */ haveCopyright = options[2].doesOccur; destdir = options[4].value; @@ -366,6 +403,21 @@ int main(int argc, char* argv[]) /* the basename without extension is the converter name */ uprv_strcpy(cnvName, outBasename); + if(TOUCHFILE) + { + uprv_strcpy(touchFileName, outBasename); + uprv_strcat(touchFileName, ".cnv"); + } + + if(pkgName != NULL) + { + /* changes both baename and filename */ + uprv_strcpy(outBasename, pkgName); + uprv_strcat(outBasename, "_"); + uprv_strcat(outBasename, cnvName); + } + + /*Adds the target extension*/ uprv_strcat(outBasename, CONVERTER_FILE_EXTENSION); @@ -378,7 +430,7 @@ int main(int argc, char* argv[]) if (U_FAILURE(err) || (mySharedData == NULL)) { /* if an error is found, print out an error msg and keep going */ - fprintf(stderr, "Error creating \"%s\" file for \"%s\" (error code %d - %s)\n", outFileName, arg, err, + fprintf(stderr, "Error creating converter for \"%s\" file for \"%s\" (error code %d - %s)\n", outFileName, arg, err, u_errorName(err)); err = U_ZERO_ERROR; } @@ -395,8 +447,42 @@ int main(int argc, char* argv[]) uprv_strcpy((char*)mySharedData->staticData->name, cnvName); - writeConverterData(mySharedData, cnvName, destdir, &err); + if(pkgName == NULL) + { + uprv_strcpy(cnvNameWithPkg, cnvName); + } + else + { + uprv_strcpy(cnvNameWithPkg, pkgName); + uprv_strcat(cnvNameWithPkg, "_"); + uprv_strcat(cnvNameWithPkg, cnvName); + } + + writeConverterData(mySharedData, cnvNameWithPkg, destdir, &err); ((NewConverter *)mySharedData->table)->close((NewConverter *)mySharedData->table); + if(TOUCHFILE) + { + FileStream *q; + char msg[1024]; + + sprintf(msg, "This empty file tells nmake that %s in package %s has been updated.\n", + cnvName, pkgName); + + q = T_FileStream_open(touchFileName, "w"); + if(q == NULL) + { + fprintf(stderr, "Error writing touchfile \"%s\"\n", touchFileName); + err = U_FILE_ACCESS_ERROR; + } + + else + { + T_FileStream_write(q, msg, uprv_strlen(msg)); + T_FileStream_close(q); + } + } + + /* write the information data */ uprv_free((UConverterStaticData *)mySharedData->staticData); uprv_free(mySharedData); @@ -828,7 +914,8 @@ UConverterSharedData* createConverterFromTableFile(const char* converterName, UE uprv_memset(myStaticData, 0, sizeof(UConverterStaticData)); mySharedData->staticData = myStaticData; myStaticData->structSize = sizeof(UConverterStaticData); - mySharedData->staticDataOwned = TRUE; +/* mySharedData->staticDataOwned = FALSE; */ /* not owned if in udata */ + mySharedData->sharedDataCached = FALSE; mySharedData->dataMemory = NULL; /* for init */ diff --git a/icu4c/source/tools/pkgdata/pkgdata.c b/icu4c/source/tools/pkgdata/pkgdata.c index b99d1a95f82..3ad830bf139 100644 --- a/icu4c/source/tools/pkgdata/pkgdata.c +++ b/icu4c/source/tools/pkgdata/pkgdata.c @@ -434,11 +434,19 @@ static void loadLists(UPKGOptions *o, UErrorCode *status) { CharList *l, *tail = NULL, *tail2 = NULL; FileStream *in; - char line[2048]; - char tmp[1024]; + char line[16384]; + char *linePtr, *lineNext; + const uint32_t lineMax = 16300; + char tmp[1024], tmp2[1024]; + char pkgPrefix[1024]; + int32_t pkgPrefixLen; const char* baseName; char *s; + int32_t ln; + strcpy(pkgPrefix, o->shortName); + strcat(pkgPrefix, "_"); + pkgPrefixLen=uprv_strlen(pkgPrefix); for(l = o->fileListFiles; l; l = l->next) { if(o->verbose) { fprintf(stdout, "# Reading %s..\n", l->str); @@ -451,8 +459,16 @@ static void loadLists(UPKGOptions *o, UErrorCode *status) *status = U_FILE_ACCESS_ERROR; return; } + + ln = 0; while(T_FileStream_readLine(in, line, sizeof(line))!=NULL) { + ln++; + if(uprv_strlen(line)>lineMax) + { + fprintf(stderr, "%s:%d - line too long (over %d chars)\n", l->str, ln, lineMax); + exit(1); + } /* remove trailing newline characters */ s=line; while(*s!=0) { @@ -466,22 +482,91 @@ static void loadLists(UPKGOptions *o, UErrorCode *status) continue; /* comment or empty line */ } - /* add the file */ - s = (char*)getLongPathname(line); + /* Now, process the line */ + linePtr = line; + lineNext = NULL; + + while(linePtr && *linePtr) + { + while(*linePtr == ' ') + { + linePtr++; + } - baseName = findBasename(s); + /* Find the next */ + if(linePtr[0] == '"') + { + lineNext = uprv_strchr(linePtr+1, '"'); + if(lineNext == NULL) + { + fprintf(stderr, "%s:%d - missing trailing double quote (\")\n", + l->str, ln); + exit(1); + } + else + { + lineNext++; + if(*lineNext) + { + if(*lineNext != ' ') + { + fprintf(stderr, "%s:%d - malformed quoted line at position %d, expected ' ' got '%c'\n", + l->str, ln, lineNext-line, (*lineNext)?*lineNext:'0'); + exit(1); + } - o->files = pkg_appendToList(o->files, &tail, uprv_strdup(baseName)); + *lineNext = 0; + lineNext++; + } + } + } + else + { + lineNext = uprv_strchr(linePtr, ' '); + if(lineNext) + { + *lineNext = 0; /* terminate at space */ + lineNext++; + } + } - if(s != baseName) { /* s was something long, so we leave it as it is */ - o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(s)); - } else { /* s was just a basename, we want to prepend source dir*/ - uprv_strcpy(tmp, o->srcDir); - uprv_strcat(tmp, o->srcDir[uprv_strlen(o->srcDir)-1]==U_FILE_SEP_CHAR?"":U_FILE_SEP_STRING); - uprv_strcat(tmp, s); - o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(tmp)); - } - } + /* add the file */ + s = (char*)getLongPathname(linePtr); + + baseName = findBasename(s); + + + if(s != baseName) { /* s was something long, so we leave it as it is */ + o->files = pkg_appendToList(o->files, &tail, uprv_strdup(baseName)); + o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(s)); + } else { /* s was just a basename, we want to prepend source dir*/ + /* check for prefix of package */ + uprv_strcpy(tmp, o->srcDir); + uprv_strcat(tmp, o->srcDir[uprv_strlen(o->srcDir)-1]==U_FILE_SEP_CHAR?"":U_FILE_SEP_STRING); + + if(strncmp(pkgPrefix,s, pkgPrefixLen)) + { + /* didn't have the prefix - add it */ + uprv_strcat(tmp, pkgPrefix); + + /* make up a new basename */ + uprv_strcpy(tmp2, pkgPrefix); + uprv_strcat(tmp2, s); + o->files = pkg_appendToList(o->files, &tail, uprv_strdup(tmp2)); + } + else + { + o->files = pkg_appendToList(o->files, &tail, uprv_strdup(baseName)); + } + + uprv_strcat(tmp, s); + + o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(tmp)); + } + + linePtr = lineNext; + } + } T_FileStream_close(in); } diff --git a/icu4c/source/tools/pkgdata/pkgtypes.c b/icu4c/source/tools/pkgdata/pkgtypes.c index 07cd848301a..e16525146f5 100644 --- a/icu4c/source/tools/pkgdata/pkgtypes.c +++ b/icu4c/source/tools/pkgdata/pkgtypes.c @@ -27,12 +27,14 @@ const char *pkg_writeCharListWrap(FileStream *s, CharList *l, const char *delim, { int32_t ln = 0; char buffer[1024]; + const CharList *ol = NULL; while(l != NULL) { if(l->str) { - uprv_strcpy(buffer, l->str); - + uprv_strncpy(buffer, l->str, 1020); + buffer[1019]=0; + if(quote < 0) { /* remove quotes */ if(buffer[uprv_strlen(buffer)-1] == '"') { buffer[uprv_strlen(buffer)-1] = '\0'; @@ -43,7 +45,7 @@ const char *pkg_writeCharListWrap(FileStream *s, CharList *l, const char *delim, } else if(quote > 0) { /* add quotes */ if(l->str[0] != '"') { uprv_strcpy(buffer, "\""); - uprv_strcat(buffer, l->str); + uprv_strncat(buffer, l->str,1020); } if(l->str[uprv_strlen(l->str)-1] != '"') { uprv_strcat(buffer, "\""); @@ -54,6 +56,7 @@ const char *pkg_writeCharListWrap(FileStream *s, CharList *l, const char *delim, ln += uprv_strlen(l->str); + ol = l; if(l->next && delim) { diff --git a/icu4c/source/tools/pkgdata/sttcmode.c b/icu4c/source/tools/pkgdata/sttcmode.c index 863daba2edd..8c2fd981d81 100644 --- a/icu4c/source/tools/pkgdata/sttcmode.c +++ b/icu4c/source/tools/pkgdata/sttcmode.c @@ -280,8 +280,11 @@ void pkg_mode_static(UPKGOptions *o, FileStream *makefile, UErrorCode *status) T_FileStream_writeLine(makefile, "install: $(TARG_PATH)$(LIB_TARGET)\n" "\t$(INSTALL-L) $(TARG_PATH)$(LIB_TARGET) $(INSTALLTO)/$(LIB_TARGET)\n"); + T_FileStream_writeLine(makefile, "\t$(RANLIB) $(INSTALLTO)/$(LIB_TARGET)\n"); if (o->version) { T_FileStream_writeLine(makefile, "\tcd $(INSTALLTO) && $(RM) $(MIDDLE_STATIC_LIB_TARGET) && ln -s $(LIB_TARGET) $(MIDDLE_STATIC_LIB_TARGET)\n\tcd $(INSTALLTO) && $(RM) $(STATIC_LIB_TARGET) && ln -s $(LIB_TARGET) $(STATIC_LIB_TARGET)\n"); + T_FileStream_writeLine(makefile, "\t$(RANLIB) $(INSTALLTO)/$(STATIC_LIB_TARGET)\n\n"); + } *status = U_ZERO_ERROR;