Uwe Bonnes : msvcrt: Handle CR at buffer boundary and test case.
Alexandre Julliard
julliard at winehq.org
Mon Jan 18 10:58:56 CST 2010
Module: wine
Branch: master
Commit: e6f1ae029e39d24ca3c56175df966ffb39ba532e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e6f1ae029e39d24ca3c56175df966ffb39ba532e
Author: Uwe Bonnes <bon at elektron.ikp.physik.tu-darmstadt.de>
Date: Sat Jan 16 17:24:19 2010 +0100
msvcrt: Handle CR at buffer boundary and test case.
---
dlls/msvcrt/file.c | 22 ++++++++++++++++++++++
dlls/msvcrt/tests/file.c | 42 ++++++++++++++++++++++++++++++++++++++++--
2 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index a9678ed..655f17e 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -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--;
}
}
}
diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c
index 042a82e..18247ad 100644
--- a/dlls/msvcrt/tests/file.c
+++ b/dlls/msvcrt/tests/file.c
@@ -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();
More information about the wine-cvs
mailing list