Merge remote-tracking branch 'origin/5.4'
[scilab.git] / scilab / modules / call_scilab / src / c / SendScilabJobs.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2007 - INRIA - Allan CORNET
4 * Copyright (C) 2009-2010 - DIGITEO - Allan CORNET
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 #include <stdio.h>
14 #include <string.h>
15 #include "call_scilab.h"
16 #include "MALLOC.h"
17 #include "scirun.h"
18 #include "localization.h"
19 #include "freeArrayOfString.h"
20 #ifdef _MSC_VER
21 #include "strdup_windows.h"
22 #endif
23 #include "api_scilab.h"
24 #include "call_scilab_engine_state.h"
25 /*--------------------------------------------------------------------------*/
26 static BOOL RemoveCharsFromEOL(char *line, char CharToRemove);
27 static BOOL RemoveComments(char *line);
28 static BOOL CleanBuffers(char *bufCommands, char **LOCALJOBS, int numberjobs);
29 static BOOL SetLastJob(char *JOB);
30 static char *lastjob = NULL;
31
32 /*--------------------------------------------------------------------------*/
33 /* see call_scilab.h more information */
34 /*--------------------------------------------------------------------------*/
35 int SendScilabJob(char *job)
36 {
37     SciErr sciErr;
38     int retCode = -1;
39     char *command = NULL;
40
41 #define COMMAND_EXECSTR  "Err_Job = execstr(TMP_EXEC_STRING,\"errcatch\",\"n\");quit;"
42 #define COMMAND_CLEAR "clear TMP_EXEC_STRING;clear Err_Job;quit;"
43
44     if (getCallScilabEngineState() == CALL_SCILAB_ENGINE_STOP)
45     {
46         fprintf(stderr, "Error: SendScilabJob call_scilab engine not started.\n");
47         return retCode;
48     }
49
50     command = strdup(job);
51
52     if (command)
53     {
54         double Err_Job = 0.;
55         int m = 0, n = 0;
56
57         /* clear prev. Err , TMP_EXEC_STRING scilab variables */
58         C2F(scirun) (COMMAND_CLEAR, (long int)strlen(COMMAND_CLEAR));
59
60         SetLastJob(command);
61
62         /* Creation of a temp variable in Scilab which contains the command */
63         sciErr = createNamedMatrixOfString(pvApiCtx, "TMP_EXEC_STRING", 1, 1, &command);
64         if (sciErr.iErr)
65         {
66             printError(&sciErr, 0);
67             /* Problem */
68             fprintf(stderr, "Error: SendScilabJob (1) call_scilab failed to create the temporary variable 'TMP_EXEC_STRING'.\n");
69             retCode = -1;
70
71             if (command)
72             {
73                 FREE(command);
74                 command = NULL;
75             }
76
77             return retCode;
78         }
79
80         /* Run the command within an execstr */
81         C2F(scirun) (COMMAND_EXECSTR, (long int)strlen(COMMAND_EXECSTR));
82         sciErr = getNamedVarDimension(pvApiCtx, "Err_Job", &m, &n);
83         if (sciErr.iErr)
84         {
85             printError(&sciErr, 0);
86             fprintf(stderr, "Error: SendScilabJob (2) call_scilab failed to detect the temporary variable 'Err_Job' size.\n");
87             retCode = -2;
88
89             if (command)
90             {
91                 FREE(command);
92                 command = NULL;
93             }
94
95             return retCode;
96         }
97
98         if ((m != 1) && (n != 1))
99         {
100             fprintf(stderr, "Error: SendScilabJob (3) call_scilab detected a badly formated 'Err_Job' variable. Size [1,1] expected.\n");
101             retCode = -3;
102
103             if (command)
104             {
105                 FREE(command);
106                 command = NULL;
107             }
108
109             return retCode;
110         }
111
112         sciErr = readNamedMatrixOfDouble(pvApiCtx, "Err_Job", &m, &n, &Err_Job);
113         if (sciErr.iErr)
114         {
115             printError(&sciErr, 0);
116             fprintf(stderr, "Error: SendScilabJob (4) call_scilab failed to read the temporary variable 'Err_Job'.\n");
117             retCode = -4;
118
119             if (command)
120             {
121                 FREE(command);
122                 command = NULL;
123             }
124
125             return retCode;
126         }
127
128         if (command)
129         {
130             FREE(command);
131             command = NULL;
132         }
133
134         retCode = (int)Err_Job;
135
136         /* clear prev. Err , TMP_EXEC_STRING scilab variables */
137         C2F(scirun) (COMMAND_CLEAR, (long int)strlen(COMMAND_CLEAR));
138     }
139     else
140     {
141         fprintf(stderr, "Error: SendScilabJob (5) call_scilab failed to create the 'command' variable (MALLOC).\n");
142         retCode = -4;
143     }
144
145     return retCode;
146 }
147
148 /*--------------------------------------------------------------------------*/
149 static BOOL SetLastJob(char *JOB)
150 {
151     if (lastjob)
152     {
153         FREE(lastjob);
154         lastjob = NULL;
155     }
156
157     if (JOB)
158     {
159         lastjob = strdup(JOB);
160         if (lastjob)
161         {
162             return TRUE;
163         }
164     }
165     return FALSE;
166 }
167
168 /*--------------------------------------------------------------------------*/
169 BOOL GetLastJob(char *JOB, int nbcharsJOB)
170 {
171     if (JOB)
172     {
173         if ((int)strlen(lastjob) < nbcharsJOB)
174         {
175             strcpy(JOB, lastjob);
176         }
177         else
178         {
179             strncpy(JOB, lastjob, nbcharsJOB);
180         }
181         return TRUE;
182     }
183     return FALSE;
184 }
185
186 /*--------------------------------------------------------------------------*/
187 int SendScilabJobs(char **jobs, int numberjobs)
188 {
189 #define BUFFERSECURITYSIZE 64
190
191     int retcode = -10;
192
193     if (jobs)
194     {
195         int i = 0;
196         int nbcharsjobs = 0;
197         char *bufCommands = NULL;
198         char **LOCALJOBS = NULL;
199
200         int jobsloop = 0;
201
202         LOCALJOBS = (char **)MALLOC(sizeof(char *) * numberjobs);
203
204         if (LOCALJOBS)
205         {
206             for (i = 0; i < numberjobs; i++)
207             {
208                 if (jobs[i])
209                 {
210                     nbcharsjobs = nbcharsjobs + (int)strlen(jobs[i]);
211                     LOCALJOBS[i] = (char *)MALLOC(sizeof(char) * (strlen(jobs[i]) + BUFFERSECURITYSIZE));
212                     if (LOCALJOBS[i])
213                     {
214                         strcpy(LOCALJOBS[i], jobs[i]);
215                     }
216                     else
217                     {
218                         CleanBuffers(bufCommands, LOCALJOBS, numberjobs);
219                         fprintf(stderr, "Error: SendScilabJobs (1) 'LOCALJOBS[%d] MALLOC'.\n", i);
220                         return retcode;
221                     }
222                 }
223                 else
224                 {
225                     fprintf(stderr, "Error: SendScilabJobs (2) 'jobs[%d] == NULL'.\n", i);
226                     FREE(LOCALJOBS);
227                     return retcode;
228                 }
229             }
230
231             bufCommands = (char *)MALLOC(sizeof(char) * (nbcharsjobs + numberjobs + BUFFERSECURITYSIZE));
232
233             if (bufCommands)
234             {
235                 strcpy(bufCommands, "");
236
237                 for (jobsloop = 0; jobsloop < numberjobs; jobsloop++)
238                 {
239                     if (jobs[jobsloop])
240                     {
241                         char *currentline = NULL;
242                         BOOL AddSemiColon;
243
244                         if (jobsloop == 0)
245                         {
246                             AddSemiColon = FALSE;
247                         }
248                         else
249                         {
250                             AddSemiColon = TRUE;
251                         }
252
253 DOTDOTLOOP:
254                         currentline = LOCALJOBS[jobsloop];
255
256                         RemoveCharsFromEOL(currentline, '\n');
257                         RemoveComments(currentline);
258                         RemoveCharsFromEOL(currentline, ' ');
259
260                         if (RemoveCharsFromEOL(currentline, '.'))
261                         {
262                             RemoveCharsFromEOL(currentline, ' ');
263                             strcat(bufCommands, currentline);
264                             jobsloop++;
265                             AddSemiColon = FALSE;
266                             goto DOTDOTLOOP;
267                         }
268                         else
269                         {
270                             if (!AddSemiColon)
271                             {
272                                 strcat(currentline, ";");
273                             }
274                             else
275                             {
276                                 strcat(bufCommands, ";");
277                             }
278
279                             strcat(bufCommands, currentline);
280                         }
281                     }
282                 }
283
284                 retcode = SendScilabJob(bufCommands);
285                 CleanBuffers(bufCommands, LOCALJOBS, numberjobs);
286             }
287             else
288             {
289                 CleanBuffers(bufCommands, LOCALJOBS, numberjobs);
290                 fprintf(stderr, "Error: SendScilabJobs (3) 'bufCommands MALLOC'.\n");
291                 return retcode;
292             }
293         }
294         else
295         {
296             CleanBuffers(bufCommands, LOCALJOBS, numberjobs);
297             fprintf(stderr, "Error: SendScilabJobs (4) 'LOCALJOBS == NULL'.\n");
298             return retcode;
299         }
300     }
301     else
302     {
303         fprintf(stderr, "Error: SendScilabJobs (5) 'jobs == NULL'.\n");
304         retcode = -10;
305     }
306
307     return retcode;
308 }
309
310 /*--------------------------------------------------------------------------*/
311 static BOOL RemoveCharsFromEOL(char *line, char CharToRemove)
312 {
313     int l = 0;
314     BOOL bOK = FALSE;
315     int len = 0;
316
317     len = (int)strlen(line);
318     for (l = (len - 1); l > 0; l--)
319     {
320         if (line[l] == CharToRemove)
321         {
322             line[l] = '\0';
323             bOK = TRUE;
324         }
325         else
326         {
327             break;
328         }
329     }
330     return bOK;
331 }
332
333 /*--------------------------------------------------------------------------*/
334 static BOOL RemoveComments(char *line)
335 {
336     int l = 0;
337     int len = 0;
338     int idx = -1;
339
340     len = (int)strlen(line);
341     for (l = len - 1; l > 0; l--)
342     {
343         if (line[l] == '/')
344         {
345             if (l - 1 >= 0)
346             {
347                 if (line[l - 1] == '/')
348                 {
349                     idx = l - 1;
350                     l = l - 2;
351                 }
352             }
353         }
354     }
355
356     if (idx >= 0)
357     {
358         line[idx] = '\0';
359     }
360
361     return FALSE;
362 }
363
364 /*--------------------------------------------------------------------------*/
365 static BOOL CleanBuffers(char *bufCommands, char **LOCALJOBS, int numberjobs)
366 {
367     if (bufCommands)
368     {
369         FREE(bufCommands);
370         bufCommands = NULL;
371     }
372     freeArrayOfString(LOCALJOBS, numberjobs);
373     return TRUE;
374 }
375
376 /*--------------------------------------------------------------------------*/