Merge remote-tracking branch 'origin/master' into JIMS
[scilab.git] / scilab / modules / ui_data / src / cpp / BrowseVarManager.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - DIGITEO - Allan CORNET
4  * Copyright (C) 2010 - DIGITEO - 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-en.txt
11  *
12  */
13
14 #include <iostream>
15 #include "BrowseVar.hxx"
16
17 #include <sstream>
18 #include <string>
19 #include <iterator>
20 using std::string;
21
22 #include <set>
23
24 extern "C"
25 {
26 #include <string.h>
27 #include "BrowseVarManager.h"
28 #include "localization.h"
29 #include "MALLOC.h"
30 #include "BOOL.h"
31 #include "stackinfo.h"
32 #include "api_scilab.h"
33 #include "getScilabJavaVM.h"
34 #include "Scierror.h"
35 #include "freeArrayOfString.h"
36 #include "sci_types.h"
37 #ifdef _MSC_VER
38 #include "strdup_windows.h"
39 #endif
40 }
41 using namespace org_scilab_modules_ui_data;
42
43 static std::set < string > createScilabDefaultVariablesSet();
44 static char * getListName(char * variableName);
45 static std::string formatMatrix(int nbRows, int nbCols, BOOL isComplex, double *pdblReal, double *pdblImg);
46 static char * valueToDisplay(char * variableName, int variableType, int nbRows, int nbCols);
47 void OpenBrowseVar()
48 {
49     BrowseVar::openVariableBrowser(getScilabJavaVM());
50     SetBrowseVarData();
51 }
52
53 void UpdateBrowseVar()
54 {
55     if (BrowseVar::isVariableBrowserOpened(getScilabJavaVM()))
56     {
57         SetBrowseVarData();
58     }
59 }
60
61 void SetBrowseVarData()
62 {
63     SciErr err;
64     int iGlobalVariablesUsed = 0;
65     int iGlobalVariablesTotal = 0;
66     int iLocalVariablesUsed = 0;
67     int iLocalVariablesTotal = 0;
68     int i = 0;
69
70     // First get how many global / local variable we have.
71     C2F(getvariablesinfo) (&iLocalVariablesTotal, &iLocalVariablesUsed);
72     C2F(getgvariablesinfo) (&iGlobalVariablesTotal, &iGlobalVariablesUsed);
73
74     char **pstAllVariableNames = (char **)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(char *));
75     char **pstAllVariableVisibility = (char **)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(char *));
76     char **pstAllVariableListTypes = (char **)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(char *));
77     int *piAllVariableBytes = (int *)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(int));
78     char **pstAllVariableSizes = (char **)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(char *));
79     int *piAllVariableTypes = (int *)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(int));
80     int *piAllVariableIntegerTypes = (int *)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(int));
81     bool *piAllVariableFromUser = (bool *) MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(bool));
82     /* Necessary for the plots in the var browser */
83     int *piAllVariableNbRows = (int *)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(int));
84     int *piAllVariableNbCols = (int *)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(int));
85
86     int nbRows, nbCols;
87     char *sizeStr = NULL;
88
89     std::set < string > scilabDefaultVariablesSet = createScilabDefaultVariablesSet();
90
91     // for each local variable get information
92     for (; i < iLocalVariablesUsed; ++i)
93     {
94         // name
95         pstAllVariableNames[i] = getLocalNamefromId(i + 1);
96         // type
97         err = getNamedVarType(pvApiCtx, pstAllVariableNames[i], &piAllVariableTypes[i]);
98         if (!err.iErr)
99         {
100             piAllVariableBytes[i] = getLocalSizefromId(i);
101             err = getNamedVarDimension(pvApiCtx, pstAllVariableNames[i], &nbRows, &nbCols);
102         }
103
104         if (err.iErr || nbRows * nbCols == 0)
105         {
106 #define N_A "N/A"
107             pstAllVariableSizes[i] = (char *)MALLOC((sizeof(N_A) + 1) * sizeof(char));
108             strcpy(pstAllVariableSizes[i], N_A);
109         }
110         else
111         {
112             pstAllVariableSizes[i] = valueToDisplay(pstAllVariableNames[i], piAllVariableTypes[i], nbRows, nbCols);
113             piAllVariableNbRows[i] = nbRows;
114             piAllVariableNbCols[i] = nbCols;
115         }
116
117
118         if (piAllVariableTypes[i] == sci_ints)
119         {
120             // Integer case
121             int iPrec       = 0;
122             err = getNamedMatrixOfIntegerPrecision(pvApiCtx, pstAllVariableNames[i], &iPrec);
123             switch (iPrec)
124             {
125                 case SCI_INT8:
126                     piAllVariableIntegerTypes[i] = 8;
127                     break;
128                 case SCI_INT16:
129                     piAllVariableIntegerTypes[i] = 16;
130                     break;
131                 case SCI_INT32:
132                     piAllVariableIntegerTypes[i] = 32;
133                     break;
134 #ifdef __SCILAB_INT64__
135                 case SCI_INT64:
136                     piAllVariableIntegerTypes[i] = 64;
137                     break;
138 #endif
139                 default:
140                     piAllVariableIntegerTypes[i] = 0; // Should never occurs
141                     break;
142             }
143         }
144         else
145         {
146             piAllVariableIntegerTypes[i] = -1;
147         }
148
149         if (piAllVariableTypes[i] == sci_tlist || piAllVariableTypes[i] == sci_mlist)
150         {
151             pstAllVariableListTypes[i] = getListName(pstAllVariableNames[i]);
152         }
153         else
154         {
155             pstAllVariableListTypes[i] = strdup("");
156         }
157
158
159         // global / local ??
160         pstAllVariableVisibility[i] = strdup("local");
161
162         if (scilabDefaultVariablesSet.find(string(pstAllVariableNames[i])) == scilabDefaultVariablesSet.end() && piAllVariableTypes[i] != sci_lib)
163         {
164             piAllVariableFromUser[i] = TRUE;
165         }
166         else
167         {
168             piAllVariableFromUser[i] = FALSE;
169         }
170     }
171
172     // for each global variable get information
173     for (int j = 0; j < iGlobalVariablesUsed; ++j, ++i)
174     {
175         // name
176         pstAllVariableNames[i] = getGlobalNamefromId(j);
177         // Bytes used - 8 is the number of bytes in a word
178         piAllVariableBytes[i] = getGlobalSizefromId(j) * 8;
179         // type
180         // Calling "API Scilab": not yet implemented for global variable
181         //getNamedVarType(pvApiCtx, pstAllVariableNames[i], &piAllVariableTypes[i]);
182         // Using old stack operations...
183         int pos = C2F(vstk).isiz + 2 + j;
184
185         piAllVariableTypes[i] = C2F(gettype) (&pos);
186
187         // Sizes of the variable
188         getNamedVarDimension(pvApiCtx, pstAllVariableNames[i], &nbRows, &nbCols);
189         pstAllVariableSizes[i] = valueToDisplay(pstAllVariableNames[i], piAllVariableTypes[i], nbRows, nbCols);
190         piAllVariableNbRows[i] = nbRows;
191         piAllVariableNbCols[i] = nbCols;
192
193
194         // global / local ??
195         pstAllVariableVisibility[i] = strdup("global");
196
197
198         if (piAllVariableTypes[i] == sci_tlist || piAllVariableTypes[i] == sci_mlist)
199         {
200             pstAllVariableListTypes[i] = getListName(pstAllVariableNames[i]);
201         }
202         else
203         {
204             pstAllVariableListTypes[i] = strdup("");
205         }
206
207
208         if (scilabDefaultVariablesSet.find(string(pstAllVariableNames[i])) == scilabDefaultVariablesSet.end()
209                 && piAllVariableTypes[i] != sci_c_function && piAllVariableTypes[i] != sci_lib)
210         {
211             piAllVariableFromUser[i] = TRUE;
212         }
213         else
214         {
215             piAllVariableFromUser[i] = FALSE;
216         }
217     }
218
219     // Launch Java Variable Browser through JNI
220     BrowseVar::setVariableBrowserData(getScilabJavaVM(),
221                                       pstAllVariableNames, iLocalVariablesUsed + iGlobalVariablesUsed,
222                                       piAllVariableBytes, iLocalVariablesUsed + iGlobalVariablesUsed,
223                                       piAllVariableTypes, iLocalVariablesUsed + iGlobalVariablesUsed,
224                                       piAllVariableIntegerTypes, iLocalVariablesUsed + iGlobalVariablesUsed,
225                                       pstAllVariableListTypes, iLocalVariablesUsed + iGlobalVariablesUsed,
226                                       pstAllVariableSizes, iLocalVariablesUsed + iGlobalVariablesUsed,
227                                       piAllVariableNbRows, iLocalVariablesUsed + iGlobalVariablesUsed,
228                                       piAllVariableNbCols, iLocalVariablesUsed + iGlobalVariablesUsed,
229                                       pstAllVariableVisibility, iLocalVariablesUsed + iGlobalVariablesUsed,
230                                       piAllVariableFromUser, iLocalVariablesUsed + iGlobalVariablesUsed);
231
232     freeArrayOfString(pstAllVariableNames, iLocalVariablesUsed + iGlobalVariablesUsed);
233     freeArrayOfString(pstAllVariableVisibility, iLocalVariablesUsed + iGlobalVariablesUsed);
234     freeArrayOfString(pstAllVariableSizes, iLocalVariablesUsed + iGlobalVariablesUsed);
235     freeArrayOfString(pstAllVariableListTypes, iLocalVariablesUsed + iGlobalVariablesUsed);
236
237     if (piAllVariableFromUser)
238     {
239         FREE(piAllVariableFromUser);
240         piAllVariableFromUser = NULL;
241     }
242
243     if (piAllVariableBytes)
244     {
245         FREE(piAllVariableBytes);
246         piAllVariableBytes = NULL;
247     }
248
249     if (piAllVariableTypes)
250     {
251         FREE(piAllVariableTypes);
252         piAllVariableTypes = NULL;
253     }
254
255     if (piAllVariableIntegerTypes)
256     {
257         FREE(piAllVariableIntegerTypes);
258         piAllVariableIntegerTypes = NULL;
259     }
260
261     if (piAllVariableNbRows)
262     {
263         FREE(piAllVariableNbRows);
264         piAllVariableNbRows = NULL;
265     }
266
267     if (piAllVariableNbCols)
268     {
269         FREE(piAllVariableNbCols);
270         piAllVariableNbCols = NULL;
271     }
272 }
273
274 /*--------------------------------------------------------------------------*/
275 static std::set < string > createScilabDefaultVariablesSet()
276 {
277     string arr[] = { "home",
278                      "PWD",
279                      "%tk",
280                      "%pvm",
281                      "MSDOS",
282                      "%F",
283                      "%T",
284                      "%f",
285                      "%t",
286                      "%e",
287                      "%pi",
288                      "%modalWarning",
289                      "%nan",
290                      "%inf",
291                      "SCI",
292                      "WSCI",
293                      "SCIHOME",
294                      "TMPDIR",
295                      "%gui",
296                      "%fftw",
297                      "%helps",
298                      "%eps",
299                      "%io",
300                      "%i",
301                      "demolist",
302                      "%z",
303                      "%s",
304                      "$",
305                      "%toolboxes",
306                      "%toolboxes_dir",
307                      "TICTOC",
308                      "%helps_modules",
309                      "%_atoms_cache",
310                      "evoid", // Constant for external object
311                      "jvoid" // Constant for external object Java (jims)
312                    };
313     int i = 0;
314
315 #define NBELEMENT 35
316     std::set < string > ScilabDefaultVariables;
317
318     for (i = 0; i < NBELEMENT; i++)
319     {
320         ScilabDefaultVariables.insert(arr[i]);
321     }
322
323     return ScilabDefaultVariables;
324 }
325
326 static char * getListName(char * variableName)
327 {
328     SciErr sciErr;
329     int *piAddr = NULL;
330     int* piAddr1 = NULL;
331     int iRows = 0;
332     int iCols = 0;
333     char **pstType;
334     char *tmpChar;
335     sciErr = getVarAddressFromName(pvApiCtx, variableName, &piAddr);
336     if (sciErr.iErr)
337     {
338         return strdup("");
339     }
340
341     sciErr = getListItemAddress(pvApiCtx, piAddr, 1, &piAddr1);
342     if (sciErr.iErr)
343     {
344         return strdup("");
345     }
346
347     if (getAllocatedMatrixOfString(pvApiCtx, piAddr1, &iRows, &iCols, &pstType))
348     {
349
350         return strdup("");
351     }
352     tmpChar = strdup(pstType[0]);
353     freeAllocatedMatrixOfString(iRows, iCols, pstType);
354     return tmpChar;
355 }
356
357 static char * valueToDisplay(char * variableName, int variableType, int nbRows, int nbCols)
358 {
359     SciErr err;
360
361
362     // 4 is the dimension max to which display the content
363     if (nbRows * nbCols <= 4 && variableType == sci_matrix)
364     {
365         // Small double value, display it
366         double* pdblReal = (double *)malloc(((nbRows) * (nbCols)) * sizeof(double));
367         double* pdblImg = (double *)malloc(((nbRows) * (nbCols)) * sizeof(double));
368         BOOL isComplex = FALSE;
369
370         if (isNamedVarComplex(pvApiCtx, variableName))
371         {
372             err = readNamedComplexMatrixOfDouble(pvApiCtx, variableName, &nbRows, &nbCols, pdblReal, pdblImg);
373             isComplex = TRUE;
374         }
375         else
376         {
377             err = readNamedMatrixOfDouble(pvApiCtx, variableName, &nbRows, &nbCols, pdblReal);
378         }
379
380
381         return strdup(formatMatrix(nbRows, nbCols, isComplex, pdblReal, pdblImg).c_str());
382     }
383     else
384     {
385         char *sizeStr = NULL;
386         // 11 =strlen("2147483647")+1 (1 for security)
387         sizeStr = (char *)MALLOC((11 + 11 + 1 + 1) * sizeof(char));
388         sprintf(sizeStr, "%dx%d", nbRows, nbCols);
389         return sizeStr;
390     }
391 }
392
393 std::string formatMatrix(int nbRows, int nbCols, BOOL isComplex, double *pdblReal, double *pdblImg)
394 {
395     int i, j ;
396 #define PRECISION_DISPLAY 3
397     if (nbRows * nbCols == 1)
398     {
399         std::ostringstream os;
400         os.precision(PRECISION_DISPLAY);
401         os << pdblReal[0]; // Convert the double to string
402         if (isComplex)
403         {
404             os << " + " << pdblImg[0] << "i";
405         }
406         return os.str();
407     }
408
409     std::string formated = "[";
410     for (j = 0 ; j < nbRows ; j++)
411     {
412         for (i = 0 ; i < nbCols ; i++)
413         {
414             /* Display the formated matrix ... the way the user
415              * expect */
416             std::ostringstream os;
417             os.precision(PRECISION_DISPLAY);
418             os << pdblReal[i * nbRows + j]; // Convert the double to string
419             formated += os.str();
420             if (isComplex)
421             {
422                 std::ostringstream osComplex;
423                 osComplex.precision(PRECISION_DISPLAY);
424                 osComplex << pdblImg[i * nbRows + j];
425                 formated += " + " + osComplex.str() + "i";
426             }
427
428
429             if (i + 1 != nbCols) // Not the last element of the matrix
430             {
431                 formated += ", ";
432             }
433         }
434         if (j + 1 != nbRows) // Not the last line of the matrix
435         {
436             formated += "; ";
437         }
438     }
439     return formated + "]";
440 }