Added Scilab function runVMKit to be used to change how the AST is visited.
[scilab.git] / scilab / modules / core / src / cpp / scilab.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2006-2008 - DIGITEO - Bruno JOFRET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12 #pragma comment(lib,"../../bin/libintl.lib")
13
14 #include <cstdio>
15 #include <iostream>
16 #include <string.h>
17
18 extern "C"
19 {
20 #ifndef _MSC_VER
21 #include <unistd.h>
22 #include "initConsoleMode.h"
23 #endif
24 #include "LaunchScilabSignal.h"
25 #include "signal_mgmt.h"
26
27     //#include "SetScilabEnvironment.h"
28 #include "prompt.h"
29 #include "InitializeLocalization.h"
30 #include "MALLOC.h"
31 #include "sci_path.h"
32 #include "inisci-c.h"
33 #include "sci_mode.h"
34 #ifdef _MSC_VER
35 #include "../src/c/scilab_windows/getScilabDirectory.h"
36 #endif
37 #include "ConsoleRead.h"
38 #include "../../../console/includes/InitializeConsole.h"
39 #include "../../../jvm/includes/InitializeJVM.h"
40 #include "InitializeCore.h"
41 #include "../../../console/includes/InitializeConsole.h"
42 #include "../../../tclsci/includes/InitializeTclTk.h"
43 #include "../../../localization/includes/InitializeLocalization.h"
44 #include "../../../graphics/includes/graphicModuleLoad.h"
45 #include "../../../jvm/includes/InitializeJVM.h"
46 #ifdef _MSC_VER
47 #include "../../../windows_tools/includes/InitializeWindows_tools.h"
48 #endif
49 #include "../../../gui/includes/InitializeGUI.h"
50 #include "../../../string/includes/InitializeString.h"
51 #include "../../../jvm/includes/loadBackGroundClassPath.h"
52
53 #include "HistoryManager.h"
54 #include "InitializeHistoryManager.h"
55 #include "TerminateHistoryManager.h"
56 #include "getCommentDateSession.h"
57 #include "os_swprintf.h"
58 #include "os_strdup.h"
59 #include "localization.h"
60 #include "diary.h"
61 #include "PATH_MAX.h"
62 #include "sci_tmpdir.h"
63 #include "deleteafile.h"
64 #include "setgetlanguage.h"
65 #include "scilabRead.h"
66 #include "elem_common.h"
67 #include "inittypenames.h"
68
69 #ifdef __APPLE__
70 #include "initMacOSXEnv.h"
71 #endif
72
73 #if defined(linux) && defined(__i386__)
74 #include "setPrecisionFPU.h"
75 #endif
76
77     /*
78     ** HACK HACK HACK
79     */
80     extern char *getCmdLine(void);
81 }
82
83 #include "string.hxx"
84 #include "polynom.hxx"
85 #include "double.hxx"
86
87 #include "scilabWrite.hxx"
88 #include "tasks.hxx"
89 #include "parser.hxx"
90 #include "context.hxx"
91 #include "configvariable.hxx"
92 #include "setenvvar.hxx"
93 #include "funcmanager.hxx"
94 #include "filemanager.hxx"
95 #include "runner.hxx"
96
97 #if defined(VMKIT_ENABLED)
98 #include <vmkit_core.h>
99 #endif
100
101 #define INTERACTIVE     -1
102
103 const wchar_t *prog_name;
104 const wchar_t *file_name;
105
106 bool parseTrace = false;
107 bool printAst = false;
108 bool execAst = true;
109 bool dumpAst = false;
110 bool dumpStack = false;
111 bool timed = false;
112 bool ASTtimed = false;
113 bool execVerbose = false;
114 bool consoleMode = false;
115 bool noJvm = false;
116 bool noStart = false;
117 bool noBanner = false;
118 bool execCommand = false;
119 bool execFile = false;
120 bool parseFile = false;
121
122 bool ASTrunVMKit = false;
123
124 using symbol::Context;
125 using std::string;
126
127 static void Add_i(void);
128 static void Add_pi(void);
129 static void Add_eps(void);
130 static void Add_e(void);
131 static void Add_s(void);
132 static void Add_z(void);
133 static void Add_true(void);
134 static void Add_false(void);
135 static void Add_Nan(void);
136 static void Add_Inf(void);
137 static void Add_WITH_DEMOS(void);      //temporary variable
138 static void Add_All_Variables(void);
139
140 static void Add_Double_Constant(wstring _szName, double _dblReal, double _dblImg, bool _bComplex);
141 static void Add_Poly_Constant(wstring _szName, wstring _szPolyVar, int _iRank, Double * _pdblReal);
142 static void Add_Boolean_Constant(wstring _szName, bool _bBool);
143 static void Add_String_Constant(wstring _szName, const char *_pstString);
144
145 int InitializeEnvironnement(void);
146 bool execScilabStart(void);
147
148 int StartScilabEngine(int argc, char *argv[], int iFileIndex, int iLangIndex);
149 static Parser::ControlStatus processCommand(char *_pstCommand);
150
151 #if defined(VMKIT_ENABLED)
152 namespace VMKitScilab {
153         void ScilabThread::setArgs(int argc, char** argv, int iFileIndex, int iLangIndex){
154                 this->argc = argc;
155                 this->argv = argv;
156                 this->iFileIndex = iFileIndex;
157                 this->iLangIndex = iLangIndex;
158         }
159         void ScilabThread::setret(int ret){
160                 this->ret = ret;
161         }
162         int ScilabThread::getargc(){
163                 return argc;
164         }
165         int ScilabThread::getiFileIndex(){
166                 return iFileIndex;
167         }
168         int ScilabThread::getiLangIndex(){
169                 return iLangIndex;
170         }
171         char **ScilabThread::getargv(){
172                 return argv;
173         }
174         int ScilabThread::getret(){
175                 return ret;
176         }
177         ScilabThread::ScilabThread (ScilabVM* vm) : vmkit::MutatorThread(){
178                 MyVM = (vmkit::VirtualMachine*)vm;
179         }
180         ScilabVM* ScilabThread::vm(){
181                 return (ScilabVM *)MyVM;
182         }
183         void ScilabThread::execute(){
184                 setret(StartScilabEngine(getargc(), getargv(), getiFileIndex(), getiLangIndex()));
185         }
186
187         void ScilabVM::mainStart(ScilabThread* thread){
188                 ScilabVM* vm = thread->vm();
189                 printf("\nVMKitThread: Create\n\n");
190
191                 thread->execute();
192
193                 vm->setret(thread->getret());
194
195                 printf("\nVMKitThread: Exit\n\n");
196                 vm->exit();
197         }
198         void ScilabVM::runApplication(int argc, char** argv, int iFileIndex, int iLangIndex){
199                 VMKitScilab::ScilabThread * mainThread = new VMKitScilab::ScilabThread(this);
200
201                 mainThread->setArgs(argc, argv, iFileIndex, iLangIndex);
202
203                 mainThread->start((void (*)(vmkit::Thread *))mainStart);
204         }
205
206         int ScilabVM::getret(){
207                 return ret;
208         }
209
210         void ScilabVM::setret(int ret){
211                 this->ret = ret;
212         }
213 }
214 #endif
215
216 /*
217  * Private function to check any linker errors
218  */
219
220 extern "C"
221 {
222     /* Defined without include to avoid useless header dependency */
223     extern BOOL isItTheDisabledLib(void);
224 }
225
226 static void checkForLinkerErrors(void)
227 {
228 #ifndef _MSC_VER
229     /*
230        Depending on the linking order, sometime, libs are not loaded the right way.
231        This can cause painful debugging tasks for packager or developer, we are
232        doing the check to help them.
233     */
234 #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"
235 #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"
236
237     if (getScilabMode() != SCILAB_NWNI)
238     {
239         if (isItTheDisabledLib())
240         {
241             fprintf(stderr, LINKER_ERROR_1);
242             fprintf(stderr, "Here, Scilab should have 'libscijvm' defined but gets 'libscijvm-disable' instead.\n");
243             fprintf(stderr, LINKER_ERROR_2);
244             exit(1);
245
246         }
247     }
248     else
249     {
250         /* NWNI mode */
251         if (!isItTheDisabledLib())
252         {
253             fprintf(stderr, LINKER_ERROR_1);
254             fprintf(stderr, "Here, Scilab should have 'libscijvm-disable' defined but gets 'libscijvm' instead.\n");
255             fprintf(stderr, LINKER_ERROR_2);
256             exit(1);
257         }
258     }
259 #undef LINKER_ERROR_1
260 #undef LINKER_ERROR_2
261 #endif
262 }
263
264 /*
265 ** Usage
266 **
267 ** Display usage : options available in YaSp
268 */
269 static void usage(void)
270 {
271     std::cerr << "Usage: " << prog_name << " <options>" << std::endl;
272     std::cerr << "      -f file          : Batch mode on the given file." << std::endl;
273     std::cerr << "      -l lang          : Change the language of scilab ( default : en_US )." << std::endl;
274     std::cerr << "      -nw              : Enable console mode." << std::endl;
275     std::cerr << "      -nwni            : Enable terminal mode." << std::endl;
276     std::cerr << "      -ns              : Don't execute etc/scilab.start." << std::endl;
277     std::cerr << "      --help           : Display this help." << std::endl;
278     std::cerr << "Developer Trace arguments:" << std::endl;
279     std::cerr << "      --parse-trace    : Display bison state machine evolution." << std::endl;
280     std::cerr << "      --AST-trace      : Display ASCII-art AST to be human readable." << std::endl;
281     std::cerr << "      --pretty-print   : Display pretty-printed code, standard Scilab syntax." << std::endl;
282     std::cerr << " " << std::endl;
283     std::cerr << "Developer Timer arguments:" << std::endl;
284     std::cerr << "      --AST-timed      : Time each AST node." << std::endl;
285     std::cerr << "      --timed          : Time global execution." << std::endl;
286     std::cerr << " " << std::endl;
287     std::cerr << "Developer Debug arguments:" << std::endl;
288     std::cerr << "      --no-exec        : Only do Lexing/parsing do not execute instructions." << std::endl;
289     std::cerr << "      --context-dump   : Display context status." << std::endl;
290     std::cerr << "      --exec-verbose   : Display command before running it." << std::endl;
291 }
292
293 /*
294 ** Get Options
295 **
296 **
297 */
298 static int get_option(const int argc, char *argv[], int *_piFileIndex, int *_piLangIndex)
299 {
300     int i = 0;
301
302 #ifdef DEBUG
303     std::cerr << "-*- Getting Options -*-" << std::endl;
304 #endif
305
306     for (i = 1; i < argc; ++i)
307     {
308         if (!strcmp("--parse-trace", argv[i]))
309         {
310             parseTrace = true;
311         }
312         else if (!strcmp("--pretty-print", argv[i]))
313         {
314             printAst = true;
315         }
316         else if (!strcmp("--help", argv[i]))
317         {
318             usage();
319             exit(WELL_DONE);
320         }
321         else if (!strcmp("--AST-trace", argv[i]))
322         {
323             dumpAst = true;
324         }
325         else if (!strcmp("--no-exec", argv[i]))
326         {
327             execAst = false;
328         }
329         else if (!strcmp("--context-dump", argv[i]))
330         {
331             dumpStack = true;
332         }
333         else if (!strcmp("--timed", argv[i]))
334         {
335             timed = true;
336         }
337         else if (!strcmp("--AST-timed", argv[i]))
338         {
339             std::cout << "Timed execution" << std::endl;
340             ASTtimed = true;
341         }
342         else if (!strcmp("--parse-file", argv[i]))
343         {
344             i++;
345             parseFile = true;
346             *_piFileIndex = i;
347         }
348         else if (!strcmp("-f", argv[i]))
349         {
350             i++;
351             execFile = true;
352             *_piFileIndex = i;
353         }
354         else if (!strcmp("-e", argv[i]))
355         {
356             i++;
357             execCommand = true;
358             *_piFileIndex = i;
359         }
360         else if (!strcmp("-l", argv[i]))
361         {
362             i++;
363             *_piLangIndex = i;
364         }
365         else if (!strcmp("-nw", argv[i]))
366         {
367             consoleMode = true;
368             setScilabMode(SCILAB_NW);
369         }
370         else if (!strcmp("-nwni", argv[i]))
371         {
372             consoleMode = true;
373             noJvm = true;
374             setScilabMode(SCILAB_NWNI);
375         }
376         else if (!strcmp("-ns", argv[i]))
377         {
378             noStart = true;
379         }
380         else if (!strcmp("-nb", argv[i]))
381         {
382             noBanner = true;
383         }
384         else if (!strcmp("--exec-verbose", argv[i]))
385         {
386             execVerbose = true;
387         }
388     }
389
390 #ifdef DEBUG
391     if (*_piFileIndex >= 0) {
392         std::cerr << "File : " << argv[*_piFileIndex] << std::endl;
393     }
394 #endif
395
396     ConfigVariable::setCommandLineArgs(argc, argv);
397     return 0;
398 }
399
400 /*
401 ** HACK HACK HACK
402 */
403
404 extern "C"
405 {
406 #include <stdio.h>
407
408 #ifndef _MSC_VER
409 #include <unistd.h>
410 #endif
411     extern char *getCmdLine(void);
412     extern void ConsolePrintf(char *);
413 }
414
415 /*
416 ** -*- stateView
417 ** Used to show parser state.
418 ** Find if we are stuck within some control structure.
419 */
420
421 static void stateShow(Parser::ControlStatus status)
422 {
423     switch (status)
424     {
425         case Parser::WithinFor:
426             SetTemporaryPrompt("-for       ->");
427             break;
428         case Parser::WithinWhile:
429             SetTemporaryPrompt("-while     ->");
430             break;
431         case Parser::WithinIf:
432             SetTemporaryPrompt("-if        ->");
433             break;
434         case Parser::WithinElse:
435             SetTemporaryPrompt("-else      ->");
436             break;
437         case Parser::WithinElseIf:
438             SetTemporaryPrompt("-elseif    ->");
439             break;
440         case Parser::WithinTry:
441             SetTemporaryPrompt("-try       ->");
442             break;
443         case Parser::WithinCatch:
444             SetTemporaryPrompt("-catch     ->");
445             break;
446         case Parser::WithinFunction:
447             SetTemporaryPrompt("-function  ->");
448             break;
449         case Parser::WithinSelect:
450             SetTemporaryPrompt("-select    ->");
451             break;
452         case Parser::WithinCase:
453             SetTemporaryPrompt("-case      ->");
454             break;
455         case Parser::WithinSwitch:
456             SetTemporaryPrompt("-switch    ->");
457             break;
458         case Parser::WithinOtherwise:
459             SetTemporaryPrompt("-otherwise ->");
460             break;
461         case Parser::WithinMatrix:
462             SetTemporaryPrompt("- [        ->");
463             break;
464         case Parser::WithinCell:
465             SetTemporaryPrompt("- {        ->");
466             break;
467         case Parser::WithinBlockComment:
468             SetTemporaryPrompt("- /*       ->");
469             break;
470         case Parser::WithinDots:
471             SetTemporaryPrompt("- ...      ->");
472             break;
473         case Parser::AllControlClosed:
474             ClearTemporaryPrompt();
475             break;
476     }
477 }
478
479 /*
480 ** -*- Interactive Main -*-
481 */
482 static int interactiveMain(void)
483 {
484     int pause = 0;
485     char *command = NULL;
486
487     Parser::ControlStatus controlStatus = Parser::AllControlClosed;
488
489 #ifndef WITH_GUI
490 #ifndef _MSC_VER
491     if (getScilabMode() != SCILAB_NWNI)
492     {
493         fprintf(stderr, "Scilab was compiled without its GUI and advanced features. Run scilab-cli or us the -nwni option.\n");
494         initConsoleMode(ATTR_RESET);
495         exit(1);
496     }
497 #endif
498 #endif
499
500     if (noBanner == false)
501     {
502         //banner();
503     }
504
505     InitializeHistoryManager();
506
507     //before calling reader, try to call %onprompt function
508     callOnPrompt();
509
510     while (!ConfigVariable::getForceQuit())
511     {
512         // Show Parser Sate before prompt
513         stateShow(controlStatus);
514
515         pause = ConfigVariable::getPauseLevel();
516
517         //set prompt value
518         C2F(setprlev) (&pause);
519
520         if (controlStatus == Parser::AllControlClosed)
521         {
522             if (command)
523             {
524                 FREE(command);
525                 command = NULL;
526             }
527             scilabWriteW(L"\n");
528             command = scilabRead();
529         }
530         else
531         {
532             char *pstRead = scilabRead();
533
534             //+1 for null termination and +1 for '\n'
535             size_t iLen = strlen(command) + strlen(pstRead) + 2;
536             char *pstNewCommand = (char *)MALLOC(iLen * sizeof(char));
537
538 #ifdef _MSC_VER
539             sprintf_s(pstNewCommand, iLen, "%s\n%s", command, pstRead);
540 #else
541             sprintf(pstNewCommand, "%s\n%s", command, pstRead);
542 #endif
543             FREE(pstRead);
544             FREE(command);
545             command = pstNewCommand;
546         }
547
548         controlStatus = processCommand(command);
549     }
550 #ifdef DEBUG
551     std::cerr << "To end program press [ENTER]" << std::endl;
552 #endif
553     return ConfigVariable::getExitStatus();
554 }
555
556 static Parser::ControlStatus processCommand(char *_pstCommand)
557 {
558     Parser *parser = new Parser();
559
560     parser->setParseTrace(parseTrace);
561     if (strcmp(_pstCommand, "") != 0)
562     {
563         wchar_t *pwstCommand = to_wide_string(_pstCommand);
564
565         /*
566          ** -*- PARSING -*-
567          */
568         parseCommandTask(parser, timed, pwstCommand);
569
570         /*
571          ** -*- DUMPING TREE -*-
572          */
573         if (dumpAst == true)
574         {
575             dumpAstTask(parser->getTree(), timed);
576         }
577
578         if (parser->getExitStatus() == Parser::Succeded)
579         {
580             /*
581              ** -*- PRETTY PRINT TREE -*-
582              */
583             if (printAst == true)
584             {
585                 printAstTask(parser->getTree(), timed);
586             }
587
588             /*
589              ** -*- EXECUTING TREE -*-
590              */
591             if (execAst == true)
592             {
593                 //before calling YaspReader, try to call %onprompt function
594                 callOnPrompt();
595                 execAstTask(parser->getTree(), timed, ASTtimed, execVerbose, ASTrunVMKit);
596             }
597
598             /*
599              ** -*- DUMPING STACK AFTER EXECUTION -*-
600              */
601             if (dumpStack == true)
602             {
603                 dumpStackTask(timed);
604             }
605         }
606         else if (parser->getExitStatus() == Parser::Failed && parser->getControlStatus() == Parser::AllControlClosed)
607         {
608             if (execAst == true)
609             {
610                 //before calling YaspReader, try to call %onprompt function
611                 callOnPrompt();
612             }
613
614             scilabWriteW(parser->getErrorMessage());
615         }
616
617         FREE(pwstCommand);
618     }
619     else
620     {
621         if (execAst == true)
622         {
623             //before calling YaspReader, try to call %onprompt function
624             callOnPrompt();
625         }
626     }
627     return parser->getControlStatus();
628 }
629
630 static void TermPrintf(char *text)
631 {
632     //std::cout << text;
633     printf("%s", text);
634 }
635
636 /*
637 ** -*- MAIN -*-
638 */
639 int main(int argc, char *argv[])
640 {
641     int iFileIndex = INTERACTIVE;
642     int iLangIndex = 0;
643
644     prog_name = to_wide_string(argv[0]);
645
646
647     InitializeLaunchScilabSignal();
648
649     /* This bug only occurs under Linux 32 bits
650      * See: http://wiki.scilab.org/Scilab_precision
651      */
652 #if defined(linux) && defined(__i386__)
653     setFPUToDouble();
654 #endif
655
656 #ifndef _MSC_VER
657     /* Management of the signals (seg fault, floating point exception, etc) */
658     if (getenv("SCI_DISABLE_EXCEPTION_CATCHING") == NULL)
659     {
660         base_error_init();
661     }
662 #endif
663
664 #if defined(netbsd) || defined(freebsd)
665     /* floating point exceptions */
666     fpsetmask(0);
667 #endif
668
669 #ifdef WITHOUT_GUI
670     /* Building Scilab-cli-bin. We won't ever had the gui nor the jvm */
671     consoleMode = true;
672     noJvm = true;
673     setScilabMode(SCILAB_NWNI);
674 #else
675     setScilabMode(SCILAB_STD);
676 #endif
677
678     get_option(argc, argv, &iFileIndex, &iLangIndex);
679
680     if (iFileIndex >= argc || iLangIndex >= argc)
681     {
682         // we used -l, -e or -f without another argument
683         usage();
684         return -1;
685     }
686
687     // if WITHOUT_GUI is defined
688     // force Terminal IO -> Terminal IO + StartScilabEngine
689
690     // WITHOUT_GUI (All Platform) => Terminal IO + StartScilabEngine
691     // GUI (MacOSX) =>      [no option]     -> Console IO + InitMacOSXEnv
692     //                      | [-nwni]       -> Terminal IO + StartScilabEngine
693     //                      | [-nw]         -> Terminal IO + InitMacOSXEnv
694 #ifndef WITHOUT_GUI
695     if (consoleMode)
696     {
697         setScilabInputMethod(&getCmdLine);
698         setScilabOutputMethod(&TermPrintf);
699 #if defined(__APPLE__)
700         if (!noJvm)
701         {
702             return initMacOSXEnv(argc, argv, iFileIndex);
703         }
704 #endif // !defined(__APPLE__)
705         return StartScilabEngine(argc, argv, iFileIndex, iLangIndex);
706     }
707     else
708     {
709         setScilabInputMethod(&ConsoleRead);
710         setScilabOutputMethod(&ConsolePrintf);
711 #if defined(__APPLE__)
712         return initMacOSXEnv(argc, argv, iFileIndex);
713 #else
714         return StartScilabEngine(argc, argv, iFileIndex, iLangIndex);
715 #endif // !defined(__APPLE__)
716     }
717 #else
718     setScilabInputMethod(&getCmdLine);
719     setScilabOutputMethod(&TermPrintf);
720 #if defined(VMKIT_ENABLED)
721     vmkit::CompiledFrames** frametables;
722     vmkit::BumpPtrAllocator Allocator;
723
724     VMKitScilab::ScilabVM* vm = new(Allocator, "VM") VMKitScilab::ScilabVM (Allocator, frametables);
725
726     vm->runApplication(argc, argv, iFileIndex, iLangIndex);
727
728     vm->waitForExit();
729
730     return vm->getret();
731
732 #else
733     return StartScilabEngine(argc, argv, iFileIndex, iLangIndex);
734 #endif // ifdef VMKIT_ENABLED
735 #endif // defined(WITHOUT_GUI)
736 }
737
738 /*
739 ** -*- Batch Main -*-
740 */
741 static int batchMain(char *pstFileName)
742 {
743     /*
744      ** -*- PARSING -*-
745      */
746     Parser *parser = new Parser();
747
748     parser->setParseTrace(parseTrace);
749
750     wchar_t *pwstFileName = to_wide_string(pstFileName);
751
752     /*
753      ** -*- PARSING -*-
754      */
755     parseFileTask(parser, timed, pwstFileName, L"YaSp");
756
757     /*
758      ** -*- DUMPING TREE -*-
759      */
760     if (dumpAst == true)
761     {
762         dumpAstTask(parser->getTree(), timed);
763     }
764
765     if (parser->getExitStatus() == Parser::Succeded)
766     {
767         /*
768          ** -*- PRETTY PRINT TREE -*-
769          */
770         if (printAst == true)
771         {
772             printAstTask(parser->getTree(), timed);
773         }
774
775     }
776     else
777     {
778         scilabWriteW(parser->getErrorMessage());
779     }
780
781 #ifdef DEBUG
782     std::cerr << "To end program press [ENTER]" << std::endl;
783 #endif
784     return parser->getExitStatus();
785 }
786
787 int StartScilabEngine(int argc, char *argv[], int iFileIndex, int iLangIndex)
788 {
789     int iMainRet = 0;
790
791     Runner::init();
792
793     checkForLinkerErrors();
794
795     /* Scilab Startup */
796     InitializeEnvironnement();
797
798     if (iLangIndex)
799     {
800         wchar_t *pwstLang = to_wide_string(argv[iLangIndex]);
801
802         setlanguage(pwstLang);
803         FREE(pwstLang);
804     }
805
806     InitializeString();
807
808 #ifdef _MSC_VER
809     InitializeWindows_tools();
810 #endif
811
812     //InitializeCore();
813
814     if (!noJvm)
815     {
816         /* bug 3702 */
817         /* tclsci creates a TK window on Windows */
818         /* it changes focus on previous windows */
819         /* we put InitializeTclTk before InitializeGUI */
820
821         //InitializeTclTk();
822         InitializeJVM();
823         InitializeGUI();
824
825         /* create needed data structure if not already created */
826         loadGraphicModule();
827
828         loadBackGroundClassPath();
829     }
830
831     /* Standard mode -> init Java Console */
832     if (!consoleMode)
833     {
834         /* Initialize console: lines... */
835         InitializeConsole();
836     }
837     else
838     {
839 #ifndef _MSC_VER
840         initConsoleMode(RAW);
841 #endif
842     }
843
844     /* set current language of scilab */
845     FuncManager *pFM = new FuncManager();
846
847     pFM->LoadModules(noStart);
848
849     //execute scilab.start
850     if (noStart == false)
851     {
852         execScilabStartTask();
853     }
854
855     C2F(inittypenames)();
856
857     int pause = 0;
858
859     //set prompt value
860     C2F(setprlev) (&pause);
861
862     ConfigVariable::setPromptMode(0);
863     try
864     {
865         if (execCommand)
866         {
867             //-e option
868
869             processCommand(argv[iFileIndex]);
870         }
871         else if (execFile)
872         {
873             //-f option execute exec('%s',-1)
874             char *pstCommand = (char *)MALLOC(sizeof(char) * (strlen("exec(\"\",-1)") + strlen(argv[iFileIndex]) + 1));
875
876             sprintf(pstCommand, "exec(\"%s\",-1)", argv[iFileIndex]);
877             processCommand(pstCommand);
878             FREE(pstCommand);
879         }
880     }
881     catch (ScilabException se)
882     {
883         scilabErrorW(se.GetErrorMessage().c_str());
884     }
885
886     ConfigVariable::setStartFinished(true);
887     ConfigVariable::setPromptMode(2);
888     if (!parseFile)
889     {
890         //always run as interactiveMain even after -e or -f option
891         file_name = L"prompt";
892         iMainRet = interactiveMain();
893     }
894     else
895     {
896         // Only for parsing test, won't execute anything.
897         iMainRet = batchMain(argv[iFileIndex]);
898     }
899
900     //execute scilab.quit
901     if (noStart == false)
902     {
903         execScilabQuitTask();
904     }
905     //close main scope
906     symbol::Context::getInstance()->scope_end();
907     delete pFM;
908
909     /* Remove TMPDIR before exit */
910     clearTMPDIR();
911
912     /* Reset terminal configuration */
913     if (consoleMode)
914     {
915 #ifndef _MSC_VER
916         initConsoleMode(ATTR_RESET);
917 #endif
918     }
919
920     return iMainRet;
921 }
922
923 int InitializeEnvironnement(void)
924 {
925     SetScilabEnvironment();
926     InitializeLocalization();
927
928     ConfigVariable::setConsoleWidth(75);
929     ConfigVariable::setFormatSize(10);
930     ConfigVariable::setFormatMode(1);
931     Add_All_Variables();
932     FileManager::initialize();
933     return 0;
934 }
935
936 static void Add_All_Variables(void)
937 {
938     Add_pi();
939     Add_eps();
940     Add_e();
941     Add_i();
942     Add_s();
943     Add_z();
944     Add_true();
945     Add_false();
946     Add_Nan();
947     Add_Inf();
948     Add_WITH_DEMOS();
949 }
950
951 static void Add_WITH_DEMOS(void)
952 {
953     Add_Boolean_Constant(L"WITH_DEMOS", false);
954 }
955
956 static void Add_Nan(void)
957 {
958     double dbl1 = 1.0;
959     double dbl0 = dbl1 - dbl1;
960
961     Add_Double_Constant(L"%nan", dbl0 / dbl0, 0, false);
962 }
963
964 static void Add_Inf(void)
965 {
966     double dbl1 = 1.0;
967     double dbl0 = dbl1 - dbl1;
968
969     Add_Double_Constant(L"%inf", dbl1 / dbl0, 0, false);
970 }
971
972 static void Add_false(void)
973 {
974     Add_Boolean_Constant(L"%f", false);
975 }
976
977 static void Add_true(void)
978 {
979     Add_Boolean_Constant(L"%t", true);
980 }
981
982 static void Add_pi(void)
983 {
984     Add_Double_Constant(L"%pi", 3.1415926535897931159980, 0, false);
985 }
986
987 static void Add_eps(void)
988 {
989     Add_Double_Constant(L"%eps", C2F(dlamch) ("p", 1L), 0, false);
990 }
991
992 static void Add_e(void)
993 {
994     Add_Double_Constant(L"%e", 2.71828182845904530, 0, false);
995 }
996
997 static void Add_i(void)
998 {
999     Add_Double_Constant(L"%i", 0, 1, true);
1000 }
1001
1002 static void Add_s(void)
1003 {
1004     Double dblCoef(1, 2);
1005
1006     dblCoef.set(0, 0, 0);
1007     dblCoef.set(0, 1, 1);
1008
1009     Add_Poly_Constant(L"%s", L"s", 2, &dblCoef);
1010 }
1011
1012 static void Add_z(void)
1013 {
1014     Double dblCoef(1, 2);
1015
1016     dblCoef.set(0, 0, 0);
1017     dblCoef.set(0, 1, 1);
1018
1019     Add_Poly_Constant(L"%z", L"z", 2, &dblCoef);
1020 }
1021
1022 static void Add_Poly_Constant(wstring _szName, wstring _szPolyVar, int _iRank, Double * _pdbl)
1023 {
1024     types::Polynom * pVar = new types::Polynom(_szPolyVar, 1, 1, &_iRank);
1025     SinglePoly *poPoly = pVar->get(0, 0);
1026
1027     poPoly->setCoef(_pdbl);
1028     Context::getInstance()->put(symbol::Symbol(_szName), *pVar);
1029 }
1030
1031 static void Add_Double_Constant(wstring _szName, double _dblReal, double _dblImg, bool _bComplex)
1032 {
1033     types::Double * pVal = new types::Double(1, 1, _bComplex);
1034     pVal->set(0, 0, _dblReal);
1035     pVal->setImg(0, 0, _dblImg);
1036     symbol::Context::getInstance()->put(symbol::Symbol(_szName), *pVal);
1037 }
1038
1039 static void Add_Boolean_Constant(wstring _szName, bool _bBool)
1040 {
1041     types::Bool * pVal = new types::Bool(_bBool);
1042     symbol::Context::getInstance()->put(symbol::Symbol(_szName), *pVal);
1043 }
1044
1045 static void Add_String_Constant(wstring _szName, const char *_pstString)
1046 {
1047     types::String * ps = new types::String(_pstString);
1048     symbol::Context::getInstance()->put(symbol::Symbol(_szName), *ps);
1049 }