From e4d2f9992bc72368b0b1f439b32c169142209b0b Mon Sep 17 00:00:00 2001 From: Didier Raboud Date: Sat, 31 Mar 2018 20:38:43 +0200 Subject: Import Upstream version 3.01 --- Source/Tests/compression.cpp | 8 +- Source/Tests/mmap.cpp | 5 +- Source/Tests/textrunner.cpp | 5 ++ Source/Tests/winchar.cpp | 7 +- Source/build.cpp | 7 ++ Source/build.h | 8 +- Source/exehead/Ui.c | 2 +- Source/exehead/exec.c | 41 ++++++---- Source/makenssi.cpp | 36 +++++--- Source/script.cpp | 190 +++++++++++++++++-------------------------- Source/utf.cpp | 3 + Source/util.cpp | 50 ++++++++++-- Source/util.h | 8 +- Source/winchar.cpp | 4 +- 14 files changed, 206 insertions(+), 168 deletions(-) (limited to 'Source') diff --git a/Source/Tests/compression.cpp b/Source/Tests/compression.cpp index f38ab3a..f586d48 100755 --- a/Source/Tests/compression.cpp +++ b/Source/Tests/compression.cpp @@ -17,8 +17,12 @@ public: void randData(IGrowBuf &buf, int kb) { srand(time(0)); +#define IsBug1156(r) ( ((r) & 0x80) == 0x80 ) for (int i = 0; i < kb; i++) { - int r = rand(); + int r; + do + r = rand(); + while (IsBug1156(r)); // Temporary workaround for https://sf.net/p/nsis/bugs/1156/#zlibCompressionTest loops endlessly for (size_t j = 0; j < 1024/sizeof(int); j++) { buf.add(&r, sizeof(int)); } @@ -89,11 +93,13 @@ public: CPPUNIT_ASSERT_EQUAL( C_OK, compressor.Init(9, 1 << 23) ); testCompressDecompress(1024, compressor, decompressor); +#ifndef NSIS_TESTS_FASTCOMPRESSIONONLY CPPUNIT_ASSERT_EQUAL( C_OK, compressor.Init(9, 1 << 23) ); testCompressDecompress(8*1024, compressor, decompressor); CPPUNIT_ASSERT_EQUAL( C_OK, compressor.Init(9, 1 << 23) ); testCompressDecompress(32*1024, compressor, decompressor); +#endif } }; diff --git a/Source/Tests/mmap.cpp b/Source/Tests/mmap.cpp index 8e04b5e..9ed0e5b 100755 --- a/Source/Tests/mmap.cpp +++ b/Source/Tests/mmap.cpp @@ -9,11 +9,10 @@ using namespace std; // for std::min -int g_display_errors = 1; -FILE *g_output = stderr; void quit() { - _ftprintf(g_output, _T("MMap quit\n")); + extern FILE *g_errout; + _ftprintf(g_errout, _T("MMap quit\n")); } class MMapTest : public CppUnit::TestFixture { diff --git a/Source/Tests/textrunner.cpp b/Source/Tests/textrunner.cpp index 171a578..9f116fa 100755 --- a/Source/Tests/textrunner.cpp +++ b/Source/Tests/textrunner.cpp @@ -1,9 +1,14 @@ #include #include #include +#include "../util.h" // for NSISRT_* + +NSISRT_DEFINEGLOBALS(); int main(int argc, char* argv[]) { + if (!NSISRT_Initialize()) return 1; + // Get the top level suite from the registry CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); diff --git a/Source/Tests/winchar.cpp b/Source/Tests/winchar.cpp index 6fdb3bc..bd6b780 100755 --- a/Source/Tests/winchar.cpp +++ b/Source/Tests/winchar.cpp @@ -28,22 +28,21 @@ class WinCharTest : public CppUnit::TestFixture { public: void setUp() { - NSISRT_Initialize(); } void testFromTchar() { WINWCHAR test[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 }; WINWCHAR *dyn = WinWStrDupFromTChar(_T("test")); - CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) ); + CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, sizeof(test)) ); free(dyn); dyn = WinWStrDupFromChar("test"); - CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) ); + CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, sizeof(test)) ); free(dyn); dyn = WinWStrDupFromWC(L"test"); - CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) ); + CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, sizeof(test)) ); free(dyn); } diff --git a/Source/build.cpp b/Source/build.cpp index 44689e9..639951d 100755 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -3730,6 +3730,13 @@ int CEXEBuild::DeclaredUserVar(const TCHAR *szVarName) } +int CEXEBuild::GetUnsafeUserVarIndex(LineParser &line, int token) +{ + TCHAR *p = line.gettoken_str(token); + int idx = (*p == _T('$') && *++p) ? m_UserVarNames.get(p) : -1; + if (idx >= 0 && m_UserVarNames.get_reference(idx) >= 0) m_UserVarNames.inc_reference(idx); + return idx; +} int CEXEBuild::GetUserVarIndex(LineParser &line, int token) { TCHAR *p = line.gettoken_str(token); diff --git a/Source/build.h b/Source/build.h index 1be2979..d08399e 100755 --- a/Source/build.h +++ b/Source/build.h @@ -82,12 +82,13 @@ namespace MakensisAPI { }; #ifdef _WIN32 enum sndmsg_e { - QUERYHOST = WM_APP // QUERYHOST_e in wParam + QUERYHOST = WM_APP // [0x03000000] QUERYHOST_e in wParam. MUST return 0 for unknown QUERYHOST_e values! }; +#endif enum QUERYHOST_e { - QH_OUTPUTCHARSET = 1 // return (wincodepage+1) or 0 for default (This encoding is used by stdout and the notify messages) + QH_OUTPUTCHARSET = 1, // [0x03000000] return (wincodepage+1) or 0 for default (This encoding is used by stdout, stderr and the notify messages) + QH_ENABLESTDERR // [0x03001000] return 1 to output error messages to stderr or 0 to output error messages to stdout }; -#endif } #define PAGE_CUSTOM 0 @@ -410,6 +411,7 @@ class CEXEBuild { int disable_window_icon; // User variables stuff + int GetUnsafeUserVarIndex(LineParser &line, int token); int GetUserVarIndex(LineParser &line, int token); // Added by ramon 3 jun 2003 UserVarsStringList m_UserVarNames; diff --git a/Source/exehead/Ui.c b/Source/exehead/Ui.c index 5a02104..6e6b3bf 100755 --- a/Source/exehead/Ui.c +++ b/Source/exehead/Ui.c @@ -232,7 +232,7 @@ FORCE_INLINE int NSISCALL ui_doinstall(void) // detect default language // more information at: - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_0xrn.asp + // https://web.archive.org/web/20060618155426/http://msdn.microsoft.com/library/en-us/intl/nls_0xrn.asp LANGID (WINAPI *GUDUIL)(); diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c index a30e345..6d5702b 100755 --- a/Source/exehead/exec.c +++ b/Source/exehead/exec.c @@ -122,12 +122,23 @@ void NSISCALL update_status_text_buf1(int strtab) update_status_text(strtab, g_bufs[1]); } -static INT_PTR NSISCALL GetIntPtrFromParm(int id_) +#ifdef _WIN64 +static INT_PTR NSISCALL GetIntPtrFromParm(int id) { - return strtoiptr(GetNSISStringTT(g_parms[id_])); + return strtoiptr(GetNSISStringTT(g_parms[id])); } +#else +#define GetIntPtrFromParm(id_) ( (INT32)(GetIntFromParmEx(id_).LowPart) ) +#endif #define GetHwndFromParm(id_) ( (HWND)GetIntPtrFromParm(id_) ) #define GetIntFromParm(id_) ( (INT32)(UINT32)GetIntPtrFromParm(id_) ) +static LARGE_INTEGER GetIntFromParmEx(int id) +{ + LARGE_INTEGER v; + const TCHAR *p = GetNSISStringTT(g_parms[id]); + v.LowPart = myatoi(p), v.HighPart = *p; + return v; // HighPart is non-zero if the string is not empty +} // NB - USE CAUTION when rearranging code to make use of the new return value of // this function - be sure the parm being accessed is not modified before the call. @@ -616,20 +627,18 @@ static int NSISCALL ExecuteEntry(entry *entry_) break; case EW_ASSIGNVAR: { - int newlen=GetIntFromParm(2); - int start=GetIntFromParm(3); - int l; - TCHAR *p=var0; - TCHAR *buf0=GetStringFromParm(0x01); + LARGE_INTEGER newlenex=GetIntFromParmEx(2); + int start=GetIntFromParm(3), newlen=newlenex.LowPart; + TCHAR *p=var0, *buf0=GetStringFromParm(0x01); + int srclen=mystrlen(buf0); *p=0; - if (!parm2 || newlen) + if (!newlenex.HighPart) newlen=srclen; // "StrCpy $1 $2 $3" where $3="" + if (newlen) { - l=mystrlen(buf0); - - if (start<0) start=l+start; + if (start<0) start=srclen+start; if (start>=0) { - if (start>l) start=l; + if (start>srclen) start=srclen; mystrcpy(p,buf0+start); if (newlen) { @@ -1702,10 +1711,12 @@ static int NSISCALL ExecuteEntry(entry *entry_) #ifdef NSIS_LOCKWINDOW_SUPPORT case EW_LOCKWINDOW: { - // ui_dlg_visible is 1 or 0, so is parm0 + // ui_dlg_visible is 1 or 0, so is parm0. It is used because WM_SETREDRAW will toggle WS_VISIBLE! + // BUGBUG: This has unfortunate consequences when used in + // combination with BringToFront on the first page. + // See http://forums.winamp.com/showthread.php?t=397781 for details. SendMessage(g_hwnd, WM_SETREDRAW, parm0 & ui_dlg_visible, 0); - if ( parm0 ) - InvalidateRect(g_hwnd, NULL, FALSE); + if (parm0) InvalidateRect(g_hwnd, NULL, FALSE); break; } #endif //NSIS_LOCKWINDOW_SUPPORT diff --git a/Source/makenssi.cpp b/Source/makenssi.cpp index 0a17290..2c3b4e2 100755 --- a/Source/makenssi.cpp +++ b/Source/makenssi.cpp @@ -36,14 +36,13 @@ using namespace std; +NSISRT_DEFINEGLOBALS(); bool g_dopause=false, g_warnaserror=false; -int g_display_errors=1; -FILE *g_output; NStreamEncoding g_outputenc; #ifdef _WIN32 UINT g_wincon_orgoutcp; #ifdef _UNICODE -WINSIO_OSDATA g_osdata_stdout; +WINSIO_OSDATA g_osdata_stdout, g_osdata_stderr; #endif #endif const TCHAR *g_argv0=0; @@ -71,7 +70,8 @@ static void myatexit() { dopause(); ResetPrintColor(); - if (g_output != stdout && g_output) fclose(g_output); + if (g_output != stdout && g_output) fclose(g_output), g_output = 0; + if (g_errout != stderr && g_errout) fclose(g_errout), g_errout = 0; #ifdef _WIN32 SetConsoleOutputCP(g_wincon_orgoutcp); #endif @@ -108,7 +108,11 @@ static DWORD WINAPI sigint_event_msg_handler(LPVOID ThreadParam) return 0; } -#endif + +static UINT_PTR QueryHost(HWND hHost, UINT_PTR wp, UINT_PTR lp=0, UINT_PTR def=0) { return hHost ? SendMessage(hHost, MakensisAPI::QUERYHOST, wp, lp) : def; } +#else //! _WIN32 +static inline UINT_PTR QueryHost(HWND hHost, UINT_PTR wp, UINT_PTR lp=0, UINT_PTR def=0) { return def; } +#endif //~ _WIN32 static void init_signals(HWND notify_hwnd) { @@ -285,6 +289,7 @@ static inline int makensismain(int argc, TCHAR **argv) allow_unaligned_data_access(); #endif assert(sizeof(UINT_PTR) == sizeof(void*)); + assert('a' + 25 == 'z' && '0' < 'A' && 'A' < 'a'); // ASCII, do you speak it? assert(sizeof(wchar_t) > 1 && sizeof(wchar_t) <= 4); assert(sizeof(WINWCHAR) == 2 && sizeof(WORD) == 2); assert(sizeof(WINWCHAR) == sizeof(WCHAR)); // Not really required but if WCHAR changes we need to know @@ -293,7 +298,7 @@ static inline int makensismain(int argc, TCHAR **argv) if (!NSISRT_Initialize()) { - _ftprintf(stdout,_T("NSISRT_Initialize failed!\n")); + _ftprintf(stderr,_T("NSISRT_Initialize failed!\n")); return 1; } @@ -301,11 +306,10 @@ static inline int makensismain(int argc, TCHAR **argv) const TCHAR*stdoutredirname=0; NStreamEncoding inputenc, &outputenc = g_outputenc; int argpos=0; - bool in_files=false; - bool do_cd=true; + bool do_cd=true, noconfig=false; bool no_logo=true; - bool initialparsefail=false; - bool noconfig=false; + bool initialparsefail=false, in_files=false; + bool oneoutputstream=false; signed char pponly=0; #ifdef _WIN32 signed char outputbom=1; @@ -390,17 +394,23 @@ static inline int makensismain(int argc, TCHAR **argv) FILE*stdoutredir=stdout; if (stdoutredirname) stdoutredir=my_fopen(stdoutredirname,"w"); g_output=stdoutredir; - if (!g_output) g_output=stdout; + if (!g_output) + g_output=stdout; // We could not open stdoutredirname, fall back to stdout + else if (stdoutredirname) + oneoutputstream=true; // -O used, put all output in the same file + if (oneoutputstream || !(1 & QueryHost(hostnotifyhandle,MakensisAPI::QH_ENABLESTDERR,0,1))) + g_errout=g_output; #if defined(_WIN32) && defined(_UNICODE) if (hostnotifyhandle) { // The host can override the output format if they want to LPARAM lp=MAKELONG(outputenc.GetCodepage(),outputbom); - LRESULT mr=SendMessage(hostnotifyhandle,MakensisAPI::QUERYHOST,MakensisAPI::QH_OUTPUTCHARSET,lp); + LRESULT mr=QueryHost(hostnotifyhandle,MakensisAPI::QH_OUTPUTCHARSET,lp); if (mr) outputenc.SetCodepage((WORD)(--mr)), outputbom = -1; } - if (!WinStdIO_OStreamInit(g_osdata_stdout,g_output,outputenc.GetCodepage(),outputbom)) + if (( !WinStdIO_OStreamInit(g_osdata_stdout,g_output,outputenc.GetCodepage(),outputbom)) + || (g_errout != g_output && !WinStdIO_OStreamInit(g_osdata_stderr,g_errout,outputenc.GetCodepage(),outputbom))) { assert(!"StdIO init failed"); return 1; diff --git a/Source/script.cpp b/Source/script.cpp index bb390bc..f921d51 100755 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -77,6 +77,36 @@ static UINT read_line_helper(NStreamLineReader&lr, TCHAR*buf, UINT cch) return ++cch - eof; } +#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT +static bool LookupWinSysColorId(const TCHAR*Str, UINT&Clr) +{ + static const struct { const TCHAR*Name; UINT Id; } map[] = { // Note: This list is incomplete. + { _T("WINDOW"), 5 }, { _T("WINDOWTEXT"), 8 }, + { _T("3DFACE"), 15 }, { _T("BTNTEXT"), 18 }, // "Three-dimensional display elements and dialog box" + { _T("HIGHLIGHT"), 13 }, { _T("HIGHLIGHTTEXT"), 14 }, // "Item(s) selected in a control" + { _T("GRAYTEXT"), 17 }, // "Grayed (disabled) text" + { _T("HOTLIGHT"), 26 }, // "Color for a hyperlink or hot-tracked item" (Win98+) + }; + for (UINT i = 0; i < COUNTOF(map); ++i) + if (!_tcsicmp(map[i].Name, Str)) return (Clr = map[i].Id, true); + return false; +} +static UINT ParseCtlColor(const TCHAR*Str, int&CCFlags, int CCFlagmask) +{ + UINT clr, v; + TCHAR buf[7+!0], *pEnd; + my_strncpy(buf, Str, 7+!0), buf[7] = '\0'; + if (!_tcscmp(_T("SYSCLR:"), buf)) + { + CCFlags |= ((CC_TEXT_SYS|CC_BK_SYS) & CCFlagmask); // ExeHead must call GetSysColor + if (!LookupWinSysColorId(Str+7, clr)) clr = _tcstoul(Str+7, &pEnd, 0); + } + else + v = _tcstoul(Str, &pEnd, 16), clr = ((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16); + return clr; +} +#endif + #ifdef NSIS_SUPPORT_STANDARD_PREDEFINES // Added by Sunil Kamath 11 June 2003 TCHAR *CEXEBuild::set_file_predefine(const TCHAR *filename) @@ -3205,7 +3235,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case 1: comp=4; break; case 2: comp=5, validparams=!!*(define=line.gettoken_str(2)); break; case 3: cmpv=line.gettoken_int(3,&validparams); break; - default: comp=-1; + default: forceutf8=comp=-1; } if (!validparams || comp == -1) PRINTHELP() tstring compile; @@ -4458,69 +4488,41 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.which=EW_SETCTLCOLORS; ent.offsets[0]=add_string(line.gettoken_str(1)); ctlcolors c={0, }; - int a = 2; - if (!_tcsicmp(line.gettoken_str(2),_T("/BRANDING"))) - a++; - TCHAR *p; - if (a == 2 && line.getnumtokens() == 5) { + int a = 2, ctok = line.getnumtokens(); + if (!_tcsicmp(line.gettoken_str(2),_T("/BRANDING"))) a+=1; + if (!_tcsicmp(line.gettoken_str(2),_T("/RESET"))) { if (ctok != 3) return PS_ERROR; else a+=2; } + if (a == 2 && ctok == 5) { ERROR_MSG(_T("Error: SetCtlColors expected 3 parameters, got 4\n")); return PS_ERROR; } - if (!_tcsicmp(line.gettoken_str(a+1),_T("transparent"))) { - c.flags|=CC_BKB; - c.lbStyle=BS_NULL; - c.bkmode=TRANSPARENT; + c.flags|=CC_BKB, c.lbStyle=BS_NULL, c.bkmode=TRANSPARENT; } - else { - p=line.gettoken_str(a+1); - if (*p) { - int v=_tcstoul(p,&p,16); - c.bkc=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16); - c.flags|=CC_BK|CC_BKB; - } - c.lbStyle=BS_SOLID; - c.bkmode=OPAQUE; - } - - p=line.gettoken_str(a); - if (*p) { - int v=_tcstoul(p,&p,16); - c.text=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16); - c.flags|=CC_TEXT; + else { // Parse background color + c.lbStyle=BS_SOLID, c.bkmode=OPAQUE; + if (*(p=line.gettoken_str(a+1))) + c.flags|=CC_BK|CC_BKB, c.bkc=ParseCtlColor(p, c.flags, CC_BK_SYS); } - - if (a == 3) - { + if (*(p=line.gettoken_str(a))) // Set text color? + c.flags|=CC_TEXT, c.text=ParseCtlColor(p, c.flags, CC_TEXT_SYS); + if (a == 3) { // Handle /BRANDING c.flags|=CC_BK|CC_BKB; c.lbStyle=BS_NULL; - if (!*line.gettoken_str(a+1)) - { - c.bkc=COLOR_BTNFACE; - c.flags|=CC_BK_SYS; - } + if (!*line.gettoken_str(a+1)) c.bkc=COLOR_BTNFACE, c.flags|=CC_BK_SYS; c.flags|=CC_TEXT; - if (!*line.gettoken_str(a)) - { - c.text=COLOR_BTNFACE; - c.flags|=CC_TEXT_SYS; - } + if (!*line.gettoken_str(a)) c.text=COLOR_BTNFACE, c.flags|=CC_TEXT_SYS; c.bkmode=OPAQUE; } - + if (a == 4) c.bkmode=OPAQUE, c.flags=0, c.bkb = 0; // Experimental and undocumented /RESET, a formal way of doing SetCtlColors $hCtl "" "" assert(sizeof(ctlcolors64) > sizeof(ctlcolors)); int i, l=cur_ctlcolors->getlen()/sizeof(ctlcolors), pad=is_target_64bit()?sizeof(ctlcolors64)-sizeof(ctlcolors):0; - for (i=0; iget()+i,&c,sizeof(ctlcolors))) { ent.offsets[1]=i*(sizeof(ctlcolors)+pad); break; } - } - if (i>=l) { - ent.offsets[1]=cur_ctlcolors->add(&c,sizeof(ctlcolors))+(l*pad); - } - + if (i>=l) ent.offsets[1]=cur_ctlcolors->add(&c,sizeof(ctlcolors))+(l*pad); SCRIPT_MSG(_T("SetCtlColors: hwnd=%") NPRIs _T(" %") NPRIs _T("text=%") NPRIs _T(" background=%") NPRIs _T("\n"),line.gettoken_str(1),a==2?_T(""):_T("/BRANDING "),line.gettoken_str(a),line.gettoken_str(a+1)); } return add_entry(&ent); @@ -4599,8 +4601,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.which=EW_SHOWWINDOW; ent.offsets[0]=add_asciistring(_T("$HWNDPARENT")); ent.offsets[1]=add_asciistring(_T("5")/*SW_SHOW*/); - ret = add_entry(&ent); - if (ret != PS_OK) return ret; + if ((ret = add_entry(&ent)) != PS_OK) return ret; ent.which=EW_BRINGTOFRONT; ent.offsets[0]=0; ent.offsets[1]=0; @@ -5041,22 +5042,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) const TCHAR* msgprefix = _T(""); int idx = -1; if (TOK_STRCPY == which_token) - { idx = GetUserVarIndex(line, 1); - } else - { - msgprefix = _T("Unsafe"); - TCHAR *p = line.gettoken_str(1); - if (*p == _T('$') && *++p) idx = m_UserVarNames.get(p); - if (-1 != idx && m_UserVarNames.get_reference(idx) != -1) m_UserVarNames.inc_reference(idx); - } + idx = GetUnsafeUserVarIndex(line, 1), msgprefix = _T("Unsafe"); if (idx < 0) PRINTHELP() - ent.offsets[0]=idx; - ent.offsets[1]=add_string(line.gettoken_str(2)); - ent.offsets[2]=add_string(line.gettoken_str(3)); - ent.offsets[3]=add_string(line.gettoken_str(4)); - + ent.offsets[0]=idx; // Destination variable + ent.offsets[1]=add_string(line.gettoken_str(2)); // Source string + ent.offsets[2]=add_string(line.gettoken_str(3)); // Optional MaxLen + ent.offsets[3]=add_string(line.gettoken_str(4)); // Optional StartOffset SCRIPT_MSG(_T("%") NPRIs _T("StrCpy %") NPRIs _T(" \"%") NPRIs _T("\" (%") NPRIs _T(") (%") NPRIs _T(")\n"), msgprefix,line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4)); return add_entry(&ent); @@ -5080,11 +5073,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_GETCURRENTADDR: ent.which=EW_ASSIGNVAR; - ent.offsets[0]=GetUserVarIndex(line, 1); + if ((ent.offsets[0]=GetUserVarIndex(line, 1)) < 0) PRINTHELP() ent.offsets[1]=add_intstring(1+(cur_header->blocks[NB_ENTRIES].num)); - if (ent.offsets[0] < 0) PRINTHELP() - ent.offsets[2]=0; - ent.offsets[3]=0; + ent.offsets[2]=ent.offsets[3]=0; SCRIPT_MSG(_T("GetCurrentAddress: %") NPRIs _T("\n"),line.gettoken_str(1)); return add_entry(&ent); case TOK_STRCMP: @@ -5107,18 +5098,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_ERROR; } ent.which=EW_ASSIGNVAR; - ent.offsets[0]=GetUserVarIndex(line, 2); + if ((ent.offsets[0]=GetUserVarIndex(line, 2)) < 0) PRINTHELP() ent.offsets[1]=add_intstring(high); - ent.offsets[2]=0; - ent.offsets[3]=0; - if (ent.offsets[0]<0) PRINTHELP() - add_entry(&ent); - - ent.offsets[0]=GetUserVarIndex(line, 3); + ent.offsets[2]=ent.offsets[3]=0; + if (PS_OK != add_entry(&ent)) return PS_ERROR; + if ((ent.offsets[0]=GetUserVarIndex(line, 3)) < 0) PRINTHELP() ent.offsets[1]=add_intstring(low); - ent.offsets[2]=0; - ent.offsets[3]=0; - if (ent.offsets[0]<0) PRINTHELP() + ent.offsets[2]=ent.offsets[3]=0; SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T(" (%u,%u)->(%") NPRIs _T(",%") NPRIs _T(")\n"), cmdname,line.gettoken_str(1),high,low,line.gettoken_str(2),line.gettoken_str(3)); } @@ -5152,22 +5138,16 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) unsigned long long ll = (st.st_mtime * 10000000LL) + 116444736000000000LL; high = (DWORD) (ll >> 32), low = (DWORD) ll; #endif - ent.which=EW_ASSIGNVAR; - ent.offsets[0]=GetUserVarIndex(line, 2); + if ((ent.offsets[0]=GetUserVarIndex(line, 2)) < 0) PRINTHELP() wsprintf(buf,_T("%u"),high); ent.offsets[1]=add_string(buf); - ent.offsets[2]=0; - ent.offsets[3]=0; - if (ent.offsets[0]<0) PRINTHELP() - add_entry(&ent); - - ent.offsets[0]=GetUserVarIndex(line, 3); + ent.offsets[2]=ent.offsets[3]=0; + if (PS_OK != add_entry(&ent)) return PS_ERROR; + if ((ent.offsets[0]=GetUserVarIndex(line, 3)) < 0) PRINTHELP() wsprintf(buf,_T("%u"),low); ent.offsets[1]=add_string(buf); - ent.offsets[2]=0; - ent.offsets[3]=0; - if (ent.offsets[0]<0) PRINTHELP() + ent.offsets[2]=ent.offsets[3]=0; SCRIPT_MSG(_T("GetFileTimeLocal: %") NPRIs _T(" (%u,%u)->(%") NPRIs _T(",%") NPRIs _T(")\n"), line.gettoken_str(1),high,low,line.gettoken_str(2),line.gettoken_str(3)); } @@ -6147,7 +6127,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) PRINTHELP(); case TOK__PLUGINCOMMAND: { - int ret; tstring command, dllPath; if (!m_pPlugins->GetCommandInfo(line.gettoken_str(0), command, dllPath)) @@ -6157,17 +6136,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } tstring dllName = get_file_name(dllPath); - int data_handle = m_pPlugins->GetDllDataHandle(!!uninstall_mode, command); + int data_handle = m_pPlugins->GetDllDataHandle(!!uninstall_mode, command), ret; if (uninstall_mode) uninst_plugin_used = true; else plugin_used = true; // Initialize $PLUGINSDIR ent.which=EW_CALL; ent.offsets[0]=ns_func.add(uninstall_mode?_T("un.Initialize_____Plugins"):_T("Initialize_____Plugins"),0); - ret=add_entry(&ent); - if (ret != PS_OK) { - return ret; - } + if ((ret=add_entry(&ent)) != PS_OK) return ret; // DLL name on the users machine TCHAR tempDLL[NSIS_MAX_STRLEN]; @@ -6215,17 +6191,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[3]=0xffffffff; ent.offsets[4]=0xffffffff; ent.offsets[5]=DefineInnerLangString(NLF_FILE_ERROR); - ret=add_entry(&ent); - if (ret != PS_OK) { - return ret; - } + if ((ret=add_entry(&ent)) != PS_OK) return ret; } // SetDetailsPrint lastused ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1); - if (ret != PS_OK) { - return ret; - } + if (ret != PS_OK) return ret; // Call the DLL tstring funcname = get_string_suffix(command, _T("::")); @@ -6234,8 +6205,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) int i = 1; int nounload = 0; if (!_tcsicmp(line.gettoken_str(i), _T("/NOUNLOAD"))) { - i++; - nounload++; + i++, nounload++; } // First push dll args @@ -6249,10 +6219,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (!_tcsicmp(line.gettoken_str(w), _T("/NOUNLOAD"))) nounloadmisused=1; ent.offsets[1]=0; ent.offsets[2]=0; - ret=add_entry(&ent); - if (ret != PS_OK) { - return ret; - } + if ((ret=add_entry(&ent)) != PS_OK) return ret; SCRIPT_MSG(_T(" %") NPRIs,line.gettoken_str(i)); } SCRIPT_MSG(_T("\n")); @@ -6266,10 +6233,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[2]=0; ent.offsets[3]=nounload|build_plugin_unload; ent.offsets[4]=1; - ret=add_entry(&ent); - if (ret != PS_OK) { - return ret; - } + if ((ret=add_entry(&ent)) != PS_OK) return ret; DefineInnerLangString(NLF_SYMBOL_NOT_FOUND); DefineInnerLangString(NLF_COULD_NOT_LOAD); @@ -6286,8 +6250,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) // Call [un.]Initialize_____Plugins ent.which=EW_CALL; ent.offsets[0]=ns_func.add(uninstall_mode?_T("un.Initialize_____Plugins"):_T("Initialize_____Plugins"),0); - ret=add_entry(&ent); - if (ret != PS_OK) return ret; + if ((ret=add_entry(&ent)) != PS_OK) return ret; // SetDetailsPrint lastused ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1); if (ret != PS_OK) return ret; @@ -6297,9 +6260,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_PLUGINDIR: case TOK__PLUGINCOMMAND: case TOK_INITPLUGINSDIR: - { ERROR_MSG(_T("Error: %") NPRIs _T(" specified, NSIS_CONFIG_PLUGIN_SUPPORT not defined.\n"),line.gettoken_str(0)); - } return PS_ERROR; #endif// NSIS_CONFIG_PLUGIN_SUPPORT @@ -6308,8 +6269,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG(_T("LockWindow: lock state=%d\n"),line.gettoken_str(1)); ent.which=EW_LOCKWINDOW; ent.offsets[0]=line.gettoken_enum(1,_T("on\0off\0")); - if (ent.offsets[0] == -1) - PRINTHELP(); + if (ent.offsets[0] == -1) PRINTHELP(); return add_entry(&ent); #else case TOK_LOCKWINDOW: diff --git a/Source/utf.cpp b/Source/utf.cpp index 8d0f842..7658552 100755 --- a/Source/utf.cpp +++ b/Source/utf.cpp @@ -32,6 +32,9 @@ bool StrSetUTF16LE(tstring&dest, const void*src) if (!cec.Initialize(-1,NStreamEncoding::UTF16LE)) return false; src = (const void*) cec.Convert(src); if (!src) return false; +#endif +#ifdef C_ASSERT + C_ASSERT(sizeof(tstring::value_type) >= sizeof(wchar_t)); #endif try { dest = (wchar_t*) src; } catch(...) { return false; } return true; diff --git a/Source/util.cpp b/Source/util.cpp index 43e6ac1..13c0926 100755 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -56,7 +56,7 @@ namespace Apple { // defines struct section using namespace std; extern int g_display_errors; -extern FILE *g_output; +extern FILE *g_output, *g_errout; double my_wtof(const wchar_t *str) { @@ -203,7 +203,7 @@ static char g_nrt_iconv_narrowlocbuf[50], *g_nrt_iconv_narrowloc = 0; #ifdef HAVE_LANGINFO_H // BUGBUG: scons needs to check for HAVE_LANGINFO_H and HAVE_NL_LANGINFO support? #include #endif -bool NSISRT_Initialize() +bool NSISRT_Initialize() // Init function for POSIX { iconvdescriptor id; g_nrt_iconv_narrowloc = const_cast(""); // Use "" and not "char", "char" is a GNU extension? @@ -1019,7 +1019,13 @@ bool GetFileSize64(HANDLE hFile, ULARGE_INTEGER &uli) uli.LowPart = GetFileSize(hFile, &uli.HighPart); return INVALID_FILE_SIZE != uli.LowPart || !GetLastError(); } -#endif +static HANDLE NSISRT_GetConsoleScreenHandle() +{ + DWORD cm; + HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); + return GetConsoleMode(hCon, &cm) ? hCon : GetStdHandle(STD_ERROR_HANDLE); +} +#endif //~ _WIN32 #if defined(_WIN32) && defined(_UNICODE) && defined(MAKENSIS) #include // for _get_osfhandle bool WINAPI WinStdIO_OStreamInit(WINSIO_OSDATA&osd, FILE*strm, WORD cp, int bom) @@ -1073,17 +1079,23 @@ end: strm.Detach(); return retval; } +static WINSIO_OSDATA*WinStdIO_GetNativeStreamData(FILE*strm) +{ + extern WINSIO_OSDATA g_osdata_stdout, g_osdata_stderr; + if (g_output == strm) return &g_osdata_stdout; + return g_errout == strm ? &g_osdata_stderr : NULL; +} int WINAPI WinStdIO_vfwprintf(FILE*strm, const wchar_t*Fmt, va_list val) { - if (g_output == strm && Fmt) + WINSIO_OSDATA*pOSD; + if (Fmt && (pOSD = WinStdIO_GetNativeStreamData(strm))) { - extern WINSIO_OSDATA g_osdata_stdout; ExpandoString buf; errno = ENOMEM; const size_t cchfmt = buf.StrFmt(Fmt, val, false); UINT cch = (UINT) cchfmt; assert(sizeof(size_t) <= 4 || cchfmt == cch); - if (cch && !WinStdIO_OStreamWrite(g_osdata_stdout, buf, cch)) + if (cch && !WinStdIO_OStreamWrite(*pOSD, buf, cch)) { cch = 0, errno = EIO; } @@ -1107,12 +1119,36 @@ int WinStdIO_wprintf(const wchar_t*Fmt, ...) va_end(val); return rv; } +static HANDLE NSISRT_FastGetConsoleScreenHandle() +{ + extern WINSIO_OSDATA g_osdata_stdout, g_osdata_stderr; + return WinStdIO_IsConsole(g_osdata_stdout) ? g_osdata_stdout.hNative : g_osdata_stderr.hNative; +} +bool NSISRT_Initialize() // Init function for MakeNSIS Win32 +{ + static bool inited = false; + if (inited) return inited; + extern WINSIO_OSDATA g_osdata_stdout, g_osdata_stderr; + g_osdata_stderr.mode = g_osdata_stdout.mode = 0, g_osdata_stderr.hNative = g_osdata_stdout.hNative = 0; + return (inited = true); +} +#elif defined(_WIN32) +#define NSISRT_FastGetConsoleScreenHandle NSISRT_GetConsoleScreenHandle +bool NSISRT_Initialize() { return true; } // Init function for non-MakeNSIS Win32 (NSISRT_DEFINEGLOBALS sets g_output and g_errout) #endif +void PrintColorFmtErrMsg(const TCHAR *fmtstr, va_list args) +{ + PrintColorFmtMsg_WARN(_T("")); // flush g_output + SetPrintColorERR(); + _vftprintf(g_errout, fmtstr, args), fflush(g_errout); + ResetPrintColor(); +} + void PrintColorFmtMsg(unsigned int type, const TCHAR *fmtstr, va_list args) { #ifdef _WIN32 - const HANDLE hWin32Con = GetStdHandle(STD_OUTPUT_HANDLE); + HANDLE hWin32Con = NSISRT_FastGetConsoleScreenHandle(); static INT32 contxtattrbak = -1; WORD txtattr = 0; if (contxtattrbak < 0) diff --git a/Source/util.h b/Source/util.h index ea148ce..eddd49e 100755 --- a/Source/util.h +++ b/Source/util.h @@ -105,6 +105,8 @@ public: int sane_system(const TCHAR *command); +#define NSISRT_DEFINEGLOBALS() int g_display_errors=1; FILE *g_output=stdout, *g_errout=stderr +void PrintColorFmtErrMsg(const TCHAR *fmtstr, va_list args); void PrintColorFmtMsg(unsigned int type, const TCHAR *fmtstr, va_list args); void FlushOutputAndResetPrintColor(); #ifdef _WIN32 @@ -161,11 +163,12 @@ inline void PrintColorFmtMsg_ERR(const TCHAR *fmtstr, ...) { va_list val; va_start(val,fmtstr); - PrintColorFmtMsg(2, fmtstr, val); + PrintColorFmtErrMsg(fmtstr, val); va_end(val); } +bool NSISRT_Initialize(); #ifndef _WIN32 // iconv const inconsistency workaround by Alexandre Oliva template @@ -233,7 +236,6 @@ BOOL IsValidCodePage(UINT CodePage); #else #define CharNext CharNextA #endif -bool NSISRT_Initialize(); #define NSISRT_free(p) ( free((void*)(p)) ) wchar_t* NSISRT_mbtowc(const char *Str); char* NSISRT_wctomb(const wchar_t *Str); @@ -260,8 +262,6 @@ int my_open(const TCHAR *pathname, int flags); #else // _WIN32 -#define NSISRT_Initialize() (true) - #define my_convert(x) (x) #define my_convert_free(x) diff --git a/Source/winchar.cpp b/Source/winchar.cpp index 0e11c6f..864b386 100755 --- a/Source/winchar.cpp +++ b/Source/winchar.cpp @@ -46,7 +46,7 @@ int WinWStrNICmpASCII(const WINWCHAR *a, const char *b, size_t n) WINWCHAR* WinWStrDupFromChar(const char *s, unsigned int cp) { int cch = MultiByteToWideChar(cp, 0, s, -1, 0, 0); - wchar_t *p = (wchar_t*) malloc(cch); + wchar_t *p = (wchar_t*) malloc(cch * sizeof(wchar_t)); if (p) { MultiByteToWideChar(cp, 0, s, -1, p, cch); @@ -111,7 +111,7 @@ WINWCHAR* WinWStrDupFromWC(const wchar_t *s) // NOTE: Anything outside the ASCII range will not convert correctly! size_t cch = wcslen(s); WINWCHAR* p = (WINWCHAR*) malloc(++cch * 2); - if (p) for (size_t i = 0; i < cch; ++i) p[i] = (unsigned char) s[i]; + if (p) for (size_t i = 0; i < cch; ++i) p[i] = FIX_ENDIAN_INT16(s[i]); return p; #endif } -- cgit v1.2.3