diff --git a/icu4c/source/common/udata.c b/icu4c/source/common/udata.c index 2712e76c269..470d8153098 100644 --- a/icu4c/source/common/udata.c +++ b/icu4c/source/common/udata.c @@ -35,6 +35,12 @@ #define COMMON_DATA_NAME_LENGTH 8 /* Tests must verify that it remains 8 characters. */ +#ifdef OS390 +#define COMMON_DATA1_NAME "icudata390" +#define COMMON_DATA1_NAME_LENGTH 10 +static UBool s390dll = TRUE; +#endif + #define DATA_TYPE "dat" /* If you are excruciatingly bored turn this on .. */ @@ -114,44 +120,44 @@ # include void *dlopen (const char *filename, int flag) { - void *handle; /* real type: 'shl_t' */ + void *handle; /* real type: 'shl_t' */ # ifdef UDATA_DEBUG - fprintf(stderr, "shl_load: %s ", filename); + fprintf(stderr, "shl_load: %s ", filename); # endif - handle=shl_load(filename, BIND_NONFATAL | BIND_DEFERRED | DYNAMIC_PATH, 0L); + handle=shl_load(filename, BIND_NONFATAL | BIND_DEFERRED | DYNAMIC_PATH, 0L); # ifdef UDATA_DEBUG - fprintf(stderr, " -> %08X\n", handle ); + fprintf(stderr, " -> %08X\n", handle ); # endif - return handle; + return handle; } void *dlsym(void *h, char *symbol) { - void *val=0; - int rv; - shl_t mysh; + void *val=0; + int rv; + shl_t mysh; - mysh=(shl_t)h; /* real type */ + mysh=(shl_t)h; /* real type */ - rv=shl_findsym(&mysh, symbol, TYPE_DATA, (void*)&val); + rv=shl_findsym(&mysh, symbol, TYPE_DATA, (void*)&val); # ifdef UDATA_DEBUG - fprintf(stderr, "shl_findsym(%08X, %s) -> %08X [%d]\n", h, symbol, val, rv); + fprintf(stderr, "shl_findsym(%08X, %s) -> %08X [%d]\n", h, symbol, val, rv); # endif - return val; + return val; } int dlclose (void *handle) { # ifndef HPUX # ifdef UDATA_DEBUG - fprintf(stderr, "shl_unload: %08X\n", handle); + fprintf(stderr, "shl_unload: %08X\n", handle); # endif - return shl_unload((shl_t)handle); + return shl_unload((shl_t)handle); # else - /* "shl_unload .. always unloads the library.. no refcount is kept on PA32" - -- HPUX man pages [v. 11] + /* "shl_unload .. always unloads the library.. no refcount is kept on PA32" + -- HPUX man pages [v. 11] - Fine, we'll leak! [for now.. Jitterbug 414 has been filed ] - */ - return 0; + Fine, we'll leak! [for now.. Jitterbug 414 has been filed ] + */ + return 0; # endif /* HPUX */ } # endif /* HPUX shl_load */ @@ -327,18 +333,18 @@ typedef struct { uprv_mapFile(UDataMemory *pData, const char *path, const char *basename) { char buffer[200]; HANDLE map; - char *p; + char *p; /* set up the mapping name and the filename */ uprv_strcpy(buffer, "icu" U_ICU_VERSION " "); uprv_strcat(buffer, path); - - /* replace in buffer \ with / */ - for(p=buffer; *p; p++) { - if (*p == '\\') { - *p = '/'; - } - } + + /* replace in buffer \ with / */ + for(p=buffer; *p; p++) { + if (*p == '\\') { + *p = '/'; + } + } /* open the mapping */ map=OpenFileMapping(FILE_MAP_READ, FALSE, buffer); @@ -514,10 +520,11 @@ offsetTOCLookupFn(const UDataMemory *pData, const char *tocEntryName, const char *dllEntryName, UErrorCode *pErrorCode) { + #ifdef UDATA_DEBUG fprintf(stderr, "offsetTOC[%p] looking for %s/%s\n", - pData, - tocEntryName,dllEntryName); + pData, + tocEntryName,dllEntryName); #endif if(pData->toc!=NULL) { @@ -540,18 +547,18 @@ offsetTOCLookupFn(const UDataMemory *pData, if(uprv_strcmp(tocEntryName, base+toc[2*start])==0) { /* found it */ #ifdef UDATA_DEBUG - fprintf(stderr, "Found: %p\n",(base+toc[2*start+1])); + fprintf(stderr, "Found: %p\n",(base+toc[2*start+1])); #endif return (const DataHeader *)(base+toc[2*start+1]); } else { #ifdef UDATA_DEBUG - fprintf(stderr, "Not found.\n"); + fprintf(stderr, "Not found.\n"); #endif return NULL; } } else { #ifdef UDATA_DEBUG - fprintf(stderr, "returning header\n"); + fprintf(stderr, "returning header\n"); #endif return pData->pHeader; @@ -565,8 +572,8 @@ pointerTOCLookupFn(const UDataMemory *pData, UErrorCode *pErrorCode) { #ifdef UDATA_DEBUG fprintf(stderr, "ptrTOC[%p] looking for %s/%s\n", - pData, - tocEntryName,dllEntryName); + pData, + tocEntryName,dllEntryName); #endif if(pData->toc!=NULL) { const PointerTOCEntry *toc=(const PointerTOCEntry *)((const uint32_t *)pData->toc+2); @@ -577,8 +584,8 @@ pointerTOCLookupFn(const UDataMemory *pData, limit=*(const uint32_t *)pData->toc; /* number of names in this table of contents */ #ifdef UDATA_DEBUG - fprintf(stderr, " # of ents: %d\n", limit); - fflush(stderr); + fprintf(stderr, " # of ents: %d\n", limit); + fflush(stderr); #endif while(startpHeader; + return pData->pHeader; } } @@ -627,7 +634,7 @@ dllTOCLookupFn(const UDataMemory *pData, /* common library functions ------------------------------------------------- */ - static UDataMemory commonICUData={ NULL }; +static UDataMemory commonICUData={ NULL }; static void setCommonICUData(UDataMemory *pData) { @@ -730,6 +737,11 @@ openCommonData(UDataMemory *pData, /* set up path and basename */ basename=setPathGetBasename(path, pathBuffer); if(isICUData) { +#ifdef OS390 + if (s390dll) + inBasename=COMMON_DATA1_NAME; + else +#endif inBasename=COMMON_DATA_NAME; } else { inBasename=findBasename(path); @@ -756,7 +768,14 @@ openCommonData(UDataMemory *pData, /* ### hack: we still need to get u_getDataDirectory() fixed for OS/390 (batch mode - always return "//"? ) and this here straightened out with LIB_PREFIX and LIB_SUFFIX (both empty?!) */ - lib=LOAD_LIBRARY("//" U_ICUDATA_NAME, "//" U_ICUDATA_NAME); + if (s390dll) { + lib=LOAD_LIBRARY("//IXMICUD1", "//IXMICUD1"); + } + else { + /* U_ICUDATA_NAME should always have the correct name */ + lib=LOAD_LIBRARY("//" U_ICUDATA_NAME, "//" U_ICUDATA_NAME); +/* lib=LOAD_LIBRARY("//IXMICUDA", "//IXMICUDA");*/ + } # else lib=LOAD_LIBRARY(pathBuffer, basename); # endif @@ -988,6 +1007,63 @@ doOpenChoice(const char *path, const char *type, const char *name, /* set up the ToC names for DLL and offset-ToC lookups */ setEntryNames(type, name, tocEntryName, dllEntryName); +#ifdef OS390 + if(s390dll == TRUE) + { + /* try to get high frequency S390 common data first */ + uprv_memset(&dataMemory, 0, sizeof(UDataMemory)); + pathBuffer[0]=0; + pCommonData=openCommonData(&dataMemory, path, isICUData, pathBuffer, &errorCode); + if(U_SUCCESS(errorCode)) { + /* look up the data piece in the common data */ + pHeader=pCommonData->lookupFn(pCommonData, tocEntryName, dllEntryName, &errorCode); + if(pHeader!=NULL) { + /* data found in the common data, test it */ + if(pHeader->dataHeader.magic1==0xda && pHeader->dataHeader.magic2==0x27 && + pHeader->info.isBigEndian==U_IS_BIG_ENDIAN && + (isAcceptable==NULL || isAcceptable(context, type, name, &pHeader->info)) + ) { + /* acceptable - allocate parent, too, if necessary */ + if(pCommonData==&dataMemory) { + /* trick: do one malloc for both the common and the entry */ + pEntryData=(UDataMemory *)uprv_malloc(2*sizeof(UDataMemory)); + if(pEntryData!=NULL) { + pCommonData=pEntryData+1; + uprv_memcpy(pCommonData, &dataMemory, sizeof(UDataMemory)); + } + } else { + pEntryData=(UDataMemory *)uprv_malloc(sizeof(UDataMemory)); + } + if(pEntryData==NULL) { + *pErrorCode=U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + uprv_memset(pEntryData, 0, sizeof(UDataMemory)); + pEntryData->parent=pCommonData; + pEntryData->pHeader=pHeader; + pEntryData->flags=pCommonData->flags&DATA_MEMORY_TYPE_MASK|1UL<flags = 0; + /* clear out the 'mini cache' used in openCommonData */ + /* This is not thread safe!!!!!!! */ + } + } + s390dll=FALSE; + (&commonICUData)->flags = 0 ; + } +#endif + /* try to get common data */ uprv_memset(&dataMemory, 0, sizeof(UDataMemory)); pathBuffer[0]=0; @@ -1001,7 +1077,7 @@ doOpenChoice(const char *path, const char *type, const char *name, /* look up the data piece in the common data */ pHeader=pCommonData->lookupFn(pCommonData, tocEntryName, dllEntryName, &errorCode); #ifdef UDATA_DEBUG - fprintf(stderr, "Common found: %p\n", pHeader); + fprintf(stderr, "Common found: %p\n", pHeader); #endif if(pHeader!=NULL) { /* data found in the common data, test it */ @@ -1029,13 +1105,13 @@ doOpenChoice(const char *path, const char *type, const char *name, pEntryData->pHeader=pHeader; pEntryData->flags=(pCommonData->flags&DATA_MEMORY_TYPE_MASK)|1UL<