2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2006 - INRIA - Antoine ELIAS
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
14 //#include "AnalysisVisitor.hxx"
16 #include "functions_gw.hxx"
17 #include "visitor_common.hxx"
18 #include "scilabWrite.hxx"
19 #include "configvariable.hxx"
20 #include "threadmanagement.hxx"
28 #include "sci_malloc.h"
29 #include "os_string.h"
32 #include "localization.h"
33 #include "os_string.h"
36 #define MUTE_FLAG L"n"
37 #define NO_MUTE_FLAG L"m"
39 /*--------------------------------------------------------------------------*/
40 types::Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::typed_list &out)
43 bool bErrCatch = false;
45 wchar_t* pstMsg = NULL;
46 ast::Exp* pExp = NULL;
47 wchar_t *pstCommand = NULL;
50 if (in.size() < 1 || in.size() > 3)
52 Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "execstr" , 1, 3);
53 return types::Function::Error;
60 if (in[1]->isString() == false || in[1]->getAs<types::String>()->getSize() != 1)
62 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "execstr", 2);
63 return types::Function::Error;
66 types::String* pS = in[1]->getAs<types::String>();
67 if (os_wcsicmp(pS->get(0), L"errcatch") == 0)
73 Scierror(999, _("%s: Wrong value for input argument #%d: 'errcatch' expected.\n"), "execstr", 2);
74 return types::Function::Error;
83 if (in[2]->isString() == false || in[2]->getAs<types::String>()->getSize() != 1)
85 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "execstr", 3);
86 return types::Function::Error;
89 if (os_wcsicmp(in[2]->getAs<types::String>()->get(0), MUTE_FLAG) == 0)
93 else if (os_wcsicmp(in[2]->getAs<types::String>()->get(0), NO_MUTE_FLAG) == 0)
99 Scierror(999, _("%s: Wrong value for input argument #%d: '%s' or '%s' expected.\n"), "execstr", 3, MUTE_FLAG, NO_MUTE_FLAG);
100 return types::Function::Error;
105 if (in[0]->isDouble() && in[0]->getAs<types::Double>()->getSize() == 0)
108 out.push_back(types::Double::Empty());
109 return types::Function::OK;
112 if (in[0]->isString() == false || (in[0]->getAs<types::String>()->getRows() != 1 && in[0]->getAs<types::String>()->getCols() != 1))
114 Scierror(999, _("%s: Wrong type for input argument #%d: Vector of strings expected.\n"), "execstr", 1);
115 return types::Function::Error;
118 types::String* pS = in[0]->getAs<types::String>();
119 int iTotalLen = pS->getSize(); //add \n after each string
120 for (int i = 0 ; i < pS->getSize() ; i++)
122 iTotalLen += (int)wcslen(pS->get(i));
125 pstCommand = (wchar_t*)MALLOC(sizeof(wchar_t) * (iTotalLen + 1));//+1 for null termination
127 for (int i = 0, iPos = 0 ; i < pS->getSize() ; i++)
129 wcscpy(pstCommand + iPos, pS->get(i));
130 iPos = (int)wcslen(pstCommand);
131 pstCommand[iPos++] = L'\n';
132 pstCommand[iPos] = 0;
135 ThreadManagement::LockParser();
136 parser.parse(pstCommand);
138 if (parser.getExitStatus() != Parser::Succeded)
142 out.push_back(new types::Double(999));
143 //to lock last error information
144 ConfigVariable::setLastErrorCall();
145 ConfigVariable::setLastErrorMessage(parser.getErrorMessage());
146 ConfigVariable::setLastErrorNumber(999);
147 ThreadManagement::UnlockParser();
148 return types::Function::OK;
152 char* pst = wide_string_to_UTF8(parser.getErrorMessage());
153 Scierror(999, "%s", pst);
155 ThreadManagement::UnlockParser();
156 return types::Function::Error;
160 if (ConfigVariable::getSerialize())
162 ast::Exp* temp = parser.getTree();
163 if (ConfigVariable::getTimed())
165 pExp = callTyper(temp, L"execstr");
169 pExp = callTyper(temp);
176 pExp = parser.getTree();
179 ThreadManagement::UnlockParser();
183 return types::Function::Error;
186 //save current prompt mode
187 int iPromptMode = ConfigVariable::getPromptMode();
188 ConfigVariable::setPromptMode(-1);
190 if (ConfigVariable::getAnalyzerOptions() == 1)
192 //analysis::AnalysisVisitor analysis;
193 //pExp->accept(analysis);
194 //ast::DebugVisitor debugMe;
195 //pExp->accept(debugMe);
198 ast::SeqExp* pSeqExp = pExp->getAs<ast::SeqExp>();
200 // add execstr in list of macro called
201 // to manage line displayed when error occured.
202 ConfigVariable::macroFirstLine_begin(1);
204 ast::ConstVisitor* run = ConfigVariable::getDefaultVisitor();
208 symbol::Context* pCtx = symbol::Context::getInstance();
209 int scope = pCtx->getScopeLevel();
210 int level = ConfigVariable::getRecursionLevel();
213 pSeqExp->accept(*run);
216 catch (const ast::RecursionException& /* re */)
218 //close opened scope during try
219 while (pCtx->getScopeLevel() > scope)
224 //decrease recursion to init value
225 while (ConfigVariable::getRecursionLevel() > level)
227 ConfigVariable::where_end();
228 ConfigVariable::decreaseRecursion();
231 //print msg about recursion limit and trigger an error
233 os_swprintf(sz, 1024, _W("Recursion limit reached (%d).\n").data(), ConfigVariable::getRecursionLimit());
234 throw ast::InternalError(sz);
237 catch (const ast::InternalError& ie)
239 if (bErrCatch == false)
242 ConfigVariable::macroFirstLine_end();
243 ConfigVariable::setPromptMode(iPromptMode);
249 scilabForcedWriteW(ie.GetErrorMessage().c_str());
252 ConfigVariable::resetWhereError();
253 iErr = ConfigVariable::getLastErrorNumber();
258 out.push_back(new types::Double(iErr));
259 //to lock last error information
260 ConfigVariable::setLastErrorCall();
262 ConfigVariable::resetError();
265 ConfigVariable::macroFirstLine_end();
266 ConfigVariable::setPromptMode(iPromptMode);
269 return types::Function::OK;
271 /*--------------------------------------------------------------------------*/