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         {
185             strncpy(JOB, lastjob, nbcharsJOB);
186         }
187         return TRUE;
188     }
189     return FALSE;
190 }
191
192 /*--------------------------------------------------------------------------*/
193 int SendScilabJobs(char **jobs, int numberjobs)
194 {
195 #define BUFFERSECURITYSIZE 64
196
197     int retcode = -10;
198
199     if (jobs)
200     {
201         int i = 0;
202         int nbcharsjobs = 0;
203         char *bufCommands = NULL;
204         char **LOCALJOBS = NULL;
205
206         int jobsloop = 0;
207
208         LOCALJOBS = (char **)MALLOC(sizeof(char *) * numberjobs);
209
210         if (LOCALJOBS)
211         {
212             for (i = 0; i < numberjobs; i++)
213             {
214                 if (jobs[i])
215                 {
216                     nbcharsjobs = nbcharsjobs + (int)strlen(jobs[i]);
217                     LOCALJOBS[i] = (char *)MALLOC(sizeof(char) * (strlen(jobs[i]) + BUFFERSECURITYSIZE));
218                     if (LOCALJOBS[i])
219                     {
220                         strcpy(LOCALJOBS[i], jobs[i]);
221                     }
222                     else
223                     {
224                         CleanBuffers(bufCommands, LOCALJOBS, numberjobs);
225                         fprintf(stderr, "Error: SendScilabJobs (1) 'LOCALJOBS[%d] MALLOC'.\n", i);
226                         return retcode;
227                     }
228                 }
229                 else
230                 {
231                     fprintf(stderr, "Error: SendScilabJobs (2) 'jobs[%d] == NULL'.\n", i);
232                     FREE(LOCALJOBS);
233                     return retcode;
234                 }
235             }
236
237             bufCommands = (char *)MALLOC(sizeof(char) * (nbcharsjobs + numberjobs + BUFFERSECURITYSIZE));
238
239             if (bufCommands)
240             {
241                 strcpy(bufCommands, "");
242
243                 for (jobsloop = 0; jobsloop < numberjobs; jobsloop++)
244                 {
245                     if (jobs[jobsloop])
246                     {
247                         char *currentline = NULL;
248                         BOOL AddSemiColon;
249
250                         if (jobsloop == 0)
251                         {
252                             AddSemiColon = FALSE;
253                         }
254                         else
255                         {
256                             AddSemiColon = TRUE;
257                         }
258
259 DOTDOTLOOP:
260                         currentline = LOCALJOBS[jobsloop];
261
262                         RemoveCharsFromEOL(currentline, '\n');
263                         RemoveComments(currentline);
264                         RemoveCharsFromEOL(currentline, ' ');
265
266                         if (RemoveCharsFromEOL(currentline, '.'))
267                         {
268                             RemoveCharsFromEOL(currentline, ' ');
269                             strcat(bufCommands, currentline);
270                             jobsloop++;
271                             AddSemiColon = FALSE;
272                             goto DOTDOTLOOP;
273                         }
274                         else
275                         {
276                             if (!AddSemiColon)
277                             {
278                                 strcat(currentline, ";");
279                             }
280                             else
281                             {
282                                 strcat(bufCommands, ";");
283                             }
284
285                             strcat(bufCommands, currentline);
286                         }
287                     }
288                 }
289
290                 retcode = SendScilabJob(bufCommands);
291                 CleanBuffers(bufCommands, LOCALJOBS, numberjobs);
292             }
293             else
294             {
295                 CleanBuffers(bufCommands, LOCALJOBS, numberjobs);
296                 fprintf(stderr, "Error: SendScilabJobs (3) 'bufCommands MALLOC'.\n");
297                 return retcode;
298             }
299         }
300         else
301         {
302             CleanBuffers(bufCommands, LOCALJOBS, numberjobs);
303             fprintf(stderr, "Error: SendScilabJobs (4) 'LOCALJOBS == NULL'.\n");
304             return retcode;
305         }
306     }
307     else
308     {
309         fprintf(stderr, "Error: SendScilabJobs (5) 'jobs == NULL'.\n");
310         retcode = -10;
311     }
312
313     return retcode;
314 }
315
316 /*--------------------------------------------------------------------------*/
317 static BOOL RemoveCharsFromEOL(char *line, char CharToRemove)
318 {
319     int l = 0;
320     BOOL bOK = FALSE;
321     int len = 0;
322
323     len = (int)strlen(line);
324     for (l = (len - 1); l > 0; l--)
325     {
326         if (line[l] == CharToRemove)
327         {
328             line[l] = '\0';
329             bOK = TRUE;
330         }
331         else
332         {
333             break;
334         }
335     }
336     return bOK;
337 }
338
339 /*--------------------------------------------------------------------------*/
340 static BOOL RemoveComments(char *line)
341 {
342     int l = 0;
343     int len = 0;
344     int idx = -1;
345
346     len = (int)strlen(line);
347     for (l = len - 1; l > 0; l--)
348     {
349         if (line[l] == '/')
350         {
351             if (l - 1 >= 0)
352             {
353                 if (line[l - 1] == '/')
354                 {
355                     idx = l - 1;
356                     l = l - 2;
357                 }
358             }
359         }
360     }
361
362     if (idx >= 0)
363     {
364         line[idx] = '\0';
365     }
366
367     return FALSE;
368 }
369
370 /*--------------------------------------------------------------------------*/
371 static BOOL CleanBuffers(char *bufCommands, char **LOCALJOBS, int numberjobs)
372 {
373     if (bufCommands)
374     {
375         FREE(bufCommands);
376         bufCommands = NULL;
377     }
378     freeArrayOfString(LOCALJOBS, numberjobs);
379     return TRUE;
380 }
381
382 /*--------------------------------------------------------------------------*/