95fe7df243f061bfd13b4ce8df9893c04aa6ac85
[scilab.git] / scilab / modules / startup / 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  *  Copyright (C) 2013 - Scilab Enterprises - Antoine ELIAS
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17
18 #ifdef _MSC_VER
19 #pragma comment(lib,"../../../../../bin/libintl.lib")
20 #endif
21
22 #include <cstdio>
23 #include <iostream>
24 #include <string.h>
25 #include <setjmp.h>
26
27 extern "C"
28 {
29 #ifdef __APPLE__
30 #include "initMacOSXEnv.h"
31 #endif
32 #include "InitScilab.h"
33 #include "configvariable_interface.h"
34 #include "scilabRead.h"
35 #include "ConsoleRead.h"
36 #include "version.h"
37 #include "sci_malloc.h"
38 #include "lasterror.h"
39 #include "getpipeline.h"
40
41     extern char *getCmdLine(void);
42
43 #ifdef _MSC_VER
44 #include "FilesAssociations.h"
45 #include "PATH_MAX.h"
46     jmp_buf ScilabJmpEnv;
47 #else
48     extern jmp_buf ScilabJmpEnv;
49 #endif
50 #include "isatty.hxx"
51 }
52
53 #include "configvariable.hxx"
54 #include "exit_status.hxx"
55 #include "scilabWrite.hxx"
56
57 #define INTERACTIVE     -1
58
59 extern "C"
60 {
61 #ifdef ENABLE_MPI
62 #include "initMPI.h"
63 #endif
64 }
65
66 /*
67 ** Usage
68 **
69 ** Display usage : options available
70 */
71 static void usage(void)
72 {
73     std::cerr << "Usage: Scilab <options>" << std::endl;
74     std::cerr << "      -e Instruction   : execute the scilab instruction given in Instruction argument.";
75     std::cerr << "                         -e and -f arguments are mutually exclusive.";
76     std::cerr << "      -f File          : execute the scilab script given in File argument.";
77     std::cerr << "                         -e and -f arguments are mutually exclusive.";
78     std::cerr << "      -quit            : force scilab exit after execution of script from -e or -f argument.";
79     std::cerr << "                         this flag is ignored if it is not used with -e or -f argument.";
80     std::cerr << "      -l lang          : Change the language of scilab ( default : en_US )." << std::endl;
81     std::cerr << "      -nw              : Enable console mode." << std::endl;
82     std::cerr << "      -nwni            : Enable terminal mode." << std::endl;
83     std::cerr << "      -ns              : Don't execute etc/scilab.start." << std::endl;
84     std::cerr << "      --help           : Display this help." << std::endl;
85     std::cerr << "Developer Trace arguments:" << std::endl;
86     std::cerr << "      --parse-trace    : Display bison state machine evolution." << std::endl;
87     std::cerr << "      --AST-trace      : Display ASCII-art AST to be human readable." << std::endl;
88     std::cerr << "      --pretty-print   : Display pretty-printed code, standard Scilab syntax." << std::endl;
89     std::cerr << " " << std::endl;
90     std::cerr << "Developer Timer arguments:" << std::endl;
91     std::cerr << "      --AST-timed      : Time each AST node." << std::endl;
92     std::cerr << "      --timed          : Time global execution." << std::endl;
93     std::cerr << " " << std::endl;
94     std::cerr << "Developer Debug arguments:" << std::endl;
95     std::cerr << "      --no-exec        : Only do Lexing/parsing do not execute instructions." << std::endl;
96     std::cerr << "      --context-dump   : Display context status." << std::endl;
97     std::cerr << "      --exec-verbose   : Display command before running it." << std::endl;
98 }
99
100 /*
101 ** Get Options
102 **
103 */
104 static int get_option(const int argc, char *argv[], ScilabEngineInfo* _pSEI)
105 {
106     int i = 0;
107
108 #ifdef DEBUG
109     std::cerr << "-*- Getting Options -*-" << std::endl;
110 #endif
111
112     for (i = 1; i < argc; ++i)
113     {
114         if (!strcmp("--parse-trace", argv[i]))
115         {
116             _pSEI->iParseTrace = 1;
117         }
118         else if (!strcmp("--pretty-print", argv[i]))
119         {
120             _pSEI->iPrintAst = 1;
121         }
122         else if (!strcmp("--help", argv[i]))
123         {
124             usage();
125             exit(WELL_DONE);
126         }
127         else if (!strcmp("--AST-trace", argv[i]))
128         {
129             _pSEI->iDumpAst = 1;
130         }
131         else if (!strcmp("--no-exec", argv[i]))
132         {
133             _pSEI->iExecAst = 0;
134         }
135         else if (!strcmp("--context-dump", argv[i]))
136         {
137             _pSEI->iDumpStack = 1;
138         }
139         else if (!strcmp("--timed", argv[i]))
140         {
141             _pSEI->iTimed = 1;
142             ConfigVariable::setTimed(true);
143         }
144         else if (!strcmp("--serialize", argv[i]))
145         {
146             _pSEI->iSerialize = 1;
147             ConfigVariable::setSerialize(true);
148         }
149         else if (!strcmp("--AST-timed", argv[i]))
150         {
151             std::cout << "Timed execution" << std::endl;
152             _pSEI->iAstTimed = 1;
153         }
154         else if (!strcmp("--parse-file", argv[i]))
155         {
156             i++;
157             if (argc >= i)
158             {
159                 _pSEI->pstParseFile = argv[i];
160             }
161         }
162         else if (!strcmp("-quit", argv[i]))
163         {
164             _pSEI->iForceQuit = 1;
165         }
166         else if (!strcmp("-version", argv[i]))
167         {
168             i++;
169             if (argc >= i)
170             {
171                 _pSEI->iShowVersion = 1;
172             }
173         }
174         else if (!strcmp("-f", argv[i]))
175         {
176             i++;
177             if (argc >= i)
178             {
179                 _pSEI->pstFile = argv[i];
180             }
181         }
182         else if (!strcmp("-e", argv[i]))
183         {
184             i++;
185             if (argc >= i)
186             {
187                 _pSEI->pstExec = argv[i];
188             }
189         }
190         else if (!strcmp("-O", argv[i]))
191         {
192             i++;
193             if (argc >= i)
194             {
195                 _pSEI->pstExec = argv[i];
196                 _pSEI->iCodeAction = 0;
197             }
198         }
199         else if (!strcmp("-X", argv[i]))
200         {
201             i++;
202             if (argc >= i)
203             {
204                 _pSEI->pstExec = argv[i];
205                 _pSEI->iCodeAction = 1;
206             }
207         }
208         else if (!strcmp("-P", argv[i]))
209         {
210             i++;
211             if (argc >= i)
212             {
213                 _pSEI->pstExec = argv[i];
214                 _pSEI->iCodeAction = 2;
215             }
216         }
217         else if (!strcmp("-l", argv[i]))
218         {
219             i++;
220             if (argc >= i)
221             {
222                 _pSEI->pstLang = argv[i];
223             }
224         }
225         else if (!strcmp("-nw", argv[i]))
226         {
227             _pSEI->iConsoleMode = 1;
228         }
229         else if (!strcmp("-nwni", argv[i]))
230         {
231             _pSEI->iConsoleMode = 1;
232             _pSEI->iNoJvm = 1;
233         }
234         else if (!strcmp("-ns", argv[i]))
235         {
236             _pSEI->iNoStart = 1;
237         }
238         else if (!strcmp("-nb", argv[i]))
239         {
240             _pSEI->iNoBanner = 0;
241         }
242         else if (!strcmp("--exec-verbose", argv[i]))
243         {
244             _pSEI->iExecVerbose = 1;
245         }
246         else if (!strcmp("-keepconsole", argv[i]))
247         {
248             _pSEI->iKeepConsole = 1;
249         }
250     }
251
252     ConfigVariable::setCommandLineArgs(argc, argv);
253     return 0;
254 }
255
256 extern "C"
257 {
258 #include <stdio.h>
259
260 #ifndef _MSC_VER
261 #include <unistd.h>
262 #endif
263     extern char *getCmdLine(void);
264     extern void ConsolePrintf(const char *);
265 }
266
267 static void TermPrintf(const char *text)
268 {
269     //std::cout << text;
270     printf("%s", text);
271 }
272
273 /*
274 ** -*- MAIN -*-
275 */
276 //#if defined(_WIN32) && !defined(WITHOUT_GUI)
277 //int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
278 //#else
279 int main(int argc, char *argv[])
280 //#endif
281 {
282     int iRet = 0;
283
284 #ifdef ENABLE_MPI
285     initScilabMPI();
286 #endif
287
288     ScilabEngineInfo* pSEI = InitScilabEngineInfo();
289 #ifdef WITHOUT_GUI
290     /* Building Scilab-cli-bin. We won't ever had the gui nor the jvm */
291     pSEI->iConsoleMode = 1;
292     pSEI->iNoJvm = 1;
293     setScilabMode(SCILAB_NWNI);
294 #else
295     setScilabMode(SCILAB_STD);
296 #endif
297
298     //#if defined(_WIN32) && !defined(WITHOUT_GUI)
299     //    {
300     //        LPSTR my_argv[256];
301     //        int nArgs = 0;
302     //        LPWSTR *szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
303     //        if (szArglist)
304     //        {
305     //            for (int i = 0; i < nArgs; i++)
306     //            {
307     //                my_argv[i] = wide_string_to_UTF8(szArglist[i]);
308     //            }
309     //            LocalFree(szArglist);
310     //        }
311     //        get_option(nArgs, my_argv, pSEI);
312     //    }
313     //#else
314     get_option(argc, argv, pSEI);
315     //#endif
316
317     // if WITHOUT_GUI is defined
318     // force Terminal IO -> Terminal IO + StartScilabEngine
319
320     // WITHOUT_GUI (All Platform) => Terminal IO + StartScilabEngine
321     // GUI (MacOSX) =>      [no option]     -> Console IO + InitMacOSXEnv
322     //                      | [-nwni]       -> Terminal IO + StartScilabEngine
323     //                      | [-nw]         -> Terminal IO + InitMacOSXEnv
324 #ifndef WITHOUT_GUI
325     if (pSEI->iConsoleMode)
326     {
327         setScilabMode(SCILAB_NW);
328         setScilabInputMethod(&getCmdLine);
329         setScilabOutputMethod(&TermPrintf);
330 #if defined(__APPLE__)
331         if (pSEI->iNoJvm == 0)
332         {
333             return initMacOSXEnv(pSEI);
334         }
335 #endif // !defined(__APPLE__)
336     }
337     else
338     {
339         setScilabMode(SCILAB_STD);
340         setScilabInputMethod(&ConsoleRead);
341         setScilabOutputMethod(&ConsolePrintf);
342
343 #ifdef _MSC_VER
344         if (pSEI->iCodeAction != -1)
345         {
346             //manage calls from explorer ( double click on sce file , ... )
347             char* Cmd = (char*)MALLOC(((PATH_MAX * 2) + 1) * sizeof(char));
348             strcpy(Cmd, "");
349             int ret = CommandByFileExtension(pSEI->pstExec, pSEI->iCodeAction, Cmd);
350
351             if (ret && Cmd[0] != '\0')
352             {
353                 pSEI->pstExec = Cmd; //Cmd must be freed in StartScilabEngine after process.
354             }
355             else
356             {
357                 pSEI->iCodeAction = -1;
358             }
359         }
360 #endif
361
362 #if defined(__APPLE__)
363         return initMacOSXEnv(pSEI);
364 #endif // !defined(__APPLE__)
365     }
366 #else
367     setScilabMode(SCILAB_NWNI);
368     setScilabInputMethod(&getCmdLine);
369     setScilabOutputMethod(&TermPrintf);
370 #endif // defined(WITHOUT_GUI)
371
372 #ifdef _MSC_VER
373     /* if file descriptor returned is -2 stdin is not associated with an input stream */
374     /* example : echo plot3d | scilex -nw -e */
375     if (!isatty(_fileno(stdin)) && (_fileno(stdin) != -2))
376 #else
377     if (!isatty(fileno(stdin)))
378 #endif
379     {
380         // We are in a pipe
381         setScilabInputMethod(&getPipeLine);
382     }
383
384     if (pSEI->iShowVersion == 1)
385     {
386         disp_scilab_version();
387         exit(0);
388     }
389
390     int val = setjmp(ScilabJmpEnv);
391     if (!val)
392     {
393         iRet = StartScilabEngine(pSEI);
394         if (iRet == 0)
395         {
396             iRet = RunScilabEngine(pSEI);
397         }
398
399         StopScilabEngine(pSEI);
400         FREE(pSEI);
401         return iRet;
402     }
403     else
404     {
405         // We probably had a segfault so print error
406         std::wcerr << getLastErrorMessage() << std::endl;
407         return val;
408     }
409 }
410