From 0a8c72c95024448c5ab32eef0b01cd030932de6e Mon Sep 17 00:00:00 2001 From: anders_k Date: Fri, 4 Jul 2014 23:27:04 +0000 Subject: [PATCH] !insertmacro allows macro recursion (RFE #497) git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6511 212acab6-be3b-0410-9dea-997c60f758d6 --- Docs/src/history.but | 2 ++ Include/Util.nsh | 60 +++++++++++++++++++------------------------- Source/build.h | 3 ++- Source/script.cpp | 18 ++++++------- 4 files changed, 38 insertions(+), 45 deletions(-) diff --git a/Docs/src/history.but b/Docs/src/history.but index 3d227dfb..fb3e6b5e 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -8,6 +8,8 @@ Released on ?, 2014 \S2{} Major Changes +\b !insertmacro allows macro recursion (\W{http://sf.net/p/nsis/feature-requests/497}{RFE #497}) + \b Added \R{makensis}{!makensis} command \b InitiateShutdown is used to reboot the machine if available (\W{http://sf.net/p/nsis/patches/247}{patch #247}) diff --git a/Include/Util.nsh b/Include/Util.nsh index 736b6ba3..58d67cfe 100644 --- a/Include/Util.nsh +++ b/Include/Util.nsh @@ -8,46 +8,38 @@ !ifndef ___UTIL__NSH___ !define ___UTIL__NSH___ -# see WinVer.nsh and *Func.nsh for usage examples -!macro CallArtificialFunction NAME - !ifndef __UNINSTALL__ - !define CallArtificialFunction_TYPE inst - !else - !define CallArtificialFunction_TYPE uninst - !endif - Call :.${NAME}${CallArtificialFunction_TYPE} - !ifndef ${NAME}${CallArtificialFunction_TYPE}_DEFINED - Goto ${NAME}${CallArtificialFunction_TYPE}_DONE - !define ${NAME}${CallArtificialFunction_TYPE}_DEFINED - .${NAME}${CallArtificialFunction_TYPE}: +# CallArtificialFunction, see WinVer.nsh and *Func.nsh for usage examples +!macro CallArtificialFunctionHelper TYPE NAME + !verbose pop + Call :.${NAME}${TYPE} + !ifndef ${NAME}${TYPE}_DEFINED + !verbose push 2 + Goto ${NAME}${TYPE}_DONE + !define ${NAME}${TYPE}_DEFINED + !verbose pop + .${NAME}${TYPE}: !insertmacro ${NAME} - Return - ${NAME}${CallArtificialFunction_TYPE}_DONE: + Return + ${NAME}${TYPE}_DONE: !endif - !undef CallArtificialFunction_TYPE + !verbose push 2 +!macroend + +!macro CallArtificialFunction NAME + !verbose push 2 + !ifdef __UNINSTALL__ + !insertmacro CallArtificialFunctionHelper uninst ${NAME} + !else + !insertmacro CallArtificialFunctionHelper inst ${NAME} + !endif + !verbose pop !macroend !define CallArtificialFunction `!insertmacro CallArtificialFunction` -# for usage of artificial functions inside artificial functions -# macro recursion is prohibited -!macro CallArtificialFunction2 NAME - !ifndef __UNINSTALL__ - !define CallArtificialFunction2_TYPE inst - !else - !define CallArtificialFunction2_TYPE uninst - !endif - Call :.${NAME}${CallArtificialFunction2_TYPE} - !ifndef ${NAME}${CallArtificialFunction2_TYPE}_DEFINED - Goto ${NAME}${CallArtificialFunction2_TYPE}_DONE - !define ${NAME}${CallArtificialFunction2_TYPE}_DEFINED - .${NAME}${CallArtificialFunction2_TYPE}: - !insertmacro ${NAME} - Return - ${NAME}${CallArtificialFunction2_TYPE}_DONE: - !endif - !undef CallArtificialFunction2_TYPE +!macro CallArtificialFunction2 NAME ; Retained for v2.4x..v3.0b0 compatibility + ${CallArtificialFunction} ${NAME} !macroend -!define CallArtificialFunction2 `!insertmacro CallArtificialFunction2` +!define CallArtificialFunction2 `!insertmacro CallArtificialFunction` !define Int32Op '!insertmacro Int32Op ' diff --git a/Source/build.h b/Source/build.h index d4d4a733..e4b5e77b 100644 --- a/Source/build.h +++ b/Source/build.h @@ -107,7 +107,8 @@ class CEXEBuild { ~CEXEBuild(); enum { - MAX_LINELENGTH = 16384 // NSI/NSH line limit, in TCHARs (including \0) + MAX_LINELENGTH = 16384, // NSI/NSH line limit, in TCHARs (including \0) + MAX_MACRORECURSION = 50 }; void warning(const TCHAR *s, ...); // to add a warning to the compiler's warning list. diff --git a/Source/script.cpp b/Source/script.cpp index ad3db9c4..4d857bb3 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -1256,22 +1256,20 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) macroname,npr,line.getnumtokens()-2); return PS_ERROR; } - - int lp=0; - TCHAR str[1024]; - if (m_macro_entry.find(macroname,0)>=0) + static unsigned char insertmacrorecursion=0; + if (++insertmacrorecursion > MAX_MACRORECURSION) { - ERROR_MSG(_T("!insertmacro: macro \"%") NPRIs _T("\" already being inserted!\n"),macroname); + ERROR_MSG(_T("!insertmacro: insert depth is limited to %u macros!\n"),MAX_MACRORECURSION); return PS_ERROR; } - int npos=m_macro_entry.add(macroname,0); - const bool oldparserinsidecomment=inside_comment; inside_comment=false; // "!insertmacro foo /*" does not mean that the macro body is a comment + TCHAR str[1024]; wsprintf(str,_T("macro:%") NPRIs,macroname); - const TCHAR* oldmacroname=m_currentmacroname; + const TCHAR *oldmacroname=m_currentmacroname; m_currentmacroname=macroname; definedlist.set(_T("__MACRO__"),m_currentmacroname); + int lp=0; while (*t) { lp++; @@ -1291,7 +1289,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } t+=_tcslen(t)+1; } - m_macro_entry.delbypos(npos); { TCHAR *p=(TCHAR*)l_define_names.get(); while (*p) @@ -1304,8 +1301,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } definedlist.del(_T("__MACRO__")); m_currentmacroname=oldmacroname; - inside_comment=oldparserinsidecomment; if (oldmacroname) definedlist.add(_T("__MACRO__"),oldmacroname); + inside_comment=oldparserinsidecomment; + --insertmacrorecursion; SCRIPT_MSG(_T("!insertmacro: end of %") NPRIs _T("\n"),macroname); } return PS_OK;