ICU-3499 Fix some scanf issues when width is specified for any string type.
X-SVN-Rev: 15574
This commit is contained in:
parent
f30027fcca
commit
6c416836d5
@ -371,9 +371,9 @@ u_scanf_string_handler(UFILE *input,
|
||||
if(U_FAILURE(status))
|
||||
return -1;
|
||||
|
||||
while( (isNotEOF = ufile_getch(input, &c))
|
||||
&& (c != info->fPadChar && !u_isWhitespace(c))
|
||||
&& (info->fWidth == -1 || count < info->fWidth) )
|
||||
while( (info->fWidth == -1 || count < info->fWidth)
|
||||
&& (isNotEOF = ufile_getch(input, &c))
|
||||
&& (c != info->fPadChar && !u_isWhitespace(c)))
|
||||
{
|
||||
|
||||
if (!info->fSkipArg) {
|
||||
@ -399,7 +399,7 @@ u_scanf_string_handler(UFILE *input,
|
||||
|
||||
/* put the final character we read back on the input */
|
||||
if (!info->fSkipArg) {
|
||||
if(isNotEOF)
|
||||
if(isNotEOF && (info->fWidth == -1 || count < info->fWidth) )
|
||||
u_fungetc(c, input);
|
||||
|
||||
/* add the terminator */
|
||||
@ -432,9 +432,9 @@ u_scanf_ustring_handler(UFILE *input,
|
||||
/* get the string one character at a time, truncating to the width */
|
||||
count = 0;
|
||||
|
||||
while( (isNotEOF = ufile_getch(input, &c))
|
||||
&& (c != info->fPadChar && ! u_isWhitespace(c))
|
||||
&& (info->fWidth == -1 || count < info->fWidth) )
|
||||
while( (info->fWidth == -1 || count < info->fWidth)
|
||||
&& (isNotEOF = ufile_getch(input, &c))
|
||||
&& (c != info->fPadChar && ! u_isWhitespace(c)))
|
||||
{
|
||||
|
||||
/* put the character from the input onto the target */
|
||||
@ -448,8 +448,9 @@ u_scanf_ustring_handler(UFILE *input,
|
||||
|
||||
/* put the final character we read back on the input */
|
||||
if (!info->fSkipArg) {
|
||||
if(isNotEOF)
|
||||
if(isNotEOF && (info->fWidth == -1 || count < info->fWidth)) {
|
||||
u_fungetc(c, input);
|
||||
}
|
||||
|
||||
/* add the terminator */
|
||||
*alias = 0x0000;
|
||||
@ -1042,56 +1043,45 @@ u_scanf_scanset_handler(UFILE *input,
|
||||
{
|
||||
USet *scanset;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t chLeft = INT32_MAX;
|
||||
UChar32 c;
|
||||
UChar *s = (UChar*) (args[0].ptrValue);
|
||||
UChar *alias = NULL;
|
||||
UChar *limit = NULL;
|
||||
UChar *alias = (UChar*) (args[0].ptrValue);
|
||||
UBool isNotEOF = FALSE;
|
||||
UBool readCharacter = FALSE;
|
||||
|
||||
|
||||
/* fill the input's internal buffer */
|
||||
ufile_fill_uchar_buffer(input);
|
||||
|
||||
/* Create an empty set */
|
||||
scanset = uset_open(0, -1);
|
||||
|
||||
/* Back up one to get the [ */
|
||||
fmt--;
|
||||
|
||||
if (!info->fSkipArg) {
|
||||
/* truncate to the width, if specified and alias the target */
|
||||
alias = s;
|
||||
if(info->fWidth != -1) {
|
||||
limit = alias + info->fWidth;
|
||||
}
|
||||
else {
|
||||
limit = U_MAX_PTR(alias);
|
||||
}
|
||||
/* truncate to the width, if specified and alias the target */
|
||||
if(info->fWidth >= 0) {
|
||||
chLeft = info->fWidth;
|
||||
}
|
||||
|
||||
/* parse the scanset from the fmt string */
|
||||
*consumed = uset_applyPattern(scanset, fmt, u_strlen(fmt), 0, &status);
|
||||
*consumed = uset_applyPattern(scanset, fmt, -1, 0, &status);
|
||||
|
||||
/* verify that the parse was successful */
|
||||
if (U_SUCCESS(status)) {
|
||||
c=0;
|
||||
|
||||
/* grab characters one at a time and make sure they are in the scanset */
|
||||
while(info->fSkipArg || alias < limit) {
|
||||
while(chLeft > 0) {
|
||||
if ((isNotEOF = ufile_getch32(input, &c)) && uset_contains(scanset, c)) {
|
||||
readCharacter = TRUE;
|
||||
if (!info->fSkipArg) {
|
||||
int32_t idx = 0;
|
||||
UBool isError = FALSE;
|
||||
int32_t capacity = (int32_t)(limit - alias);
|
||||
|
||||
U16_APPEND(alias, idx, capacity, c, isError);
|
||||
alias += idx;
|
||||
U16_APPEND(alias, idx, chLeft, c, isError);
|
||||
if (isError) {
|
||||
break;
|
||||
}
|
||||
alias += idx;
|
||||
}
|
||||
chLeft -= (1 + U_IS_SUPPLEMENTARY(c));
|
||||
}
|
||||
else {
|
||||
/* if the character's not in the scanset, break out */
|
||||
@ -1100,7 +1090,7 @@ u_scanf_scanset_handler(UFILE *input,
|
||||
}
|
||||
|
||||
/* put the final character we read back on the input */
|
||||
if(isNotEOF) {
|
||||
if(isNotEOF && chLeft > 0) {
|
||||
u_fungetc(c, input);
|
||||
}
|
||||
}
|
||||
|
@ -1103,6 +1103,8 @@ static void TestFScanset(void) {
|
||||
TestFScanSetFormat("%1[ab] ", abcUChars, abcChars, TRUE);
|
||||
TestFScanSetFormat("%2[^f]", abcUChars, abcChars, TRUE);
|
||||
|
||||
TestFScanSetFormat("%[qrst]", abcUChars, abcChars, TRUE);
|
||||
|
||||
/* Bad format */
|
||||
TestFScanSetFormat("%[f-a]", abcUChars, abcChars, FALSE);
|
||||
TestFScanSetFormat("%[c-a]", abcUChars, abcChars, FALSE);
|
||||
|
@ -453,18 +453,20 @@ static void DataDrivenScanf(void) {
|
||||
}
|
||||
break;
|
||||
case 0x73: // 's' char *
|
||||
u_austrncpy(cExpected, uBuffer, sizeof(cBuffer));
|
||||
u_austrcpy(cExpected, expectedResult);
|
||||
uBufferLenReturned = u_sscanf_u(argument, format, cBuffer);
|
||||
//uFileBufferLenReturned = u_fscanf_u(testFile, format, cBuffer);
|
||||
if (strcmp(cBuffer, cExpected) != 0) {
|
||||
log_err("error in scanf char * string. Test case = %d\n", i);
|
||||
log_err("error in scanf char * string. Got \"%s\" Expected \"%s\". Test case = %d\n", cBuffer, cExpected, i);
|
||||
}
|
||||
break;
|
||||
case 0x53: // 'S' UChar *
|
||||
uBufferLenReturned = u_sscanf_u(argument, format, uBuffer);
|
||||
//uFileBufferLenReturned = u_fscanf_u(testFile, format, argument);
|
||||
if (u_strcmp(uBuffer, expectedResult) != 0) {
|
||||
log_err("error in scanf UChar * string. Test case = %d\n", i);
|
||||
u_austrcpy(cExpected, format);
|
||||
u_austrcpy(cBuffer, uBuffer);
|
||||
log_err("error in scanf UChar * string %s Got: \"%s\". Test case = %d\n", cExpected, cBuffer, i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -628,6 +628,8 @@ static void TestSScanset(void) {
|
||||
|
||||
TestSScanSetFormat("%1[ab] ", abcUChars, abcChars, TRUE);
|
||||
TestSScanSetFormat("%2[^f]", abcUChars, abcChars, TRUE);
|
||||
|
||||
TestSScanSetFormat("%[qrst]", abcUChars, abcChars, TRUE);
|
||||
TestSScanSetFormat("%[a-]", abcUChars, abcChars, TRUE);
|
||||
|
||||
/* Bad format */
|
||||
|
17
icu4c/source/test/testdata/icuio.txt
vendored
17
icu4c/source/test/testdata/icuio.txt
vendored
@ -254,6 +254,9 @@ icuio {
|
||||
{
|
||||
"%llx", "123456789abcdef0", "8", "123456789abcdef0"
|
||||
}
|
||||
{
|
||||
"%S", "a\U00010000b", "S", "a\U00010000b"
|
||||
}
|
||||
{
|
||||
"%[abce]", "abcd ef01", "S", "abc"
|
||||
}
|
||||
@ -276,7 +279,19 @@ icuio {
|
||||
"%3[^e-f]", "abccdefg", "S", "abc"
|
||||
}
|
||||
{
|
||||
"%S", "a\U00010000b", "S", "a\U00010000b"
|
||||
"%*3[abc]%[cde]", "abccdefg", "S", "cde"
|
||||
}
|
||||
{
|
||||
"%*3S%S", "a bc efg", "S", "bc"
|
||||
}
|
||||
{
|
||||
"%*3S%S", "abcd efg", "S", "d"
|
||||
}
|
||||
{
|
||||
"%*3s%s", "abcd efg", "s", "d"
|
||||
}
|
||||
{
|
||||
"%*3d%d", "1234", "4", "4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user