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