Added IntPtrCmp, IntPtrCmpU, Int64Cmp and Int64CmpU

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6930 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2017-10-14 16:49:40 +00:00
parent 34e9873d5f
commit 1a039ca71f
9 changed files with 99 additions and 61 deletions

View file

@ -12,6 +12,8 @@
\define{NsisFuncReqU} This function is only available when building a \R{intro-unicode}{Unicode installer}. \define{NsisFuncReqU} This function is only available when building a \R{intro-unicode}{Unicode installer}.
\define{NsisFuncReq64} This function is only available when building a 64-bit installer.
\define{NsisACPcp} system default ANSI codepage (ACP) \define{NsisACPcp} system default ANSI codepage (ACP)
\define{NsisInputCharset} ACP|OEM|CP#|UTF8|UTF16<LE|BE> \define{NsisInputCharset} ACP|OEM|CP#|UTF8|UTF16<LE|BE>

View file

@ -185,6 +185,34 @@ Compares two integers val1 and val2. If val1 and val2 are equal, Gotos jump_if_e
Same as \R{intcmp}{IntCmp}, but treats the values as unsigned integers. Same as \R{intcmp}{IntCmp}, but treats the values as unsigned integers.
\S2{int64cmp} Int64Cmp
\c val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]
Same as \R{intcmp}{IntCmp}, but treats the values as 64-bit integers.
\NsisFuncReq64
\S2{int64cmpu} Int64CmpU
\c val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]
Same as \R{intcmp}{IntCmp}, but treats the values as 64-bit unsigned integers.
\NsisFuncReq64
\S2{intptrcmp} IntPtrCmp
\c val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]
Same as \R{intcmp}{IntCmp}, but treats the values as pointer sized integers.
\S2{intptrcmpu} IntPtrCmpU
\c val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]
Same as \R{intcmp}{IntCmp}, but treats the values as pointer sized unsigned integers.
\S2{messagebox} MessageBox \S2{messagebox} MessageBox
\c mb_option_list messagebox_text [/SD return] [return_check jumpto [return_check_2 jumpto_2]] \c mb_option_list messagebox_text [/SD return] [return_check jumpto [return_check_2 jumpto_2]]

View file

@ -20,6 +20,8 @@ Released on ??? ??rd, 20??
\S2{} Minor Changes \S2{} Minor Changes
\b Added \R{intptrcmp}{IntPtrCmp}, IntPtrCmpU, Int64Cmp and Int64CmpU
\b Added \R{intptrop}{IntPtrOp} \b Added \R{intptrop}{IntPtrOp}
\b Added IntOp and System::Int64Op >>> operator \b Added IntOp and System::Int64Op >>> operator

View file

@ -46,11 +46,7 @@
!define Int64Op '!insertmacro Int64Op ' !define Int64Op '!insertmacro Int64Op '
!define IntPtrOp '!insertmacro IntPtrOp ' !define IntPtrOp '!insertmacro IntPtrOp '
!macro Int32Op r a o b !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 !macroend
!macro Int64Op r a o b !macro Int64Op r a o b
!echo "Int64Op ${r}=${a}${o}${b}" !echo "Int64Op ${r}=${a}${o}${b}"
@ -67,13 +63,10 @@ IntPtrOp `${r}` `${a}` `${o}` `${b}`
!define Int64Cmp '!insertmacro Int64Cmp ' !define Int64Cmp '!insertmacro Int64Cmp '
!define IntPtrCmp '!insertmacro IntPtrCmp ' !define IntPtrCmp '!insertmacro IntPtrCmp '
!macro Int32Cmp a b jeek jles jgtr !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
!macroend !macroend
!macro Int64Cmp a b jeek jles jgtr !macro Int64Cmp a b jeek jles jgtr
!if ${NSIS_PTR_SIZE} <= 4
!ifmacrondef _LOGICLIB_TEMP !ifmacrondef _LOGICLIB_TEMP
!include LogicLib.nsh !include LogicLib.nsh
!endif !endif
@ -82,24 +75,19 @@ IntPtrOp `${r}` `${a}` `${o}` `${b}`
${IfThen} ${a} L= ${b} ${|} Goto ${jeek} ${|} ${IfThen} ${a} L= ${b} ${|} Goto ${jeek} ${|}
!insertmacro _L< ${a} ${b} `${jles}` `${jgtr}` !insertmacro _L< ${a} ${b} `${jles}` `${jgtr}`
!verbose pop !verbose pop
!else
Int64Cmp `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
!endif
!macroend !macroend
!macro IntPtrCmp a b jeek jles jgtr !macro IntPtrCmp a b jeek jles jgtr
!if ${NSIS_PTR_SIZE} <= 4 IntPtrCmp `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
${Int32Cmp} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
!else
${Int64Cmp} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
!endif
!macroend !macroend
!define Int32CmpU '!insertmacro Int32CmpU ' !define Int32CmpU '!insertmacro Int32CmpU '
!define Int64CmpU '!insertmacro Int64CmpU ' !define Int64CmpU '!insertmacro Int64CmpU '
!define IntPtrCmpU '!insertmacro IntPtrCmpU ' !define IntPtrCmpU '!insertmacro IntPtrCmpU '
!macro Int32CmpU a b jeek jles jgtr !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 !macroend
!macro Int64CmpUHelper !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 ; 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
@ -148,6 +136,7 @@ Pop $1
Pop $2 Pop $2
!macroend !macroend
!macro Int64CmpU a b jeek jles jgtr !macro Int64CmpU a b jeek jles jgtr
!if ${NSIS_PTR_SIZE} <= 4
!echo "Int64CmpU ${a}:${b} =${jeek}, <${jles}, >${jgtr}" !echo "Int64CmpU ${a}:${b} =${jeek}, <${jles}, >${jgtr}"
!verbose push 2 !verbose push 2
Push `${a}` Push `${a}`
@ -155,13 +144,12 @@ Push `${b}`
!insertmacro CallArtificialFunction Int64CmpUHelper !insertmacro CallArtificialFunction Int64CmpUHelper
IntCmp $_LOGICLIB_TEMP 0 `${jeek}` `${jles}` `${jgtr}` IntCmp $_LOGICLIB_TEMP 0 `${jeek}` `${jles}` `${jgtr}`
!verbose pop !verbose pop
!else
Int64CmpU `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
!endif
!macroend !macroend
!macro IntPtrCmpU a b jeek jles jgtr !macro IntPtrCmpU a b jeek jles jgtr
!if ${NSIS_PTR_SIZE} <= 4 IntPtrCmpU `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
${Int32CmpU} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
!else
${Int64CmpU} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
!endif
!macroend !macroend

View file

@ -683,18 +683,27 @@ static int NSISCALL ExecuteEntry(entry *entry_)
#ifdef NSIS_SUPPORT_INTOPTS #ifdef NSIS_SUPPORT_INTOPTS
case EW_INTCMP: case EW_INTCMP:
{ {
int v,v2; UINT supp64=sizeof(void*) > 4, opu=supp64 ? (BYTE) parm5 : parm5, op64=supp64 ? (INT16) parm5 < 0 : FALSE;
v=GetIntFromParm(0); INT_PTR v=GetIntPtrFromParm(0), v2=GetIntPtrFromParm(1); // Note: This needs to be INT64 if supp64 is ever set to true for 32-bit builds!
v2=GetIntFromParm(1); if (!opu) { // signed:
if (!parm5) { if (op64) {
// signed if ((INT64)v < (INT64)v2) return parm3;
if (v<v2) return parm3; if ((INT64)v > (INT64)v2) return parm4;
if (v>v2) return parm4; }
else {
if ((signed int)v < (signed int)v2) return parm3;
if ((signed int)v > (signed int)v2) return parm4;
}
} }
else { else { // unsigned:
// unsigned if (op64) {
if ((unsigned int)v<(unsigned int)v2) return parm3; if ((UINT64)v < (UINT64)v2) return parm3;
if ((unsigned int)v>(unsigned int)v2) return parm4; if ((UINT64)v > (UINT64)v2) return parm4;
}
else {
if ((unsigned int)v < (unsigned int)v2) return parm3;
if ((unsigned int)v > (unsigned int)v2) return parm4;
}
} }
} }
return parm2; return parm2;

View file

@ -96,7 +96,7 @@ enum
EW_READENVSTR, // ReadEnvStr/ExpandEnvStrings: 3 [output, string_with_env_variables, IsRead] EW_READENVSTR, // ReadEnvStr/ExpandEnvStrings: 3 [output, string_with_env_variables, IsRead]
#endif #endif
#ifdef NSIS_SUPPORT_INTOPTS #ifdef NSIS_SUPPORT_INTOPTS
EW_INTCMP, // IntCmp: 6 [val1, val2, equal, val1<val2, val1>val2, unsigned?] EW_INTCMP, // IntCmp: 6 [val1, val2, equal, val1<val2, val1>val2, flags] where flags: bit 0x01 is set for unsigned operations and bit 0x8000 is set for 64-bit operations
EW_INTOP, // IntOp: 4 [output, input1, input2, op] where op: 0=add, 1=sub, 2=mul, 3=div, 4=bor, 5=band, 6=bxor, 7=bnot input1, 8=lor, 9=land 10=mod, 11=shl, 12=sar, 13=shr (bneg is implemented with bxor in compiler) EW_INTOP, // IntOp: 4 [output, input1, input2, op] where op: 0=add, 1=sub, 2=mul, 3=div, 4=bor, 5=band, 6=bxor, 7=bnot input1, 8=lor, 9=land 10=mod, 11=shl, 12=sar, 13=shr (bneg is implemented with bxor in compiler)
EW_INTFMT, // IntFmt: [output, format, input] EW_INTFMT, // IntFmt: [output, format, input]
#endif #endif

View file

@ -87,6 +87,15 @@ static LANGID ParseLangId(const TCHAR*Str)
return _T('0') == p[0] && _T('x') == (p[1]|32) ? LineParser::parse_int(Str) : _ttoi(Str); return _T('0') == p[0] && _T('x') == (p[1]|32) ? LineParser::parse_int(Str) : _ttoi(Str);
} }
LANGID CEXEBuild::ParseLangIdParameter(const LineParser&line, int token)
{
int succ, lid = line.gettoken_int(token, &succ);
if (!lid) lid = last_used_lang;
if (!succ)
warning_fl(DW_BAD_LANGID, _T("\"%") NPRIs _T("\" is not a valid language id, using language id %u!"), line.gettoken_str(token), lid);
return lid;
}
int CEXEBuild::process_script(NIStream&Strm, const TCHAR *filename) int CEXEBuild::process_script(NIStream&Strm, const TCHAR *filename)
{ {
NStreamLineReader linereader(Strm); NStreamLineReader linereader(Strm);
@ -4169,23 +4178,24 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ent.offsets[2]=add_string(line.gettoken_str(3)); ent.offsets[2]=add_string(line.gettoken_str(3));
SCRIPT_MSG(_T("IntFmt: %") NPRIs _T("->%") NPRIs _T(" (fmt:%") NPRIs _T(")\n"),line.gettoken_str(3),line.gettoken_str(1),line.gettoken_str(2)); SCRIPT_MSG(_T("IntFmt: %") NPRIs _T("->%") NPRIs _T(" (fmt:%") NPRIs _T(")\n"),line.gettoken_str(3),line.gettoken_str(1),line.gettoken_str(2));
return add_entry(&ent); return add_entry(&ent);
case TOK_INTCMP: case TOK_INTCMP: case TOK_INTCMPU: case TOK_INT64CMP: case TOK_INT64CMPU: case TOK_INTPTRCMP: case TOK_INTPTRCMPU:
case TOK_INTCMPU: {
ent.which=EW_INTCMP; int t64 = is_target_64bit(), o32 = TOK_INTCMP == which_token || TOK_INTCMPU == which_token, o64 = TOK_INT64CMP == which_token || TOK_INT64CMPU == which_token;
ent.offsets[0]=add_string(line.gettoken_str(1)); if (!t64 && o64) return (ERROR_MSG(_T("Instruction only supported by 64-bit targets!\n")), PS_ERROR);
ent.offsets[1]=add_string(line.gettoken_str(2)); ent.which=EW_INTCMP;
ent.offsets[5]=which_token == TOK_INTCMPU; ent.offsets[0]=add_string(line.gettoken_str(1));
if (process_jump(line,3,&ent.offsets[2]) || ent.offsets[1]=add_string(line.gettoken_str(2));
process_jump(line,4,&ent.offsets[3]) || ent.offsets[5]=(which_token == TOK_INTCMPU || which_token == TOK_INT64CMPU || which_token == TOK_INTPTRCMPU) | (t64 && !o32 ? 0x8000 : 0);
process_jump(line,5,&ent.offsets[4])) PRINTHELP() if (process_jump(line,3,&ent.offsets[2]) | process_jump(line,4,&ent.offsets[3]) | process_jump(line,5,&ent.offsets[4]))
SCRIPT_MSG(_T("%") NPRIs _T(" %") NPRIs _T(":%") NPRIs _T(" equal=%") NPRIs _T(", < %") NPRIs _T(", > %") NPRIs _T("\n"),line.gettoken_str(0), PRINTHELP()
line.gettoken_str(1),line.gettoken_str(2), line.gettoken_str(3),line.gettoken_str(4),line.gettoken_str(5)); SCRIPT_MSG(_T("%") NPRIs _T(" %") NPRIs _T(":%") NPRIs _T(" equal=%") NPRIs _T(", < %") NPRIs _T(", > %") NPRIs _T("\n"),line.gettoken_str(0),
return add_entry(&ent); line.gettoken_str(1),line.gettoken_str(2), line.gettoken_str(3),line.gettoken_str(4),line.gettoken_str(5));
return add_entry(&ent);
}
#else #else
case TOK_INTOP: case TOK_INTOP: case TOK_INTPTROP:
case TOK_INTCMP: case TOK_INTCMP: case TOK_INTCMPU: case TOK_INT64CMP: case TOK_INT64CMPU: case TOK_INTPTRCMP: case TOK_INTPTRCMPU:
case TOK_INTFMT: case TOK_INTFMT:
case TOK_INTCMPU:
ERROR_MSG(_T("Error: %") NPRIs _T(" specified, NSIS_SUPPORT_INTOPTS not defined.\n"), line.gettoken_str(0)); ERROR_MSG(_T("Error: %") NPRIs _T(" specified, NSIS_SUPPORT_INTOPTS not defined.\n"), line.gettoken_str(0));
return PS_ERROR; return PS_ERROR;
#endif //~ NSIS_SUPPORT_INTOPTS #endif //~ NSIS_SUPPORT_INTOPTS
@ -5427,12 +5437,3 @@ int CEXEBuild::do_add_file_create_dir(const tstring& local_dir, const tstring& d
return PS_OK; return PS_OK;
} }
#endif #endif
LANGID CEXEBuild::ParseLangIdParameter(const LineParser&line, int token)
{
int succ, lid = line.gettoken_int(token, &succ);
if (!lid) lid = last_used_lang;
if (!succ)
warning_fl(DW_BAD_LANGID, _T("\"%") NPRIs _T("\" is not a valid language id, using language id %u!"), line.gettoken_str(token), lid);
return lid;
}

View file

@ -126,6 +126,10 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_INTPTROP,_T("IntPtrOp"),3,1,_T("$(user_var: result) val1 OP [val2]"),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_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_INTCMPU,_T("IntCmpU"),3,2,_T("val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"),TP_CODE},
{TOK_INT64CMP,_T("Int64Cmp"),3,2,_T("val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"),TP_CODE},
{TOK_INT64CMPU,_T("Int64CmpU"),3,2,_T("val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"),TP_CODE},
{TOK_INTPTRCMP,_T("IntPtrCmp"),3,2,_T("val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"),TP_CODE},
{TOK_INTPTRCMPU,_T("IntPtrCmpU"),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}, {TOK_INTFMT,_T("IntFmt"),3,0,_T("$(user_var: output) format_string input"),TP_CODE},
{TOK_ISWINDOW,_T("IsWindow"),2,1,_T("hwnd jump_if_window [jump_if_not_window]"),TP_CODE}, {TOK_ISWINDOW,_T("IsWindow"),2,1,_T("hwnd jump_if_window [jump_if_not_window]"),TP_CODE},
{TOK_GOTO,_T("Goto"),1,0,_T("label"),TP_CODE}, {TOK_GOTO,_T("Goto"),1,0,_T("label"),TP_CODE},

View file

@ -241,6 +241,10 @@ enum
TOK_INTPTROP, TOK_INTPTROP,
TOK_INTCMP, TOK_INTCMP,
TOK_INTCMPU, TOK_INTCMPU,
TOK_INT64CMP,
TOK_INT64CMPU,
TOK_INTPTRCMP,
TOK_INTPTRCMPU,
TOK_INTFMT, TOK_INTFMT,
TOK_ENUMREGKEY, TOK_ENUMREGKEY,
TOK_ENUMREGVAL, TOK_ENUMREGVAL,