diff options
Diffstat (limited to 'Build/source/libs/icu-xetex/io/uscanf_p.c')
-rw-r--r-- | Build/source/libs/icu-xetex/io/uscanf_p.c | 175 |
1 files changed, 113 insertions, 62 deletions
diff --git a/Build/source/libs/icu-xetex/io/uscanf_p.c b/Build/source/libs/icu-xetex/io/uscanf_p.c index 0fa7e68dde4..804f9a55de4 100644 --- a/Build/source/libs/icu-xetex/io/uscanf_p.c +++ b/Build/source/libs/icu-xetex/io/uscanf_p.c @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 1998-2004, International Business Machines +* Copyright (C) 1998-2006, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -306,6 +306,7 @@ typedef struct u_scanf_info { } u_scanf_info; #define USCANF_NUM_FMT_HANDLERS 108 +#define USCANF_SYMBOL_BUFFER_SIZE 8 /* We do not use handlers for 0-0x1f */ #define USCANF_BASE_FMT_HANDLERS 0x20 @@ -332,6 +333,43 @@ u_scanf_skip_leading_ws(UFILE *input, return count; } +/* TODO: Is always skipping the prefix symbol as a positive sign a good idea in all locales? */ +static int32_t +u_scanf_skip_leading_positive_sign(UFILE *input, + UNumberFormat *format, + UErrorCode *status) +{ + UChar c; + int32_t count = 0; + UBool isNotEOF; + UChar plusSymbol[USCANF_SYMBOL_BUFFER_SIZE]; + int32_t symbolLen; + UErrorCode localStatus = U_ZERO_ERROR; + + if (U_SUCCESS(*status)) { + symbolLen = unum_getSymbol(format, + UNUM_PLUS_SIGN_SYMBOL, + plusSymbol, + sizeof(plusSymbol)/sizeof(*plusSymbol), + &localStatus); + + if (U_SUCCESS(localStatus)) { + /* skip all leading ws in the input */ + while( (isNotEOF = ufile_getch(input, &c)) && (count < symbolLen && c == plusSymbol[count]) ) + { + count++; + } + + /* put the final character back on the input */ + if(isNotEOF) { + u_fungetc(c, input); + } + } + } + + return count; +} + static int32_t u_scanf_simple_percent_handler(UFILE *input, u_scanf_spec_info *info, @@ -366,6 +404,7 @@ u_scanf_count_handler(UFILE *input, else *(int32_t*)(args[0].ptrValue) = (int32_t)(UINT32_MAX & info->fWidth); } + *argConverted = 0; /* we converted 0 args */ return 0; @@ -383,11 +422,12 @@ u_scanf_double_handler(UFILE *input, double num; UNumberFormat *format; int32_t parsePos = 0; + int32_t skipped; UErrorCode status = U_ZERO_ERROR; /* skip all ws in the input */ - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); @@ -406,11 +446,19 @@ u_scanf_double_handler(UFILE *input, if(format == 0) return 0; + /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */ + skipped += u_scanf_skip_leading_positive_sign(input, format, &status); + /* parse the number */ num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status); if (!info->fSkipArg) { - *(double*)(args[0].ptrValue) = num; + if (info->fIsLong) + *(double*)(args[0].ptrValue) = num; + else if (info->fIsLongDouble) + *(long double*)(args[0].ptrValue) = num; + else + *(float*)(args[0].ptrValue) = (float)num; } /* mask off any necessary bits */ @@ -422,7 +470,7 @@ u_scanf_double_handler(UFILE *input, /* we converted 1 arg */ *argConverted = !info->fSkipArg; - return parsePos; + return parsePos + skipped; } static int32_t @@ -437,11 +485,12 @@ u_scanf_scientific_handler(UFILE *input, double num; UNumberFormat *format; int32_t parsePos = 0; + int32_t skipped; UErrorCode status = U_ZERO_ERROR; /* skip all ws in the input */ - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); @@ -460,11 +509,19 @@ u_scanf_scientific_handler(UFILE *input, if(format == 0) return 0; + /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */ + skipped += u_scanf_skip_leading_positive_sign(input, format, &status); + /* parse the number */ num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status); if (!info->fSkipArg) { - *(double*)(args[0].ptrValue) = num; + if (info->fIsLong) + *(double*)(args[0].ptrValue) = num; + else if (info->fIsLongDouble) + *(long double*)(args[0].ptrValue) = num; + else + *(float*)(args[0].ptrValue) = (float)num; } /* mask off any necessary bits */ @@ -476,7 +533,7 @@ u_scanf_scientific_handler(UFILE *input, /* we converted 1 arg */ *argConverted = !info->fSkipArg; - return parsePos; + return parsePos + skipped; } static int32_t @@ -487,12 +544,13 @@ u_scanf_scidbl_handler(UFILE *input, int32_t *fmtConsumed, int32_t *argConverted) { - int32_t len; + int32_t len; double num; UNumberFormat *scientificFormat, *genericFormat; /*int32_t scientificResult, genericResult;*/ double scientificResult, genericResult; int32_t scientificParsePos = 0, genericParsePos = 0, parsePos = 0; + int32_t skipped; UErrorCode scientificStatus = U_ZERO_ERROR; UErrorCode genericStatus = U_ZERO_ERROR; @@ -504,7 +562,7 @@ u_scanf_scidbl_handler(UFILE *input, /* skip all ws in the input */ - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); @@ -524,6 +582,9 @@ u_scanf_scidbl_handler(UFILE *input, if(scientificFormat == 0 || genericFormat == 0) return 0; + /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */ + skipped += u_scanf_skip_leading_positive_sign(input, genericFormat, &genericStatus); + /* parse the number using each format*/ scientificResult = unum_parseDouble(scientificFormat, input->str.fPos, len, @@ -548,7 +609,12 @@ u_scanf_scidbl_handler(UFILE *input, input->str.fPos += parsePos; if (!info->fSkipArg) { - *(double*)(args[0].ptrValue) = num; + if (info->fIsLong) + *(double*)(args[0].ptrValue) = num; + else if (info->fIsLongDouble) + *(long double*)(args[0].ptrValue) = num; + else + *(float*)(args[0].ptrValue) = (float)num; } /* mask off any necessary bits */ @@ -557,7 +623,7 @@ u_scanf_scidbl_handler(UFILE *input, /* we converted 1 arg */ *argConverted = !info->fSkipArg; - return parsePos; + return parsePos + skipped; } static int32_t @@ -572,12 +638,13 @@ u_scanf_integer_handler(UFILE *input, void *num = (void*) (args[0].ptrValue); UNumberFormat *format; int32_t parsePos = 0; + int32_t skipped; UErrorCode status = U_ZERO_ERROR; int64_t result; /* skip all ws in the input */ - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); @@ -596,6 +663,9 @@ u_scanf_integer_handler(UFILE *input, if(format == 0) return 0; + /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */ + skipped += u_scanf_skip_leading_positive_sign(input, format, &status); + /* parse the number */ result = unum_parseInt64(format, input->str.fPos, len, &parsePos, &status); @@ -614,7 +684,7 @@ u_scanf_integer_handler(UFILE *input, /* we converted 1 arg */ *argConverted = !info->fSkipArg; - return parsePos; + return parsePos + skipped; } static int32_t @@ -641,11 +711,12 @@ u_scanf_percent_handler(UFILE *input, double num; UNumberFormat *format; int32_t parsePos = 0; + int32_t skipped; UErrorCode status = U_ZERO_ERROR; /* skip all ws in the input */ - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); @@ -664,6 +735,9 @@ u_scanf_percent_handler(UFILE *input, if(format == 0) return 0; + /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */ + skipped += u_scanf_skip_leading_positive_sign(input, format, &status); + /* parse the number */ num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status); @@ -698,12 +772,13 @@ u_scanf_string_handler(UFILE *input, char *limit; UErrorCode status = U_ZERO_ERROR; int32_t count; + int32_t skipped = 0; UChar c; UBool isNotEOF = FALSE; /* skip all ws in the input */ if (info->fIsString) { - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); } /* get the string one character at a time, truncating to the width */ @@ -762,7 +837,7 @@ u_scanf_string_handler(UFILE *input, /* we converted 1 arg */ *argConverted = !info->fSkipArg; - return count; + return count + skipped; } static int32_t @@ -791,12 +866,13 @@ u_scanf_ustring_handler(UFILE *input, UChar *arg = (UChar*)(args[0].ptrValue); UChar *alias = arg; int32_t count; + int32_t skipped = 0; UChar c; UBool isNotEOF = FALSE; /* skip all ws in the input */ if (info->fIsString) { - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); } /* get the string one character at a time, truncating to the width */ @@ -830,7 +906,7 @@ u_scanf_ustring_handler(UFILE *input, /* we converted 1 arg */ *argConverted = !info->fSkipArg; - return count; + return count + skipped; } static int32_t @@ -860,11 +936,12 @@ u_scanf_spellout_handler(UFILE *input, double num; UNumberFormat *format; int32_t parsePos = 0; + int32_t skipped; UErrorCode status = U_ZERO_ERROR; /* skip all ws in the input */ - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); @@ -883,6 +960,10 @@ u_scanf_spellout_handler(UFILE *input, if(format == 0) return 0; + /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */ + /* This is not applicable to RBNF. */ + /*skipped += u_scanf_skip_leading_positive_sign(input, format, &status);*/ + /* parse the number */ num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status); @@ -899,7 +980,7 @@ u_scanf_spellout_handler(UFILE *input, /* we converted 1 arg */ *argConverted = !info->fSkipArg; - return parsePos; + return parsePos + skipped; } static int32_t @@ -911,11 +992,12 @@ u_scanf_hex_handler(UFILE *input, int32_t *argConverted) { int32_t len; + int32_t skipped; void *num = (void*) (args[0].ptrValue); int64_t result; /* skip all ws in the input */ - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); @@ -954,7 +1036,7 @@ u_scanf_hex_handler(UFILE *input, /* we converted 1 arg */ *argConverted = !info->fSkipArg; - return len; + return len + skipped; } static int32_t @@ -965,12 +1047,13 @@ u_scanf_octal_handler(UFILE *input, int32_t *fmtConsumed, int32_t *argConverted) { - int32_t len; - void *num = (void*) (args[0].ptrValue); - int64_t result; + int32_t len; + int32_t skipped; + void *num = (void*) (args[0].ptrValue); + int64_t result; /* skip all ws in the input */ - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); @@ -1000,7 +1083,7 @@ u_scanf_octal_handler(UFILE *input, /* we converted 1 arg */ *argConverted = !info->fSkipArg; - return len; + return len + skipped; } static int32_t @@ -1012,12 +1095,13 @@ u_scanf_pointer_handler(UFILE *input, int32_t *argConverted) { int32_t len; + int32_t skipped; void *result; void **p = (void**)(args[0].ptrValue); /* skip all ws in the input */ - u_scanf_skip_leading_ws(input, info->fPadChar); + skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); @@ -1030,37 +1114,6 @@ u_scanf_pointer_handler(UFILE *input, len = ufmt_min(len, info->fWidth); } -#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); @@ -1073,14 +1126,12 @@ u_scanf_pointer_handler(UFILE *input, *p = result; } -#endif - /* update the input's position to reflect consumed data */ input->str.fPos += len; /* we converted 1 arg */ *argConverted = !info->fSkipArg; - return len; + return len + skipped; } static int32_t |