mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 06:25:30 +00:00
ICU-1075 Data updates. Unix ports (not complete) and Common Data Caching impl.
X-SVN-Rev: 5454
This commit is contained in:
parent
f255a31517
commit
19b4dec854
21 changed files with 622 additions and 541 deletions
|
@ -38,7 +38,7 @@ include @platform_make_fragment@
|
|||
CLEANFILES = *~
|
||||
|
||||
DOCDIRS = common i18n
|
||||
SUBDIRS = common i18n $(EXTRA) $(LAYOUT) tools data $(TEST) $(SAMPLE)
|
||||
SUBDIRS = stubdata common i18n $(EXTRA) $(LAYOUT) tools data $(TEST) $(SAMPLE)
|
||||
|
||||
## Extra files to install [nothing at present]
|
||||
EXTRA_DATA =
|
||||
|
|
|
@ -61,8 +61,10 @@ ENABLE_RPATH = @ENABLE_RPATH@
|
|||
ifeq ($(ENABLE_RPATH),YES)
|
||||
RPATHLDFLAGS = $(LD_RPATH)$(LD_RPATH_PRE)$(libdir)
|
||||
endif
|
||||
|
||||
# todo: need t make $(LIBICUDT) conditional on using dll-based data.
|
||||
LDFLAGS = @LDFLAGS@ $(RPATHLDFLAGS)
|
||||
LIBS = @LIBS@
|
||||
LIBS = $(LIBICUDT) @LIBS@
|
||||
|
||||
# Data packaging options are set at configure time with --with-data-packaging.
|
||||
CPPFLAGS += @DATA_PACKAGING_CPPFLAGS@
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "cstring.h"
|
||||
#include "unicode/udata.h"
|
||||
#include "unicode/uversion.h"
|
||||
#include "uhash.h"
|
||||
|
||||
#ifdef OS390
|
||||
#include <stdlib.h>
|
||||
|
@ -236,8 +237,8 @@ static UBool s390dll = TRUE;
|
|||
therefore they are defined later
|
||||
*/
|
||||
|
||||
#define MAP_WIN32 1
|
||||
#define MAP_POSIX 2
|
||||
#define MAP_WIN32 1
|
||||
#define MAP_POSIX 2
|
||||
#define MAP_FILE_STREAM 3
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -283,34 +284,37 @@ static UBool s390dll = TRUE;
|
|||
|
||||
/* constants for UDataMemory flags: type of data memory */
|
||||
enum {
|
||||
NO_DATA_MEMORY,
|
||||
FLAT_DATA_MEMORY,
|
||||
DLL_DATA_MEMORY
|
||||
NO_DATA_MEMORY = 0,
|
||||
FLAT_DATA_MEMORY = 1,
|
||||
DLL_DATA_MEMORY = 2
|
||||
};
|
||||
#define DATA_MEMORY_TYPE_MASK 0xf
|
||||
|
||||
/* constants for UDataMemory flags: type of TOC */
|
||||
enum {
|
||||
NO_TOC,
|
||||
OFFSET_TOC,
|
||||
POINTER_TOC,
|
||||
DLL_INTRINSIC_TOC
|
||||
NO_TOC =0x00,
|
||||
OFFSET_TOC =0x10,
|
||||
POINTER_TOC =0x20,
|
||||
DLL_INTRINSIC_TOC =0x30
|
||||
};
|
||||
#define TOC_TYPE_MASK 0xf0
|
||||
|
||||
/* constants for UDataMemory flags: type of TOC */
|
||||
#define DATA_MEMORY_TYPE_MASK 0xf
|
||||
#define TOC_TYPE_SHIFT 4
|
||||
#define TOC_TYPE_MASK 0xf
|
||||
#define SET_DATA_POINTER_SHIFT 30
|
||||
#define DYNAMIC_DATA_MEMORY_SHIFT 31
|
||||
#define SET_DATA_POINTER_FLAG 0x40000000
|
||||
#define DYNAMIC_DATA_MEMORY_FLAG 0x80000000
|
||||
|
||||
typedef struct {
|
||||
uint16_t headerSize;
|
||||
uint8_t magic1, magic2;
|
||||
#define IS_DATA_MEMORY_LOADED(pData) ((pData)->flags!=0)
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t headerSize;
|
||||
uint8_t magic1;
|
||||
uint8_t magic2;
|
||||
} MappedData;
|
||||
|
||||
typedef struct {
|
||||
MappedData dataHeader;
|
||||
UDataInfo info;
|
||||
typedef struct {
|
||||
MappedData dataHeader;
|
||||
UDataInfo info;
|
||||
} DataHeader;
|
||||
|
||||
typedef const DataHeader *
|
||||
|
@ -319,67 +323,90 @@ LookupFn(const UDataMemory *pData,
|
|||
const char *dllEntryName,
|
||||
UErrorCode *pErrorCode);
|
||||
|
||||
struct UDataMemory {
|
||||
UDataMemory *parent;
|
||||
Library lib;
|
||||
MemoryMap map;
|
||||
LookupFn *lookupFn;
|
||||
const void *toc;
|
||||
const DataHeader *pHeader;
|
||||
uint32_t flags;
|
||||
int32_t refCount;
|
||||
};
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* *
|
||||
* UDataMemory Very Important Struct. Pointers to these are returned *
|
||||
* to callers from the various data open functions. *
|
||||
* These keep track of everything about the memeory *
|
||||
* *
|
||||
*----------------------------------------------------------------------------------*/
|
||||
typedef struct UDataMemory {
|
||||
UDataMemory *parent; /* Set if we're suballocated from some common */
|
||||
Library lib; /* OS dependent handle for DLLs, .so, etc */
|
||||
MemoryMap map; /* Handle, or whatever. OS dependent. */
|
||||
LookupFn *lookupFn;
|
||||
const void *toc; /* For common memory, to find pieces within. */
|
||||
const DataHeader *pHeader; /* Header. For common data, header is at top of file */
|
||||
uint32_t flags; /* Memory format, TOC type, Allocation type, etc. */
|
||||
int32_t refCount; /* Not used just yet... */
|
||||
} UDataMemory;
|
||||
|
||||
#define IS_DATA_MEMORY_LOADED(pData) ((pData)->flags!=0)
|
||||
|
||||
static void UDataMemory_init(UDataMemory *This) {
|
||||
uprv_memset(This, 0, sizeof(UDataMemory));
|
||||
}
|
||||
|
||||
|
||||
static void UDataMemory_copy(UDataMemory *dest, UDataMemory *source) {
|
||||
uprv_memcpy(dest, source, sizeof(UDataMemory));
|
||||
}
|
||||
|
||||
static UDataMemory *UDataMemory_createNewInstance() {
|
||||
UDataMemory *This;
|
||||
This = uprv_malloc(sizeof(UDataMemory));
|
||||
UDataMemory_init(This);
|
||||
return This;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Pointer TOCs. This form of table-of-contents should be removed because *
|
||||
* DLLs must be relocated on loading to correct the pointer values *
|
||||
* and this operation makes shared memory mapping of the data *
|
||||
* much less likely to work. *
|
||||
* *
|
||||
*----------------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
const char *entryName;
|
||||
const DataHeader *pHeader;
|
||||
} PointerTOCEntry;
|
||||
|
||||
/* memory-mapping base functions -------------------------------------------- */
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Memory Mapped File support. Platform dependent implementation of functions *
|
||||
* used by the rest of the implementation. *
|
||||
* *
|
||||
*----------------------------------------------------------------------------------*/
|
||||
#if MAP_IMPLEMENTATION==MAP_WIN32
|
||||
static UBool
|
||||
uprv_mapFile(UDataMemory *pData, const char *path, const char *basename) {
|
||||
char buffer[200];
|
||||
uprv_mapFile(
|
||||
UDataMemory *pData, /* Fill in with info on the result doing the mapping. */
|
||||
/* Output only; any original contents are cleared. */
|
||||
const char *path /* File path to be opened/mapped */
|
||||
)
|
||||
{
|
||||
HANDLE map;
|
||||
char *p;
|
||||
HANDLE file;
|
||||
|
||||
UDataMemory_init(pData); /* Clear the output struct. */
|
||||
|
||||
/* 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 = '/';
|
||||
}
|
||||
/* open the input file */
|
||||
file=CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, NULL);
|
||||
if(file==INVALID_HANDLE_VALUE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* open the mapping */
|
||||
map=OpenFileMapping(FILE_MAP_READ, FALSE, buffer);
|
||||
|
||||
/* create an unnamed Windows file-mapping object for the specified file */
|
||||
map=CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
CloseHandle(file);
|
||||
if(map==NULL) {
|
||||
/* the mapping has not been created */
|
||||
HANDLE file;
|
||||
|
||||
/* open the input file */
|
||||
file=CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, NULL);
|
||||
if(file==INVALID_HANDLE_VALUE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* create the mapping */
|
||||
map=CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, buffer);
|
||||
CloseHandle(file);
|
||||
if(map==NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get a view of the mapping */
|
||||
|
||||
/* map a view of the file into our address space */
|
||||
pData->pHeader=(const DataHeader *)MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
|
||||
if(pData->pHeader==NULL) {
|
||||
CloseHandle(map);
|
||||
|
@ -390,6 +417,7 @@ typedef struct {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
uprv_unmapFile(UDataMemory *pData) {
|
||||
if(pData!=NULL && pData->map!=NULL) {
|
||||
|
@ -402,12 +430,14 @@ typedef struct {
|
|||
|
||||
#elif MAP_IMPLEMENTATION==MAP_POSIX
|
||||
static UBool
|
||||
uprv_mapFile(UDataMemory *pData, const char *path, const char *basename) {
|
||||
uprv_mapFile(UDataMemory *pData, const char *path) {
|
||||
int fd;
|
||||
int length;
|
||||
struct stat mystat;
|
||||
const void *data;
|
||||
|
||||
UDataMemory_init(pData); /* Clear the output struct. */
|
||||
|
||||
/* determine the length of the file */
|
||||
if(stat(path, &mystat)!=0 || mystat.st_size<=0) {
|
||||
return FALSE;
|
||||
|
@ -462,11 +492,12 @@ typedef struct {
|
|||
|
||||
#elif MAP_IMPLEMENTATION==MAP_FILE_STREAM
|
||||
static UBool
|
||||
uprv_mapFile(UDataMemory *pData, const char *path, const char *basename) {
|
||||
uprv_mapFile(UDataMemory *pData, const char *path) {
|
||||
FileStream *file;
|
||||
int32_t fileLength;
|
||||
void *p;
|
||||
|
||||
UDataMemory_init(pData); /* Clear the output struct. */
|
||||
/* open the input file */
|
||||
file=T_FileStream_open(path, "rb");
|
||||
if(file==NULL) {
|
||||
|
@ -513,8 +544,13 @@ typedef struct {
|
|||
# error MAP_IMPLEMENTATION is set incorrectly
|
||||
#endif
|
||||
|
||||
/* entry point lookup implementations --------------------------------------- */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* *
|
||||
* entry point lookup implementations *
|
||||
* *
|
||||
*----------------------------------------------------------------------------------*/
|
||||
static const DataHeader *
|
||||
normalizeDataPointer(const DataHeader *p) {
|
||||
/* allow the data to be optionally prepended with an alignment-forcing double value */
|
||||
|
@ -658,7 +694,7 @@ setCommonICUData(UDataMemory *pData) {
|
|||
umtx_lock(NULL);
|
||||
if(!IS_DATA_MEMORY_LOADED(&commonICUData)) {
|
||||
uprv_memcpy(&commonICUData, pData, sizeof(UDataMemory));
|
||||
commonICUData.flags&=~(1UL<<DYNAMIC_DATA_MEMORY_SHIFT);
|
||||
commonICUData.flags&=~DYNAMIC_DATA_MEMORY_FLAG;
|
||||
uprv_memset(pData, 0, sizeof(UDataMemory));
|
||||
setThisLib=TRUE;
|
||||
}
|
||||
|
@ -679,10 +715,19 @@ strcpy_returnEnd(char *dest, const char *src) {
|
|||
return dest;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------*
|
||||
* *
|
||||
* setPathGetBasename given a (possibly partial) path of an item *
|
||||
* to be opened, compute a full directory path and leave *
|
||||
* it in pathBuffer. Returns a pointer to the null at *
|
||||
* the end of the computed path. *
|
||||
* If a non-empty path buffer is passed in, assume that *
|
||||
* it already contains the right result, and don't *
|
||||
* bother to figure it all out again. *
|
||||
* *
|
||||
*------------------------------------------------------------------------------*/
|
||||
static char *
|
||||
setPathGetBasename(const char *path, char *pathBuffer) {
|
||||
/* set up the path in the pathBuffer and return a pointer behind its end,
|
||||
to where the basename will go */
|
||||
if(*pathBuffer!=0) {
|
||||
/* the pathBuffer is already filled,
|
||||
we just need to find the basename position;
|
||||
|
@ -731,6 +776,96 @@ findBasename(const char *path) {
|
|||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------*
|
||||
* *
|
||||
* Cache for common data *
|
||||
* Functions for looking up or adding entries to a cache of *
|
||||
* data that has been previously opened. Avoids a potentially *
|
||||
* expensive operation of re-opening the data for subsequent *
|
||||
* uses. *
|
||||
* *
|
||||
* Data remains cached for the duration of the process. *
|
||||
* *
|
||||
*----------------------------------------------------------------------*/
|
||||
|
||||
typedef struct DataCacheElement {
|
||||
char *path;
|
||||
UDataMemory item;
|
||||
} DataCacheElement;
|
||||
|
||||
/* udata_getCacheHashTable()
|
||||
* Get the hash table used to store the data cache entries.
|
||||
* Lazy create it if it doesn't yet exist.
|
||||
*/
|
||||
static UHashtable *udata_getHashTable() {
|
||||
static UHashtable *gHashTable;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
|
||||
if (gHashTable != NULL) {
|
||||
return gHashTable;
|
||||
}
|
||||
umtx_lock(NULL);
|
||||
if (gHashTable == NULL) {
|
||||
gHashTable = uhash_open(uhash_hashChars, uhash_compareChars, &err);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
|
||||
if U_FAILURE(err) {
|
||||
return NULL;
|
||||
}
|
||||
return gHashTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static UDataMemory *udata_findCachedData(const char *path)
|
||||
{
|
||||
UHashtable *htable;
|
||||
UDataMemory *retVal;
|
||||
|
||||
umtx_lock(NULL);
|
||||
htable = udata_getHashTable();
|
||||
umtx_unlock(NULL);
|
||||
retVal = (UDataMemory *)uhash_get(htable, path);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
static UDataMemory *udata_cacheDataItem(const char *path, UDataMemory *item) {
|
||||
DataCacheElement *newElement;
|
||||
int pathLen;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
|
||||
/* Create a new DataCacheElement - the thingy we store in the hash table -
|
||||
* and copy the supplied path and UDataMemoryItems into it.
|
||||
*/
|
||||
newElement = uprv_malloc(sizeof(DataCacheElement));
|
||||
UDataMemory_copy(&newElement->item, item);
|
||||
newElement->item.flags &= ~DYNAMIC_DATA_MEMORY_FLAG;
|
||||
pathLen = uprv_strlen(path);
|
||||
newElement->path = uprv_malloc(pathLen+1);
|
||||
uprv_strcpy(newElement->path, path);
|
||||
|
||||
/* Stick the new DataCacheElement into the hash table.
|
||||
*/
|
||||
umtx_lock(NULL);
|
||||
uhash_put(udata_getHashTable(),
|
||||
newElement->path, /* Key */
|
||||
&newElement->item, /* Value */
|
||||
&err);
|
||||
umtx_unlock(NULL);
|
||||
/* Just ignore any error returned.
|
||||
* 1. Failure to add to the cache is not, by itself, fatal.
|
||||
* 2. The only reason the hash table would fail is if memory
|
||||
* allocation fails, which means complete death is just
|
||||
* around the corner anyway...
|
||||
*/
|
||||
|
||||
return &newElement->item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* */
|
||||
/* Add a static reference to the common data from a library if the */
|
||||
/* build options are set to request it. */
|
||||
|
@ -740,24 +875,51 @@ findBasename(const char *path) {
|
|||
extern const DataHeader U_IMPORT U_ICUDATA_ENTRY_POINT;
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------*
|
||||
* *
|
||||
* openCommonData Attempt to open a common format (.dat) file *
|
||||
* Map it into memory (if it's not there already) *
|
||||
* and return a UDataMemory object for it. *
|
||||
* The UDataMemory object will either be heap or *
|
||||
* global - in either case, it is permanent and can *
|
||||
* be safely passed back the chain of callers. *
|
||||
* *
|
||||
*----------------------------------------------------------------------*/
|
||||
static UDataMemory *
|
||||
openCommonData(UDataMemory *pData,
|
||||
const char *path, UBool isICUData,
|
||||
char *pathBuffer,
|
||||
UErrorCode *pErrorCode) {
|
||||
openCommonData(
|
||||
const char *path, /* Path from OpenCHoice? */
|
||||
UBool isICUData, /* ICU Data true if path == NULL */
|
||||
UErrorCode *pErrorCode)
|
||||
{
|
||||
const char *inBasename;
|
||||
char *basename, *suffix;
|
||||
const DataHeader *pHeader;
|
||||
char pathBuffer[1024];
|
||||
UDataMemory tData;
|
||||
|
||||
UDataMemory_init(&tData);
|
||||
|
||||
|
||||
/* "mini-cache" for common ICU data */
|
||||
if(isICUData && IS_DATA_MEMORY_LOADED(&commonICUData)) {
|
||||
return &commonICUData;
|
||||
}
|
||||
|
||||
/* ### we should have a real cache with a UHashTable and the path as the key */
|
||||
|
||||
#if defined(UDATA_STATIC_LIB) || defined(UDATA_DLL)
|
||||
/* Is this data cached? Meaning, have we seen this before */
|
||||
if (!isICUData) {
|
||||
UDataMemory *dataToReturn = udata_findCachedData(path);
|
||||
if (dataToReturn != NULL) {
|
||||
return dataToReturn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isICUData) {
|
||||
/* ICU common data is already in our address space, thanks to a static reference */
|
||||
/* to a symbol from the data library. Just follow that pointer to set up */
|
||||
/* our ICU data. */
|
||||
pHeader = &U_ICUDATA_ENTRY_POINT;
|
||||
if(!(pHeader->dataHeader.magic1==0xda && pHeader->dataHeader.magic2==0x27 &&
|
||||
pHeader->info.isBigEndian==U_IS_BIG_ENDIAN &&
|
||||
|
@ -775,10 +937,10 @@ openCommonData(UDataMemory *pData,
|
|||
pHeader->info.formatVersion[0]==1
|
||||
) {
|
||||
/* dataFormat="CmnD" */
|
||||
pData->lib=NULL;
|
||||
pData->lookupFn=offsetTOCLookupFn;
|
||||
pData->toc=(const char *)pHeader+pHeader->dataHeader.headerSize;
|
||||
pData->flags=DLL_DATA_MEMORY|OFFSET_TOC<<TOC_TYPE_SHIFT;
|
||||
tData.lib=NULL;
|
||||
tData.lookupFn=offsetTOCLookupFn;
|
||||
tData.toc=(const char *)pHeader+pHeader->dataHeader.headerSize;
|
||||
tData.flags= DLL_DATA_MEMORY | OFFSET_TOC;
|
||||
} else if(pHeader->info.dataFormat[0]==0x54 &&
|
||||
pHeader->info.dataFormat[1]==0x6f &&
|
||||
pHeader->info.dataFormat[2]==0x43 &&
|
||||
|
@ -786,10 +948,10 @@ openCommonData(UDataMemory *pData,
|
|||
pHeader->info.formatVersion[0]==1
|
||||
) {
|
||||
/* dataFormat="ToCP" */
|
||||
pData->lib=NULL;
|
||||
pData->lookupFn=pointerTOCLookupFn;
|
||||
pData->toc=(const char *)pHeader+pHeader->dataHeader.headerSize;
|
||||
pData->flags=DLL_DATA_MEMORY|POINTER_TOC<<TOC_TYPE_SHIFT;
|
||||
tData.lib=NULL;
|
||||
tData.lookupFn=pointerTOCLookupFn;
|
||||
tData.toc=(const char *)pHeader+pHeader->dataHeader.headerSize;
|
||||
tData.flags=DLL_DATA_MEMORY|POINTER_TOC;
|
||||
} else {
|
||||
/* dataFormat not recognized */
|
||||
*pErrorCode=U_INVALID_FORMAT_ERROR;
|
||||
|
@ -797,23 +959,16 @@ openCommonData(UDataMemory *pData,
|
|||
}
|
||||
|
||||
/* we have common data from a DLL */
|
||||
setCommonICUData(pData);
|
||||
setCommonICUData(&tData);
|
||||
return &commonICUData;
|
||||
}
|
||||
|
||||
|
||||
#endif /*UDATA_STATIC_LIB*/
|
||||
|
||||
|
||||
|
||||
/* set up path and basename */
|
||||
pathBuffer[0] = 0;
|
||||
basename=setPathGetBasename(path, pathBuffer);
|
||||
if(isICUData) {
|
||||
#ifdef OS390
|
||||
if (s390dll)
|
||||
inBasename=COMMON_DATA1_NAME;
|
||||
else
|
||||
#endif
|
||||
inBasename=COMMON_DATA_NAME;
|
||||
} else {
|
||||
inBasename=findBasename(path);
|
||||
|
@ -825,134 +980,21 @@ openCommonData(UDataMemory *pData,
|
|||
}
|
||||
|
||||
|
||||
/* */
|
||||
/* Deprecated code to dynamically load a DLL. */
|
||||
/* */
|
||||
|
||||
/* try to load a common data DLL */
|
||||
# if !UDATA_NO_DLL
|
||||
{
|
||||
Library lib;
|
||||
/* set up the library name */
|
||||
# ifndef LIB_PREFIX
|
||||
suffix=strcpy_returnEnd(basename, inBasename);
|
||||
# else
|
||||
uprv_memcpy(basename, LIB_PREFIX, LIB_PREFIX_LENGTH);
|
||||
suffix=strcpy_returnEnd(basename+LIB_PREFIX_LENGTH, inBasename);
|
||||
# endif
|
||||
uprv_strcpy(suffix, LIB_SUFFIX);
|
||||
|
||||
/* try path/basename first */
|
||||
# ifdef OS390BATCH
|
||||
/* ### 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?!)
|
||||
This is probably due to the strange file system on OS/390. It's more like
|
||||
a database with short entry names than a typical file system. */
|
||||
if (s390dll) {
|
||||
lib=LOAD_LIBRARY("//IXMICUD1", "//IXMICUD1");
|
||||
}
|
||||
else {
|
||||
/* U_ICUDATA_NAME should always have the correct name */
|
||||
/* 390port: BUT FOR BATCH MODE IT IS AN EXCEPTION ... */
|
||||
/* 390port: THE NEXT LINE OF CODE WILL NOT WORK !!!!! */
|
||||
/*lib=LOAD_LIBRARY("//" U_ICUDATA_NAME, "//" U_ICUDATA_NAME);*/
|
||||
lib=LOAD_LIBRARY("//IXMICUDA", "//IXMICUDA"); /*390port*/
|
||||
}
|
||||
# else
|
||||
lib=LOAD_LIBRARY(pathBuffer, basename);
|
||||
# endif
|
||||
if(!IS_LIBRARY(lib) && basename!=pathBuffer) {
|
||||
/* try basename only next */
|
||||
lib=LOAD_LIBRARY(basename, basename);
|
||||
}
|
||||
|
||||
if(IS_LIBRARY(lib)) {
|
||||
/* we have a data DLL - what kind of lookup do we need here? */
|
||||
char entryName[100];
|
||||
*basename=0;
|
||||
|
||||
/* try to find the Table of Contents */
|
||||
#if 0
|
||||
if(uprv_strcmp(inBasename, U_ICUDATA_NAME) == 0) {
|
||||
uprv_strcpy(entryName, "icudata");
|
||||
} else {
|
||||
uprv_strcpy(entryName, inBasename);
|
||||
}
|
||||
#endif
|
||||
uprv_strcpy(entryName, inBasename);
|
||||
|
||||
uprv_strcat(entryName, "_" DATA_TYPE);
|
||||
pHeader=normalizeDataPointer((const DataHeader *)GET_LIBRARY_ENTRY(lib, entryName));
|
||||
if(pHeader==NULL) {
|
||||
/* no TOC: assume DLL-intrinsic lookup */
|
||||
pData->lib=lib;
|
||||
pData->lookupFn=dllTOCLookupFn;
|
||||
pData->flags=DLL_DATA_MEMORY|DLL_INTRINSIC_TOC<<TOC_TYPE_SHIFT;
|
||||
} else if(!(pHeader->dataHeader.magic1==0xda && pHeader->dataHeader.magic2==0x27 &&
|
||||
pHeader->info.isBigEndian==U_IS_BIG_ENDIAN &&
|
||||
pHeader->info.charsetFamily==U_CHARSET_FAMILY)
|
||||
) {
|
||||
/* header not valid */
|
||||
UNLOAD_LIBRARY(lib);
|
||||
*pErrorCode=U_INVALID_FORMAT_ERROR;
|
||||
return NULL;
|
||||
|
||||
/* which TOC type? */
|
||||
} else if(pHeader->info.dataFormat[0]==0x43 &&
|
||||
pHeader->info.dataFormat[1]==0x6d &&
|
||||
pHeader->info.dataFormat[2]==0x6e &&
|
||||
pHeader->info.dataFormat[3]==0x44 &&
|
||||
pHeader->info.formatVersion[0]==1
|
||||
) {
|
||||
/* dataFormat="CmnD" */
|
||||
pData->lib=lib;
|
||||
pData->lookupFn=offsetTOCLookupFn;
|
||||
pData->toc=(const char *)pHeader+pHeader->dataHeader.headerSize;
|
||||
pData->flags=DLL_DATA_MEMORY|OFFSET_TOC<<TOC_TYPE_SHIFT;
|
||||
} else if(pHeader->info.dataFormat[0]==0x54 &&
|
||||
pHeader->info.dataFormat[1]==0x6f &&
|
||||
pHeader->info.dataFormat[2]==0x43 &&
|
||||
pHeader->info.dataFormat[3]==0x50 &&
|
||||
pHeader->info.formatVersion[0]==1
|
||||
) {
|
||||
/* dataFormat="ToCP" */
|
||||
pData->lib=lib;
|
||||
pData->lookupFn=pointerTOCLookupFn;
|
||||
pData->toc=(const char *)pHeader+pHeader->dataHeader.headerSize;
|
||||
pData->flags=DLL_DATA_MEMORY|POINTER_TOC<<TOC_TYPE_SHIFT;
|
||||
} else {
|
||||
/* dataFormat not recognized */
|
||||
UNLOAD_LIBRARY(lib);
|
||||
*pErrorCode=U_INVALID_FORMAT_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* we have common data from a DLL */
|
||||
if(isICUData) {
|
||||
setCommonICUData(pData);
|
||||
return &commonICUData;
|
||||
} else {
|
||||
return pData;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* !UDATA_NO_DLL */
|
||||
|
||||
/* try to map a common data file */
|
||||
|
||||
/* set up the file name */
|
||||
suffix=strcpy_returnEnd(basename, inBasename);
|
||||
uprv_strcpy(suffix, "." DATA_TYPE);
|
||||
uprv_strcpy(suffix, "." DATA_TYPE); /* DATA_TYPE is ".dat" */
|
||||
|
||||
/* try path/basename first, then basename only */
|
||||
if( uprv_mapFile(pData, pathBuffer, basename) ||
|
||||
(basename!=pathBuffer && uprv_mapFile(pData, basename, basename))
|
||||
if( uprv_mapFile(&tData, pathBuffer) ||
|
||||
(basename!=pathBuffer && uprv_mapFile(&tData, basename))
|
||||
) {
|
||||
*basename=0;
|
||||
|
||||
/* we have mapped a file, check its header */
|
||||
pHeader=pData->pHeader;
|
||||
pHeader=tData.pHeader;
|
||||
if(!(pHeader->dataHeader.magic1==0xda && pHeader->dataHeader.magic2==0x27 &&
|
||||
pHeader->info.isBigEndian==U_IS_BIG_ENDIAN &&
|
||||
pHeader->info.charsetFamily==U_CHARSET_FAMILY &&
|
||||
|
@ -962,21 +1004,24 @@ openCommonData(UDataMemory *pData,
|
|||
pHeader->info.dataFormat[3]==0x44 &&
|
||||
pHeader->info.formatVersion[0]==1)
|
||||
) {
|
||||
uprv_unmapFile(pData);
|
||||
pData->flags=0;
|
||||
uprv_unmapFile(&tData);
|
||||
tData.flags=0;
|
||||
*pErrorCode=U_INVALID_FORMAT_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* we have common data from a mapped file */
|
||||
pData->lookupFn=offsetTOCLookupFn;
|
||||
pData->toc=(const char *)pHeader+pHeader->dataHeader.headerSize;
|
||||
pData->flags|=OFFSET_TOC<<TOC_TYPE_SHIFT;
|
||||
tData.lookupFn=offsetTOCLookupFn;
|
||||
tData.toc=(const char *)pHeader+pHeader->dataHeader.headerSize;
|
||||
tData.flags|=OFFSET_TOC;
|
||||
if(isICUData) {
|
||||
setCommonICUData(pData);
|
||||
setCommonICUData(&tData);
|
||||
return &commonICUData;
|
||||
} else {
|
||||
return pData;
|
||||
// Cache the UDataMemory struct for this .dat file,
|
||||
// so we won't need to hunt it down and open it again next time
|
||||
// something is needed from it.
|
||||
return udata_cacheDataItem(path, &tData);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1025,7 +1070,7 @@ udata_setCommonData(const void *data, UErrorCode *pErrorCode) {
|
|||
/* dataFormat="CmnD" */
|
||||
dataMemory.lookupFn=offsetTOCLookupFn;
|
||||
dataMemory.toc=(const char *)pHeader+pHeader->dataHeader.headerSize;
|
||||
dataMemory.flags=DLL_DATA_MEMORY|OFFSET_TOC<<TOC_TYPE_SHIFT;
|
||||
dataMemory.flags=DLL_DATA_MEMORY|OFFSET_TOC;
|
||||
} else if(pHeader->info.dataFormat[0]==0x54 &&
|
||||
pHeader->info.dataFormat[1]==0x6f &&
|
||||
pHeader->info.dataFormat[2]==0x43 &&
|
||||
|
@ -1035,7 +1080,7 @@ udata_setCommonData(const void *data, UErrorCode *pErrorCode) {
|
|||
/* dataFormat="ToCP" */
|
||||
dataMemory.lookupFn=pointerTOCLookupFn;
|
||||
dataMemory.toc=(const char *)pHeader+pHeader->dataHeader.headerSize;
|
||||
dataMemory.flags=DLL_DATA_MEMORY|POINTER_TOC<<TOC_TYPE_SHIFT;
|
||||
dataMemory.flags=DLL_DATA_MEMORY|POINTER_TOC;
|
||||
} else {
|
||||
/* dataFormat not recognized */
|
||||
*pErrorCode=U_INVALID_FORMAT_ERROR;
|
||||
|
@ -1043,7 +1088,7 @@ udata_setCommonData(const void *data, UErrorCode *pErrorCode) {
|
|||
}
|
||||
|
||||
/* we have common data */
|
||||
dataMemory.flags|=1UL<<SET_DATA_POINTER_SHIFT;
|
||||
dataMemory.flags|=SET_DATA_POINTER_FLAG;
|
||||
setCommonICUData(&dataMemory);
|
||||
if(dataMemory.flags!=0) {
|
||||
/* some thread passed us */
|
||||
|
@ -1052,6 +1097,21 @@ udata_setCommonData(const void *data, UErrorCode *pErrorCode) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
*
|
||||
* udata_setAppData
|
||||
*
|
||||
*---------------------------------------------------------------------------- */
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
udata_setAppData(const char *path, const void *data, UErrorCode *err)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
/* main data loading function ----------------------------------------------- */
|
||||
|
||||
static void
|
||||
|
@ -1097,67 +1157,10 @@ 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<<DYNAMIC_DATA_MEMORY_SHIFT;
|
||||
return pEntryData;
|
||||
} else {
|
||||
/* the data is not acceptable, look further */
|
||||
errorCode=U_INVALID_FORMAT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* the data is not in the common data, close that and look further */
|
||||
s390dll=FALSE;
|
||||
if(pCommonData==&dataMemory) {
|
||||
udata_close(&dataMemory);
|
||||
/* commonICUData = { NULL }; */
|
||||
(&commonICUData)->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;
|
||||
pCommonData=openCommonData(&dataMemory, path, isICUData, pathBuffer, &errorCode);
|
||||
pCommonData=openCommonData(path, isICUData, &errorCode);
|
||||
#ifdef UDATA_DEBUG
|
||||
fprintf(stderr, "commonData;%p\n", pCommonData);
|
||||
fflush(stderr);
|
||||
|
@ -1172,45 +1175,31 @@ doOpenChoice(const char *path, const char *type, const char *name,
|
|||
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));
|
||||
}
|
||||
pHeader->info.isBigEndian==U_IS_BIG_ENDIAN &&
|
||||
(isAcceptable==NULL || isAcceptable(context, type, name, &pHeader->info))
|
||||
) {
|
||||
pEntryData=UDataMemory_createNewInstance();
|
||||
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<<DYNAMIC_DATA_MEMORY_SHIFT;
|
||||
UDataMemory_init(pEntryData);
|
||||
pEntryData->parent = pCommonData;
|
||||
pEntryData->pHeader = pHeader;
|
||||
pEntryData->flags = (pCommonData->flags&DATA_MEMORY_TYPE_MASK)|DYNAMIC_DATA_MEMORY_FLAG;
|
||||
#ifdef UDATA_DEBUG
|
||||
fprintf(stderr, " made data @%p\n", pEntryData);
|
||||
fprintf(stderr, " made data @%p\n", pEntryData);
|
||||
#endif
|
||||
return pEntryData;
|
||||
} else {
|
||||
/* the data is not acceptable, look further */
|
||||
#ifdef UDATA_DEBUG
|
||||
fprintf(stderr, "Not acceptable\n");
|
||||
#endif
|
||||
/* If we eventually find something good, this errorcode will be */
|
||||
/* cleared out. */
|
||||
errorCode=U_INVALID_FORMAT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* the data is not in the common data, close that and look further */
|
||||
if(pCommonData==&dataMemory) {
|
||||
udata_close(&dataMemory);
|
||||
}
|
||||
/* the data was not found in the common data, look further */
|
||||
}
|
||||
|
||||
/* try to get an individual data file */
|
||||
|
@ -1231,8 +1220,8 @@ doOpenChoice(const char *path, const char *type, const char *name,
|
|||
*suffix++='_';
|
||||
uprv_strcpy(suffix, tocEntryName);
|
||||
|
||||
if( uprv_mapFile(&dataMemory, pathBuffer, basename) ||
|
||||
(basename!=pathBuffer && uprv_mapFile(&dataMemory, basename, basename))
|
||||
if( uprv_mapFile(&dataMemory, pathBuffer) ||
|
||||
(basename!=pathBuffer && uprv_mapFile(&dataMemory, basename))
|
||||
) {
|
||||
pHeader=dataMemory.pHeader;
|
||||
if(pHeader->dataHeader.magic1==0xda && pHeader->dataHeader.magic2==0x27 &&
|
||||
|
@ -1246,7 +1235,7 @@ doOpenChoice(const char *path, const char *type, const char *name,
|
|||
*pErrorCode=U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
dataMemory.flags|=1UL<<DYNAMIC_DATA_MEMORY_SHIFT;
|
||||
dataMemory.flags |= DYNAMIC_DATA_MEMORY_FLAG;
|
||||
uprv_memcpy(pEntryData, &dataMemory, sizeof(UDataMemory));
|
||||
return pEntryData;
|
||||
} else {
|
||||
|
@ -1259,8 +1248,8 @@ doOpenChoice(const char *path, const char *type, const char *name,
|
|||
|
||||
/* try path+entryName next */
|
||||
uprv_strcpy(basename, tocEntryName);
|
||||
if( uprv_mapFile(&dataMemory, pathBuffer, basename) ||
|
||||
(basename!=pathBuffer && uprv_mapFile(&dataMemory, basename, basename))
|
||||
if( uprv_mapFile(&dataMemory, pathBuffer) ||
|
||||
(basename!=pathBuffer && uprv_mapFile(&dataMemory, basename))
|
||||
) {
|
||||
pHeader=dataMemory.pHeader;
|
||||
if(pHeader->dataHeader.magic1==0xda && pHeader->dataHeader.magic2==0x27 &&
|
||||
|
@ -1274,7 +1263,7 @@ doOpenChoice(const char *path, const char *type, const char *name,
|
|||
*pErrorCode=U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
dataMemory.flags|=1UL<<DYNAMIC_DATA_MEMORY_SHIFT;
|
||||
dataMemory.flags |= DYNAMIC_DATA_MEMORY_FLAG;
|
||||
uprv_memcpy(pEntryData, &dataMemory, sizeof(UDataMemory));
|
||||
return pEntryData;
|
||||
} else {
|
||||
|
@ -1299,7 +1288,7 @@ doOpenChoice(const char *path, const char *type, const char *name,
|
|||
|
||||
static void
|
||||
unloadDataMemory(UDataMemory *pData) {
|
||||
if(!(pData->flags&(1UL<<SET_DATA_POINTER_SHIFT))) {
|
||||
if ((pData->flags & SET_DATA_POINTER_FLAG) == 0) {
|
||||
switch(pData->flags&DATA_MEMORY_TYPE_MASK) {
|
||||
case FLAT_DATA_MEMORY:
|
||||
if(IS_MAP(pData->map)) {
|
||||
|
@ -1361,13 +1350,12 @@ udata_close(UDataMemory *pData) {
|
|||
fprintf(stderr, "udata_close()\n");fflush(stderr);
|
||||
#endif
|
||||
|
||||
if(pData!=NULL && IS_DATA_MEMORY_LOADED(pData)) {
|
||||
if(pData!=NULL &&
|
||||
IS_DATA_MEMORY_LOADED(pData)) {
|
||||
// TODO: maybe reference count cached data, rather than just
|
||||
// permanently keeping it around?
|
||||
unloadDataMemory(pData);
|
||||
if(pData->flags&(1UL<<DYNAMIC_DATA_MEMORY_SHIFT)) {
|
||||
if(pData->parent==pData+1) {
|
||||
/* this data entry was allocated together with its parent */
|
||||
unloadDataMemory(pData+1);
|
||||
}
|
||||
if(pData->flags & DYNAMIC_DATA_MEMORY_FLAG ) {
|
||||
uprv_free(pData);
|
||||
} else {
|
||||
pData->flags=0;
|
||||
|
|
|
@ -262,6 +262,32 @@ udata_getInfo(UDataMemory *pData, UDataInfo *pInfo);
|
|||
U_CAPI void U_EXPORT2
|
||||
udata_setCommonData(const void *data, UErrorCode *err);
|
||||
|
||||
|
||||
/**
|
||||
* This function bypasses the normal ICU data loading process for application-specific
|
||||
* data and allows you to force the it to come out of a user-specified
|
||||
* pointer.
|
||||
*
|
||||
* The format of this data is that of the icu common data file, 'icudata.dat'
|
||||
* Read in or memory map the whole file and then pass the address to the start of the
|
||||
* data to this function.
|
||||
*
|
||||
* Warning: setAppData will fail with a U_USING_DEFAULT_ERROR error if
|
||||
* data with the specifed path that has already been opened, or
|
||||
* if setAppData with the same path has already been called.
|
||||
* Any such calls to setAppData will have no effect.
|
||||
*
|
||||
*
|
||||
* @draft
|
||||
* @param path pointer to the path name by which the application will refer
|
||||
* to (open) this data.
|
||||
* @param data pointer to the data
|
||||
* @param err outgoing error status <code>U_USING_DEFAULT_ERROR, U_UNSUPPORTED_ERROR</code>
|
||||
*
|
||||
*/
|
||||
U_CAPI void U_EXPORT2
|
||||
udata_setAppData(const char *path, const void *data, UErrorCode *err);
|
||||
|
||||
U_CDECL_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -117,17 +117,21 @@
|
|||
# if U_IS_BIG_ENDIAN
|
||||
/* EBCDIC - should always be BE */
|
||||
# define U_ICUDATA_TYPE_LETTER "e"
|
||||
# define U_ICUDATA_TYPE_LITLETTER e
|
||||
# else
|
||||
# error "Don't know what to do with little endian EBCDIC!"
|
||||
# define U_ICUDATA_TYPE_LETTER "x"
|
||||
# define U_ICUDATA_TYPE_LITLETTER x
|
||||
# endif
|
||||
#else
|
||||
# if U_IS_BIG_ENDIAN
|
||||
/* Big-endian ASCII */
|
||||
# define U_ICUDATA_TYPE_LETTER "b"
|
||||
# define U_ICUDATA_TYPE_LITLETTER b
|
||||
# else
|
||||
/* Little-endian ASCII */
|
||||
# define U_ICUDATA_TYPE_LETTER "l"
|
||||
# define U_ICUDATA_TYPE_LITLETTER l
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -145,10 +149,18 @@
|
|||
* the literal text U_ICU_VERSION_MAJOR_NUM into the name.
|
||||
* The net result will be something of the form
|
||||
* #define U_ICU_ENTRY_POINT icudt19_dat
|
||||
* Note & TODO: On Unixes, the name includes the endianness letter
|
||||
* e.g. icudt19l_dat. It should be removed, which will
|
||||
* involve doing something in the area of the data build.
|
||||
*/
|
||||
#define U_ICUDATA_ENTRY_POINT U_DEF2_ICUDATA_ENTRY_POINT(U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM)
|
||||
#define U_DEF2_ICUDATA_ENTRY_POINT(major, minor) U_DEF_ICUDATA_ENTRY_POINT(major, minor)
|
||||
#define U_DEF_ICUDATA_ENTRY_POINT(major, minor) icudt##major##minor##_dat
|
||||
#ifdef WIN32
|
||||
#pragma warning( disable : 4003 ) /* Disable 'not enough actual parameters for macro' warning */
|
||||
#define U_ICUDATA_ENTRY_POINT U_DEF2_ICUDATA_ENTRY_POINT(U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM)
|
||||
#else
|
||||
#define U_ICUDATA_ENTRY_POINT U_DEF2_ICUDATA_ENTRY_POINT(U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM, U_ICUDATA_TYPE_LITLETTER)
|
||||
#endif
|
||||
#define U_DEF2_ICUDATA_ENTRY_POINT(major, minor, letter) U_DEF_ICUDATA_ENTRY_POINT(major, minor, letter)
|
||||
#define U_DEF_ICUDATA_ENTRY_POINT(major, minor, letter) icudt##major##minor##letter##_dat
|
||||
|
||||
#if 0
|
||||
#define FOO(X) STRINGIZE(X)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## Copyright (c) 1999-2000, International Business Machines Corporation and
|
||||
## others. All Rights Reserved.
|
||||
##
|
||||
## $Id: mh-aix,v 1.20 2001/07/16 23:34:12 aheninger Exp $
|
||||
## $Id: mh-aix,v 1.21 2001/08/10 20:49:59 aheninger Exp $
|
||||
|
||||
## Commands to generate dependency files
|
||||
GEN_DEPS.c= $(CC) -E -M $(DEFS) $(CPPFLAGS)
|
||||
|
@ -56,7 +56,8 @@ INSTALL-S = $(INSTALL_PROGRAM)
|
|||
INSTALL-L = $(INSTALL_DATA)
|
||||
|
||||
## Link commands to link to ICU libs
|
||||
LIBICUUC= -brtl -L$(top_builddir)/common -l$(ICUPREFIX)uc
|
||||
LIBICUDT= -L$(top_builddir)/data -L$(top_builddir)/stubdata -l$(ICUPREFIX)data
|
||||
LIBICUUC= -brtl -L$(top_builddir)/common -l$(ICUPREFIX)uc $(LIBICUDT)
|
||||
LIBICUI18N= -brtl -L$(top_builddir)/i18n -l$(ICUPREFIX)i18n
|
||||
LIBCTESTFW= -brtl -L$(top_builddir)/tools/ctestfw -lctestfw
|
||||
LIBICUTOOLUTIL= -brtl -L$(top_builddir)/tools/toolutil -l$(ICUPREFIX)toolutil
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## Copyright (c) 1999-2000, International Business Machines Corporation and
|
||||
## others. All Rights Reserved.
|
||||
##
|
||||
## $Id: mh-hpux-acc,v 1.22 2001/07/16 23:34:12 aheninger Exp $
|
||||
## $Id: mh-hpux-acc,v 1.23 2001/08/10 20:49:59 aheninger Exp $
|
||||
|
||||
## Commands to generate dependency files
|
||||
GEN_DEPS.c= :
|
||||
|
@ -54,7 +54,8 @@ INSTALL-S = $(INSTALL_PROGRAM)
|
|||
INSTALL-L = $(INSTALL_DATA)
|
||||
|
||||
## Link commands to link to ICU libs
|
||||
LIBICUUC= -L$(top_builddir)/common -l$(ICUPREFIX)uc
|
||||
LIBICUDT= -L$(top_builddir)/data -L$(top_builddir)/stubdata -l$(ICUPREFIX)data
|
||||
LIBICUUC= -L$(top_builddir)/common -l$(ICUPREFIX)uc $(LIBICUDT)
|
||||
LIBICUI18N= -L$(top_builddir)/i18n -l$(ICUPREFIX)i18n
|
||||
LIBCTESTFW= -L$(top_builddir)/tools/ctestfw -lctestfw
|
||||
LIBICUTOOLUTIL=-L$(top_builddir)/tools/toolutil -l$(ICUPREFIX)toolutil
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## Copyright (c) 1999-2000, International Business Machines Corporation and
|
||||
## others. All Rights Reserved.
|
||||
##
|
||||
## $Id: mh-linux,v 1.23 2000/11/04 02:16:11 srl Exp $
|
||||
## $Id: mh-linux,v 1.24 2001/08/10 20:49:59 aheninger Exp $
|
||||
|
||||
## Commands to generate dependency files
|
||||
GEN_DEPS.c= $(CC) -E -MM $(DEFS) $(CPPFLAGS)
|
||||
|
@ -60,10 +60,11 @@ INSTALL-S = $(INSTALL_PROGRAM)
|
|||
INSTALL-L = $(INSTALL_DATA)
|
||||
|
||||
## Link commands to link to ICU libs
|
||||
LIBICUUC= -L$(top_builddir)/common -l$(ICUPREFIX)uc
|
||||
LIBICUDT= -L$(top_builddir)/data -L$(top_builddir)/stubdata -l$(ICUPREFIX)data
|
||||
LIBICUUC= -L$(top_builddir)/common -l$(ICUPREFIX)uc $(LIBICUDT)
|
||||
LIBICUI18N= -L$(top_builddir)/i18n -l$(ICUPREFIX)i18n
|
||||
LIBCTESTFW= -L$(top_builddir)/tools/ctestfw -lctestfw
|
||||
LIBICUTOOLUTIL=-L$(top_builddir)/tools/toolutil -l$(ICUPREFIX)toolutil
|
||||
LIBICUTOOLUTIL= -L$(top_builddir)/tools/toolutil -l$(ICUPREFIX)toolutil
|
||||
LIBUSTDIO= -L$(top_builddir)/extra/ustdio -lustdio
|
||||
|
||||
## Compilation rules
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## Copyright (c) 1999-2000, International Business Machines Corporation and
|
||||
## others. All Rights Reserved.
|
||||
##
|
||||
## $Id: mh-solaris,v 1.21 2000/11/04 02:16:11 srl Exp $
|
||||
## $Id: mh-solaris,v 1.22 2001/08/10 20:49:59 aheninger Exp $
|
||||
|
||||
## Flags for position independent code
|
||||
SHAREDLIBCFLAGS = -KPIC
|
||||
|
@ -58,7 +58,8 @@ INSTALL-S = $(INSTALL_PROGRAM)
|
|||
INSTALL-L = $(INSTALL_DATA)
|
||||
|
||||
## Link commands to link to ICU libs
|
||||
LIBICUUC= -L$(top_builddir)/common -l$(ICUPREFIX)uc
|
||||
LIBICUDT= -L$(top_builddir)/data -L$(top_builddir)/stubdata -licudata
|
||||
LIBICUUC= -L$(top_builddir)/common -l$(ICUPREFIX)uc $(LIBICUDT)
|
||||
LIBICUI18N= -L$(top_builddir)/i18n -l$(ICUPREFIX)i18n
|
||||
LIBCTESTFW= -L$(top_builddir)/tools/ctestfw -lctestfw
|
||||
LIBICUTOOLUTIL=-L$(top_builddir)/tools/toolutil -l$(ICUPREFIX)toolutil
|
||||
|
|
386
icu4c/source/configure
vendored
386
icu4c/source/configure
vendored
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,7 @@ dnl Copyright (c) 1999-2000, International Business Machines Corporation and
|
|||
dnl others. All Rights Reserved.
|
||||
dnl Stephen F. Booth, heavily modified by Yves and others
|
||||
|
||||
dnl $Id: configure.in,v 1.114 2001/07/23 19:52:19 grhoten Exp $
|
||||
dnl $Id: configure.in,v 1.115 2001/08/10 20:49:58 aheninger Exp $
|
||||
|
||||
dnl Process this file with autoconf to produce a configure script
|
||||
AC_INIT(common/unicode/utypes.h)
|
||||
|
@ -170,6 +170,23 @@ AC_SUBST(ENABLE_STATIC)
|
|||
|
||||
AC_PROG_RANLIB
|
||||
|
||||
dnl Check whether to make static reference to the data dll
|
||||
AC_MSG_CHECKING([whether to statically reference common data library])
|
||||
AC_ARG_ENABLE(refdata,
|
||||
[ --enable-refdata compile in a reference to the common data library [default=yes]],
|
||||
[ case "#{enableval}" in
|
||||
yes|"") enabled=yes; ENABLE_REFDATA=YES ;;
|
||||
no) enabled=no ;;
|
||||
*) enabled=yes; ENBABLE_REFDATA=YES ;;
|
||||
esac],
|
||||
[enabled=yes; ENABLE_REFDATA=YES]
|
||||
)
|
||||
AC_MSG_RESULT($enabled)
|
||||
AC_SUBST(ENABLE_REFDATA)
|
||||
|
||||
|
||||
|
||||
|
||||
dnl Check whether to use the evil rpath or not
|
||||
AC_ARG_ENABLE(rpath,
|
||||
[ --enable-rpath use rpath when linking [default is only if necessary]],
|
||||
|
@ -746,6 +763,7 @@ AC_OUTPUT([README icudefs.mk \
|
|||
common/Makefile config/Makefile.inc i18n/Makefile \
|
||||
layout/Makefile \
|
||||
extra/Makefile extra/ustdio/Makefile \
|
||||
stubdata/Makefile \
|
||||
tools/Makefile tools/ctestfw/Makefile tools/makeconv/Makefile \
|
||||
tools/genrb/Makefile \
|
||||
tools/genuca/Makefile \
|
||||
|
|
|
@ -38,7 +38,7 @@ LIB_ICUDATA_NAME=lib$(ICUDATA_NAME)
|
|||
SPECIALTESTDATA=test1.cnv test3.cnv test4.cnv
|
||||
TESTDATAOBJDIR=../test/testdata
|
||||
top_builddir_from_tmp = $(patsubst ..%,../..%,$(top_builddir))
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir_from_tmp)/common:$(top_builddir_from_tmp)/tools/toolutil:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir_from_tmp)/common:$(top_builddir_from_tmp)/tools/toolutil:$(top_builddir_from_tmp)/stubdata:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
CURDIR=$(shell pwd)
|
||||
PKGDATA = $(top_builddir_from_tmp)/tools/pkgdata/pkgdata -O $(top_builddir_from_tmp)/tools/pkgdata/icupkg.inc -d $(CURDIR) -m $(PKGDATA_MODE)
|
||||
|
||||
|
@ -104,7 +104,10 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
|||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
packagedata: build/icudata.lst $(top_builddir)/tools/pkgdata/icupkg.inc
|
||||
( cd build ; $(INVOKE) $(PKGDATA) -e $(ICUDATA_NAME) -s . -T . -p $(ICUDATA_NAME) icudata.lst )
|
||||
( cd build ; \
|
||||
$(INVOKE) $(PKGDATA) -e $(ICUDATA_NAME) -s . -T . -p $(ICUDATA_NAME) icudata.lst ; \
|
||||
)
|
||||
$(RM) libicudata.$(SO) && ln -s $(LIB_ICUDATA_NAME).$(SO) libicudata.$(SO) ; \
|
||||
|
||||
packagetest: $(TESTDATAOBJDIR)/testdata.lst $(top_builddir)/tools/pkgdata/icupkg.inc
|
||||
( cd $(TESTDATAOBJDIR) ; $(INVOKE) $(PKGDATA) -T . -s . -p testdata testdata.lst )
|
||||
|
|
|
@ -27,7 +27,7 @@ SRCLISTDEPS=Makefile $(srcdir)/Makefile.in $(SRCDATADIR)/resfiles.mk $(SRCDATADI
|
|||
OBJDATADIR=.
|
||||
|
||||
# relative lib links from pkgdata are the same as for tmp
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir)/common:$(top_builddir)/i18n:$(top_builddir)/tools/toolutil:$(top_builddir)/extra/ustdio:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir)/common:$(top_builddir)/i18n:$(top_builddir)/tools/toolutil:$(top_builddir)/extra/ustdio:$(top_builddir)/stubdata/:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
TOOLDIR=$(top_builddir)/tools
|
||||
|
||||
## List of phony targets
|
||||
|
|
|
@ -39,7 +39,7 @@ ifeq ($(ENABLE_RPATH),YES)
|
|||
RPATHLDFLAGS = $(LD_RPATH)$(LD_RPATH_PRE)$(libdir)
|
||||
endif
|
||||
LDFLAGS = @LDFLAGS@ $(RPATHLDFLAGS)
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir)/common:$(top_builddir)/i18n:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir)/common:$(top_builddir)/i18n:$(top_bilddir)/source/data:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
LIBS = $(LIBICUI18N) $(LIBICUUC) @LIBS@ @LIB_M@
|
||||
|
||||
OBJECTS = uprint.o cal.o
|
||||
|
|
|
@ -39,7 +39,7 @@ ifeq ($(ENABLE_RPATH),YES)
|
|||
RPATHLDFLAGS = $(LD_RPATH)$(LD_RPATH_PRE)$(libdir)
|
||||
endif
|
||||
LDFLAGS = @LDFLAGS@ $(RPATHLDFLAGS)
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir)/common:$(top_builddir)/i18n:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir)/common:$(top_builddir)/i18n:$(top_bilddir)/source/data:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
LIBS = $(LIBICUI18N) $(LIBICUUC) @LIBS@ @LIB_M@
|
||||
|
||||
OBJECTS = uprint.o date.o
|
||||
|
|
|
@ -28,15 +28,17 @@ typedef struct {
|
|||
UDataInfo info;
|
||||
char padding[8];
|
||||
uint32_t count, reserved;
|
||||
// const struct {
|
||||
// const char *const name;
|
||||
// const void *const data;
|
||||
// } toc[1];
|
||||
int fakeNameAndData[4]; // TODO: Change this header type from
|
||||
// pointerTOC to OffsetTOC.
|
||||
} ICU_Data_Heaser;;
|
||||
/*
|
||||
const struct {
|
||||
const char *const name;
|
||||
const void *const data;
|
||||
} toc[1];
|
||||
*/
|
||||
int fakeNameAndData[4]; /* TODO: Change this header type from */
|
||||
/* pointerTOC to OffsetTOC. */
|
||||
} ICU_Data_Header;
|
||||
|
||||
U_EXPORT const ICU_Data_Heaser U_EXPORT2 U_ICUDATA_ENTRY_POINT = {
|
||||
U_EXPORT const ICU_Data_Header U_EXPORT2 U_ICUDATA_ENTRY_POINT = {
|
||||
32, /* headerSize */
|
||||
0xda, /* magic1, (see struct MappedData in udata.c) */
|
||||
0x27, /* magic2 */
|
||||
|
|
|
@ -46,7 +46,7 @@ ifeq ($(ENABLE_RPATH),YES)
|
|||
RPATHLDFLAGS = $(LD_RPATH)$(LD_RPATH_PRE)$(libdir)
|
||||
endif
|
||||
LDFLAGS = @LDFLAGS@ $(RPATHLDFLAGS)
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir)/common:$(top_builddir)/i18n:$(top_builddir)/tools/ctestfw:$(top_builddir)/tools/toolutil:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir)/common:$(top_builddir)/i18n:$(top_builddir)/tools/ctestfw:$(top_builddir)/tools/toolutil:$(top_builddir)/data:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
LIBS = $(LIBCTESTFW) $(LIBICUI18N) $(LIBICUUC) $(LIBICUTOOLUTIL) @LIBS@ @LIB_M@
|
||||
|
||||
OBJECTS = callcoll.o calltest.o capitst.o cbiapts.o cbkittst.o \
|
||||
|
@ -58,7 +58,7 @@ cnmdptst.o cnormtst.o cnumtst.o cregrtst.o crestst.o creststn.o cturtst.o \
|
|||
cucdtst.o cutiltst.o encoll.o nucnvtst.o susctest.o nccbtst.o \
|
||||
cbiditst.o cbididat.o eurocreg.o udatatst.o utf16tst.o utransts.o \
|
||||
ncnvfbts.o ncnvtst.o putiltst.o cstrtest.o mstrmtst.o utf8tst.o ucmptst.o \
|
||||
ucmpetst.o stdnmtst.o
|
||||
stdnmtst.o ucmpetst.o
|
||||
|
||||
DEPS = $(OBJECTS:.o=.d)
|
||||
|
||||
|
@ -93,7 +93,7 @@ distclean-local: clean-local
|
|||
-include Makefile.local
|
||||
|
||||
check-local: all-local
|
||||
ICU_DATA=$(top_builddir)/data/ TZ=PST8PDT $(INVOKE) ./$(TARGET) $(CINTLTEST_OPTS)
|
||||
TZ=PST8PDT $(INVOKE) ./$(TARGET) $(CINTLTEST_OPTS)
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
|
|
|
@ -223,18 +223,21 @@ void ctest_setICU_DATA() {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/* U_SRCDATADIR is set by the makefiles on UNIXes when building cintltst and intltst
|
||||
* to point to the right place, "wherever/icu/source/data"
|
||||
* to point to "wherever/icu/data"
|
||||
* We can make a path from there to "wherever/icu/source/data"
|
||||
* The value is complete with quotes, so it can be used as-is as a string constant.
|
||||
*/
|
||||
#if defined (U_SRCDATADIR)
|
||||
{
|
||||
static char env_string[] = "ICU_DATA=" U_SRCDATADIR;
|
||||
static char env_string[] = "ICU_DATA=" U_SRCDATADIR "/../source/data";
|
||||
putenv(env_string);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* On Windows, the file name obtained from __FILE__ includes a full path.
|
||||
* This file is "wherever\icu\source\test\cintltst\cintltst.c"
|
||||
* Change to "wherever\icu\source\data"
|
||||
|
|
|
@ -32,7 +32,7 @@ ifeq ($(ENABLE_RPATH),YES)
|
|||
RPATHLDFLAGS = $(LD_RPATH)$(LD_RPATH_PRE)$(libdir)
|
||||
endif
|
||||
LDFLAGS = @LDFLAGS@ $(RPATHLDFLAGS)
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir)/common:$(top_builddir)/i18n:$(top_builddir)/tools/toolutil:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(top_builddir)/common:$(top_builddir)/i18n:$(top_builddir)/tools/toolutil:$(top_builddir)/data:$$$(LDLIBRARYPATH_ENVVAR)
|
||||
LIBS = $(LIBICUI18N) $(LIBICUUC) $(LIBICUTOOLUTIL) @LIBS@ @LIB_M@
|
||||
|
||||
OBJECTS = allcoll.o apicoll.o callimts.o calregts.o caltest.o \
|
||||
|
@ -82,7 +82,7 @@ distclean-local: clean-local
|
|||
-include Makefile.local
|
||||
|
||||
check-local: all-local
|
||||
ICU_DATA=$(top_builddir)/data/ TZ=PST8PDT $(INVOKE) ./$(TARGET) $(INTLTESTOPTS)
|
||||
TZ=PST8PDT $(INVOKE) ./$(TARGET) $(INTLTESTOPTS) || true
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "unicode/unistr.h"
|
||||
#include "unicode/ures.h"
|
||||
|
@ -509,9 +508,6 @@ IntlTest::setTestDirectory(const char* newDir)
|
|||
* 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.
|
||||
*
|
||||
* TODO: The use of ICU_DATA can be eliminated once the proposed
|
||||
* udata_setApplicationData() API exists.
|
||||
*/
|
||||
void IntlTest::setICU_DATA() {
|
||||
const char *original_ICU_DATA;
|
||||
|
@ -523,12 +519,13 @@ void IntlTest::setICU_DATA() {
|
|||
}
|
||||
|
||||
/* U_SRCDATADIR is set by the makefiles on UNIXes when building cintltst and intltst
|
||||
* to point to the right place, "wherever/icu/source/data"
|
||||
* to point to "wherever/icu/data"
|
||||
* We can make a path from there to "wherever/icu/source/data"
|
||||
* The value is complete with quotes, so it can be used as-is as a string constant.
|
||||
*/
|
||||
#if defined (U_SRCDATADIR)
|
||||
{
|
||||
static char env_string[] = "ICU_DATA=" U_SRCDATADIR;
|
||||
static char env_string[] = "ICU_DATA=" U_SRCDATADIR "/../source/data";
|
||||
putenv(env_string);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ protected:
|
|||
/*The function to get the Test Directory*/
|
||||
static const char* getTestDirectory(void);
|
||||
public:
|
||||
static void IntlTest::setICU_DATA(); // Set up ICU_DATA if necessary.
|
||||
static void setICU_DATA(); // Set up ICU_DATA if necessary.
|
||||
|
||||
public:
|
||||
UBool run_phase2( char* name, char* par ); // internally, supports reporting memory leaks
|
||||
|
|
Loading…
Add table
Reference in a new issue