!searchparse and !define /file support
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@5682 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
1ec1f9798c
commit
8794e84cf1
4 changed files with 227 additions and 3 deletions
|
@ -196,7 +196,9 @@ class CEXEBuild {
|
||||||
|
|
||||||
void ERROR_MSG(const char *s, ...) const;
|
void ERROR_MSG(const char *s, ...) const;
|
||||||
void SCRIPT_MSG(const char *s, ...) const;
|
void SCRIPT_MSG(const char *s, ...) const;
|
||||||
void INFO_MSG(const char *s, ...) const;
|
void INFO_MSG(const char *s, ...) const;
|
||||||
|
|
||||||
|
DefineList *searchParseString(const char *source_string, LineParser *line, int parmOffs, bool ignCase, bool noErrors);
|
||||||
|
|
||||||
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
|
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
|
||||||
int add_plugins_dir_initializer(void);
|
int add_plugins_dir_initializer(void);
|
||||||
|
|
|
@ -2766,7 +2766,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
case TOK_P_DEFINE:
|
case TOK_P_DEFINE:
|
||||||
{
|
{
|
||||||
char *define=line.gettoken_str(1);
|
char *define=line.gettoken_str(1);
|
||||||
char *value;
|
char *value;
|
||||||
|
GrowBuf file_buf;
|
||||||
char datebuf[256];
|
char datebuf[256];
|
||||||
char mathbuf[256];
|
char mathbuf[256];
|
||||||
|
|
||||||
|
@ -2793,6 +2794,39 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
datebuf[max(s,sizeof(datebuf)-1)]=0;
|
datebuf[max(s,sizeof(datebuf)-1)]=0;
|
||||||
|
|
||||||
value=datebuf;
|
value=datebuf;
|
||||||
|
} else if (!stricmp(define,"/file") || !stricmp(define,"/file_noerr")) {
|
||||||
|
|
||||||
|
if (line.getnumtokens()!=4) PRINTHELP()
|
||||||
|
|
||||||
|
define=line.gettoken_str(2);
|
||||||
|
const char *filename=line.gettoken_str(3);
|
||||||
|
FILE *fp=fopen(filename,"r");
|
||||||
|
|
||||||
|
if (!fp && stricmp(define,"/file_noerr")) {
|
||||||
|
ERROR_MSG("!define /file: file not found (\"%s\")\n",filename);
|
||||||
|
return PS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fp) {
|
||||||
|
char str[MAX_LINELENGTH];
|
||||||
|
for (;;) {
|
||||||
|
char *p=str;
|
||||||
|
*p=0;
|
||||||
|
fgets(str,MAX_LINELENGTH,fp);
|
||||||
|
linecnt++;
|
||||||
|
if (feof(fp)&&!str[0]) break;
|
||||||
|
|
||||||
|
while (*p) p++;
|
||||||
|
if (p > str) p--;
|
||||||
|
while (p >= str && (*p == '\r' || *p == '\n')) p--;
|
||||||
|
*++p=0;
|
||||||
|
if (file_buf.getlen()) file_buf.add("\n",1);
|
||||||
|
file_buf.add(str,strlen(str));
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
file_buf.add("\0",1);
|
||||||
|
value = (char *)file_buf.get();
|
||||||
|
|
||||||
} else if (!stricmp(define,"/math")) {
|
} else if (!stricmp(define,"/math")) {
|
||||||
|
|
||||||
|
@ -3042,6 +3076,123 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
case TOK_P_ECHO:
|
case TOK_P_ECHO:
|
||||||
SCRIPT_MSG("%s (%s:%d)\n", line.gettoken_str(1),curfilename,linecnt);
|
SCRIPT_MSG("%s (%s:%d)\n", line.gettoken_str(1),curfilename,linecnt);
|
||||||
return PS_OK;
|
return PS_OK;
|
||||||
|
case TOK_P_SEARCHPARSESTRING:
|
||||||
|
{
|
||||||
|
bool ignCase=false;
|
||||||
|
bool noErrors=false;
|
||||||
|
bool isFile=false;
|
||||||
|
int parmOffs=1;
|
||||||
|
while (parmOffs < line.getnumtokens())
|
||||||
|
{
|
||||||
|
if (!stricmp(line.gettoken_str(parmOffs),"/ignorecase")) { ignCase=true; parmOffs++; }
|
||||||
|
else if (!stricmp(line.gettoken_str(parmOffs),"/noerrors")) { noErrors=true; parmOffs++; }
|
||||||
|
else if (!stricmp(line.gettoken_str(parmOffs),"/file")) { isFile=true; parmOffs++; }
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
if (parmOffs+3 > line.getnumtokens())
|
||||||
|
{
|
||||||
|
ERROR_MSG("!searchparse: not enough parameters\n");
|
||||||
|
return PS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *source_string = line.gettoken_str(parmOffs++);
|
||||||
|
DefineList *list=NULL;
|
||||||
|
|
||||||
|
if (isFile)
|
||||||
|
{
|
||||||
|
FILE *fp=fopen(source_string,"r");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
ERROR_MSG("!searchparse /file: error opening \"%s\"\n",source_string);
|
||||||
|
return PS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int req_parm = (line.getnumtokens() - parmOffs)/2;
|
||||||
|
|
||||||
|
GrowBuf tmpstr;
|
||||||
|
char str[MAX_LINELENGTH];
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
str[0]=0;
|
||||||
|
fgets(str,sizeof(str),fp);
|
||||||
|
if (!str[0]) break;
|
||||||
|
|
||||||
|
char *p=str;
|
||||||
|
while (*p) p++;
|
||||||
|
if (p > str) p--;
|
||||||
|
while (p >= str && (*p == '\r' || *p == '\n')) p--;
|
||||||
|
*++p=0;
|
||||||
|
|
||||||
|
bool endSlash = (str[0] && str[strlen(str)-1] == '\\');
|
||||||
|
if (tmpstr.getlen() || endSlash) tmpstr.add(str,strlen(str));
|
||||||
|
|
||||||
|
if (!endSlash) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *thisline=str;
|
||||||
|
if (tmpstr.getlen())
|
||||||
|
{
|
||||||
|
tmpstr.add("\0",1);
|
||||||
|
thisline=(char *)tmpstr.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DefineList *tlist = searchParseString(thisline,&line,parmOffs,ignCase,true);
|
||||||
|
if (tlist && tlist->getnum())
|
||||||
|
{
|
||||||
|
if (!list || tlist->getnum() > list->getnum())
|
||||||
|
{
|
||||||
|
delete list;
|
||||||
|
list=tlist;
|
||||||
|
if (tlist->getnum() >= req_parm) break; // success!
|
||||||
|
}
|
||||||
|
else delete list;
|
||||||
|
}
|
||||||
|
// parse line
|
||||||
|
|
||||||
|
tmpstr.resize(0);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
if (!noErrors)
|
||||||
|
{
|
||||||
|
if (!list)
|
||||||
|
{
|
||||||
|
ERROR_MSG("!searchparse: starting string \"%s\" not found in file!\n",line.gettoken_str(parmOffs));
|
||||||
|
return PS_ERROR;
|
||||||
|
}
|
||||||
|
else if (list->getnum() < req_parm)
|
||||||
|
{
|
||||||
|
char *p=line.gettoken_str(parmOffs + list->getnum()*2);
|
||||||
|
ERROR_MSG("!searchparse: failed search at string \"%s\" not found in file!\n",p?p:"(null)");
|
||||||
|
return PS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list=searchParseString(source_string,&line,parmOffs,ignCase,noErrors);
|
||||||
|
if (!list && !noErrors) return PS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list) // if we got our list, merge them defines in
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0;i<list->getnum(); i ++)
|
||||||
|
{
|
||||||
|
char *def=list->getname(i);
|
||||||
|
char *val=list->getvalue(i);
|
||||||
|
if (def && val)
|
||||||
|
{
|
||||||
|
if (definedlist.find(def)) definedlist.del(def);
|
||||||
|
definedlist.add(def,val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete list;
|
||||||
|
}
|
||||||
|
return PS_OK;
|
||||||
|
|
||||||
case TOK_P_VERBOSE:
|
case TOK_P_VERBOSE:
|
||||||
{
|
{
|
||||||
|
@ -6184,3 +6335,70 @@ int CEXEBuild::do_add_file_create_dir(const string& local_dir, const string& dir
|
||||||
return PS_OK;
|
return PS_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DefineList *CEXEBuild::searchParseString(const char *source_string, LineParser *line, int parmOffs, bool ignCase, bool noErrors)
|
||||||
|
{
|
||||||
|
const char *tok = line->gettoken_str(parmOffs++);
|
||||||
|
if (tok && *tok)
|
||||||
|
{
|
||||||
|
int toklen = strlen(tok);
|
||||||
|
while (*source_string && (ignCase?strnicmp(source_string,tok,toklen):strncmp(source_string,tok,toklen))) source_string++;
|
||||||
|
|
||||||
|
if (!*source_string)
|
||||||
|
{
|
||||||
|
if (!noErrors) ERROR_MSG("!searchparse: starting string \"%s\" not found, aborted search!\n",tok);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (*source_string) source_string+=toklen;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineList *ret = NULL;
|
||||||
|
|
||||||
|
while (parmOffs < line->getnumtokens())
|
||||||
|
{
|
||||||
|
const char *defout = line->gettoken_str(parmOffs++);
|
||||||
|
if (parmOffs < line->getnumtokens()) tok=line->gettoken_str(parmOffs++);
|
||||||
|
else tok=NULL;
|
||||||
|
|
||||||
|
|
||||||
|
int maxlen=-1;
|
||||||
|
const char *src_start = source_string;
|
||||||
|
if (tok && *tok)
|
||||||
|
{
|
||||||
|
int toklen = strlen(tok);
|
||||||
|
while (*source_string && (ignCase?strnicmp(source_string,tok,toklen):strncmp(source_string,tok,toklen))) source_string++;
|
||||||
|
|
||||||
|
maxlen = source_string - src_start;
|
||||||
|
|
||||||
|
if (*source_string) source_string += toklen;
|
||||||
|
else if (!noErrors)
|
||||||
|
{
|
||||||
|
ERROR_MSG("!searchparse: string \"%s\" not found, aborted search!\n",tok);
|
||||||
|
delete ret;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defout && defout[0])
|
||||||
|
{
|
||||||
|
if (!ret) ret = new DefineList;
|
||||||
|
|
||||||
|
if (maxlen < 0) ret->add(defout,src_start);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *p=strdup(src_start);
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
p[maxlen]=0;
|
||||||
|
ret->add(defout,p);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -238,7 +238,7 @@ static tokenType tokenlist[TOK__LAST] =
|
||||||
{TOK_P_IFDEF,"!ifdef",1,-1,"symbol [| symbol2 [& symbol3 [...]]]",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_IFNDEF,"!ifndef",1,-1,"symbol [| symbol2 [& symbol3 [...]]]",TP_ALL},
|
||||||
{TOK_P_ENDIF,"!endif",0,0,"",TP_ALL},
|
{TOK_P_ENDIF,"!endif",0,0,"",TP_ALL},
|
||||||
{TOK_P_DEFINE,"!define",1,4,"([/date|/utcdate] symbol [value]) | (/math symbol val1 OP val2)\n OP=(+ - * / % & | ^)",TP_ALL},
|
{TOK_P_DEFINE,"!define",1,4,"([/date|/utcdate] symbol [value]) | (/file symbol filename) | (/math symbol val1 OP val2)\n OP=(+ - * / % & | ^)",TP_ALL},
|
||||||
{TOK_P_UNDEF,"!undef",1,1,"symbol [value]",TP_ALL},
|
{TOK_P_UNDEF,"!undef",1,1,"symbol [value]",TP_ALL},
|
||||||
{TOK_P_ELSE,"!else",0,-1,"[if[macro][n][def] ...]",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_ECHO,"!echo",1,0,"message",TP_ALL},
|
||||||
|
@ -256,6 +256,8 @@ static tokenType tokenlist[TOK__LAST] =
|
||||||
{TOK_P_TEMPFILE,"!tempfile",1,0,"symbol",TP_ALL},
|
{TOK_P_TEMPFILE,"!tempfile",1,0,"symbol",TP_ALL},
|
||||||
{TOK_P_DELFILE,"!delfile",1,0,"file",TP_ALL},
|
{TOK_P_DELFILE,"!delfile",1,0,"file",TP_ALL},
|
||||||
{TOK_P_APPENDFILE,"!appendfile",2,0,"file appended_line",TP_ALL},
|
{TOK_P_APPENDFILE,"!appendfile",2,0,"file appended_line",TP_ALL},
|
||||||
|
|
||||||
|
{TOK_P_SEARCHPARSESTRING,"!searchparse",3,-1,"[/ignorecase] [/noerrors] [/file] source_string substring OUTPUTSYM1 [substring [OUTPUTSYM2 [substring ...]]]",TP_ALL},
|
||||||
|
|
||||||
{TOK_MISCBUTTONTEXT,"MiscButtonText",0,4,"[back button text] [next button text] [cancel button text] [close button text]",TP_GLOBAL},
|
{TOK_MISCBUTTONTEXT,"MiscButtonText",0,4,"[back button text] [next button text] [cancel button text] [close button text]",TP_GLOBAL},
|
||||||
{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,1,"[details button text]",TP_PG},
|
{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,1,"[details button text]",TP_PG},
|
||||||
|
|
|
@ -116,6 +116,8 @@ enum
|
||||||
TOK_P_TEMPFILE,
|
TOK_P_TEMPFILE,
|
||||||
TOK_P_DELFILE,
|
TOK_P_DELFILE,
|
||||||
TOK_P_APPENDFILE,
|
TOK_P_APPENDFILE,
|
||||||
|
|
||||||
|
TOK_P_SEARCHPARSESTRING,
|
||||||
|
|
||||||
// section/function shit
|
// section/function shit
|
||||||
TOK_SECTION,
|
TOK_SECTION,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue