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