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