mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-14 17:24:01 +00:00
ICU-3682 Temporary fix for os/400 scanf(%p)
X-SVN-Rev: 15828
This commit is contained in:
parent
9d6d10c50a
commit
16bd247007
3 changed files with 90 additions and 6 deletions
|
@ -141,7 +141,7 @@ ufmt_uto64(const UChar *buffer,
|
|||
/* intialize parameters */
|
||||
limit = buffer + *len;
|
||||
count = 0;
|
||||
result = 0;
|
||||
result = 0;
|
||||
|
||||
/* iterate through buffer */
|
||||
while(ufmt_isdigit(*buffer, radix) && buffer < limit) {
|
||||
|
@ -158,6 +158,39 @@ ufmt_uto64(const UChar *buffer,
|
|||
return result;
|
||||
}
|
||||
|
||||
void *
|
||||
ufmt_utop(const UChar *buffer,
|
||||
int32_t *len)
|
||||
{
|
||||
/*
|
||||
TODO: Fix this code so that it will work with pointers that are 2<=sizeof(void*)<=16
|
||||
*/
|
||||
const UChar *limit;
|
||||
int32_t count;
|
||||
int64_t result;
|
||||
|
||||
|
||||
/* intialize parameters */
|
||||
limit = buffer + *len;
|
||||
count = 0;
|
||||
result = 0;
|
||||
|
||||
/* iterate through buffer */
|
||||
/* limit to sixteen iterations since that is the max that an int64_t can contain for pointer work */
|
||||
while(ufmt_isdigit(*buffer, 16) && buffer < limit) {
|
||||
|
||||
/* read the next digit */
|
||||
result *= 16;
|
||||
result += ufmt_digitvalue(*buffer++);
|
||||
|
||||
/* increment our count */
|
||||
++count;
|
||||
}
|
||||
|
||||
*len = count;
|
||||
return (void *)result;
|
||||
}
|
||||
|
||||
UChar*
|
||||
ufmt_defaultCPToUnicode(const char *s, int32_t sSize,
|
||||
UChar *target, int32_t tSize)
|
||||
|
|
|
@ -86,7 +86,7 @@ ufmt_isdigit(UChar c,
|
|||
int32_t radix);
|
||||
|
||||
/**
|
||||
* Convert a long to a UChar* in a specified radix
|
||||
* Convert an int64_t to a UChar* in a specified radix
|
||||
* @param buffer The target buffer
|
||||
* @param len On input, the size of <TT>buffer</TT>. On output,
|
||||
* the number of UChars written to <TT>buffer</TT>.
|
||||
|
@ -116,7 +116,7 @@ ufmt_ptou(UChar *buffer,
|
|||
UBool uselower);
|
||||
|
||||
/**
|
||||
* Convert a UChar* in a specified radix to a long.
|
||||
* Convert a UChar* in a specified radix to an int64_t.
|
||||
* @param buffer The target buffer
|
||||
* @param len On input, the size of <TT>buffer</TT>. On output,
|
||||
* the number of UChars read from <TT>buffer</TT>.
|
||||
|
@ -128,6 +128,18 @@ ufmt_uto64(const UChar *buffer,
|
|||
int32_t *len,
|
||||
int8_t radix);
|
||||
|
||||
/**
|
||||
* Convert a UChar* in a specified radix to a pointer,
|
||||
* @param buffer The target buffer
|
||||
* @param len On input, the size of <TT>buffer</TT>. On output,
|
||||
* the number of UChars read from <TT>buffer</TT>.
|
||||
* @param radix The desired radix
|
||||
* @return The pointer value.
|
||||
*/
|
||||
void *
|
||||
ufmt_utop(const UChar *buffer,
|
||||
int32_t *len);
|
||||
|
||||
/**
|
||||
* Convert a string from the default codepage to Unicode.
|
||||
* @param s The string to convert, in the default codepage.
|
||||
|
|
|
@ -1026,16 +1026,55 @@ u_scanf_pointer_handler(UFILE *input,
|
|||
len = input->str.fLimit - input->str.fPos;
|
||||
|
||||
/* truncate to the width, if specified */
|
||||
if(info->fWidth != -1)
|
||||
if(info->fWidth != -1) {
|
||||
len = ufmt_min(len, info->fWidth);
|
||||
}
|
||||
|
||||
/* parse the pointer - cast to void** to assign to *p */
|
||||
result = (void*) ufmt_uto64(input->str.fPos, &len, 16);
|
||||
#ifdef OS400
|
||||
/* TODO: Fix this code so that it will work on all platforms */
|
||||
{
|
||||
int64_t result[2];
|
||||
int32_t lenOrig = len;
|
||||
|
||||
/* Make sure that we don't consume too much */
|
||||
if (len > (int32_t)(sizeof(int64_t)*2)) {
|
||||
len = (int32_t)(sizeof(int64_t)*2);
|
||||
}
|
||||
|
||||
/* parse the pointer - set first half of big endian pointer */
|
||||
result[0] = (int64_t)ufmt_utop(input->str.fPos, &len);
|
||||
|
||||
/* update the input's position to reflect consumed data */
|
||||
input->str.fPos += len;
|
||||
len = lenOrig - len;
|
||||
|
||||
/* Make sure that we don't consume too much */
|
||||
if (len > (int32_t)(sizeof(int64_t)*2)) {
|
||||
len = (int32_t)(sizeof(int64_t)*2);
|
||||
}
|
||||
|
||||
/* parse the pointer - set second half of big endian pointer */
|
||||
result[1] = (int64_t)ufmt_utop(input->str.fPos, &len);
|
||||
|
||||
if (!info->fSkipArg) {
|
||||
p = *((void **)result);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Make sure that we don't consume too much */
|
||||
if (len > (int32_t)(sizeof(void*)*2)) {
|
||||
len = (int32_t)(sizeof(void*)*2);
|
||||
}
|
||||
|
||||
/* parse the pointer - assign to temporary value */
|
||||
result = ufmt_utop(input->str.fPos, &len);
|
||||
|
||||
if (!info->fSkipArg) {
|
||||
*p = result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* update the input's position to reflect consumed data */
|
||||
input->str.fPos += len;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue