5d86f33175abeaa747ddf69535710cb48e133608
[scilab.git] / scilab / modules / core / src / cpp / tasks.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2009-2009 - DIGITEO - Bruno JOFRET
4 *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
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.
13 *
14 */
15
16 #include "AnalysisVisitor.hxx"
17 #include "FBlockListener.hxx"
18 #include "tasks.hxx"
19 #include "timer.hxx"
20 #include "context.hxx"
21 #include "visitor.hxx"
22 #include "printvisitor.hxx"
23 #include "execvisitor.hxx"
24 #include "timedvisitor.hxx"
25 #include "prettyprintvisitor.hxx"
26 #include "debuggervisitor.hxx"
27 #include "stepvisitor.hxx"
28 #include "visitor_common.hxx"
29 #include "threadmanagement.hxx"
30
31 #include "scilabWrite.hxx"
32 #include "runner.hxx"
33
34 #define SCILAB_START    L"/etc/scilab.start"
35 #define SCILAB_QUIT     L"/etc/scilab.quit"
36
37 Timer _timer;
38
39 //#define DEBUG
40
41 /*
42 ** Parse
43 **
44 ** Parse the given file and create the AST.
45 */
46 void parseFileTask(Parser *parser, bool timed, const wchar_t* file_name, const wchar_t* prog_name)
47 {
48 #ifdef DEBUG
49     std::cerr << "*** Processing " << file_name << " file..." << std::endl;
50 #endif
51
52     if (timed)
53     {
54         _timer.start();
55     }
56
57     parser->parseFile(file_name, prog_name);
58
59     if (timed)
60     {
61         _timer.check(L"Parsing");
62     }
63 }
64
65 /*
66 ** Parse
67 **
68 ** Parse the given command and create the AST.
69 */
70 void parseCommandTask(Parser *parser, bool timed, char *command)
71 {
72 #ifdef DEBUG
73     std::cerr << "*** Processing [" <<  command << "]..." << std::endl;
74 #endif
75
76     if (timed)
77     {
78         _timer.start();
79     }
80
81     parser->parse(command);
82
83     if (timed && parser->getControlStatus() == Parser::AllControlClosed)
84     {
85         _timer.check(L"Parsing");
86     }
87 }
88
89 /*
90 ** Dump AST
91 **
92 ** Display the AST in human readable format.
93 */
94 void dumpAstTask(ast::Exp *tree, bool timed)
95 {
96     if (timed)
97     {
98         _timer.start();
99     }
100
101     ast::PrettyPrintVisitor debugMe;
102     if (tree)
103     {
104         tree->accept(debugMe);
105     }
106
107     if (timed)
108     {
109         _timer.check(L"AST Dump");
110     }
111 }
112
113 /*
114 ** Pretty Print
115 **
116 ** Pretty print the Stored AST.
117 */
118 void printAstTask(ast::Exp *tree, bool timed)
119 {
120     if (timed)
121     {
122         _timer.start();
123     }
124
125     if (tree)
126     {
127         ast::PrintVisitor printMe (std::wcout);
128         tree->accept(printMe);
129     }
130
131     if (timed)
132     {
133         _timer.check(L"Pretty Print");
134     }
135 }
136
137
138 /*
139 ** Exec Tree
140 **
141 ** Execute the stored AST.
142 */
143 void execAstTask(ast::Exp* tree, bool serialize, bool timed, bool ASTtimed, bool execVerbose,
144                  bool isInterruptibleThread, bool isPrioritaryThread, command_origin_t iCommandOrigin)
145 {
146     if (tree == NULL)
147     {
148         return;
149     }
150
151     ast::Exp* newTree = NULL;
152     if (serialize)
153     {
154         if (timed)
155         {
156             newTree = callTyper(tree, L"tasks");
157         }
158         else
159         {
160             newTree = callTyper(tree);
161         }
162
163         delete tree;
164     }
165     else
166     {
167         newTree = tree;
168     }
169
170     ast::RunVisitor *exec;
171     if (timed)
172     {
173         _timer.start();
174     }
175
176     if (ASTtimed)
177     {
178         exec = new ast::TimedVisitor();
179     }
180     else if (execVerbose)
181     {
182         exec = new ast::StepVisitor();
183     }
184     else
185     {
186         //call analyzer visitor before exec visitor
187         if (ConfigVariable::getAnalyzerOptions() == 1)
188         {
189             FBlockListener fb;
190             analysis::AnalysisVisitor analysis;
191             analysis.registerFBlockEmittedListener(&fb);
192             newTree->accept(analysis);
193         }
194
195         exec = (ast::RunVisitor*)ConfigVariable::getDefaultVisitor();
196     }
197
198     StaticRunner::execAndWait(newTree, exec, isInterruptibleThread, isPrioritaryThread, iCommandOrigin);
199     //DO NOT DELETE tree or newTree, they was deleted by Runner or previously;
200
201     if (timed)
202     {
203         _timer.check(L"Execute AST");
204     }
205 }
206
207 /*
208 ** Dump Stack Trace
209 **
210 ** Display what is stored in scilab.
211 */
212 void dumpStackTask(bool timed)
213 {
214     if (timed)
215     {
216         _timer.start();
217     }
218
219     symbol::Context::getInstance()->print(std::wcout);
220
221     if (timed)
222     {
223         _timer.check(L"Dumping Stack");
224     }
225 }
226
227 /*
228 ** Execute scilab.start
229 **
230 */
231 int execScilabStartTask(bool _bSerialize)
232 {
233     Parser parse;
234     std::wstring stSCI = ConfigVariable::getSCIPath();
235     stSCI += SCILAB_START;
236
237     ThreadManagement::LockParser();
238     try
239     {
240         parse.parseFile(stSCI, L"");
241     }
242     catch (const ast::InternalError& ie)
243     {
244         scilabWrite(ie.what());
245         ThreadManagement::UnlockParser();
246         return 1;
247     }
248
249     if (parse.getExitStatus() != Parser::Succeded)
250     {
251         scilabWriteW(parse.getErrorMessage());
252         scilabWriteW(L"Failed to parse scilab.start");
253         ThreadManagement::UnlockParser();
254         return 1;
255     }
256     ThreadManagement::UnlockParser();
257
258     ast::Exp* newTree = parse.getTree();
259     if (_bSerialize)
260     {
261         newTree = callTyper(parse.getTree());
262     }
263
264     return StaticRunner::exec(newTree, new ast::ExecVisitor()) ? 0 : 1;
265 }
266
267 /*
268 ** Execute scilab.quit
269 **
270 */
271 int execScilabQuitTask(bool _bSerialize)
272 {
273     Parser parse;
274     std::wstring stSCI = ConfigVariable::getSCIPath();
275     stSCI += SCILAB_QUIT;
276
277     ThreadManagement::LockParser();
278     try
279     {
280         parse.parseFile(stSCI, L"");
281     }
282     catch (const ast::InternalError& ie)
283     {
284         scilabWrite(ie.what());
285         ThreadManagement::UnlockParser();
286         return 1;
287     }
288
289     if (parse.getExitStatus() != Parser::Succeded)
290     {
291         scilabWriteW(parse.getErrorMessage());
292         scilabWriteW(L"Failed to parse scilab.quit");
293         ThreadManagement::UnlockParser();
294         return 1;
295     }
296     ThreadManagement::UnlockParser();
297
298     ast::Exp* newTree = parse.getTree();
299     if (_bSerialize)
300     {
301         newTree = callTyper(parse.getTree());
302     }
303
304     return StaticRunner::exec(newTree, new ast::ExecVisitor()) ? 0 : 1;
305 }
306
307
308 ast::Exp* parseCommand(std::wstring _command)
309 {
310     if (_command.empty())
311     {
312         return NULL;
313     }
314
315     Parser parse;
316     parse.parse((wchar_t*)_command.c_str());
317     if (parse.getExitStatus() != Parser::Succeded)
318     {
319         return NULL;
320     }
321
322     return parse.getTree();
323 }