diff --git a/Docs/src/defines.but b/Docs/src/defines.but index f6c97958..dbc5b06e 100644 --- a/Docs/src/defines.but +++ b/Docs/src/defines.but @@ -61,6 +61,7 @@ The opposite of !ifdef. The lines will be compiled when the gflag has not been d \S1{if} !if \c [!] value [op value2] +\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. op can be either == or != (string comparison), <=, < > or >= (float comparison), & (bitwise AND comparison), && or || (boolean comparison). @@ -74,6 +75,10 @@ If [!] is set, return value will be switched from true to false and vice versa. \c !error "neither should this" \c !endif +\c !if /FileExists ".\cert.pfx" +\c !finalize '".\sign.bat" "%1"' +\c !endif + \S1{ifmacrodef} !ifmacrodef \c gflag [bcheck gflag [...]]] diff --git a/Source/dirreader.h b/Source/dirreader.h index 52cebe8f..e42394fb 100644 --- a/Source/dirreader.h +++ b/Source/dirreader.h @@ -33,6 +33,10 @@ public: virtual const std::set& files(); virtual const std::set& dirs(); + // dir_reader always excludes . and .. AND the exclude list is private, + // use this backdoor if you need to match "." + virtual std::set& hack_simpleexcluded() {return m_excluded;} + virtual void exclude(const tstring& spec); virtual void exclude(const std::set& specs); diff --git a/Source/script.cpp b/Source/script.cpp index 1c9dfa3b..2f3c900a 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -486,7 +486,33 @@ parse_again: if(line.getnumtokens() == 2) istrue = line.gettoken_int(1); - + + else if (line.getnumtokens() == 3) { + if (!_tcsicmp(line.gettoken_str(1),_T("/fileexists"))) + { + TCHAR *fc = my_convert(line.gettoken_str(2)); + tstring dir = get_dir_name(fc), spec = get_file_name(fc); + my_convert_free(fc); + if (dir == spec) dir = _T("."); + + boost::scoped_ptr dr( new_dir_reader() ); + dr->hack_simpleexcluded().erase(_T(".")); + dr->read(dir); + + for (dir_reader::iterator fit = dr->files().begin(); + fit != dr->files().end() && !istrue; fit++) + { + if (dir_reader::matches(*fit, spec)) istrue = true; + } + if (!istrue) for (dir_reader::iterator dit = dr->dirs().begin(); + dit != dr->dirs().end() && !istrue; dit++) + { + if (dir_reader::matches(*dit, spec)) istrue = true; + } + } + else PRINTHELP() + } + else if (line.getnumtokens() == 4) { mod = line.gettoken_enum(2,_T("=\0==\0!=\0<=\0<\0>\0>=\0&\0&&\0|\0||\0")); diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 85ade425..39ef29df 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -246,7 +246,7 @@ static tokenType tokenlist[TOK__LAST] = {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_CD,_T("!cd"),1,0,_T("absolute_or_relative_new_directory"),TP_ALL}, -{TOK_P_IF,_T("!if"),1,3,_T("[!] value [(==,!=,<=,<,>,>=,&,&&,||) value2] [...]"),TP_ALL}, +{TOK_P_IF,_T("!if"),1,3,_T("[!] (value [(==,!=,<=,<,>,>=,&,&&,||) value2] | /FILEEXISTS path) [...]"),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_ENDIF,_T("!endif"),0,0,_T(""),TP_ALL},