!system and !execute can store the exit code in a define

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6461 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2014-04-13 17:49:39 +00:00
parent 3337a6d606
commit 8d7dd2cf9f
7 changed files with 37 additions and 23 deletions

View file

@ -89,7 +89,7 @@ This command will issue an error to the script compiler and will stop execution
\S1{execute} !execute \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. 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 \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 '"%WINDIR%\notepad.exe" "${NSISDIR}\license.txt"'
\c !system 'echo !define something > newinclude.nsh' \c !system 'echo !define something > newinclude.nsh'

View file

@ -24,6 +24,8 @@ Released on ?, 2014
\b !system will decode child output as OEMCP if GetConsoleOutputCP() == GetOEMCP() \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 \b !execute supports comparing the exit code with the same syntax as !system
\H{v3.0a2} 3.0 Alpha 2 \H{v3.0a2} 3.0 Alpha 2

View file

@ -3689,19 +3689,17 @@ int CEXEBuild::set_target_architecture_data()
{ {
build_strlist.setunicode(build_unicode), ubuild_strlist.setunicode(build_unicode); 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) if (build_unicode)
{ {
definedlist.add(_T("NSIS_UNICODE")); definedlist.set(_T("NSIS_UNICODE"));
definedlist.add(_T("NSIS_CHAR_SIZE"), _T("2")); definedlist.set(_T("NSIS_CHAR_SIZE"), _T("2"));
} }
else 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; return PS_OK;
} }

View file

@ -1280,8 +1280,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
wsprintf(str,_T("macro:%") NPRIs,macroname); wsprintf(str,_T("macro:%") NPRIs,macroname);
const TCHAR* oldmacroname=m_currentmacroname; const TCHAR* oldmacroname=m_currentmacroname;
m_currentmacroname=macroname; m_currentmacroname=macroname;
definedlist.del(_T("__MACRO__")); definedlist.set(_T("__MACRO__"),m_currentmacroname);
definedlist.add(_T("__MACRO__"),m_currentmacroname);
while (*t) while (*t)
{ {
lp++; lp++;
@ -3189,14 +3188,17 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
case TOK_P_EXECUTE: case TOK_P_EXECUTE:
{ {
const TCHAR *cmdname=get_commandtoken_name(which_token); 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")); int comp=line.gettoken_enum(2,_T("<\0>\0<>\0=\0ignore\0"));
if (line.getnumtokens() == 2) comp = 4; int validparams=true, ret=-1, cmpv;
if (comp == -1 && line.getnumtokens() == 3) comp=4; switch(line.getnumtokens()-1)
if (comp == -1) PRINTHELP() {
int success=0, ret; case 1: comp=4; break;
int cmpv=line.gettoken_int(3,&success); case 2: comp=5, validparams=!!*(define=line.gettoken_str(2)); break;
if (!success && comp != 4) PRINTHELP() 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); SCRIPT_MSG(_T("%") NPRIs _T(": \"%") NPRIs _T("\"\n"),cmdname,exec);
#ifdef _WIN32 #ifdef _WIN32
if (TOK_P_EXECUTE == which_token) if (TOK_P_EXECUTE == which_token)
@ -3204,13 +3206,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
#ifdef _UNICODE #ifdef _UNICODE
ret=RunChildProcessRedirected(0,exec); ret=RunChildProcessRedirected(0,exec);
#else #else
ret=-1;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
STARTUPINFO si={sizeof(STARTUPINFO),}; STARTUPINFO si={sizeof(STARTUPINFO),};
if (CreateProcess(NULL,exec,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) if (CreateProcess(NULL,exec,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
{ {
WaitForSingleObject(pi.hProcess,INFINITE); 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); CloseHandle(pi.hThread), CloseHandle(pi.hProcess);
} }
#endif #endif
@ -3223,6 +3224,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
else if (comp == 2 && ret != cmpv); else if (comp == 2 && ret != cmpv);
else if (comp == 3 && ret == cmpv); else if (comp == 3 && ret == cmpv);
else if (comp == 4); else if (comp == 4);
else if (comp == 5)
{
TCHAR buf[50];
_stprintf(buf,_T("%d"),ret);
definedlist.set(define,buf);
}
else else
{ {
ERROR_MSG(_T("%") NPRIs _T(": returned %d, aborting\n"),cmdname,ret); ERROR_MSG(_T("%") NPRIs _T(": returned %d, aborting\n"),cmdname,ret);

View file

@ -332,6 +332,12 @@ int DefineList::add(const TCHAR *name, const TCHAR *value/*=_T("")*/)
return 0; return 0;
} }
void DefineList::set(const TCHAR *name, const TCHAR *value/*=_T("")*/)
{
del(name);
add(name, value);
}
TCHAR *DefineList::find(const TCHAR *name) TCHAR *DefineList::find(const TCHAR *name)
{ {
int v=SortedStringList<struct define>::find(name); int v=SortedStringList<struct define>::find(name);

View file

@ -476,6 +476,7 @@ class DefineList : public SortedStringList<struct define>
* general program exit with error logging. * general program exit with error logging.
*/ */
int add(const TCHAR *name, const TCHAR *value=_T("")); 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 * This function returns the pointer to the .value TCHAR* that corresponds

View file

@ -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_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_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_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_SYSTEMEXEC,_T("!system"),1,2,_T("command [<OP retval> | <retvalsymbol>]\n OP=(< > <> =)"),TP_ALL},
{TOK_P_EXECUTE, _T("!execute"),1,2,_T("command [<|>|<>|= retval]"),TP_ALL}, {TOK_P_EXECUTE, _T("!execute"),1,2,_T("command [<OP retval> | <retvalsymbol>]\n OP=(< > <> =)"),TP_ALL},
{TOK_P_ADDINCLUDEDIR,_T("!AddIncludeDir"),1,0,_T("dir"),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_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}, {TOK_P_CD,_T("!cd"),1,0,_T("absolute_or_relative_new_directory"),TP_ALL},