diff --git a/Include/LogicLib.nsh b/Include/LogicLib.nsh index 0646a385..cab15b4b 100644 --- a/Include/LogicLib.nsh +++ b/Include/LogicLib.nsh @@ -55,7 +55,7 @@ ; ptrdiff_t integer tests ; a P= b; a P<> b; a P< b; a P>= b; a P> b; a P<= b ; size_t integer tests -; a Z= b; a Z<> b +; a Z= b; a Z<> b; a Z< b; a Z>= b; a Z> b; a Z<= b ; Built-in NSIS flag tests: ; ${Abort}; ${Errors}; ${RebootFlag}; ${Silent} ; Built-in NSIS other tests: @@ -281,26 +281,25 @@ !macro _P<= _a _b _t _f !insertmacro LogicLib_PtrDiffTest <= `${_a}` `${_b}` `${_t}` `${_f}` !macroend + !include Util.nsh !macro _Z= _a _b _t _f !insertmacro LogicLib_PtrDiffTest = `${_a}` `${_b}` `${_t}` `${_f}` !macroend !macro _Z<> _a _b _t _f !insertmacro LogicLib_PtrDiffTest <> `${_a}` `${_b}` `${_t}` `${_f}` !macroend -!if "${NSIS_PTR_SIZE}" <= 4 ; BUGBUG: System::Int64Op does not support unsigned operations! !macro _Z< _a _b _t _f - !insertmacro _U< `${_a}` `${_b}` `${_t}` `${_f}` + !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_f}` `${_t}` `${_f}` !macroend !macro _Z>= _a _b _t _f - !insertmacro _U>= `${_a}` `${_b}` `${_t}` `${_f}` + !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_t}` `${_f}` `${_t}` !macroend !macro _Z> _a _b _t _f - !insertmacro _U> `${_a}` `${_b}` `${_t}` `${_f}` + !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_f}` `${_f}` `${_t}` !macroend !macro _Z<= _a _b _t _f - !insertmacro _U<= `${_a}` `${_b}` `${_t}` `${_f}` + !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_t}` `${_t}` `${_f}` !macroend -!endif ; Flag tests !macro _Abort _a _b _t _f diff --git a/Include/Util.nsh b/Include/Util.nsh index 58d67cfe..8755bff8 100644 --- a/Include/Util.nsh +++ b/Include/Util.nsh @@ -47,20 +47,23 @@ !define IntPtrOp '!insertmacro IntPtrOp ' !macro Int32Op r a o b !if ${NSIS_PTR_SIZE} <= 4 - IntOp ${r} ${a} ${o} ${b} + IntOp `${r}` `${a}` `${o}` ${b} !else !error "Int32Op not implemented" !endif !macroend !macro Int64Op r a o b -System::Int64Op ${a} ${o} ${b} +!echo "Int64Op ${r}=${a}${o}${b}" +!verbose push 2 +System::Int64Op `${a}` `${o}` ${b} Pop ${r} +!verbose pop !macroend !macro IntPtrOp r a o b !if ${NSIS_PTR_SIZE} <= 4 - ${Int32Op} ${r} ${a} ${o} "${b}" + ${Int32Op} `${r}` `${a}` `${o}` `${b}` !else - ${Int64Op} ${r} ${a} ${o} "${b}" + ${Int64Op} `${r}` `${a}` `${o}` `${b}` !endif !macroend @@ -69,7 +72,7 @@ Pop ${r} !define IntPtrCmp '!insertmacro IntPtrCmp ' !macro Int32Cmp a b jeek jles jgtr !if ${NSIS_PTR_SIZE} <= 4 - IntCmp ${a} ${b} "${jeek}" "${jles}" "${jgtr}" + IntCmp `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}` !else !error "Int32Cmp not implemented" !endif @@ -78,17 +81,17 @@ Pop ${r} !ifmacrondef _LOGICLIB_TEMP !include LogicLib.nsh !endif -!echo "Int64Cmp ${a} ${b} ${jeek} ${jles} ${jgtr}" +!echo "Int64Cmp ${a}:${b} =${jeek}, <${jles}, >${jgtr}" !verbose push 2 ${IfThen} ${a} L= ${b} ${|} Goto ${jeek} ${|} -!insertmacro _L< ${a} ${b} ${jles} ${jgtr} +!insertmacro _L< ${a} ${b} `${jles}` `${jgtr}` !verbose pop !macroend !macro IntPtrCmp a b jeek jles jgtr !if ${NSIS_PTR_SIZE} <= 4 - ${Int32Cmp} ${a} ${b} ${jeek} ${jles} ${jgtr} + ${Int32Cmp} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}` !else - ${Int64Cmp} ${a} ${b} ${jeek} ${jles} ${jgtr} + ${Int64Cmp} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}` !endif !macroend @@ -97,32 +100,71 @@ ${IfThen} ${a} L= ${b} ${|} Goto ${jeek} ${|} !define IntPtrCmpU '!insertmacro IntPtrCmpU ' !macro Int32CmpU a b jeek jles jgtr !if ${NSIS_PTR_SIZE} <= 4 - IntCmpU ${a} ${b} "${jeek}" "${jles}" "${jgtr}" + IntCmpU `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}` !else !error "Int32CmpU not implemented" !endif !macroend -!macro Int64CmpU a b jeek jles jgtr +!macro Int64CmpUHelper +; This macro performs "$_LOGICLIB_TEMP = a < b ? -1 : a > b ? 1 : 0" but System::Int64Op does not support unsigned operations so we have to perform multiple steps !ifmacrondef _LOGICLIB_TEMP !include LogicLib.nsh !endif -!echo "Int64CmpU ${a} ${b} ${jeek} ${jles} ${jgtr}" -!verbose push 2 !insertmacro _LOGICLIB_TEMP -${IfThen} ${a} L= ${b} ${|} Goto ${jeek} ${|} -${If} ${a} L> 0 - ${IfThen} ${b} L< 0 ${|} Goto ${jles} ${|} -${ElseIf} ${b} L> 0 - ${IfThen} ${a} L< 0 ${|} Goto ${jgtr} ${|} -${EndIf} -!insertmacro _L< ${a} ${b} ${jles} ${jgtr} +Exch $2 ; b +Exch +Exch $1 ; a +; if (a == b) return 0; +; if (a < 0) +; { +; if (b >= 0) return 1 +; } +; else +; { +; if (b < 0) return -1 +; } +; return a < b ? -1 : 1 +System::Int64Op $1 ^ $2 ; Using xor so $_LOGICLIB_TEMP ends up as 0 when they are equal +Pop $_LOGICLIB_TEMP +StrCmp $_LOGICLIB_TEMP 0 ret ; NOTE: Must use StrCmp, IntCmp fails on "0x8000000000000001 Z> 1" +System::Int64Op $1 < 0 +Pop $_LOGICLIB_TEMP +StrCmp $_LOGICLIB_TEMP 0 checkNegOther +System::Int64Op $2 < 0 ; System::Int64Op does not support the >= operator so we invert the operation +Pop $_LOGICLIB_TEMP +StrCmp $_LOGICLIB_TEMP 0 retPos finalCmp +retPos: +StrCpy $_LOGICLIB_TEMP "1" +Goto ret +checkNegOther: +System::Int64Op $2 < 0 +Pop $_LOGICLIB_TEMP +StrCmp $_LOGICLIB_TEMP 0 finalCmp retNeg +retNeg: +StrCpy $_LOGICLIB_TEMP "-1" +Goto ret +finalCmp: +System::Int64Op $1 < $2 +Pop $_LOGICLIB_TEMP +StrCmp $_LOGICLIB_TEMP 0 retPos retNeg +ret: +Pop $1 +Pop $2 +!macroend +!macro Int64CmpU a b jeek jles jgtr +!echo "Int64CmpU ${a}:${b} =${jeek}, <${jles}, >${jgtr}" +!verbose push 2 +Push `${a}` +Push `${b}` +!insertmacro CallArtificialFunction Int64CmpUHelper +IntCmp $_LOGICLIB_TEMP 0 `${jeek}` `${jles}` `${jgtr}` !verbose pop !macroend !macro IntPtrCmpU a b jeek jles jgtr !if ${NSIS_PTR_SIZE} <= 4 - ${Int32CmpU} ${a} ${b} ${jeek} ${jles} ${jgtr} + ${Int32CmpU} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}` !else - ${Int64CmpU} ${a} ${b} ${jeek} ${jles} ${jgtr} + ${Int64CmpU} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}` !endif !macroend