From 388d994ada79d3c77ae8fb7dac8a628c618f7f1a Mon Sep 17 00:00:00 2001 From: anders_k Date: Thu, 14 Jul 2016 10:53:25 +0000 Subject: [PATCH] Added support for !finalize return value comparison git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6771 212acab6-be3b-0410-9dea-997c60f758d6 --- Docs/src/compiler.but | 2 +- Docs/src/history.but | 10 ++++++++++ Source/build.cpp | 19 ++++++++++++++++++- Source/build.h | 2 ++ Source/script.cpp | 25 +++++++++++-------------- Source/tokens.cpp | 2 +- 6 files changed, 43 insertions(+), 17 deletions(-) diff --git a/Docs/src/compiler.but b/Docs/src/compiler.but index 85dd93b6..5cf9fa85 100644 --- a/Docs/src/compiler.but +++ b/Docs/src/compiler.but @@ -118,7 +118,7 @@ This option makes the compiler use an external EXE packer (such as \W{http://www \S1{finalize} !finalize -\c command +\c command [compare comparevalue] This option will execute 'command' using a call to system() after the output EXE has been generated. You can typically use it to sign (Authenticode) your installer. If 'command' contains a '%1' it will be replaced by the executables filename. diff --git a/Docs/src/history.but b/Docs/src/history.but index cc660a72..130795e7 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -1,5 +1,15 @@ \A{history} Changelog and Release Notes +\H{v3.0} 3.0 + +Released on ???? ?th, 2016 + +\S1{v3.0-cl} Changelog + +\S2{} Minor Changes + +\b \R{finalize}{!finalize} command now supports the same compare operators as !system (\W{http://sf.net/p/nsis/bugs/1148}{bug #1148}) + \H{v3.0rc2} 3.0 Release Candidate 2 Released on July 8th, 2016 diff --git a/Source/build.cpp b/Source/build.cpp index 6ecf645e..44689e9b 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -3026,7 +3026,12 @@ int CEXEBuild::write_output(void) SCRIPT_MSG(_T("\nFinalize command: %") NPRIs _T("\n"),cmdstr); int ret = sane_system(cmdstr); - if (ret != 0) INFO_MSG(_T("Finalize command returned %d\n"),ret); + if (!check_external_exitcode(ret, cmd->cmpop, cmd->cmpval)) + { + ERROR_MSG(_T("%") NPRIs _T(" %d, aborting\n"), _T("Finalize command returned"), ret); + return PS_ERROR; + } + if (ret != 0) INFO_MSG(_T("%") NPRIs _T(" %d\n"), _T("Finalize command returned"), ret); free(cmdstrbuf); } } @@ -3938,3 +3943,15 @@ void CEXEBuild::set_code_type_predefines(const TCHAR *value) } } +int CEXEBuild::check_external_exitcode(int exitcode, int op, int val) +{ + switch(op) + { + case 0: return exitcode < val; + case 1: return exitcode > val; + case 2: return exitcode != val; + case 3: return exitcode == val; + case 4: return -1; // ignore + } + return 0; +} diff --git a/Source/build.h b/Source/build.h index f4a50d4c..1be29798 100644 --- a/Source/build.h +++ b/Source/build.h @@ -448,8 +448,10 @@ class CEXEBuild { struct postbuild_cmd { struct postbuild_cmd*next; + int cmpop, cmpval; TCHAR cmd[1]; } *postbuild_cmds; + int check_external_exitcode(int exitcode, int op, int val); TCHAR build_packname[1024], build_packcmd[1024]; int build_overwrite, build_last_overwrite, build_crcchk, diff --git a/Source/script.cpp b/Source/script.cpp index d7c5e85c..bb390bc0 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -3179,12 +3179,15 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_P_FINALIZE: { TCHAR* cmdstr=line.gettoken_str(1); + int validparams=false; struct postbuild_cmd *newcmd, *prevcmd; - newcmd = (struct postbuild_cmd*) (new BYTE[FIELD_OFFSET(struct postbuild_cmd,cmd[_tcsclen(cmdstr)+1])]); - newcmd->next=NULL; - _tcscpy(newcmd->cmd,cmdstr); - for (prevcmd=postbuild_cmds; prevcmd && prevcmd->next;) prevcmd = prevcmd->next; - if (prevcmd) prevcmd->next = newcmd; else postbuild_cmds = newcmd; + newcmd=(struct postbuild_cmd*) (new BYTE[FIELD_OFFSET(struct postbuild_cmd,cmd[_tcsclen(cmdstr)+1])]); + newcmd->next=NULL, _tcscpy(newcmd->cmd,cmdstr); + newcmd->cmpop=line.gettoken_enum(2,_T("<\0>\0<>\0=\0ignore\0")), newcmd->cmpval=line.gettoken_int(3,&validparams); + if (line.getnumtokens() == 1+1) newcmd->cmpop=4, validparams=true; // just a command, ignore the exit code + if (newcmd->cmpop == -1 || !validparams) PRINTHELP(); + for (prevcmd=postbuild_cmds; prevcmd && prevcmd->next;) prevcmd=prevcmd->next; + if (prevcmd) prevcmd->next=newcmd; else postbuild_cmds=newcmd; SCRIPT_MSG(_T("!finalize: \"%") NPRIs _T("\"\n"),cmdstr); } return PS_OK; @@ -3194,6 +3197,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { const TCHAR *cmdname=get_commandtoken_name(which_token); const TCHAR *exec=line.gettoken_str(1), *define=0; + TCHAR buf[33]; int comp=line.gettoken_enum(2,_T("<\0>\0<>\0=\0ignore\0")); int validparams=true, ret=-1, cmpv=0, forceutf8=0; switch(line.getnumtokens()-1) @@ -3208,7 +3212,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (TOK_P_MAKENSIS == which_token) { extern const TCHAR *g_argv0; - TCHAR buf[33]; compile=_T("\""), compile+=get_executable_path(g_argv0), compile+= _T("\""); compile+= _T(" ") OPT_STR _T("v"), wsprintf(buf,_T("%d"),get_verbosity()), compile+=buf; #if defined(_WIN32) && defined(_UNICODE) // POSIX does not support -OUTPUTCHARSET @@ -3225,18 +3228,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) else #endif //~ _WIN32 ret=sane_system(exec); - if (comp == 0 && ret < cmpv); - else if (comp == 1 && ret > cmpv); - else if (comp == 2 && ret != cmpv); - else if (comp == 3 && ret == cmpv); - else if (comp == 4); - else if (comp == 5) + if (comp == 5) { - TCHAR buf[25]; _stprintf(buf,_T("%d"),ret); definedlist.set(define,buf); } - else + else if (!check_external_exitcode(ret,comp,cmpv)) { ERROR_MSG(_T("%") NPRIs _T(": returned %d, aborting\n"),cmdname,ret); return PS_ERROR; diff --git a/Source/tokens.cpp b/Source/tokens.cpp index e806de62..998bcf29 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -247,7 +247,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_MANIFEST_DPIAWARE,_T("ManifestDPIAware"),1,0,_T("notset|true|false"),TP_GLOBAL}, {TOK_MANIFEST_SUPPORTEDOS,_T("ManifestSupportedOS"),1,-1,_T("none|all|WinVista|Win7|Win8|Win8.1|Win10|{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_FINALIZE,_T("!finalize"),1,2,_T("command_with_%1 []"),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_MAKENSIS,_T("!makensis"),1,2,_T("parameters [ | ]"),TP_ALL},