MakeNSISW should request UTF16LE output

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6370 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2013-05-28 20:07:47 +00:00
parent b8aee8098d
commit 7d930ed452
3 changed files with 43 additions and 34 deletions

View file

@ -413,7 +413,7 @@ INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
} }
case MakensisAPI::QUERYHOST: { case MakensisAPI::QUERYHOST: {
if (MakensisAPI::QH_OUTPUTCHARSET) { if (MakensisAPI::QH_OUTPUTCHARSET) {
const UINT reqcp = CP_UTF8; // TODO: UTF16LE will be faster for makensis const UINT reqcp = 1200; // We want UTF-16LE
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)(1+reqcp)); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)(1+reqcp));
return TRUE; return TRUE;
} }
@ -717,7 +717,7 @@ INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
return 0; return 0;
} }
DWORD WINAPI MakeNSISProc(LPVOID p) { DWORD WINAPI MakeNSISProc(LPVOID TreadParam) {
TCHAR eventnamebuf[100]; TCHAR eventnamebuf[100];
wsprintf(eventnamebuf, MakensisAPI::SigintEventNameFmt, g_sdata.hwnd); wsprintf(eventnamebuf, MakensisAPI::SigintEventNameFmt, g_sdata.hwnd);
if (g_sdata.sigint_event) CloseHandle(g_sdata.sigint_event); if (g_sdata.sigint_event) CloseHandle(g_sdata.sigint_event);
@ -728,10 +728,6 @@ DWORD WINAPI MakeNSISProc(LPVOID p) {
return 1; return 1;
} }
#ifdef _UNICODE
TCHAR buf[1024];
#endif
char iobuf[1024]; //i/o buffer
STARTUPINFO si; STARTUPINFO si;
HANDLE newstdout,read_stdout; HANDLE newstdout,read_stdout;
@ -750,35 +746,44 @@ DWORD WINAPI MakeNSISProc(LPVOID p) {
return 1; return 1;
} }
CloseHandle(newstdout); // close this handle (duplicated in subprocess) now so we get ERROR_BROKEN_PIPE CloseHandle(newstdout); // close this handle (duplicated in subprocess) now so we get ERROR_BROKEN_PIPE
DWORD dwLeft = 0, dwRead = 0;
while (ReadFile(read_stdout, iobuf+dwLeft, sizeof(iobuf)-dwLeft-1, &dwRead, NULL)) //wait for buffer, or fails with ERROR_BROKEN_PIPE when subprocess exits char iob[1024 & ~1];
WCHAR *p = (WCHAR*) iob, wcl = 0, wct = 0;
DWORD cb = 0, cbofs = 0, cch, cbio;
for(;;)
{ {
dwRead += dwLeft; BOOL rok = ReadFile(read_stdout, iob+cbofs, sizeof(iob)-cbofs, &cbio, NULL);
iobuf[dwRead] = '\0'; cb += cbio;
#ifdef _UNICODE logappend:
// this tweak is to prevent LogMessage from cutting in the middle of an UTF-8 sequence cch = cb / sizeof(WCHAR);
// we print only up to the latest \n of the buffer, and keep the remaining for the next loop if (!cch)
// BUGBUG: What if the line is longer than sizeof(iobuf)? {
char* lastLF = strrchr(iobuf,'\n'); if (!rok) break;
if (!lastLF) lastLF = iobuf+dwRead-1; cbofs += cbio;
char ch = *++lastLF; continue;
*lastLF = '\0'; }
MultiByteToWideChar(CP_UTF8,0,iobuf,lastLF+1-iobuf,buf,COUNTOF(buf)); bool fullbuf = sizeof(iob) == cb, incompsurr = false;
LogMessage(g_sdata.hwnd, buf); cbofs = 0, cb = 0, --cch;
*lastLF = ch; if (fullbuf || (incompsurr = IS_HIGH_SURROGATE(p[cch])))
dwLeft = iobuf+dwRead-lastLF; {
memmove(iobuf, lastLF, dwLeft); wcl = p[cch], cbofs = sizeof(WCHAR);
#else if (cch && IS_HIGH_SURROGATE(p[cch-1]) && !incompsurr)
LogMessage(g_sdata.hwnd, iobuf); wct = wcl, wcl = p[cch-1], cbofs += sizeof(WCHAR);
#endif }
p[cch] = L'\0';
LogMessage(g_sdata.hwnd, p);
p[0] = wcl, p[1] = wct;
if (!rok)
{
if (cbofs)
{
if (incompsurr) p[0] = 0xfffd, cbofs = sizeof(WCHAR); // Unable to complete the surrogate pair
cb = cbofs;
goto logappend;
}
break;
}
} }
#ifdef _UNICODE
// because of UTF-8 tweak, in rare case there can be some data remaining
dwRead += dwLeft;
iobuf[dwRead] = 0;
MultiByteToWideChar(CP_UTF8,0,iobuf,dwRead+1,buf,COUNTOF(buf));
LogMessage(g_sdata.hwnd, buf);
#endif
FreeSpawn(&pi, read_stdout, 0); FreeSpawn(&pi, read_stdout, 0);
g_sdata.retcode = pi.dwProcessId; g_sdata.retcode = pi.dwProcessId;
PostMessage(g_sdata.hwnd, WM_MAKENSIS_PROCESSCOMPLETE, 0, 0); PostMessage(g_sdata.hwnd, WM_MAKENSIS_PROCESSCOMPLETE, 0, 0);

View file

@ -156,7 +156,7 @@ int compressor_strings[] = {IDS_SCRIPT,
extern const TCHAR* NSISW_VERSION; extern const TCHAR* NSISW_VERSION;
DWORD WINAPI MakeNSISProc(LPVOID p); DWORD WINAPI MakeNSISProc(LPVOID TreadParam);
INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK DialogResize(HWND hWnd, LPARAM /* unused*/); BOOL CALLBACK DialogResize(HWND hWnd, LPARAM /* unused*/);
INT_PTR CALLBACK AboutProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK AboutProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);

View file

@ -227,6 +227,10 @@ typedef DWORDLONG ULONGLONG,*PULONGLONG;
# define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0) # define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
#endif #endif
#ifndef IS_HIGH_SURROGATE
# define IS_HIGH_SURROGATE(wch) (((wch) >= 0xd800) && ((wch) <= 0xdbff))
#endif
// functions // functions
// Anders: MSVC's swprintf is non standard, use _snwprintf when you really mean swprintf // Anders: MSVC's swprintf is non standard, use _snwprintf when you really mean swprintf