ICU-4894 Improve U_MAX_PTR for i5/OS.
X-SVN-Rev: 22578
This commit is contained in:
parent
e9f3e3e5e0
commit
ffc55edf36
@ -94,6 +94,7 @@ Cleanly installed Solaris can use this #define.
|
||||
# include <qusec.h> /* error code structure */
|
||||
# include <qusrjobi.h>
|
||||
# include <qliept.h> /* EPT_CALL macro - this include must be after all other "QSYSINCs" */
|
||||
# include <mih/testptr.h> /* For uprv_maximumPtr */
|
||||
#elif defined(XP_MAC)
|
||||
# include <Files.h>
|
||||
# include <IntlResources.h>
|
||||
@ -486,51 +487,38 @@ uprv_log(double d)
|
||||
return log(d);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This isn't used. If it's readded, readd putiltst.c tests */
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
uprv_digitsAfterDecimal(double x)
|
||||
U_CAPI void * U_EXPORT2
|
||||
uprv_maximumPtr(void * base)
|
||||
{
|
||||
char buffer[20];
|
||||
int32_t numDigits, bytesWritten;
|
||||
char *p = buffer;
|
||||
int32_t ptPos, exponent;
|
||||
|
||||
/* cheat and use the string-format routine to get a string representation*/
|
||||
/* (it handles mathematical inaccuracy better than we can), then find out */
|
||||
/* many characters are to the right of the decimal point */
|
||||
bytesWritten = sprintf(buffer, "%+.9g", x);
|
||||
while (isdigit(*(++p))) {
|
||||
#if defined(OS400)
|
||||
/*
|
||||
* With the provided function we should never be out of range of a given segment
|
||||
* (a traditional/typical segment that is). Our segments have 5 bytes for the
|
||||
* id and 3 bytes for the offset. The key is that the casting takes care of
|
||||
* only retrieving the offset portion minus x1000. Hence, the smallest offset
|
||||
* seen in a program is x001000 and when casted to an int would be 0.
|
||||
* That's why we can only add 0xffefff. Otherwise, we would exceed the segment.
|
||||
*
|
||||
* Currently, 16MB is the current addressing limitation on i5/OS if the activation is
|
||||
* non-TERASPACE. If it is TERASPACE it is 2GB - 4k(header information).
|
||||
* This function determines the activation based on the pointer that is passed in and
|
||||
* calculates the appropriate maximum available size for
|
||||
* each pointer type (TERASPACE and non-TERASPACE)
|
||||
*
|
||||
* Unlike other operating systems, the pointer model isn't determined at
|
||||
* compile time on i5/OS.
|
||||
*/
|
||||
if ((base != NULL) && (_TESTPTR(base, _C_TERASPACE_CHECK))) {
|
||||
/* if it is a TERASPACE pointer the max is 2GB - 4k */
|
||||
return ((void *)(((char *)base)-((uint32_t)(base))+((uint32_t)0x7fffefff)));
|
||||
}
|
||||
/* otherwise 16MB since NULL ptr is not checkable or the ptr is not TERASPACE */
|
||||
return ((void *)(((char *)base)-((uint32_t)(base))+((uint32_t)0xffefff)));
|
||||
|
||||
ptPos = (int32_t)(p - buffer);
|
||||
numDigits = (int32_t)(bytesWritten - ptPos - 1);
|
||||
|
||||
/* if the number's string representation is in scientific notation, find */
|
||||
/* the exponent and take it into account*/
|
||||
exponent = 0;
|
||||
p = uprv_strchr(buffer, 'e');
|
||||
if (p != 0) {
|
||||
int16_t expPos = (int16_t)(p - buffer);
|
||||
numDigits -= bytesWritten - expPos;
|
||||
exponent = (int32_t)(atol(p + 1));
|
||||
}
|
||||
|
||||
/* the string representation may still have spurious decimal digits in it, */
|
||||
/* so we cut off at the ninth digit to the right of the decimal, and have */
|
||||
/* to search backward from there to the first non-zero digit*/
|
||||
if (numDigits > 9) {
|
||||
numDigits = 9;
|
||||
while (numDigits > 0 && buffer[ptPos + numDigits] == '0')
|
||||
--numDigits;
|
||||
}
|
||||
numDigits -= exponent;
|
||||
if (numDigits < 0) {
|
||||
return 0;
|
||||
}
|
||||
return numDigits;
|
||||
}
|
||||
#else
|
||||
return U_MAX_PTR(base);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Platform-specific Implementations
|
||||
|
@ -226,6 +226,14 @@ U_INTERNAL UDate U_EXPORT2 uprv_getUTCtime(void);
|
||||
*/
|
||||
U_INTERNAL UBool U_EXPORT2 uprv_pathIsAbsolute(const char *path);
|
||||
|
||||
/**
|
||||
* Use U_MAX_PTR instead of this function.
|
||||
* @param void pointer to test
|
||||
* @return the largest possible pointer greater than the base
|
||||
* @internal (ICU 3.8)
|
||||
*/
|
||||
U_INTERNAL void * U_EXPORT2 uprv_maximumPtr(void *base);
|
||||
|
||||
/**
|
||||
* Maximum value of a (void*) - use to indicate the limit of an 'infinite' buffer.
|
||||
* In fact, buffer sizes must not exceed 2GB so that the difference between
|
||||
@ -245,26 +253,14 @@ U_INTERNAL UBool U_EXPORT2 uprv_pathIsAbsolute(const char *path);
|
||||
/* We have 31-bit pointers. */
|
||||
# define U_MAX_PTR(base) ((void *)0x7fffffff)
|
||||
# elif defined(OS400)
|
||||
/*
|
||||
* With the provided macro we should never be out of range of a given segment
|
||||
* (a traditional/typical segment that is). Our segments have 5 bytes for the
|
||||
* id and 3 bytes for the offset. The key is that the casting takes care of
|
||||
* only retrieving the offset portion minus x1000. Hence, the smallest offset
|
||||
* seen in a program is x001000 and when casted to an int would be 0.
|
||||
* That's why we can only add 0xffefff. Otherwise, we would exceed the segment.
|
||||
*
|
||||
* Currently, 16MB is the current addressing limitation on as/400. This macro
|
||||
* may eventually be changed to use 2GB addressability for the newer version of
|
||||
* as/400 machines.
|
||||
*/
|
||||
# define U_MAX_PTR(base) ((void *)(((char *)base)-((int32_t)(base))+((int32_t)0xffefff)))
|
||||
# define U_MAX_PTR(base) uprv_maximumPtr((void *)base)
|
||||
# elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
/*
|
||||
* Due to a compiler optimization bug, gcc 4 causes test failures when doing
|
||||
* this math arithmetic on pointers on some platforms. It seems like the
|
||||
* pointers are considered signed instead of unsigned. The uintptr_t type
|
||||
* isn't available on all platforms (i.e MSVC 6) and pointers aren't always
|
||||
* a scalar value (i.e. i5/OS in the lines above).
|
||||
* a scalar value (i.e. i5/OS see uprv_maximumPtr function).
|
||||
*/
|
||||
# define U_MAX_PTR(base) \
|
||||
((void *)(((uintptr_t)(base)+0x7fffffffu) > (uintptr_t)(base) \
|
||||
|
@ -1053,6 +1053,7 @@
|
||||
#define uprv_malloc uprv_malloc_3_8
|
||||
#define uprv_mapFile uprv_mapFile_3_8
|
||||
#define uprv_max uprv_max_3_8
|
||||
#define uprv_maximumPtr uprv_maximumPtr_3_8
|
||||
#define uprv_maxMantissa uprv_maxMantissa_3_8
|
||||
#define uprv_min uprv_min_3_8
|
||||
#define uprv_modf uprv_modf_3_8
|
||||
|
Loading…
Reference in New Issue
Block a user