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