diff --git a/Contrib/System/System.html b/Contrib/System/System.html
index 78380992..47a065b1 100644
--- a/Contrib/System/System.html
+++ b/Contrib/System/System.html
@@ -585,7 +585,7 @@ good:
-
-Int64Op ARG1 OP [ARG2]
+Int64Op ARG1 OP [ARG2]
Performs OP on ARG1 and optionally ARG2 and returns the result on the stack. Both ARG1 and ARG2 are 64-bit integers. This means they can range between -2^63 and 2^63 - 1.
Available Operations
@@ -601,13 +601,13 @@ good:
- Bitwise or -- |
- Bitwise and -- &
- Bitwise xor -- ^
+- Bitwise not (one argument) -- ~
+- Logical not (one argument) -- !
- Logical or -- ||
- Logical and -- &&
- Less than -- <
- Equals -- =
- Greater than -- >
-- Bitwise not (one argument) -- ~
-- Logical not (one argument) -- !
Usage Examples
diff --git a/Contrib/nsDialogs/example.nsi b/Contrib/nsDialogs/example.nsi
index b2259cbf..94523eac 100644
--- a/Contrib/nsDialogs/example.nsi
+++ b/Contrib/nsDialogs/example.nsi
@@ -1,6 +1,5 @@
!include nsDialogs.nsh
!include LogicLib.nsh
-!include Util.nsh ; IntPtrOp
!include WinCore.nsh ; MAKELONG
Name "nsDialogs Example"
@@ -196,7 +195,7 @@ Function OnNotify
IntOp $2 $5 - $4
System::Call '*(ir4,ir5,l,&t$2,i)p.r2' ; Create TEXTRANGE and a text buffer
${If} $2 P<> 0
- ${IntPtrOp} $3 $2 + 16 ; Find buffer
+ IntPtrOp $3 $2 + 16 ; Find buffer
System::Call '*$2(i,i,p$3)' ; Set buffer in TEXTRANGE
SendMessage $1 ${EM_GETTEXTRANGE} "" $2 $4
${If} $4 <> 0
diff --git a/Docs/src/history.but b/Docs/src/history.but
index 33528ebf..bd453a80 100644
--- a/Docs/src/history.but
+++ b/Docs/src/history.but
@@ -20,6 +20,8 @@ Released on ??? ??rd, 20??
\S2{} Minor Changes
+\b Added \R{intptrop}{IntPtrOp}
+
\b Added IntOp and System::Int64Op >>> operator
\b Removed unused NSD_LB_Clear macro parameter
diff --git a/Docs/src/int.but b/Docs/src/int.but
index 19a2d3b5..57ac9964 100644
--- a/Docs/src/int.but
+++ b/Docs/src/int.but
@@ -50,3 +50,11 @@ Combines value1 and (depending on OP) value2 into the specified user variable (\
\c IntOp $0 $0 << 2
\c IntOp $0 $0 ~
\c IntOp $0 $0 & 0xF
+
+\S2{intptrop} IntPtrOp
+
+\c user_var(output) value1 OP [value2]
+
+Combines value1 and (depending on OP) value2 into the specified user variable (\c{user_var}). OP is the same list of operators as supported by \c{IntOp}.
+
+\c IntPtrOp $FieldAddress $MyBuffer + $FieldOffset
\ No newline at end of file
diff --git a/Include/Util.nsh b/Include/Util.nsh
index 8755bff8..620a4410 100644
--- a/Include/Util.nsh
+++ b/Include/Util.nsh
@@ -60,11 +60,7 @@ Pop ${r}
!verbose pop
!macroend
!macro IntPtrOp r a o b
-!if ${NSIS_PTR_SIZE} <= 4
- ${Int32Op} `${r}` `${a}` `${o}` `${b}`
-!else
- ${Int64Op} `${r}` `${a}` `${o}` `${b}`
-!endif
+IntPtrOp `${r}` `${a}` `${o}` `${b}`
!macroend
!define Int32Cmp '!insertmacro Int32Cmp '
diff --git a/Source/build.h b/Source/build.h
index cb4853db..d1848211 100644
--- a/Source/build.h
+++ b/Source/build.h
@@ -318,6 +318,7 @@ class CEXEBuild {
#else
void ps_addtoline(const TCHAR *str, GrowBuf &linedata, StringList &hist);
#endif
+ int doParse(int verbosity, const TCHAR *fmt, ...);
int doParse(const TCHAR *str);
int doCommand(int which_token, LineParser &line);
TCHAR m_templinebuf[MAX_LINELENGTH]; // Buffer used by parseScript() & doCommand(), not recursion safe!
diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c
index 53b1a199..183dadc2 100644
--- a/Source/exehead/exec.c
+++ b/Source/exehead/exec.c
@@ -702,7 +702,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
{
int v,v2;
TCHAR *p=var0;
- v=GetIntFromParm(1); // BUGBUG64: TODO: These should be INT_PTR, the script might be playing with pointers and System::Call
+ v=GetIntFromParm(1);
v2=GetIntFromParm(2);
switch (parm3)
{
@@ -728,7 +728,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
TCHAR *buf0=GetStringFromParm(0x01);
wsprintf(var0,
buf0,
- GetIntPtrFromParm(2));
+ GetIntPtrFromParm(2)); // TODO: BUGBUG64: This sign-extends from INT32 to INT64, do we want that?
}
break;
#endif//NSIS_SUPPORT_INTOPTS
diff --git a/Source/script.cpp b/Source/script.cpp
index 6a6c3e94..87ce291d 100644
--- a/Source/script.cpp
+++ b/Source/script.cpp
@@ -161,6 +161,20 @@ int CEXEBuild::num_ifblock()
return build_preprocessor_data.getlen() / sizeof(ifblock);
}
+int CEXEBuild::doParse(int verbosity, const TCHAR *fmt, ...)
+{
+ ExpandoString buf;
+ int orgv = get_verbosity(), res;
+ va_list val;
+ va_start(val, fmt);
+ buf.StrVFmt(fmt, val);
+ va_end(val);
+ if (verbosity >= 0) set_verbosity(verbosity);
+ res = doParse(buf.GetPtr());
+ set_verbosity(orgv);
+ return res;
+}
+
int CEXEBuild::doParse(const TCHAR *str)
{
LineParser line(inside_comment);
@@ -4122,17 +4136,30 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
return PS_ERROR;
#endif //~ NSIS_SUPPORT_GETFILETIME
#ifdef NSIS_SUPPORT_INTOPTS
- case TOK_INTOP:
- ent.which=EW_INTOP;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- ent.offsets[3]=line.gettoken_enum(3,_T("+\0-\0*\0/\0|\0&\0^\0!\0||\0&&\0%\0<<\0>>\0>>>\0~\0"));
- if (ent.offsets[0] < 0 || ent.offsets[3] < 0 ||
- ((ent.offsets[3] == 7 || ent.offsets[3] == 14) && line.getnumtokens() > 4))
- PRINTHELP()
- ent.offsets[1]=add_string(line.gettoken_str(2));
- if (ent.offsets[3] != 7 && ent.offsets[3] != 14) ent.offsets[2]=add_string(line.gettoken_str(4));
- if (ent.offsets[3] == 14) ent.offsets[2]=add_asciistring(_T("0xFFFFFFFF")), ent.offsets[3]=6; // ~ using ^
- SCRIPT_MSG(_T("IntOp: %") NPRIs _T("=%") NPRIs _T("%") NPRIs _T("%") NPRIs _T("\n"),line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ case TOK_INTOP: case TOK_INTPTROP:
+ {
+ const TCHAR *val1=line.gettoken_str(2), *opstr=0, *val2=0, *cmdname=get_commandtoken_name(which_token);
+ int t64 = is_target_64bit(), res;
+ ent.which=EW_INTOP;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ ent.offsets[3]=line.gettoken_enum(3,_T("+\0-\0*\0/\0|\0&\0^\0!\0||\0&&\0%\0<<\0>>\0>>>\0~\0"));
+ if (ent.offsets[0] < 0 || ent.offsets[3] < 0 || ((ent.offsets[3] == 7 || ent.offsets[3] == 14) && line.getnumtokens() > 4))
+ PRINTHELP()
+ if (ent.offsets[3] != 7 && ent.offsets[3] != 14) val2=line.gettoken_str(4);
+ if (ent.offsets[3] == 14) val2=t64?_T("0xFFFFFFFFFFFFFFFF"):_T("0xFFFFFFFF"), ent.offsets[3]=6, opstr = _T("^"); // ~ using ^
+ if (TOK_INTPTROP == which_token && t64)
+ {
+ res = doParse(2, _T("System::Int64Op %") NPRIs _T(" %") NPRIs _T(" %") NPRIs _T("\n"), val1, opstr ? opstr : line.gettoken_str(3), val2 ? val2 : _T(""));
+ if (res != PS_OK) return res;
+ ent.which=EW_PUSHPOP, ent.offsets[1]=1, ent.offsets[3]=0; // Pop $result
+ }
+ else
+ {
+ ent.offsets[1]=add_string(val1);
+ if (val2) ent.offsets[2]=add_string(val2);
+ }
+ SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T("=%") NPRIs _T("%") NPRIs _T("%") NPRIs _T("\n"),cmdname,line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ }
return add_entry(&ent);
case TOK_INTFMT:
ent.which=EW_INTFMT;
@@ -5010,7 +5037,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
// Call the DLL
tstring funcname = get_string_suffix(command, _T("::"));
- SCRIPT_MSG(_T("Plugin Command: %") NPRIs,funcname.c_str());
+ SCRIPT_MSG(_T("Plugin command: %") NPRIs,funcname.c_str());
int i = 1;
int nounload = 0;
diff --git a/Source/tokens.cpp b/Source/tokens.cpp
index ae3c27c4..3cf89a37 100644
--- a/Source/tokens.cpp
+++ b/Source/tokens.cpp
@@ -123,6 +123,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_INSTPROGRESSFLAGS,_T("InstProgressFlags"),0,-1,_T("[flag [...]]\n flag={smooth|colored}"),TP_GLOBAL},
{TOK_INSTTYPE,_T("InstType"),1,0,_T("[un.]install_type_name | /NOCUSTOM | /CUSTOMSTRING=str | /COMPONENTSONLYONCUSTOM"),TP_GLOBAL},
{TOK_INTOP,_T("IntOp"),3,1,_T("$(user_var: result) val1 OP [val2]\n OP=(+ - * / % | & ^ ~ ! || && << >> >>>)"),TP_CODE},
+{TOK_INTPTROP,_T("IntPtrOp"),3,1,_T("$(user_var: result) val1 OP [val2]"),TP_CODE},
{TOK_INTCMP,_T("IntCmp"),3,2,_T("val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"),TP_CODE},
{TOK_INTCMPU,_T("IntCmpU"),3,2,_T("val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"),TP_CODE},
{TOK_INTFMT,_T("IntFmt"),3,0,_T("$(user_var: output) format_string input"),TP_CODE},
diff --git a/Source/tokens.h b/Source/tokens.h
index 697add25..7549374c 100644
--- a/Source/tokens.h
+++ b/Source/tokens.h
@@ -238,6 +238,7 @@ enum
TOK_GETFILETIMELOCAL,
TOK_STRLEN,
TOK_INTOP,
+ TOK_INTPTROP,
TOK_INTCMP,
TOK_INTCMPU,
TOK_INTFMT,