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;
53 if (in.size() < 1 || in.size() > 3)
55 Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "execstr" , 1, 3);
56 return types::Function::Error;
63 if (in[1]->isString() == false || in[1]->getAs<types::String>()->getSize() != 1)
65 Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "execstr", 2);
66 return types::Function::Error;
69 types::String* pS = in[1]->getAs<types::String>();
70 if (os_wcsicmp(pS->get(0), L"errcatch") == 0)
76 Scierror(999, _("%s: Wrong value for input argument #%d: 'errcatch' expected.\n"), "execstr", 2);
77 return types::Function::Error;
86 if (in[2]->isString() == false || in[2]->getAs<types::String>()->getSize() != 1)
88 Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "execstr", 3);
89 return types::Function::Error;
92 if (os_wcsicmp(in[2]->getAs<types::String>()->get(0), MUTE_FLAG) == 0)
96 else if (os_wcsicmp(in[2]->getAs<types::String>()->get(0), NO_MUTE_FLAG) == 0)
102 Scierror(999, _("%s: Wrong value for input argument #%d: '%s' or '%s' expected.\n"), "execstr", 3, MUTE_FLAG, NO_MUTE_FLAG);
103 return types::Function::Error;
108 if (in[0]->isDouble() && in[0]->getAs<types::Double>()->getSize() == 0)
111 out.push_back(types::Double::Empty());
112 return types::Function::OK;
115 if (in[0]->isString() == false || (in[0]->getAs<types::String>()->getRows() != 1 && in[0]->getAs<types::String>()->getCols() != 1))
117 Scierror(999, _("%s: Wrong type for input argument #%d: Vector of strings expected.\n"), "execstr", 1);
118 return types::Function::Error;
121 types::String* pS = in[0]->getAs<types::String>();
122 int iTotalLen = pS->getSize(); //add \n after each string
123 for (int i = 0 ; i < pS->getSize() ; i++)
125 iTotalLen += (int)wcslen(pS->get(i));
128 pstCommand = (wchar_t*)MALLOC(sizeof(wchar_t) * (iTotalLen + 1));//+1 for null termination
130 for (int i = 0, iPos = 0 ; i < pS->getSize() ; i++)
132 wcscpy(pstCommand + iPos, pS->get(i));
133 iPos = (int)wcslen(pstCommand);
134 pstCommand[iPos++] = L'\n';
135 pstCommand[iPos] = 0;
138 // add execstr in list of macro called
139 // to manage line displayed when error occurred.
140 ConfigVariable::macroFirstLine_begin(1);
142 ThreadManagement::LockParser();
143 parser.parse(pstCommand);
145 if (parser.getExitStatus() != Parser::Succeded)
149 out.push_back(new types::Double(999));
150 //to lock last error information
151 ConfigVariable::setLastErrorCall();
152 ConfigVariable::setLastErrorMessage(parser.getErrorMessage());
153 ConfigVariable::setLastErrorNumber(999);
154 ThreadManagement::UnlockParser();
155 ConfigVariable::macroFirstLine_end();
156 return types::Function::OK;
160 char* pst = wide_string_to_UTF8(parser.getErrorMessage());
161 Scierror(999, "%s", pst);
163 ThreadManagement::UnlockParser();
164 ConfigVariable::macroFirstLine_end();
165 return types::Function::Error;
169 if (ConfigVariable::getSerialize())
171 ast::Exp* temp = parser.getTree();
172 if (ConfigVariable::getTimed())
174 pExp = callTyper(temp, L"execstr");
178 pExp = callTyper(temp);
185 pExp = parser.getTree();
188 ThreadManagement::UnlockParser();
192 return types::Function::Error;
195 //save current prompt mode
196 int iPromptMode = ConfigVariable::getPromptMode();
197 ConfigVariable::setPromptMode(-1);
199 if (ConfigVariable::getAnalyzerOptions() == 1)
201 //analysis::AnalysisVisitor analysis;
202 //pExp->accept(analysis);
203 //ast::DebugVisitor debugMe;
204 //pExp->accept(debugMe);
207 ast::SeqExp* pSeqExp = pExp->getAs<ast::SeqExp>();
208 std::unique_ptr<ast::ConstVisitor> run(ConfigVariable::getDefaultVisitor());
211 symbol::Context* pCtx = symbol::Context::getInstance();
212 int scope = pCtx->getScopeLevel();
213 int level = ConfigVariable::getRecursionLevel();
216 pSeqExp->accept(*run);
218 catch (const ast::RecursionException& /* re */)
220 //close opened scope during try
221 while (pCtx->getScopeLevel() > scope)
226 //decrease recursion to init value
227 while (ConfigVariable::getRecursionLevel() > level)
229 ConfigVariable::where_end();
230 ConfigVariable::decreaseRecursion();
233 //print msg about recursion limit and trigger an error
235 os_swprintf(sz, 1024, _W("Recursion limit reached (%d).\n").data(), ConfigVariable::getRecursionLimit());
236 throw ast::InternalError(sz);
239 catch (const ast::InternalError& ie)
241 if (bErrCatch == false)
244 ConfigVariable::macroFirstLine_end();
245 ConfigVariable::setPromptMode(iPromptMode);
251 scilabForcedWriteW(ie.GetErrorMessage().c_str());
254 ConfigVariable::resetWhereError();
255 iErr = ConfigVariable::getLastErrorNumber();
260 out.push_back(new types::Double(iErr));
261 //to lock last error information
262 ConfigVariable::setLastErrorCall();
264 ConfigVariable::resetError();
267 ConfigVariable::macroFirstLine_end();
268 ConfigVariable::setPromptMode(iPromptMode);
271 return types::Function::OK;
273 /*--------------------------------------------------------------------------*/