8fe70a2287cbce6233d90a39ab8421d8925d9f7d
[scilab.git] / scilab / modules / core / src / c / stackinfo.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Allan CORNET
4  * Copyright (C) 2010 - DIGITEO - Allan CORNET
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 #ifdef _MSC_VER
15 #include <windows.h> /* for MAXLONG32 on Win64 */
16 #endif
17 #ifdef HAVE_LIMITS_H
18 #include <limits.h>
19 #define MAXLONG LONG_MAX
20 #else
21 #ifdef HAVE_VALUES_H
22 #include <values.h>
23 #endif /* HAVE_VALUES_H */
24 #endif /* !HAVE_LIMITS_H */
25 #include "machine.h"
26 #include "stackinfo.h"
27 #include "stack-def.h"
28 #include "stack-c.h"
29 #include "MALLOC.h"
30 #ifdef _MSC_VER
31 #include "strdup_windows.h"
32 #endif
33 /*--------------------------------------------------------------------------*/
34 #ifndef MAXLONG
35 #define MAXLONG LONG_MAX
36 #endif
37
38 #ifndef LONG_MAX
39 #define LONG_MAX 2147483647L
40 #endif
41
42 #ifndef MAXLONG
43 #define MAXLONG LONG_MAX
44 #endif
45
46 /* MAXLONG on 64 bits platform is not 2147483647 but 9223372036854775807 */
47 /* For scilab's stack size, we need to limit to 2147483647 */
48 #ifdef USE_DYNAMIC_STACK
49 #ifndef MAXLONG32
50 #define MAXLONG32 2147483647L
51 #endif
52 #endif
53 /*--------------------------------------------------------------------------*/
54 static void cleanFortranString(char *fortanbuffer);
55 /*--------------------------------------------------------------------------*/
56 int C2F(getstackinfo)(int *total, int *used)
57 {
58     *used = C2F(vstk).lstk[C2F(vstk).isiz - 1] - C2F(vstk).lstk[Bot - 1] + 1;
59     *total = C2F(vstk).lstk[C2F(vstk).isiz - 1] - C2F(vstk).lstk[0];
60     return(0);
61 }
62 /*--------------------------------------------------------------------------*/
63 int C2F(getgstackinfo)(int *total, int *used)
64 {
65     *used = C2F(vstk).lstk[C2F(vstk).gtop] - C2F(vstk).lstk[C2F(vstk).isiz + 1] + 1;
66     *total = C2F(vstk).lstk[C2F(vstk).gbot - 1] - C2F(vstk).lstk[C2F(vstk).isiz + 1] ;
67     return(0);
68 }
69 /*--------------------------------------------------------------------------*/
70 int C2F(getvariablesinfo)(int *total, int *used)
71 {
72     *used = C2F(vstk).isiz - Bot ;
73     *total = C2F(vstk).isiz - 1;
74     return 0;
75 }
76 /*--------------------------------------------------------------------------*/
77 int C2F(getgvariablesinfo)(int *total, int *used)
78 {
79     *used = C2F(vstk).gtop - C2F(vstk).isiz - 1;
80     *total = 10000 - C2F(vstk).isiz - 1;
81     return 0;
82 }
83 /*--------------------------------------------------------------------------*/
84 int getIntermediateMemoryNeeded(void)
85 {
86     return (Err + C2F(vstk).lstk[Bot - 1] - C2F(vstk).lstk[0]);
87 }
88 /*--------------------------------------------------------------------------*/
89 BOOL is_a_valid_size_for_scilab_stack(int sizestack)
90 {
91 #if (defined(_MSC_VER) && defined(_WIN64)) || defined (USE_DYNAMIC_STACK)
92     /* On x64 with scilab's stack , we need to limit stack access */
93     if ((unsigned long)sizestack >= get_max_memory_for_scilab_stack() + 1)
94     {
95         return FALSE;
96     }
97     return TRUE;
98 #else
99     double dsize = ((double) sizeof(double)) * (sizestack);
100     unsigned long ulsize = ((unsigned long)sizeof(double)) * (sizestack);
101     if ( dsize != (double) ulsize)
102     {
103         return FALSE;
104     }
105     return TRUE;
106 #endif
107 }
108 /*--------------------------------------------------------------------------*/
109 unsigned long get_max_memory_for_scilab_stack(void)
110 {
111 #if (defined(_MSC_VER) && defined(_WIN64)) || defined (USE_DYNAMIC_STACK)
112     return MAXLONG32 / sizeof(double);
113 #else
114     return MAXLONG / sizeof(double);
115 #endif
116 }
117 /*--------------------------------------------------------------------------*/
118 char *getLocalNamefromId(int n)
119 {
120     int *id = NULL;
121     int one = 1;
122     char *Name = NULL;
123     char fortranName[nlgh + 1];
124
125     id = &C2F(vstk).idstk[Bot * 6 - 6];
126     id -= 7;
127
128     C2F(cvname)(&id[n * 6 + 1], fortranName, &one, nlgh);
129
130     cleanFortranString(fortranName);
131
132     if (strlen(fortranName) > 0)
133     {
134         Name = strdup(fortranName);
135     }
136     return Name;
137 }
138 /*--------------------------------------------------------------------------*/
139 char *getGlobalNamefromId(int n)
140 {
141     int *id = NULL;
142     static int one = 1;
143     char *Name = NULL;
144     char fortranName[nlgh + 1];
145
146     id = &C2F(vstk).idstk[(C2F(vstk).isiz + 2) * 6 - 6];
147     id -= 7;
148
149     C2F(cvname)(&id[(n + 1) * 6 + 1], fortranName, &one, nlgh);
150
151     cleanFortranString(fortranName);
152
153     if (strlen(fortranName) > 0)
154     {
155         Name = strdup(fortranName);
156     }
157     return Name;
158 }
159 /*--------------------------------------------------------------------------*/
160 int getLocalSizefromId(int n)
161 {
162     int LocalSize = 0;
163     int Lused = 0;
164     int Ltotal = 0;
165
166     C2F(getvariablesinfo)(&Ltotal, &Lused);
167
168     if ( (n >= 0) && ( n < Lused ) )
169     {
170         LocalSize = (int)(C2F(vstk).lstk[Bot + n] - C2F(vstk).lstk[Bot + n - 1]);
171     }
172     else
173     {
174         LocalSize = -1;
175     }
176
177     return LocalSize;
178 }
179 /*--------------------------------------------------------------------------*/
180 int getGlobalSizefromId(int n)
181 {
182     int GlobalSize = 0;
183     int Gused = 0;
184     int Gtotal = 0;
185
186     C2F(getgvariablesinfo)(&Gtotal, &Gused);
187
188     if ( (n >= 0) && ( n < Gused ) )
189     {
190         GlobalSize = (int)(C2F(vstk).lstk[C2F(vstk).isiz + 2 + n] - C2F(vstk).lstk[C2F(vstk).isiz + 2 + n - 1]);
191     }
192     else
193     {
194         GlobalSize = -1;
195     }
196     return GlobalSize;
197 }
198 /*--------------------------------------------------------------------------*/
199 static void cleanFortranString(char *fortanbuffer)
200 {
201     int i = 0;
202     fortanbuffer[nlgh] = '\0';
203
204     for (i = 0; i < nlgh; i++)
205     {
206         if (fortanbuffer[i] == '\0')
207         {
208             break;
209         }
210         else if (fortanbuffer[i] == ' ')
211         {
212             fortanbuffer[i] = '\0';
213             break;
214         }
215     }
216 }
217 /*--------------------------------------------------------------------------*/
218 BOOL existVariableNamedOnStack(char *varname)
219 {
220     if (existLocalVariableNamedOnStack(varname) ||
221             existGlobalVariableNamedOnStack(varname) )
222     {
223         return TRUE;
224     }
225     return FALSE;
226 }
227 /*--------------------------------------------------------------------------*/
228 BOOL existLocalVariableNamedOnStack(char *varname)
229 {
230     if (varname)
231     {
232         int Lused = 0;
233         int Ltotal = 0;
234         int i = 0;
235
236         C2F(getvariablesinfo)(&Ltotal, &Lused);
237
238         for ( i = 0; i < Lused; i++)
239         {
240             char *varOnStack = getLocalNamefromId(i);
241             if (varOnStack)
242             {
243                 if (strcmp(varname, varOnStack) == 0)
244                 {
245                     FREE(varOnStack);
246                     varOnStack = NULL;
247                     return TRUE;
248                 }
249                 FREE(varOnStack);
250                 varOnStack = NULL;
251             }
252         }
253     }
254     return FALSE;
255 }
256 /*--------------------------------------------------------------------------*/
257 BOOL existGlobalVariableNamedOnStack(char *varname)
258 {
259     if (varname)
260     {
261         int Gused = 0;
262         int Gtotal = 0;
263         int i = 0;
264
265         C2F(getgvariablesinfo)(&Gtotal, &Gused);
266         for ( i = 0; i < Gused; i++)
267         {
268             char *varOnStack = getGlobalNamefromId(i);
269             if (varOnStack)
270             {
271                 if (strcmp(varname, varOnStack) == 0)
272                 {
273                     FREE(varOnStack);
274                     varOnStack = NULL;
275                     return TRUE;
276                 }
277                 FREE(varOnStack);
278                 varOnStack = NULL;
279             }
280         }
281     }
282     return FALSE;
283 }
284 /*--------------------------------------------------------------------------*/