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