d1ebecfa4af8e4fd2036e7208d4790d0d03ed52d
[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.1-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 "sci_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 "os_string.h"
37 #include "sci_types.h"
38 }
39 using namespace org_scilab_modules_ui_data;
40
41 static std::set < string > createScilabDefaultVariablesSet();
42 static char * getListName(char * variableName);
43 static std::string formatMatrix(int nbRows, int nbCols, BOOL isComplex, double *pdblReal, double *pdblImg);
44 static char * valueToDisplay(char * variableName, int variableType, int nbRows, int nbCols);
45 void OpenBrowseVar()
46 {
47     BrowseVar::openVariableBrowser(getScilabJavaVM());
48     SetBrowseVarData();
49 }
50
51 void UpdateBrowseVar()
52 {
53     if (BrowseVar::isVariableBrowserOpened(getScilabJavaVM()))
54     {
55         SetBrowseVarData();
56     }
57 }
58
59 void SetBrowseVarData()
60 {
61 #if 0
62     SciErr err;
63     int iGlobalVariablesUsed = 0;
64     int iGlobalVariablesTotal = 0;
65     int iLocalVariablesUsed = 0;
66     int iLocalVariablesTotal = 0;
67     int i = 0;
68
69     // First get how many global / local variable we have.
70     C2F(getvariablesinfo) (&iLocalVariablesTotal, &iLocalVariablesUsed);
71     C2F(getgvariablesinfo) (&iGlobalVariablesTotal, &iGlobalVariablesUsed);
72
73     char **pstAllVariableNames = (char **)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(char *));
74     char **pstAllVariableVisibility = (char **)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(char *));
75     char **pstAllVariableListTypes = (char **)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(char *));
76     int *piAllVariableBytes = (int *)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(int));
77     char **pstAllVariableSizes = (char **)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(char *));
78     int *piAllVariableTypes = (int *)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(int));
79     int *piAllVariableIntegerTypes = (int *)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(int));
80     bool *piAllVariableFromUser = (bool *) MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(bool));
81     /* Necessary for the plots in the var browser */
82     int *piAllVariableNbRows = (int *)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(int));
83     int *piAllVariableNbCols = (int *)MALLOC((iLocalVariablesUsed + iGlobalVariablesUsed) * sizeof(int));
84
85     int nbRows, nbCols;
86     char *sizeStr = NULL;
87
88     std::set < string > scilabDefaultVariablesSet = createScilabDefaultVariablesSet();
89
90     // for each local variable get information
91     for (; i < iLocalVariablesUsed; ++i)
92     {
93         // name
94         pstAllVariableNames[i] = getLocalNamefromId(i + 1);
95         // type
96         err = getNamedVarType(pvApiCtx, pstAllVariableNames[i], &piAllVariableTypes[i]);
97         if (!err.iErr)
98         {
99             piAllVariableBytes[i] = getLocalSizefromId(i);
100             err = getNamedVarDimension(pvApiCtx, pstAllVariableNames[i], &nbRows, &nbCols);
101         }
102
103         if (err.iErr || nbRows * nbCols == 0)
104         {
105 #define N_A "N/A"
106             pstAllVariableSizes[i] = (char *)MALLOC((sizeof(N_A) + 1) * sizeof(char));
107             strcpy(pstAllVariableSizes[i], N_A);
108         }
109         else
110         {
111             pstAllVariableSizes[i] = valueToDisplay(pstAllVariableNames[i], piAllVariableTypes[i], nbRows, nbCols);
112             piAllVariableNbRows[i] = nbRows;
113             piAllVariableNbCols[i] = nbCols;
114         }
115
116
117         if (piAllVariableTypes[i] == sci_ints)
118         {
119             // Integer case
120             int iPrec       = 0;
121             err = getNamedMatrixOfIntegerPrecision(pvApiCtx, pstAllVariableNames[i], &iPrec);
122             switch (iPrec)
123             {
124                 case SCI_INT8:
125                     piAllVariableIntegerTypes[i] = 8;
126                     break;
127                 case SCI_INT16:
128                     piAllVariableIntegerTypes[i] = 16;
129                     break;
130                 case SCI_INT32:
131                     piAllVariableIntegerTypes[i] = 32;
132                     break;
133 #ifdef __SCILAB_INT64__
134                 case SCI_INT64:
135                     piAllVariableIntegerTypes[i] = 64;
136                     break;
137 #endif
138                 default:
139                     piAllVariableIntegerTypes[i] = 0; // Should never occurs
140                     break;
141             }
142         }
143         else
144         {
145             piAllVariableIntegerTypes[i] = -1;
146         }
147
148         if (piAllVariableTypes[i] == sci_tlist || piAllVariableTypes[i] == sci_mlist)
149         {
150             pstAllVariableListTypes[i] = getListName(pstAllVariableNames[i]);
151         }
152         else
153         {
154             pstAllVariableListTypes[i] = strdup("");
155         }
156
157
158         // global / local ??
159         pstAllVariableVisibility[i] = strdup("local");
160
161         if (scilabDefaultVariablesSet.find(string(pstAllVariableNames[i])) == scilabDefaultVariablesSet.end() && piAllVariableTypes[i] != sci_lib)
162         {
163             piAllVariableFromUser[i] = TRUE;
164         }
165         else
166         {
167             piAllVariableFromUser[i] = FALSE;
168         }
169     }
170
171     // for each global variable get information
172     for (int j = 0; j < iGlobalVariablesUsed; ++j, ++i)
173     {
174         // name
175         pstAllVariableNames[i] = getGlobalNamefromId(j);
176         // Bytes used - 8 is the number of bytes in a word
177         piAllVariableBytes[i] = getGlobalSizefromId(j) * 8;
178         // type
179         // Calling "API Scilab": not yet implemented for global variable
180         //getNamedVarType(pvApiCtx, pstAllVariableNames[i], &piAllVariableTypes[i]);
181         // Using old stack operations...
182         int pos = C2F(vstk).isiz + 2 + j;
183
184         piAllVariableTypes[i] = C2F(gettype) (&pos);
185
186         // Sizes of the variable
187         getNamedVarDimension(pvApiCtx, pstAllVariableNames[i], &nbRows, &nbCols);
188         pstAllVariableSizes[i] = valueToDisplay(pstAllVariableNames[i], piAllVariableTypes[i], nbRows, nbCols);
189         piAllVariableNbRows[i] = nbRows;
190         piAllVariableNbCols[i] = nbCols;
191
192
193         // global / local ??
194         pstAllVariableVisibility[i] = strdup("global");
195
196
197         if (piAllVariableTypes[i] == sci_tlist || piAllVariableTypes[i] == sci_mlist)
198         {
199             pstAllVariableListTypes[i] = getListName(pstAllVariableNames[i]);
200         }
201         else
202         {
203             pstAllVariableListTypes[i] = strdup("");
204         }
205
206
207         if (scilabDefaultVariablesSet.find(string(pstAllVariableNames[i])) == scilabDefaultVariablesSet.end()
208                 && piAllVariableTypes[i] != sci_c_function && piAllVariableTypes[i] != sci_lib)
209         {
210             piAllVariableFromUser[i] = TRUE;
211         }
212         else
213         {
214             piAllVariableFromUser[i] = FALSE;
215         }
216     }
217
218     // Launch Java Variable Browser through JNI
219     BrowseVar::setVariableBrowserData(getScilabJavaVM(),
220                                       pstAllVariableNames, iLocalVariablesUsed + iGlobalVariablesUsed,
221                                       piAllVariableBytes, iLocalVariablesUsed + iGlobalVariablesUsed,
222                                       piAllVariableTypes, iLocalVariablesUsed + iGlobalVariablesUsed,
223                                       piAllVariableIntegerTypes, iLocalVariablesUsed + iGlobalVariablesUsed,
224                                       pstAllVariableListTypes, iLocalVariablesUsed + iGlobalVariablesUsed,
225                                       pstAllVariableSizes, iLocalVariablesUsed + iGlobalVariablesUsed,
226                                       piAllVariableNbRows, iLocalVariablesUsed + iGlobalVariablesUsed,
227                                       piAllVariableNbCols, iLocalVariablesUsed + iGlobalVariablesUsed,
228                                       pstAllVariableVisibility, iLocalVariablesUsed + iGlobalVariablesUsed,
229                                       piAllVariableFromUser, iLocalVariablesUsed + iGlobalVariablesUsed);
230
231     freeArrayOfString(pstAllVariableNames, iLocalVariablesUsed + iGlobalVariablesUsed);
232     freeArrayOfString(pstAllVariableVisibility, iLocalVariablesUsed + iGlobalVariablesUsed);
233     freeArrayOfString(pstAllVariableSizes, iLocalVariablesUsed + iGlobalVariablesUsed);
234     freeArrayOfString(pstAllVariableListTypes, iLocalVariablesUsed + iGlobalVariablesUsed);
235
236     if (piAllVariableFromUser)
237     {
238         FREE(piAllVariableFromUser);
239         piAllVariableFromUser = NULL;
240     }
241
242     if (piAllVariableBytes)
243     {
244         FREE(piAllVariableBytes);
245         piAllVariableBytes = NULL;
246     }
247
248     if (piAllVariableTypes)
249     {
250         FREE(piAllVariableTypes);
251         piAllVariableTypes = NULL;
252     }
253
254     if (piAllVariableIntegerTypes)
255     {
256         FREE(piAllVariableIntegerTypes);
257         piAllVariableIntegerTypes = NULL;
258     }
259
260     if (piAllVariableNbRows)
261     {
262         FREE(piAllVariableNbRows);
263         piAllVariableNbRows = NULL;
264     }
265
266     if (piAllVariableNbCols)
267     {
268         FREE(piAllVariableNbCols);
269         piAllVariableNbCols = NULL;
270     }
271 #endif
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                      "jnull", // Constant for external object Java (jims)
313                      "enull"  // Constant for external object
314                    };
315     int i = 0;
316
317 #define NBELEMENT 37
318     std::set < string > ScilabDefaultVariables;
319
320     for (i = 0; i < NBELEMENT; i++)
321     {
322         ScilabDefaultVariables.insert(arr[i]);
323     }
324
325     return ScilabDefaultVariables;
326 }
327
328 static char * getListName(char * variableName)
329 {
330     SciErr sciErr;
331     int *piAddr = NULL;
332     int* piAddr1 = NULL;
333     int iRows = 0;
334     int iCols = 0;
335     char **pstType;
336     char *tmpChar;
337     sciErr = getVarAddressFromName(NULL, variableName, &piAddr);
338     if (sciErr.iErr)
339     {
340         return os_strdup("");
341     }
342
343     sciErr = getListItemAddress(NULL, piAddr, 1, &piAddr1);
344     if (sciErr.iErr)
345     {
346         return os_strdup("");
347     }
348
349     if (getAllocatedMatrixOfString(NULL, piAddr1, &iRows, &iCols, &pstType))
350     {
351
352         return os_strdup("");
353     }
354     tmpChar = os_strdup(pstType[0]);
355     freeAllocatedMatrixOfString(iRows, iCols, pstType);
356     return tmpChar;
357 }
358
359 static char * valueToDisplay(char * variableName, int variableType, int nbRows, int nbCols)
360 {
361     SciErr err;
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(NULL, variableName))
371         {
372             err = readNamedComplexMatrixOfDouble(NULL, variableName, &nbRows, &nbCols, pdblReal, pdblImg);
373             isComplex = TRUE;
374         }
375         else
376         {
377             err = readNamedMatrixOfDouble(NULL, variableName, &nbRows, &nbCols, pdblReal);
378         }
379
380
381         return os_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 }