Improved !searchparse error detection/handling

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6348 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2013-04-16 21:02:50 +00:00
parent bbe60b09dd
commit cf0d27706a
2 changed files with 48 additions and 66 deletions

View file

@ -227,7 +227,7 @@ class CEXEBuild {
bool inside_comment; bool inside_comment;
int multiple_entries_instruction; // 1 (true) or 0 (false) int multiple_entries_instruction; // 1 (true) or 0 (false)
DefineList *searchParseString(const TCHAR *source_string, LineParser *line, int parmOffs, bool ignCase, bool noErrors); DefineList *searchParseString(const TCHAR *source_string, LineParser&line, int parmOffs, bool ignCase, bool noErrors, UINT*failParam = 0);
// build.cpp functions used mostly by script.cpp // build.cpp functions used mostly by script.cpp
void set_target_architecture_predefines(); void set_target_architecture_predefines();

View file

@ -3397,7 +3397,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ERROR_MSG(_T("!searchparse: not enough parameters\n")); ERROR_MSG(_T("!searchparse: not enough parameters\n"));
return PS_ERROR; return PS_ERROR;
} }
const TCHAR *source_string = line.gettoken_str(parmOffs++); const TCHAR *source_string = line.gettoken_str(parmOffs++);
DefineList *list=NULL; DefineList *list=NULL;
@ -3410,7 +3409,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ERROR_MSG(_T("!searchparse /file: error opening \"%s\"\n"),filename); ERROR_MSG(_T("!searchparse /file: error opening \"%s\"\n"),filename);
return PS_ERROR; return PS_ERROR;
} }
int req_parm = (line.getnumtokens() - parmOffs)/2; UINT req_parm=(line.getnumtokens() - parmOffs)/2, fail_parm=0;
NStreamLineReader lr(filestrm); NStreamLineReader lr(filestrm);
GrowBuf tmpstr; GrowBuf tmpstr;
TCHAR *str=m_templinebuf; TCHAR *str=m_templinebuf;
@ -3434,7 +3433,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
} }
str[--cch]=_T('\0'); // remove newline str[--cch]=_T('\0'); // remove newline
const bool endSlash = cch && _T('\\') == str[cch-1]; const bool endSlash=cch && _T('\\') == str[cch-1];
if (endSlash) --cch; // don't include the slash character if (endSlash) --cch; // don't include the slash character
if (tmpstr.getlen() || endSlash) tmpstr.add(str,cch*sizeof(TCHAR)); if (tmpstr.getlen() || endSlash) tmpstr.add(str,cch*sizeof(TCHAR));
@ -3450,38 +3449,36 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
tmpstr.add(_T("\0"),sizeof(TCHAR)); tmpstr.add(_T("\0"),sizeof(TCHAR));
thisline=(TCHAR *)tmpstr.get(); thisline=(TCHAR *)tmpstr.get();
} }
UINT linefailparm;
DefineList *tlist = searchParseString(thisline,&line,parmOffs,ignCase,true); DefineList *tlist = searchParseString(thisline,line,parmOffs,ignCase,true,&linefailparm);
if (linefailparm > fail_parm) fail_parm = linefailparm;
if (tlist && tlist->getnum()) if (tlist && tlist->getnum())
{ {
if (!list || tlist->getnum() > list->getnum()) if (!list || tlist->getnum() > list->getnum())
{ {
delete list; delete list;
list=tlist; list=tlist, tlist=0;
if (tlist->getnum() >= req_parm) break; // success! if ((unsigned)list->getnum() >= req_parm)
{
fail_parm = -1; // success
break; // we found all the tokens, stop parsing the file
}
} }
else delete list;
} }
delete tlist;
// parse line // parse line
} }
if (!noErrors) if ((unsigned)-1 != fail_parm && !noErrors)
{ {
if (!list) const TCHAR *msgprefix=!fail_parm ? _T("starting ") : _T("");
{ TCHAR *p=line.gettoken_str(parmOffs + (fail_parm*2));
ERROR_MSG(_T("!searchparse: starting string \"%s\" not found in file!\n"),line.gettoken_str(parmOffs)); ERROR_MSG(_T("!searchparse: %sstring \"%s\" not found in file!\n"),msgprefix,p?p:_T("(null)"));
return PS_ERROR; return PS_ERROR;
}
else if (list->getnum() < req_parm)
{
TCHAR *p=line.gettoken_str(parmOffs + list->getnum()*2);
ERROR_MSG(_T("!searchparse: failed search at string \"%s\" not found in file!\n"),p?p:_T("(null)"));
return PS_ERROR;
}
} }
} }
else else
{ {
list=searchParseString(source_string,&line,parmOffs,ignCase,noErrors); list=searchParseString(source_string,line,parmOffs,ignCase,noErrors);
if (!list && !noErrors) return PS_ERROR; if (!list && !noErrors) return PS_ERROR;
} }
@ -6844,66 +6841,51 @@ int CEXEBuild::do_add_file_create_dir(const tstring& local_dir, const tstring& d
DefineList *CEXEBuild::searchParseString(const TCHAR *source_string, LineParser *line, int parmOffs, bool ignCase, bool noErrors) DefineList *CEXEBuild::searchParseString(const TCHAR *source_string, LineParser&line, int parmOffs, bool ignCase, bool noErrors, UINT*failParam)
{ {
const TCHAR *tok = line->gettoken_str(parmOffs++); if (failParam) *failParam = 0;
if (tok && *tok)
{
int toklen = _tcslen(tok);
while (*source_string && (ignCase?_tcsnicmp(source_string,tok,toklen):_tcsncmp(source_string,tok,toklen))) source_string++;
if (!*source_string)
{
if (!noErrors) ERROR_MSG(_T("!searchparse: starting string \"%s\" not found, aborted search!\n"),tok);
return NULL;
}
if (*source_string) source_string+=toklen;
}
DefineList *ret = NULL; DefineList *ret = NULL;
const TCHAR *defout = 0, *src_start = 0, *tok;
while (parmOffs < line->getnumtokens()) int toklen = 0, maxlen;
for (;;)
{ {
const TCHAR *defout = line->gettoken_str(parmOffs++); tok = line.gettoken_str(parmOffs++);
if (parmOffs < line->getnumtokens()) tok=line->gettoken_str(parmOffs++); const bool lasttoken = parmOffs > line.getnumtokens();
else tok=NULL; if (!tok || !*tok)
tok = 0, maxlen = -1; // No more tokens to search for, save the rest of the string
else
int maxlen=-1;
const TCHAR *src_start = source_string;
if (tok && *tok)
{ {
int toklen = _tcslen(tok); toklen = _tcslen(tok);
while (*source_string && (ignCase?_tcsnicmp(source_string,tok,toklen):_tcsncmp(source_string,tok,toklen))) source_string++; while (*source_string && (ignCase?_tcsnicmp(source_string,tok,toklen):_tcsncmp(source_string,tok,toklen))) source_string++;
maxlen = source_string - src_start; // Length of previous string
maxlen = source_string - src_start;
if (*source_string) source_string += toklen;
else if (!noErrors)
{
ERROR_MSG(_T("!searchparse: string \"%s\" not found, aborted search!\n"),tok);
delete ret;
return NULL;
}
} }
if (defout && defout[0]) // We now know the start and length of the previous string, add it to the list
if (defout && defout[0])
{ {
if (!ret) ret = new DefineList; if (!ret) ret = new DefineList();
if (maxlen < 0)
if (maxlen < 0) ret->add(defout,src_start); ret->add(defout,src_start);
else else
{ {
TCHAR *p=_tcsdup(src_start); TCHAR *p = _tcsdup(src_start);
if (p) if (p)
{ {
p[maxlen]=0; p[maxlen] = 0;
ret->add(defout,p); ret->add(defout,p);
free(p); free(p);
} }
} }
} }
if (!*source_string || (!tok && !lasttoken)) // We did not find the requested token!
{
if (failParam) *failParam = ret ? ret->getnum() : 0;
if (noErrors) break; // Caller is OK with a incomplete list of matched strings
const TCHAR *msgprefix = src_start ? _T("") : _T("starting ");
ERROR_MSG(_T("!searchparse: %sstring \"%s\" not found, aborted search!\n"),msgprefix,tok);
delete ret;
return NULL;
}
if (maxlen < 0) break;
defout = line.gettoken_str(parmOffs++), src_start = source_string + toklen;
} }
return ret; return ret;
} }