add more help pages related to CAPI - check parameters - optional parameters
[scilab.git] / scilab / modules / core / help / en_US / capi / HowToDealWithOptionalParameters.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <refentry version="5.0-subset Scilab" xml:id="HowToDealWithOptionalParameters"
3           xmlns="http://docbook.org/ns/docbook"
4           xmlns:xlink="http://www.w3.org/1999/xlink"
5           xmlns:xi="http://www.w3.org/2001/XInclude"
6           xmlns:svg="http://www.w3.org/2000/svg"
7           xmlns:mml="http://www.w3.org/1998/Math/MathML"
8           xmlns:html="http://www.w3.org/1999/xhtml"
9           xmlns:db="http://docbook.org/ns/docbook">
10   <refnamediv>
11     <refname>How to deal with optional parameters</refname>
12
13     <refpurpose>how to deal with optional parameters send to an interface
14     using the C API</refpurpose>
15   </refnamediv>
16
17   <refsection>
18     <title>Description</title>
19
20     <para>The goal is to get a set of optional parameters via a C interface
21     and then to perform some checks in the C function (number of optional
22     parameters, does an optional parameters exists, etc.).</para>
23
24     <para>This example is available in the directory
25     CAPI/examples/optional_parameters</para>
26   </refsection>
27
28   <refsection>
29     <title>The C function</title>
30
31     <programlisting role="example"> 
32 #include &lt;stack-c.h&gt;
33
34 int ex2c(double * a, int * ma, int * na,
35          double * b, int * mb, int * nb) 
36 {
37   int i;
38
39   for(i=0;i&lt;(*ma)*(*na);i++) a[i] = 2*a[i];
40   for(i=0;i&lt;(*mb)*(*nb);i++) b[i] = 3*b[i];
41
42   return(0);
43 }
44
45 int sci_optional_parameters(char * fname)
46
47   int m1,n1,l1;
48
49   // optional names must be stored in alphabetical order in opts
50   static rhs_opts opts[]= {{-1,"v1","d",0,0,0},
51                            {-1,"v2","d",0,0,0},
52                            {-1,NULL,NULL,0,0}};
53
54   int minrhs = 1, maxrhs = 1;
55   int minlhs = 1, maxlhs = 3;
56   int nopt, iopos, res;
57   char buffer_name[csiz]; // csiz used for character coding
58
59   nopt = NumOpt();
60
61   CheckRhs(minrhs,maxrhs+nopt);
62   CheckLhs(minlhs,maxlhs);
63
64   // first non optional argument
65   GetRhsVar( 1, "c", &amp;m1, &amp;n1, &amp;l1);
66   
67   if (get_optionals(fname,opts)==0) return 0;
68
69   // default values if optional arguments are not given:  v1=[99] and v2=[3]
70
71   sciprint("number of optional parameters = %d\n", NumOpt());
72   sciprint("first optional parameters = %d\n", FirstOpt());
73   sciprint("FindOpt(v1) = %d\n", FindOpt("v1", opts));
74   sciprint("FindOpt(v2) = %d\n", FindOpt("v2", opts));
75
76   if (IsOpt(1,buffer_name))
77     sciprint("parameter 1 is optional: %s\n", buffer_name);
78   if (IsOpt(2,buffer_name))
79     sciprint("parameter 2 is optional: %s\n", buffer_name);
80   if (IsOpt(3,buffer_name))
81     sciprint("parameter 3 is optional: %s\n", buffer_name);
82
83   iopos = Rhs;
84
85   if (opts[0].position==-1)
86     {
87       iopos++;
88       opts[0].position = iopos;
89       opts[0].m = 1; opts[0].n = 1; 
90       opts[0].type = "d";
91       CreateVar(opts[0].position, opts[0].type, &amp;opts[0].m, &amp;opts[0].n, &amp;opts[0].l);
92       *stk(opts[0].l) = 99.0;
93     }
94
95   if (opts[1].position==-1) 
96     {
97       iopos++ ; 
98       opts[1].position = iopos;
99       opts[1].m = 1; opts[1].n = 1;
100       opts[1].type = "d";
101       CreateVar(opts[1].position, opts[1].type, &amp;opts[1].m, &amp;opts[1].n, &amp;opts[1].l);
102       *stk(opts[1].l) = 3;
103     }
104
105   ex2c(stk(opts[0].l),&amp;opts[0].m,&amp;opts[0].n,
106        stk(opts[1].l),&amp;opts[1].m,&amp;opts[1].n);
107
108   // return the first argument (unchanged ) then v1 and v2
109
110   LhsVar(1) = 1;
111   LhsVar(2) = opts[0].position;
112   LhsVar(3) = opts[1].position;
113
114   return 0;
115 }
116   </programlisting>
117
118     <para>This file must be saved as "optional_parameters.c".</para>
119
120     <para>The main thing to highlight is that, to build a C interface
121     function, we need to include the header stack-c.h. In this header, we find
122     the prototypes and macros of the main C interface functions. We also need
123     to include sciprint.h because we use the sciprint function.</para>
124
125     <para>To be able to build and link such a C function to scilab, we need to
126     write a Scilab script which will compile this C function and then create a
127     loader script which will link the C function to a Scilab function.</para>
128   </refsection>
129
130   <refsection>
131     <title>The builder script</title>
132
133     <programlisting role="example"> 
134 // This is the builder.sce 
135 // must be run from this directory 
136
137 lines(0);
138
139 ilib_name  = 'lib_optional_parameters';
140
141 files = ['optional_parameters.c'];
142
143 libs  = [];
144
145 table =['optional_parameters', 'sci_optional_parameters'];
146
147 ldflags = "";
148 cflags  = "";
149 fflags  = "";
150
151 // do not modify below 
152 // ----------------------------------------------
153 ilib_build(ilib_name,table,files,libs,'Makelib',ldflags,cflags,fflags);
154   </programlisting>
155
156     <para>This file must be saved as "builder.sce".</para>
157
158     <para>This script will tell Scilab which files must be compiled (here,
159     it's optional_parameters.c), what will be the name of the shared library
160     (here, it's lib_optional_parameters) and which C symbol will be linked to
161     a Scilab function (here, we will link the sci_optional_parameters C symbol
162     to the Scilab function "optional_parameters").</para>
163
164     <para>To build this function, we just need to to:</para>
165
166     <programlisting> 
167 exec builder.sce;
168  </programlisting>
169
170     <para>Now we are able to test our new C function. First, let's load this
171     new function in scilab:</para>
172
173     <programlisting> 
174 exec loader.sce; 
175  </programlisting>
176
177     <para>The script loader.sce is normally automatically built by
178     builder.sce.</para>
179   </refsection>
180
181   <refsection>
182     <title>Testing our new function</title>
183
184     <para>We now write a simple example to test our new functions.</para>
185
186     <programlisting role="example"> 
187 // Example with optional argument specified with the 'arg=value syntax'
188 // [a,b,c] = ex12c(x1, [v1 = arg1, v2 = arg2]), arg1 default value 99
189 //                                              arg2 default value 3
190 // only v1 and v2 are recognized as optional argument names 
191 // the return value are a = x1, b = 2*v2, c = 3*v2 
192
193 [a,b,c] = optional_parameters('test');
194 disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c));
195
196 [a,b,c] = optional_parameters('test',v1=[10,20]);
197 disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c));
198
199 [a,b,c] = optional_parameters('test',v1=[10,20],v2=8);
200 disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c));
201
202 [a,b,c] = optional_parameters('test',v2=8,v1=[10]);
203 disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c));
204   </programlisting>
205
206     <para>The script must be saved as "optional_parameters.sce".</para>
207
208     <para>Let's run our scripts and see what is the result:</para>
209
210     <programlisting> 
211 --&gt;exec builder.sce;
212    Génère un fichier gateway
213    Génère un fichier loader
214    Génère un Makefile : Makelib
215    Exécute le makefile
216    Compilation de optional_parameters.c
217    Construction de la bibliothèque partagée (soyez patient)
218  
219 --&gt;exec loader.sce;
220 Bibliothèque partagée chargée.
221 Link done.
222  
223 --&gt;exec optional_parameters.sce;
224 number of optional parameters = 0
225 first optional parameters = 2
226 FindOpt(v1) = 0
227 FindOpt(v2) = 0
228  
229  a = test b = 198 c = 9   
230 number of optional parameters = 1
231 first optional parameters = 2
232 FindOpt(v1) = 2
233 FindOpt(v2) = 0
234 parameter 2 is optional: v1
235  
236 !a = test b = 20 c = 9  a = test b = 40 c = 9  !
237 number of optional parameters = 2
238 first optional parameters = 2
239 FindOpt(v1) = 2
240 FindOpt(v2) = 3
241 parameter 2 is optional: v1
242 parameter 3 is optional: v2
243  
244 !a = test b = 20 c = 24  a = test b = 40 c = 24  !
245 number of optional parameters = 2
246 first optional parameters = 2
247 FindOpt(v1) = 3
248 FindOpt(v2) = 2
249 parameter 2 is optional: v2
250 parameter 3 is optional: v1
251  
252  a = test b = 20 c = 24  
253  </programlisting>
254   </refsection>
255
256   <refsection>
257     <title>See Also</title>
258
259     <simplelist type="inline">
260       <member><link linkend="GetRhsVar">GetRhsVar</link></member>
261
262       <member><link linkend="CheckColumn">CheckColumn</link></member>
263
264       <member><link linkend="CheckDims">CheckDims</link></member>
265
266       <member><link linkend="CheckRow">CheckRow</link></member>
267
268       <member><link linkend="CheckScalar">CheckScalar</link></member>
269
270       <member><link linkend="CheckVector">CheckVector</link></member>
271
272       <member><link linkend="CheckDimProp">CheckDimProp</link></member>
273
274       <member><link linkend="CheckLength">CheckLength</link></member>
275
276       <member><link linkend="CheckSameDims">CheckSameDims</link></member>
277
278       <member><link linkend="CheckSquare">CheckSquare</link></member>
279
280       <member><link linkend="OverLoad">OverLoad</link></member>
281
282       <member><link linkend="ilib_build">ilib_build</link></member>
283     </simplelist>
284   </refsection>
285 </refentry>