92698d644cee10677ba7a11220954a9bd7b9d393
[scilab.git] / scilab / modules / core / src / cpp / InitScilab.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2013 - Scilab Enterprises - Antoine ELIAS
4  * Copyright (C) 2013 - Scilab Enterprises - Cedric DELAMARRE
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 #include <string>
15 #include <libxml/parser.h>
16
17 #include "inspector.hxx"
18 #include "double.hxx"
19 #include "polynom.hxx"
20 #include "string.hxx"
21 #include "bool.hxx"
22
23 #include "scilabWrite.hxx"
24 #include "tasks.hxx"
25 #include "parser.hxx"
26 #include "context.hxx"
27 #include "configvariable.hxx"
28 #include "filemanager.hxx"
29 #include "runner.hxx"
30 #include "visitor_common.hxx"
31 #include "operations.hxx"
32 #include "threadmanagement.hxx"
33 #include "numericconstants.hxx"
34 #include "expandPathVariable.h"
35 #include "execvisitor.hxx"
36 #include "debugmanager.hxx"
37 #include "consoledebugger.hxx"
38
39 extern "C"
40 {
41 #include "machine.h"
42 #include "InitializeLocalization.h"
43 #include "elem_common.h"
44 #include "InitializeJVM.h"
45 #include "TerminateJVM.h"
46 #include "InitializeGUI.h"
47 #include "graphicModuleLoad.h"
48 #include "TerminateGraphics.h"
49 #include "loadBackGroundClassPath.h"
50 #include "sci_tmpdir.h"
51 #include "setgetlanguage.h"
52 #include "InitializeConsole.h"
53 #include "InitializeHistoryManager.h"
54 #include "TerminateHistoryManager.h"
55 #include "prompt.h"
56 #include "scilabRead.h"
57 #include "functions_manager.h"
58 #include "InitScilab.h"
59 #include "setenvvar.h"
60 #include "getScilabPreference.h"
61 #include "saveCWDInPreferences.h"
62 #include "h5_fileManagement.h"
63 #include "with_fftw.h"
64 #include "BrowseVarManager.h"
65 #include "scicurdir.h"
66 #include "FileBrowserChDir.h"
67 #include "InitializePreferences.h"
68
69 #ifdef _MSC_VER
70 #include "InitializeWindows_tools.h"
71 #include "TerminateWindows_tools.h"
72 #include "WndThread.h"
73 #include "console.h"
74 #include "InnosetupMutex.h"
75 #include "MutexClosingScilab.h"
76 #include "WinConsole.h"
77 #else
78 #include "signal_mgmt.h"
79 #include "initConsoleMode.h"
80 #endif
81
82 #if defined(linux) && defined(__i386__)
83 #include "setPrecisionFPU.h"
84 #endif
85
86 #include "InitializeTclTk.h"
87
88     /* Defined without include to avoid useless header dependency */
89     extern BOOL isItTheDisabledLib(void);
90 }
91
92 static void Add_i(void);
93 static void Add_pi(void);
94 static void Add_eps(void);
95 static void Add_e(void);
96 static void Add_s(void);
97 static void Add_z(void);
98 static void Add_gui(void);
99 static void Add_fftw(void);
100 static void Add_Nan(void);
101 static void Add_Inf(void);
102 static void Add_io(void);
103 static void Add_All_Variables(void);
104 static void Add_Double_Constant(const std::wstring& _szName, double _dblReal, double _dblImg, bool _bComplex);
105 static void Add_Poly_Constant(const std::wstring& _szName, const std::wstring& _szPolyVar, int _iRank, types::Double * _pdblReal);
106 static void Add_Boolean_Constant(const std::wstring& _szName, bool _bBool);
107 static void Add_String_Constant(const std::wstring& _szName, const char *_pstString);
108 static void checkForLinkerErrors(void);
109
110 static int batchMain(ScilabEngineInfo* _pSEI);
111 static int InitializeEnvironnement(void);
112 static int interactiveMain(ScilabEngineInfo* _pSEI);
113 static void processCommand(ScilabEngineInfo* _pSEI);
114 static void stateShow(Parser::ControlStatus status);
115
116 using namespace ast;
117
118 ScilabEngineInfo* InitScilabEngineInfo()
119 {
120     // Disable all startup flags.
121     ScilabEngineInfo* pSEI = (ScilabEngineInfo*)CALLOC(1, sizeof(ScilabEngineInfo));
122
123     //Active default flags
124     pSEI->iExecAst = 1;
125     pSEI->iNoBanner = 1;
126
127     pSEI->iMultiLine = 0;
128     pSEI->isInterruptible = 1;      // by default all thread are interruptible
129     pSEI->isPrioritary = 0;         // by default all thread are non-prioritary
130     pSEI->iStartConsoleThread = 1;  // used in call_scilab to avoid "prompt" thread execution
131     pSEI->iForceQuit = 0;           // management of -quit argument
132     pSEI->iCommandOrigin = NONE;
133
134     return pSEI;
135 }
136
137 int StartScilabEngine(ScilabEngineInfo* _pSEI)
138 {
139     int iMainRet = 0;
140     ConfigVariable::setStartProcessing(true);
141
142     // ignore -e argument if the command is empty
143     if (_pSEI->pstExec && strcmp(_pSEI->pstExec, "") == 0)
144     {
145         _pSEI->pstExec = NULL;
146     }
147
148     // ignore -quit if -e or -f are not given
149     _pSEI->iForceQuit = _pSEI->iForceQuit && (_pSEI->pstExec || _pSEI->pstFile);
150     ConfigVariable::setForceQuit(_pSEI->iForceQuit == 1);
151
152     /* This bug only occurs under Linux 32 bits
153      * See: http://wiki.scilab.org/Scilab_precision
154      */
155 #if defined(linux) && defined(__i386__)
156     setFPUToDouble();
157 #endif
158
159 #ifndef _MSC_VER
160     /* Management of the signals (seg fault, floating point exception, etc) */
161     if (getenv("SCI_DISABLE_EXCEPTION_CATCHING") == NULL)
162     {
163         base_error_init();
164     }
165 #endif
166
167 #if defined(netbsd) || defined(freebsd)
168     /* floating point exceptions */
169     fpsetmask(0);
170 #endif
171
172     ThreadManagement::initialize();
173     NumericConstants::Initialize();
174     checkForLinkerErrors();
175
176 #ifdef _MSC_VER
177     //get current console window and hide it
178     int scilabMode = getScilabMode();
179     if (scilabMode == SCILAB_STD || scilabMode == SCILAB_NW || scilabMode == SCILAB_API)
180     {
181         CreateScilabHiddenWndThread();
182     }
183
184     if (scilabMode == SCILAB_STD)
185     {
186         //show banner in console window
187         CreateScilabConsole(_pSEI->iNoBanner);
188
189         if (_pSEI->iKeepConsole == 0)
190         {
191             HideScilex(); /* hide console window */
192         }
193         else
194         {
195             ShowScilex();
196         }
197     }
198     else
199     {
200         if (scilabMode == SCILAB_NW || scilabMode == SCILAB_NWNI)
201         {
202             SaveConsoleColors();
203             if (scilabMode == SCILAB_NW)
204             {
205                 RenameConsole();
206                 UpdateConsoleColors();
207             }
208         }
209     }
210
211     //create a thread for innosetup to allow reinstall during scilab running
212     createInnosetupMutex();
213 #endif
214
215     //open scope lvl 0 for gateway from modules and first variables ( SCI, HOME, TMPDIR, ...)
216     symbol::Context::getInstance()->scope_begin();
217
218     /* Scilab Startup */
219     xmlInitParser();
220     InitializeEnvironnement();
221
222     if (_pSEI->pstLang)
223     {
224         wchar_t *pwstLang = to_wide_string(_pSEI->pstLang);
225         setlanguage(pwstLang);
226         FREE(pwstLang);
227     }
228
229 #ifdef _MSC_VER
230     InitializeWindows_tools();
231 #endif
232
233     if (_pSEI->iNoJvm == 0) // With JVM
234     {
235         InitializeTclTk();
236         InitializeJVM();
237         InitializeGUI();
238
239         /* create needed data structure if not already created */
240         loadGraphicModule();
241
242         loadBackGroundClassPath();
243
244         //update %gui to true
245         Add_Boolean_Constant(L"%gui", true);
246     }
247
248     /* Standard mode -> init Java Console */
249     if (_pSEI->iConsoleMode == 0)
250     {
251         /* Initialize console: lines... */
252         InitializeConsole();
253     }
254     else
255     {
256 #ifndef _MSC_VER
257         initConsoleMode(RAW);
258 #endif
259     }
260
261     //set prompt value
262     int pause = 0;
263     C2F(setprlev) (&pause);
264
265     //load gateways
266     if (LoadModules() == false)
267     {
268         //clear opened files
269         FileManager::destroy();
270         return 1;
271     }
272
273     //variables are needed by loadModules but must be in SCOPE_CONSOLE under protection
274     //remove (W)SCI/SCIHOME/HOME/TMPDIR
275     symbol::Context::getInstance()->remove(symbol::Symbol(L"SCI"));
276     symbol::Context::getInstance()->remove(symbol::Symbol(L"WSCI"));
277     symbol::Context::getInstance()->remove(symbol::Symbol(L"SCIHOME"));
278     symbol::Context::getInstance()->remove(symbol::Symbol(L"home"));
279     symbol::Context::getInstance()->remove(symbol::Symbol(L"TMPDIR"));
280
281     //open a scope for macros
282     symbol::Context::getInstance()->scope_begin();
283
284     Add_All_Variables();
285     SetScilabVariables();
286
287     symbol::Context::getInstance()->protect();
288     //execute scilab.start
289     if (_pSEI->iNoStart == 0)
290     {
291         int ierr = execScilabStartTask(_pSEI->iSerialize != 0);
292         if (ierr)
293         {
294             return ierr;
295         }
296     }
297
298     //open console scope
299     //symbol::Context::getInstance()->scope_begin();
300
301     ConfigVariable::setStartProcessing(false);
302
303     ConfigVariable::setPromptMode(0);
304     int iScript = 0;
305     if (_pSEI->pstExec)
306     {
307         //-e option
308         Parser parser;
309         parseCommandTask(&parser, _pSEI->iTimed != 0, _pSEI->pstExec);
310
311         if (parser.getExitStatus() == Parser::Failed)
312         {
313             scilabWriteW(parser.getErrorMessage());
314         }
315         else if (parser.getControlStatus() !=  Parser::AllControlClosed)
316         {
317             _pSEI->iMultiLine = 1;
318         }
319         else
320         {
321             StoreConsoleCommand(_pSEI->pstExec, 0);
322         }
323
324         if (parser.getTree())
325         {
326             delete parser.getTree();
327             parser.setTree(NULL);
328         }
329         iMainRet = ConfigVariable::getExitStatus();
330         iScript = 1;
331     }
332     else if (_pSEI->pstFile)
333     {
334         //-f option execute exec('%s',-1)
335         char *pstCommand = (char *)MALLOC(sizeof(char) * (strlen("exec(\"\",-1)") + strlen(_pSEI->pstFile) + 1));
336         sprintf(pstCommand, "exec(\"%s\",-1)", _pSEI->pstFile);
337
338         StoreConsoleCommand(pstCommand, 0);
339         FREE(pstCommand);
340         iMainRet = ConfigVariable::getExitStatus();
341         _pSEI->pstExec = NULL;
342         _pSEI->pstFile = NULL;
343         iScript = 1;
344     }
345
346     ConfigVariable::setPromptMode(2);
347
348     InitializePreferences(iScript);
349
350
351     //register console debugger as debugger
352     debugger::DebuggerMagager::getInstance()->addDebugger(new debugger::ConsoleDebugger());
353     return iMainRet;
354 }
355
356 int RunScilabEngine(ScilabEngineInfo* _pSEI)
357 {
358     if (_pSEI->pstParseFile)
359     {
360         // Only for parsing test, won't execute anything.
361         return batchMain(_pSEI);
362     }
363     else
364     {
365         //always run as interactiveMain even after -e or -f option
366         return interactiveMain(_pSEI);
367     }
368 }
369
370 int ExecExternalCommand(ScilabEngineInfo* _pSEI)
371 {
372     if (_pSEI->pstExec)
373     {
374         StoreConsoleCommand(_pSEI->pstExec, 1);
375         return ConfigVariable::getExitStatus();
376     }
377
378     return -1;
379 }
380
381 void StopScilabEngine(ScilabEngineInfo* _pSEI)
382 {
383     ConfigVariable::setEndProcessing(true);
384 #ifdef _MSC_VER
385     /* bug 3672 */
386     /* Create a Mutex (closing scilab)
387      * used by files association
388      */
389     createMutexClosingScilab();
390 #endif
391
392     clearScilabPreferences();
393
394     //close console scope
395     //symbol::Context::getInstance()->scope_end();
396
397     // close macros scope before close dynamic library.
398     // all pointers allocated by a dynamic library have to be free before dlclose.
399     symbol::Context::getInstance()->scope_end();
400
401     //execute scilab.quit
402     if (_pSEI->pstFile)
403     {
404         //-f option execute exec('%s',-1)
405         char *pstCommand = (char *)MALLOC(sizeof(char) * (strlen("exec(\"\",-1)") + strlen(_pSEI->pstFile) + 1));
406         sprintf(pstCommand, "exec(\"%s\",-1)", _pSEI->pstFile);
407
408         _pSEI->pstExec = pstCommand;
409         processCommand(_pSEI);
410         FREE(pstCommand);
411     }
412     else if (_pSEI->iNoStart == 0)
413     {
414         execScilabQuitTask(_pSEI->iSerialize != 0);
415         //call all modules.quit
416         EndModules();
417     }
418
419     //close gateways scope
420     symbol::Context::getInstance()->scope_end();
421
422     //clean context
423     symbol::Context::getInstance()->clearAll();
424     //destroy context
425     symbol::Context::destroyInstance();
426 #ifndef NDEBUG
427     //uncomment to print mem leak log
428     //types::Inspector::displayMemleak();
429 #endif
430
431     // cleanup Java dependent features
432     saveCWDInPreferences();
433     clearScilabPreferences();
434     TerminateHistoryManager();
435
436     // stop the JVM
437     if (_pSEI->iNoJvm == 0)
438     {
439         TerminateGraphics();
440         TerminateJVM();
441     }
442
443     // reset struct to prevent the use of deleted objects
444     // when we start scilab again without kill process (ie: call_scilab)
445     resetVariableValueDefinedInScilab();
446
447     /* TerminateCorePart2 */
448
449     //clear opened files
450     FileManager::destroy();
451
452     /* Remove TMPDIR before exit */
453     clearTMPDIR();
454
455     //Unload dynamic modules
456     UnloadModules();
457
458     //destroy function manager
459     destroyfunctionManagerInstance();
460     /* TerminateCorePart2 end */
461
462     /*
463     * Cleanup function for the XML library.
464     */
465     xmlCleanupParser();
466
467     /* Cleanup the parser state */
468     Parser::cleanup();
469
470 #ifdef _MSC_VER
471     TerminateWindows_tools();
472 #endif
473
474     /* Reset terminal configuration */
475     if (_pSEI->iConsoleMode)
476     {
477 #ifndef _MSC_VER
478         initConsoleMode(ATTR_RESET);
479 #endif
480     }
481
482 #ifdef _MSC_VER
483     /* close mutex (closing scilab)
484      * used by files association
485      */
486     terminateMutexClosingScilab();
487 #endif
488
489     ConfigVariable::clearLastError();
490     ConfigVariable::setEndProcessing(false);
491 }
492
493 static void processCommand(ScilabEngineInfo* _pSEI)
494 {
495     /*
496      ** -*- DUMPING TREE -*-
497      */
498     if (_pSEI->iDumpAst)
499     {
500         dumpAstTask((ast::Exp*)_pSEI->pExpTree, _pSEI->iTimed != 0);
501     }
502
503     /*
504      ** -*- PRETTY PRINT TREE -*-
505      */
506     if (_pSEI->iPrintAst)
507     {
508         printAstTask((ast::Exp*)_pSEI->pExpTree, _pSEI->iTimed != 0);
509     }
510
511     /*
512      ** -*- EXECUTING TREE -*-
513      */
514     if (_pSEI->iExecAst)
515     {
516         execAstTask((ast::Exp*)_pSEI->pExpTree, _pSEI->iSerialize != 0,
517                     _pSEI->iTimed != 0, _pSEI->iAstTimed != 0,
518                     _pSEI->iExecVerbose != 0, _pSEI->isInterruptible != 0,
519                     _pSEI->isPrioritary != 0, _pSEI->iCommandOrigin);
520     }
521
522     /*
523      ** -*- DUMPING STACK AFTER EXECUTION -*-
524      */
525     if (_pSEI->iDumpStack)
526     {
527         dumpStackTask(_pSEI->iTimed != 0);
528     }
529 }
530
531 // Thread used to parse and execute Scilab command setted in storeCommand
532 void* scilabReadAndExecCommand(void* param)
533 {
534     char* command           = NULL;
535     int iInterruptibleCmd   = 0;
536     int iPrioritaryCmd      = 0;
537
538     command_origin_t iCmdOrigin = NONE;
539
540     ScilabEngineInfo* _pSEI = (ScilabEngineInfo*)param;
541
542     do
543     {
544         if (GetCommand(&command, &iPrioritaryCmd, &iInterruptibleCmd, &iCmdOrigin) == 0)
545         {
546             ThreadManagement::WaitForCommandStoredSignal();
547             continue;
548         }
549
550         // empty command
551         if (command == NULL || strlen(command) == 0)
552         {
553             continue;
554         }
555
556         _pSEI->isInterruptible = iInterruptibleCmd;
557         _pSEI->isPrioritary = iPrioritaryCmd;
558         _pSEI->iCommandOrigin = iCmdOrigin;
559
560         ThreadManagement::LockParser();
561         Parser parser;
562         parser.setParseTrace(_pSEI->iParseTrace != 0);
563         parseCommandTask(&parser, _pSEI->iTimed != 0, command);
564
565         if (parser.getExitStatus() == Parser::Failed)
566         {
567             scilabWriteW(parser.getErrorMessage());
568             ThreadManagement::UnlockParser();
569             continue;
570         }
571
572         _pSEI->pExpTree = parser.getTree();
573         ThreadManagement::UnlockParser();
574
575         processCommand(_pSEI);
576         FREE(command);
577     }
578     while (ConfigVariable::getForceQuit() == false);
579
580     return NULL;
581 }
582
583 //Thread used to parse and set console commands in storeCommand
584 void* scilabReadAndStore(void* param)
585 {
586     Parser::ControlStatus controlStatus = Parser::AllControlClosed;
587
588     char *command = NULL;
589     wchar_t* parserErrorMsg = NULL;
590
591     ScilabEngineInfo* _pSEI = (ScilabEngineInfo*)param;
592
593     if (_pSEI->iMultiLine)
594     {
595         command = _pSEI->pstExec;
596     }
597
598     if (isEmptyCommandQueue() == false)
599     {
600         // unlock main thread
601         ThreadManagement::SendStartPendingSignal();
602
603         // Command stored as console command by -f
604         // We have to wait this execution before
605         // callOnPrompt (ie: onPrompt perform a quit in test_run)
606         ThreadManagement::WaitForConsoleExecDoneSignal();
607     }
608
609     // unlock main thread
610     ThreadManagement::SendStartPendingSignal();
611
612     while (ConfigVariable::getForceQuit() == false)
613     {
614         callOnPrompt();
615
616         Parser parser;
617         parser.setParseTrace(_pSEI->iParseTrace != 0);
618
619         Parser::ParserStatus exitStatus = Parser::Failed;
620
621         if (ConfigVariable::isPrintCompact() == false)
622         {
623             scilabWriteW(L"\n");
624         }
625
626         do
627         {
628             // Show Parser Sate before prompt
629             stateShow(controlStatus);
630
631             int pause = ConfigVariable::getPauseLevel();
632
633             //set prompt value
634             C2F(setprlev) (&pause);
635
636             ConfigVariable::setScilabCommand(1);
637             scilabRead();
638             if (ConfigVariable::isScilabCommand() == 0)
639             {
640                 // happens when the return of scilabRead is used
641                 // in other thread (ie: call mscanf in a callback)
642                 ThreadManagement::WaitForConsoleExecDoneSignal();
643                 continue;
644             }
645
646             char* pstRead = ConfigVariable::getConsoleReadStr();
647             if (command == NULL)
648             {
649                 command = pstRead;
650                 if (strcmp(command, "") == 0)
651                 {
652                     FREE(command);
653                     command = NULL;
654                     break;
655                 }
656 #ifdef DEBUG_THREAD
657                 ThreadManagement::PrintDebugHead();
658 #endif // DEBUG_THREAD
659             }
660             else
661             {
662                 if (ConfigVariable::isExecutionBreak())
663                 {
664                     //clean parser state and close opened instruction.
665                     if (parser.getControlStatus() != Parser::AllControlClosed)
666                     {
667                         parser.cleanup();
668                         FREE(command);
669                         command = NULL;
670                         parser.setControlStatus(Parser::AllControlClosed);
671                         controlStatus = parser.getControlStatus();
672                     }
673
674                     ConfigVariable::resetExecutionBreak();
675                     break;
676                 }
677                 else
678                 {
679                     //+1 for null termination and +1 for '\n'
680                     size_t iLen = strlen(command) + strlen(pstRead) + 2;
681                     char *pstNewCommand = (char *)MALLOC(iLen * sizeof(char));
682
683 #ifdef _MSC_VER
684                     sprintf_s(pstNewCommand, iLen, "%s\n%s", command, pstRead);
685 #else
686                     sprintf(pstNewCommand, "%s\n%s", command, pstRead);
687 #endif
688                     FREE(pstRead);
689                     FREE(command);
690                     command = pstNewCommand;
691                 }
692             }
693
694             if (ConfigVariable::getEnableDebug())
695             {
696                 bool disableDebug = false;
697                 char* tmpCommand = NULL;
698                 int commandsize = strlen(command);
699
700                 //all commands must be prefixed by debug except e(xec) (r)un or p(rint) "something" that become "something" or disp("something")
701                 if (strncmp(command, "e ", 2) == 0 || strncmp(command, "r ", 2) == 0)
702                 {
703                     tmpCommand = os_strdup(command + 2);
704                 }
705                 else if (commandsize >= 5 && strncmp(command, "exec ", 5) == 0)
706                 {
707                     tmpCommand = os_strdup(command + 5);
708                 }
709                 else if (commandsize >= 4 && strncmp(command, "run ", 4) == 0)
710                 {
711                     tmpCommand = os_strdup(command + 5);
712                 }
713
714                 if (tmpCommand)
715                 {
716                     if (debugger::DebuggerMagager::getInstance()->isInterrupted())
717                     {
718                         sciprint(_("Debugger is on a breakpoint\n"));
719                         sciprint(_("(c)ontinue or (a)bort current execution before execute a new command\n"));
720                         continue;
721                     }
722                 }
723                 else if (commandsize > 1 && command[0] == 'd' && command[1] == ' ')
724                 {
725                     std::string s("disp(");
726                     s += command + 2;
727                     s += ")";
728                     tmpCommand = os_strdup(s.data());
729                     disableDebug = true;
730                 }
731                 else if (commandsize > 5 && strncmp(command, "disp ", 5) == 0)
732                 {
733                     std::string s("disp(");
734                     s += command + 5;
735                     s += ")";
736                     tmpCommand = os_strdup(s.data());
737                     disableDebug = true;
738                 }
739                 else if (commandsize > 1 && command[0] == 'p' && command[1] == ' ')
740                 {
741                         std::string s("disp(");
742                         s += command + 2;
743                         s += ")";
744                         tmpCommand = os_strdup(s.data());
745                         disableDebug = true;
746                 }
747                 else if (commandsize > 6 && strncmp(command, "print ", 6) == 0)
748                 {
749                     std::string s("disp(");
750                     s += command + 6;
751                     s += ")";
752                     tmpCommand = os_strdup(s.data());
753                     disableDebug = true;
754                 }
755                 else
756                 {
757                     int iLen = (int)strlen(command) + (int)strlen("debug ") + 1;
758                     tmpCommand = (char*)MALLOC(sizeof(char) * iLen);
759 #ifdef _MSC_VER
760                     os_sprintf(tmpCommand, iLen, "%s %s", "debug", command);
761 #else
762                     os_sprintf(tmpCommand, "%s %s", "debug", command);
763 #endif
764                     disableDebug = true;
765                 }
766
767                 if (disableDebug)
768                 {
769                     //disable debugger time to exec debug command
770                     //it will be enable in debuggervisitor, after execution
771                     ConfigVariable::setEnableDebug(false);
772                 }
773
774                 FREE(command);
775                 command = tmpCommand;
776             }
777
778             ThreadManagement::LockParser();
779             parseCommandTask(&parser, _pSEI->iTimed != 0, command);
780             controlStatus = parser.getControlStatus();
781             exitStatus = parser.getExitStatus();
782             parserErrorMsg = parser.getErrorMessage();
783             if (parser.getTree())
784             {
785                 delete parser.getTree();
786                 parser.setTree(NULL);
787             }
788             ThreadManagement::UnlockParser();
789         }
790         while (controlStatus != Parser::AllControlClosed);
791
792         if (command == NULL)
793         {
794             continue;
795         }
796
797         if (exitStatus == Parser::Failed)
798         {
799             FREE(command);
800             command = NULL;
801             scilabForcedWriteW(parserErrorMsg);
802             continue;
803         }
804
805         // store the command and wait for this execution ends.
806         StoreConsoleCommand(command, 1);
807
808         FREE(command);
809         command = NULL;
810     }
811
812     // Awake scilabReadAndExecCommand thread in case of scilab exit
813     ThreadManagement::SendCommandStoredSignal();
814     return NULL;
815 }
816
817 /*
818 ** -*- Interactive Main -*-
819 */
820 static int interactiveMain(ScilabEngineInfo* _pSEI)
821 {
822 #ifndef WITH_GUI
823 #ifndef _MSC_VER
824     if (getScilabMode() != SCILAB_NWNI)
825     {
826         fprintf(stderr, "Scilab was compiled without its GUI and advanced features. Run scilab-cli or use the -nwni option.\n");
827         initConsoleMode(ATTR_RESET);
828         exit(1);
829     }
830 #endif
831 #endif
832
833     InitializeHistoryManager();
834
835     if (getScilabMode() != SCILAB_NWNI && getScilabMode() != SCILAB_API)
836     {
837
838         char *cwd = NULL;
839
840         int err = 0;
841
842         UpdateBrowseVar();
843         cwd = scigetcwd(&err);
844         if (cwd)
845         {
846             FileBrowserChDir(cwd);
847             FREE(cwd);
848         }
849     }
850
851     // -e -quit with parser error, command queue is empty
852     if (_pSEI->iForceQuit && isEmptyCommandQueue())
853     {
854         return 1;
855     }
856
857     __threadId threadIdConsole;
858     __threadKey threadKeyConsole;
859     __threadId threadIdCommand;
860     __threadKey threadKeyCommand;
861
862     if (_pSEI->iStartConsoleThread)
863     {
864         // thread to manage console command
865         __CreateThreadWithParams(&threadIdConsole, &threadKeyConsole, &scilabReadAndStore, _pSEI);
866
867         // scilabReadAndStore thread must be execute before scilabReadAndExecCommand
868         // to be such that the -f command stored is not removed
869         // from queue before scilabReadAndStore is waiting for.
870         ThreadManagement::WaitForStartPendingSignal();
871     }
872
873     // thread to manage command stored
874     __CreateThreadWithParams(&threadIdCommand, &threadKeyCommand, &scilabReadAndExecCommand, _pSEI);
875
876 #ifdef DEBUG_THREAD
877     ThreadManagement::SetThreadKey( __GetCurrentThreadKey(), threadKeyCommand, threadKeyConsole);
878 #endif // DEBUG_THREAD
879
880     int iRet = 0;
881     do
882     {
883         // wait for available runner
884         ThreadManagement::WaitForRunMeSignal();
885
886         try
887         {
888             iRet = StaticRunner::launch();
889         }
890         catch (const ast::InternalAbort& /*ia*/)
891         {
892             // go out when exit/quit is called
893             iRet = ConfigVariable::getExitStatus();
894         }
895         catch (const ast::RecursionException& /*re*/)
896         {
897             // go out when exit/quit is called
898             iRet = 1;
899         }
900
901         ThreadManagement::SendAwakeRunnerSignal();
902     }
903     while (ConfigVariable::getForceQuit() == false);
904
905     return iRet;
906 }
907
908 /*
909 ** -*- Batch Main -*-
910 */
911 static int batchMain(ScilabEngineInfo* _pSEI)
912 {
913     /*
914      ** -*- PARSING -*-
915      */
916     Parser *parser = new Parser();
917
918     parser->setParseTrace(_pSEI->iParseTrace != 0);
919
920     wchar_t *pwstFileName = to_wide_string(_pSEI->pstParseFile);
921
922     /*
923      ** -*- PARSING -*-
924      */
925     parseFileTask(parser, _pSEI->iTimed != 0, pwstFileName, L"scilab 6");
926
927     /*
928      ** -*- DUMPING TREE -*-
929      */
930     if (_pSEI->iDumpAst)
931     {
932         dumpAstTask(parser->getTree(), _pSEI->iTimed != 0);
933     }
934
935     if (parser->getExitStatus() == Parser::Succeded)
936     {
937         /*
938          ** -*- PRETTY PRINT TREE -*-
939          */
940         if (_pSEI->iPrintAst)
941         {
942             printAstTask(parser->getTree(), _pSEI->iTimed != 0);
943         }
944
945     }
946     else
947     {
948         scilabWriteW(parser->getErrorMessage());
949     }
950
951 #ifdef DEBUG
952     std::cerr << "To end program press [ENTER]" << std::endl;
953 #endif
954     return parser->getExitStatus();
955 }
956
957 /*
958 ** -*- stateView
959 */
960 static void stateShow(Parser::ControlStatus status)
961 {
962     if (status != Parser::AllControlClosed)
963     {
964         SetTemporaryPrompt("  > ");
965     }
966 }
967
968 static int InitializeEnvironnement(void)
969 {
970     SetScilabEnvironment();
971     InitializeLocalization();
972
973     ConfigVariable::setConsoleWidth(75);
974     ConfigVariable::setFormatSize(10);
975     ConfigVariable::setFormatMode(1);
976     //Add_All_Variables();
977     FileManager::initialize();
978     initOperationArray();
979     return 0;
980 }
981
982 /*
983  * Private function to check any linker errors
984  */
985
986 static void checkForLinkerErrors(void)
987 {
988 #ifndef _MSC_VER
989     /*
990        Depending on the linking order, sometime, libs are not loaded the right way.
991        This can cause painful debugging tasks for packager or developer, we are
992        doing the check to help them.
993     */
994 #define LINKER_ERROR_1 "Scilab startup function detected that the function proposed to the engine is the wrong one. Usually, it comes from a linker problem in your distribution/OS.\n"
995 #define LINKER_ERROR_2 "If you do not know what it means, please report a bug on http://bugzilla.scilab.org/. If you do, you probably know that you should change the link order in SCI/modules/Makefile.am\n"
996
997     if (getScilabMode() != SCILAB_NWNI && getScilabMode() != SCILAB_API)
998     {
999         if (isItTheDisabledLib())
1000         {
1001             fprintf(stderr, LINKER_ERROR_1);
1002             fprintf(stderr, "Here, Scilab should have 'libscijvm' defined but gets 'libscijvm-disable' instead.\n");
1003             fprintf(stderr, LINKER_ERROR_2);
1004             exit(1);
1005         }
1006     }
1007     else
1008     {
1009         /* NWNI mode */
1010         if (!isItTheDisabledLib())
1011         {
1012             fprintf(stderr, LINKER_ERROR_1);
1013             fprintf(stderr, "Here, Scilab should have 'libscijvm-disable' defined but gets 'libscijvm' instead.\n");
1014             fprintf(stderr, LINKER_ERROR_2);
1015             exit(1);
1016         }
1017     }
1018 #undef LINKER_ERROR_1
1019 #undef LINKER_ERROR_2
1020 #endif
1021 }
1022
1023 static void Add_All_Variables(void)
1024 {
1025     Add_pi();
1026     Add_eps();
1027     Add_e();
1028     Add_i();
1029     Add_s();
1030     Add_z();
1031     Add_gui();
1032     Add_fftw();
1033     Add_Nan();
1034     Add_Inf();
1035     Add_io();
1036 }
1037
1038 static void Add_Nan(void)
1039 {
1040     double dbl1 = -1.0;
1041     double dbl0 = fabs(dbl1 - dbl1);
1042
1043     Add_Double_Constant(L"%nan", dbl0 / dbl0, 0, false);
1044 }
1045
1046 static void Add_Inf(void)
1047 {
1048     double dbl1 = 1.0;
1049     double dbl0 = dbl1 - dbl1;
1050
1051     Add_Double_Constant(L"%inf", dbl1 / dbl0, 0, false);
1052 }
1053
1054 static void Add_gui(void)
1055 {
1056     Add_Boolean_Constant(L"%gui", false);
1057 }
1058
1059 static void Add_fftw(void)
1060 {
1061     Add_Boolean_Constant(L"%fftw", withfftw() == 1);
1062 }
1063
1064 static void Add_pi(void)
1065 {
1066     Add_Double_Constant(L"%pi", M_PI, 0, false);
1067 }
1068
1069 static void Add_eps(void)
1070 {
1071     Add_Double_Constant(L"%eps", NumericConstants::eps_machine, 0, false);
1072 }
1073
1074 static void Add_e(void)
1075 {
1076     Add_Double_Constant(L"%e", 2.71828182845904530, 0, false);
1077 }
1078
1079 static void Add_i(void)
1080 {
1081     Add_Double_Constant(L"%i", 0, 1, true);
1082 }
1083
1084 static void Add_s(void)
1085 {
1086     types::Double dblCoef(1, 2);
1087
1088     dblCoef.set(0, 0, 0);
1089     dblCoef.set(0, 1, 1);
1090
1091     Add_Poly_Constant(L"%s", L"s", 1, &dblCoef);
1092 }
1093
1094 static void Add_z(void)
1095 {
1096     types::Double dblCoef(1, 2);
1097
1098     dblCoef.set(0, 0, 0);
1099     dblCoef.set(0, 1, 1);
1100
1101     Add_Poly_Constant(L"%z", L"z", 1, &dblCoef);
1102 }
1103
1104 static void Add_io(void)
1105 {
1106     types::Double * pVal = new types::Double(1, 2);
1107     pVal->set(0, 5);
1108     pVal->set(1, 6);
1109     symbol::Context::getInstance()->put(symbol::Symbol(L"%io"), pVal);
1110 }
1111
1112 static void Add_Poly_Constant(const std::wstring& _szName, const std::wstring& _szPolyVar, int _iRank, types::Double * _pdbl)
1113 {
1114     types::Polynom * pVar = new types::Polynom(_szPolyVar, 1, 1, &_iRank);
1115     types::SinglePoly *poPoly = pVar->get(0);
1116
1117     poPoly->setCoef(_pdbl);
1118     symbol::Context::getInstance()->put(symbol::Symbol(_szName), pVar);
1119 }
1120
1121 static void Add_Double_Constant(const std::wstring& _szName, double _dblReal, double _dblImg, bool _bComplex)
1122 {
1123     types::Double * pVal = new types::Double(1, 1, _bComplex);
1124     pVal->set(0, 0, _dblReal);
1125     pVal->setImg(0, 0, _dblImg);
1126     symbol::Context::getInstance()->put(symbol::Symbol(_szName), pVal);
1127 }
1128
1129 static void Add_Boolean_Constant(const std::wstring& _szName, bool _bBool)
1130 {
1131     types::Bool * pVal = new types::Bool(_bBool);
1132     symbol::Context::getInstance()->put(symbol::Symbol(_szName), pVal);
1133 }
1134
1135 static void Add_String_Constant(const std::wstring& _szName, const char *_pstString)
1136 {
1137     types::String * ps = new types::String(_pstString);
1138     symbol::Context::getInstance()->put(symbol::Symbol(_szName), ps);
1139 }