Akihiro Sagawa : cmd: Properly handle multibyte characters in batch files.
Alexandre Julliard
julliard at winehq.org
Mon Oct 22 13:42:45 CDT 2012
Module: wine
Branch: master
Commit: 8daef1649b242e26236df9c9cb1810750113bed2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8daef1649b242e26236df9c9cb1810750113bed2
Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date: Sat Oct 20 01:02:24 2012 +0900
cmd: Properly handle multibyte characters in batch files.
---
programs/cmd/batch.c | 58 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 40 insertions(+), 18 deletions(-)
diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c
index bacb6cd..02d1fcf 100644
--- a/programs/cmd/batch.c
+++ b/programs/cmd/batch.c
@@ -234,31 +234,53 @@ WCHAR *WCMD_fgets(WCHAR *buf, DWORD noChars, HANDLE h)
{
DWORD charsRead;
BOOL status;
- LARGE_INTEGER filepos;
DWORD i;
/* We can't use the native f* functions because of the filename syntax differences
between DOS and Unix. Also need to lose the LF (or CRLF) from the line. */
if (!WCMD_is_console_handle(h)) {
- /* Save current file position */
- filepos.QuadPart = 0;
- SetFilePointerEx(h, filepos, &filepos, FILE_CURRENT);
- }
+ LARGE_INTEGER filepos;
+ char *bufA;
+ UINT cp;
+ const char *p;
+
+ cp = GetConsoleCP();
+ bufA = HeapAlloc(GetProcessHeap(), 0, noChars);
+ if (!bufA) return NULL;
+
+ /* Save current file position */
+ filepos.QuadPart = 0;
+ SetFilePointerEx(h, filepos, &filepos, FILE_CURRENT);
+
+ status = ReadFile(h, bufA, noChars, &charsRead, NULL);
+ if (!status || charsRead == 0) {
+ HeapFree(GetProcessHeap(), 0, bufA);
+ return NULL;
+ }
- status = WCMD_ReadFile(h, buf, noChars, &charsRead);
- if (!status || charsRead == 0) return NULL;
+ /* Find first EOL */
+ for (p = bufA; p < (bufA + charsRead); p = CharNextExA(cp, p, 0)) {
+ if (*p == '\n' || *p == '\r')
+ break;
+ }
- /* Find first EOL */
- for (i = 0; i < charsRead; i++) {
- if (buf[i] == '\n' || buf[i] == '\r')
- break;
- }
+ /* Sets file pointer to the start of the next line, if any */
+ filepos.QuadPart += p - bufA + 1 + (*p == '\r' ? 1 : 0);
+ SetFilePointerEx(h, filepos, NULL, FILE_BEGIN);
- if (!WCMD_is_console_handle(h) && i != charsRead) {
- /* Sets file pointer to the start of the next line, if any */
- filepos.QuadPart += i + 1 + (buf[i] == '\r' ? 1 : 0);
- SetFilePointerEx(h, filepos, NULL, FILE_BEGIN);
+ i = MultiByteToWideChar(cp, 0, bufA, p - bufA, buf, noChars);
+ HeapFree(GetProcessHeap(), 0, bufA);
+ }
+ else {
+ status = WCMD_ReadFile(h, buf, noChars, &charsRead);
+ if (!status || charsRead == 0) return NULL;
+
+ /* Find first EOL */
+ for (i = 0; i < charsRead; i++) {
+ if (buf[i] == '\n' || buf[i] == '\r')
+ break;
+ }
}
/* Truncate at EOL (or end of buffer) */
More information about the wine-cvs
mailing list