An overview of the Apifun toolbox.
The goal of this module is to provide a set to function to check input arguments in macros.
In functions with a variable number of input arguments, we often have the following source code, which checks that the number of input arguments provided by the user is consistent with the number of expected arguments :
[lhs,rhs]=argn() if ( rhs < 2 | rhs > 5 ) then msgfmt = "%s: Unexpected number of input arguments :"+.. "%d provided while from %d to %d are expected." errmsg = msprintf(gettext(msgfmt), "myfunction", rhs,2,5) error(errmsg) end | ![]() | ![]() |
Writing this code is error-prone and boring. Moreover, this fragment of source code is duplicated in many functions, leading to small variations depending on the developer. In particular, this makes the localization of the error messages difficult, because the message can be slightly different depending on the function. It can also lead to unexpected errors, for example when the string containing the error message is wrongly formatted. In this case, instead of the expected error, the user gets a message telling that the argument of the msprintf function has a wrong format ; this is an information which can let the user confused about the source of the error. Moreover, because writing this source code is boring, many existing functions are not sufficiently robust against wrong uses.
The goal of the apifun module is to simplify this task. For example, the apifun_checkrhs function checks that the number of input arguments provided by the user of the function corresponds to the number of expected arguments. The following function takes 2/3 input arguments and 1 output arguments.
function y=myfunction(varargin) [lhs, rhs] = argn() apifun_checkrhs ( "myfunction" , rhs , 2:3 ) apifun_checklhs ( "myfunction" , lhs , 1 ) x1 = varargin(1) x2 = varargin(2) if ( rhs >= 3 ) then x3 = varargin(3) else x3 = 2 end y = x1 + x2 + x3 endfunction | ![]() | ![]() |
When called with 1 or 4 arguments, an error will be generated.
// Calling sequences which work y = myfunction ( 1 , 2 ) y = myfunction ( 1 , 2 , 3 ) // Calling sequences which generate an error y = myfunction ( 1 ) y = myfunction ( 1 , 2 , 3 , 4 ) | ![]() | ![]() |
The following session shows the kind of error message which is produced by the apifun module, for example when the number of input argument is wrong. The error message is clear about the function which generates the message (e.g. "myfunction").
-->y = myfunction ( 1 ) !--error 10000 myfunction: Unexpected number of input arguments : 1 provided while the number of expected input arguments should be in the set [2 3]. at line 131 of function called by : at line 3 of function called by : y = myfunction ( 1 ) | ![]() | ![]() |
The following session shows the kind of error message which is produced when the type of an argument is wrong.
-->mycrudemc ( 1 , 1 ) !--error 10000 mycrudemc: Expected type ["function" or "list"] for input argument func at input #1, but got "constant" instead. at line 65 of function called by : at line 32 of function called by : mycrudemc ( 1 , 1 ) | ![]() | ![]() |
The advantages of using the current module are the following.
Designing robust functions is much simpler which improves both the quality and the robustness of functions.
The provided source code is factored into one single module.
It is similar to what is provided to the developers of Scilab gateways, at the C level.
The apifun package itself is tested. Moreover, when we call a apifun_* function, the arguments that we pass to it are checked. Therefore, we can be confident in the fact that the argument checking that we perform is correctly done and that we consistently use the apifun package.
In the body of each apifun_* function, we check the input arguments. But we do not make use of the apifun_* functions, in order to clarify the messages.
This project is managed on the Scilab Forge : http://forge.scilab.org/index.php/p/apifun/
Michael Baudin thanks Pierre Maréchal for his suggestions.
This toolbox is distributed under the CeCILL_V2 license : http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt