diff --git a/Docs/src/compiler.but b/Docs/src/compiler.but index 5c1aebe6..ba9490f6 100644 --- a/Docs/src/compiler.but +++ b/Docs/src/compiler.but @@ -89,7 +89,7 @@ This command will issue an error to the script compiler and will stop execution \S1{execute} !execute -\c command +\c command [compare comparevalue | symbol] This command will execute 'command' using a call to CreateProcess(). Unlike \R{system}{!system}, it does not use the command line processor, so input/output redirection and commands like 'cd', 'dir' and 'type' can not be used. Currently, the only known advantage of \R{execute}{!execute} over \R{system}{!system} is that it does not give trouble when the current working directory is specified using UNC. @@ -115,9 +115,9 @@ This option will execute 'command' using a call to system() after the output EXE \S1{system} !system -\c command [compare comparevalue] +\c command [compare comparevalue | symbol] -This command will execute 'command' using a call to system(), and if the return value compared (using 'compare') to 'comparevalue' is false, execution will halt. 'compare' can be '<' or '>' or '<>' or '='. +This command will execute 'command' using a call to system(). You can store the return value in a define ('symbol') or halt execution if the return value compared (using 'compare') to 'comparevalue' is false. 'compare' can be '<' or '>' or '<>' or '='. \c !system '"%WINDIR%\notepad.exe" "${NSISDIR}\license.txt"' \c !system 'echo !define something > newinclude.nsh' diff --git a/Docs/src/history.but b/Docs/src/history.but index 1f6b14da..237f7b4d 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -24,6 +24,8 @@ Released on ?, 2014 \b !system will decode child output as OEMCP if GetConsoleOutputCP() == GetOEMCP() +\b !system and !execute can store the exit code in a define + \b !execute supports comparing the exit code with the same syntax as !system \H{v3.0a2} 3.0 Alpha 2 diff --git a/Source/build.cpp b/Source/build.cpp index 43547e16..844d74a2 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -3689,19 +3689,17 @@ int CEXEBuild::set_target_architecture_data() { build_strlist.setunicode(build_unicode), ubuild_strlist.setunicode(build_unicode); - definedlist.del(_T("NSIS_UNICODE")); - definedlist.del(_T("NSIS_CHAR_SIZE")); - definedlist.del(_T("NSIS_PTR_SIZE")); if (build_unicode) { - definedlist.add(_T("NSIS_UNICODE")); - definedlist.add(_T("NSIS_CHAR_SIZE"), _T("2")); + definedlist.set(_T("NSIS_UNICODE")); + definedlist.set(_T("NSIS_CHAR_SIZE"), _T("2")); } else { - definedlist.add(_T("NSIS_CHAR_SIZE"), _T("1")); + definedlist.del(_T("NSIS_UNICODE")); + definedlist.set(_T("NSIS_CHAR_SIZE"), _T("1")); } - definedlist.add(_T("NSIS_PTR_SIZE"), is_target_64bit() ? _T("8") : _T("4")); + definedlist.set(_T("NSIS_PTR_SIZE"), is_target_64bit() ? _T("8") : _T("4")); return PS_OK; } diff --git a/Source/script.cpp b/Source/script.cpp index ef661522..54263c33 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -1280,8 +1280,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) wsprintf(str,_T("macro:%") NPRIs,macroname); const TCHAR* oldmacroname=m_currentmacroname; m_currentmacroname=macroname; - definedlist.del(_T("__MACRO__")); - definedlist.add(_T("__MACRO__"),m_currentmacroname); + definedlist.set(_T("__MACRO__"),m_currentmacroname); while (*t) { lp++; @@ -3189,14 +3188,17 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_P_EXECUTE: { const TCHAR *cmdname=get_commandtoken_name(which_token); - TCHAR *exec=line.gettoken_str(1); + TCHAR *exec=line.gettoken_str(1), *define; int comp=line.gettoken_enum(2,_T("<\0>\0<>\0=\0ignore\0")); - if (line.getnumtokens() == 2) comp = 4; - if (comp == -1 && line.getnumtokens() == 3) comp=4; - if (comp == -1) PRINTHELP() - int success=0, ret; - int cmpv=line.gettoken_int(3,&success); - if (!success && comp != 4) PRINTHELP() + int validparams=true, ret=-1, cmpv; + switch(line.getnumtokens()-1) + { + 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; + } + if (!validparams || comp == -1) PRINTHELP() SCRIPT_MSG(_T("%") NPRIs _T(": \"%") NPRIs _T("\"\n"),cmdname,exec); #ifdef _WIN32 if (TOK_P_EXECUTE == which_token) @@ -3204,13 +3206,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef _UNICODE ret=RunChildProcessRedirected(0,exec); #else - ret=-1; PROCESS_INFORMATION pi; STARTUPINFO si={sizeof(STARTUPINFO),}; if (CreateProcess(NULL,exec,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) { WaitForSingleObject(pi.hProcess,INFINITE); - if (GetExitCodeProcess(pi.hProcess, &si.cb)) ret=(int)si.cb; + if (GetExitCodeProcess(pi.hProcess,&si.cb)) ret=(int)si.cb; CloseHandle(pi.hThread), CloseHandle(pi.hProcess); } #endif @@ -3223,6 +3224,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) else if (comp == 2 && ret != cmpv); else if (comp == 3 && ret == cmpv); else if (comp == 4); + else if (comp == 5) + { + TCHAR buf[50]; + _stprintf(buf,_T("%d"),ret); + definedlist.set(define,buf); + } else { ERROR_MSG(_T("%") NPRIs _T(": returned %d, aborting\n"),cmdname,ret); diff --git a/Source/strlist.cpp b/Source/strlist.cpp index 6a850ebc..359c20ef 100644 --- a/Source/strlist.cpp +++ b/Source/strlist.cpp @@ -332,6 +332,12 @@ int DefineList::add(const TCHAR *name, const TCHAR *value/*=_T("")*/) return 0; } +void DefineList::set(const TCHAR *name, const TCHAR *value/*=_T("")*/) +{ + del(name); + add(name, value); +} + TCHAR *DefineList::find(const TCHAR *name) { int v=SortedStringList::find(name); diff --git a/Source/strlist.h b/Source/strlist.h index 44571223..8e1b36ec 100644 --- a/Source/strlist.h +++ b/Source/strlist.h @@ -476,6 +476,7 @@ class DefineList : public SortedStringList * general program exit with error logging. */ int add(const TCHAR *name, const TCHAR *value=_T("")); + void set(const TCHAR *name, const TCHAR *value=_T("")); /** * This function returns the pointer to the .value TCHAR* that corresponds diff --git a/Source/tokens.cpp b/Source/tokens.cpp index c117dd0c..b2ed8b12 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -244,8 +244,8 @@ static tokenType tokenlist[TOK__LAST] = {TOK_MANIFEST_SUPPORTEDOS,_T("ManifestSupportedOS"),1,-1,_T("none|all|WinVista|Win7|Win8|Win8.1|{GUID} [...]"),TP_GLOBAL}, {TOK_P_PACKEXEHEADER,_T("!packhdr"),2,0,_T("temp_file_name command_line_to_compress_that_temp_file"),TP_ALL}, {TOK_P_FINALIZE,_T("!finalize"),1,0,_T("command_with_%1"),TP_ALL}, -{TOK_P_SYSTEMEXEC,_T("!system"),1,2,_T("command [<|>|<>|= retval]"),TP_ALL}, -{TOK_P_EXECUTE, _T("!execute"),1,2,_T("command [<|>|<>|= retval]"),TP_ALL}, +{TOK_P_SYSTEMEXEC,_T("!system"),1,2,_T("command [ | ]\n OP=(< > <> =)"),TP_ALL}, +{TOK_P_EXECUTE, _T("!execute"),1,2,_T("command [ | ]\n OP=(< > <> =)"),TP_ALL}, {TOK_P_ADDINCLUDEDIR,_T("!AddIncludeDir"),1,0,_T("dir"),TP_ALL}, {TOK_P_INCLUDE,_T("!include"),1,2,_T("[/NONFATAL] [/CHARSET=<") TSTR_INPUTCHARSET _T(">] filename.nsh"),TP_ALL}, {TOK_P_CD,_T("!cd"),1,0,_T("absolute_or_relative_new_directory"),TP_ALL},