diff options
Diffstat (limited to 'Source')
-rwxr-xr-x | Source/Tests/compression.cpp | 8 | ||||
-rwxr-xr-x | Source/Tests/mmap.cpp | 5 | ||||
-rwxr-xr-x | Source/Tests/textrunner.cpp | 5 | ||||
-rwxr-xr-x | Source/Tests/winchar.cpp | 7 | ||||
-rwxr-xr-x | Source/build.cpp | 7 | ||||
-rwxr-xr-x | Source/build.h | 8 | ||||
-rwxr-xr-x | Source/exehead/Ui.c | 2 | ||||
-rwxr-xr-x | Source/exehead/exec.c | 41 | ||||
-rwxr-xr-x | Source/makenssi.cpp | 36 | ||||
-rwxr-xr-x | Source/script.cpp | 190 | ||||
-rwxr-xr-x | Source/utf.cpp | 3 | ||||
-rwxr-xr-x | Source/util.cpp | 50 | ||||
-rwxr-xr-x | Source/util.h | 8 | ||||
-rwxr-xr-x | Source/winchar.cpp | 4 |
14 files changed, 206 insertions, 168 deletions
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 <cppunit/CompilerOutputter.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/ui/text/TestRunner.h> +#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; i<l; i++) {
+ for (i=0; i<l; i++)
if (!memcmp((ctlcolors*)cur_ctlcolors->get()+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 @@ -33,6 +33,9 @@ bool StrSetUTF16LE(tstring&dest, const void*src) 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 <langinfo.h> #endif -bool NSISRT_Initialize() +bool NSISRT_Initialize() // Init function for POSIX { iconvdescriptor id; g_nrt_iconv_narrowloc = const_cast<char*>(""); // 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 <io.h> // 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<wchar_t, NSIS_MAX_STRLEN> 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 <typename T> @@ -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 } |