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