Example #1
0
static DWORD WINAPI scriptRunThread(void* arg)
{
    int destline = (int)(uint)arg;
    if(!destline || destline > (int)linemap.size()) //invalid line
        destline = 0;
    if(destline)
    {
        destline = scriptinternalstep(destline - 1); //no breakpoints on non-executable locations
        if(!scriptinternalbpget(destline)) //no breakpoint set
            scriptinternalbptoggle(destline);
    }
    bAbort = false;
    if(scriptIp)
        scriptIp--;
    scriptIp = scriptinternalstep(scriptIp);
    bool bContinue = true;
    while(bContinue && !bAbort) //run loop
    {
        bContinue = scriptinternalcmd();
        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;
}
Example #2
0
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;
        case STATUS_PAUSE:
            bContinue = false; //stop running the script
            scriptIp = scriptinternalstep(scriptIp);
            GuiScriptSetIp(scriptIp);
            break;
        }
    }
    else if(cur.type == linebranch)
    {
        if(cur.u.branch.type == scriptcall) //calls have a special meaning
            scriptstack.push_back(scriptIp);
        if(scriptinternalbranch(cur.u.branch.type))
            scriptIp = scriptlabelfind(cur.u.branch.branchlabel);
    }
    return bContinue;
}
Example #3
0
DWORD WINAPI scriptStepThread(void* param)
{
    if(bIsRunning) //already running
        return 0;
    scriptIp = scriptinternalstep(scriptIp - 1); //probably useless
    if(!scriptinternalcmd())
        return 0;
    if(scriptIp == scriptinternalstep(scriptIp)) //end of script
        scriptIp = 0;
    scriptIp = scriptinternalstep(scriptIp);
    GuiScriptSetIp(scriptIp);
    return 0;
}
Example #4
0
DWORD WINAPI scriptRunSync(void* arg)
{
    int destline = (int)(duint)arg;
    if(!destline || destline > (int)linemap.size()) //invalid line
        destline = 0;
    if(destline)
    {
        destline = scriptinternalstep(destline - 1); //no breakpoints on non-executable locations
        if(!scriptinternalbpget(destline)) //no breakpoint set
            scriptinternalbptoggle(destline);
    }
    bAbort = false;
    if(scriptIp)
        scriptIp--;
    scriptIp = scriptinternalstep(scriptIp);
    bool bContinue = true;
    bool bIgnoreTimeout = settingboolget("Engine", "NoScriptTimeout");
    unsigned long long kernelTime, userTime;
    FILETIME creationTime, exitTime; // unused
    while(bContinue && !bAbort) //run loop
    {
        bContinue = scriptinternalcmd();
        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;
        if(bContinue && !bIgnoreTimeout && GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, reinterpret_cast<LPFILETIME>(&kernelTime), reinterpret_cast<LPFILETIME>(&userTime)) != 0)
        {
            if(userTime + kernelTime >= 10 * 10000000) // time out in 10 seconds of CPU time
            {
                if(GuiScriptMsgyn(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "The script is too busy. Would you like to terminate it now?"))) != 0)
                {
                    dputs(QT_TRANSLATE_NOOP("DBG", "Script is terminated by user."));
                    break;
                }
                else
                    bIgnoreTimeout = true;
            }
        }
    }
    bIsRunning = false; //not running anymore
    GuiScriptSetIp(scriptIp);
    return 0;
}
Example #5
0
void scriptsetip(int line)
{
    if(line)
        line--;
    scriptIp = scriptinternalstep(line);
    GuiScriptSetIp(scriptIp);
}
Example #6
0
bool scriptcmdexec(const char* command)
{
    switch(scriptinternalcmdexec(command))
    {
    case STATUS_ERROR:
        return false;
    case STATUS_EXIT:
        scriptIp = scriptinternalstep(0);
        GuiScriptSetIp(scriptIp);
        break;
    case STATUS_PAUSE:
    case STATUS_CONTINUE:
        break;
    }
    return true;
}
Example #7
0
static DWORD WINAPI scriptLoadThread(void* filename)
{
    GuiScriptClear();
    GuiScriptEnableHighlighting(true); //enable default script syntax highlighting
    scriptIp = 0;
    std::vector<SCRIPTBP>().swap(scriptbplist); //clear breakpoints
    std::vector<int>().swap(scriptstack); //clear script stack
    bAbort = false;
    if(!scriptcreatelinemap((const char*)filename))
        return 0;
    int lines = (int)linemap.size();
    const char** script = (const char**)BridgeAlloc(lines * sizeof(const char*));
    for(int i = 0; i < lines; i++) //add script lines
        script[i] = linemap.at(i).raw;
    GuiScriptAdd(lines, script);
    scriptIp = scriptinternalstep(0);
    GuiScriptSetIp(scriptIp);
    return 0;
}
Example #8
0
bool scriptbptoggle(int line)
{
    if(!line || line > (int)linemap.size()) //invalid line
        return false;
    line = scriptinternalstep(line - 1); //no breakpoints on non-executable locations
    if(scriptbpget(line)) //remove breakpoint
    {
        int bpcount = (int)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;
            }
    }
    else //add breakpoint
    {
        SCRIPTBP newbp;
        newbp.silent = false;
        newbp.line = line;
        scriptbplist.push_back(newbp);
    }
    return true;
}
Example #9
0
static bool scriptcreatelinemap(const char* filename)
{
    Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(filename).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    if(hFile == INVALID_HANDLE_VALUE)
    {
        GuiScriptError(0, "CreateFile failed...");
        return false;
    }
    unsigned int filesize = GetFileSize(hFile, 0);
    if(!filesize)
    {
        GuiScriptError(0, "Empty script...");
        return false;
    }
    Memory<char*> filedata(filesize + 1, "createlinemap:filedata");
    DWORD read = 0;
    if(!ReadFile(hFile, filedata(), filesize, &read, 0))
    {
        GuiScriptError(0, "ReadFile failed...");
        return false;
    }
    hFile.Close();
    int len = (int)strlen(filedata());
    char temp[256] = "";
    LINEMAPENTRY entry;
    memset(&entry, 0, sizeof(entry));
    std::vector<LINEMAPENTRY>().swap(linemap);
    for(int i = 0, j = 0; i < len; i++) //make raw line map
    {
        if(filedata()[i] == '\r' && filedata()[i + 1] == '\n') //windows file
        {
            memset(&entry, 0, sizeof(entry));
            int add = 0;
            while(temp[add] == ' ')
                add++;
            strcpy_s(entry.raw, temp + add);
            *temp = 0;
            j = 0;
            i++;
            linemap.push_back(entry);
        }
        else if(filedata()[i] == '\n') //other file
        {
            memset(&entry, 0, sizeof(entry));
            int add = 0;
            while(temp[add] == ' ')
                add++;
            strcpy_s(entry.raw, temp + add);
            *temp = 0;
            j = 0;
            linemap.push_back(entry);
        }
        else if(j >= 254)
        {
            memset(&entry, 0, sizeof(entry));
            int add = 0;
            while(temp[add] == ' ')
                add++;
            strcpy_s(entry.raw, temp + add);
            *temp = 0;
            j = 0;
            linemap.push_back(entry);
        }
        else
            j += sprintf(temp + j, "%c", filedata()[i]);
    }
    if(*temp)
    {
        memset(&entry, 0, sizeof(entry));
        strcpy_s(entry.raw, temp);
        linemap.push_back(entry);
    }
    int linemapsize = (int)linemap.size();
    while(!*linemap.at(linemapsize - 1).raw) //remove empty lines from the end
    {
        linemapsize--;
        linemap.pop_back();
    }
    for(int i = 0; i < linemapsize; i++)
    {
        LINEMAPENTRY cur = linemap.at(i);

        //temp. remove comments from the raw line
        char line_comment[256] = "";
        char* comment = strstr(&cur.raw[0], "//");
        if(comment && comment != cur.raw) //only when the line doesnt start with a comment
        {
            if(*(comment - 1) == ' ') //space before comment
            {
                strcpy_s(line_comment, comment);
                *(comment - 1) = '\0';
            }
            else //no space before comment
            {
                strcpy_s(line_comment, comment);
                *comment = 0;
            }
        }

        int rawlen = (int)strlen(cur.raw);
        if(!rawlen) //empty
        {
            cur.type = lineempty;
        }
        else if(!strncmp(cur.raw, "//", 2)) //comment
        {
            cur.type = linecomment;
            strcpy_s(cur.u.comment, cur.raw);
        }
        else if(cur.raw[rawlen - 1] == ':') //label
        {
            cur.type = linelabel;
            sprintf(cur.u.label, "l %.*s", rawlen - 1, cur.raw); //create a fake command for formatting
            strcpy_s(cur.u.label, StringUtils::Trim(cur.u.label).c_str());
            char temp[256] = "";
            strcpy_s(temp, cur.u.label + 2);
            strcpy_s(cur.u.label, temp); //remove fake command
            if(!*cur.u.label || !strcmp(cur.u.label, "\"\"")) //no label text
            {
                char message[256] = "";
                sprintf(message, "Empty label detected on line %d!", i + 1);
                GuiScriptError(0, message);
                std::vector<LINEMAPENTRY>().swap(linemap);
                return false;
            }
            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);
                std::vector<LINEMAPENTRY>().swap(linemap);
                return false;
            }
        }
        else if(scriptgetbranchtype(cur.raw) != scriptnobranch) //branch
        {
            cur.type = linebranch;
            cur.u.branch.type = scriptgetbranchtype(cur.raw);
            char newraw[MAX_SCRIPT_LINE_SIZE] = "";
            strcpy_s(newraw, StringUtils::Trim(cur.raw).c_str());
            int len = (int)strlen(newraw);
            for(int i = 0; i < len; i++)
                if(newraw[i] == ' ')
                {
                    strcpy_s(cur.u.branch.branchlabel, newraw + i + 1);
                    break;
                }
        }
        else
        {
            cur.type = linecommand;
            strcpy_s(cur.u.command, cur.raw);
        }

        //append the comment to the raw line again
        if(*line_comment)
            sprintf(cur.raw + rawlen, " %s", line_comment);
        linemap.at(i) = cur;
    }
    linemapsize = (int)linemap.size();
    for(int i = 0; i < linemapsize; i++)
    {
        auto & currentLine = linemap.at(i);
        if(currentLine.type == linebranch)  //invalid branch label
        {
            int labelline = scriptlabelfind(currentLine.u.branch.branchlabel);
            if(!labelline) //invalid branch label
            {
                char message[256] = "";
                sprintf(message, "Invalid branch label \"%s\" detected on line %d!", currentLine.u.branch.branchlabel, i + 1);
                GuiScriptError(0, message);
                std::vector<LINEMAPENTRY>().swap(linemap);
                return false;
            }
            else //set the branch destination line
                currentLine.u.branch.dest = scriptinternalstep(labelline);
        }
    }
    if(linemap.at(linemapsize - 1).type == linecomment || linemap.at(linemapsize - 1).type == linelabel) //label/comment on the end
    {
        memset(&entry, 0, sizeof(entry));
        entry.type = linecommand;
        strcpy_s(entry.raw, "ret");
        strcpy_s(entry.u.command, "ret");
        linemap.push_back(entry);
    }
    return true;
}
Example #10
0
static bool scriptcreatelinemap(const char* filename)
{
    String filedata;
    if(!FileHelper::ReadAllText(filename, filedata))
    {
        String TranslatedString = GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "FileHelper::ReadAllText failed..."));
        GuiScriptError(0, TranslatedString.c_str());
        return false;
    }
    auto len = filedata.length();
    char temp[256] = "";
    LINEMAPENTRY entry;
    memset(&entry, 0, sizeof(entry));
    std::vector<LINEMAPENTRY>().swap(linemap);
    for(size_t i = 0, j = 0; i < len; i++) //make raw line map
    {
        if(filedata[i] == '\r' && filedata[i + 1] == '\n') //windows file
        {
            memset(&entry, 0, sizeof(entry));
            int add = 0;
            while(temp[add] == ' ')
                add++;
            strcpy_s(entry.raw, temp + add);
            *temp = 0;
            j = 0;
            i++;
            linemap.push_back(entry);
        }
        else if(filedata[i] == '\n') //other file
        {
            memset(&entry, 0, sizeof(entry));
            int add = 0;
            while(temp[add] == ' ')
                add++;
            strcpy_s(entry.raw, temp + add);
            *temp = 0;
            j = 0;
            linemap.push_back(entry);
        }
        else if(j >= 254)
        {
            memset(&entry, 0, sizeof(entry));
            int add = 0;
            while(temp[add] == ' ')
                add++;
            strcpy_s(entry.raw, temp + add);
            *temp = 0;
            j = 0;
            linemap.push_back(entry);
        }
        else
            j += sprintf(temp + j, "%c", filedata[i]);
    }
    if(*temp)
    {
        memset(&entry, 0, sizeof(entry));
        strcpy_s(entry.raw, temp);
        linemap.push_back(entry);
    }
    int linemapsize = (int)linemap.size();
    while(!*linemap.at(linemapsize - 1).raw) //remove empty lines from the end
    {
        linemapsize--;
        linemap.pop_back();
    }
    for(int i = 0; i < linemapsize; i++)
    {
        LINEMAPENTRY cur = linemap.at(i);

        //temp. remove comments from the raw line
        char line_comment[256] = "";
        char* comment = strstr(&cur.raw[0], "//");
        if(!comment)
            comment = strstr(&cur.raw[0], ";");
        if(comment && comment != cur.raw) //only when the line doesnt start with a comment
        {
            if(*(comment - 1) == ' ') //space before comment
            {
                strcpy_s(line_comment, comment);
                *(comment - 1) = '\0';
            }
            else //no space before comment
            {
                strcpy_s(line_comment, comment);
                *comment = 0;
            }
        }

        int rawlen = (int)strlen(cur.raw);
        if(!rawlen) //empty
        {
            cur.type = lineempty;
        }
        else if(!strncmp(cur.raw, "//", 2) || *cur.raw == ';')  //comment
        {
            cur.type = linecomment;
            strcpy_s(cur.u.comment, cur.raw);
        }
        else if(cur.raw[rawlen - 1] == ':') //label
        {
            cur.type = linelabel;
            sprintf(cur.u.label, "l %.*s", rawlen - 1, cur.raw); //create a fake command for formatting
            strcpy_s(cur.u.label, StringUtils::Trim(cur.u.label).c_str());
            strcpy_s(temp, cur.u.label + 2);
            strcpy_s(cur.u.label, temp); //remove fake command
            if(!*cur.u.label || !strcmp(cur.u.label, "\"\"")) //no label text
            {
                char message[256] = "";
                sprintf(message, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Empty label detected on line %d!")), i + 1);
                GuiScriptError(0, message);
                std::vector<LINEMAPENTRY>().swap(linemap);
                return false;
            }
            int foundlabel = scriptlabelfind(cur.u.label);
            if(foundlabel) //label defined twice
            {
                char message[256] = "";
                sprintf(message, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Duplicate label \"%s\" detected on lines %d and %d!")), cur.u.label, foundlabel, i + 1);
                GuiScriptError(0, message);
                std::vector<LINEMAPENTRY>().swap(linemap);
                return false;
            }
        }
        else if(scriptgetbranchtype(cur.raw) != scriptnobranch) //branch
        {
            cur.type = linebranch;
            cur.u.branch.type = scriptgetbranchtype(cur.raw);
            char newraw[MAX_SCRIPT_LINE_SIZE] = "";
            strcpy_s(newraw, StringUtils::Trim(cur.raw).c_str());
            int rlen = (int)strlen(newraw);
            for(int j = 0; j < rlen; j++)
                if(newraw[j] == ' ')
                {
                    strcpy_s(cur.u.branch.branchlabel, newraw + j + 1);
                    break;
                }
        }
        else
        {
            cur.type = linecommand;
            strcpy_s(cur.u.command, cur.raw);
        }

        //append the comment to the raw line again
        if(*line_comment)
            sprintf(cur.raw + rawlen, " %s", line_comment);
        linemap.at(i) = cur;
    }
    linemapsize = (int)linemap.size();
    for(int i = 0; i < linemapsize; i++)
    {
        auto & currentLine = linemap.at(i);
        if(currentLine.type == linebranch)  //invalid branch label
        {
            int labelline = scriptlabelfind(currentLine.u.branch.branchlabel);
            if(!labelline) //invalid branch label
            {
                char message[256] = "";
                sprintf(message, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Invalid branch label \"%s\" detected on line %d!")), currentLine.u.branch.branchlabel, i + 1);
                GuiScriptError(0, message);
                std::vector<LINEMAPENTRY>().swap(linemap);
                return false;
            }
            else //set the branch destination line
                currentLine.u.branch.dest = scriptinternalstep(labelline);
        }
    }
    if(linemap.at(linemapsize - 1).type == linecomment || linemap.at(linemapsize - 1).type == linelabel) //label/comment on the end
    {
        memset(&entry, 0, sizeof(entry));
        entry.type = linecommand;
        strcpy_s(entry.raw, "ret");
        strcpy_s(entry.u.command, "ret");
        linemap.push_back(entry);
    }
    return true;
}