Added !if S==, S!=, = and <> compare ops and hex/int/float parsing support

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6198 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2011-12-06 19:14:45 +00:00
parent 357aa9675b
commit 67d0b165b1
5 changed files with 44 additions and 18 deletions

View file

@ -64,10 +64,10 @@ The opposite of !ifdef. The lines will be compiled when the gflag has not been d
\c [!] /FileExists "c:\path\file.exe" \c [!] /FileExists "c:\path\file.exe"
This command, when paired with an !endif command, will tell the compiler whether or not to compile the lines in between the two lines. If value is non-zero, or the comparison of value and value2 depending on the operator results in true, the contained lines will be compiled. Otherwise, they will be skipped. This command, when paired with an !endif command, will tell the compiler whether or not to compile the lines in between the two lines. If value is non-zero, or the comparison of value and value2 depending on the operator results in true, the contained lines will be compiled. Otherwise, they will be skipped.
op can be either == or != (string comparison), <=, < > or >= (float comparison), & (bitwise AND comparison), && or || (boolean comparison). op can be either == or != (case-insensitive string comparison), S== or S!= (case-sensitive string comparison), =, <>, <=, <, > or >= (int/hex/float comparison), & (bitwise AND comparison), && or || (boolean comparison).
If [!] is set, return value will be switched from true to false and vice versa. If [!] is set, return value will be switched from true to false and vice versa.
\c !if 1 < 2 \c !if 1 < 0x2
\c !echo "1 is smaller than 2!!" \c !echo "1 is smaller than 2!!"
\c !else if ! 3.1 > 1.99 \c !else if ! 3.1 > 1.99
\c !error "this line should never appear" \c !error "this line should never appear"

View file

@ -88,6 +88,7 @@ double LineParser::gettoken_float(int token, int *success/*=0*/)
if (success) if (success)
{ {
TCHAR *t=m_tokens[token]; TCHAR *t=m_tokens[token];
if (_T('-') == *t || _T('+') == *t) ++t;
*success=*t?1:0; *success=*t?1:0;
while (*t) while (*t)
{ {
@ -108,12 +109,22 @@ int LineParser::gettoken_int(int token, int *success/*=0*/)
} }
TCHAR *tmp; TCHAR *tmp;
int l; int l;
if (m_tokens[token][0] == _T('-')) l=_tcstol(m_tokens[token],&tmp,0); if (_T('-') == m_tokens[token][0])
else l=(int)_tcstoul(m_tokens[token],&tmp,0); l=_tcstol(m_tokens[token],&tmp,0);
else
l=(int)_tcstoul(m_tokens[token],&tmp,0);
if (success) *success=! (int)(*tmp); if (success) *success=! (int)(*tmp);
return l; return l;
} }
double LineParser::gettoken_number(int token, int *success/*=0*/)
{
const TCHAR*str=gettoken_str(token);
if (_T('-') == *str || _T('+') == *str) ++str;
if (_T('0') == str[0] && _T('x') == (str[1]|32)) return gettoken_int(token,success);
return gettoken_float(token,success);
}
TCHAR* LineParser::gettoken_str(int token) TCHAR* LineParser::gettoken_str(int token)
{ {
token+=m_eat; token+=m_eat;

View file

@ -34,6 +34,7 @@ class LineParser {
void eattoken(); void eattoken();
double gettoken_float(int token, int *success=0); double gettoken_float(int token, int *success=0);
int gettoken_int(int token, int *success=0); int gettoken_int(int token, int *success=0);
double gettoken_number(int token, int *success=0);
TCHAR *gettoken_str(int token); TCHAR *gettoken_str(int token);
int gettoken_enum(int token, const TCHAR *strlist); // null seperated list int gettoken_enum(int token, const TCHAR *strlist); // null seperated list

View file

@ -489,8 +489,7 @@ parse_again:
istrue = line.gettoken_int(1); istrue = line.gettoken_int(1);
else if (line.getnumtokens() == 3) { else if (line.getnumtokens() == 3) {
if (!_tcsicmp(line.gettoken_str(1),_T("/fileexists"))) if (!_tcsicmp(line.gettoken_str(1),_T("/fileexists"))) {
{
TCHAR *fc = my_convert(line.gettoken_str(2)); TCHAR *fc = my_convert(line.gettoken_str(2));
tstring dir = get_dir_name(fc), spec = get_file_name(fc); tstring dir = get_dir_name(fc), spec = get_file_name(fc);
my_convert_free(fc); my_convert_free(fc);
@ -515,32 +514,47 @@ parse_again:
} }
else if (line.getnumtokens() == 4) { else if (line.getnumtokens() == 4) {
mod = line.gettoken_enum(2,_T("=\0==\0!=\0<=\0<\0>\0>=\0&\0&&\0|\0||\0")); mod = line.gettoken_enum(2,
_T("==\0!=\0S==\0S!=\0")
_T("=\0<>\0<=\0<\0>\0>=\0")
_T("&\0&&\0|\0||\0")
);
int cnv1 = 1, cnv2 = 1;
switch(mod) { switch(mod) {
case 0: case 0:
case 1:
istrue = _tcsicmp(line.gettoken_str(1),line.gettoken_str(3)) == 0; break; istrue = _tcsicmp(line.gettoken_str(1),line.gettoken_str(3)) == 0; break;
case 2: case 1:
istrue = _tcsicmp(line.gettoken_str(1),line.gettoken_str(3)) != 0; break; istrue = _tcsicmp(line.gettoken_str(1),line.gettoken_str(3)) != 0; break;
case 2:
istrue = _tcscmp(line.gettoken_str(1),line.gettoken_str(3)) == 0; break;
case 3: case 3:
istrue = line.gettoken_float(1) <= line.gettoken_float(3); break; istrue = _tcscmp(line.gettoken_str(1),line.gettoken_str(3)) != 0; break;
case 4: case 4:
istrue = line.gettoken_float(1) < line.gettoken_float(3); break; istrue = line.gettoken_number(1,&cnv1) == line.gettoken_number(3,&cnv2); break;
case 5: case 5:
istrue = line.gettoken_float(1) > line.gettoken_float(3); break; istrue = line.gettoken_number(1,&cnv1) != line.gettoken_number(3,&cnv2); break;
case 6: case 6:
istrue = line.gettoken_float(1) >= line.gettoken_float(3); break; istrue = line.gettoken_number(1,&cnv1) <= line.gettoken_number(3,&cnv2); break;
case 7: case 7:
istrue = (line.gettoken_int(1) & line.gettoken_int(3)) != 0; break; istrue = line.gettoken_number(1,&cnv1) < line.gettoken_number(3,&cnv2); break;
case 8: case 8:
istrue = line.gettoken_int(1) && line.gettoken_int(3); break; istrue = line.gettoken_number(1,&cnv1) > line.gettoken_number(3,&cnv2); break;
case 9: case 9:
istrue = line.gettoken_number(1,&cnv1) >= line.gettoken_number(3,&cnv2); break;
case 10: case 10:
istrue = line.gettoken_int(1) || line.gettoken_int(3); break; istrue = (line.gettoken_int(1,&cnv1) & line.gettoken_int(3,&cnv2)) != 0; break;
case 11:
istrue = line.gettoken_int(1,&cnv1) && line.gettoken_int(3,&cnv2); break;
case 12:
case 13:
istrue = line.gettoken_int(1,&cnv1) || line.gettoken_int(3,&cnv2); break;
default: default:
PRINTHELP() PRINTHELP()
} }
if (!cnv1 || !cnv2) {
warning_fl("Invalid number: \"%s\"", line.gettoken_str(!cnv1 ? 1 : 3));
}
} }
else PRINTHELP() else PRINTHELP()

View file

@ -247,7 +247,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_P_ADDINCLUDEDIR,_T("!AddIncludeDir"),1,0,_T("dir"),TP_ALL}, {TOK_P_ADDINCLUDEDIR,_T("!AddIncludeDir"),1,0,_T("dir"),TP_ALL},
{TOK_P_INCLUDE,_T("!include"),1,1,_T("[/NONFATAL] filename.nsh"),TP_ALL}, {TOK_P_INCLUDE,_T("!include"),1,1,_T("[/NONFATAL] filename.nsh"),TP_ALL},
{TOK_P_CD,_T("!cd"),1,0,_T("absolute_or_relative_new_directory"),TP_ALL}, {TOK_P_CD,_T("!cd"),1,0,_T("absolute_or_relative_new_directory"),TP_ALL},
{TOK_P_IF,_T("!if"),1,3,_T("[!] (value [(==,!=,<=,<,>,>=,&,&&,||) value2] | /FILEEXISTS path)"),TP_ALL}, {TOK_P_IF,_T("!if"),1,3,_T("[!] (value [(==,!=,S==,S!=,=,<>,<=,<,>,>=,&,&&,||) value2] | /FILEEXISTS path)"),TP_ALL},
{TOK_P_IFDEF,_T("!ifdef"),1,-1,_T("symbol [| symbol2 [& symbol3 [...]]]"),TP_ALL}, {TOK_P_IFDEF,_T("!ifdef"),1,-1,_T("symbol [| symbol2 [& symbol3 [...]]]"),TP_ALL},
{TOK_P_IFNDEF,_T("!ifndef"),1,-1,_T("symbol [| symbol2 [& symbol3 [...]]]"),TP_ALL}, {TOK_P_IFNDEF,_T("!ifndef"),1,-1,_T("symbol [| symbol2 [& symbol3 [...]]]"),TP_ALL},
{TOK_P_ENDIF,_T("!endif"),0,0,_T(""),TP_ALL}, {TOK_P_ENDIF,_T("!endif"),0,0,_T(""),TP_ALL},