Scilab Website | Contribute with GitLab | Mailing list archives | ATOMS toolboxes
Scilab Online Help
5.3.0 - Português

Change language to:
English - Français - 日本語 -

Please note that the recommended version of Scilab is 2024.1.0. This page might be outdated.
However, this page did not exist in the previous stable version.

Manual Scilab >> API Scilab > Scilab Gateway API > How to > How to deal with optional parameters

How to deal with optional parameters

how to deal with optional parameters send to an interface using the C gateway functions

Description

WARNING: This API is deprecated from Scilab 5.2.0 and is going to be removed with Scilab 6.0. Please use API Scilab (the new Scilab API).

The goal is to get a set of optional parameters via a C gateway and then to perform some checks in the C function (number of optional parameters, does an optional parameters exists, etc.).

This example is available in the directory core/examples/optional_parameters

The C function

#include <stack-c.h>

int ex2c(double * a, int * ma, int * na,
         double * b, int * mb, int * nb) 
{
  int i;

  for(i=0;i<(*ma)*(*na);i++) a[i] = 2*a[i];
  for(i=0;i<(*mb)*(*nb);i++) b[i] = 3*b[i];

  return(0);
}

int sci_optional_parameters(char * fname)
{ 
  int m1,n1,l1;

  // optional names must be stored in alphabetical order in opts
  static rhs_opts opts[]= {{-1,"v1","d",0,0,0},
                           {-1,"v2","d",0,0,0},
                           {-1,NULL,NULL,0,0}};

  int minrhs = 1, maxrhs = 1;
  int minlhs = 1, maxlhs = 3;
  int nopt, iopos, res;
  char buffer_name[csiz]; // csiz used for character coding

  nopt = NumOpt();

  CheckRhs(minrhs,maxrhs+nopt);
  CheckLhs(minlhs,maxlhs);

  // first non optional argument
  GetRhsVar( 1, "c", &m1, &n1, &l1);
  
  if (get_optionals(fname,opts)==0) return 0;

  // default values if optional arguments are not given:  v1=[99] and v2=[3]

  sciprint("number of optional parameters = %d\n", NumOpt());
  sciprint("first optional parameters = %d\n", FirstOpt());
  sciprint("FindOpt(v1) = %d\n", FindOpt("v1", opts));
  sciprint("FindOpt(v2) = %d\n", FindOpt("v2", opts));

  if (IsOpt(1,buffer_name))
    sciprint("parameter 1 is optional: %s\n", buffer_name);
  if (IsOpt(2,buffer_name))
    sciprint("parameter 2 is optional: %s\n", buffer_name);
  if (IsOpt(3,buffer_name))
    sciprint("parameter 3 is optional: %s\n", buffer_name);

  iopos = Rhs;

  if (opts[0].position==-1)
    {
      iopos++;
      opts[0].position = iopos;
      opts[0].m = 1; opts[0].n = 1; 
      opts[0].type = "d";
      CreateVar(opts[0].position, opts[0].type, &opts[0].m, &opts[0].n, &opts[0].l);
      *stk(opts[0].l) = 99.0;
    }

  if (opts[1].position==-1) 
    {
      iopos++ ; 
      opts[1].position = iopos;
      opts[1].m = 1; opts[1].n = 1;
      opts[1].type = "d";
      CreateVar(opts[1].position, opts[1].type, &opts[1].m, &opts[1].n, &opts[1].l);
      *stk(opts[1].l) = 3;
    }

  ex2c(stk(opts[0].l),&opts[0].m,&opts[0].n,
       stk(opts[1].l),&opts[1].m,&opts[1].n);

  // return the first argument (unchanged ) then v1 and v2

  LhsVar(1) = 1;
  LhsVar(2) = opts[0].position;
  LhsVar(3) = opts[1].position;

  return 0;
}

This file must be saved as "optional_parameters.c".

The main thing to highlight is that, to build a C interface function, we need to include the header stack-c.h. In this header, we find the prototypes and macros of the main C interface functions. We also need to include sciprint.h because we use the sciprint function.

To be able to build and link such a C function to scilab, we need to write a Scilab script which will compile this C function and then create a loader script which will link the C function to a Scilab function.

The builder script

// This is the builder.sce 
// must be run from this directory 

lines(0);

ilib_name  = 'lib_optional_parameters';

files = ['optional_parameters.c'];

libs  = [];

table =['optional_parameters', 'sci_optional_parameters'];

ldflags = "";
cflags  = "";
fflags  = "";

ilib_build(ilib_name,table,files,libs,'Makelib',ldflags,cflags,fflags);

This file must be saved as "builder.sce".

This script will tell Scilab which files must be compiled (here, it's optional_parameters.c), what will be the name of the shared library (here, it's lib_optional_parameters) and which C symbol will be linked to a Scilab function (here, we will link the sci_optional_parameters C symbol to the Scilab function "optional_parameters").

To build this function, we just need to to:

exec builder.sce;

Now we are able to test our new C function. First, let's load this new function in scilab:

exec loader.sce;

The script loader.sce is normally automatically built by builder.sce.

Testing our new function

We now write a simple example to test our new functions.

// Example with optional argument specified with the 'arg=value syntax'
// [a,b,c] = ex12c(x1, [v1 = arg1, v2 = arg2]), arg1 default value 99
//                                              arg2 default value 3
// only v1 and v2 are recognized as optional argument names 
// the return value are a = x1, b = 2*v2, c = 3*v2 

[a,b,c] = optional_parameters('test');
disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c));

[a,b,c] = optional_parameters('test',v1=[10,20]);
disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c));

[a,b,c] = optional_parameters('test',v1=[10,20],v2=8);
disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c));

[a,b,c] = optional_parameters('test',v2=8,v1=[10]);
disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c));

The script must be saved as "optional_parameters.sce".

Let's run our scripts and see what is the result:

-->;exec builder.sce;
   Génère un fichier gateway
   Génère un fichier loader
   Génère un Makefile : Makelib
   Exécute le makefile
   Compilation de optional_parameters.c
   Construction de la bibliothèque partagée (soyez patient)
 
-->;exec loader.sce;
Bibliothèque partagée chargée.
Link done.
 
-->;exec optional_parameters.sce;
number of optional parameters = 0
first optional parameters = 2
FindOpt(v1) = 0
FindOpt(v2) = 0
 
 a = test b = 198 c = 9   
number of optional parameters = 1
first optional parameters = 2
FindOpt(v1) = 2
FindOpt(v2) = 0
parameter 2 is optional: v1
 
!a = test b = 20 c = 9  a = test b = 40 c = 9  !
number of optional parameters = 2
first optional parameters = 2
FindOpt(v1) = 2
FindOpt(v2) = 3
parameter 2 is optional: v1
parameter 3 is optional: v2
 
!a = test b = 20 c = 24  a = test b = 40 c = 24  !
number of optional parameters = 2
first optional parameters = 2
FindOpt(v1) = 3
FindOpt(v2) = 2
parameter 2 is optional: v2
parameter 3 is optional: v1
 
 a = test b = 20 c = 24
<< How to create and access a list How to CheckColumn >>

Copyright (c) 2022-2024 (Dassault Systèmes)
Copyright (c) 2017-2022 (ESI Group)
Copyright (c) 2011-2017 (Scilab Enterprises)
Copyright (c) 1989-2012 (INRIA)
Copyright (c) 1989-2007 (ENPC)
with contributors
Last updated:
Wed Jan 26 16:24:43 CET 2011