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