summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu-xetex/io/uscanf_p.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/icu-xetex/io/uscanf_p.c')
-rw-r--r--Build/source/libs/icu-xetex/io/uscanf_p.c175
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