Merge remote-tracking branch 'origin/master' into windows
[scilab.git] / scilab / modules / api_scilab / src / cpp / api_stack_optional.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Antoine ELIAS
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  */
14
15 #include "function.hxx"
16 #include "gatewaystruct.hxx"
17 #include "alltypes.hxx"
18
19 extern "C"
20 {
21 #include <string.h>
22 #include "api_scilab.h"
23 #include "localization.h"
24 #include "Scierror.h"
25 #include "call_scilab.h"
26 #include "sciprint.h"
27 #include "sci_malloc.h"
28 }
29
30
31 static int findOptional(void* _pvCtx, const char *fname, rhs_opts opts[]);
32 static void printOptionalNames(void* _pvCtx, rhs_opts opts[]);
33
34 /**************************/
35 /*   optional functions   */
36 /**************************/
37 int getOptionals(void* _pvCtx, char* pstFuncName, rhs_opts opts[])
38 {
39     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
40     types::optional_list opt = *pStr->m_pOpt;
41     int i = 0;
42
43     /* reset first field since opts is declared static in calling function */
44
45     while (opts[i].pstName != NULL)
46     {
47         opts[i].iPos = -1;
48         i++;
49     }
50
51
52     for (const auto& o : opt)
53     {
54         int typeOfOpt = -1;
55         int index = findOptional(_pvCtx, o.first.c_str(), opts);
56
57         if (index < 0)
58         {
59             sciprint(_("%s: Unrecognized optional arguments %s.\n"), pStr->m_pstName, o.first.c_str());
60             printOptionalNames(_pvCtx, opts);
61             return 0;
62         }
63
64         opts[index].iPos = i + 1;
65         types::GenericType* pGT = (types::GenericType*)o.second;
66         getVarType(_pvCtx, (int*)pGT, &typeOfOpt);
67         opts[index].iType = typeOfOpt;
68
69         if (typeOfOpt == sci_implicit_poly)
70         {
71             types::InternalType* pIT = NULL;
72             types::ImplicitList* pIL = pGT->getAs<types::ImplicitList>();
73             pIT = pIL->extractFullMatrix();
74             types::Double* impResult = (types::Double*)pIT;
75             opts[index].iRows = impResult->getRows();
76             opts[index].iCols = impResult->getCols();
77             opts[index].piAddr = (int*)impResult;
78             opts[index].iType = sci_matrix;
79         }
80         else
81         {
82             opts[index].iRows = pGT->getRows();
83             opts[index].iCols = pGT->getCols();
84             opts[index].piAddr = (int*)pGT;
85         }
86     }
87     //   int index = -1;
88     //GatewayStruct* pStr = (GatewayStruct*)_pvCtx;
89
90     //   wchar_t* pwstProperty = to_wide_string(pstProperty);
91
92     //   for(int i = 0 ; i < pStr->m_pOpt->size() ; i++)
93     //   {
94     //       std::pair<std::wstring, InternalType*> current = (*pStr->m_pOpt)[i];
95     //       if(wcscmp(current.first.c_str(), pwstProperty) == 0)
96     //       {
97     //           index = i;
98     //           break;
99     //       }
100     //   }
101
102     //   FREE(pwstProperty);
103
104     return 1;
105 }
106
107 int FirstOpt(void* _pvCtx)
108 {
109     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
110     return (int)pStr->m_pIn->size() + 1;
111 }
112
113 int NumOpt(void* _pvCtx)
114 {
115     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
116     return (int)pStr->m_pOpt->size();
117 }
118
119 int FindOpt(void* _pvCtx, char* pstProperty, rhs_opts opts[])
120 {
121     int i = findOptional(_pvCtx, pstProperty, opts);
122     if (i >= 0 && opts[i].iPos > 0)
123     {
124         return i;
125     }
126
127     return -1;
128 }
129
130 static int findOptional(void* _pvCtx, const char *pstProperty, rhs_opts opts[])
131 {
132     int rep = -1, i = 0;
133
134     while (opts[i].pstName != NULL)
135     {
136         int cmp;
137
138         /* name is terminated by white space and we want to ignore them */
139         if ((cmp = strcmp(pstProperty, opts[i].pstName)) == 0)
140         {
141             rep = i;
142             break;
143         }
144         else if (cmp < 0)
145         {
146             break;
147         }
148         else
149         {
150             i++;
151         }
152     }
153     return rep;
154 }
155
156 void printOptionalNames(void* _pvCtx, rhs_opts opts[])
157 /* array of optinal names (in alphabetical order)
158 * the array is null terminated */
159 {
160     int i = 0;
161
162     if (opts[i].pstName == NULL)
163     {
164         sciprint(_("Optional argument list is empty.\n"));
165         return;
166     }
167
168     sciprint(_("Optional arguments list: \n"));
169     while (opts[i + 1].pstName != NULL)
170     {
171         sciprint("%s, ", opts[i].pstName);
172         i++;
173     }
174     sciprint(_("and %s.\n"), opts[i].pstName);
175 }