2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2006 - INRIA - Antoine ELIAS
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
16 //#include "AnalysisVisitor.hxx"
18 #include "functions_gw.hxx"
19 #include "visitor_common.hxx"
20 #include "scilabWrite.hxx"
21 #include "configvariable.hxx"
22 #include "threadmanagement.hxx"
31 #include "sci_malloc.h"
32 #include "os_string.h"
35 #include "localization.h"
36 #include "os_string.h"
39 #define MUTE_FLAG L"n"
40 #define NO_MUTE_FLAG L"m"
42 /*--------------------------------------------------------------------------*/
43 types::Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::typed_list &out)
46 bool bErrCatch = false;
48 wchar_t* pstMsg = NULL;
49 ast::Exp* pExp = NULL;
50 wchar_t *pstCommand = NULL;
51 bool bSilentError = ConfigVariable::isSilentError();
54 if (in.size() < 1 || in.size() > 3)
56 Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "execstr" , 1, 3);
57 return types::Function::Error;
64 if (in[1]->isString() == false || in[1]->getAs<types::String>()->getSize() != 1)
66 Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "execstr", 2);
67 return types::Function::Error;
70 types::String* pS = in[1]->getAs<types::String>();
71 if (os_wcsicmp(pS->get(0), L"errcatch") == 0)
77 Scierror(999, _("%s: Wrong value for input argument #%d: 'errcatch' expected.\n"), "execstr", 2);
78 return types::Function::Error;
87 if (in[2]->isString() == false || in[2]->getAs<types::String>()->getSize() != 1)
89 Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "execstr", 3);
90 return types::Function::Error;
93 if (os_wcsicmp(in[2]->getAs<types::String>()->get(0), MUTE_FLAG) == 0)
97 else if (os_wcsicmp(in[2]->getAs<types::String>()->get(0), NO_MUTE_FLAG) == 0)
103 Scierror(999, _("%s: Wrong value for input argument #%d: '%s' or '%s' expected.\n"), "execstr", 3, MUTE_FLAG, NO_MUTE_FLAG);
104 return types::Function::Error;
109 if (in[0]->isDouble() && in[0]->getAs<types::Double>()->getSize() == 0)
112 out.push_back(types::Double::Empty());
113 return types::Function::OK;
116 if (in[0]->isString() == false || (in[0]->getAs<types::String>()->getRows() != 1 && in[0]->getAs<types::String>()->getCols() != 1))
118 Scierror(999, _("%s: Wrong type for input argument #%d: Vector of strings expected.\n"), "execstr", 1);
119 return types::Function::Error;
122 types::String* pS = in[0]->getAs<types::String>();
123 int iTotalLen = pS->getSize(); //add \n after each string
124 for (int i = 0 ; i < pS->getSize() ; i++)
126 iTotalLen += (int)wcslen(pS->get(i));
129 pstCommand = (wchar_t*)MALLOC(sizeof(wchar_t) * (iTotalLen + 1));//+1 for null termination
131 for (int i = 0, iPos = 0 ; i < pS->getSize() ; i++)
133 wcscpy(pstCommand + iPos, pS->get(i));
134 iPos = (int)wcslen(pstCommand);
135 pstCommand[iPos++] = L'\n';
136 pstCommand[iPos] = 0;
139 // add execstr in list of macro called
140 // to manage line displayed when error occurred.
141 ConfigVariable::macroFirstLine_begin(1);
143 ThreadManagement::LockParser();
144 parser.parse(pstCommand);
146 if (parser.getExitStatus() != Parser::Succeded)
150 out.push_back(new types::Double(999));
151 //to lock last error information
152 ConfigVariable::setLastErrorCall();
153 ConfigVariable::setLastErrorMessage(parser.getErrorMessage());
154 ConfigVariable::setLastErrorNumber(999);
155 ThreadManagement::UnlockParser();
156 ConfigVariable::macroFirstLine_end();
157 return types::Function::OK;
161 char* pst = wide_string_to_UTF8(parser.getErrorMessage());
162 Scierror(999, "%s", pst);
164 ThreadManagement::UnlockParser();
165 ConfigVariable::macroFirstLine_end();
166 return types::Function::Error;
170 if (ConfigVariable::getSerialize())
172 ast::Exp* temp = parser.getTree();
173 if (ConfigVariable::getTimed())
175 pExp = callTyper(temp, L"execstr");
179 pExp = callTyper(temp);
186 pExp = parser.getTree();
189 ThreadManagement::UnlockParser();
193 return types::Function::Error;
196 //save current prompt mode
197 int iPromptMode = ConfigVariable::getPromptMode();
198 ConfigVariable::setPromptMode(-1);
200 if (ConfigVariable::getAnalyzerOptions() == 1)
202 //analysis::AnalysisVisitor analysis;
203 //pExp->accept(analysis);
204 //ast::DebugVisitor debugMe;
205 //pExp->accept(debugMe);
208 ast::SeqExp* pSeqExp = pExp->getAs<ast::SeqExp>();
209 std::unique_ptr<ast::ConstVisitor> run(ConfigVariable::getDefaultVisitor());
210 ConfigVariable::setSilentError(bErrCatch);
213 symbol::Context* pCtx = symbol::Context::getInstance();
214 int scope = pCtx->getScopeLevel();
215 int level = ConfigVariable::getRecursionLevel();
218 pSeqExp->accept(*run);
220 catch (const ast::RecursionException& /* re */)
222 ConfigVariable::setSilentError(bSilentError);
224 //close opened scope during try
225 while (pCtx->getScopeLevel() > scope)
230 //decrease recursion to init value
231 while (ConfigVariable::getRecursionLevel() > level)
233 ConfigVariable::where_end();
234 ConfigVariable::decreaseRecursion();
237 //print msg about recursion limit and trigger an error
239 os_swprintf(sz, 1024, _W("Recursion limit reached (%d).\n").data(), ConfigVariable::getRecursionLimit());
240 throw ast::InternalError(sz);
243 catch (const ast::InternalError& ie)
245 if (bErrCatch == false)
248 ConfigVariable::macroFirstLine_end();
249 ConfigVariable::setPromptMode(iPromptMode);
250 ConfigVariable::setSilentError(bSilentError);
256 scilabForcedWriteW(ie.GetErrorMessage().c_str());
259 ConfigVariable::resetWhereError();
260 iErr = ConfigVariable::getLastErrorNumber();
265 out.push_back(new types::Double(iErr));
266 //to lock last error information
267 ConfigVariable::setLastErrorCall();
269 ConfigVariable::resetError();
272 ConfigVariable::macroFirstLine_end();
273 ConfigVariable::setPromptMode(iPromptMode);
274 ConfigVariable::setSilentError(bSilentError);
277 return types::Function::OK;
279 /*--------------------------------------------------------------------------*/