thread management fixed.
[scilab.git] / scilab / modules / tclsci / src / c / ScilabEval.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2005-2008 - INRIA - Allan CORNET
4  * Copyright (C) 2008-2008 - INRIA - Bruno JOFRET
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.1-en.txt
11  *
12  */
13 #include <string.h>
14 #include "machine.h"
15 #include "TCL_Global.h"
16 #include "ScilabEval.h"
17 #include "sciprint.h"
18 #include "sciprint_full.h"
19 #include "Scierror.h"
20 #include "localization.h"
21 #include "syncexec.h"
22 #include "storeCommand.h"
23 #include "os_string.h"
24 /*--------------------------------------------------------------------------*/
25 /* what's the max number of commands in the queue ??*/
26 #define arbitrary_max_queued_callbacks 20
27 #define AddCharacters 4
28 /*--------------------------------------------------------------------------*/
29 /* Used by tksynchro
30  * static int c_n1 = -1;
31  */
32 /*--------------------------------------------------------------------------*/
33 int TCL_EvalScilabCmd(ClientData clientData, Tcl_Interp * theinterp, int objc, CONST char ** argv)
34 {
35     int ierr = 0, seq = 0;
36     wchar_t *pwstCommand = NULL;
37     char *pstCommand = NULL;
38
39     wchar_t* pwstComm = NULL;
40     char *comm[arbitrary_max_queued_callbacks];
41     int   seqf[arbitrary_max_queued_callbacks];
42     int nc, ncomm = -1;
43
44     if (C2F(iop).ddt == -1)
45     {
46         /* trace for debugging */
47         int argc = 1;
48         char *msg = _("TCL_EvalScilabCmd %s");
49
50         sciprint_full(msg, argv[1]);
51
52         while (argv[++argc])
53         {
54             sciprint(" %s", argv[argc]);
55         }
56         sciprint("\n");
57
58     }
59
60     if (argv[1] != (char *)0)
61     {
62         pwstCommand = to_wide_string(argv[1]);
63         pstCommand = os_strdup(argv[1]);
64
65         if (pwstCommand == NULL || pstCommand == NULL)
66         {
67             sciprint(_("%s: No more memory.\n"), "TCL_EvalScilabCmd");
68             return TCL_ERROR;
69         }
70
71
72         if ( (argv[2] != (char *)0) && (strncmp(argv[2], "sync", 4) == 0) )
73         {
74             /* sync or sync seq
75              * TODO : Scilab is supposed to be busy there. Add mutex lock...
76              * C2F(tksynchro)(&c_n1);
77              * set sciprompt to -1 (scilab busy)
78              */
79             seq = ( (argv[3] != (char *)0) && (strncmp(argv[3], "seq", 3) == 0) );
80
81             if (C2F(iop).ddt == -1)
82             {
83                 char *msg = _("Execution starts for %s");
84                 sciprint_full(msg, pstCommand);
85                 sciprint("\n");
86             }
87
88             /*
89             int ns=(int)strlen(command);
90             Was : syncexec(command,&ns,&ierr,&seq,ns);
91             So far as Tcl has it's own thread now mixing global values
92             and threads within parse makes Scilab crash often.
93             */
94             //            StorePrioritaryCommandWithFlag(pwstCommand, seq);
95             ierr = 0;
96
97             if (C2F(iop).ddt == -1)
98             {
99                 char *msg = _("Execution ends for %s");
100                 sciprint_full(msg, pstCommand);
101                 sciprint("\n");
102             }
103             // TODO : Scilab is supposed to be busy there. Add mutex lock...
104             // C2F(tksynchro)(&C2F(recu).paus);
105             if (ierr != 0)
106             {
107                 return TCL_ERROR;
108             }
109         }
110         else if (strncmp(pstCommand, "flush", 5) == 0)
111         {
112             /* flush */
113             if (C2F(iop).ddt == -1)
114             {
115                 sciprint(_(" Flushing starts for queued commands.\n"));
116             }
117             while (ismenu() && ncomm < arbitrary_max_queued_callbacks - 1)
118             {
119                 ncomm++;
120                 comm[ncomm] = (char *) MALLOC (bsiz + 1);
121                 if (comm[ncomm] == (char *) 0)
122                 {
123                     sciprint(_("%s: No more memory.\n"), "TCL_EvalScilabCmd");
124                     FREE(pwstCommand);
125                     FREE(pstCommand);
126                     return TCL_ERROR;
127                 }
128                 //                seqf[ncomm] = GetCommand (comm[ncomm]);
129             }
130             if (ismenu())
131             {
132                 sciprint(_("Warning: Too many callbacks in queue!\n"));
133             }
134             for (nc = 0 ; nc <= ncomm ; nc++ )
135             {
136                 // TODO : Scilab is supposed to be busy there. Add mutex lock...
137                 // C2F(tksynchro)(&c_n1);  // set sciprompt to -1 (scilab busy)
138                 if (C2F(iop).ddt == -1)
139                 {
140                     if (seqf[nc] == 0)
141                     {
142                         char *msg = _("Flushed execution starts for %s - No option");
143                         sciprint_full(msg, comm[nc]);
144                         sciprint("\n");
145                     }
146                     else
147                     {
148                         char *msg = _("Flushed execution starts for %s - seq");
149                         sciprint_full(msg, comm[nc]);
150                         sciprint("\n");
151                     }
152                 }
153                 /*
154                 Was : syncexec(comm[nc],&ns,&ierr,&(seqf[nc]),ns);
155                 So far as Tcl has it's own thread now mixing global values
156                 and threads within parse makes Scilab crash often.
157                 */
158                 pwstComm = to_wide_string(comm[nc]);
159                 //                StorePrioritaryCommandWithFlag(pwstComm, seqf[nc]);
160                 FREE(pwstComm);
161                 if (C2F(iop).ddt == -1)
162                 {
163                     char *msg = _("Flushed execution ends for %s");
164                     sciprint_full(msg, comm[nc]);
165                     sciprint("\n");
166                 }
167                 FREE(comm[nc]);
168                 // TODO : Scilab is supposed to be busy there. Add mutex lock...
169                 // C2F(tksynchro)(&C2F(recu).paus);
170                 if (ierr != 0)
171                 {
172                     return TCL_ERROR;
173                 }
174             }
175             if (C2F(iop).ddt == -1)
176             {
177                 sciprint(_("Flushing ends\n"));
178             }
179         }
180         else
181         {
182             if ( (argv[2] != (char *)0) && (strncmp(argv[2], "seq", 3) == 0) )
183             {
184                 /* seq */
185                 //                StoreCommandWithFlag(pwstCommand, 1);
186             }
187             else
188             {
189                 /* no option or unknown option (TODO: no error for this latter case?) */
190                 //                StoreCommand(pwstCommand);
191                 Tcl_SetResult(theinterp, NULL, NULL);
192             }
193         }
194         FREE(pwstCommand);
195         FREE(pstCommand);
196
197     }
198     else
199     {
200         /* ScilabEval called without argument */
201         Scierror(999, _("%s: Wrong number of input argument(s): at least one expected.\n"), "TCL_EvalScilabCmd");
202     }
203
204     return TCL_OK;
205 }