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