ICU-3499 Improve 64-bit support. (re-commit changes due to CVS reconstruction)

X-SVN-Rev: 14719
This commit is contained in:
George Rhoten 2004-03-22 21:59:02 +00:00
parent c641111443
commit 0b2dabafa5
5 changed files with 223 additions and 163 deletions

View File

@ -421,10 +421,11 @@ u_scanf_integer_handler(u_localized_string *input,
int32_t *consumed)
{
int32_t len;
long *num = (long*) (args[0].ptrValue);
UNumberFormat *format;
void *num = (void*) (args[0].ptrValue);
UNumberFormat *format;
int32_t parsePos = 0;
UErrorCode status = U_ZERO_ERROR;
UErrorCode status = U_ZERO_ERROR;
int64_t result;
/* skip all ws in the input */
@ -445,13 +446,15 @@ u_scanf_integer_handler(u_localized_string *input,
return 0;
/* parse the number */
*num = unum_parse(format, &(input->str[input->pos]), len, &parsePos, &status);
result = unum_parseInt64(format, &(input->str[input->pos]), len, &parsePos, &status);
/* mask off any necessary bits */
if(info->fIsShort)
*num &= UINT16_MAX;
else if(! info->fIsLong || ! info->fIsLongLong)
*num &= UINT32_MAX;
if (info->fIsShort)
*(int16_t*)num = (int16_t)(UINT16_MAX & result);
else if (info->fIsLongLong)
*(int64_t*)num = result;
else
*(int32_t*)num = (int32_t)(UINT32_MAX & result);
/* update the input's position to reflect consumed data */
input->pos += parsePos;
@ -635,7 +638,8 @@ u_scanf_hex_handler(u_localized_string *input,
int32_t *consumed)
{
int32_t len;
long *num = (long*) (args[0].ptrValue);
void *num = (void*) (args[0].ptrValue);
int64_t result;
/* skip all ws in the input */
@ -658,16 +662,18 @@ u_scanf_hex_handler(u_localized_string *input,
}
/* parse the number */
*num = ufmt_utol(&(input->str[input->pos]), &len, 16);
result = ufmt_uto64(&(input->str[input->pos]), &len, 16);
/* update the input's position to reflect consumed data */
input->pos += len;
/* mask off any necessary bits */
if(info->fIsShort)
*num &= UINT16_MAX;
else if(! info->fIsLong || ! info->fIsLongLong)
*num &= UINT32_MAX;
if (info->fIsShort)
*(int16_t*)num = (int16_t)(UINT16_MAX & result);
else if (info->fIsLongLong)
*(int64_t*)num = result;
else
*(int32_t*)num = (int32_t)(UINT32_MAX & result);
/* we converted 1 arg */
return 1;
@ -681,8 +687,8 @@ u_scanf_octal_handler(u_localized_string *input,
int32_t *consumed)
{
int32_t len;
long *num = (long*) (args[0].ptrValue);
void *num = (void*) (args[0].ptrValue);
int64_t result;
/* skip all ws in the input */
u_scanf_skip_leading_ws(input, info->fPadChar);
@ -695,16 +701,18 @@ u_scanf_octal_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* parse the number */
*num = ufmt_utol(&(input->str[input->pos]), &len, 8);
result = ufmt_uto64(&(input->str[input->pos]), &len, 8);
/* update the input's position to reflect consumed data */
input->pos += len;
/* mask off any necessary bits */
if(info->fIsShort)
*num &= UINT16_MAX;
else if(! info->fIsLong || ! info->fIsLongLong)
*num &= UINT32_MAX;
if (info->fIsShort)
*(int16_t*)num = (int16_t)(UINT16_MAX & result);
else if (info->fIsLongLong)
*(int64_t*)num = result;
else
*(int32_t*)num = (int32_t)(UINT32_MAX & result);
/* we converted 1 arg */
return 1;
@ -732,7 +740,7 @@ u_scanf_pointer_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* parse the pointer - cast to void** to assign to *p */
*(void**)p = (void*) ufmt_utol(&(input->str[input->pos]), &len, 16);
*(void**)p = (void*) ufmt_uto64(&(input->str[input->pos]), &len, 16);
/* update the input's position to reflect consumed data */
input->pos += len;
@ -751,7 +759,7 @@ u_scanf_scanset_handler(u_localized_string *input,
USet *scanset;
int32_t len;
UErrorCode status = U_ZERO_ERROR;
UChar c;
UChar32 c;
UChar *s = (UChar*) (args[0].ptrValue);
UChar *alias, *limit;
@ -997,7 +1005,7 @@ u_vsscanf_u(const UChar *buffer,
break;
case ufmt_count:
args.intValue = va_arg(ap, int);
args.int64Value = va_arg(ap, int);
/* set the spec's width to the # of items converted */
spec.fInfo.fWidth = converted;
break;

View File

@ -60,10 +60,10 @@ ufmt_isdigit(UChar c,
#define TO_LC_DIGIT(a) a <= 9 ? (0x0030 + a) : (0x0030 + a + 39)
void
ufmt_ltou(UChar *buffer,
ufmt_64tou(UChar *buffer,
int32_t *len,
uint32_t value,
uint32_t radix,
uint64_t value,
uint8_t radix,
UBool uselower,
int32_t minDigits)
{
@ -72,7 +72,7 @@ ufmt_ltou(UChar *buffer,
UChar *left, *right, temp;
do {
digit = value % radix;
digit = (uint32_t)(value % radix);
value = value / radix;
buffer[length++] = (UChar)(uselower ? TO_LC_DIGIT(digit)
: TO_UC_DIGIT(digit));
@ -96,14 +96,14 @@ ufmt_ltou(UChar *buffer,
*len = length;
}
long
ufmt_utol(const UChar *buffer,
int64_t
ufmt_uto64(const UChar *buffer,
int32_t *len,
int32_t radix)
int8_t radix)
{
const UChar *limit;
int32_t count;
long result;
int64_t result;
/* intialize parameters */

View File

@ -53,7 +53,7 @@ typedef enum ufmt_type_info ufmt_type_info;
* Union representing a uprintf/uscanf argument
*/
union ufmt_args {
signed int intValue; /* int, UChar */ /* TODO: Should int32_t be used instead of int? */
int64_t int64Value; /* int, UChar */ /* TODO: Should int32_t be used instead of int? */
float floatValue; /* float */
double doubleValue; /* double */
void *ptrValue; /* any pointer - void*, char*, wchar_t*, UChar* */
@ -100,10 +100,10 @@ ufmt_isdigit(UChar c,
* which will be padded with zeroes. -1 means do not pad.
*/
void
ufmt_ltou(UChar *buffer,
ufmt_64tou(UChar *buffer,
int32_t *len,
uint32_t value,
uint32_t radix,
uint64_t value,
uint8_t radix,
UBool uselower,
int32_t minDigits);
@ -115,10 +115,10 @@ ufmt_ltou(UChar *buffer,
* @param radix The desired radix
* @return The numeric value.
*/
long
ufmt_utol(const UChar *buffer,
int64_t
ufmt_uto64(const UChar *buffer,
int32_t *len,
int32_t radix);
int8_t radix);
/**
* Convert a string from the default codepage to Unicode.

View File

@ -234,7 +234,7 @@ u_printf_char_handler(const u_printf_stream_handler *handler,
{
UChar s[UTF_MAX_CHAR_LENGTH+1];
int32_t len = 1, written;
unsigned char arg = (unsigned char)(args[0].intValue);
unsigned char arg = (unsigned char)(args[0].int64Value);
/* convert from default codepage to Unicode */
ufmt_defaultCPToUnicode((const char *)&arg, 2, s, sizeof(s)/sizeof(UChar));
@ -342,7 +342,7 @@ u_printf_integer_handler(const u_printf_stream_handler *handler,
const u_printf_spec_info *info,
const ufmt_args *args)
{
long num = (long) (args[0].intValue);
int64_t num = args[0].int64Value;
UNumberFormat *format;
UChar result[UPRINTF_BUFFER_SIZE];
UChar prefixBuffer[UPRINTF_BUFFER_SIZE];
@ -353,9 +353,139 @@ u_printf_integer_handler(const u_printf_stream_handler *handler,
prefixBuffer[0] = 0;
/* mask off any necessary bits */
if(info->fIsShort)
if (info->fIsShort)
num = (int16_t)num;
else if (!info->fIsLongLong)
num = (int32_t)num;
/* get the formatter */
format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL);
/* handle error */
if(format == 0)
return 0;
/* set the appropriate flags on the formatter */
/* set the minimum integer digits */
if(info->fPrecision != -1) {
/* set the minimum # of digits */
minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS);
unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision);
}
/* set whether to show the sign */
if(info->fShowSign) {
u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status);
}
/* format the number */
unum_formatInt64(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status);
/* restore the number format */
if (minDigits != -1) {
unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits);
}
if (info->fShowSign) {
/* Reset back to original value regardless of what the error was */
UErrorCode localStatus = U_ZERO_ERROR;
u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus);
}
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_printf_hex_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
int64_t num = args[0].int64Value;
UChar result[UPRINTF_BUFFER_SIZE];
int32_t len = UPRINTF_BUFFER_SIZE;
/* mask off any necessary bits */
if (info->fIsShort)
num &= UINT16_MAX;
else if(! info->fIsLong || ! info->fIsLongLong)
else if (!info->fIsLongLong)
num &= UINT32_MAX;
/* format the number, preserving the minimum # of digits */
ufmt_64tou(result, &len, num, 16,
(UBool)(info->fSpec == 0x0078),
(info->fPrecision == -1 && info->fZero) ? info->fWidth : info->fPrecision);
/* convert to alt form, if desired */
if(num != 0 && info->fAlt && len < UPRINTF_BUFFER_SIZE - 2) {
/* shift the formatted string right by 2 chars */
memmove(result + 2, result, len * sizeof(UChar));
result[0] = 0x0030;
result[1] = info->fSpec;
len += 2;
}
return handler->pad_and_justify(context, info, result, len);
}
static int32_t
u_printf_octal_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
int64_t num = args[0].int64Value;
UChar result[UPRINTF_BUFFER_SIZE];
int32_t len = UPRINTF_BUFFER_SIZE;
/* mask off any necessary bits */
if (info->fIsShort)
num &= UINT16_MAX;
else if (!info->fIsLongLong)
num &= UINT32_MAX;
/* format the number, preserving the minimum # of digits */
ufmt_64tou(result, &len, num, 8,
FALSE, /* doesn't matter for octal */
info->fPrecision == -1 && info->fZero ? info->fWidth : info->fPrecision);
/* convert to alt form, if desired */
if(info->fAlt && result[0] != 0x0030 && len < UPRINTF_BUFFER_SIZE - 1) {
/* shift the formatted string right by 1 char */
memmove(result + 1, result, len * sizeof(UChar));
result[0] = 0x0030;
len += 1;
}
return handler->pad_and_justify(context, info, result, len);
}
static int32_t
u_printf_uinteger_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
int64_t num = args[0].int64Value;
UNumberFormat *format;
UChar result[UPRINTF_BUFFER_SIZE];
UChar prefixBuffer[UPRINTF_BUFFER_SIZE];
int32_t prefixBufferLen = sizeof(prefixBuffer);
int32_t minDigits = -1;
UErrorCode status = U_ZERO_ERROR;
prefixBuffer[0] = 0;
/* TODO: Fix this once uint64_t can be formatted. */
if (info->fIsShort)
num &= UINT16_MAX;
else if (!info->fIsLongLong)
num &= UINT32_MAX;
/* get the formatter */
@ -380,7 +510,7 @@ u_printf_integer_handler(const u_printf_stream_handler *handler,
}
/* format the number */
unum_format(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status);
unum_formatInt64(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status);
/* restore the number format */
if (minDigits != -1) {
@ -396,97 +526,6 @@ u_printf_integer_handler(const u_printf_stream_handler *handler,
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_printf_hex_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
long num = (long) (args[0].intValue);
UChar result[UPRINTF_BUFFER_SIZE];
int32_t len = UPRINTF_BUFFER_SIZE;
/* mask off any necessary bits */
if(info->fIsShort)
num &= UINT16_MAX;
else if(! info->fIsLong || ! info->fIsLongLong)
num &= UINT32_MAX;
/* format the number, preserving the minimum # of digits */
ufmt_ltou(result, &len, num, 16,
(UBool)(info->fSpec == 0x0078),
(info->fPrecision == -1 && info->fZero) ? info->fWidth : info->fPrecision);
/* convert to alt form, if desired */
if(num != 0 && info->fAlt && len < UPRINTF_BUFFER_SIZE - 2) {
/* shift the formatted string right by 2 chars */
memmove(result + 2, result, len * sizeof(UChar));
result[0] = 0x0030;
result[1] = info->fSpec;
len += 2;
}
return handler->pad_and_justify(context, info, result, len);
}
static int32_t
u_printf_octal_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
long num = (long) (args[0].intValue);
UChar result[UPRINTF_BUFFER_SIZE];
int32_t len = UPRINTF_BUFFER_SIZE;
/* mask off any necessary bits */
if(info->fIsShort)
num &= UINT16_MAX;
else if(! info->fIsLong || ! info->fIsLongLong)
num &= UINT32_MAX;
/* format the number, preserving the minimum # of digits */
ufmt_ltou(result, &len, num, 8,
FALSE, /* doesn't matter for octal */
info->fPrecision == -1 && info->fZero ? info->fWidth : info->fPrecision);
/* convert to alt form, if desired */
if(info->fAlt && result[0] != 0x0030 && len < UPRINTF_BUFFER_SIZE - 1) {
/* shift the formatted string right by 1 char */
memmove(result + 1, result, len * sizeof(UChar));
result[0] = 0x0030;
len += 1;
}
return handler->pad_and_justify(context, info, result, len);
}
static int32_t
u_printf_uinteger_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
u_printf_spec_info uint_info;
ufmt_args uint_args;
memcpy(&uint_info, info, sizeof(u_printf_spec_info));
memcpy(&uint_args, args, sizeof(ufmt_args));
uint_info.fPrecision = 0;
uint_info.fAlt = FALSE;
/* Get around int32_t limitations */
uint_args.doubleValue = ((double) ((uint32_t) (uint_args.intValue)));
return u_printf_double_handler(handler, context, formatBundle, &uint_info, &uint_args);
}
static int32_t
u_printf_pointer_handler(const u_printf_stream_handler *handler,
void *context,
@ -494,13 +533,13 @@ u_printf_pointer_handler(const u_printf_stream_handler *handler,
const u_printf_spec_info *info,
const ufmt_args *args)
{
long num = (long) (args[0].intValue);
int64_t num = args[0].int64Value;
UChar result[UPRINTF_BUFFER_SIZE];
int32_t len = UPRINTF_BUFFER_SIZE;
/* format the pointer in hex */
ufmt_ltou(result, &len, num, 16, TRUE, info->fPrecision);
ufmt_64tou(result, &len, num, 16, TRUE, info->fPrecision);
return handler->pad_and_justify(context, info, result, len);
}
@ -732,7 +771,7 @@ u_printf_uchar_handler(const u_printf_stream_handler *handler,
const ufmt_args *args)
{
int32_t written = 0;
UChar arg = (UChar)(args[0].intValue);
UChar arg = (UChar)(args[0].int64Value);
/* width = minimum # of characters to write */
@ -1262,7 +1301,12 @@ u_printf_print_spec(const u_printf_stream_handler *streamHandler,
case ufmt_char:
case ufmt_uchar:
case ufmt_int:
args.intValue = va_arg(*ap, int);
if (info->fIsLongLong) {
args.int64Value = va_arg(*ap, int64_t);
}
else {
args.int64Value = va_arg(*ap, int);
}
break;
case ufmt_float:
args.floatValue = (float) va_arg(*ap, double);

View File

@ -431,10 +431,11 @@ u_scanf_integer_handler(UFILE *input,
int32_t *consumed)
{
int32_t len;
long *num = (long*) (args[0].ptrValue);
UNumberFormat *format;
int32_t parsePos = 0;
UErrorCode status = U_ZERO_ERROR;
void *num = (void*) (args[0].ptrValue);
UNumberFormat *format;
int32_t parsePos = 0;
UErrorCode status = U_ZERO_ERROR;
int64_t result;
/* skip all ws in the input */
@ -458,13 +459,15 @@ u_scanf_integer_handler(UFILE *input,
return 0;
/* parse the number */
*num = unum_parse(format, input->fUCPos, len, &parsePos, &status);
result = unum_parseInt64(format, input->fUCPos, len, &parsePos, &status);
/* mask off any necessary bits */
if(info->fIsShort)
*num &= UINT16_MAX;
else if(! info->fIsLong || ! info->fIsLongLong)
*num &= UINT32_MAX;
if (info->fIsShort)
*(int16_t*)num = (int16_t)(UINT16_MAX & result);
else if (info->fIsLongLong)
*(int64_t*)num = result;
else
*(int32_t*)num = (int32_t)(UINT32_MAX & result);
/* update the input's position to reflect consumed data */
input->fUCPos += parsePos;
@ -654,8 +657,8 @@ u_scanf_hex_handler(UFILE *input,
int32_t *consumed)
{
int32_t len;
long *num = (long*) (args[0].ptrValue);
void *num = (void*) (args[0].ptrValue);
int64_t result;
/* skip all ws in the input */
u_scanf_skip_leading_ws(input, info->fPadChar);
@ -680,16 +683,18 @@ u_scanf_hex_handler(UFILE *input,
}
/* parse the number */
*num = ufmt_utol(input->fUCPos, &len, 16);
result = ufmt_uto64(input->fUCPos, &len, 16);
/* update the input's position to reflect consumed data */
input->fUCPos += len;
/* mask off any necessary bits */
if(info->fIsShort)
*num &= UINT16_MAX;
else if(! info->fIsLong || ! info->fIsLongLong)
*num &= UINT32_MAX;
if (info->fIsShort)
*(int16_t*)num = (int16_t)(UINT16_MAX & result);
else if (info->fIsLongLong)
*(int64_t*)num = result;
else
*(int32_t*)num = (int32_t)(UINT32_MAX & result);
/* we converted 1 arg */
return 1;
@ -703,7 +708,8 @@ u_scanf_octal_handler(UFILE *input,
int32_t *consumed)
{
int32_t len;
long *num = (long*) (args[0].ptrValue);
void *num = (void*) (args[0].ptrValue);
int64_t result;
/* skip all ws in the input */
@ -720,16 +726,18 @@ u_scanf_octal_handler(UFILE *input,
len = ufmt_min(len, info->fWidth);
/* parse the number */
*num = ufmt_utol(input->fUCPos, &len, 8);
result = ufmt_uto64(input->fUCPos, &len, 8);
/* update the input's position to reflect consumed data */
input->fUCPos += len;
/* mask off any necessary bits */
if(info->fIsShort)
*num &= UINT16_MAX;
else if(! info->fIsLong || ! info->fIsLongLong)
*num &= UINT32_MAX;
if (info->fIsShort)
*(int16_t*)num = (int16_t)(UINT16_MAX & result);
else if (info->fIsLongLong)
*(int64_t*)num = result;
else
*(int32_t*)num = (int32_t)(UINT32_MAX & result);
/* we converted 1 arg */
return 1;
@ -760,7 +768,7 @@ u_scanf_pointer_handler(UFILE *input,
len = ufmt_min(len, info->fWidth);
/* parse the pointer - cast to void** to assign to *p */
*(void**)p = (void*) ufmt_utol(input->fUCPos, &len, 16);
*(void**)p = (void*) ufmt_uto64(input->fUCPos, &len, 16);
/* update the input's position to reflect consumed data */
input->fUCPos += len;
@ -1014,7 +1022,7 @@ u_vfscanf_u(UFILE *f,
break;
case ufmt_count:
args.intValue = va_arg(ap, int);
args.int64Value = va_arg(ap, int);
/* set the spec's width to the # of items converted */
spec.fInfo.fWidth = converted;
break;