93856b4853848b3f9bf38a71ba5509e3520f3c06
[scilab.git] / scilab / modules / call_scilab / src / c / call_scilab.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2005 - INRIA - Allan CORNET
4 * Copyright (C) 2010 - DIGITEO - Allan CORNET
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 #include <string.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include "BOOL.h"
21 #include "call_scilab.h"
22 #include "lasterror.h"          /* clearInternalLastError, getInternalLastErrorValue */
23 #include "sci_malloc.h"
24 #include "configvariable_interface.h"
25 #include "fromc.h"
26 #include "isdir.h"
27 #include "sci_path.h"
28 #include "scilabDefaults.h"
29 #include "sci_tmpdir.h"
30 #include "Thread_Wrapper.h"
31 #include "storeCommand.h"
32 #include "FigureList.h"
33 #include "api_scilab.h"
34 #include "call_scilab_engine_state.h"
35 #include "os_string.h"
36 #include "charEncoding.h"
37 #include "InitScilab.h"
38 #include "scilabRead.h"
39 #include "scilabWrite.hxx"
40
41 #ifdef _MSC_VER
42 #include "SetScilabEnvironmentVariables.h"
43 #include "getScilabDirectory.h"
44 #include <Windows.h>
45 #endif
46
47 extern char *getCmdLine(void);
48
49 static void TermPrintf(const char *text)
50 {
51     //std::cout << text;
52     printf("%s", text);
53 }
54
55 static ScilabEngineInfo* pGlobalSEI = NULL;
56 static __threadId threadIdScilab;
57
58 /*--------------------------------------------------------------------------*/
59 static CALL_SCILAB_ENGINE_STATE csEngineState = CALL_SCILAB_ENGINE_STOP;
60 /*--------------------------------------------------------------------------*/
61 void DisableInteractiveMode(void)
62 {
63     setScilabMode(SCILAB_NWNI);
64 }
65
66 /*--------------------------------------------------------------------------*/
67 BOOL StartScilab(char *SCIpath, char *ScilabStartup, int Stacksize)
68 {
69     return Call_ScilabOpen(SCIpath, TRUE, ScilabStartup, Stacksize) == 0;
70 }
71
72 /*--------------------------------------------------------------------------*/
73 /**
74 * Start Scilab engine
75 * Function created in the context of javasci v2.
76 * This function is just like StartScilab but provides more error messages
77 * in case or error. For now, it is only used in javasci v2 but it might
78 * be public sooner or later.
79 * @return
80 * 0: success
81 * -1: already running
82 * -2: Could not find SCI
83 * -3: No existing directory
84 * Any other positive integer: A Scilab internal error
85 */
86
87 #define FORMAT_SCRIPT_STARTUP "_errorCall_ScilabOpen = exec(\"%s\", \"errcatch\", -1);"
88
89 int Call_ScilabOpen(char *SCIpath, BOOL advancedMode, char *ScilabStartup, int Stacksize)
90 {
91     __threadKey threadKeyScilab;
92     char *InitStringToScilab = NULL;
93     static int iflag = -1, ierr = 0;
94
95     if (advancedMode == FALSE)
96     {
97         DisableInteractiveMode();
98     }
99
100     if (getCallScilabEngineState() == CALL_SCILAB_ENGINE_STARTED)
101     {
102         return -1;
103     }
104
105     SetFromCToON();
106
107     if (SCIpath == NULL)        /* No SCIpath provided... */
108     {
109 #ifndef _MSC_VER
110         /* Other doesn't */
111         fprintf(stderr, "StartScilab: Could not find SCI\n");
112         return -2;
113 #endif
114     }
115     else
116     {
117         if (!isdir(SCIpath))
118         {
119             /* Check if the directory actually exists */
120             fprintf(stderr, "StartScilab: Could not find the directory %s\n", SCIpath);
121             return -3;
122         }
123     }
124
125     pGlobalSEI = InitScilabEngineInfo();
126     if (ScilabStartup)
127     {
128         int lengthStringToScilab = (int)(strlen(FORMAT_SCRIPT_STARTUP) + strlen(ScilabStartup) + 1);
129         InitStringToScilab = (char *)MALLOC(lengthStringToScilab * sizeof(char));
130         sprintf(InitStringToScilab, FORMAT_SCRIPT_STARTUP, ScilabStartup);
131         pGlobalSEI->iNoStart = 1;
132     }
133
134     setScilabInputMethod(&getCmdLine);
135     setScilabOutputMethod(&TermPrintf);
136
137     /* Scilab Initialization */
138     pGlobalSEI->pstFile = InitStringToScilab;
139     pGlobalSEI->iConsoleMode = 1;
140     pGlobalSEI->iStartConsoleThread = 0;
141
142     if (getScilabMode() != SCILAB_NWNI)
143     {
144         pGlobalSEI->iNoJvm = 1;
145     }
146
147     pGlobalSEI->iNoJvm = 0;
148
149     ierr = StartScilabEngine(pGlobalSEI);
150
151     if (InitStringToScilab)
152     {
153         FREE(InitStringToScilab);
154         InitStringToScilab = NULL;
155     }
156
157     if (ierr)
158     {
159         FREE(pGlobalSEI);
160         return ierr;
161     }
162
163     __CreateThreadWithParams(&threadIdScilab, &threadKeyScilab, &RunScilabEngine, pGlobalSEI);
164
165     setCallScilabEngineState(CALL_SCILAB_ENGINE_STARTED);
166
167     return 0;
168 }
169
170 /*--------------------------------------------------------------------------*/
171 BOOL TerminateScilab(char *ScilabQuit)
172 {
173     if (getCallScilabEngineState() == CALL_SCILAB_ENGINE_STARTED)
174     {
175         if (getForceQuit() == 0)
176         {
177             if (pGlobalSEI->iNoStart)
178             {
179                 StoreConsoleCommand("exit(_errorCall_ScilabOpen)", 0);
180             }
181             else
182             {
183                 StoreConsoleCommand("exit()", 0);
184             }
185         }
186
187         __WaitThreadDie(threadIdScilab);
188         pGlobalSEI->pstFile = ScilabQuit;
189         StopScilabEngine(pGlobalSEI);
190
191         setCallScilabEngineState(CALL_SCILAB_ENGINE_STOP);
192
193         /* restore default mode */
194         setScilabMode(SCILAB_API);
195
196         FREE(pGlobalSEI);
197         pGlobalSEI = NULL;
198
199         return TRUE;
200     }
201     return FALSE;
202 }
203
204 /*--------------------------------------------------------------------------*/
205 /**
206 * function called javasci
207 */
208 void ScilabDoOneEvent(void)
209 {
210     if (getCallScilabEngineState() == CALL_SCILAB_ENGINE_STARTED)
211     {
212         if (getScilabMode() != SCILAB_NWNI)
213         {
214 #if 0
215             C2F(scirun) ("quit;", (int)strlen("quit;"));
216 #endif
217         }
218     }
219 }
220
221 /*--------------------------------------------------------------------------*/
222 int ScilabHaveAGraph(void)
223 {
224     if (getCallScilabEngineState() == CALL_SCILAB_ENGINE_STARTED)
225     {
226         return sciHasFigures();
227     }
228     return 0;
229 }
230
231 /*--------------------------------------------------------------------------*/
232 CALL_SCILAB_ENGINE_STATE setCallScilabEngineState(CALL_SCILAB_ENGINE_STATE state)
233 {
234     csEngineState = state;
235     return csEngineState;
236 }
237
238 /*--------------------------------------------------------------------------*/
239 CALL_SCILAB_ENGINE_STATE getCallScilabEngineState(void)
240 {
241     return csEngineState;
242 }
243
244 /*--------------------------------------------------------------------------*/
245 sci_types getVariableType(char *varName)
246 {
247     int iSciType = -1;
248     SciErr sciErr = getNamedVarType(NULL, (char*)varName, &iSciType);
249
250     if (sciErr.iErr == API_ERROR_NAMED_UNDEFINED_VAR)
251     {
252         return (sci_types) - 2;
253     }
254
255     if (sciErr.iErr)
256     {
257         printError(&sciErr, 0);
258         return (sci_types) - 1;
259     }
260     return (sci_types) iSciType;
261 }
262
263 /*--------------------------------------------------------------------------*/
264
265 /**
266  * Call the Scilab function getLastErrorMessage
267  * Take the result (a matrix of string) and concatenate into a single string
268  * This is way easier to manage in swig.
269 */
270 char *getLastErrorMessageSingle(void)
271 {
272     return wide_string_to_UTF8(getLastErrorMessage());
273 }
274
275 /*--------------------------------------------------------------------------*/
276 int getLastErrorValue(void)
277 {
278     /* defined in lasterror.h */
279     return getLastErrorNumber();
280 }
281 /*--------------------------------------------------------------------------*/