示例#1
0
void SLintScilabResult::finalize()
{
    for (const auto & p1 : results)
    {
        std::wstring str = L"In " + p1.first + L":\n";
        scilabWriteW(str.c_str());
        for (const auto & p2 : p1.second)
        {
            std::wstring str = L"  At line " + std::to_wstring(p2.first.first_line) + L": " + p2.second + L"\n";
            scilabWriteW(str.c_str());
        }
    }
}
void DebuggerVisitor::visit(const SeqExp  &e)
{
    RunVisitor* exec = NULL;
    std::list<Exp *>::const_iterator itExp;
    debugger::DebuggerMagager* manager = debugger::DebuggerMagager::getInstance();

    if (ConfigVariable::getEnableDebug() == false)
    {
        //enable debugger for next execution
        ConfigVariable::setEnableDebug(true);

        ExecVisitor exec;
        e.accept(exec);
        return;
    }

    for (const auto& exp : e.getExps())
    {
        if (e.isBreakable())
        {
            exp->resetBreak();
            exp->setBreakable();
        }

        if (e.isContinuable())
        {
            exp->resetContinue();
            exp->setContinuable();
        }

        if (e.isReturnable())
        {
            exp->setReturnable();
        }

        //debugger check !
        if (ConfigVariable::getEnableDebug())
        {
            std::vector<ConfigVariable::WhereEntry> lWhereAmI = ConfigVariable::getWhere();
            int iLine = (exp->getLocation().first_line - ConfigVariable::getMacroFirstLines()) + 1;

            //manage step next
            if (manager->isStepNext())
            {
                manager->resetStepNext();
                manager->stop(exp, -1);
            }
            else if (manager->isStepIn())
            {
                manager->resetStepIn();
                manager->stop(exp, -1);
            }
            else if (manager->isStepOut())
            {
                manager->resetStepOut();
                manager->stop(exp, -1);
            }
            else
            {
                //set information from debugger commands
                if (lWhereAmI.size() != 0 && manager->getBreakPointCount() != 0)
                {
                    debugger::Breakpoints bps = manager->getAllBreakPoint();
                    std::wstring functionName = lWhereAmI.back().m_name;
                    int i = -1;
                    for (const auto& bp : bps)
                    {
                        ++i;
                        if (bp->isEnable() == false)
                        {
                            continue;
                        }

                        if (functionName == bp->getFunctioName())
                        {
                            if (bp->getMacroLine() == -1)
                            {
                                //first pass in macro.
                                //update first line with real value
                                bp->setMacroLine(iLine);
                            }

                            if (bp->getMacroLine() == iLine)
                            {
                                //check condition
                                if (bp->getConditionExp() != NULL)
                                {
                                    //do not use debuggervisitor !
                                    symbol::Context* pCtx = symbol::Context::getInstance();
                                    try
                                    {
                                        ExecVisitor execCond;
                                        //protect current env during condition execution
                                        pCtx->scope_begin();
                                        bp->getConditionExp()->accept(execCond);
                                        types::InternalType* pIT = pCtx->getCurrentLevel(symbol::Symbol(L"ans"));
                                        if (pIT == NULL ||
                                                pIT->isBool() == false ||
                                                ((types::Bool*)pIT)->isScalar() == false ||
                                                ((types::Bool*)pIT)->get(0) == 0)
                                        {
                                            pCtx->scope_end();
                                            //not a boolean, not scalar or false
                                            continue;
                                        }

                                        pCtx->scope_end();
                                        //ok condition is valid and true
                                    }
                                    catch (ast::ScilabException &/*e*/)
                                    {
                                        pCtx->scope_end();
                                        //not work !
                                        //invalid breakpoint
                                        continue;
                                    }
                                }

                                //we have a breakpoint !
                                //stop execution and wait signal from debugger to restart
                                manager->stop(exp, i);

                                //only one breakpoint can be "call" on same exp
                                break;
                            }
                        }
                    }
                }
            }
            exec = this;
        }
        else
        {
            //change visitor to execvitor instead of debuggervisitor
            exec = new ExecVisitor();
        }

        //copy from runvisitor::seqexp
        try
        {
            //reset default values
            setResult(NULL);
            int iExpectedSize = getExpectedSize();
            setExpectedSize(-1);
            exp->accept(*exec);
            setExpectedSize(iExpectedSize);
            types::InternalType * pIT = getResult();

            // In case of exec file, set the file name in the Macro to store where it is defined.
            int iFileID = ConfigVariable::getExecutedFileID();
            if (iFileID && exp->isFunctionDec())
            {
                types::InternalType* pITMacro = symbol::Context::getInstance()->get(exp->getAs<ast::FunctionDec>()->getSymbol());
                if (pITMacro)
                {
                    types::Macro* pMacro = pITMacro->getAs<types::Macro>();
                    const wchar_t* filename = getfile_filename(iFileID);
                    // scilab.quit is not open with mopen
                    // in this case filename is NULL because FileManager have not been filled.
                    if (filename)
                    {
                        pMacro->setFileName(filename);
                    }
                }
            }

            if (pIT != NULL)
            {
                bool bImplicitCall = false;
                if (pIT->isCallable()) //to manage call without ()
                {
                    types::Callable *pCall = pIT->getAs<types::Callable>();
                    types::typed_list out;
                    types::typed_list in;
                    types::optional_list opt;

                    try
                    {
                        //in this case of calling, we can return only one values
                        int iSaveExpectedSize = getExpectedSize();
                        setExpectedSize(1);

                        pCall->invoke(in, opt, getExpectedSize(), out, e);
                        setExpectedSize(iSaveExpectedSize);

                        if (out.size() == 0)
                        {
                            setResult(NULL);
                        }
                        else
                        {
                            setResult(out[0]);
                        }

                        bImplicitCall = true;
                    }
                    catch (const InternalError& ie)
                    {
                        if (ConfigVariable::getLastErrorFunction() == L"")
                        {
                            ConfigVariable::setLastErrorFunction(pCall->getName());
                            ConfigVariable::setLastErrorLine(e.getLocation().first_line);
                        }

                        throw ie;
                    }
                }

                //don't output Simplevar and empty result
                if (getResult() != NULL && (!exp->isSimpleVar() || bImplicitCall))
                {
                    //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
                    types::InternalType* pITAns = getResult();
                    symbol::Context::getInstance()->put(m_pAns, pITAns);
                    if (exp->isVerbose() && ConfigVariable::isPrintOutput())
                    {
                        //TODO manage multiple returns
                        scilabWriteW(L" ans  =\n\n");
                        std::wostringstream ostrName;
                        ostrName << L"ans";
                        types::VariableToString(pITAns, ostrName.str().c_str());
                    }
                }

                pIT->killMe();
            }

            if ((&e)->isBreakable() && exp->isBreak())
            {
                const_cast<SeqExp *>(&e)->setBreak();
                exp->resetBreak();
                break;
            }

            if ((&e)->isContinuable() && exp->isContinue())
            {
                const_cast<SeqExp *>(&e)->setContinue();
                exp->resetContinue();
                break;
            }

            if ((&e)->isReturnable() && exp->isReturn())
            {
                const_cast<SeqExp *>(&e)->setReturn();
                exp->resetReturn();
                break;
            }
        }
        catch (const InternalError& ie)
        {
            ConfigVariable::fillWhereError(ie.GetErrorLocation().first_line);

            std::vector<ConfigVariable::WhereEntry> lWhereAmI = ConfigVariable::getWhere();

            //where can be empty on last stepout, on first calling expression
            if (lWhereAmI.size())
            {
                std::wstring& filename = lWhereAmI.back().m_file_name;

                if (filename.empty())
                {
                    //error in a console script
                    std::wstring functionName = lWhereAmI.back().m_name;
                    manager->errorInScript(functionName, exp);
                }
                else
                {
                    manager->errorInFile(filename, exp);
                }
            }

            throw ie;
        }

        // If something other than NULL is given to setResult, then that would imply
        // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
        setResult(NULL);

    }

    //propagate StepNext to parent SeqExp
    if (ConfigVariable::getEnableDebug())
    {
    }
}
示例#3
0
/*--------------------------------------------------------------------------*/
types::Function::ReturnValue sci_genlib(types::typed_list &in, int _iRetCount, types::typed_list &out)
{
    int succes = 1;
    std::vector<std::wstring> failed_files;
    std::vector<std::wstring> success_files;
    std::vector<std::wstring> funcs;

    wchar_t pstParseFile[PATH_MAX + FILENAME_MAX];
    wchar_t pstVerbose[65535];

    int iNbFile = 0;
    wchar_t *pstParsePath = NULL;
    int iParsePathLen = 0;
    wchar_t* pstLibName = NULL;
    bool bVerbose = false;
    bool bForce = false;

    if (in.size() < 1 || in.size() > 4)
    {
        Scierror(78, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "genlib", 1, 4);
        return types::Function::Error;
    }

    //param 1, library name
    types::InternalType* pIT = in[0];
    if (pIT->isString() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "genlib", 1);
        return types::Function::Error;
    }

    types::String *pS = pIT->getAs<types::String>();
    if (pS->getSize() != 1)
    {
        Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), "genlib", 1);
        return types::Function::Error;
    }
    pstLibName = pS->get(0);

    //param 2, library path
    if (in.size() > 1)
    {
        pIT = in[1];
        if (pIT->isString() == false)
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "genlib", 2);
            return types::Function::Error;
        }
    }
    else
    {
        int ierr = 0;
        char* pstr = scigetcwd(&ierr);
        pIT = new types::String(pstr);
        FREE(pstr);
    }

    pS = pIT->getAs<types::String>();
    if (pS->isScalar() == false)
    {
        Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), "genlib", 2);
        return types::Function::Error;
    }

    //param 3, force flag
    if (in.size() > 2)
    {
        pIT = in[2];
        if (pIT->isBool() == false)
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: A scalar boolean expected.\n"), "genlib", 3);
            return types::Function::Error;
        }

        types::Bool* p = pIT->getAs<types::Bool>();
        if (p->isScalar() == false)
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: A scalar boolean expected.\n"), "genlib", 3);
            return types::Function::Error;
        }

        bForce = p->get()[0] == 1;
    }

    if (in.size() > 3)
    {
        //verbose flag
        pIT = in[3];
        if (pIT->isBool() == false)
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: A scalar boolean expected.\n"), "genlib", 3);
            return types::Function::Error;
        }

        types::Bool* p = pIT->getAs<types::Bool>();
        if (p->isScalar() == false)
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: A scalar boolean expected.\n"), "genlib", 3);
            return types::Function::Error;
        }

        bVerbose = p->get()[0] == 1;
    }

    wchar_t* pstFile = pS->get(0);
    pstParsePath = pathconvertW(pstFile, TRUE, TRUE, AUTO_STYLE);

    if (in.size() == 1)
    {
        delete pS;
    }

    os_swprintf(pstParseFile, PATH_MAX + FILENAME_MAX, L"%lslib", pstParsePath);

    if (bVerbose)
    {
        os_swprintf(pstVerbose, 65535, _W("-- Creation of [%ls] (Macros) --\n").c_str(), pstLibName);

        //save current prompt mode
        int oldVal = ConfigVariable::getPromptMode();
        //set mode silent for errors
        ConfigVariable::setPromptMode(0);
        scilabWriteW(pstVerbose);
        //restore previous prompt mode
        ConfigVariable::setPromptMode(oldVal);
    }

    MacroInfoList lstOld;
    if (FileExistW(pstParseFile))
    {
        //read it to get previous information like md5
        std::wstring libname;
        parseLibFile(pstParseFile, lstOld, libname);
        deleteafileW(pstParseFile);
    }

    xmlTextWriterPtr pWriter = openXMLFile(pstParseFile, pstLibName);

    if (pWriter == NULL)
    {
        os_swprintf(pstVerbose, 65535, _W("%ls: Cannot open file ''%ls''.\n").c_str(), L"genlib", pstParseFile);
        scilabWriteW(pstVerbose);

        out.push_back(new types::Bool(0));
        FREE(pstParsePath);
        return types::Function::OK;
    }


    wchar_t **pstPath = findfilesW(pstParsePath, L"*.sci", &iNbFile, FALSE);

    if (pstPath)
    {
        types::Library* pLib = new types::Library(pstParsePath);
        for (int k = 0 ; k < iNbFile ; k++)
        {
            //version with direct parsing
            //parse the file to find all functions
            std::wstring stFullPath = std::wstring(pstParsePath) + std::wstring(pstPath[k]);
            std::wstring stFullPathBin(stFullPath);
            stFullPathBin.replace(stFullPathBin.end() - 3, stFullPathBin.end(), L"bin");
            std::wstring pstPathBin(pstPath[k]);
            pstPathBin.replace(pstPathBin.end() - 3, pstPathBin.end(), L"bin");

            //compute file md5
            FILE* fmdf5 = os_wfopen(stFullPath.data(), L"rb");
            if (fmdf5 == NULL)
            {
                char* pstr = wide_string_to_UTF8(stFullPath.data());
                Scierror(999, _("%s: Cannot open file ''%s''.\n"), "genlib", pstr);
                FREE(pstr);
                FREE(pstParsePath);
                freeArrayOfWideString(pstPath, iNbFile);
                pLib->killMe();
                return types::Function::Error;
            }

            char* md5 = md5_file(fmdf5);
            fclose(fmdf5);

            wchar_t* wmd5 = to_wide_string(md5);
            FREE(md5);
            std::wstring wide_md5(wmd5);
            FREE(wmd5);

            if (bForce == false)
            {
                //check if is exist in old file
                MacroInfoList::iterator it = lstOld.find(pstPathBin);
                if (it != lstOld.end())
                {
                    if (wide_md5 == (*it).second.md5)
                    {
                        //file not change, we can skip it
                        AddMacroToXML(pWriter, (*it).second.name, pstPathBin, wide_md5);
                        pLib->add((*it).second.name, new types::MacroFile((*it).second.name, stFullPathBin, pstLibName));
                        success_files.push_back(stFullPath);
                        funcs.push_back((*it).second.name);
                        continue;
                    }
                }
            }

            if (bVerbose)
            {
                sciprint(_("%ls: Processing file: %ls\n"), L"genlib", pstPath[k]);
            }

            Parser parser;
            parser.parseFile(stFullPath, ConfigVariable::getSCIPath());
            if (parser.getExitStatus() !=  Parser::Succeded)
            {
                if (_iRetCount != 4)
                {
                    std::wstring wstrErr = parser.getErrorMessage();

                    wchar_t errmsg[256];
                    os_swprintf(errmsg, 256, _W("%ls: Error in file %ls.\n").c_str(), L"genlib", stFullPath.data());
                    wstrErr += errmsg;

                    char* str = wide_string_to_UTF8(wstrErr.c_str());
                    Scierror(999, str);
                    FREE(str);

                    FREE(pstParsePath);
                    freeArrayOfWideString(pstPath, iNbFile);
                    closeXMLFile(pWriter);
                    delete pLib;
                    return types::Function::Error;
                }

                failed_files.push_back(stFullPath);
                succes = 0;
                continue;
            }

            //serialize ast
            ast::SerializeVisitor* s = new ast::SerializeVisitor(parser.getTree());

            unsigned char* serialAst = s->serialize();
            // Header is : buffer size (4 bytes) + scilab version (4 bytes)
            unsigned int size = *((unsigned int*)serialAst);

            FILE* f = os_wfopen(stFullPathBin.c_str(), L"wb");
            fwrite(serialAst, 1, size, f);
            fclose(f);

            ast::exps_t LExp = parser.getTree()->getAs<ast::SeqExp>()->getExps();
            for (ast::exps_t::iterator j = LExp.begin(), itEnd = LExp.end() ; j != itEnd ; ++j)
            {
                if ((*j)->isFunctionDec())
                {
                    ast::FunctionDec* pFD = (*j)->getAs<ast::FunctionDec>();
                    const std::wstring& name = pFD->getSymbol().getName();
                    if (name + L".sci" == pstPath[k])
                    {
                        if (AddMacroToXML(pWriter, name, pstPathBin, wide_md5) == false)
                        {
                            os_swprintf(pstVerbose, 65535, _W("%ls: Warning: %ls information cannot be added to file %ls. File ignored\n").c_str(), L"genlib", pFD->getSymbol().getName().c_str(), pstPath[k]);
                            scilabWriteW(pstVerbose);
                        }

                        pLib->add(name, new types::MacroFile(name, stFullPathBin, pstLibName));
                        success_files.push_back(stFullPath);
                        funcs.push_back(name);
                        break;
                    }
                }
            }

            delete s;
            free(serialAst);
            delete parser.getTree();
        }

        symbol::Context* ctx = symbol::Context::getInstance();
        symbol::Symbol sym = symbol::Symbol(pstLibName);
        if (ctx->isprotected(sym) == false)
        {
            ctx->put(symbol::Symbol(pstLibName), pLib);
        }
        else
        {
            Scierror(999, _("Redefining permanent variable.\n"));

            freeArrayOfWideString(pstPath, iNbFile);
            FREE(pstParsePath);
            closeXMLFile(pWriter);
            delete pLib;
            return types::Function::Error;
        }
    }

    freeArrayOfWideString(pstPath, iNbFile);

    out.push_back(new types::Bool(succes));

    if (_iRetCount > 1)
    {
        int size = static_cast<int>(funcs.size());
        if (size == 0)
        {
            out.push_back(types::Double::Empty());
        }
        else
        {
            types::String* s = new types::String(size, 1);

            for (int i = 0; i < size; ++i)
            {
                s->set(i, funcs[i].data());
            }

            out.push_back(s);
        }
    }

    if (_iRetCount > 2)
    {
        int size = static_cast<int>(success_files.size());
        if (size == 0)
        {
            out.push_back(types::Double::Empty());
        }
        else
        {
            types::String* s = new types::String(size, 1);

            for (int i = 0; i < size; ++i)
            {
                s->set(i, success_files[i].data());
            }

            out.push_back(s);
        }
    }

    if (_iRetCount > 3)
    {
        int size = static_cast<int>(failed_files.size());
        if (size == 0)
        {
            out.push_back(types::Double::Empty());
        }
        else
        {
            types::String* s = new types::String(size, 1);

            for (int i = 0; i < size; ++i)
            {
                s->set(i, failed_files[i].data());
            }

            out.push_back(s);
        }
    }

    FREE(pstParsePath);
    closeXMLFile(pWriter);
    return types::Function::OK;
}