Exemplo n.º 1
0
/** \brief parse the given file name */
void ParserSingleInstance::parseFile(const std::wstring& fileName, const std::wstring& progName)
{
    yylloc.first_line = yylloc.last_line = 1;
    yylloc.first_column = yylloc.last_column = 1;
#ifdef _MSC_VER
    _wfopen_s(&yyin, fileName.c_str(), L"r");
#else
    char* pstTemp = wide_string_to_UTF8(fileName.c_str());
    yyin = fopen(pstTemp, "r");
    FREE(pstTemp);
#endif

    if (!yyin)
    {
        wchar_t szError[bsiz];
        os_swprintf(szError, bsiz, _W("%ls: Cannot open file %ls.\n").c_str(), L"parser", fileName.c_str());
        throw ast::InternalError(szError);
    }


    ParserSingleInstance::disableStrictMode();
    //  Parser::getInstance()->enableStrictMode();
    ParserSingleInstance::setFileName(fileName);
    ParserSingleInstance::setProgName(progName);

    ParserSingleInstance::setTree(nullptr);
    ParserSingleInstance::setExitStatus(Parser::Succeded);
    ParserSingleInstance::resetControlStatus();
    ParserSingleInstance::resetErrorMessage();
    yyparse();
    fclose(yyin);
}
Exemplo n.º 2
0
/**
 * Export the variable LC_XXXX to the system
 *
 * @param locale the locale (ex : fr_FR or en_US)
 */
BOOL exportLocaleToSystem(const wchar_t *locale)
{

    if (locale == NULL)
    {
#ifdef _MSC_VER
        fprintf(stderr, "Localization: Have not been able to find a suitable locale. Remains to default %s.\n", "LC_CTYPE");
#else
        fprintf(stderr, "Localization: Have not been able to find a suitable locale. Remains to default %ls.\n", EXPORTENVLOCALESTR);
#endif
        return FALSE;
    }

    /* It will put in the env something like LC_MESSAGES=fr_FR */
    if ( !setenvcW(EXPORTENVLOCALESTR, locale))
    {
#ifdef _MSC_VER
        fprintf(stderr, "Localization: Failed to declare the system variable %s.\n", "LC_CTYPE");
#else
        fprintf(stderr, "Localization: Failed to declare the system variable %d.\n", EXPORTENVLOCALE);
#endif
        return FALSE;
    }

#ifdef _MSC_VER
#ifdef USE_SAFE_GETTEXT_DLL
    {
        /* gettext is buggy on Windows */
        /* We need to set a external environment variable to scilab env. */
        char* pstr = NULL;
        wchar_t env[MAX_PATH];
        os_swprintf(env, MAX_PATH, L"%ls=%ls", EXPORTENVLOCALESTR, locale);
        pstr = wide_string_to_UTF8(env);
        gettext_putenv(pstr);
        FREE(pstr);
    }
#endif
#else
    /* Export LC_NUMERIC to the system to make sure that the rest of system
       is using the english notation (Java, Tcl ...) */
    setenvc("LC_NUMERIC", LCNUMERICVALUE);
#endif

    return TRUE;
}
Exemplo n.º 3
0
/*--------------------------------------------------------------------------*/
types::Function::ReturnValue sci_intg(types::typed_list &in, int _iRetCount, types::typed_list &out)
{
    double pdA    = 0;
    double pdB    = 0;
    double pdEpsR = 1.0e-8;
    double pdEpsA = 1.0e-13;

    double result = 0;
    double abserr = 0;

    int iOne = 1;

    // error message catched
    std::wostringstream os;
    bool bCatch = false;

    // *** check the minimal number of input args. ***
    if (in.size() < 3 || in.size() > 5)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "intg", 3);
        return types::Function::Error;
    }

    // *** check number of output args ***
    if (_iRetCount > 3)
    {
        Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "intg", 3);
        return types::Function::Error;
    }

    // *** check type of input args and get it. ***
    // A
    if (in[0]->isDouble() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "intg", 1);
        return types::Function::Error;
    }

    types::Double* pDblA = in[0]->getAs<types::Double>();

    if (pDblA->isScalar() == false)
    {
        Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), "intg", 1);
        return types::Function::Error;
    }

    pdA = pDblA->get(0);

    if (ISNAN(pdA) || C2F(vfinite)(&iOne , &pdA) == false)
    {
        Scierror(264, _("%s: Wrong type for input argument #%d: Must not contain NaN or Inf.\n"), "intg", 1);
        return types::Function::Error;
    }

    // B
    if (in[1]->isDouble() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "intg", 2);
        return types::Function::Error;
    }

    types::Double* pDblB = in[1]->getAs<types::Double>();

    if (pDblB->isScalar() == false)
    {
        Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), "intg", 2);
        return types::Function::Error;
    }

    pdB = pDblB->get(0);

    if (ISNAN(pdB) || C2F(vfinite)(&iOne , &pdB) == false)
    {
        Scierror(264, _("%s: Wrong type for input argument #%d: Must not contain NaN or Inf.\n"), "intg", 1);
        return types::Function::Error;
    }

    // function
    DifferentialEquationFunctions deFunctionsManager(L"intg");
    DifferentialEquation::addDifferentialEquationFunctions(&deFunctionsManager);

    if (in[2]->isCallable())
    {
        types::Callable* pCall = in[2]->getAs<types::Callable>();
        deFunctionsManager.setFFunction(pCall);

        // check function
        double t = 1;
        double ret = intg_f(&t);
        /* if (ret == 0)
        {
            Scierror(50, _("%s: Argument #%d: Variable returned by scilab argument function is incorrect.\n"), "intg", 3);
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }*/
    }
    else if (in[2]->isString())
    {
        bool bOK = false;
        types::String* pStr = in[2]->getAs<types::String>();
        bOK = deFunctionsManager.setFFunction(pStr);

        if (bOK == false)
        {
            char* pst = wide_string_to_UTF8(pStr->get(0));
            Scierror(50, _("%s: Subroutine not found: %s\n"), "intg", pst);
            FREE(pst);
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }
    }
    else if (in[2]->isList())
    {
        types::List* pList = in[2]->getAs<types::List>();

        if (pList->getSize() == 0)
        {
            Scierror(50, _("%s: Argument #%d: Subroutine not found in list: %s\n"), "intg", 3, "(string empty)");
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }

        if (pList->get(0)->isCallable())
        {
            deFunctionsManager.setFFunction(pList->get(0)->getAs<types::Callable>());
            for (int iter = 1; iter < pList->getSize(); iter++)
            {
                deFunctionsManager.setFArgs(pList->get(iter)->getAs<types::InternalType>());
            }
        }
        else
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: The first argument in the list must be a Scilab function.\n"), "intg", 3);
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }
    }
    else
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A function expected.\n"), "intg", 3);
        DifferentialEquation::removeDifferentialEquationFunctions();
        return types::Function::Error;
    }

    if (in.size() > 3)
    {
        if (in[3]->isDouble() == false)
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "intg", 4);
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }

        types::Double* pDblEpsA = in[3]->getAs<types::Double>();

        if (pDblEpsA->isScalar() == false)
        {
            Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), "intg", 4);
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }

        pdEpsA = pDblEpsA->get(0);
    }

    if (in.size() == 5)
    {
        if (in[4]->isDouble() == false)
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "intg", 5);
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }

        types::Double* pDblEpsR = in[4]->getAs<types::Double>();

        if (pDblEpsR->isScalar() == false)
        {
            Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), "intg", 5);
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }
        pdEpsR = pDblEpsR->get(0);
    }

    // *** Create working table. ***
    int limit   = 750;
    int neval   = 0;
    int last    = 0;
    int lenw    = 4 * limit;

    double* dwork   = (double*)MALLOC(lenw * sizeof(double));
    int* iwork      = (int*)MALLOC(limit * sizeof(int));

    double epsabs   = fabs(pdEpsA);
    double epsrel   = fabs(pdEpsR);

    // *** Perform operation. ***
    int ier = 0;
    try
    {
        C2F(dqags)(intg_f, &pdA, &pdB, &epsabs, &epsrel,
                   &result, &abserr, &neval, &ier,
                   &limit, &lenw, &last, iwork, dwork);
    }
    catch (ast::InternalError &ie)
    {
        os << ie.GetErrorMessage();
        bCatch = true;
    }

    FREE(dwork);
    FREE(iwork);
    DifferentialEquation::removeDifferentialEquationFunctions();

    if (bCatch)
    {
        wchar_t szError[bsiz];
        os_swprintf(szError, bsiz, _W("%ls: An error occurred in '%ls' subroutine.\n").c_str(), L"intg", L"dqags");
        os << szError;
        throw ast::InternalError(os.str());
    }

    if (ier)
    {
        char* msg = NULL;
        switch (ier)
        {
            case 1 :
            {
                msg = _("%s: Maximum number of subdivisions achieved. Splitting the interval might help.\n");
                break;
            }
            case 2 :
            {
                msg = _("%s: Round-off error detected, the requested tolerance (or default) cannot be achieved. Try using bigger tolerances.\n");
                break;
            }
            case 3 :
            {
                msg = _("%s: Bad integrand behavior occurs at some points of the integration interval.\n");
                break;
            }
            case 4 :
            {
                msg = _("%s: Convergence problem, round-off error detected. Try using bigger tolerances.\n");
                break;
            }
            case 5 :
            {
                msg = _("%s: The integral is probably divergent, or slowly convergent.\n");
                break;
            }
            case 6 :
            {
                msg = _("%s: Invalid input, absolute tolerance <= 0 and relative tolerance < 2.e-14.\n");
                break;
            }
            default :
                msg = _("%s: Convergence problem...\n");
        }

        if (_iRetCount == 3)
        {
            if (getWarningMode())
            {
                sciprint(msg, "intg: Warning");
            }
        }
        else
        {
            Scierror(999, msg, "intg: Error");
            return types::Function::Error;
        }
    }

    // *** Return result in Scilab. ***
    types::Double* pDblOut = new types::Double(result);
    out.push_back(pDblOut);

    if (_iRetCount > 1)
    {
        out.push_back(new types::Double(abserr));
    }

    if (_iRetCount == 3)
    {
        out.push_back(new types::Double((double)ier));
    }

    return types::Function::OK;
}
Exemplo n.º 4
0
int StaticRunner::launch()
{
    //set execution thread in java
    if (!initialJavaHooks && getScilabMode() != SCILAB_NWNI)
    {
        initialJavaHooks = true;
        // Execute the initial hooks registered in Scilab.java
        ExecuteInitialHooks();
    }

    int iRet = 0;
    // get the runner to execute
    std::unique_ptr<Runner> runMe(getRunner());
    // set if the current comment is interruptible
    setInterruptibleCommand(runMe->isInterruptible());
    debugger::DebuggerMagager* manager = debugger::DebuggerMagager::getInstance();

    ConfigVariable::resetExecutionBreak();

    int oldMode = ConfigVariable::getPromptMode();
    symbol::Context* pCtx = symbol::Context::getInstance();
    int scope = pCtx->getScopeLevel();

    // a TCL command display nothing
    int iOldPromptMode = 0;
    if (runMe->getCommandOrigin() == TCLSCI)
    {
        iOldPromptMode = ConfigVariable::getPromptMode();
        ConfigVariable::setPromptMode(-1);
    }

    try
    {
        int level = ConfigVariable::getRecursionLevel();
        try
        {
            runMe->getProgram()->accept(*(runMe->getVisitor()));
        }
        catch (const ast::RecursionException& re)
        {
            // management of pause
            if (ConfigVariable::getPauseLevel())
            {
                ConfigVariable::DecreasePauseLevel();
                throw re;
            }

            //close opened scope during try
            while (pCtx->getScopeLevel() > scope)
            {
                pCtx->scope_end();
            }

            //decrease recursion to init value and close where
            while (ConfigVariable::getRecursionLevel() > level)
            {
                ConfigVariable::where_end();
                ConfigVariable::decreaseRecursion();
            }

            ConfigVariable::resetWhereError();
            ConfigVariable::setPromptMode(oldMode);

            //print msg about recursion limit and trigger an error
            wchar_t sz[1024];
            os_swprintf(sz, 1024, _W("Recursion limit reached (%d).\n").data(), ConfigVariable::getRecursionLimit());
            throw ast::InternalError(sz);
        }
    }
    catch (const ast::InternalError& se)
    {
        if (runMe->getCommandOrigin() == TCLSCI)
        {
            ConfigVariable::setPromptMode(iOldPromptMode);
        }

        std::wostringstream ostr;
        ConfigVariable::whereErrorToString(ostr);
        scilabErrorW(ostr.str().c_str());
        scilabErrorW(se.GetErrorMessage().c_str());
        ConfigVariable::resetWhereError();
        iRet = 1;
    }
    catch (const ast::InternalAbort& ia)
    {
        if (runMe->getCommandOrigin() == TCLSCI)
        {
            ConfigVariable::setPromptMode(iOldPromptMode);
        }

        // management of pause
        if (ConfigVariable::getPauseLevel())
        {
            ConfigVariable::DecreasePauseLevel();
            throw ia;
        }

        // close all scope before return to console scope
        symbol::Context* pCtx = symbol::Context::getInstance();
        while (pCtx->getScopeLevel() > scope)
        {
            pCtx->scope_end();
        }

        // send the good signal about the end of execution
        sendExecDoneSignal(runMe.get());

        //clean debugger step flag if debugger is not interrupted ( end of debug )
        manager->resetStep();
        throw ia;
    }

    if (runMe->getCommandOrigin() == TCLSCI)
    {
        ConfigVariable::setPromptMode(iOldPromptMode);
    }

    if (getScilabMode() != SCILAB_NWNI && getScilabMode() != SCILAB_API)
    {
        char *cwd = NULL;
        int err = 0;

        UpdateBrowseVar();
        cwd = scigetcwd(&err);
        if (cwd)
        {
            FileBrowserChDir(cwd);
            FREE(cwd);
        }
    }

    // reset error state when new prompt occurs
    ConfigVariable::resetError();

    // send the good signal about the end of execution
    sendExecDoneSignal(runMe.get());

    //clean debugger step flag if debugger is not interrupted ( end of debug )
    manager->resetStep();
    return iRet;
}
Exemplo n.º 5
0
/*--------------------------------------------------------------------------*/
types::Function::ReturnValue sci_feval(types::typed_list &in, int _iRetCount, types::typed_list &out)
{
    int iPos = 0;
    int nn   = 1;
    int iErr = 0;

    //input
    types::Double* pDblX = NULL;
    types::Double* pDblY = NULL;

    // output
    types::Double* pDblOut = NULL;

    // error message catched
    std::wostringstream os;
    bool bCatch = false;

    // *** check the minimal number of input args. ***
    if (in.size() < 2 || in.size() > 3)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "feval", 2, 3);
        return types::Function::Error;
    }

    // *** check number of output args according the methode. ***
    if (_iRetCount > 1)
    {
        Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "feval", 1);
        return types::Function::Error;
    }

    // *** check type of input args and get it. ***
    // X
    if (in[iPos]->isDouble() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d : A real matrix expected.\n"), "feval", iPos + 1);
        return types::Function::Error;
    }
    pDblX = in[iPos]->getAs<types::Double>();
    if (pDblX->isComplex())
    {
        Scierror(999, _("%s: Wrong type for input argument #%d : A real matrix expected.\n"), "feval", iPos + 1);
        return types::Function::Error;
    }
    iPos++;

    // Y
    if (in.size() == 3)
    {
        if (in[iPos]->isDouble() == false)
        {
            Scierror(999, _("%s: Wrong type for input argument #%d : A real matrix expected.\n"), "feval", iPos + 1);
            return types::Function::Error;
        }
        pDblY = in[iPos]->getAs<types::Double>();
        if (pDblY->isComplex())
        {
            Scierror(999, _("%s: Wrong type for input argument #%d : A real matrix expected.\n"), "feval", iPos + 1);
            return types::Function::Error;
        }
        iPos++;
        nn = 2;
    }

    // function
    DifferentialEquationFunctions deFunctionsManager(L"feval");
    DifferentialEquation::addDifferentialEquationFunctions(&deFunctionsManager);

    if (in[iPos]->isCallable())
    {
        types::Callable* pCall = in[iPos]->getAs<types::Callable>();
        deFunctionsManager.setFFunction(pCall);
    }
    else if (in[iPos]->isString())
    {
        bool bOK = false;
        types::String* pStr = in[iPos]->getAs<types::String>();
        bOK = deFunctionsManager.setFFunction(pStr);

        if (bOK == false)
        {
            char* pst = wide_string_to_UTF8(pStr->get(0));
            Scierror(50, _("%s: Subroutine not found: %s\n"), "feval", pst);
            FREE(pst);
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }
    }
    else if (in[iPos]->isList())
    {
        types::List* pList = in[iPos]->getAs<types::List>();

        if (pList->getSize() == 0)
        {
            Scierror(50, _("%s: Argument #%d : Subroutine not found in list: %s\n"), "feval", iPos + 1, "(string empty)");
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }

        if (pList->get(0)->isCallable())
        {
            deFunctionsManager.setFFunction(pList->get(0)->getAs<types::Callable>());
            for (int iter = 1; iter < pList->getSize(); iter++)
            {
                deFunctionsManager.setFArgs(pList->get(iter)->getAs<types::InternalType>());
            }
        }
        else
        {
            Scierror(999, _("%s: Wrong type for input argument #%d : The first argument in the list must be a Scilab function.\n"), "feval", 4);
            DifferentialEquation::removeDifferentialEquationFunctions();
            return types::Function::Error;
        }
    }
    else
    {
        Scierror(999, _("%s: Wrong type for input argument #%d : A function expected.\n"), "feval", iPos + 1);
        DifferentialEquation::removeDifferentialEquationFunctions();
        return types::Function::Error;
    }

    // *** Perform operation. ***
    int itype       = 0; // output value
    double* res     = (double*)MALLOC(2 * sizeof(double));
    int sizeOfY     = pDblY ? pDblY->getSize() : 1;

    if (nn == 2)
    {
        pDblOut = new types::Double(pDblX->getSize(), sizeOfY);
    }
    else
    {
        pDblOut = new types::Double(pDblX->getRows(), pDblX->getCols());
    }

    for (int y = 0; y < sizeOfY; y++)
    {
        for (int x = 0; x < pDblX->getSize(); x++)
        {
            double valX = pDblX->get(x);
            // if pDblY == NULL, nn == 1 so valY will be never used.
            double valY = pDblY ? pDblY->get(y) : 0;

            try
            {
                deFunctionsManager.execFevalF(&nn, &valX, &valY, res, &itype);
            }
            catch (ast::InternalError &ie)
            {
                os << ie.GetErrorMessage();
                bCatch = true;
            }

            if (bCatch)
            {
                DifferentialEquation::removeDifferentialEquationFunctions();
                FREE(res);
                delete pDblOut;

                wchar_t szError[bsiz];
                os_swprintf(szError, bsiz, _W("%s: An error occured in '%s' subroutine.\n").c_str(), "feval", "execFevalF");
                os << szError;
                throw ast::InternalError(os.str());
            }

            if (itype) // is complex
            {
                pDblOut->setComplex(true);
                pDblOut->set(x + y * pDblX->getSize(), res[0]);
                pDblOut->setImg(x + y * pDblX->getSize(), res[1]);
            }
            else
            {
                pDblOut->set(x + y * pDblX->getSize(), res[0]);
            }
        }
    }

    // *** Return result in Scilab. ***

    out.push_back(pDblOut);

    FREE(res);
    DifferentialEquation::removeDifferentialEquationFunctions();

    return types::Function::OK;
}
Exemplo n.º 6
0
void ConfigVariable::whereErrorToString(std::wostringstream &ostr)
{
    int iLenName = 1;
    bool isExecstr = false;
    bool isExecfile = false;

    // get max length of functions name and check if exec or execstr have been called.
    for (auto & where : m_WhereError)
    {
        if (isExecstr == false && where.m_name == L"execstr")
        {
            isExecstr = true;
            continue;
        }
        else if (isExecfile == false && where.m_name == L"exec")
        {
            isExecfile = true;
            continue;
        }

        iLenName = (std::max)((int)where.m_name.length(), iLenName);

        // in case of bin file, the file path and line is displayed only if the associated .sci file exists
        if (where.m_file_name != L"" && where.m_file_name.find(L".bin") != std::wstring::npos)
        {
            std::size_t pos = where.m_file_name.find_last_of(L".");
            where.m_file_name.replace(pos, pos + 4, L".sci");
            if (FileExistW(const_cast<wchar_t*>(where.m_file_name.c_str())) == false)
            {
                where.m_file_name = L"";
            }
        }
    }

    // add margin
    iLenName++;

    // initialize localized strings
    std::wstring wstrBuiltin(_W("in builtin "));
    std::wstring wstrAtLine(_W("at line % 5d of function "));
    std::wstring wstrExecStr(_W("at line % 5d of executed string "));
    std::wstring wstrExecFile(_W("at line % 5d of executed file "));

    // compute max size between "at line xxx of function" and "in builtin "
    // +1 : line number is pad to 5. length of "% 5d" + 1 == 5
    int iMaxLen = (std::max)(wstrAtLine.length() + 1, wstrBuiltin.length());
    if (isExecstr)
    {
        iMaxLen = (std::max)(((int)wstrExecStr.length()) + 1, iMaxLen);
    }

    if (isExecstr)
    {
        iMaxLen = (std::max)(((int)wstrExecFile.length()) + 1, iMaxLen);
    }

    // print call stack
    ostr << std::left;
    ostr.fill(L' ');
    for (auto & where : m_WhereError)
    {
        ostr.width(iMaxLen);
        if (where.m_line == 0)
        {
            ostr << wstrBuiltin;
        }
        else
        {
            if (where.m_name == L"execstr")
            {
                isExecstr = true;
                wchar_t wcsTmp[bsiz];
                os_swprintf(wcsTmp, bsiz, wstrExecStr.c_str(), where.m_line);
                ostr << wcsTmp << std::endl;
                continue;
            }
            else if (where.m_name == L"exec")
            {
                wchar_t wcsTmp[bsiz];
                os_swprintf(wcsTmp, bsiz, wstrExecFile.c_str(), where.m_line);
                ostr << wcsTmp << where.m_file_name << std::endl;
                continue;
            }
            else
            {
                wchar_t wcsTmp[bsiz];
                os_swprintf(wcsTmp, bsiz, wstrAtLine.c_str(), where.m_line);
                ostr << wcsTmp;
            }
        }

        ostr.width(iLenName);
        ostr << where.m_name;

        if (where.m_file_name != L"")
        {
            // -1 because the first line of a function dec is : "function myfunc()"
            ostr << L"( " << where.m_file_name << L" " << _W("line") << L" " << where.m_macro_first_line + where.m_line - 1 << L" )";
        }

        ostr << std::endl;
    }
}
Exemplo n.º 7
0
/*--------------------------------------------------------------------------*/
types::Function::ReturnValue sci_dasrt(types::typed_list &in, int _iRetCount, types::typed_list &out)
{
    // input args
    types::Double* pDblX0   = NULL;
    types::Double* pDblT0   = NULL;
    types::Double* pDblT    = NULL;
    types::Double* pDblRtol = NULL;
    types::Double* pDblAtol = NULL;
    types::Double* pDblHd   = NULL;
    types::Double* pDblNg   = NULL;

    // x0 = [y0, ydot0]
    double* pdYData         = NULL; // contain y0 following by all args data in list case.
    double* pdYdotData      = NULL;
    int sizeOfpdYData       = 0;

    int sizeOfYSize = 1;
    int* YSize      = NULL;    // YSize(1) = size of y0,
    // YSize(n) = size of Args(n) in list case.
    int iPos    = 0;
    int one     = 1;

    int info[15]    = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    double tstop    = 0;
    double maxstep  = 0;
    double stepin   = 0;
    int ng          = 0;
    int mu          = 0;
    int ml          = 0;

    // Indicate if the function is given.
    bool bFuncF     = false;
    bool bFuncJac   = false;
    bool bFuncG     = false;

    // Indicate if info list is given.
    bool bListInfo  = false;

    // error message catched
    std::wostringstream os;
    bool bCatch = false;

    // *** check the minimal number of input args. ***
    if (in.size() < 6 || in.size() > 11)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "dasrt", 6, 11);
        return types::Function::Error;
    }

    // *** check number of output args ***
    if (_iRetCount != 3 && _iRetCount != 2)
    {
        Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected.\n"), "dasrt", 2, 3);
        return types::Function::Error;
    }

    // *** check type of input args and get it. ***
    // x0 = [y0, yd0]
    if (in[iPos]->isDouble() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "dasrt", iPos + 1);
        return types::Function::Error;
    }

    pDblX0 = in[iPos]->getAs<types::Double>();

    if (pDblX0->isComplex())
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "dasrt", iPos + 1);
        return types::Function::Error;
    }

    if (pDblX0->getCols() > 2)
    {
        Scierror(999, _("%s: Wrong size for input argument #%d: A real matrix with %d to %d column(s) expected.\n"), "dasrt", iPos + 1, 1, 2);
        return types::Function::Error;
    }

    if (pDblX0->getCols() == 1)
    {
        info[10] = 1;
    }

    // t0
    iPos++;
    if (in[iPos]->isDouble() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "dasrt", iPos + 1);
        return types::Function::Error;
    }

    pDblT0 = in[iPos]->getAs<types::Double>();

    if (pDblT0->isScalar() == false)
    {
        Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), "dasrt", iPos + 1);
        return types::Function::Error;
    }

    // t
    iPos++;
    if (in[iPos]->isDouble() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "dasrt", iPos + 1);
        return types::Function::Error;
    }

    pDblT = in[iPos]->getAs<types::Double>();

    if (pDblT->isComplex())
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "dasrt", iPos + 1);
        return types::Function::Error;
    }

    // get next inputs
    DifferentialEquationFunctions deFunctionsManager(L"dasrt");
    DifferentialEquation::addDifferentialEquationFunctions(&deFunctionsManager);

    YSize = (int*)MALLOC(sizeOfYSize * sizeof(int));
    *YSize = pDblX0->getRows();

    pdYData = (double*)MALLOC(*YSize * sizeof(double));
    pdYdotData = (double*)MALLOC(*YSize * sizeof(double));

    C2F(dcopy)(YSize, pDblX0->get(), &one, pdYData, &one);
    if (pDblX0->getCols() == 2)
    {
        C2F(dcopy)(YSize, pDblX0->get() + *YSize, &one, pdYdotData, &one);
    }
    else
    {
        memset(pdYdotData, 0x00, *YSize);
    }

    deFunctionsManager.setOdeYRows(pDblX0->getRows());

    for (iPos++; iPos < in.size(); iPos++)
    {
        if (in[iPos]->isDouble())
        {
            if (pDblAtol == NULL && bFuncF == false)
            {
                pDblAtol = in[iPos]->getAs<types::Double>();
                if (pDblAtol->getSize() != pDblX0->getRows() && pDblAtol->isScalar() == false)
                {
                    Scierror(267, _("%s: Wrong size for input argument #%d: A scalar or a matrix of size %d expected.\n"), "dasrt", iPos + 1, pDblX0->getRows());
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    FREE(pdYdotData);
                    FREE(pdYData);
                    FREE(YSize);
                    return types::Function::Error;
                }
            }
            else if (pDblRtol == NULL && bFuncF == false)
            {
                pDblRtol = in[iPos]->getAs<types::Double>();
                if (pDblAtol->getSize() != pDblRtol->getSize())
                {
                    Scierror(267, _("%s: Wrong size for input argument #%d: Atol and Rtol must have the same size.\n"), "dasrt", iPos + 1, pDblX0->getRows());
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    FREE(pdYdotData);
                    FREE(pdYData);
                    FREE(YSize);
                    return types::Function::Error;
                }
            }
            else if (pDblNg == NULL && bFuncF == true)
            {
                pDblNg = in[iPos]->getAs<types::Double>();
                if (pDblNg->isScalar() == false)
                {
                    Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), "dasrt", iPos + 1);
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    FREE(pdYdotData);
                    FREE(pdYData);
                    FREE(YSize);
                    return types::Function::Error;
                }
                ng = (int)pDblNg->get(0);
            }
            else if (pDblHd == NULL && bFuncF == true)
            {
                pDblHd = in[iPos]->getAs<types::Double>();
                if (in.size() != iPos + 1)
                {
                    Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "dasrt", iPos + 1);
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    FREE(pdYdotData);
                    FREE(pdYData);
                    FREE(YSize);
                    return types::Function::Error;
                }
            }
            else
            {
                Scierror(999, _("%s: Wrong type for input argument #%d: A function expected.\n"), "dasrt", iPos + 1);
                DifferentialEquation::removeDifferentialEquationFunctions();
                FREE(pdYdotData);
                FREE(pdYData);
                FREE(YSize);
                return types::Function::Error;
            }
        }
        else if (in[iPos]->isCallable())
        {
            types::Callable* pCall = in[iPos]->getAs<types::Callable>();
            if (bFuncF == false)
            {
                deFunctionsManager.setFFunction(pCall);
                bFuncF = true;
            }
            else if (bFuncJac == false && pDblNg == NULL)
            {
                deFunctionsManager.setJacFunction(pCall);
                bFuncJac = true;
            }
            else if (bFuncG == false && pDblNg)
            {
                deFunctionsManager.setGFunction(pCall);
                bFuncG = true;
            }
            else
            {
                Scierror(999, _("%s: Wrong type for input argument #%d: A matrix or a list expected.\n"), "dasrt", iPos + 1);
                DifferentialEquation::removeDifferentialEquationFunctions();
                FREE(pdYdotData);
                FREE(pdYData);
                FREE(YSize);
                return types::Function::Error;
            }
        }
        else if (in[iPos]->isString())
        {
            types::String* pStr = in[iPos]->getAs<types::String>();
            bool bOK = false;

            if (bFuncF == false)
            {
                bOK = deFunctionsManager.setFFunction(pStr);
                bFuncF = true;
            }
            else if (bFuncJac == false && pDblNg == NULL)
            {
                bOK = deFunctionsManager.setJacFunction(pStr);
                bFuncJac = true;
            }
            else if (bFuncG == false && pDblNg)
            {
                bOK = deFunctionsManager.setGFunction(pStr);
                bFuncG = true;
            }
            else
            {
                Scierror(999, _("%s: Wrong type for input argument #%d: A matrix or a list expected.\n"), "dasrt", iPos + 1);
                DifferentialEquation::removeDifferentialEquationFunctions();
                FREE(pdYdotData);
                FREE(pdYData);
                FREE(YSize);
                return types::Function::Error;
            }

            if (bOK == false)
            {
                char* pst = wide_string_to_UTF8(pStr->get(0));
                Scierror(50, _("%s: Subroutine not found: %s\n"), "dasrt", pst);
                FREE(pst);
                DifferentialEquation::removeDifferentialEquationFunctions();
                FREE(pdYdotData);
                FREE(pdYData);
                FREE(YSize);
                return types::Function::Error;
            }
        }
        else if (in[iPos]->isList())
        {
            types::List* pList = in[iPos]->getAs<types::List>();

            if (pList->getSize() == 0)
            {
                Scierror(50, _("%s: Argument #%d: Subroutine not found in list: %s\n"), "dasrt", iPos + 1, "(string empty)");
                DifferentialEquation::removeDifferentialEquationFunctions();
                FREE(pdYdotData);
                FREE(pdYData);
                FREE(YSize);
                return types::Function::Error;
            }

            if (bFuncF && bListInfo)
            {
                Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "dasrt", iPos + 1);
                DifferentialEquation::removeDifferentialEquationFunctions();
                FREE(pdYdotData);
                FREE(pdYData);
                FREE(YSize);
                return types::Function::Error;
            }

            if (pList->get(0)->isString())
            {
                types::String* pStr = pList->get(0)->getAs<types::String>();
                bool bOK = false;

                if (bFuncF == false)
                {
                    bFuncF = true;
                    bOK = deFunctionsManager.setFFunction(pStr);
                    sizeOfpdYData = *YSize;
                }
                else if (bFuncJac == false && pDblNg == NULL)
                {
                    bFuncJac = true;
                    bOK = deFunctionsManager.setJacFunction(pStr);
                    if (sizeOfpdYData == 0)
                    {
                        sizeOfpdYData = *YSize;
                    }
                }
                else if (bFuncG == false && pDblNg)
                {
                    bFuncG = true;
                    bOK = deFunctionsManager.setGFunction(pStr);
                    if (sizeOfpdYData == 0)
                    {
                        sizeOfpdYData = *YSize;
                    }
                }

                if (bOK == false)
                {
                    char* pst = wide_string_to_UTF8(pStr->get(0));
                    Scierror(50, _("%s: Argument #%d: Subroutine not found in list: %s\n"), "dasrt", iPos + 1, pst);
                    FREE(pst);
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    FREE(pdYdotData);
                    FREE(pdYData);
                    FREE(YSize);
                    return types::Function::Error;
                }

                int* sizeTemp = YSize;
                int totalSize = sizeOfpdYData;

                YSize = (int*)MALLOC((sizeOfYSize + pList->getSize() - 1) * sizeof(int));
                memcpy(YSize, sizeTemp, sizeOfYSize * sizeof(int));

                std::vector<types::Double*> vpDbl;
                for (int iter = 0; iter < pList->getSize() - 1; iter++)
                {
                    if (pList->get(iter + 1)->isDouble() == false)
                    {
                        Scierror(999, _("%s: Wrong type for input argument #%d: Argument %d in the list must be a matrix.\n"), "dasrt", iPos + 1, iter + 1);
                        DifferentialEquation::removeDifferentialEquationFunctions();
                        FREE(pdYdotData);
                        FREE(pdYData);
                        FREE(YSize);
                        return types::Function::Error;
                    }

                    vpDbl.push_back(pList->get(iter + 1)->getAs<types::Double>());
                    YSize[sizeOfYSize + iter] = vpDbl[iter]->getSize();
                    totalSize += YSize[sizeOfYSize + iter];
                }

                double* pdYDataTemp = pdYData;
                pdYData = (double*)MALLOC(totalSize * sizeof(double));
                C2F(dcopy)(&sizeOfpdYData, pdYDataTemp, &one, pdYData, &one);

                int position = sizeOfpdYData;
                for (int iter = 0; iter < pList->getSize() - 1; iter++)
                {
                    C2F(dcopy)(&YSize[sizeOfYSize + iter], vpDbl[iter]->get(), &one, &pdYData[position], &one);
                    position += vpDbl[iter]->getSize();
                }
                vpDbl.clear();
                sizeOfpdYData = totalSize;
                sizeOfYSize += pList->getSize() - 1;
                FREE(pdYDataTemp);
                FREE(sizeTemp);
            }
            else if (pList->get(0)->isCallable())
            {
                if (bFuncF == false)
                {
                    bFuncF = true;
                    deFunctionsManager.setFFunction(pList->get(0)->getAs<types::Callable>());
                    for (int iter = 1; iter < pList->getSize(); iter++)
                    {
                        deFunctionsManager.setFArgs(pList->get(iter)->getAs<types::InternalType>());
                    }
                }
                else if (bFuncJac == false && pDblNg == NULL)
                {
                    bFuncJac = true;
                    deFunctionsManager.setJacFunction(pList->get(0)->getAs<types::Callable>());
                    for (int iter = 1; iter < pList->getSize(); iter++)
                    {
                        deFunctionsManager.setJacArgs(pList->get(iter)->getAs<types::InternalType>());
                    }
                }
                else if (bFuncG == false && pDblNg)
                {
                    bFuncG = true;
                    deFunctionsManager.setGFunction(pList->get(0)->getAs<types::Callable>());
                    for (int iter = 1; iter < pList->getSize(); iter++)
                    {
                        deFunctionsManager.setGArgs(pList->get(iter)->getAs<types::InternalType>());
                    }
                }
            }
            else if (pList->get(0)->isDouble() && bFuncF == true)
            {
                if (pList->getSize() != 7)
                {
                    Scierror(267, _("%s: Wrong size for input argument #%d: A list of size %d expected.\n"), "dasrt", iPos + 1, 7);
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    FREE(pdYdotData);
                    FREE(pdYData);
                    FREE(YSize);
                    return types::Function::Error;
                }

                for (int i = 0; i < 7; i++) // info = list([],0,[],[],[],0,0)
                {
                    if (pList->get(i)->isDouble() == false || (pList->get(i)->getAs<types::Double>()->isScalar() == false && (i == 1 || i == 5 || i == 6)))
                    {
                        if (i == 1 || i == 5 || i == 6)
                        {
                            Scierror(999, _("%s: Wrong type for input argument #%d: Element %d in the info list must be a scalar.\n"), "dasrt", iPos + 1, i);
                        }
                        else
                        {
                            Scierror(999, _("%s: Wrong type for input argument #%d: Element %d in the info list must be a matrix.\n"), "dasrt", iPos + 1, i);
                        }
                        DifferentialEquation::removeDifferentialEquationFunctions();
                        FREE(pdYdotData);
                        FREE(pdYData);
                        FREE(YSize);
                        return types::Function::Error;
                    }
                }

                types::Double* pDblTemp = pList->get(0)->getAs<types::Double>();
                if (pDblTemp->getSize() != 0)
                {
                    info[3] = 1;
                    tstop = pDblTemp->get(0);
                }

                info[2] = (int)pList->get(1)->getAs<types::Double>()->get(0);

                pDblTemp = pList->get(2)->getAs<types::Double>();
                if (pDblTemp->getSize() == 2)
                {
                    info[5] = 1;
                    ml = (int)pDblTemp->get(0);
                    mu = (int)pDblTemp->get(1);
                    deFunctionsManager.setMl(ml);
                    deFunctionsManager.setMu(mu);
                }
                else if (pDblTemp->getSize() != 0)
                {
                    Scierror(267, _("%s: Wrong size for input argument #%d: Argument %d in the list must be of size %d.\n"), "dasrt", iPos + 1, 3, 2);
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    FREE(pdYdotData);
                    FREE(pdYData);
                    FREE(YSize);
                    return types::Function::Error;
                }

                pDblTemp = pList->get(3)->getAs<types::Double>();
                if (pDblTemp->getSize() != 0)
                {
                    info[6] = 1;
                    maxstep = pDblTemp->get(0);
                }

                pDblTemp = pList->get(4)->getAs<types::Double>();
                if (pDblTemp->getSize() != 0)
                {
                    info[7] = 1;
                    stepin = pDblTemp->get(0);
                }

                info[9]  = (int)pList->get(5)->getAs<types::Double>()->get(0);
                if (pList->get(6)->getAs<types::Double>()->get(0) == 1)
                {
                    info[10] = 1;
                }

                bListInfo = true;
            }
            else
            {
                Scierror(999, _("%s: Wrong type for input argument #%d: The first argument in the list must be a string, a function or a matrix in case of argument info.\n"), "dasrt", iPos + 1);
                DifferentialEquation::removeDifferentialEquationFunctions();
                FREE(pdYdotData);
                FREE(pdYData);
                FREE(YSize);
                return types::Function::Error;
            }
        }
        else
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: A matrix or a function expected.\n"), "dasrt", iPos + 1);
            DifferentialEquation::removeDifferentialEquationFunctions();
            FREE(pdYdotData);
            FREE(pdYData);
            FREE(YSize);
            return types::Function::Error;
        }
    }

    if (bFuncF == false)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "dasrt", in.size() + 3);
        DifferentialEquation::removeDifferentialEquationFunctions();
        FREE(pdYdotData);
        FREE(pdYData);
        FREE(YSize);
        return types::Function::Error;
    }

    if (pDblNg == NULL)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "dasrt", in.size() + 2);
        DifferentialEquation::removeDifferentialEquationFunctions();
        FREE(pdYdotData);
        FREE(pdYData);
        FREE(YSize);
        return types::Function::Error;
    }

    if (bFuncG == false)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "dasrt", in.size() + 1);
        DifferentialEquation::removeDifferentialEquationFunctions();
        FREE(pdYdotData);
        FREE(pdYData);
        FREE(YSize);
        return types::Function::Error;
    }

    if (bFuncJac == true)
    {
        info[4] = 1;
    }

    // *** Initialization. ***
    double t0   = pDblT0->get(0);
    double rpar = 0;
    int ipar    = 0;
    int idid    = 0;
    int maxord  = 5;

    //compute itol and set the tolerances rtol and atol.
    double* rtol = NULL;
    double* atol = NULL;

    if (pDblAtol)
    {
        if (pDblAtol->isScalar())
        {
            atol  = (double*)MALLOC(sizeof(double));
            *atol = pDblAtol->get(0);
        }
        else
        {
            atol    = pDblAtol->get();
            info[1] = 1;
        }
    }
    else
    {
        atol  = (double*)MALLOC(sizeof(double));
        *atol = 1.e-7;
    }

    if (pDblRtol)
    {
        if (pDblRtol->isScalar())
        {
            rtol  = (double*)MALLOC(sizeof(double));
            *rtol = pDblRtol->get(0);
        }
        else
        {
            rtol = pDblRtol->get();
        }
    }
    else // if rtol is not given atol will be used as a scalar.
    {
        if (pDblAtol && pDblAtol->isScalar() == false) // info[1] == 1
        {
            double dblSrc = 1.e-9;
            int iSize = pDblAtol->getSize();
            int iOne = 1;
            int iZero = 0;

            rtol = (double*)MALLOC(iSize * sizeof(double));
            C2F(dcopy)(&iSize, &dblSrc, &iZero, rtol, &iOne);
        }
        else
        {
            rtol    = (double*)MALLOC(sizeof(double));
            *rtol   = 1.e-9;
        }
    }

    // Compute rwork, iwork size.
    // Create them.
    int iworksize   = 20 + pDblX0->getRows();
    int rworksize   = 0;
    int* iwork      = NULL;
    double* rwork   = NULL;
    int* root    = NULL;

    if (info[5] == 0)
    {
        rworksize = 50 + (maxord + 4) * pDblX0->getRows() + pDblX0->getRows() * pDblX0->getRows() + 3 * ng;
    }
    else if (info[4] == 1)
    {
        rworksize = 50 + (maxord + 4) * pDblX0->getRows() + (2 * ml + mu + 1) * pDblX0->getRows() + 3 * ng;
    }
    else if (info[4] == 0)
    {
        rworksize = 50 + (maxord + 4) * pDblX0->getRows() + (2 * ml + mu + 1) * pDblX0->getRows() + 2 * (pDblX0->getRows() / (ml + mu + 1) + 1) + 3 * ng;
    }

    iwork = (int*)MALLOC(iworksize * sizeof(int));
    rwork = (double*)MALLOC(rworksize * sizeof(double));
    root  = (int*)MALLOC(ng * sizeof(int));

    if (pDblHd != NULL)
    {
        if (iworksize + rworksize != pDblHd->getSize())
        {
            Scierror(77, _("%s: Wrong size for input argument(s) %d: %d expected.\n"), "dasrt", in.size(), iworksize + rworksize);
            DifferentialEquation::removeDifferentialEquationFunctions();
            FREE(pdYdotData);
            FREE(pdYData);
            FREE(YSize);
            FREE(iwork);
            FREE(rwork);
            FREE(root);
            if (pDblAtol == NULL || pDblAtol->isScalar())
            {
                FREE(atol);
            }
            if (pDblRtol == NULL || pDblRtol->isScalar())
            {
                FREE(rtol);
            }
            return types::Function::Error;
        }

        C2F(dcopy)(&rworksize, pDblHd->get(), &one, rwork, &one);

        for (int i = 0; i < iworksize; i++)
        {
            iwork[i] = (int)pDblHd->get(rworksize + i);
        }

        info[0] = 1;
    }

    if (info[3] == 1)
    {
        rwork[0] = tstop;
    }

    if (info[6] == 1)
    {
        rwork[1] = maxstep;
    }

    if (info[7] == 1)
    {
        rwork[2] = stepin;
    }

    if (info[5] == 1)
    {
        iwork[0] = ml;
        iwork[1] = mu;
    }

    // *** Perform operation. ***
    std::list<types::Double*> lpDblOut;
    int size = pDblX0->getRows();
    int rowsOut = 1 + pDblX0->getRows() * 2;
    int iret = 0;

    for (int i = 0; i < pDblT->getSize(); i++)
    {
        types::Double* pDblOut = new types::Double(rowsOut, 1);
        lpDblOut.push_back(pDblOut);

        double t = pDblT->get(i);
        int pos  = 0;
        pDblOut->set(pos, t);

        if (t == t0)
        {
            pos++;
            C2F(dcopy)(&size, pdYData, &one, pDblOut->get() + pos, &one);
            pos += pDblX0->getRows();
            C2F(dcopy)(&size, pdYdotData, &one, pDblOut->get() + pos, &one);

            continue;
        }

        try
        {
            C2F(ddasrt)(dassl_f, YSize, &t0, pdYData, pdYdotData, &t, info, rtol, atol, &idid, rwork, &rworksize, iwork, &iworksize, &rpar, &ipar, dassl_jac, dasrt_g, &ng, root);
            iret = checkError(idid, "dasrt");
            if (iret == 1) // error
            {
                Scierror(999, _("%s: %s return with state %d.\n"), "dasrt", "ddasrt", idid);
            }
        }
        catch (ast::InternalError &ie)
        {
            os << ie.GetErrorMessage();
            bCatch = true;
            iret = 1;
        }

        if (iret == 1)
        {
            lpDblOut.clear();
            DifferentialEquation::removeDifferentialEquationFunctions();
            FREE(pdYdotData);
            FREE(pdYData);
            FREE(YSize);
            FREE(iwork);
            FREE(rwork);
            FREE(root);
            if (pDblAtol == NULL || pDblAtol->isScalar())
            {
                FREE(atol);
            }
            if (pDblRtol == NULL || pDblRtol->isScalar())
            {
                FREE(rtol);
            }

            if (bCatch)
            {
                wchar_t szError[bsiz];
                os_swprintf(szError, bsiz, _W("%ls: An error occured in '%ls' subroutine.\n").c_str(), L"dasrt", L"ddasrt");
                os << szError;
                throw ast::InternalError(os.str());
            }

            return types::Function::Error;
        }

        pos++;
        C2F(dcopy)(&size, pdYData, &one, pDblOut->get() + pos, &one);
        pos += size;
        C2F(dcopy)(&size, pdYdotData, &one, pDblOut->get() + pos, &one);

        if (iret == 2) // warning
        {
            pDblOut->set(0, t0);
            break;
        }

        // iret == 0
        if (idid == 1)
        {
            pDblOut->set(0, t0);
            i--;
        }
        else if (idid == -2)
        {
            t0 = t;
            i--;
        }
        else
        {
            t0 = t;
        }

        info[0] = 1;
    }

    // *** Return result in Scilab. ***
    types::Double* pDblOut = new types::Double(rowsOut, (int)lpDblOut.size());

    int sizeOfList = (int)lpDblOut.size();
    for (int i = 0; i < sizeOfList; i++)
    {
        int pos = i * rowsOut;
        C2F(dcopy)(&rowsOut, lpDblOut.front()->get(), &one, pDblOut->get() + pos, &one);
        lpDblOut.pop_front();
    }
    out.push_back(pDblOut);


    int sizeOfRoot = 1;
    for (int i = 0; i < ng; i++)
    {
        if (root[i])
        {
            sizeOfRoot++;
        }
    }
    types::Double* pDblRoot = new types::Double(1, sizeOfRoot);
    pDblRoot->set(0, t0);
    int j = 0;
    for (int i = 0; i < ng; i++)
    {
        if (root[i])
        {
            j++;
            pDblRoot->set(j, i + 1);
        }
    }
    out.push_back(pDblRoot);

    if (_iRetCount == 3)
    {
        types::Double* pDblHdOut = new types::Double(rworksize + iworksize, 1);
        C2F(dcopy)(&rworksize, rwork, &one, pDblHdOut->get(), &one);

        for (int i = 0; i < iworksize; i++)
        {
            pDblHdOut->set(rworksize + i, (double)iwork[i]);
        }

        out.push_back(pDblHdOut);
    }

    // *** FREE. ***
    if (pDblAtol == NULL || pDblAtol->isScalar())
    {
        FREE(atol);
    }

    if (pDblRtol == NULL || pDblRtol->isScalar())
    {
        FREE(rtol);
    }

    FREE(pdYData);
    FREE(pdYdotData);
    FREE(YSize);
    FREE(rwork);
    FREE(iwork);
    FREE(root);

    DifferentialEquation::removeDifferentialEquationFunctions();

    return types::Function::OK;
}
Exemplo n.º 8
0
bool Variable::put(types::InternalType* _pIT, int _iLevel)
{
    if (isGlobal() && isGlobalVisible(_iLevel))
    {
        setGlobalValue(_pIT);
        return true;
    }

    if (empty() || top()->m_iLevel < _iLevel)
    {
        //create a new level
        last = new ScopedVariable(_iLevel, _pIT);
        stack.push(last);
        _pIT->IncreaseRef();
    }
    else
    {
        //update current level
        types::InternalType* pIT = top()->m_pIT;
        if (pIT != _pIT)
        {
            //check macro redefinition
            if (_pIT->isMacro())
            {
                int iFuncProt = ConfigVariable::getFuncprot();
                if (iFuncProt != 0)
                {
                    bool bEquals = true;
                    if (pIT && pIT->isCallable())
                    {
                        if (pIT->isMacroFile())
                        {
                            types::MacroFile* pMF = pIT->getAs<types::MacroFile>();
                            bEquals = *pMF->getMacro() == *_pIT;
                        }
                        else if (pIT->isMacro())
                        {
                            types::Macro* pM = pIT->getAs<types::Macro>();
                            bEquals = *pM == *_pIT;
                        }
                    }

                    if (bEquals == false)
                    {
                        if (iFuncProt == 2)
                        {
                            return false;
                        }

                        if (ConfigVariable::getWarningMode())
                        {
                            wchar_t pwstFuncName[1024];
                            os_swprintf(pwstFuncName, 1024, L"%-24ls", name.getName().c_str());
                            char* pstFuncName = wide_string_to_UTF8(pwstFuncName);

                            sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
                            sciprint("\n");
                            FREE(pstFuncName);
                        }
                    }
                }
            }

            // _pIT may contained in pIT
            // so increases ref of _pIT before kill pIT
            top()->m_pIT = _pIT;
            _pIT->IncreaseRef();
            pIT->DecreaseRef();
            pIT->killMe();
        }
    }

    return true;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
/*--------------------------------------------------------------------------*/
types::Function::ReturnValue sci_mcisendstring(types::typed_list &in, int _iRetCount, types::typed_list &out)
{
    std::wstring param1;
    types::String* pS = nullptr;

    int out2 = 0;
    std::wstring out3(L"OK");

    wchar_t output[2048];

    if (in.size() != 1)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), fname.data(), 1);
        return types::Function::Error;
    }

    if (_iRetCount < 1 || _iRetCount > 3)
    {
        Scierror(999, _("%s: Wrong number of output arguments: %d to %d expected.\n"), fname.data(), 1, 3);
        return types::Function::Error;
    }


    if (in[0]->isString() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), fname.data(), 1);
        return types::Function::Error;
    }

    pS = in[0]->getAs<types::String>();
    if (pS->isScalar() == false)
    {
        Scierror(999, _("%s: Wrong size for input argument #%d: String expected.\n"), fname.data(), 1);
        return types::Function::Error;
    }

    param1 = pS->get()[0];
    char* test = wide_string_to_UTF8(param1.data());
    char tout[2048];
    MCIERROR err = mciSendString(test, tout, sizeof(tout), NULL);
    out2 = (int)err;
    if (err)
    {
        wchar_t errtxt[128];

        if (mciGetErrorStringW(err, errtxt, 128) == FALSE)
        {
            os_swprintf(errtxt, L"%ls", L"Unknown MCI error");
        }

        out3 = errtxt;

        out.push_back(types::Bool::False());
    }
    else
    {
        out.push_back(types::Bool::True());
    }

    if (_iRetCount > 1)
    {
        out.push_back(new types::Double(out2));
    }

    if (_iRetCount > 2)
    {
        out.push_back(new types::String(out3.data()));
    }
    return types::Function::OK;
}
Exemplo n.º 11
0
//windows : find main DLL and extract path
//linux and macos : scilab script fill SCI env variable
char* computeTMPDIR()
{
#ifdef _MSC_VER
    wchar_t wcTmpDirDefault[PATH_MAX];

    if (!GetTempPathW(PATH_MAX, wcTmpDirDefault))
    {
        MessageBoxA(NULL, _("Cannot find Windows temporary directory (1)."), _("Error"), MB_ICONERROR);
        exit(1);
    }
    else
    {
        wchar_t wctmp_dir[PATH_MAX + FILENAME_MAX + 1];
        static wchar_t bufenv[PATH_MAX + 16];
        char *TmpDir = NULL;
        os_swprintf(wctmp_dir, PATH_MAX + FILENAME_MAX + 1, L"%lsSCI_TMP_%d_", wcTmpDirDefault, _getpid());
        if (CreateDirectoryW(wctmp_dir, NULL) == FALSE)
        {
            DWORD attribs = GetFileAttributesW(wctmp_dir);
            if (attribs & FILE_ATTRIBUTE_DIRECTORY)
            {
                /* Repertoire existant */
            }
            else
            {
#ifdef _DEBUG
                {
                    char MsgErr[1024];
                    wsprintfA(MsgErr, _("Impossible to create : %s"), wctmp_dir);
                    MessageBoxA(NULL, MsgErr, _("Error"), MB_ICONERROR);
                    exit(1);
                }
#else
                {
                    GetTempPathW(PATH_MAX, wcTmpDirDefault);
                    wcscpy(wctmp_dir, wcTmpDirDefault);
                    wctmp_dir[wcslen(wctmp_dir) - 1] = '\0'; /* Remove last \ */
                }
#endif
            }
        }

        os_swprintf(bufenv, PATH_MAX + 16, L"TMPDIR=%ls", wctmp_dir);
        _wputenv(bufenv);

        TmpDir = wide_string_to_UTF8(wctmp_dir);
        if (TmpDir)
        {
            return TmpDir;
        }
        else
        {
            return NULL;
        }
    }
    return NULL;
#else
    char *tmpdir;

    char* env_dir = (char*)MALLOC(sizeof(char) * (PATH_MAX + 16));
    /* If the env variable TMPDIR is set, honor this preference */
    tmpdir = getenv("TMPDIR");
    if (tmpdir != NULL && strlen(tmpdir) < (PATH_MAX) && strstr(tmpdir, "SCI_TMP_") == NULL)
    {
        strcpy(env_dir, tmpdir);
    }
    else
    {
        strcpy(env_dir, "/tmp");
    }

    /* XXXXXX will be randomized by mkdtemp */
    char *env_dir_strdup = os_strdup(env_dir); /* Copy to avoid to have the same buffer as input and output for sprintf */
    sprintf(env_dir, "%s/SCI_TMP_%d_XXXXXX", env_dir_strdup, (int)getpid());
    free(env_dir_strdup);

    if (mkdtemp(env_dir) == NULL)
    {
        fprintf(stderr, _("Error: Could not create %s: %s\n"), env_dir, strerror(errno));
    }

    setenvc("TMPDIR", env_dir);
    return env_dir;
#endif
}
Exemplo n.º 12
0
Callable::ReturnValue DynamicFunction::Init()
{
    /*Load library*/
    if (m_wstLibName.empty())
    {
        Scierror(999, _("%s: Library name must not be empty\n."), m_wstName.c_str());
        return Error;
    }

    DynLibHandle hLib = getDynModule(m_wstLibName.c_str());
    if (hLib == 0)
    {
        char* pstLibName = wide_string_to_UTF8(m_wstLibName.c_str());
        hLib = LoadDynLibrary(pstLibName);

        if (hLib == 0)
        {
            //2nd chance for linux !
#ifndef _MSC_VER
            char* pstError = strdup(GetLastDynLibError());

            /* Haven't been able to find the lib with dlopen...
            * This can happen for two reasons:
            * - the lib must be dynamically linked
            * - Some silly issues under Suse (see bug #2875)
            * Note that we are handling only the "source tree build"
            * because libraries are split (they are in the same directory
            * in the binary)
            */
            wchar_t* pwstScilabPath = getSCIW();
            wchar_t pwstModulesPath[] = L"/modules/";
            wchar_t pwstLTDir[] =  L".libs/";

            /* Build the full path to the library */
            int iPathToLibLen = (wcslen(pwstScilabPath) + wcslen(pwstModulesPath) + wcslen(m_wstModule.c_str()) + wcslen(L"/") + wcslen(pwstLTDir) + wcslen(m_wstLibName.c_str()) + 1);
            wchar_t* pwstPathToLib = (wchar_t*)MALLOC(iPathToLibLen * sizeof(wchar_t));
            os_swprintf(pwstPathToLib, iPathToLibLen, L"%ls%ls%ls/%ls%ls", pwstScilabPath, pwstModulesPath, m_wstModule.c_str(), pwstLTDir, m_wstLibName.c_str());
            FREE(pwstScilabPath);
            char* pstPathToLib = wide_string_to_UTF8(pwstPathToLib);
            FREE(pwstPathToLib);
            hLib = LoadDynLibrary(pstPathToLib);

            if (hLib == 0)
            {
                Scierror(999, _("An error has been detected while loading %s: %s\n"), pstLibName, pstError);
                FREE(pstError);

                pstError = GetLastDynLibError();
                Scierror(999, _("An error has been detected while loading %s: %s\n"), pstPathToLib, pstError);

                FREE(pstLibName);
                FREE(pstPathToLib);
                return Error;
            }
            FREE(pstPathToLib);
            FREE(pstError);
#else
            char* pstError = wide_string_to_UTF8(m_wstLibName.c_str());
            Scierror(999, _("Impossible to load %s library\n"), pstError);
            FREE(pstError);
            FREE(pstLibName);
            return Error;
#endif
        }
        FREE(pstLibName);
        addDynModule(m_wstLibName.c_str(), hLib);

        /*Load deps*/
        if (m_wstLoadDepsName.empty() == false && m_pLoadDeps == NULL)
        {
            char* pstLoadDepsName = wide_string_to_UTF8(m_wstLoadDepsName.c_str());
            m_pLoadDeps = (LOAD_DEPS)GetDynLibFuncPtr(hLib, pstLoadDepsName);
            FREE(pstLoadDepsName);
        }

    }

    /*Load gateway*/
    if (m_wstName != L"")
    {
        char* pstEntryPoint = wide_string_to_UTF8(m_wstEntryPoint.c_str());
        switch (m_iType)
        {
            case EntryPointCPPOpt :
                m_pOptFunc = (GW_FUNC_OPT)GetDynLibFuncPtr(hLib, pstEntryPoint);
                break;
            case EntryPointCPP :
                m_pFunc = (GW_FUNC)GetDynLibFuncPtr(hLib, pstEntryPoint);
                break;
            case EntryPointOldC :
                m_pOldFunc = (OLDGW_FUNC)GetDynLibFuncPtr(hLib, pstEntryPoint);
                break;
            case EntryPointMex:
                m_pMexFunc = (MEXGW_FUNC)GetDynLibFuncPtr(hLib, pstEntryPoint);
                break;
            case EntryPointC:
                m_pCFunc = (GW_C_FUNC)GetDynLibFuncPtr(hLib, pstEntryPoint);
                break;
        }

        FREE(pstEntryPoint);
    }

    if (m_pFunc == NULL && m_pOldFunc == NULL && m_pMexFunc == NULL && m_pOptFunc == NULL && m_pCFunc == NULL)
    {
        char* pstEntry = wide_string_to_UTF8(m_wstEntryPoint.c_str());
        char* pstLib = wide_string_to_UTF8(m_wstLibName.c_str());
        Scierror(999, _("Impossible to load %s function in %s library: %s\n"), pstEntry, pstLib, GetLastDynLibError());
        FREE(pstEntry);
        FREE(pstLib);
        return Error;
    }

    switch (m_iType)
    {
        case EntryPointCPPOpt :
            m_pFunction = new OptFunction(m_wstName, m_pOptFunc, m_pLoadDeps, m_wstModule);
            break;
        case EntryPointCPP :
            m_pFunction = new Function(m_wstName, m_pFunc, m_pLoadDeps, m_wstModule);
            break;
        case EntryPointOldC :
            m_pFunction = new WrapFunction(m_wstName, m_pOldFunc, m_pLoadDeps, m_wstModule);
            break;
        case EntryPointMex:
            m_pFunction = new WrapMexFunction(m_wstName, m_pMexFunc, m_pLoadDeps, m_wstModule);
            break;
        case EntryPointC:
            m_pFunction = new WrapCFunction(m_wstName, m_pCFunc, m_pLoadDeps, m_wstModule);
            break;
    }

    if (m_pFunction == NULL)
    {
        return Error;
    }
    return OK;
}
Exemplo n.º 13
0
/** \brief parse the given file command */
void ParserSingleInstance::parse(const char *command)
{
    size_t len = strlen(command);

    yylloc.first_line = yylloc.last_line = 1;
    yylloc.first_column = yylloc.last_column = 1;
#ifdef _MSC_VER
    char szFile[MAX_PATH];
    char* pstTmpDIr = getTMPDIR();
    os_sprintf(szFile, "%s\\%s", pstTmpDIr, "command.temp");
    FREE(pstTmpDIr);
    if (fileLocker)
    {
        fclose(fileLocker);
    }

    errno_t err;
    err = fopen_s(&yyin, szFile, "w");
    if (err)
    {
        ParserSingleInstance::setExitStatus(Parser::Failed);
        ParserSingleInstance::resetErrorMessage();
        wchar_t szError[bsiz];
        wchar_t* wszFile = to_wide_string(szFile);
        os_swprintf(szError, bsiz, _W("%ls: Cannot open file %ls.\n").c_str(), L"parser", wszFile);
        FREE(wszFile);
        appendErrorMessage(szError);
        return;
    }

    fwrite(command, sizeof(char), len, yyin);
    fclose(yyin);
    fopen_s(&yyin, szFile, "r");
#endif

#ifdef __APPLE__
    char szFile[PATH_MAX];
    char* pstTmpDIr = "/tmp";
    sprintf(szFile, "%s/%s", getTMPDIR(), "command.temp");
    //FREE(pstTmpDIr);
    if (fileLocker)
    {
        fclose(fileLocker);
    }
    yyin = fopen(szFile, "w");
    fwrite(command, 1, len, yyin);
    fclose(yyin);
    yyin = fopen(szFile, "r");
#endif


#ifndef _MSC_VER
#ifndef __APPLE__
    yyin = fmemopen((void*)command, len, "r");
#endif
#endif

    ParserSingleInstance::disableStrictMode();
    ParserSingleInstance::setFileName(L"prompt");
    ParserSingleInstance::setTree(nullptr);
    ParserSingleInstance::setExitStatus(Parser::Succeded);
    ParserSingleInstance::resetControlStatus();
    ParserSingleInstance::resetErrorMessage();

    yyparse();

    fclose(yyin);
#ifdef _MSC_VER
    DeleteFileA(szFile);
#endif

#ifdef _MSC_VER
    //reopen a file to prevents max file opened.
    fopen_s(&fileLocker, szFile, "w");
#endif
#ifdef __APPLE__
    fileLocker = fopen(szFile, "w");
#endif
}
Exemplo n.º 14
0
types::Function::ReturnValue sci_impl(types::typed_list &in, int _iRetCount, types::typed_list &out)
{
    // Methode
    types::String* pStrType     = NULL;
    const wchar_t * wcsType     = L"lsoda";
    int meth                    = 2;// default methode is stiff

    // y0
    types::Double* pDblY0       = NULL;
    double* pdYData             = NULL; // contain y0 following by all args data in list case.
    int sizeOfpdYData           = 0;

    // Other input args
    types::Double* pDblYdot0    = NULL;
    types::Double* pDblT0       = NULL;
    types::Double* pDblT        = NULL;
    types::Double* pDblRtol     = NULL;
    types::Double* pDblAtol     = NULL;
    types::Double* pDblW        = NULL;
    types::Double* pDblIw       = NULL;

    // Result
    types::Double* pDblYOut     = NULL;

    // Indicate if the function is given.
    bool bFuncF     = false; // res
    bool bFuncJac   = false; // jac
    bool bFuncG     = false; // adda

    int iPos        = 0; // Position in types::typed_list in
    int maxord      = 5; // maxord = 12 (if meth = 1) or 5 (if meth = 2)

    int sizeOfYSize = 1;
    int* YSize      = NULL;    // YSize(1) = size of y0,
    // YSize(n) = size of Args(n) in list case.

    C2F(eh0001).mesflg  = 1; // flag to control printing of error messages in lapack routine.
    // 1 means print, 0 means no printing.
    C2F(eh0001).lunit   = 6; // 6 = stdout

    int one = 1; // use in dcopy

    // error message catched
    std::wostringstream os;
    bool bCatch = false;

    // *** check the minimal number of input args. ***
    if (in.size() < 6 || in.size() > 12)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "impl", 6, 12);
        return types::Function::Error;
    }

    // *** check number of output args ***
    if (_iRetCount > 3 || _iRetCount == 2)
    {
        Scierror(78, _("%s: Wrong number of output argument(s): %d or %d expected.\n"), "impl", 1, 3);
        return types::Function::Error;
    }

    // *** Get the methode. ***
    if (in[0]->isString())
    {
        pStrType = in[0]->getAs<types::String>();
        wcsType = pStrType->get(0);
        iPos++;
    }

    if (iPos)
    {
        if (wcscmp(wcsType, L"adams") == 0)
        {
            meth = 1;
            maxord = 12;
        }
        else if (wcscmp(wcsType, L"stiff") == 0)
        {
            meth = 2;
        }
        else
        {
            Scierror(999, _("%s: Wrong value for input argument #%d: It must be one of the following strings: adams or stiff.\n"), "impl", 1);
            return types::Function::Error;
        }
    }

    // *** check type of input args and get it. ***
    // y0
    if (in[iPos]->isDouble() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "impl", iPos + 1);
        return types::Function::Error;
    }

    pDblY0 = in[iPos]->getAs<types::Double>();

    if (pDblY0->isComplex())
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "impl", iPos + 1);
        return types::Function::Error;
    }

    if (pDblY0->getCols() != 1 && pDblY0->getRows() != 1)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A real vector expected.\n"), "impl", iPos + 1);
        return types::Function::Error;
    }

    // ydot0
    iPos++;
    if (in[iPos]->isDouble() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "impl", iPos + 1);
        return types::Function::Error;
    }

    pDblYdot0 = in[iPos]->getAs<types::Double>();

    if (pDblYdot0->isComplex())
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "impl", iPos + 1);
        return types::Function::Error;
    }

    if (pDblYdot0->getCols() != 1 && pDblYdot0->getRows() != 1)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A real vector expected.\n"), "impl", iPos + 1);
        return types::Function::Error;
    }

    // t0
    iPos++;
    if (in[iPos]->isDouble() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "impl", iPos + 1);
        return types::Function::Error;
    }

    pDblT0 = in[iPos]->getAs<types::Double>();

    if (pDblT0->isScalar() == false)
    {
        Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), "impl", iPos + 1);
        return types::Function::Error;
    }

    // t
    iPos++;
    if (in[iPos]->isDouble() == false)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "impl", iPos + 1);
        return types::Function::Error;
    }

    pDblT = in[iPos]->getAs<types::Double>();

    // get next inputs
    DifferentialEquationFunctions deFunctionsManager(L"impl");
    DifferentialEquation::addDifferentialEquationFunctions(&deFunctionsManager);

    YSize = (int*)malloc(sizeOfYSize * sizeof(int));
    *YSize = pDblY0->getSize();
    pdYData = (double*)malloc(pDblY0->getSize() * sizeof(double));
    C2F(dcopy)(YSize, pDblY0->get(), &one, pdYData, &one);

    for (iPos++; iPos < in.size(); iPos++)
    {
        if (in[iPos]->isDouble())
        {
            if (pDblAtol == NULL && bFuncF == false)
            {
                pDblAtol = in[iPos]->getAs<types::Double>();
                if (pDblAtol->getSize() != pDblY0->getSize() && pDblAtol->isScalar() == false)
                {
                    Scierror(267, _("%s: Arg %d and arg %d must have equal dimensions.\n"), "impl", pStrType ? 2 : 1, iPos + 1);
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    free(pdYData);
                    free(YSize);
                    return types::Function::Error;
                }
            }
            else if (pDblRtol == NULL && bFuncF == false)
            {
                pDblRtol = in[iPos]->getAs<types::Double>();
                if (pDblRtol->getSize() != pDblY0->getSize() && pDblRtol->isScalar() == false)
                {
                    Scierror(267, _("%s: Arg %d and arg %d must have equal dimensions.\n"), "impl", pStrType ? 2 : 1, iPos + 1);
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    free(pdYData);
                    free(YSize);
                    return types::Function::Error;
                }
            }
            else if (pDblW == NULL && bFuncG == true)
            {
                if (in.size() == iPos + 2)
                {
                    if (in[iPos + 1]->isDouble() == false)
                    {
                        Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "impl", iPos + 2);
                        DifferentialEquation::removeDifferentialEquationFunctions();
                        free(pdYData);
                        free(YSize);
                        return types::Function::Error;
                    }

                    pDblW = in[iPos]->getAs<types::Double>();
                    pDblIw = in[iPos + 1]->getAs<types::Double>();
                    iPos++;
                }
                else
                {
                    Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "impl", iPos + 2);
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    free(pdYData);
                    free(YSize);
                    return types::Function::Error;
                }
            }
            else
            {
                Scierror(999, _("%s: Wrong type for input argument #%d: A function expected.\n"), "impl", iPos + 1);
                DifferentialEquation::removeDifferentialEquationFunctions();
                free(pdYData);
                free(YSize);
                return types::Function::Error;
            }
        }
        else if (in[iPos]->isCallable())
        {
            types::Callable* pCall = in[iPos]->getAs<types::Callable>();
            if (bFuncF == false)
            {
                deFunctionsManager.setFFunction(pCall);
                bFuncF = true;
            }
            else if (bFuncG == false)
            {
                deFunctionsManager.setGFunction(pCall);
                bFuncG = true;
            }
            else if (bFuncJac == false)
            {
                deFunctionsManager.setJacFunction(pCall);
                bFuncJac = true;
            }
            else
            {
                Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "impl", iPos + 1);
                DifferentialEquation::removeDifferentialEquationFunctions();
                free(pdYData);
                free(YSize);
                return types::Function::Error;
            }
        }
        else if (in[iPos]->isString())
        {
            types::String* pStr = in[iPos]->getAs<types::String>();
            bool bOK = false;

            if (bFuncF == false)
            {
                bOK = deFunctionsManager.setFFunction(pStr);
                bFuncF = true;
            }
            else if (bFuncG == false)
            {
                bOK = deFunctionsManager.setGFunction(pStr);
                bFuncG = true;
            }
            else if (bFuncJac == false)
            {
                bOK = deFunctionsManager.setJacFunction(pStr);
                bFuncJac = true;
            }
            else
            {
                Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "impl", iPos + 1);
                DifferentialEquation::removeDifferentialEquationFunctions();
                free(pdYData);
                free(YSize);
                return types::Function::Error;
            }

            if (bOK == false)
            {
                char* pst = wide_string_to_UTF8(pStr->get(0));
                Scierror(50, _("%s: Subroutine not found: %s\n"), "impl", pst);
                FREE(pst);
                DifferentialEquation::removeDifferentialEquationFunctions();
                free(pdYData);
                free(YSize);
                return types::Function::Error;
            }
        }
        else if (in[iPos]->isList())
        {
            types::List* pList = in[iPos]->getAs<types::List>();

            if (pList->getSize() == 0)
            {
                Scierror(50, _("%s: Argument #%d: Subroutine not found in list: %s\n"), "impl", iPos + 1, "(string empty)");
                DifferentialEquation::removeDifferentialEquationFunctions();
                free(pdYData);
                free(YSize);
                return types::Function::Error;
            }

            if (bFuncF && bFuncG && bFuncJac)
            {
                Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), "impl", iPos + 1);
                DifferentialEquation::removeDifferentialEquationFunctions();
                free(pdYData);
                free(YSize);
                return types::Function::Error;
            }

            if (pList->get(0)->isString())
            {
                types::String* pStr = pList->get(0)->getAs<types::String>();
                bool bOK = false;

                if (bFuncF == false)
                {
                    bFuncF = true;
                    bOK = deFunctionsManager.setFFunction(pStr);
                    sizeOfpdYData = *YSize;
                }
                else if (bFuncG == false)
                {
                    bFuncG = true;
                    bOK = deFunctionsManager.setGFunction(pStr);
                    if (sizeOfpdYData == 0)
                    {
                        sizeOfpdYData = *YSize;
                    }
                }
                else if (bFuncJac == false)
                {
                    bFuncJac = true;
                    bOK = deFunctionsManager.setJacFunction(pStr);
                    if (sizeOfpdYData == 0)
                    {
                        sizeOfpdYData = *YSize;
                    }
                }

                if (bOK == false)
                {
                    char* pst = wide_string_to_UTF8(pStr->get(0));
                    Scierror(50, _("%s: Argument #%d: Subroutine not found in list: %s\n"), "impl", iPos + 1, pst);
                    FREE(pst);
                    DifferentialEquation::removeDifferentialEquationFunctions();
                    free(pdYData);
                    free(YSize);
                    return types::Function::Error;
                }

                int* sizeTemp = YSize;
                int totalSize = sizeOfpdYData;

                YSize = (int*)malloc((sizeOfYSize + pList->getSize() - 1) * sizeof(int));
                memcpy(YSize, sizeTemp, sizeOfYSize * sizeof(int));

                std::vector<types::Double*> vpDbl;
                for (int iter = 0; iter < pList->getSize() - 1; iter++)
                {
                    if (pList->get(iter + 1)->isDouble() == false)
                    {
                        Scierror(999, _("%s: Wrong type for input argument #%d: Argument %d in the list must be a matrix.\n"), "impl", iPos + 1, iter + 1);
                        DifferentialEquation::removeDifferentialEquationFunctions();
                        free(pdYData);
                        free(YSize);
                        return types::Function::Error;
                    }

                    vpDbl.push_back(pList->get(iter + 1)->getAs<types::Double>());
                    YSize[sizeOfYSize + iter] = vpDbl[iter]->getSize();
                    totalSize += YSize[sizeOfYSize + iter];
                }

                double* pdYDataTemp = pdYData;
                pdYData = (double*)malloc(totalSize * sizeof(double));
                C2F(dcopy)(&sizeOfpdYData, pdYDataTemp, &one, pdYData, &one);

                int position = sizeOfpdYData;
                for (int iter = 0; iter < pList->getSize() - 1; iter++)
                {
                    C2F(dcopy)(&YSize[sizeOfYSize + iter], vpDbl[iter]->get(), &one, &pdYData[position], &one);
                    position += vpDbl[iter]->getSize();
                }
                vpDbl.clear();
                sizeOfpdYData = totalSize;
                sizeOfYSize += pList->getSize() - 1;
                free(pdYDataTemp);
                free(sizeTemp);
            }
            else if (pList->get(0)->isCallable())
            {
                if (bFuncF == false)
                {
                    bFuncF = true;
                    deFunctionsManager.setFFunction(pList->get(0)->getAs<types::Callable>());
                    for (int iter = 1; iter < pList->getSize(); iter++)
                    {
                        deFunctionsManager.setFArgs(pList->get(iter)->getAs<types::InternalType>());
                    }
                }
                else if (bFuncG == false)
                {
                    bFuncG = true;
                    deFunctionsManager.setGFunction(pList->get(0)->getAs<types::Callable>());
                    for (int iter = 1; iter < pList->getSize(); iter++)
                    {
                        deFunctionsManager.setGArgs(pList->get(iter)->getAs<types::InternalType>());
                    }
                }
                else if (bFuncJac == false)
                {
                    bFuncJac = true;
                    deFunctionsManager.setJacFunction(pList->get(0)->getAs<types::Callable>());
                    for (int iter = 1; iter < pList->getSize(); iter++)
                    {
                        deFunctionsManager.setJacArgs(pList->get(iter)->getAs<types::InternalType>());
                    }
                }
            }
            else
            {
                Scierror(999, _("%s: Wrong type for input argument #%d: The first argument in the list must be a string or a function.\n"), "impl", iPos + 1);
                DifferentialEquation::removeDifferentialEquationFunctions();
                free(pdYData);
                free(YSize);
                return types::Function::Error;
            }
        }
        else
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: A matrix or a function expected.\n"), "impl", iPos + 1);
            DifferentialEquation::removeDifferentialEquationFunctions();
            free(pdYData);
            free(YSize);
            return types::Function::Error;
        }
    }

    if (bFuncF == false)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "impl", in.size() + 1);
        DifferentialEquation::removeDifferentialEquationFunctions();
        free(pdYData);
        free(YSize);
        return types::Function::Error;
    }

    if (bFuncG == false)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "impl", in.size() + 1);
        DifferentialEquation::removeDifferentialEquationFunctions();
        free(pdYData);
        free(YSize);
        return types::Function::Error;
    }

    // *** Initialization. ***
    double t0   = pDblT0->get(0);
    int itol    = 1;
    int iopt    = 0;
    int istate  = 1;
    int itask   = 1;
    int jt = bFuncJac ? 1 : 2;
    int jacType = 10 * meth + jt;

    pDblYOut = new types::Double(pDblY0->getRows(), pDblT->getSize());

    // work tab
    double* rwork   = NULL;
    int* iwork      = NULL;
    int rworkSize   = 0;
    int iworkSize   = 0;

    // contain ls0001, lsa001 and eh0001 structures
    double* dStructTab  = NULL;
    int* iStructTab     = NULL;
    int dStructTabSize  = 219;  // number of double in ls0001
    int iStructTabSize  = 41;   // number of int in ls0001 (39) + eh0001 (2)

    int rwSize  = 0; // rwSize = dStructTab + rworkSize
    int iwSize  = 0; // iwSize = iStructTab + iworkSize

    // structures used by lsoda and lsode
    double* ls0001d = &(C2F(ls0001).tret);
    int* ls0001i    = &(C2F(ls0001).illin);
    int* eh0001i    = &(C2F(eh0001).mesflg);

    //compute itol and set the tolerances rtol and atol.
    double* rtol = NULL;
    double* atol = NULL;

    if (pDblRtol)
    {
        if (pDblRtol->isScalar())
        {
            rtol = (double*)malloc(sizeof(double));
            *rtol = pDblRtol->get(0);
        }
        else
        {
            rtol = pDblRtol->get();
            itol += 2;
        }
    }
    else
    {
        rtol = (double*)malloc(sizeof(double));
        *rtol = 1.e-9;
    }

    if (pDblAtol)
    {
        if (pDblAtol->isScalar())
        {
            atol = (double*)malloc(sizeof(double));
            *atol = pDblAtol->get(0);
        }
        else
        {
            atol = pDblAtol->get();
            itol ++;
        }
    }
    else
    {
        atol = (double*)malloc(sizeof(double));
        *atol = 1.e-7;
    }

    // Compute rwork, iwork size.
    // Create them.

    int nyh = (*YSize);
    if (pDblW) // structure ls0001 have been restored.
    {
        nyh = C2F(ls0001).nyh;
    }

    rworkSize = 20 + nyh * (maxord + 1) + 3 * *YSize + *YSize **YSize + 2;
    iworkSize = 20 + *YSize;

    rwSize = rworkSize + dStructTabSize;
    iwSize = iworkSize + iStructTabSize;

    rwork = (double*)malloc(rworkSize * sizeof(double));
    iwork = (int*)malloc(iworkSize * sizeof(int));

    if (pDblW && pDblIw)
    {
        if (pDblW->getSize() != rwSize || pDblIw->getSize() != iwSize)
        {
            Scierror(9999, _("%s: Wrong size for w and iw: w = %d and iw = %d expected.\n"), "impl", rwSize, iwSize);
            DifferentialEquation::removeDifferentialEquationFunctions();
            free(pdYData);
            free(YSize);
            free(rwork);
            free(iwork);
            if (itol == 1 || itol == 3)
            {
                free(atol);
            }
            if (itol < 3)
            {
                free(rtol);
            }
            return types::Function::Error;
        }

        istate = 2; // 1 means this is the first call | 2  means this is not the first call

        // restore rwork from pDblW
        C2F(dcopy)(&rworkSize, pDblW->get(), &one, rwork, &one);

        // restore iwork from pDblIw
        iStructTab = (int*)malloc(iStructTabSize * sizeof(int));
        for (int i = 0; i < iworkSize; i++)
        {
            iwork[i] = (int)pDblIw->get(i);
        }

        //restore ls0001d from pDblW
        C2F(dcopy)(&dStructTabSize, pDblW->get() + rworkSize, &one, ls0001d, &one);

        //restore ls0001i from pDblIw
        for (int i = 0; i < iStructTabSize; i++)
        {
            iStructTab[i] = (int)pDblIw->get(i + iworkSize);
        }
        memcpy(ls0001i, iStructTab, 39 * sizeof(int));
    }

    // *** Perform operation. ***
    int err = 0;
    for (int i = 0; i < pDblT->getSize(); i++)
    {
        double t = pDblT->get(i);
        try
        {
            C2F(lsodi)(impl_f, impl_g, impl_jac, YSize, pdYData, pDblYdot0->get(), &t0, &t, &itol, rtol, atol, &itask, &istate, &iopt, rwork, &rworkSize, iwork, &iworkSize, &jacType);

            // check error
            if (istate == 3)
            {
                sciprint(_("The user-supplied subroutine res signalled lsodi to halt the integration and return (ires=2). Execution of the external function has failed.\n"));
                err = 1;
                Scierror(999, _("%s: %s exit with state %d.\n"), "impl", "lsodi", istate);
            }
            else
            {
                err = checkOdeError(meth, istate);
                if (err == 1)
                {
                    Scierror(999, _("%s: %s exit with state %d.\n"), "impl", "lsodi", istate);
                }
            }
        }
        catch (ast::InternalError &ie)
        {
            os << ie.GetErrorMessage();
            bCatch = true;
            err = 1;
        }

        if (err == 1)
        {
            DifferentialEquation::removeDifferentialEquationFunctions();
            free(pdYData);
            free(YSize);
            free(rwork);
            free(iwork);
            if (iStructTab)
            {
                free(iStructTab);
            }
            if (itol == 1 || itol == 3)
            {
                free(atol);
            }
            if (itol < 3)
            {
                free(rtol);
            }

            if (bCatch)
            {
                wchar_t szError[bsiz];
                os_swprintf(szError, bsiz, _W("%s: An error occured in '%s' subroutine.\n").c_str(), "impl", "lsodi");
                os << szError;
                throw ast::InternalError(os.str());
            }

            return types::Function::Error;
        }

        for (int j = 0; j < *YSize; j++)
        {
            pDblYOut->set(i * (*YSize) + j, pdYData[j]);
        }
    }

    if (_iRetCount > 2) //save ls0001 and eh0001 following pDblW and pDblIw.
    {
        int dSize   = 219;

        if (iStructTab == NULL)
        {
            iStructTab = (int*)malloc(iStructTabSize * sizeof(int));
        }

        if (dStructTab == NULL)
        {
            dStructTab = (double*)malloc(dStructTabSize * sizeof(double));
        }

        // save ls0001
        C2F(dcopy)(&dSize, ls0001d, &one, dStructTab, &one);
        memcpy(iStructTab, ls0001i, 39 * sizeof(int));

        // save eh0001
        memcpy(&iStructTab[39], eh0001i, 2 * sizeof(int));
    }

    // *** Return result in Scilab. ***
    out.push_back(pDblYOut);

    if (_iRetCount > 2)
    {
        types::Double* pDblWOut = new types::Double(1, rwSize);
        C2F(dcopy)(&rworkSize, rwork, &one, pDblWOut->get(), &one);
        C2F(dcopy)(&dStructTabSize, dStructTab, &one, pDblWOut->get() + rworkSize, &one);

        types::Double* pDblIwOut = new types::Double(1, iwSize);
        for (int i = 0; i < iworkSize; i++)
        {
            pDblIwOut->set(i, (double)iwork[i]);
        }

        for (int i = 0; i < iStructTabSize; i++)
        {
            pDblIwOut->set(iworkSize + i, (double)iStructTab[i]);
        }

        out.push_back(pDblWOut);
        out.push_back(pDblIwOut);
    }

    // *** free. ***
    if (itol == 1 || itol == 3) // atol is scalar
    {
        free(atol);
    }

    if (itol < 3) // rtol is scalar
    {
        free(rtol);
    }

    free(pdYData);
    free(YSize);
    free(rwork);
    free(iwork);

    if (dStructTab)
    {
        free(dStructTab);
    }

    if (iStructTab)
    {
        free(iStructTab);
    }

    DifferentialEquation::removeDifferentialEquationFunctions();

    return types::Function::OK;
}