2013-11-14 20:55:18 +00:00
|
|
|
#include "simplescript.h"
|
2014-02-09 12:47:47 +00:00
|
|
|
#include "value.h"
|
2013-11-14 20:55:18 +00:00
|
|
|
#include "console.h"
|
2014-02-09 20:44:05 +00:00
|
|
|
#include "argument.h"
|
2014-02-10 20:32:17 +00:00
|
|
|
#include "variable.h"
|
2013-11-14 20:55:18 +00:00
|
|
|
|
2014-02-09 20:44:05 +00:00
|
|
|
static std::vector<LINEMAPENTRY> linemap;
|
|
|
|
static std::vector<SCRIPTBP> scriptbplist;
|
|
|
|
static int scriptIp=0;
|
|
|
|
static bool bAbort=false;
|
|
|
|
static bool bIsRunning=false;
|
2014-02-09 14:30:30 +00:00
|
|
|
|
2014-02-09 21:02:28 +00:00
|
|
|
static SCRIPTBRANCHTYPE scriptgetbranchtype(const char* text)
|
2014-02-09 14:30:30 +00:00
|
|
|
{
|
2014-02-10 21:05:23 +00:00
|
|
|
char newtext[MAX_SCRIPT_LINE_SIZE]="";
|
|
|
|
strcpy(newtext, text);
|
|
|
|
argformat(newtext); //format jump commands
|
|
|
|
if(!strncmp(newtext, "jmp", 3) or !strncmp(newtext, "goto", 4))
|
2014-02-09 20:44:05 +00:00
|
|
|
return scriptjmp;
|
2014-02-10 21:05:23 +00:00
|
|
|
else if(!strncmp(newtext, "jne", 3) or !strncmp(newtext, "ifne", 4) or !strncmp(newtext, "ifneq", 5) or !strncmp(newtext, "jnz", 3) or !strncmp(newtext, "ifnz", 4))
|
2014-02-09 20:44:05 +00:00
|
|
|
return scriptjnejnz;
|
2014-02-10 21:05:23 +00:00
|
|
|
else if(!strncmp(newtext, "je", 2) or !strncmp(newtext, "ife", 3) or !strncmp(newtext, "ifeq", 4) or !strncmp(newtext, "jz", 2) or !strncmp(newtext, "ifz", 3))
|
2014-02-10 20:40:06 +00:00
|
|
|
return scriptjejz;
|
2014-02-10 21:05:23 +00:00
|
|
|
else if(!strncmp(newtext, "jb", 2) or !strncmp(newtext, "ifb", 3) or !strncmp(newtext, "jl", 2) or !strncmp(newtext, "ifl", 3))
|
2014-02-10 20:40:06 +00:00
|
|
|
return scriptjbjl;
|
2014-02-10 21:05:23 +00:00
|
|
|
else if(!strncmp(newtext, "ja", 2) or !strncmp(newtext, "ifa", 3) or !strncmp(newtext, "jg", 2) or !strncmp(newtext, "ifg", 3))
|
2014-02-10 20:40:06 +00:00
|
|
|
return scriptjajg;
|
2014-02-10 21:05:23 +00:00
|
|
|
else if(!strncmp(newtext, "jbe", 3) or !strncmp(newtext, "ifbe", 4) or !strncmp(newtext, "ifbeq", 5) or !strncmp(newtext, "jle", 3) or !strncmp(newtext, "ifle", 4) or !strncmp(newtext, "ifleq", 5))
|
2014-02-10 20:40:06 +00:00
|
|
|
return scriptjbejle;
|
2014-02-10 21:05:23 +00:00
|
|
|
else if(!strncmp(newtext, "jae", 3) or !strncmp(newtext, "ifae", 4) or !strncmp(newtext, "ifaeq", 5) or !strncmp(newtext, "jge", 3) or !strncmp(newtext, "ifge", 4) or !strncmp(newtext, "ifgeq", 5))
|
2014-02-10 20:40:06 +00:00
|
|
|
return scriptjaejge;
|
2014-02-09 20:44:05 +00:00
|
|
|
return scriptnobranch;
|
2014-02-09 14:30:30 +00:00
|
|
|
}
|
|
|
|
|
2014-02-09 21:02:28 +00:00
|
|
|
static int scriptlabelfind(const char* labelname)
|
|
|
|
{
|
|
|
|
int linecount=linemap.size();
|
|
|
|
for(int i=0; i<linecount; i++)
|
|
|
|
if(linemap.at(i).type==linelabel && !strcmp(linemap.at(i).u.label, labelname))
|
|
|
|
return i+1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool scriptcreatelinemap(const char* filename)
|
2014-02-09 14:30:30 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
HANDLE hFile=CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
|
|
|
if(hFile==INVALID_HANDLE_VALUE)
|
2014-02-10 20:01:20 +00:00
|
|
|
{
|
|
|
|
GuiScriptError(0, "CreateFile failed...");
|
2014-02-09 20:44:05 +00:00
|
|
|
return false;
|
2014-02-10 20:01:20 +00:00
|
|
|
}
|
2014-02-09 20:44:05 +00:00
|
|
|
unsigned int filesize=GetFileSize(hFile, 0);
|
|
|
|
char* filedata=(char*)emalloc(filesize+1, "createlinemap:filedata");
|
|
|
|
memset(filedata, 0, filesize+1);
|
|
|
|
DWORD read=0;
|
|
|
|
if(!ReadFile(hFile, filedata, filesize, &read, 0))
|
|
|
|
{
|
|
|
|
CloseHandle(hFile);
|
|
|
|
GuiScriptError(0, "ReadFile failed...");
|
|
|
|
efree(filedata, "createlinemap:filedata");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
CloseHandle(hFile);
|
|
|
|
int len=strlen(filedata);
|
|
|
|
char temp[256]="";
|
|
|
|
LINEMAPENTRY entry;
|
|
|
|
memset(&entry, 0, sizeof(entry));
|
|
|
|
linemap.clear();
|
|
|
|
for(int i=0,j=0; i<len; i++) //make raw line map
|
|
|
|
{
|
|
|
|
if(filedata[i]=='\r' and filedata[i+1]=='\n') //windows file
|
|
|
|
{
|
|
|
|
memset(&entry, 0, sizeof(entry));
|
|
|
|
strcpy(entry.raw, temp);
|
|
|
|
*temp=0;
|
|
|
|
j=0;
|
|
|
|
i++;
|
|
|
|
linemap.push_back(entry);
|
|
|
|
}
|
|
|
|
else if(filedata[i]=='\n') //other file
|
|
|
|
{
|
|
|
|
memset(&entry, 0, sizeof(entry));
|
|
|
|
strcpy(entry.raw, temp);
|
|
|
|
*temp=0;
|
|
|
|
j=0;
|
|
|
|
linemap.push_back(entry);
|
|
|
|
}
|
|
|
|
else if(j>=254)
|
|
|
|
{
|
|
|
|
memset(&entry, 0, sizeof(entry));
|
|
|
|
strcpy(entry.raw, temp);
|
|
|
|
*temp=0;
|
|
|
|
j=0;
|
|
|
|
linemap.push_back(entry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
j+=sprintf(temp+j, "%c", filedata[i]);
|
|
|
|
}
|
|
|
|
if(*temp)
|
|
|
|
{
|
|
|
|
memset(&entry, 0, sizeof(entry));
|
|
|
|
strcpy(entry.raw, temp);
|
|
|
|
linemap.push_back(entry);
|
|
|
|
}
|
|
|
|
efree(filedata, "createlinemap:filedata");
|
|
|
|
unsigned int linemapsize=linemap.size();
|
|
|
|
while(!*linemap.at(linemapsize-1).raw) //remove empty lines
|
|
|
|
{
|
|
|
|
linemapsize--;
|
|
|
|
linemap.pop_back();
|
|
|
|
}
|
|
|
|
for(unsigned int i=0; i<linemapsize; i++)
|
|
|
|
{
|
|
|
|
LINEMAPENTRY cur=linemap.at(i);
|
|
|
|
int rawlen=strlen(cur.raw);
|
|
|
|
if(!strlen(cur.raw)) //empty
|
|
|
|
{
|
|
|
|
cur.type=lineempty;
|
|
|
|
}
|
|
|
|
else if(!strncmp(cur.raw, "//", 2)) //comment
|
|
|
|
{
|
|
|
|
cur.type=linecomment;
|
|
|
|
strcpy(cur.u.comment, cur.raw);
|
|
|
|
}
|
2014-02-10 21:05:23 +00:00
|
|
|
else if(cur.raw[rawlen-1]==':') //label
|
2014-02-09 20:44:05 +00:00
|
|
|
{
|
|
|
|
cur.type=linelabel;
|
2014-02-10 21:05:23 +00:00
|
|
|
sprintf(cur.u.label, "l %.*s", rawlen-1, cur.raw); //create a fake command for formatting
|
|
|
|
argformat(cur.u.label); //format labels
|
|
|
|
strcpy(cur.u.label, cur.u.label+2); //remove fake command
|
2014-02-09 21:02:28 +00:00
|
|
|
int foundlabel=scriptlabelfind(cur.u.label);
|
|
|
|
if(foundlabel) //label defined twice
|
|
|
|
{
|
|
|
|
char message[256]="";
|
|
|
|
sprintf(message, "Duplicate label \"%s\" detected on lines %d and %d!", cur.u.label, foundlabel, i+1);
|
|
|
|
GuiScriptError(0, message);
|
|
|
|
linemap.clear();
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-09 20:44:05 +00:00
|
|
|
}
|
2014-02-09 21:02:28 +00:00
|
|
|
else if(scriptgetbranchtype(cur.raw)!=scriptnobranch) //branch
|
2014-02-09 20:44:05 +00:00
|
|
|
{
|
|
|
|
cur.type=linebranch;
|
2014-02-09 21:02:28 +00:00
|
|
|
cur.u.branch.type=scriptgetbranchtype(cur.raw);
|
2014-02-10 21:05:23 +00:00
|
|
|
char newraw[MAX_SCRIPT_LINE_SIZE]="";
|
|
|
|
strcpy(newraw, cur.raw);
|
|
|
|
argformat(newraw);
|
|
|
|
int len=strlen(newraw);
|
2014-02-09 20:44:05 +00:00
|
|
|
for(int i=0; i<len; i++)
|
2014-02-10 21:05:23 +00:00
|
|
|
if(newraw[i]==' ')
|
2014-02-09 20:44:05 +00:00
|
|
|
{
|
2014-02-10 21:05:23 +00:00
|
|
|
strcpy(cur.u.branch.branchlabel, newraw+i+1);
|
2014-02-09 20:44:05 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cur.type=linecommand;
|
|
|
|
strcpy(cur.u.command, cur.raw);
|
|
|
|
}
|
|
|
|
linemap.at(i)=cur;
|
|
|
|
}
|
|
|
|
linemapsize=linemap.size();
|
2014-02-09 21:02:28 +00:00
|
|
|
for(unsigned int i=0; i<linemapsize; i++)
|
|
|
|
{
|
|
|
|
LINEMAPENTRY cur=linemap.at(i);
|
|
|
|
if(cur.type==linebranch and !scriptlabelfind(cur.u.branch.branchlabel)) //invalid branch label
|
|
|
|
{
|
|
|
|
char message[256]="";
|
|
|
|
sprintf(message, "Invalid branch label \"%s\" detected on line %d!", cur.u.branch.branchlabel, i+1);
|
|
|
|
GuiScriptError(0, message);
|
|
|
|
linemap.clear();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2014-02-09 20:44:05 +00:00
|
|
|
if(linemap.at(linemapsize-1).type==linecomment or linemap.at(linemapsize-1).type==linelabel) //label/comment on the end
|
|
|
|
{
|
|
|
|
memset(&entry, 0, sizeof(entry));
|
|
|
|
entry.type=linecommand;
|
|
|
|
strcpy(entry.raw, "ret");
|
|
|
|
strcpy(entry.u.command, "ret");
|
|
|
|
linemap.push_back(entry);
|
|
|
|
}
|
|
|
|
return true;
|
2014-02-09 14:30:30 +00:00
|
|
|
}
|
|
|
|
|
2014-02-09 20:44:05 +00:00
|
|
|
static int scriptinternalstep(int fromIp) //internal step routine
|
2014-02-09 14:30:30 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
int maxIp=linemap.size(); //maximum ip
|
2014-02-09 21:23:22 +00:00
|
|
|
if(fromIp>=maxIp) //script end
|
2014-02-09 20:44:05 +00:00
|
|
|
return fromIp;
|
|
|
|
while((linemap.at(fromIp).type==lineempty or linemap.at(fromIp).type==linecomment or linemap.at(fromIp).type==linelabel) and fromIp<maxIp) //skip empty lines
|
|
|
|
fromIp++;
|
|
|
|
fromIp++;
|
|
|
|
return fromIp;
|
2014-02-09 14:30:30 +00:00
|
|
|
}
|
|
|
|
|
2014-02-09 20:44:05 +00:00
|
|
|
static bool scriptinternalbpget(int line) //internal bpget routine
|
2014-02-09 14:30:30 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
int bpcount=scriptbplist.size();
|
|
|
|
for(int i=0; i<bpcount; i++)
|
|
|
|
if(scriptbplist.at(i).line==line)
|
|
|
|
return true;
|
2014-02-09 14:30:30 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-02-09 20:44:05 +00:00
|
|
|
static bool scriptinternalbptoggle(int line) //internal breakpoint
|
2014-02-09 14:30:30 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
if(!line or line>(int)linemap.size()) //invalid line
|
|
|
|
return false;
|
|
|
|
line=scriptinternalstep(line-1); //no breakpoints on non-executable locations
|
|
|
|
if(scriptinternalbpget(line)) //remove breakpoint
|
|
|
|
{
|
|
|
|
int bpcount=scriptbplist.size();
|
|
|
|
for(int i=0; i<bpcount; i++)
|
|
|
|
if(scriptbplist.at(i).line==line)
|
|
|
|
{
|
|
|
|
scriptbplist.erase(scriptbplist.begin()+i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else //add breakpoint
|
|
|
|
{
|
|
|
|
SCRIPTBP newbp;
|
|
|
|
newbp.silent=true;
|
|
|
|
newbp.line=line;
|
|
|
|
scriptbplist.push_back(newbp);
|
|
|
|
}
|
2014-02-09 14:30:30 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-02-09 20:44:05 +00:00
|
|
|
static CMDRESULT scriptinternalcmdexec(const char* command)
|
2014-02-09 14:30:30 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
dprintf("scriptinternalcmdexec(%s)\n", command);
|
|
|
|
if(!strcmp(command, "ret"))
|
|
|
|
{
|
|
|
|
GuiScriptMessage("Script finished!");
|
|
|
|
return STATUS_EXIT;
|
|
|
|
}
|
|
|
|
else if(!strcmp(command, "invalid"))
|
|
|
|
return STATUS_ERROR;
|
|
|
|
return STATUS_CONTINUE;
|
2014-02-09 14:30:30 +00:00
|
|
|
}
|
|
|
|
|
2014-02-10 20:32:17 +00:00
|
|
|
static bool scriptinternalbranch(SCRIPTBRANCHTYPE type) //determine if we should jump
|
|
|
|
{
|
|
|
|
uint ezflag=0;
|
|
|
|
uint bsflag=0;
|
|
|
|
varget("$_EZ_FLAG", &ezflag, 0, 0);
|
|
|
|
varget("$_BS_FLAG", &bsflag, 0, 0);
|
|
|
|
bool bJump=false;
|
|
|
|
switch(type)
|
|
|
|
{
|
|
|
|
case scriptjmp:
|
|
|
|
bJump=true;
|
|
|
|
break;
|
|
|
|
case scriptjnejnz: //$_EZ_FLAG=0
|
|
|
|
if(!ezflag)
|
|
|
|
bJump=true;
|
|
|
|
break;
|
|
|
|
case scriptjejz: //$_EZ_FLAG=1
|
|
|
|
if(ezflag)
|
|
|
|
bJump=true;
|
|
|
|
break;
|
|
|
|
case scriptjbjl: //$_BS_FLAG=0 and $_EZ_FLAG=0 //below, not equal
|
|
|
|
if(!bsflag and !ezflag)
|
|
|
|
bJump=true;
|
|
|
|
break;
|
|
|
|
case scriptjajg: //$_BS_FLAG=1 and $_EZ_FLAG=0 //above, not equal
|
|
|
|
if(bsflag and !ezflag)
|
|
|
|
bJump=true;
|
|
|
|
break;
|
|
|
|
case scriptjbejle: //$_BS_FLAG=0 or $_EZ_FLAG=1
|
|
|
|
if(!bsflag or ezflag)
|
|
|
|
bJump=true;
|
|
|
|
break;
|
|
|
|
case scriptjaejge: //$_BS_FLAG=1 or $_EZ_FLAG=1
|
|
|
|
if(bsflag or ezflag)
|
|
|
|
bJump=true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
bJump=false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return bJump;
|
|
|
|
}
|
|
|
|
|
2014-02-10 20:01:20 +00:00
|
|
|
static bool scriptinternalcmd()
|
|
|
|
{
|
|
|
|
bool bContinue=true;
|
|
|
|
LINEMAPENTRY cur=linemap.at(scriptIp-1);
|
|
|
|
if(cur.type==linecommand)
|
|
|
|
{
|
|
|
|
switch(scriptinternalcmdexec(cur.u.command))
|
|
|
|
{
|
|
|
|
case STATUS_CONTINUE:
|
|
|
|
break;
|
|
|
|
case STATUS_ERROR:
|
|
|
|
bContinue=false;
|
|
|
|
GuiScriptError(scriptIp, "Error executing command!");
|
|
|
|
break;
|
|
|
|
case STATUS_EXIT:
|
|
|
|
bContinue=false;
|
|
|
|
scriptIp=scriptinternalstep(0);
|
|
|
|
GuiScriptSetIp(scriptIp);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-02-10 20:32:17 +00:00
|
|
|
else if(cur.type==linebranch and scriptinternalbranch(cur.u.branch.type)) //branch
|
|
|
|
scriptIp=scriptlabelfind(cur.u.branch.branchlabel);
|
2014-02-10 20:01:20 +00:00
|
|
|
return bContinue;
|
|
|
|
}
|
|
|
|
|
2014-02-09 21:02:28 +00:00
|
|
|
static DWORD WINAPI scriptRunThread(void* arg)
|
2013-11-14 20:55:18 +00:00
|
|
|
{
|
2014-02-10 20:32:17 +00:00
|
|
|
int destline=(int)(uint)arg;
|
2014-02-09 20:44:05 +00:00
|
|
|
if(!destline or destline>(int)linemap.size()) //invalid line
|
|
|
|
destline=0;
|
|
|
|
if(destline)
|
2014-02-09 12:34:48 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
destline=scriptinternalstep(destline-1); //no breakpoints on non-executable locations
|
|
|
|
if(!scriptinternalbpget(destline)) //no breakpoint set
|
|
|
|
scriptinternalbptoggle(destline);
|
2014-02-09 12:34:48 +00:00
|
|
|
}
|
2014-02-09 20:44:05 +00:00
|
|
|
bAbort=false;
|
|
|
|
if(scriptIp)
|
|
|
|
scriptIp--;
|
|
|
|
scriptIp=scriptinternalstep(scriptIp);
|
|
|
|
bool bContinue=true;
|
|
|
|
while(bContinue && !bAbort) //run loop
|
|
|
|
{
|
2014-02-10 20:01:20 +00:00
|
|
|
bContinue=scriptinternalcmd();
|
2014-02-09 20:44:05 +00:00
|
|
|
if(scriptIp==scriptinternalstep(scriptIp)) //end of script
|
|
|
|
{
|
|
|
|
bContinue=false;
|
|
|
|
scriptIp=scriptinternalstep(0);
|
|
|
|
}
|
|
|
|
if(bContinue)
|
|
|
|
scriptIp=scriptinternalstep(scriptIp); //this is the next ip
|
|
|
|
if(scriptinternalbpget(scriptIp)) //breakpoint=stop run loop
|
|
|
|
bContinue=false;
|
|
|
|
Sleep(1); //don't fry the processor
|
|
|
|
}
|
|
|
|
bIsRunning=false; //not running anymore
|
|
|
|
GuiScriptSetIp(scriptIp);
|
|
|
|
return 0;
|
2013-11-14 20:55:18 +00:00
|
|
|
}
|
|
|
|
|
2014-02-09 20:44:05 +00:00
|
|
|
void scriptload(const char* filename)
|
2013-11-14 20:55:18 +00:00
|
|
|
{
|
2014-02-09 12:34:48 +00:00
|
|
|
GuiScriptClear();
|
2014-02-09 20:44:05 +00:00
|
|
|
scriptIp=0;
|
|
|
|
scriptbplist.clear(); //clear breakpoints
|
|
|
|
bAbort=false;
|
2014-02-09 21:02:28 +00:00
|
|
|
if(!scriptcreatelinemap(filename))
|
2014-02-09 20:44:05 +00:00
|
|
|
return;
|
|
|
|
for(unsigned int i=0; i<linemap.size(); i++) //add script lines
|
|
|
|
GuiScriptAddLine(linemap.at(i).raw);
|
|
|
|
scriptIp=scriptinternalstep(0);
|
|
|
|
GuiScriptSetIp(scriptIp);
|
2013-11-14 20:55:18 +00:00
|
|
|
}
|
2014-02-09 12:47:47 +00:00
|
|
|
|
2014-02-09 20:44:05 +00:00
|
|
|
void scriptunload()
|
2014-02-09 12:47:47 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
GuiScriptClear();
|
|
|
|
scriptIp=0;
|
|
|
|
scriptbplist.clear(); //clear breakpoints
|
|
|
|
bAbort=false;
|
2014-02-09 12:47:47 +00:00
|
|
|
}
|
|
|
|
|
2014-02-09 20:44:05 +00:00
|
|
|
void scriptrun(int destline)
|
2014-02-09 12:47:47 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
if(bIsRunning) //already running
|
|
|
|
return;
|
|
|
|
bIsRunning=true;
|
2014-02-10 20:32:17 +00:00
|
|
|
CreateThread(0, 0, scriptRunThread, (void*)(uint)destline, 0, 0);
|
2014-02-09 12:47:47 +00:00
|
|
|
}
|
|
|
|
|
2014-02-09 20:44:05 +00:00
|
|
|
void scriptstep()
|
2014-02-09 12:47:47 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
if(bIsRunning) //already running
|
|
|
|
return;
|
|
|
|
scriptIp=scriptinternalstep(scriptIp-1); //probably useless
|
2014-02-10 20:01:20 +00:00
|
|
|
if(!scriptinternalcmd())
|
2014-02-09 20:44:05 +00:00
|
|
|
return;
|
|
|
|
if(scriptIp==scriptinternalstep(scriptIp)) //end of script
|
|
|
|
scriptIp=0;
|
|
|
|
scriptIp=scriptinternalstep(scriptIp);
|
|
|
|
GuiScriptSetIp(scriptIp);
|
2014-02-09 12:47:47 +00:00
|
|
|
}
|
|
|
|
|
2014-02-09 20:44:05 +00:00
|
|
|
bool scriptbptoggle(int line)
|
2014-02-09 12:47:47 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
if(!line or line>(int)linemap.size()) //invalid line
|
|
|
|
return false;
|
|
|
|
line=scriptinternalstep(line-1); //no breakpoints on non-executable locations
|
|
|
|
if(scriptbpget(line)) //remove breakpoint
|
2014-02-09 12:47:47 +00:00
|
|
|
{
|
2014-02-09 20:44:05 +00:00
|
|
|
int bpcount=scriptbplist.size();
|
|
|
|
for(int i=0; i<bpcount; i++)
|
|
|
|
if(scriptbplist.at(i).line==line && !scriptbplist.at(i).silent)
|
|
|
|
{
|
|
|
|
scriptbplist.erase(scriptbplist.begin()+i);
|
|
|
|
break;
|
|
|
|
}
|
2014-02-09 12:47:47 +00:00
|
|
|
}
|
2014-02-09 20:44:05 +00:00
|
|
|
else //add breakpoint
|
|
|
|
{
|
|
|
|
SCRIPTBP newbp;
|
|
|
|
newbp.silent=false;
|
|
|
|
newbp.line=line;
|
|
|
|
scriptbplist.push_back(newbp);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool scriptbpget(int line)
|
|
|
|
{
|
|
|
|
int bpcount=scriptbplist.size();
|
|
|
|
for(int i=0; i<bpcount; i++)
|
|
|
|
if(scriptbplist.at(i).line==line && !scriptbplist.at(i).silent)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool scriptcmdexec(const char* command)
|
|
|
|
{
|
2014-02-09 21:23:22 +00:00
|
|
|
switch(scriptinternalcmdexec(command))
|
|
|
|
{
|
|
|
|
case STATUS_ERROR:
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
case STATUS_EXIT:
|
|
|
|
scriptIp=scriptinternalstep(0);
|
|
|
|
GuiScriptSetIp(scriptIp);
|
2014-02-09 20:44:05 +00:00
|
|
|
return true;
|
2014-02-09 21:23:22 +00:00
|
|
|
break;
|
|
|
|
case STATUS_CONTINUE:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return true;
|
2014-02-09 20:44:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void scriptabort()
|
|
|
|
{
|
|
|
|
if(bIsRunning)
|
|
|
|
bAbort=true;
|
|
|
|
}
|
|
|
|
|
|
|
|
SCRIPTLINETYPE scriptgetlinetype(int line)
|
|
|
|
{
|
|
|
|
if(line>(int)linemap.size())
|
|
|
|
return lineempty;
|
|
|
|
return linemap.at(line-1).type;
|
2014-02-09 12:47:47 +00:00
|
|
|
}
|
2014-02-09 21:23:22 +00:00
|
|
|
|
|
|
|
void scriptsetip(int line)
|
|
|
|
{
|
|
|
|
if(line)
|
|
|
|
line--;
|
|
|
|
scriptIp=scriptinternalstep(line);
|
|
|
|
GuiScriptSetIp(scriptIp);
|
|
|
|
}
|