applied patch #1412982 - "!if" - enhanced compile time flow control
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@4526 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
0bcee34186
commit
b1dc917843
5 changed files with 138 additions and 34 deletions
|
@ -51,6 +51,40 @@ d\
|
|||
i\
|
||||
f
|
||||
|
||||
# tests for !if statement
|
||||
!if 'test' == 'test'
|
||||
!if 1 <= 2
|
||||
!if ! 100 < 99.99
|
||||
!if 2.2 > 1.12
|
||||
!if ! 23 >= 37
|
||||
!if 1 && 1
|
||||
!if ! 0 || 0
|
||||
|
||||
# this should be compiled
|
||||
|
||||
!else
|
||||
!error "!if ! 0 || 0 is true!"
|
||||
!endif
|
||||
!else
|
||||
!error "!if 1 && 1 is true!"
|
||||
!endif
|
||||
!else
|
||||
!error "!if ! 23 >= 37 is true!"
|
||||
!endif
|
||||
!else
|
||||
!error "!if 2.2 > 1.12 is true!"
|
||||
!endif
|
||||
!else
|
||||
!error "!if ! 100 < 99.99 is true!"
|
||||
!endif
|
||||
!else
|
||||
!error "!if 1 <= 2 is true!"
|
||||
!endif
|
||||
!else
|
||||
!error "!if 'test' == 'test' is true!"
|
||||
!endif
|
||||
|
||||
|
||||
# this should just give a warning, not an error
|
||||
!include /NONFATAL file_that_doesnt_exist.nsh
|
||||
|
||||
|
|
|
@ -353,9 +353,15 @@ parse_again:
|
|||
if (cur_ifblock && cur_ifblock->inherited_ignore)
|
||||
return PS_OK;
|
||||
|
||||
if (!num_ifblock() || cur_ifblock->elseused)
|
||||
if (!num_ifblock())
|
||||
{
|
||||
ERROR_MSG("!else: stray !else\n");
|
||||
ERROR_MSG("!else: no if block open (!if[macro][n][def])\n");
|
||||
return PS_ERROR;
|
||||
}
|
||||
|
||||
if (cur_ifblock->elseused)
|
||||
{
|
||||
ERROR_MSG("!else: else already used in current if block\n");
|
||||
return PS_ERROR;
|
||||
}
|
||||
|
||||
|
@ -376,16 +382,17 @@ parse_again:
|
|||
|
||||
line.eattoken();
|
||||
|
||||
int v=line.gettoken_enum(0,"ifdef\0ifndef\0ifmacrodef\0ifmacrondef\0");
|
||||
int v=line.gettoken_enum(0,"if\0ifdef\0ifndef\0ifmacrodef\0ifmacrondef\0");
|
||||
if (v < 0) PRINTHELP()
|
||||
if (line.getnumtokens() == 1) PRINTHELP()
|
||||
int cmds[] = {TOK_P_IFDEF, TOK_P_IFNDEF, TOK_P_IFMACRODEF, TOK_P_IFMACRONDEF};
|
||||
int cmds[] = {TOK_P_IF, TOK_P_IFDEF, TOK_P_IFNDEF, TOK_P_IFMACRODEF, TOK_P_IFMACRONDEF};
|
||||
tkid = cmds[v];
|
||||
if_from_else++;
|
||||
}
|
||||
|
||||
if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFDEF ||
|
||||
tkid == TOK_P_IFMACRODEF || tkid == TOK_P_IFMACRONDEF)
|
||||
tkid == TOK_P_IFMACRODEF || tkid == TOK_P_IFMACRONDEF ||
|
||||
tkid == TOK_P_IF)
|
||||
{
|
||||
if (!if_from_else)
|
||||
start_ifblock();
|
||||
|
@ -398,29 +405,74 @@ parse_again:
|
|||
int istrue=0;
|
||||
|
||||
int mod=0;
|
||||
int p;
|
||||
|
||||
// pure left to right precedence. Not too powerful, but useful.
|
||||
for (p = 1; p < line.getnumtokens(); p ++)
|
||||
{
|
||||
if (p & 1)
|
||||
{
|
||||
int new_s;
|
||||
if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFDEF)
|
||||
new_s=!!definedlist.find(line.gettoken_str(p));
|
||||
else
|
||||
new_s=MacroExists(line.gettoken_str(p));
|
||||
if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFMACRONDEF)
|
||||
new_s=!new_s;
|
||||
|
||||
if (mod == 0) istrue = istrue || new_s;
|
||||
else istrue = istrue && new_s;
|
||||
|
||||
int p=0;
|
||||
|
||||
if (tkid == TOK_P_IF) {
|
||||
if(!strcmp(line.gettoken_str(1),"!")) {
|
||||
p = 1;
|
||||
line.eattoken();
|
||||
}
|
||||
else
|
||||
|
||||
if(line.getnumtokens() == 2)
|
||||
istrue = line.gettoken_int(1);
|
||||
|
||||
else if (line.getnumtokens() == 4) {
|
||||
mod = line.gettoken_enum(2,"=\0==\0!=\0<=\0<\0>\0>=\0&\0&&\0|\0||\0");
|
||||
|
||||
switch(mod) {
|
||||
case 0:
|
||||
case 1:
|
||||
istrue = strcmp(line.gettoken_str(1),line.gettoken_str(3)) == 0; break;
|
||||
case 2:
|
||||
istrue = strcmp(line.gettoken_str(1),line.gettoken_str(3)) != 0; break;
|
||||
case 3:
|
||||
istrue = line.gettoken_float(1) <= line.gettoken_float(3); break;
|
||||
case 4:
|
||||
istrue = line.gettoken_float(1) < line.gettoken_float(3); break;
|
||||
case 5:
|
||||
istrue = line.gettoken_float(1) > line.gettoken_float(3); break;
|
||||
case 6:
|
||||
istrue = line.gettoken_float(1) >= line.gettoken_float(3); break;
|
||||
case 7:
|
||||
case 8:
|
||||
istrue = line.gettoken_int(1) && line.gettoken_int(3); break;
|
||||
case 9:
|
||||
case 10:
|
||||
istrue = line.gettoken_int(1) || line.gettoken_int(3); break;
|
||||
default:
|
||||
PRINTHELP()
|
||||
}
|
||||
}
|
||||
else PRINTHELP()
|
||||
|
||||
if(p) istrue = !istrue;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
// pure left to right precedence. Not too powerful, but useful.
|
||||
for (p = 1; p < line.getnumtokens(); p ++)
|
||||
{
|
||||
mod=line.gettoken_enum(p,"|\0&\0||\0&&\0");
|
||||
if (mod == -1) PRINTHELP()
|
||||
mod &= 1;
|
||||
if (p & 1)
|
||||
{
|
||||
int new_s;
|
||||
if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFDEF)
|
||||
new_s=!!definedlist.find(line.gettoken_str(p));
|
||||
else
|
||||
new_s=MacroExists(line.gettoken_str(p));
|
||||
if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFMACRONDEF)
|
||||
new_s=!new_s;
|
||||
|
||||
if (mod == 0) istrue = istrue || new_s;
|
||||
else istrue = istrue && new_s;
|
||||
}
|
||||
else
|
||||
{
|
||||
mod=line.gettoken_enum(p,"|\0&\0||\0&&\0");
|
||||
if (mod == -1) PRINTHELP()
|
||||
mod &= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -437,7 +489,7 @@ parse_again:
|
|||
if (tkid == TOK_P_ENDIF) {
|
||||
if (!num_ifblock())
|
||||
{
|
||||
ERROR_MSG("!endif: no !ifdef open\n");
|
||||
ERROR_MSG("!endif: no if block open (!if[macro][n][def])\n");
|
||||
return PS_ERROR;
|
||||
}
|
||||
end_ifblock();
|
||||
|
|
|
@ -225,12 +225,13 @@ static tokenType tokenlist[TOK__LAST] =
|
|||
{TOK_P_ADDINCLUDEDIR,"!AddIncludeDir",1,0,"dir",TP_ALL},
|
||||
{TOK_P_INCLUDE,"!include",1,1,"[/NONFATAL] filename.nsh",TP_ALL},
|
||||
{TOK_P_CD,"!cd",1,0,"absolute_or_relative_new_directory",TP_ALL},
|
||||
{TOK_P_IF,"!if",1,3,"[!] value [(==,!=,<=,<,>,>=,&&,||) value2] [...]",TP_ALL},
|
||||
{TOK_P_IFDEF,"!ifdef",1,-1,"symbol [| symbol2 [& symbol3 [...]]]",TP_ALL},
|
||||
{TOK_P_IFNDEF,"!ifndef",1,-1,"symbol [| symbol2 [& symbol3 [...]]]",TP_ALL},
|
||||
{TOK_P_ENDIF,"!endif",0,0,"",TP_ALL},
|
||||
{TOK_P_DEFINE,"!define",1,2,"[/date] symbol [value]",TP_ALL},
|
||||
{TOK_P_UNDEF,"!undef",1,1,"symbol [value]",TP_ALL},
|
||||
{TOK_P_ELSE,"!else",0,-1,"[ifdef|ifndef symbol [|symbol2 [& symbol3 [...]]]]",TP_ALL},
|
||||
{TOK_P_ELSE,"!else",0,-1,"[if[macro][n][def] ...]",TP_ALL},
|
||||
{TOK_P_ECHO,"!echo",1,0,"message",TP_ALL},
|
||||
{TOK_P_WARNING,"!warning",0,1,"[warning_message]",TP_ALL},
|
||||
{TOK_P_ERROR,"!error",0,1,"[error_message]",TP_ALL},
|
||||
|
|
|
@ -71,6 +71,7 @@ enum
|
|||
TOK_FILEBUFSIZE,
|
||||
|
||||
// system "preprocessor"ish tokens
|
||||
TOK_P_IF,
|
||||
TOK_P_IFDEF,
|
||||
TOK_P_IFNDEF,
|
||||
TOK_P_ELSE,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue