ICU-3499 Fix some scanf issues when width is specified for any string type.

X-SVN-Rev: 15574
This commit is contained in:
George Rhoten 2004-05-27 04:18:30 +00:00
parent f30027fcca
commit 6c416836d5
5 changed files with 45 additions and 34 deletions

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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 */

View File

@ -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"
}
}
}