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_OPEN 0x01
|
||||||
#define WX_ATEOF 0x02
|
#define WX_ATEOF 0x02
|
||||||
#define WX_READEOF 0x04 /* like ATEOF, but for underlying file rather than buffer */
|
#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_DONTINHERIT 0x10
|
||||||
#define WX_APPEND 0x20
|
#define WX_APPEND 0x20
|
||||||
#define WX_TEXT 0x80
|
#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')
|
if (file->_ptr[i] == '\n')
|
||||||
offset--;
|
offset--;
|
||||||
}
|
}
|
||||||
|
/* Black magic when reading CR at buffer boundary*/
|
||||||
|
if(MSVCRT_fdesc[file->_file].wxflag & WX_READCR)
|
||||||
|
offset--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Discard buffered input */
|
/* Discard buffered input */
|
||||||
|
@ -1742,6 +1746,10 @@ int CDECL _rmtmp(void)
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* (internal) read_i
|
* (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)
|
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)
|
if (MSVCRT_fdesc[fd].wxflag & WX_TEXT)
|
||||||
{
|
{
|
||||||
DWORD i, j;
|
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++)
|
for (i=0, j=0; i<num_read; i++)
|
||||||
{
|
{
|
||||||
/* in text mode, a ctrl-z signals EOF */
|
/* in text mode, a ctrl-z signals EOF */
|
||||||
|
@ -2890,6 +2905,10 @@ LONG CDECL MSVCRT_ftell(MSVCRT_FILE* file)
|
||||||
if (file->_ptr[i] == '\n')
|
if (file->_ptr[i] == '\n')
|
||||||
off--;
|
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')
|
if (file->_ptr[i] == '\n')
|
||||||
off--;
|
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;
|
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 )
|
static void test_fgetc( void )
|
||||||
{
|
{
|
||||||
char* tempf;
|
char* tempf;
|
||||||
|
@ -808,15 +837,23 @@ static void test_file_write_read( void )
|
||||||
tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
|
tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
|
||||||
_lseek(tempfd, -1, FILE_END);
|
_lseek(tempfd, -1, FILE_END);
|
||||||
ret = _read(tempfd,btext,LLEN);
|
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);
|
_lseek(tempfd, -2, FILE_END);
|
||||||
ret = _read(tempfd,btext,LLEN);
|
ret = _read(tempfd,btext,LLEN);
|
||||||
ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
|
ok(ret == 1 && *btext == '\n', "_read expected '\\n' got bad length: %d\n", ret);
|
||||||
_lseek(tempfd, -3, FILE_END);
|
_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);
|
ret = _read(tempfd,btext,2);
|
||||||
ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret);
|
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));
|
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);
|
ret = unlink(tempf);
|
||||||
ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
|
ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno);
|
||||||
|
@ -1402,6 +1439,7 @@ START_TEST(file)
|
||||||
test_asciimode2();
|
test_asciimode2();
|
||||||
test_readmode(FALSE); /* binary mode */
|
test_readmode(FALSE); /* binary mode */
|
||||||
test_readmode(TRUE); /* ascii mode */
|
test_readmode(TRUE); /* ascii mode */
|
||||||
|
test_readboundary();
|
||||||
test_fgetc();
|
test_fgetc();
|
||||||
test_fputc();
|
test_fputc();
|
||||||
test_flsbuf();
|
test_flsbuf();
|
||||||
|
|
Loading…
Reference in New Issue