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