1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2006 - INRIA - Allan Cornet
4 * Copyright (C) 2006 - INRIA - Fabrice Leray
5 * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
6 * Copyright (C) 2006 - INRIA - Vincent Couvert
7 * Copyright (C) 2011 - DIGITEO - Allan CORNET
8 *
9 * Copyright (C) 2012 - 2016 - Scilab Enterprises
10 *
11 * This file is hereby licensed under the terms of the GNU GPL v2.0,
12 * pursuant to article 5.3.4 of the CeCILL v.2.1.
13 * This file was originally licensed under the terms of the CeCILL v2.1,
14 * and continues to be available under such terms.
15 * For more information, see the COPYING file which you should have received
16 * along with this program.
17 *
18 */
19
20 /*------------------------------------------------------------------------*/
21 /* file: sci_set.h */
22 /* desc : interface for sci_set routine */
23 /*------------------------------------------------------------------------*/
24 #ifdef _MSC_VER
25 #include <Windows.h>
26 #endif
27
28 #include <stdio.h>
29 /*------------------------------------------------------------------------*/
30 #include "gw_graphics.h"
31 #include "Scierror.h"
32 #include "HandleManagement.h"
33 #include "GetProperty.h"
34 #include "InitObjects.h"
35 #include "freeArrayOfString.h"
36
37 #include "SetHashTable.h"
38 #include "SetPropertyStatus.h"
39
40 #include "sci_malloc.h" /* MALLOC */
41 #include "localization.h"
42 #include "os_string.h"
43 #include "api_scilab.h"
44 #include "FigureList.h"
45 #include "sciprint.h"
46
47 /*--------------------------------------------------------------------------
48 * sciset(choice-name,x1,x2,x3,x4,x5)
49 * or xset()
50 *-----------------------------------------------------------*/
sci_set(char * fname,void * pvApiCtx)51 int sci_set(char *fname, void *pvApiCtx)
52 {
53 SciErr sciErr;
54 int i = 0;
55 int* piAddr1 = NULL;
56
57 int isMatrixOfString = 0;
58
59 char* pstNewProperty = NULL;
60
61 unsigned long hdl;
62 int iObjUID = 0;
63 int iType = 0;
64 int* piType = &iType;
65
66 int iSetProperty = 0;
67
68 int iRhs = nbInputArgument(pvApiCtx);
69 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr1);
70 if (sciErr.iErr)
71 {
72 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
73 return 1;
74 }
75
76 if (isMListType(pvApiCtx, piAddr1) || isTListType(pvApiCtx, piAddr1))
77 {
78 OverLoad(1);
79 return 0;
80 }
81
82 CheckInputArgumentAtLeast(pvApiCtx, 2);
83 CheckOutputArgument(pvApiCtx, 0, 1);
84
85 if (isDoubleType(pvApiCtx, piAddr1)) /* tclsci handle */
86 {
87 /* call "set" for tcl/tk see tclsci/sci_gateway/c/sci_set.c */
88 OverLoad(1);
89 return 0;
90 }
91
92 if (iRhs == 2)
93 {
94 #define NB_PROPERTIES_SUPPORTED 7
95 /* No object specified */
96 /* ONLY supported properties are */
97 /* 'current_entity' */
98 /* 'hdl' */
99 /* 'current_figure' */
100 /* 'current_axes' */
101 /* 'default_values' */
102 /* 'figure_style' for compatibility but do nothing */
103 /* others values must return a error */
104 char *propertiesSupported[NB_PROPERTIES_SUPPORTED] =
105 {
106 "current_entity",
107 "hdl",
108 "current_figure",
109 "current_axes",
110 "figure_style",
111 "default_values",
112 "auto_clear"
113 };
114
115 int iPropertyFound = 0;
116 int* piAddr2 = NULL;
117 int iType2 = 0;
118 int iRows2 = 0;
119 int iCols2 = 0;
120 void* pvData = NULL;
121 char* pstProperty = NULL;
122
123 if (isStringType(pvApiCtx, piAddr1) == 0)
124 {
125 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 1);
126 return 0;
127 }
128
129 if (getAllocatedSingleString(pvApiCtx, piAddr1, &pstProperty))
130 {
131 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 1);
132 return 1;
133 }
134
135 sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddr2);
136 if (sciErr.iErr)
137 {
138 freeAllocatedSingleString(pstProperty);
139 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
140 return 1;
141 }
142
143 sciErr = getVarType(pvApiCtx, piAddr2, &iType2);
144 if (sciErr.iErr)
145 {
146 freeAllocatedSingleString(pstProperty);
147 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
148 return 1;
149 }
150
151 switch (iType2)
152 {
153 case sci_matrix:
154 sciErr = getMatrixOfDouble(pvApiCtx, piAddr2, &iRows2, &iCols2, (double**)&pvData);
155 if (sciErr.iErr)
156 {
157 freeAllocatedSingleString(pstProperty);
158 printError(&sciErr, 0);
159 Scierror(999, _("%s: Wrong type for input argument #%d: Matrix expected.\n"), fname, 2);
160 return sciErr.iErr;
161 }
162 break;
163 case sci_handles :
164 sciErr = getMatrixOfHandle(pvApiCtx, piAddr2, &iRows2, &iCols2, (long long**)&pvData);
165 if (sciErr.iErr)
166 {
167 freeAllocatedSingleString(pstProperty);
168 printError(&sciErr, 0);
169 Scierror(999, _("%s: Wrong type for input argument #%d: Matrix of handle expected.\n"), fname, 3);
170 return 1;
171 }
172 break;
173 case sci_strings :
174 if (stricmp(pstProperty, "tics_labels") == 0 || stricmp(pstProperty, "auto_ticks") == 0 ||
175 stricmp(pstProperty, "axes_visible") == 0 || stricmp(pstProperty, "axes_reverse") == 0 ||
176 stricmp(pstProperty, "text") == 0 || stricmp(pstProperty, "ticks_format") == 0)
177 {
178 isMatrixOfString = 1;
179 if (getAllocatedMatrixOfString(pvApiCtx, piAddr2, &iRows2, &iCols2, (char***)&pvData))
180 {
181 freeAllocatedSingleString(pstProperty);
182 Scierror(999, _("%s: Wrong size for input argument #%d: A matrix of string expected.\n"), fname, 2);
183 return 1;
184 }
185 }
186 else
187 {
188 if (getAllocatedSingleString(pvApiCtx, piAddr2, (char**)&pvData))
189 {
190 freeAllocatedSingleString(pstProperty);
191 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 2);
192 return 1;
193 }
194 iRows2 = (int)strlen((char*)pvData);
195 iCols2 = 1;
196 isMatrixOfString = 0;
197 }
198 break;
199 }
200
201
202
203 for (i = 0; i < NB_PROPERTIES_SUPPORTED; i++)
204 {
205
206 if (strcmp(propertiesSupported[i], pstProperty) == 0)
207 {
208 iPropertyFound = 1;
209 }
210 }
211
212 if (iPropertyFound)
213 {
214 callSetProperty(pvApiCtx, 0, pvData, iType2, iRows2, iCols2, pstProperty);
215 if (iType2 == sci_strings)
216 {
217 //free allocated data
218 if (isMatrixOfString == 1)
219 {
220 freeAllocatedMatrixOfString(iRows2, iCols2, (char**)pvData);
221 }
222 else
223 {
224 freeAllocatedSingleString((char*)pvData);
225 }
226 }
227 }
228 else
229 {
230 freeAllocatedSingleString(pstProperty);
231 Scierror(999, _("%s: Wrong value for input argument #%d: a valid property expected.\n"), fname, 1);
232 if (iType2 == sci_strings)
233 {
234 if (isMatrixOfString == 1)
235 {
236 freeAllocatedMatrixOfString(iRows2, iCols2, (char**)pvData);
237 }
238 else
239 {
240 freeAllocatedSingleString((char*)pvData);
241 }
242 }
243 return 0;
244 }
245
246 freeAllocatedSingleString(pstProperty);
247 AssignOutputVariable(pvApiCtx, 1) = 0;
248 ReturnArguments(pvApiCtx);
249 return 0;
250 }
251
252 if (iRhs % 2 != 1)
253 {
254 Scierror(999, _("%s: Wrong number of input argument(s) : an odd number is expected.\n"), fname);
255 return 0;
256 }
257
258
259 /* after the call to sciSet get the status : 0 <=> OK, */
260 /* -1 <=> Error, */
261 /* 1 <=> nothing done */
262
263 /* set or create a graphic window */
264 if (isHandleType(pvApiCtx, piAddr1) == 0 && isStringType(pvApiCtx, piAddr1) == 0)
265 {
266 Scierror(999, _("%s: Wrong type for input argument #%d: A handle or a string expected.\n"), fname, 1);
267 return 0;
268 }
269
270 if (isStringType(pvApiCtx, piAddr1))
271 {
272 char* pstPath = NULL;
273 if (getAllocatedSingleString(pvApiCtx, piAddr1, &pstPath))
274 {
275 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 1);
276 return 1;
277 }
278
279 iObjUID = search_path(pstPath);
280 if (iObjUID == 0)
281 {
282 Scierror(999, _("%s: Unable to find handle for path %s.\n"), fname, pstPath);
283 freeAllocatedSingleString(pstPath);
284 return 1;
285 }
286 freeAllocatedSingleString(pstPath);
287 }
288 else
289 {
290 //matrix of handle are managed by a %h_set
291 if (isScalar(pvApiCtx, piAddr1) == FALSE)
292 {
293 OverLoad(1);
294 return 0;
295 }
296
297 if (getScalarHandle(pvApiCtx, piAddr1, (long long*)&hdl))
298 {
299 Scierror(999, _("%s: Wrong size for input argument #%d: A single handle expected.\n"), fname, 1);
300 return 1;
301 }
302
303 iObjUID = getObjectFromHandle(hdl);
304 }
305
306 if (iObjUID == 0)
307 {
308 Scierror(999, _("%s: The handle is not or no more valid.\n"), fname);
309 return 0;
310 }
311
312 for (i = 1 ; i < iRhs ; i = i + 2)
313 {
314 int setStatus = 0;
315 int* piAddr2 = NULL;
316 int* piAddr3 = NULL;
317
318 int iPos = i + 1;
319 int isData = 0;
320
321 int iRows3 = 0;
322 int iCols3 = 0;
323 int iType3 = 0;
324 void* pvData = NULL;
325 char* pstProperty = NULL;
326
327 sciErr = getVarAddressFromPosition(pvApiCtx, iPos, &piAddr2);
328 if (sciErr.iErr)
329 {
330 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos);
331 return 1;
332 }
333
334 if (isStringType(pvApiCtx, piAddr2) == 0)
335 {
336 Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), fname, iPos);
337 return 0;
338 }
339
340 if (getAllocatedSingleString(pvApiCtx, piAddr2, &pstProperty))
341 {
342 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, iPos);
343 return 1;
344 }
345
346 sciErr = getVarAddressFromPosition(pvApiCtx, iPos + 1, &piAddr3);
347 if (sciErr.iErr)
348 {
349 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos + 1);
350 freeAllocatedSingleString(pstProperty);
351 return 1;
352 }
353
354 if ((pstProperty[0] == 'd' || pstProperty[0] == 'D') && stricmp("data", pstProperty) == 0)
355 {
356 //send to datamodel
357 isData = 1;
358 }
359
360 if (stricmp(pstProperty, "user_data") == 0 ||
361 stricmp(pstProperty, "userdata") == 0 ||
362 stricmp(pstProperty, "display_function_data") == 0 ||
363 stricmp(pstProperty, "data") == 0)
364 {
365 /* in this case set_user_data_property
366 * directly uses the third position in the stack
367 * to get the variable which is to be set in
368 * the user_data property (any data type is allowed) S. Steer */
369 pvData = (void*)piAddr3; /*position in the stack */
370 iRows3 = -1; /*unused */
371 iCols3 = -1; /*unused */
372 iType3 = -1;
373 }
374 else
375 {
376 sciErr = getVarType(pvApiCtx, piAddr3, &iType3);
377 if (sciErr.iErr)
378 {
379 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos + 1);
380 freeAllocatedSingleString(pstProperty);
381 return 1;
382 }
383
384 switch (iType3)
385 {
386 case sci_matrix :
387 sciErr = getMatrixOfDouble(pvApiCtx, piAddr3, &iRows3, &iCols3, (double**)&pvData);
388 break;
389 case sci_boolean :
390 sciErr = getMatrixOfBoolean(pvApiCtx, piAddr3, &iRows3, &iCols3, (int**)&pvData);
391 break;
392 case sci_handles :
393 sciErr = getMatrixOfHandle(pvApiCtx, piAddr3, &iRows3, &iCols3, (long long**)&pvData);
394 break;
395 case sci_strings :
396 if (stricmp(pstProperty, "tics_labels") != 0 && stricmp(pstProperty, "auto_ticks") != 0 && stricmp(pstProperty, "tight_limits") != 0 &&
397 stricmp(pstProperty, "axes_visible") != 0 && stricmp(pstProperty, "axes_reverse") != 0 &&
398 stricmp(pstProperty, "text") != 0 && stricmp(pstProperty, "string") != 0 &&
399 stricmp(pstProperty, "tooltipstring") != 0 && stricmp(pstProperty, "ticks_format") != 0) /* Added for uicontrols */
400 {
401 if (isScalar(pvApiCtx, piAddr3) == 0)
402 {
403 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, iPos + 1);
404 freeAllocatedSingleString(pstProperty);
405 return 1;
406 }
407
408 if (getAllocatedSingleString(pvApiCtx, piAddr3, (char**)&pvData))
409 {
410 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos + 1);
411 freeAllocatedSingleString(pstProperty);
412 return 1;
413 }
414 iRows3 = (int)strlen((char*)pvData);
415 iCols3 = 1;
416 isMatrixOfString = 0;
417 }
418 else
419 {
420 isMatrixOfString = 1;
421 if (getAllocatedMatrixOfString(pvApiCtx, piAddr3, &iRows3, &iCols3, (char***)&pvData))
422 {
423 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos + 1);
424 freeAllocatedSingleString(pstProperty);
425 return 1;
426 }
427 }
428 break;
429 case sci_list :
430 iCols3 = 1;
431 sciErr = getListItemNumber(pvApiCtx, piAddr3, &iRows3);
432 pvData = (void*)piAddr3; /* In this case l3 is the list position in stack */
433 break;
434 default :
435 pvData = (void*)piAddr3; /* In this case l3 is the list position in stack */
436 break;
437 }
438
439 if (sciErr.iErr)
440 {
441 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos + 1);
442 freeAllocatedSingleString(pstProperty);
443 if (isMatrixOfString == 1)
444 {
445 freeAllocatedMatrixOfString(iRows3, iCols3, (char**)pvData);
446 }
447 else
448 {
449 freeAllocatedSingleString((char*)pvData);
450 }
451 return 1;
452 }
453 }
454
455 setStatus = callSetProperty(pvApiCtx, iObjUID, pvData, iType3, iRows3, iCols3, pstProperty);
456 if (iType3 == sci_strings)
457 {
458 //free allacted data
459 if (isMatrixOfString == 1)
460 {
461 freeAllocatedMatrixOfString(iRows3, iCols3, (char**)pvData);
462 }
463 else
464 {
465 freeAllocatedSingleString((char*)pvData);
466 }
467 }
468
469 freeAllocatedSingleString(pstProperty);
470 }
471
472 #ifdef _MSC_VER
473 //never occurs, just to break weird optimisation (bug 14896)
474 if (iRhs == 0)
475 {
476 Sleep(1);
477 }
478 #endif
479
480 AssignOutputVariable(pvApiCtx, 1) = 0;
481 ReturnArguments(pvApiCtx);
482 return 0;
483 }
484 /*--------------------------------------------------------------------------*/
485