msvcrt: Handle CR at buffer boundary and test case.
This commit is contained in:
parent
2bfce6cfdc
commit
e6f1ae029e
|
@ -60,6 +60,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
|
|||
#define WX_OPEN 0x01
|
||||
#define WX_ATEOF 0x02
|
||||
#define WX_READEOF 0x04 /* like ATEOF, but for underlying file rather than buffer */
|
||||
#define WX_READCR 0x08 /* underlying file is at \r */
|
||||
#define WX_DONTINHERIT 0x10
|
||||
#define WX_APPEND 0x20
|
||||
#define WX_TEXT 0x80
|
||||
|
@ -941,6 +942,9 @@ int CDECL MSVCRT_fseek(MSVCRT_FILE* file, MSVCRT_long offset, int whence)
|
|||
if (file->_ptr[i] == '\n')
|
||||
offset--;
|
||||
}
|
||||
/* Black magic when reading CR at buffer boundary*/
|
||||
if(MSVCRT_fdesc[file->_file].wxflag & WX_READCR)
|
||||
offset--;
|
||||
}
|
||||
}
|
||||
/* Discard buffered input */
|
||||
|
@ -1742,6 +1746,10 @@ int CDECL _rmtmp(void)
|
|||
|
||||
/*********************************************************************
|
||||
* (internal) read_i
|
||||
*
|
||||
* When reading \r as last character in text mode, read() positions
|
||||
* the file pointer on the \r character while getc() goes on to
|
||||
* the following \n
|
||||
*/
|
||||
static int read_i(int fd, void *buf, unsigned int count)
|
||||
{
|
||||
|
@ -1768,6 +1776,13 @@ static int read_i(int fd, void *buf, unsigned int count)
|
|||
if (MSVCRT_fdesc[fd].wxflag & WX_TEXT)
|
||||
{
|
||||
DWORD i, j;
|
||||
if (bufstart[num_read-1] == '\r')
|
||||
{
|
||||
MSVCRT_fdesc[fd].wxflag |= WX_READCR;
|
||||
num_read--;
|
||||
}
|
||||
else
|
||||
MSVCRT_fdesc[fd].wxflag &= ~WX_READCR;
|
||||
for (i=0, j=0; i<num_read; i++)
|
||||
{
|
||||
/* in text mode, a ctrl-z signals EOF */
|
||||
|
@ -2890,6 +2905,10 @@ LONG CDECL MSVCRT_ftell(MSVCRT_FILE* file)
|
|||
if (file->_ptr[i] == '\n')
|
||||
off--;
|
||||
}
|
||||
/* Black magic when reading CR at buffer boundary*/
|
||||
if(MSVCRT_fdesc[file->_file].wxflag & WX_READCR)
|
||||
off--;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2916,6 +2935,9 @@ int CDECL MSVCRT_fgetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos)
|
|||
if (file->_ptr[i] == '\n')
|
||||
off--;
|
||||
}
|
||||
/* Black magic when reading CR at buffer boundary*/
|
||||
if(MSVCRT_fdesc[file->_file].wxflag & WX_READCR)
|
||||
off--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -422,6 +422,35 @@ static WCHAR* AtoW( const char* p )
|
|||
return buffer;
|
||||
}
|
||||
|
||||
/* Test reading in text mode when the 512'th character read is \r*/
|
||||
static void test_readboundary(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[513], rbuf[513];
|
||||
int i, j;
|
||||
for (i = 0; i < 511; i++)
|
||||
{
|
||||
j = (i%('~' - ' ')+ ' ');
|
||||
buf[i] = j;
|
||||
}
|
||||
buf[511] = '\n';
|
||||
buf[512] =0;
|
||||
fp = fopen("boundary.tst", "wt");
|
||||
fwrite(buf, 512,1,fp);
|
||||
fclose(fp);
|
||||
fp = fopen("boundary.tst", "rt");
|
||||
for(i=0; i<512; i++)
|
||||
{
|
||||
fseek(fp,0 , SEEK_CUR);
|
||||
rbuf[i] = fgetc(fp);
|
||||
}
|
||||
rbuf[512] =0;
|
||||
fclose(fp);
|
||||
unlink("boundary.tst");
|
||||
|
||||
ok(strcmp(buf, rbuf) == 0,"CRLF on buffer boundary failure\n");
|
||||
}
|
||||
|
||||
static void test_fgetc( void )
|
||||
{
|
||||
char* tempf;
|
||||
|
@ -808,15 +837,23 @@ static void test_file_write_read( void )
|
|||
tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
|
||||
_lseek(tempfd, -1, FILE_END);
|
||||
ret = _read(tempfd,btext,LLEN);
|
||||
ok(ret == 1, "_read expected 1 got bad length: %d\n", ret);
|
||||
ok(ret == 1 && *btext == '\n', "_read expected 1 got bad length: %d\n", ret);
|
||||
_lseek(tempfd, -2, FILE_END);
|
||||
ret = _read(tempfd,btext,LLEN);
|
||||
ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
|
||||
_lseek(tempfd, -3, FILE_END);
|
||||
ret = _read(tempfd,btext,1);
|
||||
ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
|
||||
ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd));
|
||||
_lseek(tempfd, -3, FILE_END);
|
||||
ret = _read(tempfd,btext,2);
|
||||
ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
|
||||
ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd));
|
||||
_close(tempfd);
|
||||
_lseek(tempfd, -3, FILE_END);
|
||||
ret = _read(tempfd,btext,3);
|
||||
ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
|
||||
ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd));
|
||||
_close(tempfd);
|
||||
|
||||
ret = unlink(tempf);
|
||||
ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
|
||||
|
@ -1402,6 +1439,7 @@ START_TEST(file)
|
|||
test_asciimode2();
|
||||
test_readmode(FALSE); /* binary mode */
|
||||
test_readmode(TRUE); /* ascii mode */
|
||||
test_readboundary();
|
||||
test_fgetc();
|
||||
test_fputc();
|
||||
test_flsbuf();
|
||||
|
|
Loading…
Reference in New Issue